r4059 - in trunk/data: qcsrc/client qcsrc/common qcsrc/server scripts
DONOTREPLY at icculus.org
DONOTREPLY at icculus.org
Fri Aug 8 10:48:44 EDT 2008
Author: div0
Date: 2008-08-08 10:48:43 -0400 (Fri, 08 Aug 2008)
New Revision: 4059
Modified:
trunk/data/qcsrc/client/Defs.qc
trunk/data/qcsrc/client/Main.qc
trunk/data/qcsrc/client/sbar.qc
trunk/data/qcsrc/common/constants.qh
trunk/data/qcsrc/common/mapinfo.qc
trunk/data/qcsrc/common/mapinfo.qh
trunk/data/qcsrc/common/util.qc
trunk/data/qcsrc/common/util.qh
trunk/data/qcsrc/server/bots.qc
trunk/data/qcsrc/server/cl_client.qc
trunk/data/qcsrc/server/defs.qh
trunk/data/qcsrc/server/havocbot_roles.qc
trunk/data/qcsrc/server/progs.src
trunk/data/qcsrc/server/scores.qc
trunk/data/qcsrc/server/scores_rules.qc
trunk/data/qcsrc/server/teamplay.qc
trunk/data/scripts/entities.def
Log:
"race" game mode (beginning)
Modified: trunk/data/qcsrc/client/Defs.qc
===================================================================
--- trunk/data/qcsrc/client/Defs.qc 2008-08-08 12:08:40 UTC (rev 4058)
+++ trunk/data/qcsrc/client/Defs.qc 2008-08-08 14:48:43 UTC (rev 4059)
@@ -174,3 +174,8 @@
float caps_team1, caps_team2;
float configdb;
string shortmapname;
+
+float race_checkpoint;
+float race_time;
+float race_laptime;
+float race_checkpointtime;
Modified: trunk/data/qcsrc/client/Main.qc
===================================================================
--- trunk/data/qcsrc/client/Main.qc 2008-08-08 12:08:40 UTC (rev 4058)
+++ trunk/data/qcsrc/client/Main.qc 2008-08-08 14:48:43 UTC (rev 4059)
@@ -565,6 +565,21 @@
db_put(configdb, strcat("/s/", key), "1");
}
+void Net_ReadRace()
+{
+ float checkpoint, t;
+
+ race_checkpoint = ReadByte();
+ race_time = ReadShort();
+
+ race_checkpointtime = time;
+
+ if(race_checkpoint == 0)
+ race_laptime = time; // valid
+ else if(race_checkpoint == 255)
+ race_laptime = 0; // invalid
+}
+
// CSQC_Parse_TempEntity : Handles all temporary entity network data in the CSQC layer.
// You must ALWAYS first acquire the temporary ID, which is sent as a byte.
// Return value should be 1 if CSQC handled the temporary entity, otherwise return 0 to have the engine process the event.
@@ -595,6 +610,10 @@
Net_ReadScoresInfo();
bHandled = true;
break;
+ case TE_CSQC_RACE:
+ Net_ReadRace();
+ bHandled = true;
+ break;
default:
// No special logic for this temporary entity; return 0 so the engine can handle it
bHandled = false;
Modified: trunk/data/qcsrc/client/sbar.qc
===================================================================
--- trunk/data/qcsrc/client/sbar.qc 2008-08-08 12:08:40 UTC (rev 4058)
+++ trunk/data/qcsrc/client/sbar.qc 2008-08-08 14:48:43 UTC (rev 4059)
@@ -204,6 +204,13 @@
vl = left.scores[ps_primary];
vr = right.scores[ps_primary];
+ if(scores_flags[ps_primary] & SFL_ZERO_IS_WORST)
+ {
+ if(vl == 0 && vr != 0)
+ return 1;
+ if(vl != 0 && vr == 0)
+ return 0;
+ }
if(vl > vr)
return IS_INCREASING(scores_flags[ps_primary]);
if(vl < vr)
@@ -211,6 +218,13 @@
vl = left.scores[ps_secondary];
vr = right.scores[ps_secondary];
+ if(scores_flags[ps_secondary] & SFL_ZERO_IS_WORST)
+ {
+ if(vl == 0 && vr != 0)
+ return 1;
+ if(vl != 0 && vr == 0)
+ return 0;
+ }
if(vl > vr)
return IS_INCREASING(scores_flags[ps_secondary]);
if(vl < vr)
@@ -548,7 +562,7 @@
else
sbar_field_rgb = '1 1 1';
if(!tmp)
- if(f & (SFL_HIDE_ZERO | SFL_RANK))
+ if(f & (SFL_HIDE_ZERO | SFL_RANK | SFL_TIME))
return "";
if(f & SFL_RANK)
{
@@ -565,6 +579,10 @@
else
return strcat(str, "th");
}
+ else if(f & SFL_TIME)
+ {
+ return mmsss(tmp);
+ }
return ftos(tmp);
}
//return "error";
@@ -1017,6 +1035,42 @@
drawpic(sbar + '-36 32 0', "gfx/num_colon", '12 12 0', '1 1 1', sbar_alpha_fg, 0);
Sbar_DrawXNum('-24 32 0', seconds, -2, 12, '1 1 1', 1, DRAWFLAG_NORMAL);
}
+
+ if(gametype == GAME_RACE)
+ {
+ if(race_checkpointtime)
+ if(race_checkpoint != 255)
+ {
+ float a;
+ vector m;
+ string s;
+
+ m = '0.5 0 0' * vid_conwidth + '0 0.5 0' * vid_conheight;
+
+ a = bound(0, 2 - (time - race_checkpointtime), 1);
+ drawfont = sbar_bigfont;
+ if(a >= 0)
+ {
+ if(race_checkpoint)
+ s = strcat("Intermediate ", ftos(race_checkpoint));
+ else
+ s = strcat("Finish line");
+ drawstring(m - '0 88 0' - '12 0 0' * stringwidth(s, FALSE), s, '24 24 0', '0 1 0', sbar_alpha_fg * a, 0);
+ if(race_time)
+ {
+ s = mmsss(race_time);
+ drawstring(m - '0 64 0' - '16 0 0' * stringwidth(s, FALSE), s, '32 32 0', '0 1 0', sbar_alpha_fg * a, 0);
+ }
+ }
+
+ if(race_laptime)
+ {
+ s = mmsss(10*(time - race_laptime));
+ drawstring(m - '0 64 0' - '16 0 0' * stringwidth(s, FALSE), s, '32 32 0', '1 1 1', sbar_alpha_fg * (1 - a), 0);
+ }
+ }
+ }
+
sbar = sbar_save;
}
Modified: trunk/data/qcsrc/common/constants.qh
===================================================================
--- trunk/data/qcsrc/common/constants.qh 2008-08-08 12:08:40 UTC (rev 4058)
+++ trunk/data/qcsrc/common/constants.qh 2008-08-08 14:48:43 UTC (rev 4059)
@@ -6,7 +6,8 @@
// Revision 5: mapvote time fix
// Revision 6: more robust against packet loss/delays, also show not yet connected clients
// Revision 7: packet loss column
-#define CSQC_REVISION 7
+// Revision 8: race
+#define CSQC_REVISION 8
// probably put these in common/
// so server/ and client/ can be synced better
@@ -20,6 +21,7 @@
const float GAME_KEYHUNT = 8;
const float GAME_ASSAULT = 9;
const float GAME_ONSLAUGHT = 10;
+const float GAME_RACE = 11;
const float AS_STRING = 1;
const float AS_INT = 2;
@@ -183,6 +185,7 @@
const float TE_CSQC_MAPVOTE = 106;
const float TE_CSQC_CONFIG = 107;
const float TE_CSQC_SCORESINFO = 108;
+const float TE_CSQC_RACE = 109;
const float STAT_KH_KEYS = 32;
const float STAT_CTF_STATE = 33;
@@ -219,6 +222,14 @@
#define SFL_RANK 32
/**
+ * Display as mm:ss.s, value is stored as 10ths of a second (AND 0 is the worst possible value!)
+ */
+#define SFL_TIME 64
+
+// not an extra constant yet
+#define SFL_ZERO_IS_WORST SFL_TIME
+
+/**
* Scoring priority (NOTE: PRIMARY is used for fraglimit)
*/
#define SFL_SORT_PRIO_SECONDARY 4
Modified: trunk/data/qcsrc/common/mapinfo.qc
===================================================================
--- trunk/data/qcsrc/common/mapinfo.qc 2008-08-08 12:08:40 UTC (rev 4058)
+++ trunk/data/qcsrc/common/mapinfo.qc 2008-08-08 14:48:43 UTC (rev 4059)
@@ -421,6 +421,8 @@
++spawnpoints;
else if(v == "info_player_deathmatch")
++spawnpoints;
+ else if(v == "trigger_race_checkpoint")
+ MapInfo_Map_supportedGametypes |= MAPINFO_TYPE_RACE;
else if(v == "weapon_nex")
{ }
else if(v == "weapon_railgun")
@@ -437,7 +439,7 @@
}
diameter = vlen(mapMaxs - mapMins);
- twoBaseModes = MapInfo_Map_supportedGametypes & (MAPINFO_TYPE_CTF | MAPINFO_TYPE_ASSAULT);
+ twoBaseModes = MapInfo_Map_supportedGametypes & (MAPINFO_TYPE_CTF | MAPINFO_TYPE_ASSAULT | MAPINFO_TYPE_RACE);
if(twoBaseModes && (MapInfo_Map_supportedGametypes == twoBaseModes))
{
// we have a CTF-only or Assault-only map. Don't add other modes then,
@@ -522,6 +524,7 @@
else if(t == "kh") return MAPINFO_TYPE_KEYHUNT;
else if(t == "as") return MAPINFO_TYPE_ASSAULT;
else if(t == "ons") return MAPINFO_TYPE_ONSLAUGHT;
+ else if(t == "race") return MAPINFO_TYPE_RACE;
else if(t == "all") return MAPINFO_TYPE_ALL;
else return 0;
}
@@ -567,6 +570,7 @@
if(MapInfo_Map_supportedGametypes & MAPINFO_TYPE_ARENA) fputs(fh, "type arena 10 20\n");
if(MapInfo_Map_supportedGametypes & MAPINFO_TYPE_KEYHUNT) fputs(fh, "type kh 1000 20 3\n");
if(MapInfo_Map_supportedGametypes & MAPINFO_TYPE_ASSAULT) fputs(fh, "type as 20\n");
+ if(MapInfo_Map_supportedGametypes & MAPINFO_TYPE_RACE) fputs(fh, "type race 5 20 0\n");
if(MapInfo_Map_supportedGametypes & MAPINFO_TYPE_ONSLAUGHT) fputs(fh, "type ons 20\n");
fh2 = fopen(strcat("scripts/", pFilename, ".arena"), FILE_READ);
@@ -752,6 +756,8 @@
return MAPINFO_TYPE_KEYHUNT;
else if(cvar("g_onslaught"))
return MAPINFO_TYPE_ONSLAUGHT;
+ else if(cvar("g_race"))
+ return MAPINFO_TYPE_RACE;
else
return MAPINFO_TYPE_DEATHMATCH;
}
@@ -788,6 +794,7 @@
cvar_set("g_keyhunt", (t == MAPINFO_TYPE_KEYHUNT) ? "1" : "0");
cvar_set("g_assault", (t == MAPINFO_TYPE_ASSAULT) ? "1" : "0");
cvar_set("g_onslaught", (t == MAPINFO_TYPE_ONSLAUGHT) ? "1" : "0");
+ cvar_set("g_race", (t == MAPINFO_TYPE_RACE) ? "1" : "0");
}
void MapInfo_LoadMap(string s)
Modified: trunk/data/qcsrc/common/mapinfo.qh
===================================================================
--- trunk/data/qcsrc/common/mapinfo.qh 2008-08-08 12:08:40 UTC (rev 4058)
+++ trunk/data/qcsrc/common/mapinfo.qh 2008-08-08 14:48:43 UTC (rev 4059)
@@ -8,6 +8,7 @@
float MAPINFO_TYPE_KEYHUNT = 128;
float MAPINFO_TYPE_ASSAULT = 256;
float MAPINFO_TYPE_ONSLAUGHT = 512;
+float MAPINFO_TYPE_RACE = 1024;
float MAPINFO_TYPE_ALL = 65535; // this has to include all above bits
float MAPINFO_FEATURE_WEAPONS = 1; // not defined for minstagib-only maps
Modified: trunk/data/qcsrc/common/util.qc
===================================================================
--- trunk/data/qcsrc/common/util.qc 2008-08-08 12:08:40 UTC (rev 4058)
+++ trunk/data/qcsrc/common/util.qc 2008-08-08 14:48:43 UTC (rev 4059)
@@ -422,6 +422,17 @@
else if (g == GAME_KEYHUNT) return "kh";
else if (g == GAME_ONSLAUGHT) return "ons";
else if (g == GAME_ASSAULT) return "as";
+ else if (g == GAME_RACE) return "race";
return "dm";
}
+string mmsss(float tenths)
+{
+ float minutes;
+ string s;
+ tenths = floor(tenths + 0.5);
+ minutes = floor(tenths / 600);
+ tenths -= minutes * 600;
+ s = ftos(1000 + tenths);
+ return strcat(ftos(minutes), ":", substring(s, 1, 2), ".", substring(s, 3, 1));
+}
Modified: trunk/data/qcsrc/common/util.qh
===================================================================
--- trunk/data/qcsrc/common/util.qh 2008-08-08 12:08:40 UTC (rev 4058)
+++ trunk/data/qcsrc/common/util.qh 2008-08-08 14:48:43 UTC (rev 4059)
@@ -57,3 +57,4 @@
#endif
string GametypeNameFromType(float g);
+string mmsss(float t);
Modified: trunk/data/qcsrc/server/bots.qc
===================================================================
--- trunk/data/qcsrc/server/bots.qc 2008-08-08 12:08:40 UTC (rev 4058)
+++ trunk/data/qcsrc/server/bots.qc 2008-08-08 14:48:43 UTC (rev 4059)
@@ -1240,6 +1240,7 @@
e.nearestwaypointtimeout = time + random() * 3 + 5;
}
//dprint(e.classname, " ", ftos(f));
+ //dprint("-- checking ", e.classname, " (with cost ", ftos(e.nearestwaypoint.wpcost), ")\n");
if (e.nearestwaypoint)
if (e.nearestwaypoint.wpcost < 10000000)
{
Modified: trunk/data/qcsrc/server/cl_client.qc
===================================================================
--- trunk/data/qcsrc/server/cl_client.qc 2008-08-08 12:08:40 UTC (rev 4058)
+++ trunk/data/qcsrc/server/cl_client.qc 2008-08-08 14:48:43 UTC (rev 4059)
@@ -691,6 +691,8 @@
self.lms_traveled_distance = 0;
self.speedrunning = FALSE;
+ race_PreparePlayer();
+
if(cvar("spawn_debug"))
{
sprint(self, strcat("spawnpoint origin: ", vtos(spot.origin), "\n"));
Modified: trunk/data/qcsrc/server/defs.qh
===================================================================
--- trunk/data/qcsrc/server/defs.qh 2008-08-08 12:08:40 UTC (rev 4058)
+++ trunk/data/qcsrc/server/defs.qh 2008-08-08 14:48:43 UTC (rev 4059)
@@ -15,7 +15,7 @@
// Globals
-float g_domination, g_ctf, g_tdm, g_keyhunt, g_onslaught, g_assault, g_arena, g_lms, g_runematch;
+float g_domination, g_ctf, g_tdm, g_keyhunt, g_onslaught, g_assault, g_arena, g_lms, g_runematch, g_race;
float g_cloaked, g_footsteps, g_jump_grunt, g_grappling_hook, g_instagib, g_laserguided_missile, g_midair, g_minstagib, g_nixnex, g_nixnex_with_laser, g_norecoil, g_rocketarena, g_vampire, g_minstagib_invis_alpha;
float g_tourney;
float g_ctf_win_mode;
Modified: trunk/data/qcsrc/server/havocbot_roles.qc
===================================================================
--- trunk/data/qcsrc/server/havocbot_roles.qc 2008-08-08 12:08:40 UTC (rev 4058)
+++ trunk/data/qcsrc/server/havocbot_roles.qc 2008-08-08 14:48:43 UTC (rev 4059)
@@ -532,11 +532,49 @@
}
};
+//Race:
+//go to next checkpoint, and annoy enemies
+.float race_checkpoint;
+void havocbot_role_race()
+{
+ entity e;
+ if (self.bot_strategytime < time)
+ {
+ self.bot_strategytime = time + cvar("bot_ai_strategyinterval");
+ navigation_goalrating_start();
+ /*
+ havocbot_goalrating_items(100, self.origin, 10000);
+ havocbot_goalrating_enemyplayers(500, self.origin, 20000);
+ */
+
+ for(e = world; (e = find(e, classname, "trigger_race_checkpoint")) != world; )
+ {
+ if(e.cnt == self.race_checkpoint)
+ {
+ print("found good checkpoint\n");
+ navigation_routerating(e, 1000000, 5000);
+ }
+ else if(self.race_checkpoint == -1)
+ {
+ print("found good checkpoint -1\n");
+ navigation_routerating(e, 1000000, 5000);
+ }
+ }
+
+ navigation_goalrating_end();
+ }
+};
+
void havocbot_chooserole_dm()
{
self.havocbot_role = havocbot_role_dm;
};
+void havocbot_chooserole_race()
+{
+ self.havocbot_role = havocbot_role_race;
+};
+
void havocbot_chooserole_dom()
{
self.havocbot_role = havocbot_role_dom;
@@ -759,6 +797,8 @@
havocbot_chooserole_dom();
else if (g_keyhunt)
havocbot_chooserole_kh();
+ else if (g_race)
+ havocbot_chooserole_race();
else // assume anything else is deathmatch
havocbot_chooserole_dm();
};
Modified: trunk/data/qcsrc/server/progs.src
===================================================================
--- trunk/data/qcsrc/server/progs.src 2008-08-08 12:08:40 UTC (rev 4058)
+++ trunk/data/qcsrc/server/progs.src 2008-08-08 14:48:43 UTC (rev 4059)
@@ -22,6 +22,8 @@
ipban.qh
+race.qh
+
keyhunt.qh
antilag.qh
@@ -122,7 +124,9 @@
t_halflife.qc
t_quake.qc
+race.qc
+
//// tZork Turrets ////
tturrets/include/turret_tturrets.qh
Modified: trunk/data/qcsrc/server/scores.qc
===================================================================
--- trunk/data/qcsrc/server/scores.qc 2008-08-08 12:08:40 UTC (rev 4058)
+++ trunk/data/qcsrc/server/scores.qc 2008-08-08 14:48:43 UTC (rev 4059)
@@ -29,6 +29,20 @@
previous_y = fieldflags & SFL_SORT_PRIO_MASK;
+ if(fieldflags & SFL_ZERO_IS_WORST)
+ {
+ if(t1.field == 0)
+ {
+ previous_x = -1;
+ return previous;
+ }
+ else if(t2.field == 0)
+ {
+ previous_x = +1;
+ return previous;
+ }
+ }
+
if(fieldflags & SFL_LOWER_IS_BETTER)
previous_x = (t2.field - t1.field);
else
Modified: trunk/data/qcsrc/server/scores_rules.qc
===================================================================
--- trunk/data/qcsrc/server/scores_rules.qc 2008-08-08 12:08:40 UTC (rev 4058)
+++ trunk/data/qcsrc/server/scores_rules.qc 2008-08-08 14:48:43 UTC (rev 4059)
@@ -119,3 +119,14 @@
ScoreInfo_SetLabel_PlayerScore(SP_KH_LOSSES, "losses", SFL_LOWER_IS_BETTER);
ScoreRules_basics_end();
}
+
+// Race stuff
+#define SP_RACE_LAPS 4
+#define SP_RACE_FASTEST 5
+void ScoreRules_race()
+{
+ ScoreRules_basics(0, 0);
+ ScoreInfo_SetLabel_PlayerScore(SP_RACE_LAPS, "laps", SFL_SORT_PRIO_PRIMARY);
+ ScoreInfo_SetLabel_PlayerScore(SP_RACE_FASTEST, "fastest", SFL_SORT_PRIO_SECONDARY | SFL_LOWER_IS_BETTER | SFL_TIME);
+ ScoreRules_basics_end();
+}
Modified: trunk/data/qcsrc/server/teamplay.qc
===================================================================
--- trunk/data/qcsrc/server/teamplay.qc 2008-08-08 12:08:40 UTC (rev 4058)
+++ trunk/data/qcsrc/server/teamplay.qc 2008-08-08 14:48:43 UTC (rev 4059)
@@ -97,6 +97,7 @@
cvar_set("g_keyhunt", "0");
cvar_set("g_assault", "0");
cvar_set("g_onslaught", "0");
+ cvar_set("g_race", "0");
cvar_set("teamplay", "0");
}
@@ -263,6 +264,17 @@
gamemode_name = "Onslaught";
teams_matter = 1;
}
+ else if(game == GAME_RACE || cvar("g_race"))
+ {
+ ResetGameCvars();
+ game = GAME_RACE;
+ cvar_set("g_race", "1");
+ fraglimit_override = cvar("g_race_laps_limit");
+ gamemode_name = "Race";
+ teams_matter = 0;
+
+ ScoreRules_race();
+ }
else
{
// we can only assume...
@@ -298,6 +310,7 @@
g_keyhunt = cvar("g_keyhunt");
g_onslaught = cvar("g_onslaught");
g_assault = cvar("g_assault");
+ g_race = cvar("g_race");
g_arena = cvar("g_arena");
cache_mutatormsg = strzone("");
Modified: trunk/data/scripts/entities.def
===================================================================
--- trunk/data/scripts/entities.def 2008-08-08 12:08:40 UTC (rev 4058)
+++ trunk/data/scripts/entities.def 2008-08-08 14:48:43 UTC (rev 4059)
@@ -885,3 +885,10 @@
_celshader: Sets the cel shader used for this geometry. Note: omit the "textures/" prefix.
*/
+/*QUAKED trigger_race_checkpoint (0 1 0) ?
+A checkpoint, for the race game mode. Be sure to make them quite long, so they actually catch a player reliably!
+-------- KEYS --------
+cnt: Number of the checkpoint. 0 for finish line, and at least two other checkpoints have to exist. They MUST be touched in sequential order!
+message: Death message, when touching checkpoints in the wrong order.
+*/
+
More information about the nexuiz-commits
mailing list