Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
race.qc File Reference
Include dependency graph for race.qc:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void checkpoint_passed (entity this, entity player)
void checkpoint_touch (entity this, entity toucher)
void checkpoint_use (entity this, entity actor, entity trigger)
void defrag_waypointsprites (entity targeted, entity checkpoint, int recursionlevel)
void penalty_touch (entity this, entity toucher)
void penalty_use (entity this, entity actor, entity trigger)
void race_AbandonRaceCheck (entity p)
void race_checkAndWriteName (entity player)
float race_CheckpointNetworkID (float f)
void race_ClearPlayerRecords (entity player)
void race_ClearRecords ()
void race_ClearTime (entity e)
void race_deleteTime (string map, float pos)
float race_GetFractionalLapCount (entity e)
void race_ImposePenaltyTime (entity pl, float penalty, string reason)
float race_NextCheckpoint (float f)
void race_PreparePlayer (entity this)
float race_PreviousCheckpoint (float f)
string race_readName (string map, float pos)
float race_readPos (string map, float t)
float race_readTime (string map, float pos)
string race_readUID (string map, float pos)
void race_RetractPlayer (entity this)
void race_send_rankings_cnt (float msg)
void race_send_recordtime (float msg)
void race_send_speedaward (float msg)
void race_send_speedaward_alltimebest (float msg)
void race_SendAll (entity player, bool only_rankings)
void race_SendNextCheckpoint (entity e, float spec)
void race_SendRanking (float pos, float prevpos, float del, float msg)
void race_SendStatus (float id, entity e)
void race_SendTime (entity e, float cp, float t, float tvalid)
void race_setTime (string map, float t, string myuid, string mynetname, entity e, bool showmessage)
void race_SpeedAwardFrame (entity player)
void race_StartCompleting ()
bool race_waypointsprite_visible_for_player (entity this, entity player, entity view)
void race_writeTime (string map, float t, string myuid)
 spawnfunc (info_player_race)
 spawnfunc (target_checkpoint)
 spawnfunc (target_startTimer)
 spawnfunc (target_stopTimer)
 spawnfunc (trigger_race_checkpoint)
 spawnfunc (trigger_race_penalty)
void target_checkpoint_setup (entity this)
vector trigger_race_checkpoint_spawn_evalfunc (entity this, entity player, entity spot, vector current)
void trigger_race_checkpoint_verify (entity this)
string uid2name (string myuid)
void write_recordmarker (entity pl, float tstart, float dt)

Variables

float defrag_ents
float defragcpexists
IntrusiveList g_race_targets
IntrusiveList g_racecheckpoints
const float MAX_CHECKPOINTS = 255
float race_checkpoint
float race_checkpoint_lastlaps [MAX_CHECKPOINTS]
entity race_checkpoint_lastplayers [MAX_CHECKPOINTS]
float race_checkpoint_lasttimes [MAX_CHECKPOINTS]
float race_checkpoint_record [MAX_CHECKPOINTS]
string race_checkpoint_recordholders [MAX_CHECKPOINTS]
float race_checkpoint_records [MAX_CHECKPOINTS]
float race_checkpoint_recordspeed [MAX_CHECKPOINTS]
float race_checkpoint_recordspeeds [MAX_CHECKPOINTS]
float race_highest_checkpoint
entity race_lastpenalty
float race_penalty
float race_penalty_accumulator
string race_penalty_reason
float race_timed_checkpoint
entity sprite
string stored_netname

Function Documentation

◆ checkpoint_passed()

void checkpoint_passed ( entity this,
entity player )

Definition at line 694 of file race.qc.

