[nexuiz-commits] r8350 - trunk/data/qcsrc/server
DONOTREPLY at icculus.org
DONOTREPLY at icculus.org
Wed Dec 2 12:47:46 EST 2009
Author: fruitiex
Date: 2009-12-02 12:47:46 -0500 (Wed, 02 Dec 2009)
New Revision: 8350
Modified:
trunk/data/qcsrc/server/race.qc
Log:
add defrag waypoint support to CTS, first time someone finishes a map the code records the checkpoint sequence and saves it in a .defragcp file that it'll then use in the future (mappers should pack them in the pk3 to ensure trolls don't waypoint a map improperly on a server! :P)
Modified: trunk/data/qcsrc/server/race.qc
===================================================================
--- trunk/data/qcsrc/server/race.qc 2009-12-02 13:51:54 UTC (rev 8349)
+++ trunk/data/qcsrc/server/race.qc 2009-12-02 17:47:46 UTC (rev 8350)
@@ -18,6 +18,10 @@
float race_highest_checkpoint;
float race_timed_checkpoint;
+float dfcp_cnt;
+float defrag_ents;
+float defragcpexists;
+
float race_NextCheckpoint(float f)
{
if(f >= race_highest_checkpoint)
@@ -371,6 +375,28 @@
other.porto_forbidden = 2; // decreased by 1 each StartFrame
+ if(self.race_checkpoint == -2)
+ {
+ self.race_checkpoint = other.race_checkpoint;
+ }
+
+ entity cp;
+ float largest_cp_id;
+ for(cp = world; (cp = find(cp, classname, "target_checkpoint"));)
+ if(cp.race_checkpoint > largest_cp_id) // update the finish id if someone hit a new checkpoint
+ {
+ largest_cp_id = cp.race_checkpoint;
+ for(cp = world; (cp = find(cp, classname, "target_stopTimer"));)
+ cp.race_checkpoint = largest_cp_id + 1; // finish line
+ race_highest_checkpoint = largest_cp_id + 1;
+ race_timed_checkpoint = largest_cp_id + 1;
+
+ for(cp = world; (cp = find(cp, classname, "target_checkpoint"));) {
+ if(cp.race_checkpoint == -2) // set defragcpexists to -1 so that the cp id file will be rewritten when someone finishes
+ defragcpexists = -1;
+ }
+ }
+
if(other.race_checkpoint == -1 || other.race_checkpoint == self.race_checkpoint)
{
if(self.race_penalty)
@@ -411,6 +437,19 @@
if(g_race_qualifying)
race_SendNextCheckpoint(other, 0);
+
+ if(defrag_ents && defragcpexists < 0 && self.classname == "target_stopTimer")
+ {
+ entity cp;
+ float fh;
+ defragcpexists = fh = fopen(strcat("maps/", GetMapname(), ".defragcp"), FILE_WRITE);
+ if(fh >= 0)
+ {
+ for(cp = world; (cp = find(cp, classname, "target_checkpoint"));)
+ fputs(fh, strcat(cp.targetname, " ", ftos(cp.race_checkpoint), "\n"));
+ }
+ fclose(fh);
+ }
}
else if(other.race_checkpoint == race_NextCheckpoint(self.race_checkpoint))
{
@@ -440,7 +479,7 @@
float race_waypointsprite_visible_for_player(entity e)
{
- if(e.race_checkpoint == -1)
+ if(e.race_checkpoint == -1 || e.race_checkpoint == -2)
return TRUE;
else if(e.race_checkpoint == self.owner.race_checkpoint)
return TRUE;
@@ -496,7 +535,7 @@
}
}
}
- else
+ else if(!defrag_ents)
{
// qualifying only
self.race_checkpoint = race_NextCheckpoint(0);
@@ -505,19 +544,77 @@
if(!Spawn_FilterOutBadSpots(findchain(classname, "info_player_deathmatch"), world, 0, FALSE))
error(strcat("Checkpoint ", ftos(i), " misses a spawnpoint with race_place==", ftos(self.race_place), " (used for qualifying) - bailing out"));
}
+ else
+ {
+ self.race_checkpoint = race_NextCheckpoint(0);
+ g_race_qualifying = 1;
+ self.race_place = 0; // there's only one spawn on defrag maps
+
+ // check if a defragcp file already exists, then read it and apply the checkpoint order
+ float fh;
+ float len;
+ string l;
+ defragcpexists = fh = fopen(strcat("maps/", GetMapname(), ".defragcp"), FILE_READ);
+ if(fh >= 0)
+ {
+ while(l = fgets(fh))
+ {
+ len = tokenize_console(l);
+ if(len != 2) {
+ defragcpexists = -1; // something's wrong in the defrag cp file, set defragcpexists to -1 so that it will be rewritten when someone finishes
+ continue;
+ }
+ for(cp = world; (cp = find(cp, classname, "target_checkpoint"));)
+ if(argv(0) == cp.targetname)
+ cp.race_checkpoint = stof(argv(1));
+ }
+ fclose(fh);
+ }
+ }
+
g_race_qualifying = qual;
- if(race_timed_checkpoint)
- for(cp = world; (cp = find(cp, classname, "trigger_race_checkpoint")); )
- if(cp.sprite)
- {
- if(cp.race_checkpoint == 0)
- WaypointSprite_UpdateSprites(cp.sprite, "race-start", "", "");
- else if(cp.race_checkpoint == race_timed_checkpoint)
- WaypointSprite_UpdateSprites(cp.sprite, "race-finish", "", "");
+ if(race_timed_checkpoint) {
+ if(defrag_ents) {
+ for(cp = world; (cp = find(cp, classname, "target_startTimer"));)
+ WaypointSprite_UpdateSprites(cp.sprite, "race-start", "", "");
+ for(cp = world; (cp = find(cp, classname, "target_stopTimer"));)
+ WaypointSprite_UpdateSprites(cp.sprite, "race-finish", "", "");
+
+ for(cp = world; (cp = find(cp, classname, "target_checkpoint"));) {
+ if(cp.race_checkpoint == -2) // something's wrong with the defrag cp file or it has not been written yet, set defragcpexists to -1 so that it will be rewritten when someone finishes
+ defragcpexists = -1;
}
+ if(defragcpexists != -1){
+ float largest_cp_id;
+ for(cp = world; (cp = find(cp, classname, "target_checkpoint"));)
+ if(cp.race_checkpoint > largest_cp_id)
+ largest_cp_id = cp.race_checkpoint;
+ for(cp = world; (cp = find(cp, classname, "target_stopTimer"));)
+ cp.race_checkpoint = largest_cp_id + 1; // finish line
+ race_highest_checkpoint = largest_cp_id + 1;
+ race_timed_checkpoint = largest_cp_id + 1;
+ } else {
+ for(cp = world; (cp = find(cp, classname, "target_stopTimer"));)
+ cp.race_checkpoint = 255; // finish line
+ race_highest_checkpoint = 255;
+ race_timed_checkpoint = 255;
+ }
+ }
+ else {
+ for(cp = world; (cp = find(cp, classname, "trigger_race_checkpoint")); )
+ if(cp.sprite)
+ {
+ if(cp.race_checkpoint == 0)
+ WaypointSprite_UpdateSprites(cp.sprite, "race-start", "", "");
+ else if(cp.race_checkpoint == race_timed_checkpoint)
+ WaypointSprite_UpdateSprites(cp.sprite, "race-finish", "", "");
+ }
+ }
+ }
+
remove(self);
self = oldself;
}
@@ -573,6 +670,55 @@
InitializeEntity(self, trigger_race_checkpoint_verify, INITPRIO_FINDTARGET);
}
+void spawnfunc_target_checkpoint() // defrag entity
+{
+ vector o;
+ if(!g_race && !g_cts)
+ {
+ remove(self);
+ return;
+ }
+ defrag_ents = 1;
+
+
+ EXACTTRIGGER_INIT;
+
+ self.use = checkpoint_use;
+ //if not(self.spawnflags & 1)
+ // self.touch = checkpoint_touch;
+
+ o = (self.absmin + self.absmax) * 0.5;
+ tracebox(o, PL_MIN, PL_MAX, o - '0 0 1' * (o_z - self.absmin_z), MOVE_NORMAL, self);
+ waypoint_spawnforitem_force(self, trace_endpos);
+ self.nearestwaypointtimeout = time + 1000000000;
+
+ if(!self.message)
+ self.message = "went backwards";
+ if (!self.message2)
+ self.message2 = "was pushed backwards by";
+ if (!self.race_penalty_reason)
+ self.race_penalty_reason = "missing a checkpoint";
+
+ if(self.classname == "target_startTimer")
+ self.race_checkpoint = 0;
+ else
+ self.race_checkpoint = -2;
+
+ race_timed_checkpoint = 1;
+
+ if(self.race_checkpoint == 0)
+ WaypointSprite_SpawnFixed("race-start", o, self, sprite);
+ else
+ WaypointSprite_SpawnFixed("race-checkpoint", o, self, sprite);
+
+ self.sprite.waypointsprite_visible_for_player = race_waypointsprite_visible_for_player;
+
+ InitializeEntity(self, trigger_race_checkpoint_verify, INITPRIO_FINDTARGET);
+}
+
+void spawnfunc_target_startTimer() { spawnfunc_target_checkpoint(); }
+void spawnfunc_target_stopTimer() { spawnfunc_target_checkpoint(); }
+
void race_AbandonRaceCheck(entity p)
{
if(race_completing && !p.race_completed)
More information about the nexuiz-commits
mailing list