r4086 - in trunk/data: . qcsrc/server
DONOTREPLY at icculus.org
DONOTREPLY at icculus.org
Sun Aug 10 06:07:09 EDT 2008
Author: div0
Date: 2008-08-10 06:07:06 -0400 (Sun, 10 Aug 2008)
New Revision: 4086
Modified:
trunk/data/defaultNexuiz.cfg
trunk/data/qcsrc/server/arena.qc
trunk/data/qcsrc/server/cl_client.qc
trunk/data/qcsrc/server/cl_weaponsystem.qc
trunk/data/qcsrc/server/defs.qh
trunk/data/qcsrc/server/g_subs.qc
trunk/data/qcsrc/server/havocbot.qc
trunk/data/qcsrc/server/miscfunctions.qc
trunk/data/qcsrc/server/race.qc
trunk/data/qcsrc/server/race.qh
trunk/data/qcsrc/server/scores.qc
trunk/data/qcsrc/server/scores.qh
trunk/data/qcsrc/server/scores_rules.qc
Log:
race: "g_race_qualifying 2" makes qualifying-then-race mode (using new special entities). Race still displays stuff wrong, though - it shows lap times, it SHOULD show times to the next enemy in race (not qualifying) mode.
Modified: trunk/data/defaultNexuiz.cfg
===================================================================
--- trunk/data/defaultNexuiz.cfg 2008-08-09 23:24:29 UTC (rev 4085)
+++ trunk/data/defaultNexuiz.cfg 2008-08-10 10:07:06 UTC (rev 4086)
@@ -486,9 +486,11 @@
// race
set g_race 0
-set g_race_qualifying 0
+set g_race_qualifying 1
// Qualifying uses timelimit, and the one with the best time wins. Fraglimit is nonfunctional then.
// Normal race uses fraglimit as a limit for the laps.
+// Special mode: g_race_qualifying 2. First runs a qualifying, after
+// ready-restart it turns into a race. TODO not done yet (e.g. timing display)
set g_race_teams 0 // when 2, 3, or 4, the race is played as a team game (the team members can add up their laps)
// server game balance settings
Modified: trunk/data/qcsrc/server/arena.qc
===================================================================
--- trunk/data/qcsrc/server/arena.qc 2008-08-09 23:24:29 UTC (rev 4085)
+++ trunk/data/qcsrc/server/arena.qc 2008-08-10 10:07:06 UTC (rev 4086)
@@ -28,10 +28,12 @@
if(g_arena)
if(cvar("g_arena_warmup"))
warmup = time + cvar("g_arena_warmup");
-
+
lms_lowest_lives = 999;
lms_next_place = player_count;
+ race_ReadyRestart();
+
self = nextent(world);
while(self)
{
@@ -108,8 +110,6 @@
FOR_EACH_CLIENT(self) {
if(self.flags & FL_CLIENT) // reset all players
{
- if(g_race)
- race_PreparePlayer();
if(g_arena)
{
if(self.spawned)
Modified: trunk/data/qcsrc/server/cl_client.qc
===================================================================
--- trunk/data/qcsrc/server/cl_client.qc 2008-08-09 23:24:29 UTC (rev 4085)
+++ trunk/data/qcsrc/server/cl_client.qc 2008-08-10 10:07:06 UTC (rev 4086)
@@ -50,29 +50,39 @@
// filter out spots for assault
if(spot.target != "") {
local entity ent;
+ float good;
ent = find(world, targetname, spot.target);
- if(!ent)
- {
- return -1;
- }
while(ent) {
if(ent.classname == "target_objective")
{
if(ent.health < 0 || ent.health >= ASSAULT_VALUE_INACTIVE)
return -1;
+ good = 1;
}
else if(ent.classname == "trigger_race_checkpoint")
{
if(self.classname == "player") // spectators may spawn everywhere
- if(ent.cnt != race_PreviousCheckpoint(self.race_checkpoint))
- // checkpoint -1 players (freshly spawned) spawn close to finish!
- return -1;
+ {
+ if(ent.race_checkpoint != race_PreviousCheckpoint(self.race_checkpoint))
+ return -1;
+ print(ftos(race_place_valid), ": ");
+ print(ftos(self.race_place), " <-> ");
+ print(ftos(spot.race_place), "\n");
+ if(race_place_valid && (spot.race_place != self.race_place))
+ return -1;
+ if(!race_place_valid && (spot.race_place != 0))
+ return -1;
+ }
+ good = 1;
}
else
{
}
ent = find(ent, targetname, spot.target);
}
+
+ if(!good)
+ return -1;
}
player = playerlist;
@@ -374,6 +384,9 @@
void PutObserverInServer (void)
{
entity spot;
+
+ race_PreSpawnObserver();
+
spot = SelectSpawnPoint (TRUE);
if(!spot)
error("No spawnpoints for observers?!?\n");
@@ -464,9 +477,6 @@
self.viewzoom = 1;
self.wantswelcomemessage = 1;
- if(g_race)
- race_PreparePlayer();
-
if(g_arena)
{
if(self.version_mismatch)
@@ -590,9 +600,7 @@
if(self.classname == "player") {
entity spot;
- if(g_race)
- if(self.killcount == -666)
- race_PreparePlayer();
+ race_PreSpawn();
spot = SelectSpawnPoint (FALSE);
if(!spot)
@@ -703,16 +711,6 @@
self.statdraintime = time + 5;
self.BUTTON_ATCK = self.BUTTON_JUMP = self.BUTTON_ATCK2 = 0;
- if(g_race)
- if(self.killcount != -666)
- {
- if(spot.target == "")
- // let the player run without timing, if he did not spawn at a targetting spawnpoint
- race_PreparePlayer();
- else
- race_RetractPlayer();
- }
-
if(self.killcount == -666) {
PlayerScore_Clear(self);
self.killcount = 0;
@@ -731,6 +729,8 @@
self.lms_traveled_distance = 0;
self.speedrunning = FALSE;
+ race_PostSpawn(spot);
+
if(cvar("spawn_debug"))
{
sprint(self, strcat("spawnpoint origin: ", vtos(spot.origin), "\n"));
@@ -1061,6 +1061,8 @@
bot_clientconnect();
+ race_PreSpawnObserver();
+
//if(g_domination)
// dom_player_join_team(self);
@@ -2195,6 +2197,8 @@
=============
*/
.float idlekick_lasttimeleft;
+.float race_penalty;
+.float race_penalty_nagged;
void PlayerPostThink (void)
{
// Savage: Check for nameless players
@@ -2246,12 +2250,35 @@
if(time < restart_countdown) {
if (!cvar("sv_ready_restart_after_countdown"))
{
+ if(self.movement != '0 0 0' && g_race && !g_race_qualifying)
+ {
+ if(time < restart_countdown - 2)
+ {
+ if(!self.race_penalty_nagged)
+ {
+ centerprint_atprio(self, CENTERPRIO_IDLEKICK, "^1DO NOT MOVE DURING THE COUNTDOWN.");
+ self.race_penalty_nagged = 1;
+ }
+ }
+ else if(!self.race_penalty)
+ {
+ centerprint_atprio(self, CENTERPRIO_IDLEKICK, "^1FIVE SECONDS PENALTY.");
+ self.race_penalty = time + 5;
+ }
+ }
self.movetype = MOVETYPE_NONE;
self.velocity = '0 0 0';
self.avelocity = '0 0 0';
self.movement = '0 0 0';
}
}
+ else if (time < self.race_penalty)
+ {
+ self.movetype = MOVETYPE_NONE;
+ self.velocity = '0 0 0';
+ self.avelocity = '0 0 0';
+ self.movement = '0 0 0';
+ }
else
{
//allow the player to move again if sv_ready_restart_after_countdown is not used and countdown is over
@@ -2261,6 +2288,8 @@
{
self.movetype = MOVETYPE_WALK;
}
+ self.race_penalty = 0;
+ self.race_penalty_nagged = 0;
}
}
}
Modified: trunk/data/qcsrc/server/cl_weaponsystem.qc
===================================================================
--- trunk/data/qcsrc/server/cl_weaponsystem.qc 2008-08-09 23:24:29 UTC (rev 4085)
+++ trunk/data/qcsrc/server/cl_weaponsystem.qc 2008-08-10 10:07:06 UTC (rev 4086)
@@ -422,12 +422,13 @@
};
// perform weapon to attack (weaponstate and attack_finished check is here)
+.float race_penalty;
float weapon_prepareattack(float secondary, float attacktime)
{
//if sv_ready_restart_after_countdown is set, don't allow the player to shoot
//if all players readied up and the countdown is running
if (cvar("sv_ready_restart_after_countdown"))
- if(time < restart_countdown) {
+ if(time < restart_countdown || time < self.race_penalty) {
return FALSE;
}
Modified: trunk/data/qcsrc/server/defs.qh
===================================================================
--- trunk/data/qcsrc/server/defs.qh 2008-08-09 23:24:29 UTC (rev 4085)
+++ trunk/data/qcsrc/server/defs.qh 2008-08-10 10:07:06 UTC (rev 4086)
@@ -19,6 +19,7 @@
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;
+float g_race_qualifying;
float tourneyInMatchStage;
float sv_cheats;
Modified: trunk/data/qcsrc/server/g_subs.qc
===================================================================
--- trunk/data/qcsrc/server/g_subs.qc 2008-08-09 23:24:29 UTC (rev 4085)
+++ trunk/data/qcsrc/server/g_subs.qc 2008-08-10 10:07:06 UTC (rev 4086)
@@ -386,6 +386,7 @@
// force relinking
setorigin(self, self.origin);
setsize (self, self.mins, self.maxs);
+ print("size: ", vtos(self.maxs), "\n");
}
self.movetype = MOVETYPE_NONE;
self.modelindex = 0;
Modified: trunk/data/qcsrc/server/havocbot.qc
===================================================================
--- trunk/data/qcsrc/server/havocbot.qc 2008-08-09 23:24:29 UTC (rev 4085)
+++ trunk/data/qcsrc/server/havocbot.qc 2008-08-10 10:07:06 UTC (rev 4086)
@@ -258,7 +258,7 @@
local entity head, best;
local float rating, bestrating;
local vector eye, v;
- if (cvar("bot_nofire"))
+ if (cvar("bot_nofire") || independent_players)
{
self.enemy = world;
return;
@@ -457,7 +457,7 @@
if (self.bot_aimtarg)
{
weapon_action(self.weapon, WR_AIM);
- if (cvar("bot_nofire"))
+ if (cvar("bot_nofire") || independent_players)
{
self.BUTTON_ATCK = FALSE;
self.BUTTON_ATCK2 = FALSE;
Modified: trunk/data/qcsrc/server/miscfunctions.qc
===================================================================
--- trunk/data/qcsrc/server/miscfunctions.qc 2008-08-09 23:24:29 UTC (rev 4085)
+++ trunk/data/qcsrc/server/miscfunctions.qc 2008-08-10 10:07:06 UTC (rev 4086)
@@ -260,6 +260,18 @@
if(g_ctf || g_assault || g_onslaught || g_domination)
if(self.team)
have_team_spawns = 1;
+
+ if(cvar("r_showbboxes"))
+ {
+ // show where spawnpoints point at too
+ makevectors(self.angles);
+ entity e;
+ e = spawn();
+ e.classname = "info_player_foo";
+ setorigin(e, self.origin + v_forward * 24);
+ setsize(e, '-8 -8 -8', '8 8 8');
+ e.solid = SOLID_TRIGGER;
+ }
}
#define strstr strstrofs
@@ -719,6 +731,7 @@
sv_pogostick = cvar("sv_pogostick");
sv_doublejump = cvar("sv_doublejump");
g_ctf_win_mode = cvar("g_ctf_win_mode");
+ g_race_qualifying = cvar("g_race_qualifying");
g_pickup_shells = cvar("g_pickup_shells");
g_pickup_shells_max = cvar("g_pickup_shells_max");
Modified: trunk/data/qcsrc/server/race.qc
===================================================================
--- trunk/data/qcsrc/server/race.qc 2008-08-09 23:24:29 UTC (rev 4085)
+++ trunk/data/qcsrc/server/race.qc 2008-08-10 10:07:06 UTC (rev 4086)
@@ -1,3 +1,5 @@
+#define MAX_CHECKPOINTS 255
+
.float race_checkpoint; // player: next checkpoint that has to be reached
.float race_laptime;
@@ -3,8 +5,9 @@
.entity sprite;
-float race_checkpoint_records[256];
-string race_checkpoint_recordholders[256];
+float race_checkpoint_records[MAX_CHECKPOINTS];
+string race_checkpoint_recordholders[MAX_CHECKPOINTS];
float race_highest_checkpoint;
+float race_highest_place_spawn;
float race_NextCheckpoint(float f)
@@ -165,18 +168,18 @@
if(other.classname != "player")
return;
- if(other.race_checkpoint == -1 || other.race_checkpoint == self.cnt)
+ if(other.race_checkpoint == -1 || other.race_checkpoint == self.race_checkpoint)
{
- other.race_checkpoint = race_NextCheckpoint(self.cnt);
+ other.race_checkpoint = race_NextCheckpoint(self.race_checkpoint);
- race_SendTime(other, self.cnt, time - other.race_laptime, !!other.race_laptime);
+ race_SendTime(other, self.race_checkpoint, time - other.race_laptime, !!other.race_laptime);
- if(!self.cnt) // finish line
+ if(!self.race_checkpoint) // finish line
other.race_laptime = time;
race_SendNextCheckpoint(other);
}
- else if(other.race_checkpoint == race_NextCheckpoint(self.cnt))
+ else if(other.race_checkpoint == race_NextCheckpoint(self.race_checkpoint))
{
// ignored
}
@@ -197,7 +200,7 @@
{
if(e.race_checkpoint == -1)
return self.modelindex;
- else if(e.race_checkpoint == self.owner.cnt)
+ else if(e.race_checkpoint == self.owner.race_checkpoint)
return self.modelindex;
else
return FALSE;
@@ -223,11 +226,13 @@
if(!self.message)
self.message = "went backwards";
+
+ self.race_checkpoint = self.cnt;
- if(self.cnt > race_highest_checkpoint)
- race_highest_checkpoint = self.cnt;
+ if(self.race_checkpoint > race_highest_checkpoint)
+ race_highest_checkpoint = self.race_checkpoint;
- if(self.cnt)
+ if(self.race_checkpoint)
{
precache_model("models/sprites/race-checkpoint.sp2");
WaypointSprite_SpawnFixed("race-checkpoint", o, self, sprite);
@@ -242,9 +247,8 @@
void race_PreparePlayer()
{
- if(!g_race)
- return;
race_ClearTime(self);
+ self.race_place = 0;
}
void race_RetractPlayer()
@@ -253,9 +257,46 @@
return;
self.race_checkpoint = race_PreviousCheckpoint(self.race_checkpoint);
if(self.race_checkpoint == 0)
+ {
race_ClearTime(self);
+ self.race_checkpoint = 0;
+ }
}
+void race_PreSpawn()
+{
+ if(!g_race)
+ return;
+ if(self.killcount == -666 || g_race_qualifying)
+ race_PreparePlayer();
+}
+
+void race_PostSpawn(entity spot)
+{
+ if(!g_race)
+ return;
+ if(self.killcount != -666 && !g_race_qualifying)
+ {
+ if(spot.target == "")
+ // let the player run without timing, if he did not spawn at a targetting spawnpoint
+ race_PreparePlayer();
+ else
+ race_RetractPlayer();
+ }
+
+ if(spot.target != "" && self.race_checkpoint == -1)
+ self.race_checkpoint = 0;
+
+ self.race_place = 0;
+}
+
+void race_PreSpawnObserver()
+{
+ if(!g_race)
+ return;
+ race_PreparePlayer();
+}
+
void spawnfunc_info_player_race (void)
{
if(!g_race)
@@ -265,4 +306,42 @@
}
++race_spawns;
spawnfunc_info_player_deathmatch();
+
+ if(self.race_place > race_highest_place_spawn)
+ race_highest_place_spawn = self.race_place;
}
+
+void race_ClearRecords()
+{
+ float i;
+ entity e;
+
+ for(i = 0; i < MAX_CHECKPOINTS; ++i)
+ {
+ race_checkpoint_records[i] = 0;
+ if(race_checkpoint_recordholders[i])
+ strunzone(race_checkpoint_recordholders[i]);
+ race_checkpoint_recordholders[i] = string_null;
+ }
+
+ FOR_EACH_CLIENT(e)
+ race_ClearTime(e);
+}
+
+void race_ReadyRestart()
+{
+ race_ClearRecords();
+
+ if(g_race_qualifying == 2)
+ {
+ g_race_qualifying = 0;
+ independent_players = 0;
+ ScoreRules_race();
+ }
+
+ if(PlayerScore_Sort(race_place) <= race_highest_place_spawn)
+ race_place_valid = 1;
+ else
+ race_place_valid = 0;
+ print("VALID: ", ftos(race_place_valid), "\n");
+}
Modified: trunk/data/qcsrc/server/race.qh
===================================================================
--- trunk/data/qcsrc/server/race.qh 2008-08-09 23:24:29 UTC (rev 4085)
+++ trunk/data/qcsrc/server/race.qh 2008-08-10 10:07:06 UTC (rev 4086)
@@ -1,6 +1,10 @@
-void race_PreparePlayer();
-void race_RetractPlayer(); // go back by one checkpoint
+void race_PreSpawnObserver();
+void race_PreSpawn();
+void race_PostSpawn(entity spot);
+void race_ReadyRestart();
float race_teams;
float race_spawns;
float race_PreviousCheckpoint(float f);
float race_NextCheckpoint(float f);
+float race_place_valid;
+.float race_place;
Modified: trunk/data/qcsrc/server/scores.qc
===================================================================
--- trunk/data/qcsrc/server/scores.qc 2008-08-09 23:24:29 UTC (rev 4085)
+++ trunk/data/qcsrc/server/scores.qc 2008-08-10 10:07:06 UTC (rev 4086)
@@ -564,3 +564,61 @@
}
return out;
}
+
+float PlayerTeamScore_Compare(entity p1, entity p2)
+{
+ if(teamscores_entities_count)
+ if(p1.team != p2.team)
+ {
+ entity t1, t2;
+ t1 = teamscorekeepers[p1.team];
+ t2 = teamscorekeepers[p2.team];
+ return TeamScore_Compare(t1, t2);
+ }
+
+ return PlayerScore_Compare(p1.scorekeeper, p2.scorekeeper);
+}
+
+float PlayerScore_Sort(.float field)
+{
+ entity p, plist, pprev, pbest, pbestprev;
+ float i;
+ plist = world;
+
+ FOR_EACH_CLIENT(p)
+ p.field = 0;
+
+ FOR_EACH_PLAYER(p) if(p.scorekeeper)
+ {
+ p.chain = plist;
+ plist = p;
+ }
+ // Now plist points to the whole list.
+
+ i = 0;
+ while(plist)
+ {
+ pprev = pbestprev = world;
+ pbest = plist;
+ for(p = plist; (p = p.chain); )
+ {
+ if(PlayerTeamScore_Compare(p, pbest) > 0)
+ {
+ pbest = p;
+ pbestprev = pprev;
+ }
+ pprev = p;
+ }
+
+ // remove pbest out of the chain
+ if(pbestprev == world)
+ plist = pbest.chain;
+ else
+ pbestprev.chain = pbest.chain;
+ pbest.chain = world;
+
+ pbest.field = ++i;
+ }
+
+ return i;
+}
Modified: trunk/data/qcsrc/server/scores.qh
===================================================================
--- trunk/data/qcsrc/server/scores.qh 2008-08-09 23:24:29 UTC (rev 4085)
+++ trunk/data/qcsrc/server/scores.qh 2008-08-10 10:07:06 UTC (rev 4086)
@@ -105,3 +105,9 @@
*/
string GetPlayerScoreString(entity pl, float shortString);
string GetTeamScoreString(float tm, float shortString);
+
+/**
+ * Sorts the players and stores their place in the given field, starting with
+ * 1. Non-players get 0 written into that field.
+ */
+float PlayerScore_Sort(.float field);
Modified: trunk/data/qcsrc/server/scores_rules.qc
===================================================================
--- trunk/data/qcsrc/server/scores_rules.qc 2008-08-09 23:24:29 UTC (rev 4085)
+++ trunk/data/qcsrc/server/scores_rules.qc 2008-08-10 10:07:06 UTC (rev 4086)
@@ -133,13 +133,15 @@
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);
}
- else if(cvar("g_race_qualifying"))
+ else if(g_race_qualifying)
{
+ ScoreInfo_SetLabel_TeamScore( ST_RACE_LAPS, "laps", 0);
ScoreInfo_SetLabel_PlayerScore(SP_RACE_LAPS, "laps", 0);
ScoreInfo_SetLabel_PlayerScore(SP_RACE_FASTEST, "fastest", SFL_SORT_PRIO_PRIMARY | SFL_LOWER_IS_BETTER | SFL_TIME);
}
else
{
+ ScoreInfo_SetLabel_TeamScore( ST_RACE_LAPS, "laps", 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);
}
More information about the nexuiz-commits
mailing list