1 .float race_checkpoint; // player: next checkpoint that has to be reached
4 float race_checkpoint_records[256];
5 string race_checkpoint_recordholders[256];
7 float race_highest_checkpoint;
9 void race_SendNextCheckpoint(entity e)
15 if(clienttype(e) != CLIENTTYPE_REAL)
21 cp = e.race_checkpoint;
22 recordtime = race_checkpoint_records[cp];
23 recordholder = race_checkpoint_recordholders[cp];
25 recordtime = stof(db_get(ServerProgsDB, strcat(GetMapname(), "/racerecord/", ftos(cp), "/time")));
26 recordholder = db_get(ServerProgsDB, strcat(GetMapname(), "/racerecord/", ftos(cp), "/netname"));
28 if(recordholder == e.netname)
32 WriteByte(MSG_ONE, SVC_TEMPENTITY);
33 WriteByte(MSG_ONE, TE_CSQC_RACE);
34 WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_NEXT);
35 WriteByte(MSG_ONE, cp); // checkpoint the player will be at next
36 WriteShort(MSG_ONE, recordtime);
37 WriteString(MSG_ONE, recordholder);
40 void race_SendTime(entity e, float cp, float t, float tvalid)
42 t = floor(0.5 + 10 * t); // make integer
45 if(cp == 0) // finish line
48 s = PlayerScore_Add(e, SP_RACE_FASTEST, 0);
50 PlayerScore_Add(e, SP_RACE_FASTEST, t - s);
51 PlayerScore_Add(e, SP_RACE_LAPS, 1);
59 recordtime = race_checkpoint_records[cp];
60 recordholder = strcat1(race_checkpoint_recordholders[cp]); // make a tempstring copy, as we'll possibly strunzone it!
61 if(recordholder == e.netname)
64 if(t < recordtime || recordtime == 0)
66 race_checkpoint_records[cp] = t;
67 if(race_checkpoint_recordholders[cp])
68 strunzone(race_checkpoint_recordholders[cp]);
69 race_checkpoint_recordholders[cp] = strzone(e.netname);
74 grecordtime = stof(db_get(ServerProgsDB, strcat(GetMapname(), "/racerecord/time")));
75 grecordholder = db_get(ServerProgsDB, strcat(GetMapname(), "/racerecord/netname"));
76 if(grecordholder == e.netname)
78 if(grecordholder == "")
80 bprint(e.netname, "^7 set the all-time fastest lap record with ", mmsss(t), "\n");
82 bprint(e.netname, "^7 broke his all-time fastest lap record with ", mmsss(t), "\n");
84 bprint(e.netname, "^7 broke ", grecordholder, "^7's all-time fastest lap record with ", mmsss(t), "\n");
85 db_put(ServerProgsDB, strcat(GetMapname(), "/racerecord/time"), ftos(t));
86 db_put(ServerProgsDB, strcat(GetMapname(), "/racerecord/netname"), e.netname);
90 FOR_EACH_REALPLAYER(p)
91 if(p.race_checkpoint == cp)
92 race_SendNextCheckpoint(p);
103 if(clienttype(e) != CLIENTTYPE_REAL)
107 WriteByte(MSG_ONE, SVC_TEMPENTITY);
108 WriteByte(MSG_ONE, TE_CSQC_RACE);
109 WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_HIT);
110 WriteByte(MSG_ONE, cp); // checkpoint the player now is at
111 WriteShort(MSG_ONE, t); // time to that intermediate
112 WriteShort(MSG_ONE, recordtime); // previously best time
113 WriteString(MSG_ONE, recordholder); // record holder
114 print(race_checkpoint_recordholders[cp], "\n");
117 void race_ClearTime(entity e)
119 e.race_checkpoint = -1;
122 if(clienttype(e) != CLIENTTYPE_REAL)
126 WriteByte(MSG_ONE, SVC_TEMPENTITY);
127 WriteByte(MSG_ONE, TE_CSQC_RACE);
128 WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_CLEAR); // next
131 void checkpoint_touch()
133 if(other.classname != "player")
136 if(other.race_checkpoint == -1 || other.race_checkpoint == self.cnt)
138 if(self.cnt == race_highest_checkpoint)
139 other.race_checkpoint = 0;
141 other.race_checkpoint = self.cnt + 1;
143 race_SendTime(other, self.cnt, time - other.race_laptime, !!other.race_laptime);
145 if(!self.cnt) // finish line
146 other.race_laptime = time;
148 race_SendNextCheckpoint(other);
150 else if(other.race_checkpoint == self.cnt + 1)
154 else if(other.race_checkpoint == 0 && self.cnt == race_highest_checkpoint)
160 Damage (other, self, self, 10000, DEATH_HURTTRIGGER, other.origin, '0 0 0');
164 void checkpoint_use()
170 void spawnfunc_trigger_race_checkpoint()
177 self.use = checkpoint_use;
179 self.touch = checkpoint_touch;
181 o = (self.absmin + self.absmax) * 0.5;
182 traceline(o, o - '0 0 1' * (o_z - self.absmin_z), MOVE_NORMAL, self);
183 o = trace_endpos - '0 0 1' * PL_MIN_z;
184 self.nearestwaypoint = waypoint_spawn(o, o, WAYPOINTFLAG_GENERATED);
185 self.nearestwaypointtimeout = time + 1000000000;
188 self.message = "went backwards";
190 if(self.cnt > race_highest_checkpoint)
191 race_highest_checkpoint = self.cnt;
194 void race_PreparePlayer()
198 race_ClearTime(self);