695{
696 if(IS_VEHICLE(player) && player.owner)
697 player = player.owner;
698
699 if(player.personal && autocvar_g_allow_checkpoints)
700 return; // practice mode!
701
702 if(player.classname == "porto")
703 {
704 // do not allow portalling through checkpoints
705 trace_plane_normal = normalize(-1 * player.velocity);
706 W_Porto_Fail(player, 0);
707 return;
708 }
709
710 string oldmsg; // used twice
711
712 /*
713 * Trigger targets
714 */
715 if (!((this.spawnflags & 2) && (IS_PLAYER(player))))
716 {
717 oldmsg = this.message;
718 this.message = "";
719 SUB_UseTargets(this, player, player);
720 this.message = oldmsg;
721 }
722
723 if (!IS_PLAYER(player))
724 return;
725
726 /*
727 * Remove unauthorized equipment
728 */
729 Portal_ClearAll(player);
730
731 player.porto_forbidden = 2; // decreased by 1 each StartFrame
732
733 if(defrag_ents)
734 {
735 if(this.race_checkpoint == -2)
736 {
737 // duplicate targetname target_checkpoints get the same cp nr
738 IL_EACH(g_race_targets, it.classname == "target_checkpoint" && it.targetname == this.targetname, {
739 if(it.race_checkpoint >= 0)
740 this.race_checkpoint = it.race_checkpoint;
741 });
742 if(this.race_checkpoint == -2)
743 this.race_checkpoint = player.race_checkpoint;
744 }
745
746 int cp_amount = 0, largest_cp_id = 0;
747 IL_EACH(g_race_targets, it.classname == "target_checkpoint",
748 {
749 ++cp_amount;
750 if(it.race_checkpoint > largest_cp_id) // update the finish id if someone hit a new checkpoint
751 {
752 if(!largest_cp_id)
753 {
754 IL_EACH(g_race_targets, it.classname == "target_checkpoint",
755 {
756 if(it.race_checkpoint == -2) // set defragcpexists to -1 so that the cp id file will be rewritten when someone finishes
757 defragcpexists = -1;
758 });
759 }
760
761 largest_cp_id = it.race_checkpoint;
762 IL_EACH(g_race_targets, it.classname == "target_stopTimer",
763 {
764 it.race_checkpoint = largest_cp_id + 1; // finish line
765 });
766 race_highest_checkpoint = largest_cp_id + 1;
767 race_timed_checkpoint = largest_cp_id + 1;
768 }
769 });
770
771 if(!cp_amount)
772 {
773 IL_EACH(g_race_targets, it.classname == "target_stopTimer",
774 {
775 it.race_checkpoint = 1;
776 });
779 }
780 }
781
782 if((player.race_checkpoint == -1 && this.race_checkpoint == 0) || (player.race_checkpoint == this.race_checkpoint))
783 {
784 if(this.race_penalty)
785 {
786 if(player.race_lastpenalty != this)
787 {
788 player.race_lastpenalty = this;
790 }
791 }
792
793 if(player.race_penalty)
794 return;
795
796 /*
797 * Trigger targets
798 */
799 if(this.spawnflags & 2)
800 {
801 oldmsg = this.message;
802 this.message = "";
803 SUB_UseTargets(this, player, player); // TODO: should we be using other for the trigger here?
804 this.message = oldmsg;
805 }
806
807 if(player.race_respawn_checkpoint != this.race_checkpoint || !player.race_started)
808 player.race_respawn_spotref = this; // this is not a spot but a CP, but spawnpoint selection will deal with that
809 player.race_respawn_checkpoint = this.race_checkpoint;
810 player.race_checkpoint = race_NextCheckpoint(this.race_checkpoint);
811 player.race_started = 1;
812
813 race_SendTime(player, this.race_checkpoint, player.race_movetime, boolean(player.race_laptime));
814
815 if(!this.race_checkpoint) // start line
816 {
817 player.race_laptime = time;
818 player.race_movetime = player.race_movetime_frac = player.race_movetime_count = 0;
819 player.race_penalty_accumulator = 0;
820 player.race_lastpenalty = NULL;
821 }
822
824 race_SendNextCheckpoint(player, 0);
825
826 if(defrag_ents && defragcpexists < 0 && this.classname == "target_stopTimer")
827 {
828 float fh;
829 defragcpexists = fh = fopen(strcat("maps/", GetMapname(), ".defragcp"), FILE_WRITE);
830 if(fh >= 0)
831 {
832 IL_EACH(g_race_targets, it.classname == "target_checkpoint",
833 {
834 fputs(fh, strcat(it.targetname, " ", ftos(it.race_checkpoint), "\n"));
835 });
836 }
837 fclose(fh);
838 }
839 }
840 else if(player.race_checkpoint == race_NextCheckpoint(this.race_checkpoint))
841 {
842 // ignored
843 }
844 else
845 {
846 if(this.spawnflags & 4)
847 Damage (player, this, this, 10000, DEATH_HURTTRIGGER.m_id, DMG_NOWEP, player.origin, '0 0 0');
848 }
849}
string message
Definition powerups.qc:19
int spawnflags
Definition ammo.qh:15
float race_penalty
Definition player.qh:59
#define IS_PLAYER(s)
Definition player.qh:242
string classname
const float FILE_WRITE
float time
vector trace_plane_normal
void Damage(entity targ, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
Definition damage.qc:493
#define DMG_NOWEP
Definition damage.qh:104
string GetMapname()
#define IL_EACH(this, cond, body)
void SUB_UseTargets(entity this, entity actor, entity trigger)
Definition triggers.qc:344
void fclose(float fhandle)
float fopen(string filename, float mode)
vector normalize(vector v)
strcat(_("^F4Countdown stopped!"), "\n^BG", _("Teams are too unbalanced."))
void Portal_ClearAll(entity own)
Definition portals.qc:586
void W_Porto_Fail(entity this, bool failhard)
Definition porto.qc:114
#define NULL
Definition post.qh:14
float race_checkpoint
Definition racetimer.qh:8
float race_highest_checkpoint
Definition race.qc:168
string race_penalty_reason
Definition race.qc:152
void race_SendNextCheckpoint(entity e, float spec)
Definition race.qc:208
float race_timed_checkpoint
Definition race.qc:169
float defragcpexists
Definition race.qc:172
void race_SendTime(entity e, float cp, float t, float tvalid)
Definition race.qc:485
float defrag_ents
Definition race.qc:171
float race_NextCheckpoint(float f)
Definition race.qc:174
IntrusiveList g_race_targets
Definition race.qc:66
void race_ImposePenaltyTime(entity pl, float penalty, string reason)
Definition race.qc:1275
bool autocvar_g_allow_checkpoints
Definition race.qh:3
int g_race_qualifying
Definition race.qh:13
#define IS_VEHICLE(v)
Definition utils.qh:24

References autocvar_g_allow_checkpoints, defrag_ents, entity(), g_race_targets, IL_EACH, IS_PLAYER, IS_VEHICLE, message, normalize(), Portal_ClearAll(), race_checkpoint, race_highest_checkpoint, race_timed_checkpoint, spawnflags, SUB_UseTargets(), trace_plane_normal, and W_Porto_Fail().

Referenced by checkpoint_touch(), and checkpoint_use().

◆ checkpoint_touch()

void checkpoint_touch ( entity this,
entity toucher )

Definition at line 851 of file race.qc.

852{
855}
#define EXACTTRIGGER_TOUCH(e, t)
Definition common.qh:115
entity entity toucher
Definition self.qh:72
void checkpoint_passed(entity this, entity player)
Definition race.qc:694

References checkpoint_passed(), entity(), EXACTTRIGGER_TOUCH, and toucher.

Referenced by spawnfunc(), and target_checkpoint_setup().

◆ checkpoint_use()

void checkpoint_use ( entity this,
entity actor,
entity trigger )

Definition at line 857 of file race.qc.

858{
859 if(trigger.classname == "info_player_deathmatch") // a spawn, a spawn
860 return;
861
862 checkpoint_passed(this, actor);
863}

References checkpoint_passed(), and entity().

Referenced by spawnfunc(), and target_checkpoint_setup().

◆ defrag_waypointsprites()

void defrag_waypointsprites ( entity targeted,
entity checkpoint,
int recursionlevel )

Definition at line 879 of file race.qc.

880{
881 // bones_was_here: spawn a waypoint for every entity with a bmodel
882 // that directly or indirectly targets this checkpoint
883 // (anything a player could touch or shoot to activate this cp)
884
885 // spam a few warnings so that larger link chain loops can be found
886 if (recursionlevel > 400)
887 {
888 LOG_WARNF("df cp wp loop: ^4\"target\" ^3\"%s\"^7, ^4\"targetname\" ^3\"%s\"^7",
889 targeted.classname,
890 targeted.targetname);
891 }
892 // avoid a stack overflow
893 if (recursionlevel > 420)
894 {
895 LOG_WARNF("Aborted creating defrag checkpoint waypointsprites for ^2%s^7 due to a loop",
896 checkpoint.classname);
897 return;
898 }
899
900 entity s = WP_RaceCheckpoint;
901 if (checkpoint.classname == "target_startTimer")
902 s = WP_RaceStart;
903 else if (checkpoint.classname == "target_stopTimer")
904 s = WP_RaceFinish;
905
906 for (entity t = findchain(target, targeted.targetname); t; t = t.chain)
907 {
908 if (t.modelindex)
909 {
910 WaypointSprite_SpawnFixed(s, (t.absmin + t.absmax) * 0.5, t, sprite, RADARICON_NONE);
911 t.sprite.realowner = checkpoint;
912 t.sprite.waypointsprite_visible_for_player = race_waypointsprite_visible_for_player;
913 }
914
915 if (t.targetname && t != checkpoint)
916 defrag_waypointsprites(t, checkpoint, ++recursionlevel);
917 }
918}
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
#define LOG_WARNF(...)
Definition log.qh:62
bool race_waypointsprite_visible_for_player(entity this, entity player, entity view)
Definition race.qc:865
void defrag_waypointsprites(entity targeted, entity checkpoint, int recursionlevel)
Definition race.qc:879
entity sprite
Definition sv_assault.qc:11
string target
Definition triggers.qh:55
entity WaypointSprite_SpawnFixed(entity spr, vector ofs, entity own,.entity ownfield, entity icon)

References defrag_waypointsprites(), entity(), LOG_WARNF, race_waypointsprite_visible_for_player(), sprite, target, and WaypointSprite_SpawnFixed().

Referenced by defrag_waypointsprites().

◆ penalty_touch()

void penalty_touch ( entity this,
entity toucher )

Definition at line 1307 of file race.qc.

1308{
1310 if(toucher.race_lastpenalty != this)
1311 {
1312 toucher.race_lastpenalty = this;
1314 }
1315}

References entity(), EXACTTRIGGER_TOUCH, race_ImposePenaltyTime(), race_penalty, race_penalty_reason, and toucher.

Referenced by spawnfunc().

◆ penalty_use()

void penalty_use ( entity this,
entity actor,
entity trigger )

Definition at line 1317 of file race.qc.

1318{
1320}

References entity(), race_ImposePenaltyTime(), race_penalty, and race_penalty_reason.

Referenced by spawnfunc().

◆ race_AbandonRaceCheck()

void race_AbandonRaceCheck ( entity p)

Definition at line 1203 of file race.qc.

1204{
1206 {
1207 CS(p).race_completed = 1;
1209 Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_RACE_ABANDONED, p.netname);
1210 ClientData_Touch(p, true);
1211 }
1212}
void Send_Notification(NOTIF broadcast, entity client, MSG net_type, Notification net_name,...count)
Definition all.qc:1573
void ClientData_Touch(entity e, bool to_spectators_too)
Definition client.qc:185
#define MAKE_INDEPENDENT_PLAYER(e)
Definition client.qh:313
float race_completed
Definition race.qh:26
float race_completing
Definition race.qh:28
ClientState CS(Client this)
Definition state.qh:47

References ClientData_Touch(), CS(), entity(), MAKE_INDEPENDENT_PLAYER, NULL, race_completed, race_completing, and Send_Notification().

Referenced by MUTATOR_HOOKFUNCTION(), MUTATOR_HOOKFUNCTION(), MUTATOR_HOOKFUNCTION(), MUTATOR_HOOKFUNCTION(), and race_StartCompleting().

◆ race_checkAndWriteName()

void race_checkAndWriteName ( entity player)

Definition at line 133 of file race.qc.

134{
135 if(CS_CVAR(player).cvar_cl_allow_uidtracking == 1 && CS_CVAR(player).cvar_cl_allow_uid2name == 1)
136 {
137 if (!player.stored_netname)
138 player.stored_netname = strzone(uid2name(player.crypto_idfp));
139 if(player.stored_netname != player.netname)
140 {
141 db_put(ServerProgsDB, strcat("/uid2name/", player.crypto_idfp), player.netname);
142 strcpy(player.stored_netname, player.netname);
143 }
144 }
145}
ERASEABLE void db_put(int db, string key, string value)
Definition map.qh:101
string strzone(string s)
string uid2name(string myuid)
Definition race.qc:36
#define CS_CVAR(this)
Definition state.qh:51
#define strcpy(this, s)
Definition string.qh:52
float ServerProgsDB
Definition world.qh:128

References CS_CVAR, db_put(), entity(), ServerProgsDB, strcat(), strcpy, strzone(), and uid2name().

Referenced by MUTATOR_HOOKFUNCTION(), MUTATOR_HOOKFUNCTION(), and MUTATOR_HOOKFUNCTION().

◆ race_CheckpointNetworkID()

float race_CheckpointNetworkID ( float f)

Definition at line 196 of file race.qc.

197{
199 {
200 if(f == 0)
201 return 254; // start
202 else if(f == race_timed_checkpoint)
203 return 255; // finish
204 }
205 return f;
206}

References race_timed_checkpoint.

Referenced by race_SendNextCheckpoint(), and race_SendTime().

◆ race_ClearPlayerRecords()

void race_ClearPlayerRecords ( entity player)

Definition at line 1250 of file race.qc.

1251{
1252 for(int i = 0; i < MAX_CHECKPOINTS; ++i)
1253 {
1254 player.race_checkpoint_record[i] = 0;
1255 player.race_checkpoint_recordspeed[i] = 0;
1256 }
1257}
const float MAX_CHECKPOINTS
Definition race.qc:148

References entity(), and MAX_CHECKPOINTS.

Referenced by ClientCommand_clear_bestcptimes().

◆ race_ClearRecords()

void race_ClearRecords ( )

Definition at line 1259 of file race.qc.

1260{
1261 for(int j = 0; j < MAX_CHECKPOINTS; ++j)
1262 {
1266 }
1267
1268 FOREACH_CLIENT(true, {
1269 float p = it.race_place;
1271 it.race_place = p;
1272 });
1273}
float race_checkpoint_recordspeeds[MAX_CHECKPOINTS]
Definition race.qc:159
void race_PreparePlayer(entity this)
Definition race.qc:1220
float race_checkpoint_records[MAX_CHECKPOINTS]
Definition race.qc:158
string race_checkpoint_recordholders[MAX_CHECKPOINTS]
Definition race.qc:160
#define strfree(this)
Definition string.qh:59
#define FOREACH_CLIENT(cond, body)
Definition utils.qh:52

