53 s =
"^1Unregistered Player";
62 sprintf(
"//%s RECORD SET %s %f %f\n", strconv(2, 0, 0,
GetGametype()),
84 if(!mytime || mytime > t)
104 for (i = prevpos; i > newpos; --i)
135 if(
CS_CVAR(player).cvar_cl_allow_uidtracking == 1 &&
CS_CVAR(player).cvar_cl_allow_uid2name == 1)
137 if (!player.stored_netname)
139 if(player.stored_netname != player.netname)
142 strcpy(player.stored_netname, player.netname);
213 int cp = e.race_checkpoint;
216 float myrecordtime = e.race_checkpoint_record[cp];
217 float myrecordspeed = e.race_checkpoint_recordspeed[cp];
220 recordtime = myrecordtime;
221 recordspeed = myrecordspeed;
228 if(recordholder == e.netname)
248 WriteInt24_t(
MSG_ONE, recordtime);
250 WriteInt24_t(
MSG_ONE, myrecordtime);
253 WriteFloat(
MSG_ONE, recordspeed);
255 WriteFloat(
MSG_ONE, myrecordspeed);
350 for (
int i = 1; i <= m; ++i)
378 int player_prevpos = 0;
386 string oldrec_holder;
387 if (player_prevpos && (player_prevpos < newpos || !newpos))
392 Send_Notification(NOTIF_ALL,
NULL, MSG_INFO, INFO_RACE_FAIL_RANKED, mynetname, player_prevpos, t, oldrec);
415 if(
CS_CVAR(e).cvar_cl_allow_uidtracking != 1 ||
CS_CVAR(e).cvar_cl_allow_uid2name != 1
416 ||
uid2name(myuid) ==
"^1Unregistered Player")
429 if (newpos == 1 && showmessage)
438 if(newpos == player_prevpos)
455 Send_Notification(NOTIF_ALL,
NULL, MSG_INFO, INFO_RACE_NEW_BROKEN, mynetname, oldrec_holder, newpos, t, oldrec);
465 string therank =
ftos(i);
488 t += e.race_penalty_accumulator;
512 CS(e).race_completed = 1;
516 e.bot_attack =
false;
526 float recordtimespeed;
534 recordtime = e.race_checkpoint_record[cp];
535 recordtimespeed = e.race_checkpoint_recordspeed[cp];
545 if(recordholder == e.netname)
557 if(t < recordtime || recordtime == 0)
583 if(it == e || (
IS_SPEC(it) && it.enemy == e))
590 WriteInt24_t(
MSG_ONE, recordtime);
591 WriteInt24_t(
MSG_ONE, ((tvalid) ? it.race_checkpoint_record[cp] : 0));
595 WriteFloat(
MSG_ONE, recordtimespeed);
596 WriteFloat(
MSG_ONE, ((tvalid) ? it.race_checkpoint_recordspeed[cp] : 0));
604 float myrecordtime = e.race_checkpoint_record[cp];
606 if(t < myrecordtime || myrecordtime == 0)
608 e.race_checkpoint_record[cp] = t;
609 e.race_checkpoint_recordspeed[cp] =
vlen(
vec2(e.velocity));
615 float mylaps, lother, othtime;
624 mylaps = lother = othtime = 0;
678 e.race_checkpoint = 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;
697 player = player.owner;
702 if(player.classname ==
"porto")
731 player.porto_forbidden = 2;
739 if(it.race_checkpoint >= 0)
740 this.race_checkpoint = it.race_checkpoint;
746 int cp_amount = 0, largest_cp_id = 0;
750 if(it.race_checkpoint > largest_cp_id)
754 IL_EACH(g_race_targets, it.classname ==
"target_checkpoint",
756 if(it.race_checkpoint == -2)
761 largest_cp_id = it.race_checkpoint;
762 IL_EACH(g_race_targets, it.classname ==
"target_stopTimer",
764 it.race_checkpoint = largest_cp_id + 1;
766 race_highest_checkpoint = largest_cp_id + 1;
767 race_timed_checkpoint = largest_cp_id + 1;
775 it.race_checkpoint = 1;
782 if((player.race_checkpoint == -1 &&
this.race_checkpoint == 0) || (player.race_checkpoint == this.
race_checkpoint))
786 if(player.race_lastpenalty !=
this)
788 player.race_lastpenalty =
this;
793 if(player.race_penalty)
807 if(player.race_respawn_checkpoint !=
this.race_checkpoint || !player.race_started)
808 player.race_respawn_spotref =
this;
811 player.race_started = 1;
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;
834 fputs(fh, strcat(it.targetname,
" ", ftos(it.race_checkpoint),
"\n"));
847 Damage (player,
this,
this, 10000, DEATH_HURTTRIGGER.m_id,
DMG_NOWEP, player.origin,
'0 0 0');
859 if(trigger.classname ==
"info_player_deathmatch")
871 if(view.race_checkpoint == -1 || own.race_checkpoint == -2)
873 else if(view.race_checkpoint == own.race_checkpoint)
885 entity s = WP_RaceCheckpoint;
886 if (checkpoint.classname ==
"target_startTimer")
888 else if (checkpoint.classname ==
"target_stopTimer")
891 for (
entity t = findchain(
target, targeted.targetname); t; t = t.chain)
896 t.sprite.realowner = checkpoint;
900 if (t.loopdetector & 2)
903 LOG_WARNF(
"MAP BUG: target field of %s \"%s\" loops back to %s \"%s\"\n", t.classname, t.targetname, targeted.classname, targeted.targetname);
905 else if (t.targetname)
907 targeted.loopdetector |= 2;
909 targeted.loopdetector &= ~2;
916 static bool have_verified;
917 if (have_verified)
return;
918 have_verified =
true;
922 int pl_race_checkpoint = 0;
923 int pl_race_place = 0;
933 error(
strcat(
"Checkpoint ",
ftos(i),
" misses a spawnpoint with race_place==",
ftos(pl_race_place),
" (used for respawning in race) - bailing out"));
941 error(
strcat(
"Checkpoint ",
ftos(i),
" misses a spawnpoint with race_place==",
ftos(pl_race_place),
" (used for qualifying) - bailing out"));
949 error(
strcat(
"Checkpoint ",
ftos(i),
" misses a spawnpoint with race_place==",
ftos(pl_race_place),
" (used for initially spawning in race) - bailing out"));
960 error(
strcat(
"Checkpoint 0 misses a spawnpoint with race_place==",
ftos(pl_race_place),
" (used for qualifying) - bailing out"));
970 bool broken_defragcp =
false;
975 while ((l =
fgets(fh))) {
978 broken_defragcp =
true;
982 if (
argv(0) == cp.targetname) {
983 if(cp.race_checkpoint != -2 && cp.race_checkpoint !=
stof(
argv(1))) {
984 broken_defragcp =
true;
990 if(broken_defragcp)
break;
993 if(broken_defragcp) {
998 cp.race_checkpoint = -2;
1008 IL_EACH(
g_race_targets, it.classname ==
"target_checkpoint" || it.classname ==
"target_startTimer" || it.classname ==
"target_stopTimer",
1010 defrag_waypointsprites(it, it);
1012 if(it.classname ==
"target_checkpoint") {
1013 if(it.race_checkpoint == -2)
1014 defragcpexists = -1;
1018 float largest_cp_id = 0;
1020 if (cp.race_checkpoint > largest_cp_id) {
1021 largest_cp_id = cp.race_checkpoint;
1025 cp.race_checkpoint = largest_cp_id + 1;
1031 cp.race_checkpoint = 255;
1039 if (it.race_checkpoint == 0) {
1040 WaypointSprite_UpdateSprites(it.sprite, WP_RaceStart, WP_Null, WP_Null);
1042 WaypointSprite_UpdateSprites(it.sprite, WP_RaceFinish, WP_Null, WP_Null);
1064 if(
this == player.race_respawn_spotref || spot == player.race_respawn_spotref)
1068 int pl = player.race_place;
1071 if(pl == 0 && !player.race_started)
1073 if(spot.race_place != pl)
1097 this.
message =
"went backwards";
1099 this.
message2 =
"was pushed backwards by";
1147 if(this.
classname ==
"target_startTimer")
1174 CS(p).race_completed = 1;
1209 spawnfunc_info_player_deathmatch(
this);
1221 player.race_checkpoint_record[i] = 0;
1222 player.race_checkpoint_recordspeed[i] = 0;
1236 float p = it.race_place;
1246 pl.race_penalty_accumulator += penalty;
1260 pl.race_penalty =
time + penalty;
1277 if(
toucher.race_lastpenalty !=
this)
1279 toucher.race_lastpenalty =
this;
1323 float bestfraction, fraction;
1325 float nextcpindex, lastcpindex;
1327 nextcpindex =
max(e.race_checkpoint, 0);
1328 lastcpindex = e.race_respawn_checkpoint;
1329 lastcp = e.race_respawn_spotref;
1331 if(nextcpindex == lastcpindex)
1337 if(it.race_checkpoint != lastcpindex)
1342 o0 = (it.absmin + it.absmax) * 0.5;
1345 if(it.race_checkpoint != nextcpindex)
1347 o1 = (it.absmin + it.absmax) * 0.5;
1351 if(fraction < bestfraction)
1352 bestfraction = fraction;
float nearestwaypointtimeout
IntrusiveList g_bot_targets
void waypoint_spawnforitem_force(entity e, vector org)
#define MUTATOR_CALLHOOK(name,...)
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
limitations: NULL cannot be present elements can only be present once a maximum of IL_MAX lists can e...
#define autocvar_fraglimit
#define TIME_ENCODED_TOSTRING(n, compact)
const vector PL_MIN_CONST
const int INITPRIO_FINDTARGET
const vector PL_MAX_CONST
vector trace_plane_normal
void Damage(entity targ, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
WriteString(chan, ent.netname)
WriteByte(chan, ent.angles.y/DEC_FACTOR)
void GameLogEcho(string s)
bool intermission_running
ERASEABLE void IL_REMOVE(IntrusiveList this, entity it)
Remove any element, anywhere in the list.
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.
#define IL_EACH(this, cond, body)
void SUB_UseTargets(entity this, entity actor, entity trigger)
#define WriteHeader(to, id)
#define EXACTTRIGGER_TOUCH(e, t)
#define EXACTTRIGGER_INIT
#define db_remove(db, key)
ERASEABLE string db_get(int db, string key)
ERASEABLE void db_put(int db, string key, string value)
@ RACE_NET_CHECKPOINT_HIT_RACE_BY_OPPONENT
@ RACE_NET_SPEED_AWARD_BEST
@ RACE_NET_CHECKPOINT_NEXT_QUALIFYING
@ RACE_NET_PENALTY_QUALIFYING
@ RACE_NET_CHECKPOINT_CLEAR
@ RACE_NET_SERVER_RANKINGS
@ RACE_NET_CHECKPOINT_HIT_RACE
@ RACE_NET_CHECKPOINT_NEXT_SPEC_QUALIFYING
@ RACE_NET_CHECKPOINT_HIT_QUALIFYING
strcat(_("^F4Countdown stopped!"), "\n^BG", _("Teams are too unbalanced."))
void Send_Notification(NOTIF broadcast, entity client, MSG net_type, Notification net_name,...count)
void Portal_ClearAll(entity own)
void W_Porto_Fail(entity this, bool failhard)
void ClientData_Touch(entity e, bool to_spectators_too)
#define MAKE_INDEPENDENT_PLAYER(e)
float race_checkpoint_record[MAX_CHECKPOINTS]
float race_CheckpointNetworkID(float f)
void race_SendRanking(float pos, float prevpos, float del, float msg)
float race_readTime(string map, float pos)
float race_PreviousCheckpoint(float f)
float race_highest_checkpoint
void checkpoint_passed(entity this, entity player)
void race_SendAll(entity player, bool only_rankings)
float race_checkpoint_recordspeeds[MAX_CHECKPOINTS]
void race_PreparePlayer(entity this)
float race_checkpoint_lastlaps[MAX_CHECKPOINTS]
string race_penalty_reason
void race_SendNextCheckpoint(entity e, float spec)
void write_recordmarker(entity pl, float tstart, float dt)
void race_SpeedAwardFrame(entity player)
float race_checkpoint_recordspeed[MAX_CHECKPOINTS]
const float MAX_CHECKPOINTS
float race_timed_checkpoint
float race_readPos(string map, float t)
void race_SendTime(entity e, float cp, float t, float tvalid)
void race_ClearTime(entity e)
vector trigger_race_checkpoint_spawn_evalfunc(entity this, entity player, entity spot, vector current)
string race_readName(string map, float pos)
void defrag_waypointsprites(entity targeted, entity checkpoint)
bool race_waypointsprite_visible_for_player(entity this, entity player, entity view)
float race_NextCheckpoint(float f)
void checkpoint_use(entity this, entity actor, entity trigger)
string uid2name(string myuid)
void race_StartCompleting()
float race_GetFractionalLapCount(entity e)
void race_checkAndWriteName(entity player)
IntrusiveList g_racecheckpoints
void race_send_speedaward_alltimebest(float msg)
void race_send_speedaward(float msg)
void race_RetractPlayer(entity this)
IntrusiveList g_race_targets
entity race_checkpoint_lastplayers[MAX_CHECKPOINTS]
void checkpoint_touch(entity this, entity toucher)
float race_checkpoint_records[MAX_CHECKPOINTS]
void race_setTime(string map, float t, string myuid, string mynetname, entity e, bool showmessage)
void race_SendStatus(float id, entity e)
void race_send_recordtime(float msg)
string race_checkpoint_recordholders[MAX_CHECKPOINTS]
string race_readUID(string map, float pos)
void race_AbandonRaceCheck(entity p)
void penalty_use(entity this, entity actor, entity trigger)
float race_penalty_accumulator
void race_writeTime(string map, float t, string myuid)
void race_send_rankings_cnt(float msg)
void target_checkpoint_setup(entity this)
void race_ClearPlayerRecords(entity player)
void race_deleteTime(string map, float pos)
void trigger_race_checkpoint_verify(entity this)
float race_checkpoint_lasttimes[MAX_CHECKPOINTS]
void race_ImposePenaltyTime(entity pl, float penalty, string reason)
void penalty_touch(entity this, entity toucher)
bool autocvar_g_allow_checkpoints
bool autocvar_g_race_cptimes_onlyself
float speedaward_alltimebest
float race_lowest_place_spawn
entity race_respawn_spotref
float speedaward_lastupdate
float race_respawn_checkpoint
string speedaward_alltimebest_uid
float race_highest_place_spawn
int autocvar_g_cts_send_rankings_cnt
float speedaward_lastsent
string speedaward_alltimebest_holder
entity Spawn_FilterOutBadSpots(entity this, entity firstspot, float mindist, float teamcheck, bool targetcheck)
const int SPAWN_PRIO_RACE_PREVIOUS_SPAWN
spawn_evalfunc_t spawn_evalfunc
ClientState CS(Client this)
if(frag_attacker.flagcarried)
#define GameRules_scoring_add(client, fld, value)
#define GameRules_scoring_add_team(client, fld, value)
#define IS_REAL_CLIENT(v)
#define FOREACH_CLIENT(cond, body)
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt().
entity WaypointSprite_SpawnFixed(entity spr, vector ofs, entity own,.entity ownfield, entity icon)
void InitializeEntity(entity e, void(entity this) func, int order)
bool autocvar_sv_dedicated