float race_checkpoint_lastlaps[MAX_CHECKPOINTS];
entity race_checkpoint_lastplayers[MAX_CHECKPOINTS];
+.float race_checkpoint_record[MAX_CHECKPOINTS];
+
float race_highest_checkpoint;
float race_timed_checkpoint;
void race_SendNextCheckpoint(entity e, float spec) // qualifying only
{
- float recordtime;
- string recordholder;
- float cp;
-
if(!e.race_laptime)
return;
- cp = e.race_checkpoint;
- recordtime = race_checkpoint_records[cp];
- recordholder = race_checkpoint_recordholders[cp];
+ int cp = e.race_checkpoint;
+ float recordtime = race_checkpoint_records[cp];
+ string recordholder = race_checkpoint_recordholders[cp];
if(recordholder == e.netname)
recordholder = "";
if(!IS_REAL_CLIENT(e))
return;
- if(!spec)
+ if(!spec && !e.cvar_cl_race_cptimes_onlyself) // don't show spectators the player's personal time
msg_entity = e;
WRITESPECTATABLE_MSG_ONE(msg_entity, {
WriteHeader(MSG_ONE, TE_CSQC_RACE);
WriteInt24_t(MSG_ONE, recordtime);
WriteString(MSG_ONE, recordholder);
});
+
+ if(!spec && e.cvar_cl_race_cptimes_onlyself) // don't send to spectators!
+ {
+ recordtime = e.race_checkpoint_record[cp];
+
+ // not spectatable
+ msg_entity = e;
+ WriteHeader(MSG_ONE, TE_CSQC_RACE);
+ WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_NEXT_SELF_QUALIFYING);
+ WriteByte(MSG_ONE, race_CheckpointNetworkID(cp)); // checkpoint the player will be at next
+ WriteInt24_t(MSG_ONE, recordtime);
+ }
}
void race_send_recordtime(float msg)
}
}
- float recordtime;
- string recordholder;
if(g_race_qualifying)
{
+ float recordtime;
+ float myrecordtime;
+ string recordholder;
+
if(tvalid)
{
recordtime = race_checkpoint_records[cp];
+ myrecordtime = e.race_checkpoint_record[cp];
recordholder = strcat1(race_checkpoint_recordholders[cp]); // make a tempstring copy, as we'll possibly strunzone it!
if(recordholder == e.netname)
recordholder = "";
strunzone(race_checkpoint_recordholders[cp]);
race_checkpoint_recordholders[cp] = strzone(e.netname);
if(g_race_qualifying)
- {
FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it) && it.race_checkpoint == cp, LAMBDA(race_SendNextCheckpoint(it, 0)));
- }
}
+
+ if(t < myrecordtime || myrecordtime == 0)
+ e.race_checkpoint_record[cp] = t; // resending done below
}
}
else
// dummies
t = 0;
recordtime = 0;
+ myrecordtime = 0;
recordholder = "";
}
msg_entity = e;
if(g_race_qualifying)
{
- WRITESPECTATABLE_MSG_ONE(msg_entity, {
+ WRITESPECTATABLE_MSG_ONE(e, {
+ if(it == e && e.cvar_cl_race_cptimes_onlyself)
+ continue;
WriteHeader(MSG_ONE, TE_CSQC_RACE);
WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_HIT_QUALIFYING);
WriteByte(MSG_ONE, race_CheckpointNetworkID(cp)); // checkpoint the player now is at
WriteInt24_t(MSG_ONE, recordtime); // previously best time
WriteString(MSG_ONE, recordholder); // record holder
});
+
+ if(e.cvar_cl_race_cptimes_onlyself)
+ {
+ msg_entity = e;
+ WriteHeader(MSG_ONE, TE_CSQC_RACE);
+ WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_HIT_SELF_QUALIFYING);
+ WriteByte(MSG_ONE, race_CheckpointNetworkID(cp)); // checkpoint the player now is at
+ WriteInt24_t(MSG_ONE, t); // time to that intermediate
+ WriteInt24_t(MSG_ONE, myrecordtime); // previously best time
+ }
}
}
}
else // RACE! Not Qualifying
{
float mylaps, lother, othtime;
- entity oth;
- oth = race_checkpoint_lastplayers[cp];
+ entity oth = race_checkpoint_lastplayers[cp];
if(oth)
{
mylaps = PlayerScore_Add(e, SP_RACE_LAPS, 0);
{
WriteInt24_t(MSG_ONE, 0);
WriteByte(MSG_ONE, 0);
- WriteString(MSG_ONE, "");
+ WriteByte(MSG_ONE, 0);
}
else
{
WriteInt24_t(MSG_ONE, TIME_ENCODE(time - race_checkpoint_lasttimes[cp]));
WriteByte(MSG_ONE, mylaps - lother);
- WriteString(MSG_ONE, oth.netname); // record holder
+ WriteByte(MSG_ONE, etof(oth)); // record holder
}
});
}
{
WriteInt24_t(MSG_ONE, 0);
WriteByte(MSG_ONE, 0);
- WriteString(MSG_ONE, "");
+ WriteByte(MSG_ONE, 0);
}
else
{
WriteInt24_t(MSG_ONE, TIME_ENCODE(time - othtime));
WriteByte(MSG_ONE, lother - mylaps);
- WriteString(MSG_ONE, e.netname); // record holder
+ WriteByte(MSG_ONE, etof(e) - 1); // record holder
}
});
}
});
}
-void dumpsurface(entity e)
-{
- float n, si, ni;
- vector norm, vec;
- LOG_INFO("Surfaces of ", etos(e), ":\n");
-
- LOG_INFO("TEST = ", ftos(getsurfacenearpoint(e, '0 0 0')), "\n");
-
- for(si = 0; ; ++si)
- {
- n = getsurfacenumpoints(e, si);
- if(n <= 0)
- break;
- LOG_INFO(" Surface ", ftos(si), ":\n");
- norm = getsurfacenormal(e, si);
- LOG_INFO(" Normal = ", vtos(norm), "\n");
- for(ni = 0; ni < n; ++ni)
- {
- vec = getsurfacepoint(e, si, ni);
- LOG_INFO(" Point ", ftos(ni), " = ", vtos(vec), " (", ftos(norm * vec), ")\n");
- }
- }
-}
-
void checkpoint_passed(entity this, entity player)
{
if(player.personal && autocvar_g_allow_checkpoints)
return; // practice mode!
- string oldmsg;
- entity cp;
-
if(player.classname == "porto")
{
// do not allow portalling through checkpoints
return;
}
+ string oldmsg; // used twice
+
/*
* Trigger targets
*/
this.race_checkpoint = player.race_checkpoint;
}
- float largest_cp_id = 0;
- float cp_amount = 0;
- for(cp = NULL; (cp = find(cp, classname, "target_checkpoint"));)
+ int cp_amount = 0, largest_cp_id = 0;
+ IL_EACH(g_race_targets, it.classname == "target_checkpoint",
{
cp_amount += 1;
- if(cp.race_checkpoint > largest_cp_id) // update the finish id if someone hit a new checkpoint
+ if(it.race_checkpoint > largest_cp_id) // update the finish id if someone hit a new checkpoint
{
- largest_cp_id = cp.race_checkpoint;
- for(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;
-
- for(cp = NULL; (cp = find(cp, classname, "target_checkpoint"));)
+ if(!largest_cp_id)
{
- if(cp.race_checkpoint == -2) // set defragcpexists to -1 so that the cp id file will be rewritten when someone finishes
- defragcpexists = -1;
+ IL_EACH(g_race_targets, it.classname == "target_checkpoint",
+ {
+ if(it.race_checkpoint == -2) // set defragcpexists to -1 so that the cp id file will be rewritten when someone finishes
+ defragcpexists = -1;
+ });
}
+
+ largest_cp_id = it.race_checkpoint;
+ IL_EACH(g_race_targets, it.classname == "target_stopTimer",
+ {
+ it.race_checkpoint = largest_cp_id + 1; // finish line
+ });
+ race_highest_checkpoint = largest_cp_id + 1;
+ race_timed_checkpoint = largest_cp_id + 1;
}
- }
- if(cp_amount == 0)
+ });
+
+ if(!cp_amount)
{
- for(cp = NULL; (cp = find(cp, classname, "target_stopTimer"));)
- cp.race_checkpoint = 1;
+ IL_EACH(g_race_targets, it.classname == "target_stopTimer",
+ {
+ it.race_checkpoint = 1;
+ });
race_highest_checkpoint = 1;
race_timed_checkpoint = 1;
}
defragcpexists = fh = fopen(strcat("maps/", GetMapname(), ".defragcp"), FILE_WRITE);
if(fh >= 0)
{
- for(cp = NULL; (cp = find(cp, classname, "target_checkpoint"));)
- fputs(fh, strcat(cp.targetname, " ", ftos(cp.race_checkpoint), "\n"));
+ IL_EACH(g_race_targets, it.classname == "target_checkpoint",
+ {
+ fputs(fh, strcat(it.targetname, " ", ftos(it.race_checkpoint), "\n"));
+ });
}
fclose(fh);
}