References FOREACH_CLIENT, MAX_CHECKPOINTS, race_checkpoint_recordholders, race_checkpoint_records, race_checkpoint_recordspeeds, race_PreparePlayer(), and strfree.

Referenced by MUTATOR_HOOKFUNCTION(), and MUTATOR_HOOKFUNCTION().

◆ race_ClearTime()

void race_ClearTime ( entity e)

Definition at line 676 of file race.qc.

677{
678 e.race_checkpoint = 0;
679 e.race_laptime = 0;
680 e.race_movetime = e.race_movetime_frac = e.race_movetime_count = 0;
681 e.race_penalty_accumulator = 0;
682 e.race_lastpenalty = NULL;
683
684 if(!IS_REAL_CLIENT(e))
685 return;
686
687 msg_entity = e;
688 WRITESPECTATABLE_MSG_ONE(msg_entity, {
689 WriteHeader(MSG_ONE, TE_CSQC_RACE);
691 });
692}
#define WriteHeader(to, id)
Definition net.qh:265
float MSG_ONE
Definition menudefs.qc:56
void WriteByte(float data, float dest, float desto)
@ RACE_NET_CHECKPOINT_CLEAR
Definition net_linked.qh:15
entity msg_entity
Definition progsdefs.qc:63
#define IS_REAL_CLIENT(v)
Definition utils.qh:17

References entity(), IS_REAL_CLIENT, msg_entity, MSG_ONE, NULL, RACE_NET_CHECKPOINT_CLEAR, WriteByte(), and WriteHeader.

Referenced by race_PreparePlayer(), and race_RetractPlayer().

◆ race_deleteTime()

void race_deleteTime ( string map,
float pos )

Definition at line 461 of file race.qc.

462{
463 for(int i = pos; i <= RANKINGS_CNT; ++i)
464 {
465 string therank = ftos(i);
466 if (i == RANKINGS_CNT)
467 {
468 db_remove(ServerProgsDB, strcat(map, record_type, "time", therank));
469 db_remove(ServerProgsDB, strcat(map, record_type, "crypto_idfp", therank));
470 }
471 else
472 {
473 db_put(ServerProgsDB, strcat(map, record_type, "time", therank), ftos(race_readTime(GetMapname(), i+1)));
474 db_put(ServerProgsDB, strcat(map, record_type, "crypto_idfp", therank), race_readUID(GetMapname(), i+1));
475 }
476 }
477
478 race_SendRanking(pos, 0, 1, MSG_ALL);
479 if(pos == 1)
481
483}
string rankings_reply
Definition util.qh:161
const int RANKINGS_CNT
Definition constants.qh:31
string getrankings()
Definition getreplies.qc:46
#define db_remove(db, key)
Definition map.qh:98
string ftos(float f)
float MSG_ALL
Definition menudefs.qc:57
void race_SendRanking(float pos, float prevpos, float del, float msg)
Definition race.qc:293
float race_readTime(string map, float pos)
Definition race.qc:69
void race_send_recordtime(float msg)
Definition race.qc:259
string race_readUID(string map, float pos)
Definition race.qc:74
string record_type
Definition world.qh:55

References db_put(), db_remove, ftos(), GetMapname(), getrankings(), MSG_ALL, race_readTime(), race_readUID(), race_send_recordtime(), race_SendRanking(), RANKINGS_CNT, rankings_reply, record_type, ServerProgsDB, strcat(), and strcpy.

Referenced by GameCommand_delrec().

◆ race_GetFractionalLapCount()

float race_GetFractionalLapCount ( entity e)

Definition at line 1339 of file race.qc.

1340{
1341 // interesting metrics (idea by KrimZon) to maybe sort players in the
1342 // scoreboard, immediately updates when overtaking
1343 //
1344 // requires the track to be built so you never get farther away from the
1345 // next checkpoint, though, and current Xonotic race maps are not built that
1346 // way
1347 //
1348 // also, this code is slow and would need optimization (i.e. "next CP"
1349 // links on CP entities)
1350
1351 float l = GameRules_scoring_add(e, RACE_LAPS, 0);
1352 if(CS(e).race_completed)
1353 return l; // not fractional
1354
1355 vector o0, o1;
1356 float bestfraction, fraction;
1357 entity lastcp;
1358 float nextcpindex, lastcpindex;
1359
1360 nextcpindex = max(e.race_checkpoint, 0);
1361 lastcpindex = e.race_respawn_checkpoint;
1362 lastcp = e.race_respawn_spotref;
1363
1364 if(nextcpindex == lastcpindex)
1365 return l; // finish
1366
1367 bestfraction = 1;
1369 {
1370 if(it.race_checkpoint != lastcpindex)
1371 continue;
1372 if(lastcp)
1373 if(it != lastcp)
1374 continue;
1375 o0 = (it.absmin + it.absmax) * 0.5;
1377 {
1378 if(it.race_checkpoint != nextcpindex)
1379 continue;
1380 o1 = (it.absmin + it.absmax) * 0.5;
1381 if(o0 == o1)
1382 continue;
1383 fraction = bound(0.0001, vlen(e.origin - o1) / vlen(o0 - o1), 1);
1384 if(fraction < bestfraction)
1385 bestfraction = fraction;
1386 });
1387 });
1388
1389 // we are at CP "nextcpindex - bestfraction"
1390 // race_timed_checkpoint == 4: then nextcp==4 means 0.9999x, nextcp==0 means 0.0000x
1391 // race_timed_checkpoint == 0: then nextcp==0 means 0.9999x
1392 float c, nc;
1393 nc = race_highest_checkpoint + 1;
1394 c = ((nextcpindex - race_timed_checkpoint + nc + nc - 1) % nc) + 1 - bestfraction;
1395
1396 return l + c / nc;
1397}
float bound(float min, float value, float max)
float vlen(vector v)
float max(float f,...)
vector
Definition self.qh:92
IntrusiveList g_racecheckpoints
Definition race.qc:67
#define GameRules_scoring_add(client, fld, value)
Definition sv_rules.qh:85

References bound(), CS(), entity(), g_racecheckpoints, GameRules_scoring_add, IL_EACH, max(), race_completed, race_highest_checkpoint, race_timed_checkpoint, vector, and vlen().

◆ race_ImposePenaltyTime()

void race_ImposePenaltyTime ( entity pl,
float penalty,
string reason )

Definition at line 1275 of file race.qc.

1276{
1278 {
1279 pl.race_penalty_accumulator += penalty;
1280 if(IS_REAL_CLIENT(pl))
1281 {
1282 msg_entity = pl;
1283 WRITESPECTATABLE_MSG_ONE(msg_entity, {
1284 WriteHeader(MSG_ONE, TE_CSQC_RACE);
1286 WriteShort(MSG_ONE, TIME_ENCODE(penalty));
1287 WriteString(MSG_ONE, reason);
1288 });
1289 }
1290 }
1291 else
1292 {
1293 pl.race_penalty = time + penalty;
1294 if(IS_REAL_CLIENT(pl))
1295 {
1296 msg_entity = pl;
1297 WRITESPECTATABLE_MSG_ONE(msg_entity, {
1298 WriteHeader(MSG_ONE, TE_CSQC_RACE);
1300 WriteShort(MSG_ONE, TIME_ENCODE(penalty));
1301 WriteString(MSG_ONE, reason);
1302 });
1303 }
1304 }
1305}
#define TIME_ENCODE(t)
Definition util.qh:100
void WriteString(string data, float dest, float desto)
void WriteShort(float data, float dest, float desto)
@ RACE_NET_PENALTY_QUALIFYING
Definition net_linked.qh:21
@ RACE_NET_PENALTY_RACE
Definition net_linked.qh:20

References entity(), g_race_qualifying, IS_REAL_CLIENT, msg_entity, MSG_ONE, RACE_NET_PENALTY_QUALIFYING, RACE_NET_PENALTY_RACE, time, TIME_ENCODE, WriteByte(), WriteHeader, WriteShort(), and WriteString().

Referenced by CheatCommand(), penalty_touch(), and penalty_use().

◆ race_NextCheckpoint()

float race_NextCheckpoint ( float f)

Definition at line 174 of file race.qc.

175{
177 return 0;
178 else
179 return f + 1;
180}

References race_highest_checkpoint.

Referenced by havocbot_role_cts(), havocbot_role_race(), and trigger_race_checkpoint_verify().

◆ race_PreparePlayer()

void race_PreparePlayer ( entity this)

◆ race_PreviousCheckpoint()

float race_PreviousCheckpoint ( float f)

Definition at line 182 of file race.qc.

183{
184 if(f == -1)
185 return 0;
186 else if(f == 0)
188 else
189 return f - 1;
190}

References race_highest_checkpoint.

◆ race_readName()

string race_readName ( string map,
float pos )

Definition at line 128 of file race.qc.

129{
130 return uid2name(db_get(ServerProgsDB, strcat(map, record_type, "crypto_idfp", ftos(pos))));
131}
ERASEABLE string db_get(int db, string key)
Definition map.qh:91

References db_get(), ftos(), record_type, ServerProgsDB, strcat(), and uid2name().

Referenced by getrankings(), MUTATOR_HOOKFUNCTION(), MUTATOR_HOOKFUNCTION(), race_SendRanking(), and race_setTime().

