IntrusiveList g_race_targets;
IntrusiveList g_racecheckpoints;
-STATIC_INIT(g_race)
-{
- g_race_targets = IL_NEW();
- g_racecheckpoints = IL_NEW();
-}
void race_InitSpectator()
{
WriteByte(msg, m);
}
-void race_SendRankings(float pos, float prevpos, float del, float msg)
+void race_SendRanking(float pos, float prevpos, float del, float msg)
{
WriteHeader(msg, TE_CSQC_RACE);
WriteByte(msg, RACE_NET_SERVER_RANKINGS);
int m = min(RANKINGS_CNT, autocvar_g_cts_send_rankings_cnt);
race_send_rankings_cnt(MSG_ONE);
for (int i = 1; i <= m; ++i)
- race_SendRankings(i, 0, 0, MSG_ONE);
+ race_SendRanking(i, 0, 0, MSG_ONE);
}
void race_SendStatus(float id, entity e)
race_send_recordtime(MSG_ALL);
}
- race_SendRankings(newpos, player_prevpos, 0, MSG_ALL);
+ race_SendRanking(newpos, player_prevpos, 0, MSG_ALL);
strcpy(rankings_reply, getrankings());
if(newpos == player_prevpos)
}
}
- race_SendRankings(pos, 0, 1, MSG_ALL);
+ race_SendRanking(pos, 0, 1, MSG_ALL);
if(pos == 1)
race_send_recordtime(MSG_ALL);
return false;
}
+void defrag_waypointsprites(entity targeted, entity checkpoint)
+{
+ for(entity t = findchain(target, targeted.targetname); t; t = t.chain)
+ {
+ if(t.modelindex)
+ {
+ entity s = WP_RaceStart;
+
+ if(checkpoint.classname == "target_checkpoint")
+ s = WP_RaceCheckpoint;
+ else if(checkpoint.classname == "target_stopTimer")
+ s = WP_RaceFinish;
+
+ vector o = (t.absmin + t.absmax) * 0.5;
+
+ WaypointSprite_SpawnFixed(s, o, t, sprite, RADARICON_NONE);
+
+ t.sprite.realowner = checkpoint;
+ t.sprite.waypointsprite_visible_for_player = race_waypointsprite_visible_for_player;
+ }
+
+ if(t.targetname)
+ defrag_waypointsprites(t, checkpoint);
+ }
+}
+
void trigger_race_checkpoint_verify(entity this)
{
- static bool have_verified;
+ static bool have_verified;
if (have_verified) return;
have_verified = true;
pl_race_place = 0;
if (!Spawn_FilterOutBadSpots(this, findchain(classname, "info_player_deathmatch"), 0, false, true)) {
error(strcat("Checkpoint ", ftos(i), " misses a spawnpoint with race_place==", ftos(pl_race_place), " (used for respawning in race) - bailing out"));
- }
+ }
if (i == 0) {
// qualifying only
pl_race_place = race_lowest_place_spawn;
if (!Spawn_FilterOutBadSpots(this, findchain(classname, "info_player_deathmatch"), 0, false, true)) {
error(strcat("Checkpoint ", ftos(i), " misses a spawnpoint with race_place==", ftos(pl_race_place), " (used for qualifying) - bailing out"));
- }
+ }
// race only (initial spawn)
g_race_qualifying = 0;
pl_race_place = p;
if (!Spawn_FilterOutBadSpots(this, findchain(classname, "info_player_deathmatch"), 0, false, true)) {
error(strcat("Checkpoint ", ftos(i), " misses a spawnpoint with race_place==", ftos(pl_race_place), " (used for initially spawning in race) - bailing out"));
- }
+ }
}
}
}
pl_race_place = race_lowest_place_spawn;
if (!Spawn_FilterOutBadSpots(this, findchain(classname, "info_player_deathmatch"), 0, false, true)) {
error(strcat("Checkpoint 0 misses a spawnpoint with race_place==", ftos(pl_race_place), " (used for qualifying) - bailing out"));
- }
+ }
} else {
pl_race_checkpoint = race_NextCheckpoint(0);
g_race_qualifying = 1;
for (entity cp = NULL; (cp = find(cp, classname, "target_checkpoint"));) {
if (argv(0) == cp.targetname) {
cp.race_checkpoint = stof(argv(1));
- }
- }
+ }
+ }
}
fclose(fh);
}
g_race_qualifying = qual;
- IL_EACH(g_race_targets, it.classname == "target_checkpoint" || it.classname == "target_startTimer" || it.classname == "target_stopTimer",
- {
- if(it.targetname == "" || !it.targetname) // somehow this is a case...
- continue;
- entity cpt = it;
- FOREACH_ENTITY_STRING(target, cpt.targetname,
- {
- vector org = (it.absmin + it.absmax) * 0.5;
- if(cpt.race_checkpoint == 0)
- WaypointSprite_SpawnFixed(WP_RaceStart, org, it, sprite, RADARICON_NONE);
- else
- WaypointSprite_SpawnFixed(WP_RaceCheckpoint, org, it, sprite, RADARICON_NONE);
-
- it.sprite.realowner = cpt;
- it.sprite.waypointsprite_visible_for_player = race_waypointsprite_visible_for_player;
- });
- });
-
if (race_timed_checkpoint) {
if (defrag_ents) {
IL_EACH(g_race_targets, it.classname == "target_checkpoint" || it.classname == "target_startTimer" || it.classname == "target_stopTimer",
{
- entity cpt = it;
- if(it.classname == "target_startTimer" || it.classname == "target_stopTimer") {
- if(it.targetname == "" || !it.targetname) // somehow this is a case...
- continue;
- FOREACH_ENTITY_STRING(target, cpt.targetname, {
- if(it.sprite)
- WaypointSprite_UpdateSprites(it.sprite, ((cpt.classname == "target_startTimer") ? WP_RaceStart : WP_RaceFinish), WP_Null, WP_Null);
- });
- }
+ defrag_waypointsprites(it, it);
+
if(it.classname == "target_checkpoint") {
if(it.race_checkpoint == -2)
defragcpexists = -1; // 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
for (entity cp = NULL; (cp = find(cp, classname, "target_checkpoint"));) {
if (cp.race_checkpoint > largest_cp_id) {
largest_cp_id = cp.race_checkpoint;
- }
- }
+ }
+ }
for (entity cp = NULL; (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 (entity cp = NULL; (cp = find(cp, classname, "target_stopTimer"));) {
cp.race_checkpoint = 255; // finish line
- }
+ }
race_highest_checkpoint = 255;
race_timed_checkpoint = 255;
}
{
if (it.race_checkpoint == 0) {
WaypointSprite_UpdateSprites(it.sprite, WP_RaceStart, WP_Null, WP_Null);
- } else if (it.race_checkpoint == race_timed_checkpoint) {
+ } else if (it.race_checkpoint == race_timed_checkpoint) {
WaypointSprite_UpdateSprites(it.sprite, WP_RaceFinish, WP_Null, WP_Null);
}
- });
+ });
}
}
- if (defrag_ents) {
+ if (defrag_ents) { /* The following hack shall be removed when per-player trigger_multiple.wait is implemented for cts */
for (entity trigger = NULL; (trigger = find(trigger, classname, "trigger_multiple")); ) {
for (entity targ = NULL; (targ = find(targ, targetname, trigger.target)); ) {
if (targ.classname == "target_checkpoint" || targ.classname == "target_startTimer" || targ.classname == "target_stopTimer") {
this.sprite.waypointsprite_visible_for_player = race_waypointsprite_visible_for_player;
this.spawn_evalfunc = trigger_race_checkpoint_spawn_evalfunc;
+ if (!g_racecheckpoints)
+ g_racecheckpoints = IL_NEW();
IL_PUSH(g_racecheckpoints, this);
+ // trigger_race_checkpoint_verify checks this list too
+ if (!g_race_targets)
+ g_race_targets = IL_NEW();
+
InitializeEntity(this, trigger_race_checkpoint_verify, INITPRIO_FINDTARGET);
}
race_timed_checkpoint = 1;
+ if (!g_race_targets)
+ g_race_targets = IL_NEW();
IL_PUSH(g_race_targets, this);
+ // trigger_race_checkpoint_verify checks this list too
+ if (!g_racecheckpoints)
+ g_racecheckpoints = IL_NEW();
+
InitializeEntity(this, trigger_race_checkpoint_verify, INITPRIO_FINDTARGET);
}