◆ race_readPos()

float race_readPos ( string map,
float t )

Definition at line 79 of file race.qc.

80{
81 for(int i = 1; i <= RANKINGS_CNT; ++i)
82 {
83 int mytime = race_readTime(map, i);
84 if(!mytime || mytime > t)
85 return i;
86 }
87
88 return 0; // pos is zero if unranked
89}

References race_readTime(), and RANKINGS_CNT.

Referenced by race_setTime(), and race_writeTime().

◆ race_readTime()

float race_readTime ( string map,
float pos )

◆ race_readUID()

string race_readUID ( string map,
float pos )

Definition at line 74 of file race.qc.

75{
76 return db_get(ServerProgsDB, strcat(map, record_type, "crypto_idfp", ftos(pos)));
77}

References db_get(), ftos(), record_type, ServerProgsDB, and strcat().

Referenced by getladder(), race_deleteTime(), race_setTime(), and race_writeTime().

◆ race_RetractPlayer()

void race_RetractPlayer ( entity this)

Definition at line 1229 of file race.qc.

1230{
1231 if(!g_race && !g_cts)
1232 return;
1234 race_ClearTime(this);
1236}
#define g_race
Definition race.qh:48
#define g_cts
Definition cts.qh:36

References entity(), g_cts, g_race, race_checkpoint, race_ClearTime(), race_respawn_checkpoint, and race_timed_checkpoint.

Referenced by MUTATOR_HOOKFUNCTION(), and MUTATOR_HOOKFUNCTION().

◆ race_send_rankings_cnt()

void race_send_rankings_cnt ( float msg)

Definition at line 285 of file race.qc.

286{
287 WriteHeader(msg, TE_CSQC_RACE);
290 WriteByte(msg, m);
291}
float min(float f,...)
@ RACE_NET_RANKINGS_CNT
Definition net_linked.qh:29
int autocvar_g_cts_send_rankings_cnt
Definition race.qh:10

References autocvar_g_cts_send_rankings_cnt, min(), RACE_NET_RANKINGS_CNT, RANKINGS_CNT, WriteByte(), and WriteHeader.

Referenced by race_SendAll().

◆ race_send_recordtime()

void race_send_recordtime ( float msg)

Definition at line 259 of file race.qc.

260{
261 // send the server best time
262 WriteHeader(msg, TE_CSQC_RACE);
264 WriteInt24_t(msg, race_readTime(GetMapname(), 1));
265}
@ RACE_NET_SERVER_RECORD
Definition net_linked.qh:22

References GetMapname(), RACE_NET_SERVER_RECORD, race_readTime(), WriteByte(), and WriteHeader.

Referenced by race_deleteTime(), race_SendAll(), and race_setTime().

◆ race_send_speedaward()

void race_send_speedaward ( float msg)

Definition at line 267 of file race.qc.

268{
269 // send the best speed of the round
270 WriteHeader(msg, TE_CSQC_RACE);
272 WriteInt24_t(msg, floor(speedaward_speed+0.5));
274}
float floor(float f)
@ RACE_NET_SPEED_AWARD
Definition net_linked.qh:23
float speedaward_speed
Definition race.qh:59
string speedaward_holder
Definition race.qh:60

References floor(), RACE_NET_SPEED_AWARD, speedaward_holder, speedaward_speed, WriteByte(), WriteHeader, and WriteString().

Referenced by race_SendAll(), and race_SpeedAwardFrame().

◆ race_send_speedaward_alltimebest()

void race_send_speedaward_alltimebest ( float msg)

Definition at line 276 of file race.qc.

277{
278 // send the best speed
279 WriteHeader(msg, TE_CSQC_RACE);
281 WriteInt24_t(msg, floor(speedaward_alltimebest+0.5));
283}
@ RACE_NET_SPEED_AWARD_BEST
Definition net_linked.qh:24
float speedaward_alltimebest
Definition race.qh:63
string speedaward_alltimebest_holder
Definition race.qh:64

References floor(), RACE_NET_SPEED_AWARD_BEST, speedaward_alltimebest, speedaward_alltimebest_holder, WriteByte(), WriteHeader, and WriteString().

Referenced by race_SendAll(), and race_SpeedAwardFrame().

◆ race_SendAll()

◆ race_SendNextCheckpoint()

void race_SendNextCheckpoint ( entity e,
float spec )

Definition at line 208 of file race.qc.

209{
210 if(!e.race_laptime)
211 return;
212
213 int cp = e.race_checkpoint;
214 float recordtime;
215 float recordspeed;
216 float myrecordtime = e.race_checkpoint_record[cp];
217 float myrecordspeed = e.race_checkpoint_recordspeed[cp];
218 string recordholder;
220 recordtime = myrecordtime;
221 recordspeed = myrecordspeed;
222 recordholder = "";
223 } else {
224 recordtime = race_checkpoint_records[cp];
225 recordspeed = race_checkpoint_recordspeeds[cp];
226 recordholder = race_checkpoint_recordholders[cp];
227
228 if(recordholder == e.netname)
229 recordholder = "";
230 }
231
232 if(!IS_REAL_CLIENT(e))
233 return;
234
235 if(!spec)
236 msg_entity = e;
237 WRITESPECTATABLE_MSG_ONE(msg_entity, {
238 WriteHeader(MSG_ONE, TE_CSQC_RACE);
239 if(spec)
240 {
242 //WriteCoord(MSG_ONE, e.race_laptime - e.race_penalty_accumulator);
243 WriteCoord(MSG_ONE, time - e.race_movetime - e.race_penalty_accumulator);
244 }
245 else
247 WriteByte(MSG_ONE, race_CheckpointNetworkID(cp)); // checkpoint the player will be at next
248 WriteInt24_t(MSG_ONE, recordtime);
249 if(!spec)
250 WriteInt24_t(MSG_ONE, myrecordtime);
251 WriteString(MSG_ONE, recordholder);
252 // All speeds networked as floats to have decimal precision
253 WriteFloat(MSG_ONE, recordspeed);
254 if(!spec)
255 WriteFloat(MSG_ONE, myrecordspeed);
256 });
257}
void WriteCoord(float data, float dest, float desto)
@ RACE_NET_CHECKPOINT_NEXT_QUALIFYING
Definition net_linked.qh:16
@ RACE_NET_CHECKPOINT_NEXT_SPEC_QUALIFYING
Definition net_linked.qh:19
float race_CheckpointNetworkID(float f)
Definition race.qc:196
bool autocvar_g_race_cptimes_onlyself
Definition race.qh:11

References autocvar_g_race_cptimes_onlyself, entity(), IS_REAL_CLIENT, msg_entity, MSG_ONE, race_checkpoint_recordholders, race_checkpoint_records, race_checkpoint_recordspeeds, race_CheckpointNetworkID(), RACE_NET_CHECKPOINT_NEXT_QUALIFYING, RACE_NET_CHECKPOINT_NEXT_SPEC_QUALIFYING, time, WriteByte(), WriteCoord(), WriteHeader, and WriteString().

Referenced by SetSpectatee_status().

◆ race_SendRanking()

void race_SendRanking ( float pos,
float prevpos,
float del,
float msg )

Definition at line 293 of file race.qc.

294{
295 WriteHeader(msg, TE_CSQC_RACE);
297 WriteShort(msg, pos);
298 WriteShort(msg, prevpos);
299 WriteShort(msg, del);
301 WriteInt24_t(msg, race_readTime(GetMapname(), pos));
302}
@ RACE_NET_SERVER_RANKINGS
Definition net_linked.qh:25
string race_readName(string map, float pos)
Definition race.qc:128

References GetMapname(), RACE_NET_SERVER_RANKINGS, race_readName(), race_readTime(), WriteByte(), WriteHeader, WriteShort(), and WriteString().

Referenced by race_deleteTime(), race_SendAll(), and race_setTime().

◆ race_SendStatus()

void race_SendStatus ( float id,
entity e )

Definition at line 354 of file race.qc.

355{
356 if(!IS_REAL_CLIENT(e))
357 return;
358
359 float msg;
360 if (id == 0)
361 msg = MSG_ONE;
362 else
363 msg = MSG_ALL;
364 msg_entity = e;
365 WRITESPECTATABLE_MSG_ONE(msg_entity, {
366 WriteHeader(msg, TE_CSQC_RACE);
368 WriteShort(msg, id);
369 WriteString(msg, e.netname);
370 });
371}
@ RACE_NET_SERVER_STATUS
Definition net_linked.qh:26

References entity(), IS_REAL_CLIENT, MSG_ALL, msg_entity, MSG_ONE, RACE_NET_SERVER_STATUS, WriteByte(), WriteHeader, WriteShort(), and WriteString().

Referenced by race_setTime().

◆ race_SendTime()

void race_SendTime ( entity e,
float cp,
float t,
float tvalid )

Definition at line 485 of file race.qc.

486{
488 t += e.race_penalty_accumulator;
489
490 t = TIME_ENCODE(t); // make integer
491
492 if(tvalid)
493 if(cp == race_timed_checkpoint) // finish line
494 if (!CS(e).race_completed)
495 {
496 int s = GameRules_scoring_add(e, RACE_FASTEST, 0);
497 if(!s || t < s)
498 GameRules_scoring_add(e, RACE_FASTEST, t - s);
500 {
501 s = GameRules_scoring_add(e, RACE_TIME, 0);
502 int snew = TIME_ENCODE(time - game_starttime);
503 GameRules_scoring_add(e, RACE_TIME, snew - s);
504 int l = GameRules_scoring_add_team(e, RACE_LAPS, 1);
505
507 if(l >= autocvar_fraglimit)
509
511 {
512 CS(e).race_completed = 1;
514 if(e.bot_attack)
516 e.bot_attack = false;
517 Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_RACE_FINISHED, e.netname);
518 ClientData_Touch(e, true);
519 }
520 }
521 }
522
524 {
525 float recordtime;
526 float recordtimespeed;
527 string recordholder;
528
529 if(tvalid)
530 {
532 {
533 // return their own checkpoint time
534 recordtime = e.race_checkpoint_record[cp];
535 recordtimespeed = e.race_checkpoint_recordspeed[cp];
536 recordholder = "";
537 }
538 else
539 {
540 recordtime = race_checkpoint_records[cp];
541 recordtimespeed = race_checkpoint_recordspeeds[cp];
542 // make a tempstring copy, as we'll possibly strunzone it
543 recordholder = strcat(race_checkpoint_recordholders[cp]);
544
545 if(recordholder == e.netname)
546 recordholder = "";
547 }
548
549 if(t != 0)
550 {
551 if(cp == race_timed_checkpoint)
552 {
553 race_setTime(GetMapname(), t, e.crypto_idfp, e.netname, e, true);
554 MUTATOR_CALLHOOK(Race_FinalCheckpoint, e);
555 }
556
557 if(t < recordtime || recordtime == 0)
558 {
560 race_checkpoint_recordspeeds[cp] = vlen(vec2(e.velocity));
563 FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it) && it.race_checkpoint == cp, { race_SendNextCheckpoint(it, 0); });
564 }
565
566 }
567 }
568 else
569 {
570 // dummies
571 t = 0;
572 recordtime = 0;
573 recordtimespeed = 0;
574 recordholder = "";
575 }
576
577 if(IS_REAL_CLIENT(e))
578 {
580 {
582 {
583 if(it == e || (IS_SPEC(it) && it.enemy == e))
584 {
585 msg_entity = it;
586 WriteHeader(MSG_ONE, TE_CSQC_RACE);
588 WriteByte(MSG_ONE, race_CheckpointNetworkID(cp)); // checkpoint the player now is at
589 WriteInt24_t(MSG_ONE, t); // time to that checkpoint
590 WriteInt24_t(MSG_ONE, recordtime); // previously best time
591 WriteInt24_t(MSG_ONE, ((tvalid) ? it.race_checkpoint_record[cp] : 0)); // previously best time
592 WriteString(MSG_ONE, recordholder); // record holder
593 // All speeds networked as floats to have decimal precision
594 WriteFloat(MSG_ONE, vlen(vec2(e.velocity))); // speed of cp hit
595 WriteFloat(MSG_ONE, recordtimespeed); // speed of previous best cp hit
596 WriteFloat(MSG_ONE, ((tvalid) ? it.race_checkpoint_recordspeed[cp] : 0)); // speed of my previous best cp hit
597 }
598 });
599 }
600 }
601 // check if new pb should be set for a checkpoint
602 if(tvalid)
603 {
604 float myrecordtime = e.race_checkpoint_record[cp];
605 if(t != 0)
606 if(t < myrecordtime || myrecordtime == 0)
607 {
608 e.race_checkpoint_record[cp] = t;
609 e.race_checkpoint_recordspeed[cp] = vlen(vec2(e.velocity));
610 }
611 }
612 }
613 else // RACE! Not Qualifying
614 {
615 float mylaps, lother, othtime;
617 if(oth)
618 {
619 mylaps = GameRules_scoring_add(e, RACE_LAPS, 0);
620 lother = race_checkpoint_lastlaps[cp];
621 othtime = race_checkpoint_lasttimes[cp];
622 }
623 else
624 mylaps = lother = othtime = 0;
625
626 if(IS_REAL_CLIENT(e))
627 {
628 msg_entity = e;
629 WRITESPECTATABLE_MSG_ONE(msg_entity, {
630 WriteHeader(MSG_ONE, TE_CSQC_RACE);
632 WriteByte(MSG_ONE, race_CheckpointNetworkID(cp)); // checkpoint the player now is at
633 if(e == oth)
634 {
635 WriteInt24_t(MSG_ONE, 0);
636 WriteByte(MSG_ONE, 0);
637 WriteByte(MSG_ONE, 0);
638 }
639 else
640 {
642 WriteByte(MSG_ONE, mylaps - lother);
643 WriteByte(MSG_ONE, etof(oth)); // record holder
644 }
645 });
646 }
647
650 race_checkpoint_lastlaps[cp] = mylaps;
651
652 if(IS_REAL_CLIENT(oth))
653 {
654 msg_entity = oth;
655 WRITESPECTATABLE_MSG_ONE(msg_entity, {
656 WriteHeader(MSG_ONE, TE_CSQC_RACE);
658 WriteByte(MSG_ONE, race_CheckpointNetworkID(cp)); // checkpoint the player now is at
659 if(e == oth)
660 {
661 WriteInt24_t(MSG_ONE, 0);
662 WriteByte(MSG_ONE, 0);
663 WriteByte(MSG_ONE, 0);
664 }
665 else
666 {
667 WriteInt24_t(MSG_ONE, TIME_ENCODE(time - othtime));
668 WriteByte(MSG_ONE, lother - mylaps);
669 WriteByte(MSG_ONE, etof(e) - 1); // record holder
670 }
671 });
672 }
673 }
674}
IntrusiveList g_bot_targets
Definition api.qh:149
#define MUTATOR_CALLHOOK(id,...)
Definition base.qh:143
#define autocvar_fraglimit
Definition stats.qh:90
float game_starttime
Definition stats.qh:82
ERASEABLE void IL_REMOVE(IntrusiveList this, entity it)
Remove any element, anywhere in the list.
#define etof(e)
Definition misc.qh:25
@ RACE_NET_CHECKPOINT_HIT_RACE_BY_OPPONENT
Definition net_linked.qh:18
@ RACE_NET_CHECKPOINT_HIT_RACE
Definition net_linked.qh:17
@ RACE_NET_CHECKPOINT_HIT_QUALIFYING
Definition net_linked.qh:14
float race_checkpoint_lastlaps[MAX_CHECKPOINTS]
Definition race.qc:162
void race_StartCompleting()
Definition race.qc:1214
entity race_checkpoint_lastplayers[MAX_CHECKPOINTS]
Definition race.qc:163
void race_setTime(string map, float t, string myuid, string mynetname, entity e, bool showmessage)
Definition race.qc:373
float race_checkpoint_lasttimes[MAX_CHECKPOINTS]
Definition race.qc:161
#define GameRules_scoring_add_team(client, fld, value)
Definition sv_rules.qh:89
#define IS_SPEC(v)
Definition utils.qh:10
#define vec2(...)
Definition vector.qh:90

References autocvar_fraglimit, autocvar_g_race_cptimes_onlyself, ClientData_Touch(), CS(), entity(), etof, FOREACH_CLIENT, g_bot_targets, g_race_qualifying, game_starttime, GameRules_scoring_add, GameRules_scoring_add_team, GetMapname(), IL_REMOVE(), IS_PLAYER, IS_REAL_CLIENT, IS_SPEC, MAKE_INDEPENDENT_PLAYER, msg_entity, MSG_ONE, MUTATOR_CALLHOOK, NULL, race_checkpoint_lastlaps, race_checkpoint_lastplayers, race_checkpoint_lasttimes, race_checkpoint_recordholders, race_checkpoint_records, race_checkpoint_recordspeeds, race_CheckpointNetworkID(), race_completed, race_completing, RACE_NET_CHECKPOINT_HIT_QUALIFYING, RACE_NET_CHECKPOINT_HIT_RACE, RACE_NET_CHECKPOINT_HIT_RACE_BY_OPPONENT, race_setTime(), race_StartCompleting(), race_timed_checkpoint, Send_Notification(), strcat(), strcpy, time, TIME_ENCODE, vec2, vlen(), WriteByte(), WriteHeader, and WriteString().

◆ race_setTime()

void race_setTime ( string map,
float t,
string myuid,
string mynetname,
entity e,
bool showmessage )

Definition at line 373 of file race.qc.

374{
375 // netname only used TEMPORARILY for printing
376 int newpos = race_readPos(map, t);
377
378 int player_prevpos = 0;
379 for(int i = 1; i <= RANKINGS_CNT; ++i)
380 {
381 if(race_readUID(map, i) == myuid)
382 player_prevpos = i;
383 }
384
385 float oldrec;
386 string oldrec_holder;
387 if (player_prevpos && (player_prevpos < newpos || !newpos))
388 {
389 oldrec = race_readTime(GetMapname(), player_prevpos);
390 race_SendStatus(0, e); // "fail"
391 if(showmessage)
392 Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_RACE_FAIL_RANKED, mynetname, player_prevpos, t, oldrec);
393 return;
394 }
395 else if (!newpos)
396 {
397 // no ranking, time worse than the worst ranked
399 race_SendStatus(0, e); // "fail"
400 if(showmessage)
401 Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_RACE_FAIL_UNRANKED, mynetname, RANKINGS_CNT, t, oldrec);
402 return;
403 }
404
405 // if we didn't hit a return yet, we have a new record!
406
407 // if the player does not have a UID we can unfortunately not store the record, as the rankings system relies on UIDs
408 if(myuid == "")
409 {
410 if(showmessage)
411 Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_RACE_NEW_MISSING_UID, mynetname, t);
412 return;
413 }
414
415 if(CS_CVAR(e).cvar_cl_allow_uidtracking != 1 || CS_CVAR(e).cvar_cl_allow_uid2name != 1
416 || uid2name(myuid) == "^1Unregistered Player")
417 {
418 if(showmessage)
419 Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_RACE_NEW_MISSING_NAME, mynetname, t);
420 return;
421 }
422
423 oldrec = race_readTime(GetMapname(), newpos);
424 oldrec_holder = race_readName(GetMapname(), newpos);
425
426 // store new ranking
427 race_writeTime(GetMapname(), t, myuid);
428
429 if (newpos == 1 && showmessage)
430 {
433 }
434
435 race_SendRanking(newpos, player_prevpos, 0, MSG_ALL);
437
438 if(newpos == player_prevpos)
439 {
440 if(showmessage)
441 Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_RACE_NEW_IMPROVED, mynetname, newpos, t, oldrec);
442 if(newpos == 1) { race_SendStatus(3, e); } // "new server record"
443 else { race_SendStatus(1, e); } // "new time"
444 }
445 else if(oldrec == 0)
446 {
447 if(showmessage)
448 Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_RACE_NEW_SET, mynetname, newpos, t);
449 if(newpos == 1) { race_SendStatus(3, e); } // "new server record"
450 else { race_SendStatus(2, e); } // "new rank"
451 }
452 else
453 {
454 if(showmessage)
455 Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_RACE_NEW_BROKEN, mynetname, oldrec_holder, newpos, t, oldrec);
456 if(newpos == 1) { race_SendStatus(3, e); } // "new server record"
457 else { race_SendStatus(2, e); } // "new rank"
458 }
459}
#define TIME_DECODE(n)
Definition util.qh:101
void write_recordmarker(entity pl, float tstart, float dt)
Definition race.qc:57
float race_readPos(string map, float t)
Definition race.qc:79
void race_SendStatus(float id, entity e)
Definition race.qc:354
void race_writeTime(string map, float t, string myuid)
Definition race.qc:91

References CS_CVAR, entity(), GetMapname(), getrankings(), MSG_ALL, NULL, race_readName(), race_readPos(), race_readTime(), race_readUID(), race_send_recordtime(), race_SendRanking(), race_SendStatus(), race_writeTime(), RANKINGS_CNT, rankings_reply, Send_Notification(), strcpy, time, TIME_DECODE, uid2name(), and write_recordmarker().

Referenced by ctf_CaptureRecord(), and race_SendTime().

◆ race_SpeedAwardFrame()

void race_SpeedAwardFrame ( entity player)

Definition at line 304 of file race.qc.

305{
306 if (IS_OBSERVER(player))
307 return;
308
309 if(vdist(player.velocity - player.velocity_z * '0 0 1', >, speedaward_speed))
310 {
311 speedaward_speed = vlen(player.velocity - player.velocity_z * '0 0 1');
312 speedaward_holder = player.netname;
313 speedaward_uid = player.crypto_idfp;
315 }
317 {
321 {
328 }
329 }
330}
bool intermission_running
float speedaward_lastupdate
Definition race.qh:16
string speedaward_alltimebest_uid
Definition race.qh:65
string speedaward_uid
Definition race.qh:61
float speedaward_lastsent
Definition race.qh:15
#define IS_OBSERVER(v)
Definition utils.qh:11
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt()
Definition vector.qh:8

References db_put(), entity(), ftos(), GetMapname(), intermission_running, IS_OBSERVER, MSG_ALL, race_send_speedaward(), race_send_speedaward_alltimebest(), record_type, ServerProgsDB, speedaward_alltimebest, speedaward_alltimebest_holder, speedaward_alltimebest_uid, speedaward_holder, speedaward_lastsent, speedaward_lastupdate, speedaward_speed, speedaward_uid, strcat(), time, vdist, and vlen().

Referenced by MUTATOR_HOOKFUNCTION(), and MUTATOR_HOOKFUNCTION().

◆ race_StartCompleting()

void race_StartCompleting ( )

Definition at line 1214 of file race.qc.

1215{
1216 race_completing = 1;
1218}
#define IS_DEAD(s)
Definition player.qh:244
void race_AbandonRaceCheck(entity p)
Definition race.qc:1203

References FOREACH_CLIENT, IS_DEAD, IS_PLAYER, race_AbandonRaceCheck(), and race_completing.

Referenced by InitiateSuddenDeath(), and race_SendTime().

◆ race_waypointsprite_visible_for_player()

bool race_waypointsprite_visible_for_player ( entity this,
entity player,
entity view )

Definition at line 865 of file race.qc.

866{
867 entity own = this.owner;
868 if(this.realowner)
869 own = this.realowner; // target support
870
871 if(view.race_checkpoint == -1 || own.race_checkpoint == -2)
872 return true;
873 else if(view.race_checkpoint == own.race_checkpoint)
874 return true;
875 else
876 return false;
877}
entity owner
Definition main.qh:87
entity realowner

References entity(), owner, and realowner.

Referenced by defrag_waypointsprites(), and spawnfunc().

◆ race_writeTime()

void race_writeTime ( string map,
float t,
string myuid )

Definition at line 91 of file race.qc.

92{
93 float newpos = race_readPos(map, t);
94
95 float i, prevpos = 0;
96 for(i = 1; i <= RANKINGS_CNT; ++i)
97 {
98 if(race_readUID(map, i) == myuid)
99 prevpos = i;
100 }
101 if (prevpos)
102 {
103 // player improved their existing record, only have to iterate on ranks between new and old recs
104 for (i = prevpos; i > newpos; --i)
105 {
106 db_put(ServerProgsDB, strcat(map, record_type, "time", ftos(i)), ftos(race_readTime(map, i - 1)));
107 db_put(ServerProgsDB, strcat(map, record_type, "crypto_idfp", ftos(i)), race_readUID(map, i - 1));
108 }
109 }
110 else
111 {
112 // player has no ranked record yet
113 for (i = RANKINGS_CNT; i > newpos; --i)
114 {
115 float other_time = race_readTime(map, i - 1);
116 if (other_time) {
117 db_put(ServerProgsDB, strcat(map, record_type, "time", ftos(i)), ftos(other_time));
118 db_put(ServerProgsDB, strcat(map, record_type, "crypto_idfp", ftos(i)), race_readUID(map, i - 1));
119 }
120 }
121 }
122
123 // store new time itself
124 db_put(ServerProgsDB, strcat(map, record_type, "time", ftos(newpos)), ftos(t));
125 db_put(ServerProgsDB, strcat(map, record_type, "crypto_idfp", ftos(newpos)), myuid);
126}

References db_put(), ftos(), race_readPos(), race_readTime(), race_readUID(), RANKINGS_CNT, record_type, ServerProgsDB, and strcat().

Referenced by race_setTime().

◆ spawnfunc() [1/6]

spawnfunc ( info_player_race )

Definition at line 1238 of file race.qc.

1239{
1240 if(!g_race && !g_cts) { delete(this); return; }
1241 ++race_spawns;
1242 spawnfunc_info_player_deathmatch(this);
1243
1248}
float race_spawns
Definition race.qh:18
float race_lowest_place_spawn
Definition race.qh:20
float race_highest_place_spawn
Definition race.qh:19

References g_cts, g_race, race_highest_place_spawn, race_lowest_place_spawn, race_place, and race_spawns.

◆ spawnfunc() [2/6]

spawnfunc ( target_checkpoint )

Definition at line 1193 of file race.qc.

1194{
1195 // xonotic defrag entity
1197}
void target_checkpoint_setup(entity this)
Definition race.qc:1142

References target_checkpoint_setup().

◆ spawnfunc() [3/6]

spawnfunc ( target_startTimer )

Definition at line 1200 of file race.qc.

1200{ target_checkpoint_setup(this); }

References target_checkpoint_setup().

◆ spawnfunc() [4/6]

spawnfunc ( target_stopTimer )

Definition at line 1201 of file race.qc.

1201{ target_checkpoint_setup(this); }

References target_checkpoint_setup().

◆ spawnfunc() [5/6]

spawnfunc ( trigger_race_checkpoint )

Definition at line 1086 of file race.qc.

1087{
1088 vector o;
1089 if(!g_race && !g_cts) { delete(this); return; }
1090
1092
1093 this.use = checkpoint_use;
1094 if (!(this.spawnflags & 1))
1096
1097 o = (this.absmin + this.absmax) * 0.5;
1098 tracebox(o, PL_MIN_CONST, PL_MAX_CONST, o - '0 0 1' * (o.z - this.absmin.z), MOVE_NORMAL, this);
1100 this.nearestwaypointtimeout = -1;
1101
1102 if(this.message == "")
1103 this.message = "went backwards";
1104 if (this.message2 == "")
1105 this.message2 = "was pushed backwards by";
1106 if (this.race_penalty_reason == "")
1107 this.race_penalty_reason = "missing a checkpoint";
1108
1109 this.race_checkpoint = this.cnt;
1110
1112 {
1114 if(this.spawnflags & 8)
1116 else
1118 }
1119
1120 if(!this.race_penalty)
1121 {
1122 if(this.race_checkpoint)
1123 WaypointSprite_SpawnFixed(WP_RaceCheckpoint, o, this, sprite, RADARICON_NONE);
1124 else
1125 WaypointSprite_SpawnFixed(WP_RaceStartFinish, o, this, sprite, RADARICON_NONE);
1126 }
1127
1128 this.sprite.waypointsprite_visible_for_player = race_waypointsprite_visible_for_player;
1130
1131 if (!g_racecheckpoints)
1134
1135 // trigger_race_checkpoint_verify checks this list too
1136 if (!g_race_targets)
1138
1140}
float nearestwaypointtimeout
Definition api.qh:53
void waypoint_spawnforitem_force(entity e, vector org)
float cnt
Definition powerups.qc:24
const vector PL_MIN_CONST
Definition constants.qh:56
const int INITPRIO_FINDTARGET
Definition constants.qh:96
const vector PL_MAX_CONST
Definition constants.qh:55
const float MOVE_NORMAL
vector trace_endpos
vector absmax
vector absmin
#define use
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.
#define IL_NEW()
#define EXACTTRIGGER_INIT
Definition common.qh:116
#define settouch(e, f)
Definition self.qh:73
vector trigger_race_checkpoint_spawn_evalfunc(entity this, entity player, entity spot, vector current)
Definition race.qc:1055
void checkpoint_use(entity this, entity actor, entity trigger)
Definition race.qc:857
void checkpoint_touch(entity this, entity toucher)
Definition race.qc:851
void trigger_race_checkpoint_verify(entity this)
Definition race.qc:920
spawn_evalfunc_t spawn_evalfunc
string message2
Definition triggers.qh:19
void InitializeEntity(entity e, void(entity this) func, int order)
Definition world.qc:2230

References absmax, absmin, checkpoint_touch(), checkpoint_use(), cnt, EXACTTRIGGER_INIT, g_cts, g_race, g_race_targets, g_racecheckpoints, IL_NEW, IL_PUSH(), InitializeEntity(), INITPRIO_FINDTARGET, message, message2, MOVE_NORMAL, nearestwaypointtimeout, PL_MAX_CONST, PL_MIN_CONST, race_checkpoint, race_highest_checkpoint, race_penalty, race_penalty_reason, race_timed_checkpoint, race_waypointsprite_visible_for_player(), settouch, spawn_evalfunc, spawnflags, sprite, trace_endpos, trigger_race_checkpoint_spawn_evalfunc(), trigger_race_checkpoint_verify(), use, vector, waypoint_spawnforitem_force(), and WaypointSprite_SpawnFixed().

◆ spawnfunc() [6/6]

spawnfunc ( trigger_race_penalty )

Definition at line 1322 of file race.qc.

1323{
1324 // TODO: find out why this wasnt done:
1325 //if(!g_cts && !g_race) { remove(this); return; }
1326
1328
1329 this.use = penalty_use;
1330 if (!(this.spawnflags & 1))
1331 settouch(this, penalty_touch);
1332
1333 if (this.race_penalty_reason == "")
1334 this.race_penalty_reason = "missing a checkpoint";
1335 if (!this.race_penalty)
1336 this.race_penalty = 5;
1337}
void penalty_use(entity this, entity actor, entity trigger)
Definition race.qc:1317
void penalty_touch(entity this, entity toucher)
Definition race.qc:1307

References EXACTTRIGGER_INIT, penalty_touch(), penalty_use(), race_penalty, race_penalty_reason, settouch, spawnflags, and use.

◆ target_checkpoint_setup()

void target_checkpoint_setup ( entity this)

Definition at line 1142 of file race.qc.

1143{
1144 if(!g_race && !g_cts) { delete(this); return; }
1145 defrag_ents = 1;
1146
1147 // if this is targeted, then it probably isn't a trigger
1148 bool is_trigger = this.targetname == "";
1149
1150 if(is_trigger)
1152
1153 this.use = checkpoint_use;
1154 if (is_trigger && !(this.spawnflags & 1))
1156
1157 vector org = this.origin;
1158
1159 // bots should only pathfind to this if it is a valid touchable trigger
1160 if(is_trigger)
1161 {
1162 org = (this.absmin + this.absmax) * 0.5;
1163 tracebox(org, PL_MIN_CONST, PL_MAX_CONST, org - '0 0 1' * (org.z - this.absmin.z), MOVE_NORMAL, this);
1165 this.nearestwaypointtimeout = -1;
1166 }
1167
1168 if(this.message == "")
1169 this.message = "went backwards";
1170 if (this.message2 == "")
1171 this.message2 = "was pushed backwards by";
1172 if (this.race_penalty_reason == "")
1173 this.race_penalty_reason = "missing a checkpoint";
1174
1175 if(this.classname == "target_startTimer")
1176 this.race_checkpoint = 0;
1177 else
1178 this.race_checkpoint = -2;
1179
1181
1182 if (!g_race_targets)
1184 IL_PUSH(g_race_targets, this);
1185
1186 // trigger_race_checkpoint_verify checks this list too
1187 if (!g_racecheckpoints)
1189
1191}
vector origin
vector org
Definition self.qh:92
string targetname
Definition triggers.qh:56

References absmax, absmin, checkpoint_touch(), checkpoint_use(), classname, defrag_ents, entity(), EXACTTRIGGER_INIT, g_cts, g_race, g_race_targets, g_racecheckpoints, IL_NEW, IL_PUSH(), InitializeEntity(), INITPRIO_FINDTARGET, message, message2, MOVE_NORMAL, nearestwaypointtimeout, org, origin, PL_MAX_CONST, PL_MIN_CONST, race_checkpoint, race_penalty_reason, race_timed_checkpoint, settouch, spawnflags, targetname, trace_endpos, trigger_race_checkpoint_verify(), use, vector, and waypoint_spawnforitem_force().

Referenced by spawnfunc(), spawnfunc(), and spawnfunc().

◆ trigger_race_checkpoint_spawn_evalfunc()

vector trigger_race_checkpoint_spawn_evalfunc ( entity this,
entity player,
entity spot,
vector current )

Definition at line 1055 of file race.qc.

1056{
1058 {
1059 // spawn at first
1060 if(this.race_checkpoint != 0)
1061 return '-1 0 0';
1062 if(spot.race_place != race_lowest_place_spawn)
1063 return '-1 0 0';
1064 }
1065 else
1066 {
1067 if(this.race_checkpoint != player.race_respawn_checkpoint)
1068 return '-1 0 0';
1069 // try reusing the previous spawn
1070 if(this == player.race_respawn_spotref || spot == player.race_respawn_spotref)
1071 current.x += SPAWN_PRIO_RACE_PREVIOUS_SPAWN;
1072 if(this.race_checkpoint == 0)
1073 {
1074 int pl = player.race_place;
1076 pl = 0;
1077 if(pl == 0 && !player.race_started)
1078 pl = race_highest_place_spawn; // use last place if they have not even touched finish yet
1079 if(spot.race_place != pl)
1080 return '-1 0 0';
1081 }
1082 }
1083 return current;
1084}
const int SPAWN_PRIO_RACE_PREVIOUS_SPAWN

References entity(), g_race_qualifying, race_checkpoint, race_highest_place_spawn, race_lowest_place_spawn, SPAWN_PRIO_RACE_PREVIOUS_SPAWN, and vector.

Referenced by spawnfunc().

◆ trigger_race_checkpoint_verify()

void trigger_race_checkpoint_verify ( entity this)

Definition at line 920 of file race.qc.

921{
922 static bool have_verified;
923 if (have_verified) return;
924 have_verified = true;
925
926 int qual = g_race_qualifying;
927
928 int pl_race_checkpoint = 0;
929 int pl_race_place = 0;
930
931 if (g_race) {
932 for (int i = 0; i <= race_highest_checkpoint; ++i) {
933 pl_race_checkpoint = race_NextCheckpoint(i);
934
935 // race only (middle of the race)
937 pl_race_place = 0;
938 if (!Spawn_FilterOutBadSpots(this, findchain(classname, "info_player_deathmatch"), 0, false, true)) {
939 error(strcat("Checkpoint ", ftos(i), " misses a spawnpoint with race_place==", ftos(pl_race_place), " (used for respawning in race) - bailing out"));
940 }
941
942 if (i == 0) {
943 // qualifying only
945 pl_race_place = race_lowest_place_spawn;
946 if (!Spawn_FilterOutBadSpots(this, findchain(classname, "info_player_deathmatch"), 0, false, true)) {
947 error(strcat("Checkpoint ", ftos(i), " misses a spawnpoint with race_place==", ftos(pl_race_place), " (used for qualifying) - bailing out"));
948 }
949
950 // race only (initial spawn)
952 for (int p = 1; p <= race_highest_place_spawn; ++p) {
953 pl_race_place = p;
954 if (!Spawn_FilterOutBadSpots(this, findchain(classname, "info_player_deathmatch"), 0, false, true)) {
955 error(strcat("Checkpoint ", ftos(i), " misses a spawnpoint with race_place==", ftos(pl_race_place), " (used for initially spawning in race) - bailing out"));
956 }
957 }
958 }
959 }
960 } else if (!defrag_ents) {
961 // qualifying only
962 pl_race_checkpoint = race_NextCheckpoint(0);
964 pl_race_place = race_lowest_place_spawn;
965 if (!Spawn_FilterOutBadSpots(this, findchain(classname, "info_player_deathmatch"), 0, false, true)) {
966 error(strcat("Checkpoint 0 misses a spawnpoint with race_place==", ftos(pl_race_place), " (used for qualifying) - bailing out"));
967 }
968 } else {
969 pl_race_checkpoint = race_NextCheckpoint(0);
971 pl_race_place = 0; // there's only one spawn on defrag maps
972
973 // check if a defragcp file already exists, then read it and apply the checkpoint order
974 float fh;
975 float len;
976 bool broken_defragcp = false;
977 string l;
978
979 defragcpexists = fh = fopen(strcat("maps/", GetMapname(), ".defragcp"), FILE_READ);
980 if (fh >= 0) {
981 while ((l = fgets(fh))) {
982 len = tokenize_console(l);
983 if (len != 2) {
984 broken_defragcp = true;
985 break;
986 }
987 for (entity cp = NULL; (cp = find(cp, classname, "target_checkpoint"));) {
988 if (argv(0) == cp.targetname) {
989 if(cp.race_checkpoint != -2 && cp.race_checkpoint != stof(argv(1))) {
990 broken_defragcp = true; // cp had been previously set with diff order nr defragcp file is broken
991 break;
992 }
993 cp.race_checkpoint = stof(argv(1));
994 }
995 }
996 if(broken_defragcp) break; // no point to keep going we'll rebuild the whole order
997 }
998 fclose(fh);
999 if(broken_defragcp) {
1000 // something's wrong in the defrag cp file, set defragcpexists to -1 so that it will be rewritten when someone finishes
1001 // also clear any set cp order to make sure map is completable
1002 defragcpexists = -1;
1003 for (entity cp = NULL; (cp = find(cp, classname, "target_checkpoint"));) {
1004 cp.race_checkpoint = -2;
1005 }
1006 }
1007 }
1008 }
1009
1010 g_race_qualifying = qual;
1011
1013 if (defrag_ents) {
1014 IL_EACH(g_race_targets, it.classname == "target_checkpoint" || it.classname == "target_startTimer" || it.classname == "target_stopTimer",
1015 {
1016 defrag_waypointsprites(it, it, 0);
1017
1018 if(it.classname == "target_checkpoint") {
1019 if(it.race_checkpoint == -2)
1020 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
1021 }
1022 });
1023 if (defragcpexists != -1) {
1024 float largest_cp_id = 0;
1025 for (entity cp = NULL; (cp = find(cp, classname, "target_checkpoint"));) {
1026 if (cp.race_checkpoint > largest_cp_id) {
1027 largest_cp_id = cp.race_checkpoint;
1028 }
1029 }
1030 for (entity cp = NULL; (cp = find(cp, classname, "target_stopTimer"));) {
1031 cp.race_checkpoint = largest_cp_id + 1; // finish line
1032 }
1033 race_highest_checkpoint = largest_cp_id + 1;
1034 race_timed_checkpoint = largest_cp_id + 1;
1035 } else {
1036 for (entity cp = NULL; (cp = find(cp, classname, "target_stopTimer"));) {
1037 cp.race_checkpoint = 255; // finish line
1038 }
1041 }
1042 } else {
1043 IL_EACH(g_racecheckpoints, it.sprite,
1044 {
1045 if (it.race_checkpoint == 0) {
1046 WaypointSprite_UpdateSprites(it.sprite, WP_RaceStart, WP_Null, WP_Null);
1047 } else if (it.race_checkpoint == race_timed_checkpoint) {
1048 WaypointSprite_UpdateSprites(it.sprite, WP_RaceFinish, WP_Null, WP_Null);
1049 }
1050 });
1051 }
1052 }
1053}
const float FILE_READ
#define tokenize_console
string fgets(float fhandle)
entity find(entity start,.string field, string match)
string argv(float n)
#define error
Definition pre.qh:6
entity Spawn_FilterOutBadSpots(entity this, entity firstspot, float mindist, float teamcheck, bool targetcheck)
if(frag_attacker.flagcarried)
Definition sv_ctf.qc:2318

References argv(), classname, defrag_ents, defragcpexists, entity(), error, fclose(), fgets(), FILE_READ, find(), fopen(), ftos(), g_race, g_race_qualifying, g_race_targets, g_racecheckpoints, GetMapname(), if(), IL_EACH, NULL, race_highest_checkpoint, race_highest_place_spawn, race_lowest_place_spawn, race_NextCheckpoint(), race_timed_checkpoint, Spawn_FilterOutBadSpots(), stof(), strcat(), and tokenize_console.

Referenced by spawnfunc(), and target_checkpoint_setup().

◆ uid2name()

string uid2name ( string myuid)

Definition at line 36 of file race.qc.

37{
38 string s = db_get(ServerProgsDB, strcat("/uid2name/", myuid));
39
40 // FIXME remove this later after 0.6 release
41 // convert old style broken records to correct style
42 if(s == "")
43 {
44 s = db_get(ServerProgsDB, strcat("uid2name", myuid));
45 if(s != "")
46 {
47 db_put(ServerProgsDB, strcat("/uid2name/", myuid), s);
48 db_remove(ServerProgsDB, strcat("uid2name", myuid));
49 }
50 }
51
52 if(s == "")
53 s = "^1Unregistered Player";
54 return s;
55}

References db_get(), db_put(), db_remove, ServerProgsDB, and strcat().

Referenced by getladder(), race_checkAndWriteName(), race_readName(), race_SendAll(), and race_setTime().

◆ write_recordmarker()

void write_recordmarker ( entity pl,
float tstart,
float dt )

Definition at line 57 of file race.qc.

58{
59 GameLogEcho(strcat(":recordset:", ftos(pl.playerid), ":", ftos(dt)));
60 // also write a marker into demo files for demotc-race-record-extractor to find
61 stuffcmd(pl,
62 sprintf("//%s RECORD SET %s %f %f\n", strconv(2, 0, 0, GetGametype()),
63 TIME_ENCODED_TOSTRING(TIME_ENCODE(dt), false), tstart, dt));
64}
#define TIME_ENCODED_TOSTRING(n, compact)
Definition util.qh:96
void GameLogEcho(string s)
Definition gamelog.qc:15
string GetGametype()
#define stuffcmd(cl,...)
Definition progsdefs.qh:23

References entity(), ftos(), GameLogEcho(), GetGametype(), strcat(), stuffcmd, TIME_ENCODE, and TIME_ENCODED_TOSTRING.

Referenced by ctf_CaptureRecord(), and race_setTime().

Variable Documentation

◆ defrag_ents

float defrag_ents

◆ defragcpexists

float defragcpexists

Definition at line 172 of file race.qc.

Referenced by trigger_race_checkpoint_verify().

◆ g_race_targets

IntrusiveList g_race_targets

◆ g_racecheckpoints

◆ MAX_CHECKPOINTS

const float MAX_CHECKPOINTS = 255

Definition at line 148 of file race.qc.

Referenced by race_ClearPlayerRecords(), and race_ClearRecords().

◆ race_checkpoint

float race_checkpoint

Definition at line 153 of file race.qc.

◆ race_checkpoint_lastlaps

float race_checkpoint_lastlaps[MAX_CHECKPOINTS]

Definition at line 162 of file race.qc.

Referenced by race_SendTime().

◆ race_checkpoint_lastplayers

entity race_checkpoint_lastplayers[MAX_CHECKPOINTS]

Definition at line 163 of file race.qc.

Referenced by race_SendTime().

◆ race_checkpoint_lasttimes

float race_checkpoint_lasttimes[MAX_CHECKPOINTS]

Definition at line 161 of file race.qc.

Referenced by race_SendTime().

◆ race_checkpoint_record

float race_checkpoint_record[MAX_CHECKPOINTS]

Definition at line 165 of file race.qc.

◆ race_checkpoint_recordholders

string race_checkpoint_recordholders[MAX_CHECKPOINTS]

Definition at line 160 of file race.qc.

Referenced by race_ClearRecords(), race_SendNextCheckpoint(), and race_SendTime().

◆ race_checkpoint_records

float race_checkpoint_records[MAX_CHECKPOINTS]

Definition at line 158 of file race.qc.

Referenced by race_ClearRecords(), race_SendNextCheckpoint(), and race_SendTime().

◆ race_checkpoint_recordspeed

float race_checkpoint_recordspeed[MAX_CHECKPOINTS]

Definition at line 166 of file race.qc.

◆ race_checkpoint_recordspeeds

float race_checkpoint_recordspeeds[MAX_CHECKPOINTS]

Definition at line 159 of file race.qc.

Referenced by race_ClearRecords(), race_SendNextCheckpoint(), and race_SendTime().

◆ race_highest_checkpoint

◆ race_lastpenalty

entity race_lastpenalty

Definition at line 154 of file race.qc.

◆ race_penalty

float race_penalty

Definition at line 150 of file race.qc.

◆ race_penalty_accumulator

float race_penalty_accumulator

Definition at line 151 of file race.qc.

◆ race_penalty_reason

string race_penalty_reason

Definition at line 152 of file race.qc.

Referenced by penalty_touch(), penalty_use(), spawnfunc(), spawnfunc(), and target_checkpoint_setup().

◆ race_timed_checkpoint

◆ sprite

entity sprite

Definition at line 156 of file race.qc.

◆ stored_netname

string stored_netname

Definition at line 34 of file race.qc.