r2454 - in branches/nexuiz-2.0/data: . models models/keyhunt models/sprites qcsrc/server
DONOTREPLY at icculus.org
DONOTREPLY at icculus.org
Wed May 2 14:09:26 EDT 2007
Author: div0
Date: 2007-05-02 14:09:25 -0400 (Wed, 02 May 2007)
New Revision: 2454
Added:
branches/nexuiz-2.0/data/models/keyhunt/
branches/nexuiz-2.0/data/models/sprites/key-dropped.sp2
branches/nexuiz-2.0/data/models/sprites/key-dropped.tga
branches/nexuiz-2.0/data/models/sprites/keycarrier-blue.sp2
branches/nexuiz-2.0/data/models/sprites/keycarrier-blue.tga
branches/nexuiz-2.0/data/models/sprites/keycarrier-finish.sp2
branches/nexuiz-2.0/data/models/sprites/keycarrier-finish.tga
branches/nexuiz-2.0/data/models/sprites/keycarrier-friend.sp2
branches/nexuiz-2.0/data/models/sprites/keycarrier-friend.tga
branches/nexuiz-2.0/data/models/sprites/keycarrier-pink.sp2
branches/nexuiz-2.0/data/models/sprites/keycarrier-pink.tga
branches/nexuiz-2.0/data/models/sprites/keycarrier-red.sp2
branches/nexuiz-2.0/data/models/sprites/keycarrier-red.tga
branches/nexuiz-2.0/data/models/sprites/keycarrier-yellow.sp2
branches/nexuiz-2.0/data/models/sprites/keycarrier-yellow.tga
branches/nexuiz-2.0/data/qcsrc/server/keyhunt.qc
branches/nexuiz-2.0/data/qcsrc/server/keyhunt.qh
Modified:
branches/nexuiz-2.0/data/default.cfg
branches/nexuiz-2.0/data/game_reset.cfg
branches/nexuiz-2.0/data/models/keyhunt/key.md3
branches/nexuiz-2.0/data/qcsrc/server/bots.qc
branches/nexuiz-2.0/data/qcsrc/server/builtins.qh
branches/nexuiz-2.0/data/qcsrc/server/cl_client.qc
branches/nexuiz-2.0/data/qcsrc/server/cl_impulse.qc
branches/nexuiz-2.0/data/qcsrc/server/cl_player.qc
branches/nexuiz-2.0/data/qcsrc/server/cl_weaponsystem.qc
branches/nexuiz-2.0/data/qcsrc/server/clientcommands.qc
branches/nexuiz-2.0/data/qcsrc/server/constants.qh
branches/nexuiz-2.0/data/qcsrc/server/ctf.qc
branches/nexuiz-2.0/data/qcsrc/server/defs.qh
branches/nexuiz-2.0/data/qcsrc/server/domination.qc
branches/nexuiz-2.0/data/qcsrc/server/g_damage.qc
branches/nexuiz-2.0/data/qcsrc/server/g_world.qc
branches/nexuiz-2.0/data/qcsrc/server/havocbot.qc
branches/nexuiz-2.0/data/qcsrc/server/havocbot_roles.qc
branches/nexuiz-2.0/data/qcsrc/server/miscfunctions.qc
branches/nexuiz-2.0/data/qcsrc/server/progs.src
branches/nexuiz-2.0/data/qcsrc/server/t_items.qc
branches/nexuiz-2.0/data/qcsrc/server/teamplay.qc
branches/nexuiz-2.0/data/qcsrc/server/w_nex.qc
branches/nexuiz-2.0/data/qcsrc/server/waypointsprites.qc
Log:
- New game mode: Key Hunt
- switched yellow and pink team
- play2 function
- Weapon throwing uses Newton
- minplayers/bot_number no longer get changed by QC code (prevents suddenly appearing bot_number)
- info_player_deathmatch now does all the work, including setting classname
- fix a division by zero message in havocbots (annoying when developer 1, but harmless)
Modified: branches/nexuiz-2.0/data/default.cfg
===================================================================
--- branches/nexuiz-2.0/data/default.cfg 2007-05-02 17:12:05 UTC (rev 2453)
+++ branches/nexuiz-2.0/data/default.cfg 2007-05-02 18:09:25 UTC (rev 2454)
@@ -236,6 +236,7 @@
seta g_ctf_capture_limit -1
seta g_domination_point_limit -1
seta g_runematch_point_limit -1
+set g_keyhunt_point_limit -1
// respawn delay
set g_respawn_delay 2
@@ -713,3 +714,25 @@
alias g_maplist_remove "qc_cmd rpn /g_maplist g_maplist /$1 difference def"
alias g_maplist_putfirst "qc_cmd rpn /maps/$1.mapcfg fexists_assert /g_maplist /$1 g_maplist union def"
alias g_maplist_shufflenow "qc_cmd rpn /g_maplist g_maplist shuffle def"
+
+// key hunt
+set g_keyhunt 0
+set g_balance_keyhunt_delay_return 30
+set g_balance_keyhunt_delay_round 5
+set g_balance_keyhunt_delay_tracking 10
+set g_balance_keyhunt_delay_fadeout 2
+set g_balance_keyhunt_delay_collect 1.5
+set g_balance_keyhunt_delay_drop 0.4
+set g_balance_keyhunt_maxdist 150
+set g_balance_keyhunt_score_collect 3
+set g_balance_keyhunt_score_carrierfrag 2
+set g_balance_keyhunt_score_capture 100
+set g_balance_keyhunt_score_push 60
+set g_balance_keyhunt_score_destroyed 50
+set g_balance_keyhunt_score_destroyed_ownfactor 1
+set g_balance_keyhunt_dropvelocity 300
+set g_balance_keyhunt_throwvelocity 400
+set g_balance_keyhunt_protecttime 0.8
+set g_balance_keyhunt_damageforcescale 1
+set g_keyhunt_teams_override 0
+set g_keyhunt_teams 0 // mapcfgs NEED to specify this!
Modified: branches/nexuiz-2.0/data/game_reset.cfg
===================================================================
--- branches/nexuiz-2.0/data/game_reset.cfg 2007-05-02 17:12:05 UTC (rev 2453)
+++ branches/nexuiz-2.0/data/game_reset.cfg 2007-05-02 18:09:25 UTC (rev 2454)
@@ -14,6 +14,7 @@
set g_lms 0
set g_arena 0
set g_campaign 0
+set g_keyhunt 0
set teamplay 0
set gamecfg 0
Copied: branches/nexuiz-2.0/data/models/keyhunt (from rev 2414, trunk/data/models/keyhunt)
Modified: branches/nexuiz-2.0/data/models/keyhunt/key.md3
===================================================================
(Binary files differ)
Copied: branches/nexuiz-2.0/data/models/sprites/key-dropped.sp2 (from rev 2414, trunk/data/models/sprites/key-dropped.sp2)
===================================================================
(Binary files differ)
Copied: branches/nexuiz-2.0/data/models/sprites/key-dropped.tga (from rev 2414, trunk/data/models/sprites/key-dropped.tga)
===================================================================
(Binary files differ)
Copied: branches/nexuiz-2.0/data/models/sprites/keycarrier-blue.sp2 (from rev 2414, trunk/data/models/sprites/keycarrier-blue.sp2)
===================================================================
(Binary files differ)
Copied: branches/nexuiz-2.0/data/models/sprites/keycarrier-blue.tga (from rev 2414, trunk/data/models/sprites/keycarrier-blue.tga)
===================================================================
(Binary files differ)
Copied: branches/nexuiz-2.0/data/models/sprites/keycarrier-finish.sp2 (from rev 2414, trunk/data/models/sprites/keycarrier-finish.sp2)
===================================================================
(Binary files differ)
Copied: branches/nexuiz-2.0/data/models/sprites/keycarrier-finish.tga (from rev 2414, trunk/data/models/sprites/keycarrier-finish.tga)
===================================================================
(Binary files differ)
Copied: branches/nexuiz-2.0/data/models/sprites/keycarrier-friend.sp2 (from rev 2414, trunk/data/models/sprites/keycarrier-friend.sp2)
===================================================================
(Binary files differ)
Copied: branches/nexuiz-2.0/data/models/sprites/keycarrier-friend.tga (from rev 2414, trunk/data/models/sprites/keycarrier-friend.tga)
===================================================================
(Binary files differ)
Copied: branches/nexuiz-2.0/data/models/sprites/keycarrier-pink.sp2 (from rev 2414, trunk/data/models/sprites/keycarrier-pink.sp2)
===================================================================
(Binary files differ)
Copied: branches/nexuiz-2.0/data/models/sprites/keycarrier-pink.tga (from rev 2414, trunk/data/models/sprites/keycarrier-pink.tga)
===================================================================
(Binary files differ)
Copied: branches/nexuiz-2.0/data/models/sprites/keycarrier-red.sp2 (from rev 2414, trunk/data/models/sprites/keycarrier-red.sp2)
===================================================================
(Binary files differ)
Copied: branches/nexuiz-2.0/data/models/sprites/keycarrier-red.tga (from rev 2414, trunk/data/models/sprites/keycarrier-red.tga)
===================================================================
(Binary files differ)
Copied: branches/nexuiz-2.0/data/models/sprites/keycarrier-yellow.sp2 (from rev 2414, trunk/data/models/sprites/keycarrier-yellow.sp2)
===================================================================
(Binary files differ)
Copied: branches/nexuiz-2.0/data/models/sprites/keycarrier-yellow.tga (from rev 2414, trunk/data/models/sprites/keycarrier-yellow.tga)
===================================================================
(Binary files differ)
Modified: branches/nexuiz-2.0/data/qcsrc/server/bots.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/bots.qc 2007-05-02 17:12:05 UTC (rev 2453)
+++ branches/nexuiz-2.0/data/qcsrc/server/bots.qc 2007-05-02 18:09:25 UTC (rev 2454)
@@ -2018,6 +2018,7 @@
float botframe_spawnedwaypoints;
+float botframe_nextthink;
void() bot_serverframe =
{
float realplayers, bots;
@@ -2038,17 +2039,13 @@
{
float realminplayers, minplayers;
realminplayers = cvar("minplayers");
- minplayers = bound(0, floor(realminplayers), maxclients - 1);
- if (realminplayers != minplayers)
- cvar_set("minplayers", ftos(minplayers));
+ minplayers = max(0, floor(realminplayers));
float realminbots, minbots;
realminbots = cvar("bot_number");
- minbots = bound(0, floor(realminbots), maxclients - 1);
- if (realminbots != minbots)
- cvar_set("bot_number", ftos(minbots));
+ minbots = max(0, floor(realminbots));
- bots = bound(minbots, minplayers - realplayers, maxclients);
+ bots = min(max(minbots, minplayers - realplayers), maxclients - realplayers);
}
else
{
@@ -2059,18 +2056,21 @@
bot_ignore_bots = cvar("bot_ignore_bots");
// only add one bot per frame to avoid utter chaos
- while (currentbots < bots)
+ if(time > botframe_nextthink)
{
- if (bot_spawn() == world)
+ //dprint(ftos(bots), " ? ", ftos(currentbots), "\n");
+ while (currentbots < bots)
{
- bprint("Can not add bot, server full.\n");
- cvar_set("bot_number", ftos(currentbots));
- bots = currentbots;
- break;
+ if (bot_spawn() == world)
+ {
+ bprint("Can not add bot, server full.\n");
+ botframe_nextthink = time + 10;
+ break;
+ }
}
+ while (currentbots > bots)
+ bot_removenewest();
}
- while (currentbots > bots)
- bot_removenewest();
if(botframe_spawnedwaypoints)
{
@@ -2078,7 +2078,7 @@
localcmd("quit\n");
}
- if (bots > 0 || cvar("g_waypointeditor"))
+ if (currentbots > 0 || cvar("g_waypointeditor"))
if (!botframe_spawnedwaypoints)
{
botframe_spawnedwaypoints = TRUE;
Modified: branches/nexuiz-2.0/data/qcsrc/server/builtins.qh
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/builtins.qh 2007-05-02 17:12:05 UTC (rev 2453)
+++ branches/nexuiz-2.0/data/qcsrc/server/builtins.qh 2007-05-02 18:09:25 UTC (rev 2454)
@@ -17,7 +17,7 @@
void traceline (vector v1, vector v2, float nomonst, entity forent) = #16;
entity checkclient (void) = #17;
entity find (entity start, .string fld, string match) = #18;
-string precache_sound (string s) = #19;
+//string precache_sound (string s) = #19;
string precache_model (string s) = #20;
//void(entity client, string s)stuffcmd = #21;
entity findradius (vector org, float rad) = #22;
Modified: branches/nexuiz-2.0/data/qcsrc/server/cl_client.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/cl_client.qc 2007-05-02 17:12:05 UTC (rev 2453)
+++ branches/nexuiz-2.0/data/qcsrc/server/cl_client.qc 2007-05-02 18:09:25 UTC (rev 2454)
@@ -1,11 +1,11 @@
void info_player_start (void)
{
- self.classname = "info_player_deathmatch";
- relocate_spawnpoint();
+ info_player_deathmatch();
}
void info_player_deathmatch (void)
{
+ self.classname = "info_player_deathmatch";
relocate_spawnpoint();
}
@@ -287,13 +287,14 @@
WriteEntity(MSG_ONE, self);
}
- WaypointSprite_PlayerDead();
-
DropAllRunes(self);
+ kh_Key_DropAll(self);
if(self.flagcarried)
DropFlag(self.flagcarried);
+ WaypointSprite_PlayerDead();
+
DistributeFragsAmongTeam(self, self.team, 1);
if(self.frags <= 0 && self.frags > -666 && cvar("g_lms") && self.killcount != -666)
@@ -831,6 +832,7 @@
WaypointSprite_PlayerGone();
DropAllRunes(self);
+ kh_Key_DropAll(self);
if(self.flagcarried)
DropFlag(self.flagcarried);
@@ -1239,7 +1241,7 @@
{
self.respawn_countdown = number - 1;
if(ceil(self.death_time - (time + 0.5)) == number) // only say it if it is the same number even in 0.5s; to prevent overlapping sounds
- stuffcmd(self, strcat("play2 announcer/robotic/", ftos(number), ".ogg\n"));
+ play2(self, strcat("announcer/robotic/", ftos(number), ".ogg"));
}
}
}
@@ -1508,6 +1510,7 @@
minstagib_ammocheck();
ctf_setstatus();
+ kh_setstatus();
//self.angles_y=self.v_angle_y + 90; // temp
Modified: branches/nexuiz-2.0/data/qcsrc/server/cl_impulse.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/cl_impulse.qc 2007-05-02 17:12:05 UTC (rev 2453)
+++ branches/nexuiz-2.0/data/qcsrc/server/cl_impulse.qc 2007-05-02 18:09:25 UTC (rev 2454)
@@ -118,7 +118,7 @@
if (self.weapon != WEP_LASER
&& !cvar("g_minstagib") && !cvar("g_instagib")
&& !cvar("g_rocketarena") && !cvar("g_lms") && cvar("g_pickup_items") && !cvar("g_nixnex"))
- W_ThrowWeapon(self.velocity * 0.5 + v_forward * 750, '0 0 0', TRUE);
+ W_ThrowWeapon(W_CalculateProjectileVelocity(self.velocity, v_forward * 750), '0 0 0', TRUE);
}
}
// deploy waypoints
Modified: branches/nexuiz-2.0/data/qcsrc/server/cl_player.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/cl_player.qc 2007-05-02 17:12:05 UTC (rev 2453)
+++ branches/nexuiz-2.0/data/qcsrc/server/cl_player.qc 2007-05-02 18:09:25 UTC (rev 2454)
@@ -285,8 +285,6 @@
{
self.deaths += 1;
- // clear waypoints
- WaypointSprite_PlayerDead();
// become fully visible
self.alpha = 1;
// clear selected player display
@@ -296,8 +294,11 @@
// print an obituary message
Obituary (attacker, self, deathtype);
DropAllRunes(self);
+ kh_Key_DropAll(self);
if(self.flagcarried)
DropFlag(self.flagcarried);
+ // clear waypoints
+ WaypointSprite_PlayerDead();
// make the corpse upright (not tilted)
self.angles_x = 0;
self.angles_z = 0;
Modified: branches/nexuiz-2.0/data/qcsrc/server/cl_weaponsystem.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/cl_weaponsystem.qc 2007-05-02 17:12:05 UTC (rev 2453)
+++ branches/nexuiz-2.0/data/qcsrc/server/cl_weaponsystem.qc 2007-05-02 18:09:25 UTC (rev 2454)
@@ -404,20 +404,14 @@
// VorteX: haste can be added here
};
-void(entity missile) W_SetupProjectileVelocity =
+vector(vector pvelocity, vector mvelocity) W_CalculateProjectileVelocity =
{
- vector pvelocity;
vector mdirection;
float mspeed;
float outspeed;
float nstyle;
- vector mvelocity;
vector outvelocity;
- if(missile.owner == world)
- error("Unowned missile");
- pvelocity = missile.owner.velocity;
- mvelocity = missile.velocity;
mdirection = normalize(mvelocity);
mspeed = vlen(mvelocity);
@@ -478,7 +472,13 @@
else
error("g_projectiles_newton_style must be 0 (absolute), 1 (Newtonian), 2 (Newtonian + aimfix), 3 (pseudo Newtonian) or 4 (tZorkian)!");
- //dprint("Adjusted from ", vtos(missile.velocity));
- missile.velocity = outvelocity;
- //dprint(" to ", vtos(missile.velocity), "\n");
+ return outvelocity;
}
+
+void(entity missile) W_SetupProjectileVelocity =
+{
+ if(missile.owner == world)
+ error("Unowned missile");
+
+ missile.velocity = W_CalculateProjectileVelocity(missile.owner.velocity, missile.velocity);
+}
Modified: branches/nexuiz-2.0/data/qcsrc/server/clientcommands.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/clientcommands.qc 2007-05-02 17:12:05 UTC (rev 2453)
+++ branches/nexuiz-2.0/data/qcsrc/server/clientcommands.qc 2007-05-02 18:09:25 UTC (rev 2454)
@@ -319,6 +319,8 @@
if(self.classname == "player" && cvar("sv_spectate") == 1) {
if(self.flagcarried)
DropFlag(self.flagcarried);
+ kh_Key_DropAll(self);
+ WaypointSprite_PlayerDead();
DistributeFragsAmongTeam(self, self.team, 1.0);
self.classname = "observer";
PutClientInServer();
@@ -343,15 +345,15 @@
SV_ChangeTeam( COLOR_TEAM1 - 1 );
} else if( argv(1) == "blue" ) {
SV_ChangeTeam( COLOR_TEAM2 - 1 );
+ } else if( argv(1) == "yellow" ) {
+ SV_ChangeTeam( COLOR_TEAM3 - 1 );
} else if( argv(1) == "pink" ) {
- SV_ChangeTeam( COLOR_TEAM3 - 1 );
- } else if( argv(1) == "yellow" ) {
SV_ChangeTeam( COLOR_TEAM4 - 1 );
} else if( argv(1) == "auto" ) {
self.team = -1;
JoinBestTeam( self, 0 );
} else {
- sprint( self, strcat( "selectteam none/red/blue/pink/yellow/auto - \"", argv(1), "\" not recognised\n" ) );
+ sprint( self, strcat( "selectteam none/red/blue/yellow/pink/auto - \"", argv(1), "\" not recognised\n" ) );
}
} else if(argv(0) == "ready") {
if(cvar("sv_ready_restart"))
Modified: branches/nexuiz-2.0/data/qcsrc/server/constants.qh
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/constants.qh 2007-05-02 17:12:05 UTC (rev 2453)
+++ branches/nexuiz-2.0/data/qcsrc/server/constants.qh 2007-05-02 18:09:25 UTC (rev 2454)
@@ -220,7 +220,7 @@
float COLOR_TEAM1 = 5; // red
float COLOR_TEAM2 = 14; // blue
-float COLOR_TEAM3 = 10; // pink
-float COLOR_TEAM4 = 13; // yellow
+float COLOR_TEAM3 = 13; // yellow
+float COLOR_TEAM4 = 10; // pink
float NUM_PLAYERSKINS_TEAMPLAY = 3;
Modified: branches/nexuiz-2.0/data/qcsrc/server/ctf.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/ctf.qc 2007-05-02 17:12:05 UTC (rev 2453)
+++ branches/nexuiz-2.0/data/qcsrc/server/ctf.qc 2007-05-02 18:09:25 UTC (rev 2454)
@@ -234,7 +234,7 @@
other.next_take_time = time + 1;
}
if (self.cnt == FLAG_BASE)
- if (other.team == 5 || other.team == 14) // only red and blue team can steal flags
+ if (other.team == COLOR_TEAM1 || other.team == COLOR_TEAM2) // only red and blue team can steal flags
if (other.team != self.team)
if (!other.flagcarried)
{
@@ -268,11 +268,11 @@
if (self.cnt == FLAG_DROPPED)
{
self.flags = FL_ITEM; // clear FL_ONGROUND and any other junk
- if (other.team == self.team || (other.team != 5 && other.team != 14))
+ if (other.team == self.team || (other.team != COLOR_TEAM1 && other.team != COLOR_TEAM2))
{
// return flag
bprint(other.netname, "^7 returned the ", self.netname, "\n");
- if (other.team == 5 || other.team == 14)
+ if (other.team == COLOR_TEAM1 || other.team == COLOR_TEAM2)
UpdateFrags(other, cvar("g_ctf_flagscore_return"));
else
UpdateFrags(other, cvar("g_ctf_flagscore_return_rogue"));
@@ -315,9 +315,8 @@
*/
void() info_player_team1 =
{
- self.classname = "info_player_deathmatch";
- self.team = 5; // red
- relocate_spawnpoint();
+ self.team = COLOR_TEAM1; // red
+ info_player_deathmatch();
};
//self.team = 4;self.classname = "info_player_start";info_player_start();};
@@ -331,9 +330,8 @@
*/
void() info_player_team2 =
{
- self.classname = "info_player_deathmatch";
- self.team = 14; // blue
- relocate_spawnpoint();
+ self.team = COLOR_TEAM2; // blue
+ info_player_deathmatch();
};
//self.team = 13;self.classname = "info_player_start";info_player_start();};
@@ -347,9 +345,8 @@
*/
void() info_player_team3 =
{
- self.classname = "info_player_deathmatch";
- self.team = 10; // purple
- relocate_spawnpoint();
+ self.team = COLOR_TEAM3; // purple
+ info_player_deathmatch();
};
@@ -363,9 +360,8 @@
*/
void() info_player_team4 =
{
- self.classname = "info_player_deathmatch";
- self.team = 13; // yellow
- relocate_spawnpoint();
+ self.team = COLOR_TEAM4; // yellow
+ info_player_deathmatch();
};
@@ -404,7 +400,7 @@
// cvar_set("teamplay", "3");
self.classname = "item_flag_team1";
- self.team = 5; // color 4 team (red)
+ self.team = COLOR_TEAM1; // color 4 team (red)
self.items = IT_KEY2; // gold key (redish enough)
self.netname = "^1RED^7 flag";
self.target = "###item###";
@@ -460,7 +456,7 @@
// cvar_set("teamplay", "3");
self.classname = "item_flag_team2";
- self.team = 14; // color 13 team (blue)
+ self.team = COLOR_TEAM2; // color 13 team (blue)
self.items = IT_KEY1; // silver key (bluish enough)
self.netname = "^4BLUE^7 flag";
self.target = "###item###";
@@ -553,8 +549,8 @@
numteams = 2;//cvar("g_ctf_default_teams");
- ctf_spawnteam("Red", 4);
- ctf_spawnteam("Blue", 13);
+ ctf_spawnteam("Red", COLOR_TEAM1 - 1);
+ ctf_spawnteam("Blue", COLOR_TEAM2 - 1);
};
void() ctf_delayedinit =
@@ -578,8 +574,8 @@
{
if (flag) {
local float shift;
- if (flag.team == 5) shift = IT_RED_FLAG_TAKEN;
- else if (flag.team == 14) shift = IT_BLUE_FLAG_TAKEN;
+ if (flag.team == COLOR_TEAM1) shift = IT_RED_FLAG_TAKEN;
+ else if (flag.team == COLOR_TEAM2) shift = IT_BLUE_FLAG_TAKEN;
else shift = 0;
local float status;
Modified: branches/nexuiz-2.0/data/qcsrc/server/defs.qh
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/defs.qh 2007-05-02 17:12:05 UTC (rev 2453)
+++ branches/nexuiz-2.0/data/qcsrc/server/defs.qh 2007-05-02 18:09:25 UTC (rev 2454)
@@ -152,7 +152,6 @@
float WEP_FIRST = 1;
float WEP_LAST = 9;
-void(entity e, float chan, string samp, float vol, float atten) sound = #8;
void(entity client, string s) stuffcmd = #21;
void(entity client, string s) sprint = #24;
vector(entity e, float sped) aim = #44;
Modified: branches/nexuiz-2.0/data/qcsrc/server/domination.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/domination.qc 2007-05-02 17:12:05 UTC (rev 2453)
+++ branches/nexuiz-2.0/data/qcsrc/server/domination.qc 2007-05-02 18:09:25 UTC (rev 2454)
@@ -544,12 +544,12 @@
numteams = cvar("g_domination_default_teams");
// LordHavoc: edit this if you want to change defaults
- dom_spawnteam("Red", 4, "models/domination/dom_red.md3", 0, "domination/claim.wav", "", "Red team has captured a control point");
- dom_spawnteam("Blue", 13, "models/domination/dom_blue.md3", 0, "domination/claim.wav", "", "Blue team has captured a control point");
+ dom_spawnteam("Red", COLOR_TEAM1-1, "models/domination/dom_red.md3", 0, "domination/claim.wav", "", "Red team has captured a control point");
+ dom_spawnteam("Blue", COLOR_TEAM2-1, "models/domination/dom_blue.md3", 0, "domination/claim.wav", "", "Blue team has captured a control point");
if(numteams > 2)
- dom_spawnteam("Pink", 9, "models/domination/dom_pink.md3", 0, "domination/claim.wav", "", "Pink team has captured a control point");
+ dom_spawnteam("Yellow", COLOR_TEAM3-1, "models/domination/dom_yellow.md3", 0, "domination/claim.wav", "", "Yellow team has captured a control point");
if(numteams > 3)
- dom_spawnteam("Yellow", 12, "models/domination/dom_yellow.md3", 0, "domination/claim.wav", "", "Yellow team has captured a control point");
+ dom_spawnteam("Pink", COLOR_TEAM4-1, "models/domination/dom_pink.md3", 0, "domination/claim.wav", "", "Pink team has captured a control point");
dom_spawnteam("", 0, "models/domination/dom_unclaimed.md3", 0, "", "", "");
};
@@ -593,8 +593,8 @@
// so we don't even know yet if this map is set up for domination...
precache_model("models/domination/dom_red.md3");
precache_model("models/domination/dom_blue.md3");
+ precache_model("models/domination/dom_yellow.md3");
precache_model("models/domination/dom_pink.md3");
- precache_model("models/domination/dom_yellow.md3");
precache_model("models/domination/dom_unclaimed.md3");
precache_sound("domination/claim.wav");
e = spawn();
Modified: branches/nexuiz-2.0/data/qcsrc/server/g_damage.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/g_damage.qc 2007-05-02 17:12:05 UTC (rev 2453)
+++ branches/nexuiz-2.0/data/qcsrc/server/g_damage.qc 2007-05-02 18:09:25 UTC (rev 2454)
@@ -26,6 +26,11 @@
if(f > 0)
f = RunematchHandleFrags(attacker, targ, f);
}
+ else if(cvar("g_keyhunt"))
+ {
+ if(f > 0)
+ f = kh_HandleFrags(attacker, targ, f);
+ }
else if(cvar("g_lms"))
{
// count remaining lives, not frags in lms
@@ -91,7 +96,7 @@
void Obituary (entity attacker, entity targ, float deathtype)
{
- string s, a, m;
+ string s, a;
if (targ.classname == "player" || targ.classname == "corpse")
{
@@ -105,29 +110,11 @@
{
if (deathtype == DEATH_TEAMCHANGE)
{
- m = "You are now on: ";
- if (targ.team == 5)
- m = strcat(m, "^1Red Team");
- else if (targ.team == 14)
- m = strcat(m, "^4Blue Team");
- else if (targ.team == 10)
- m = strcat(m, "^6Pink Team");
- else if (targ.team == 13)
- m = strcat(m, "^3Yellow Team");
- centerprint(targ, m);
+ centerprint(targ, strcat("You are now on: ", ColoredTeamName(targ.team)));
}
else if (deathtype == DEATH_AUTOTEAMCHANGE)
{
- m = "You have been moved into a different team to improve team balance\nYou are now on: ";
- if (targ.team == 5)
- m = strcat(m, "^1Red Team");
- else if (targ.team == 14)
- m = strcat(m, "^4Blue Team");
- else if (targ.team == 10)
- m = strcat(m, "^6Pink Team");
- else if (targ.team == 13)
- m = strcat(m, "^3Yellow Team");
- centerprint(targ, m);
+ centerprint(targ, strcat("You have been moved into a different team to improve team balance\nYou are now on: ", ColoredTeamName(targ.team)));
return;
}
else if (deathtype == DEATH_CAMP)
@@ -249,37 +236,37 @@
if (attacker.killcount == 3)
{
bprint (a,"^7 made a ^1TRIPLE FRAG\n");
- stuffcmd(attacker, "play2 announcer/male/03kills.ogg\n");
+ play2(attacker, "announcer/male/03kills.ogg");
}
else if (attacker.killcount == 5)
{
bprint (a,"^7 made a ^1FIVE FRAG COMBO\n");
- stuffcmd(attacker, "play2 announcer/male/05kills.ogg\n");
+ play2(attacker, "announcer/male/05kills.ogg");
}
else if (attacker.killcount == 10)
{
bprint (a,"^7 is on a ^1RAGE\n");
- stuffcmd(attacker, "play2 announcer/male/10kills.ogg\n");
+ play2(attacker, "announcer/male/10kills.ogg");
}
else if (attacker.killcount == 15)
{
bprint (a,"^7 has done a ^1MASSACRE!\n");
- stuffcmd(attacker, "play2 announcer/male/15kills.ogg\n");
+ play2(attacker, "announcer/male/15kills.ogg");
}
else if (attacker.killcount == 20)
{
bprint (a,"^7 is ^1UNHUMAN!\n");
- stuffcmd(attacker, "play2 announcer/male/20kills.ogg\n");
+ play2(attacker, "announcer/male/20kills.ogg");
}
else if (attacker.killcount == 25)
{
bprint (a,"^7 is a ^1DEATH INCARNATION!\n");
- stuffcmd(attacker, "play2 announcer/male/25kills.ogg\n");
+ play2(attacker, "announcer/male/25kills.ogg");
}
else if (attacker.killcount == 30)
{
bprint (a,"^7 is maybe a ^1AIMBOTTER?!\n");
- stuffcmd(attacker, "play2 announcer/male/30kills.ogg\n");
+ play2(attacker, "announcer/male/30kills.ogg");
}
}
}
@@ -304,7 +291,7 @@
bprint ("^1",s, "^1 died\n");
GiveFrags(targ, targ, -1);
if(targ.frags == -5) {
- stuffcmd(targ, "play2 announcer/male/botlike.ogg\n");
+ play2(targ, "announcer/male/botlike.ogg");
}
if (targ.killcount > 2)
@@ -414,7 +401,7 @@
}
else if (deathtype == IT_NEX && targ.items & IT_STRENGTH)
{
- if(clienttype(attacker) == CLIENTTYPE_REAL) stuffcmd(attacker, "play2 announcer/male/yoda.ogg\n");
+ if(clienttype(attacker) == CLIENTTYPE_REAL) play2(attacker, "announcer/male/yoda.ogg");
}
if (deathtype == IT_LASER)
{
@@ -433,7 +420,7 @@
} else {
if (deathtype == IT_NEX && !targ.deadflag && !(attacker.flags & FL_ONGROUND) && !(targ.flags & FL_ONGROUND) && attacker.waterlevel < 2 && targ.waterlevel < 2 && attacker.killcount != 3 && attacker.killcount != 5 && attacker.killcount != 10 && attacker.killcount != 15 && attacker.killcount != 20 && attacker.killcount != 25 && attacker.killcount != 30)
{
- if(clienttype(attacker) == CLIENTTYPE_REAL) stuffcmd(attacker, "play2 announcer/male/yoda.ogg\n");
+ if(clienttype(attacker) == CLIENTTYPE_REAL) play2(attacker, "announcer/male/yoda.ogg");
}
}
Modified: branches/nexuiz-2.0/data/qcsrc/server/g_world.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/g_world.qc 2007-05-02 17:12:05 UTC (rev 2453)
+++ branches/nexuiz-2.0/data/qcsrc/server/g_world.qc 2007-05-02 18:09:25 UTC (rev 2454)
@@ -76,6 +76,16 @@
if(world_already_spawned)
error("world already spawned - you may have EXACTLY ONE worldspawn!");
world_already_spawned = TRUE;
+
+ /*
+ TODO sound pack system
+ // initialize sound pack system
+ soundpack = cvar_string("g_soundpack");
+ if(soundpack != "")
+ soundpack = strcat(soundpack, "/");
+ soundpack = strzone(soundpack);
+ */
+
// Precache all player models
// Workaround for "invisible players"
precache_model("models/player/carni.zym");
@@ -455,6 +465,8 @@
return "rune";
else if (game == GAME_LMS)
return "lms";
+ else if (game == GAME_KEYHUNT)
+ return "kh";
return "dm";
}
@@ -1438,8 +1450,8 @@
{
PrintScoreboardFor(e, "Red", "^1", COLOR_TEAM1);
PrintScoreboardFor(e, "Blue", "^4", COLOR_TEAM2);
- PrintScoreboardFor(e, "Pink", "^6", COLOR_TEAM3);
- PrintScoreboardFor(e, "Yellow", "^3", COLOR_TEAM4);
+ PrintScoreboardFor(e, "Yellow", "^3", COLOR_TEAM3);
+ PrintScoreboardFor(e, "Pink", "^6", COLOR_TEAM4);
}
else
{
@@ -1549,7 +1561,7 @@
{
if(teams_matter)
{
- if(cvar("g_tdm") || cvar("g_runematch") || cvar("g_ctf") || cvar("g_domination"))
+ if(cvar("g_tdm") || cvar("g_runematch") || cvar("g_ctf") || cvar("g_domination") || cvar("g_keyhunt"))
status = WinningCondition_MaxTeamSum(fraglimit);
//else if()
// status = WinningCondition_MaxTeamMax(fraglimit);
@@ -1845,7 +1857,7 @@
// notify about keep-two
if(keeptwo != 0 && mapvote_keeptwotime == 0)
- stuffcmd(other, "\nplay2 misc/invshot.wav\n");
+ play2(other, "misc/invshot.wav");
// clear possibly invalid votes
if(mapvote_maps[other.mapvote - 1] == "")
@@ -1932,12 +1944,12 @@
if(self.classname == "spectator")
{
if(self.enemy.hitsound)
- stuffcmd(self, "play2 misc/hit.wav\n");
+ play2(self, "misc/hit.wav");
}
else
{
if(self.hitsound)
- stuffcmd(self, "play2 misc/hit.wav\n");
+ play2(self, "misc/hit.wav");
}
}
FOR_EACH_CLIENT(self)
Modified: branches/nexuiz-2.0/data/qcsrc/server/havocbot.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/havocbot.qc 2007-05-02 17:12:05 UTC (rev 2453)
+++ branches/nexuiz-2.0/data/qcsrc/server/havocbot.qc 2007-05-02 18:09:25 UTC (rev 2454)
@@ -331,13 +331,13 @@
shotgun = (cvar("g_balance_shotgun_primary_damage")*cvar("g_balance_shotgun_primary_bullets")/cvar("g_balance_shotgun_primary_refire")*1.0)
* bound(0,1/cvar("g_balance_shotgun_primary_spread")/distance*spreadpenalty,1);
if (client_hasweapon(self, WEP_LASER, FALSE, FALSE))
- laser = (cvar("g_balance_laser_damage")/cvar("g_balance_laser_refire")*1.0)
- * bound(0,cvar("g_balance_laser_speed")/distance*0.2*maxdelaytime,1);
+ laser = (cvar("g_balance_laser_primary_damage")/cvar("g_balance_laser_primary_refire")*1.0)
+ * bound(0,cvar("g_balance_laser_primary_speed")/distance*0.2*maxdelaytime,1);
if((self.enemy.flags & FL_ONGROUND)==FALSE){
rocket = rocket * (1-bound(0, distancefromfloor/cvar("g_balance_rocketlauncher_radius" ),0.9)); //slight bigger change
grenade = grenade * (1-bound(0,distancefromfloor/cvar("g_balance_grenadelauncher_primary_radius"),0.95));
electro = electro * (1-bound(0,distancefromfloor/cvar("g_balance_electro_primary_radius" ),0.95));
- laser = laser * (1-bound(0,distancefromfloor/cvar("g_balance_laser_radius" ),0.95));
+ laser = laser * (1-bound(0,distancefromfloor/cvar("g_balance_laser_primary_radius" ),0.95));
}
/*
dprint("Floor distance: ",ftos(distancefromfloor),"\n");
Modified: branches/nexuiz-2.0/data/qcsrc/server/havocbot_roles.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/havocbot_roles.qc 2007-05-02 17:12:05 UTC (rev 2453)
+++ branches/nexuiz-2.0/data/qcsrc/server/havocbot_roles.qc 2007-05-02 18:09:25 UTC (rev 2454)
@@ -126,7 +126,7 @@
void(float ratingscale) havocbot_goalrating_ctf_ourflag =
{
local entity head;
- if (self.team == 5) // red
+ if (self.team == COLOR_TEAM1) // red
head = find(world, classname, "item_flag_team1"); // red flag
else // blue
head = find(world, classname, "item_flag_team2"); // blue flag
@@ -136,7 +136,7 @@
void(float ratingscale) havocbot_goalrating_ctf_enemyflag =
{
local entity head;
- if (self.team == 5) // red
+ if (self.team == COLOR_TEAM1) // red
head = find(world, classname, "item_flag_team2"); // blue flag
else // blue
head = find(world, classname, "item_flag_team1"); // red flag
@@ -151,7 +151,7 @@
void(float ratingscale) havocbot_goalrating_ctf_ourstolenflag =
{
local entity head;
- if (self.team == 5) // red
+ if (self.team == COLOR_TEAM1) // red
head = find(world, classname, "item_flag_team1"); // red flag
else // blue
head = find(world, classname, "item_flag_team2"); // blue flag
@@ -234,7 +234,7 @@
return;
}
// check our flag
- if (self.team == 5) // red
+ if (self.team == COLOR_TEAM1) // red
f = find(world, classname, "item_flag_team1");
else // blue
f = find(world, classname, "item_flag_team2");
@@ -284,7 +284,7 @@
return;
}
// check our flag
- if (self.team == 5) // red
+ if (self.team == COLOR_TEAM1) // red
f = find(world, classname, "item_flag_team1");
else // blue
f = find(world, classname, "item_flag_team2");
@@ -325,7 +325,7 @@
return;
}
// check our flag
- if (self.team == 5) // red
+ if (self.team == COLOR_TEAM1) // red
f = find(world, classname, "item_flag_team1");
else // blue
f = find(world, classname, "item_flag_team2");
@@ -385,7 +385,7 @@
return;
}
// check our flag
- if (self.team == 5) // red
+ if (self.team == COLOR_TEAM1) // red
f = find(world, classname, "item_flag_team1");
else // blue
f = find(world, classname, "item_flag_team2");
@@ -453,7 +453,7 @@
{
local float r;
dprint("choose CTF role...\n");
- if (self.team == 13)
+ if (self.team == COLOR_TEAM3 || self.team == COLOR_TEAM4)
self.havocbot_role = havocbot_role_ctf_rogue;
else
{
@@ -508,6 +508,202 @@
self.havocbot_role = havocbot_role_dom;
};
+
+
+
+
+
+void(float ratingscale_team, float ratingscale_dropped, float ratingscale_enemy) havocbot_goalrating_kh =
+{
+ local entity head;
+ for(head = world; (head = find(head, classname, "item_kh_key")); )
+ {
+ if(head.owner == self)
+ continue;
+ if(!kh_tracking_enabled)
+ if(!head.owner || head.team == self.team)
+ continue; // skip what I can't see
+ if(!head.owner)
+ navigation_routerating(head, ratingscale_dropped);
+ else if(head.team == self.team)
+ navigation_routerating(head, ratingscale_team);
+ else
+ navigation_routerating(head, ratingscale_enemy);
+ }
+};
+
+void() havocbot_role_kh_carrier;
+void() havocbot_role_kh_defense;
+void() havocbot_role_kh_offense;
+void() havocbot_role_kh_freelancer;
+void() havocbot_role_kh_carrier =
+{
+ if (!(self.items & IT_KEY1))
+ {
+ dprint("changing role to freelancer\n");
+ self.havocbot_role = havocbot_role_kh_freelancer;
+ self.havocbot_role_timeout = 0;
+ return;
+ }
+
+ if (self.bot_strategytime < time)
+ {
+ self.bot_strategytime = time + cvar("bot_ai_strategyinterval");
+ navigation_goalrating_start();
+
+ if(kh_Key_AllOwnedByWhichTeam() == self.team)
+ havocbot_goalrating_kh(10000, 1, 1); // bring home
+ else
+ havocbot_goalrating_kh(4000, 4000, 100); // play defensively
+
+ havocbot_goalrating_items(10000, self.origin, 10000);
+ navigation_goalrating_end();
+ }
+}
+
+void() havocbot_role_kh_defense =
+{
+ if (self.items & IT_KEY1)
+ {
+ dprint("changing role to carrier\n");
+ self.havocbot_role = havocbot_role_kh_carrier;
+ self.havocbot_role_timeout = 0;
+ return;
+ }
+
+ if (!self.havocbot_role_timeout)
+ self.havocbot_role_timeout = time + random() * 10 + 20;
+ if (time > self.havocbot_role_timeout)
+ {
+ dprint("changing role to freelancer\n");
+ self.havocbot_role = havocbot_role_kh_freelancer;
+ self.havocbot_role_timeout = 0;
+ return;
+ }
+
+ if (self.bot_strategytime < time)
+ {
+ float key_owner_team;
+ self.bot_strategytime = time + cvar("bot_ai_strategyinterval");
+ navigation_goalrating_start();
+
+ key_owner_team = kh_Key_AllOwnedByWhichTeam();
+ if(key_owner_team == self.team)
+ havocbot_goalrating_kh(10000, 1, 1); // defend key carriers
+ else if(key_owner_team == -1)
+ havocbot_goalrating_kh(4000, 1000, 1); // play defensively
+ else
+ havocbot_goalrating_kh(1, 1, 10000); // ATTACK ANYWAY
+
+ havocbot_goalrating_items(10000, self.origin, 10000);
+ navigation_goalrating_end();
+ }
+};
+
+void() havocbot_role_kh_offense =
+{
+ if (self.items & IT_KEY1)
+ {
+ dprint("changing role to carrier\n");
+ self.havocbot_role = havocbot_role_kh_carrier;
+ self.havocbot_role_timeout = 0;
+ return;
+ }
+
+ if (!self.havocbot_role_timeout)
+ self.havocbot_role_timeout = time + random() * 10 + 20;
+ if (time > self.havocbot_role_timeout)
+ {
+ dprint("changing role to freelancer\n");
+ self.havocbot_role = havocbot_role_kh_freelancer;
+ self.havocbot_role_timeout = 0;
+ return;
+ }
+
+ if (self.bot_strategytime < time)
+ {
+ float key_owner_team;
+
+ self.bot_strategytime = time + cvar("bot_ai_strategyinterval");
+ navigation_goalrating_start();
+
+ key_owner_team = kh_Key_AllOwnedByWhichTeam();
+ if(key_owner_team == self.team)
+ havocbot_goalrating_kh(10000, 1, 1); // defend anyway
+ else if(key_owner_team == -1)
+ havocbot_goalrating_kh(1, 1000, 4000); // play offensively
+ else
+ havocbot_goalrating_kh(1, 1, 10000); // ATTACK! EMERGENCY!
+
+ havocbot_goalrating_items(10000, self.origin, 10000);
+ navigation_goalrating_end();
+ }
+};
+
+void() havocbot_role_kh_freelancer =
+{
+ if (self.items & IT_KEY1)
+ {
+ dprint("changing role to carrier\n");
+ self.havocbot_role = havocbot_role_kh_carrier;
+ self.havocbot_role_timeout = 0;
+ return;
+ }
+
+ if (!self.havocbot_role_timeout)
+ self.havocbot_role_timeout = time + random() * 10 + 10;
+ if (time > self.havocbot_role_timeout)
+ {
+ if (random() < 0.5)
+ {
+ dprint("changing role to offense\n");
+ self.havocbot_role = havocbot_role_kh_offense;
+ }
+ else
+ {
+ dprint("changing role to defense\n");
+ self.havocbot_role = havocbot_role_kh_defense;
+ }
+ self.havocbot_role_timeout = 0;
+ return;
+ }
+
+ if (self.bot_strategytime < time)
+ {
+ float key_owner_team;
+
+ self.bot_strategytime = time + cvar("bot_ai_strategyinterval");
+ navigation_goalrating_start();
+
+ key_owner_team = kh_Key_AllOwnedByWhichTeam();
+ if(key_owner_team == self.team)
+ havocbot_goalrating_kh(10000, 1, 1); // defend anyway
+ else if(key_owner_team == -1)
+ havocbot_goalrating_kh(1000, 4000, 1000); // prefer dropped keys
+ else
+ havocbot_goalrating_kh(1, 1, 10000); // ATTACK ANYWAY
+
+ havocbot_goalrating_items(10000, self.origin, 10000);
+ navigation_goalrating_end();
+ }
+};
+
+
+
+
+
+void() havocbot_chooserole_kh =
+{
+ local float r;
+ r = random() * 3;
+ if (r < 1)
+ self.havocbot_role = havocbot_role_kh_offense;
+ else if (r < 2)
+ self.havocbot_role = havocbot_role_kh_defense;
+ else
+ self.havocbot_role = havocbot_role_kh_freelancer;
+};
+
void() havocbot_chooserole =
{
dprint("choose a role...\n");
@@ -517,6 +713,8 @@
havocbot_chooserole_ctf();
else if (cvar("g_domination"))
havocbot_chooserole_dom();
+ else if (cvar("g_keyhunt"))
+ havocbot_chooserole_kh();
else // assume anything else is deathmatch
havocbot_chooserole_dm();
};
Copied: branches/nexuiz-2.0/data/qcsrc/server/keyhunt.qc (from rev 2414, trunk/data/qcsrc/server/keyhunt.qc)
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/keyhunt.qc (rev 0)
+++ branches/nexuiz-2.0/data/qcsrc/server/keyhunt.qc 2007-05-02 18:09:25 UTC (rev 2454)
@@ -0,0 +1,711 @@
+string STR_ITEM_KH_KEY = "item_kh_key";
+#define FOR_EACH_KH_KEY(v) for(v = world; (v = find(v, classname, STR_ITEM_KH_KEY)); )
+
+typedef void(void) kh_Think_t;
+var kh_Think_t kh_Controller_Thinkfunc;
+string kh_Controller_Waitmsg;
+
+float kh_Team_ByID(float t)
+{
+ if(t == 0) return COLOR_TEAM1;
+ if(t == 1) return COLOR_TEAM2;
+ if(t == 2) return COLOR_TEAM3;
+ if(t == 3) return COLOR_TEAM4;
+ return 0;
+}
+
+entity kh_controller;
+float kh_tracking_enabled;
+float kh_teams;
+float kh_interferemsg_time, kh_interferemsg_team;
+.entity kh_next, kh_prev; // linked list
+.float kh_droptime;
+
+string kh_sound_capture = "sound/ctf/capture.wav";
+string kh_sound_destroy = "sound/ctf/return.wav";
+string kh_sound_drop = "sound/misc/mouseclick.wav";
+string kh_sound_collect = "sound/ctf/take.wav";
+
+float kh_sprite_dropped, kh_sprite_finish, kh_sprite_red, kh_sprite_blue, kh_sprite_pink, kh_sprite_yellow, kh_sprite_friend;
+
+float kh_GetCarrierSprite(float t, float e)
+{
+ if(t == e) return kh_sprite_friend;
+ if(t == COLOR_TEAM1) return kh_sprite_red;
+ if(t == COLOR_TEAM2) return kh_sprite_blue;
+ if(t == COLOR_TEAM3) return kh_sprite_yellow;
+ if(t == COLOR_TEAM4) return kh_sprite_pink;
+ return 0;
+}
+
+void kh_Controller_SetThink(float t, string msg, kh_Think_t func)
+{
+ kh_Controller_Thinkfunc = func;
+ kh_controller.cnt = t;
+ if(kh_Controller_Waitmsg != "")
+ strunzone(kh_Controller_Waitmsg);
+ if(msg == "")
+ kh_Controller_Waitmsg = "";
+ else
+ kh_Controller_Waitmsg = strzone(msg);
+ if(t == 0)
+ kh_controller.nextthink = time; // force
+}
+
+void kh_Controller_Think()
+{
+ entity e;
+ if(intermission_running)
+ return;
+ if(self.cnt > 0)
+ {
+ if(kh_Controller_Waitmsg != "")
+ {
+ string s;
+ if(substring(kh_Controller_Waitmsg, strlen(kh_Controller_Waitmsg)-1, 1) == " ")
+ s = strcat(kh_Controller_Waitmsg, ftos(self.cnt));
+ else
+ s = kh_Controller_Waitmsg;
+
+ dprint(s, "\n");
+
+ FOR_EACH_PLAYER(e)
+ if(clienttype(e) == CLIENTTYPE_REAL)
+ centerprint_atprio(e, CENTERPRIO_SPAM, s);
+ }
+ self.cnt -= 1;
+ }
+ else if(self.cnt == 0)
+ {
+ self.cnt -= 1;
+ kh_Controller_Thinkfunc();
+ }
+ self.nextthink = time + 1;
+}
+
+// frags f: take from cvar * f
+// frags 0: no frags
+void kh_Scores_Event(entity player, entity key, string what, float frags_player, float frags_owner)
+{
+ string s;
+ if(frags_player)
+ player.frags = player.frags + floor(0.5 + frags_player);
+ if(frags_owner)
+ key.owner.frags = key.owner.frags + floor(0.5 + frags_owner);
+ if(!cvar("sv_eventlog"))
+ return;
+ s = strcat(":keyhunt:", what, ":", ftos(player.playerid));
+ s = strcat(s, ":", ftos(frags_player));
+ if(key && key.owner)
+ s = strcat(s, ":", ftos(key.owner.playerid));
+ else
+ s = strcat(s, ":0");
+ s = strcat(s, ":", ftos(frags_owner), ":");
+ if(key)
+ s = strcat(s, key.netname);
+ GameLogEcho(s, FALSE);
+}
+
+void kh_Key_Attach(entity key)
+{
+ setattachment(key, key.owner, "");
+ setorigin(key, '0 0 -15'); // x/y fixed later in think, z has to be -15 to make the key fit even in the crouchbox
+ key.angles_y -= key.owner.angles_y;
+ key.flags = 0;
+ key.solid = SOLID_NOT;
+ key.movetype = MOVETYPE_NONE;
+ key.team = key.owner.team;
+ key.nextthink = time;
+ key.damageforcescale = 0;
+}
+
+vector kh_AttachedOrigin(entity e)
+{
+ if(e.tag_entity)
+ {
+ makevectors(e.tag_entity.angles);
+ return e.tag_entity.origin + e.origin_x * v_forward - e.origin_y * v_right + e.origin_z * v_up;
+ }
+ else
+ return e.origin;
+}
+
+void kh_Key_Detach(entity key)
+{
+ setorigin(key, key.owner.origin + key.origin_z * '0 0 1');
+ setattachment(key, world, "");
+ key.angles_y += key.owner.angles_y;
+ key.aiment = world;
+ key.flags = FL_ITEM;
+ key.solid = SOLID_TRIGGER;
+ key.movetype = MOVETYPE_TOSS;
+ key.pain_finished = time + cvar("g_balance_keyhunt_delay_return");
+ key.damageforcescale = cvar("g_balance_keyhunt_damageforcescale");
+ // let key.team stay
+}
+
+void kh_Key_AssignTo(entity key, entity player)
+{
+ if(key.owner == player)
+ return;
+
+ if(key.owner)
+ {
+ kh_Key_Detach(key);
+
+ // remove from linked list
+ if(key.kh_next)
+ key.kh_next.kh_prev = key.kh_prev;
+ key.kh_prev.kh_next = key.kh_next;
+ key.kh_next = world;
+ key.kh_prev = world;
+
+ if(key.owner.kh_next == world)
+ {
+ // No longer a key carrier
+ WaypointSprite_DetachCarrier(key.owner);
+ }
+ }
+
+ key.owner = player;
+
+ if(player)
+ {
+ // insert into linked list
+ key.kh_next = player.kh_next;
+ key.kh_prev = player;
+ player.kh_next = key;
+ if(key.kh_next)
+ key.kh_next.kh_prev = key;
+
+ kh_Key_Attach(key);
+
+ if(key.kh_next == world)
+ {
+ // player is now a key carrier
+ WaypointSprite_AttachCarrier("", player);
+ player.waypointsprite_attachedforcarrier.waypointsprite_for_player = kh_KeyCarrier_waypointsprite_for_player;
+ player.waypointsprite_attachedforcarrier.team = player.team;
+ }
+ }
+
+ key.pusher = world;
+}
+
+void kh_Key_Damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
+{
+ if(self.owner)
+ return;
+ if(vlen(force) <= 0)
+ return;
+ if(time > self.pushltime)
+ if(attacker.classname == "player")
+ self.team = attacker.team;
+}
+
+void kh_Key_Spawn(entity initial_owner, float angle)
+{
+ entity key;
+ key = spawn();
+ key.classname = STR_ITEM_KH_KEY;
+ key.touch = kh_Key_Touch;
+ key.think = kh_Key_Think;
+ key.nextthink = time;
+ key.items = IT_KEY1 | IT_KEY2;
+ key.cnt = angle;
+ key.angles = '0 360 0' * random();
+ key.event_damage = kh_Key_Damage;
+ setmodel(key, "models/keyhunt/key.md3");
+ setsize(key, '-8 -8 -8', '8 8 40');
+
+ switch(initial_owner.team)
+ {
+ case COLOR_TEAM1:
+ key.netname = "^1red key";
+ key.colormod = '103 0 0' * (1/96);
+ break;
+ case COLOR_TEAM2:
+ key.netname = "^4blue key";
+ key.colormod = '35 35 191' * (1/96);
+ break;
+ case COLOR_TEAM3:
+ key.netname = "^3yellow key";
+ key.colormod = '187 167 15' * (1/96);
+ break;
+ case COLOR_TEAM4:
+ key.netname = "^6pink key";
+ key.colormod = '139 79 107' * (1/96);
+ break;
+ default:
+ key.netname = "NETGIER key";
+ key.colormod = '1 1 1';
+ break;
+ }
+
+ sprint(initial_owner, strcat("You got the ^2", key.netname, "\n"));
+
+ WaypointSprite_AttachCarrier("", key);
+ key.waypointsprite_attachedforcarrier.waypointsprite_for_player = kh_Key_waypointsprite_for_player;
+
+ kh_Key_AssignTo(key, initial_owner);
+}
+
+void kh_Key_Remove(entity key)
+{
+ entity o;
+ o = key.owner;
+ kh_Key_AssignTo(key, world);
+ if(o) // it was attached
+ WaypointSprite_Kill(key.waypointsprite_attachedforcarrier);
+ else // it was dropped
+ WaypointSprite_DetachCarrier(key);
+
+ remove(key);
+}
+
+// -1 when no team completely owns all keys yet
+float kh_Key_AllOwnedByWhichTeam()
+{
+ entity key;
+ float teem;
+
+ teem = -1;
+ FOR_EACH_KH_KEY(key)
+ {
+ if(!key.owner)
+ return -1;
+ if(teem == -1)
+ teem = key.team;
+ else if(teem != key.team)
+ return -1;
+ }
+ return teem;
+}
+
+void kh_Key_Collect(entity key, entity player)
+{
+ sound(key, CHAN_AUTO, kh_sound_collect, 1, ATTN_NORM);
+
+ kh_Scores_Event(player, key, "collect", cvar("g_balance_keyhunt_score_collect"), 0);
+ bprint(player.netname, "^7 collected the ", key.netname, "\n");
+ kh_Key_AssignTo(key, player);
+
+ if(kh_Key_AllOwnedByWhichTeam() != -1)
+ {
+ kh_interferemsg_time = time + 0.2;
+ kh_interferemsg_team = player.team;
+ }
+}
+
+void kh_Key_DropAll(entity player)
+{
+ entity key;
+ entity mypusher;
+ if(player.kh_next)
+ {
+ mypusher = world;
+ if(player.pusher)
+ if(time < player.pushltime)
+ mypusher = player.pusher;
+ while((key = player.kh_next))
+ {
+ kh_Scores_Event(player, key, "losekey", 0, 0);
+ bprint(player.netname, "^7 lost the ", key.netname, "\n");
+ kh_Key_AssignTo(key, world);
+ makevectors('-1 0 0' * (45 + 45 * random()) + '0 360 0' * random());
+ key.velocity = W_CalculateProjectileVelocity(player.velocity, cvar("g_balance_keyhunt_dropvelocity") * v_forward);
+ key.pusher = mypusher;
+ key.pushltime = time + cvar("g_balance_keyhunt_protecttime");
+ }
+ sound(player, CHAN_AUTO, kh_sound_drop, 1, ATTN_NORM);
+ }
+}
+
+void kh_Key_Touch()
+{
+ if(self.owner) // already carried
+ return;
+ if(other.classname != "player")
+ return;
+ if(other.deadflag != DEAD_NO)
+ return;
+ if(other == self.enemy)
+ if(time < self.kh_droptime + cvar("g_balance_keyhunt_delay_collect"))
+ return; // you just dropped it!
+ kh_Key_Collect(self, other);
+}
+
+void kh_Key_Think()
+{
+ entity head;
+
+ //self.angles_y = math_mod(self.angles_y + 0.05 * 135, 360);
+ // model is EF_ROTATING now
+
+ if(self.owner)
+ {
+ makevectors('0 1 0' * (self.cnt + math_mod(time, 360) * 45));
+ setorigin(self, v_forward * 24 + '0 0 1' * self.origin_z);
+
+ if(self.owner.buttonuse)
+ if(time >= self.owner.kh_droptime + cvar("g_balance_keyhunt_delay_drop"))
+ {
+ self.owner.kh_droptime = time;
+ self.kh_droptime = time; // prevent collecting this one for some time
+ self.enemy = self.owner;
+ self.pusher = world;
+ kh_Scores_Event(self.owner, self, "dropkey", 0, 0);
+ bprint(self.owner.netname, "^7 dropped the ", self.netname, "\n");
+ sound(self.owner, CHAN_AUTO, kh_sound_drop, 1, ATTN_NORM);
+ makevectors(self.owner.v_angle);
+ self.velocity = W_CalculateProjectileVelocity(self.owner.velocity, cvar("g_balance_keyhunt_throwvelocity") * v_forward);
+ kh_Key_AssignTo(self, world);
+ self.pushltime = time + cvar("g_balance_keyhunt_protecttime");
+ }
+ }
+
+ // if in nodrop or time over, end the round
+ if(!self.owner)
+ if(time > self.pain_finished)
+ kh_LoserTeam(self.team, self);
+
+ if(self.owner)
+ if(kh_Key_AllOwnedByWhichTeam() != -1)
+ {
+ entity key;
+ vector p;
+ p = self.owner.origin;
+ FOR_EACH_KH_KEY(key)
+ if(vlen(key.owner.origin - p) > cvar("g_balance_keyhunt_maxdist"))
+ goto not_winning;
+ kh_WinnerTeam(self.team);
+:not_winning
+ }
+
+ if(kh_interferemsg_time && time > kh_interferemsg_time)
+ {
+ kh_interferemsg_time = 0;
+ FOR_EACH_PLAYER(head)
+ {
+ if(head.team == kh_interferemsg_team)
+ if(head.kh_next)
+ centerprint(head, "All keys are in your team's hands!\n\nMeet the other key carriers ^1NOW^7!\n");
+ else
+ centerprint(head, "All keys are in your team's hands!\n\nHelp the key carriers to meet!\n");
+ else
+ centerprint(head, "All keys are in the enemy's hands!\n\nInterfere ^1NOW^7!\n");
+ }
+ }
+
+ self.nextthink = time + 0.05;
+}
+
+void kh_WinnerTeam(float teem)
+{
+ // all key carriers get some points
+ vector firstorigin, lastorigin;
+ float first;
+ entity key;
+ float score;
+ score = (kh_teams - 1) * cvar("g_balance_keyhunt_score_capture");
+ DistributeEvenly_Init(score, kh_teams);
+ // twice the score for 3 team games, three times the score for 4 team games!
+ // note: for a win by destroying the key, this should NOT be applied
+ FOR_EACH_KH_KEY(key)
+ kh_Scores_Event(key.owner, key, "capture", DistributeEvenly_Get(1), 0);
+
+ first = TRUE;
+ FOR_EACH_KH_KEY(key)
+ if(key.owner.kh_next == key)
+ {
+ if(!first)
+ bprint("^7, ");
+ bprint(key.owner.netname);
+ first = FALSE;
+ }
+ bprint("^7 captured the keys for the ", ColoredTeamName(teem), "\n");
+
+ first = TRUE;
+ FOR_EACH_KH_KEY(key)
+ {
+ vector thisorigin;
+
+ thisorigin = kh_AttachedOrigin(key);
+
+ if(!first)
+ te_lightning2(world, lastorigin, thisorigin);
+ lastorigin = thisorigin;
+ if(first)
+ firstorigin = thisorigin;
+ first = FALSE;
+ }
+ if(kh_teams > 2)
+ {
+ te_lightning2(world, lastorigin, firstorigin);
+ }
+
+ sound(world, CHAN_AUTO, kh_sound_capture, 1, ATTN_NONE);
+ kh_FinishRound();
+}
+
+void kh_LoserTeam(float teem, entity lostkey)
+{
+ entity player, key, attacker;
+ float players;
+ float keys;
+
+ attacker = world;
+ if(lostkey.pusher)
+ if(lostkey.pusher.team != teem)
+ if(lostkey.pusher.classname == "player")
+ attacker = lostkey.pusher;
+
+ players = keys = 0;
+
+ if(attacker)
+ {
+ kh_Scores_Event(attacker, world, "push", cvar("g_balance_keyhunt_score_push"), 0);
+ centerprint(attacker, "Your push is the best!\n\n\n");
+ bprint("The ", ColoredTeamName(teem), "^7 could not take care of the ", lostkey.netname, "\n");
+ }
+ else
+ {
+ float of, fragsleft, i, thisteam;
+ of = cvar("g_balance_keyhunt_score_destroyed_ownfactor");
+
+ FOR_EACH_PLAYER(player)
+ if(player.team != teem)
+ ++players;
+
+ FOR_EACH_KH_KEY(key)
+ if(key.owner && key.team != teem)
+ ++keys;
+
+ DistributeEvenly_Init(cvar("g_balance_keyhunt_score_destroyed"), keys * of + players);
+
+ FOR_EACH_KH_KEY(key)
+ if(key.owner && key.team != teem)
+ kh_Scores_Event(key.owner, world, "destroyed_holdingkey", DistributeEvenly_Get(of), 0);
+
+ fragsleft = DistributeEvenly_Get(players);
+
+ // Now distribute these among all other teams...
+ for(i = 0; i < kh_teams; ++i)
+ {
+ thisteam = kh_Team_ByID(i);
+ players = 0;
+ FOR_EACH_PLAYER(player)
+ if(player.team == thisteam)
+ ++players;
+
+ DistributeEvenly_Init(fragsleft, kh_teams - i);
+ fragsleft = DistributeEvenly_Get(kh_teams - i - 1);
+ DistributeEvenly_Init(DistributeEvenly_Get(1), players);
+
+ FOR_EACH_PLAYER(player)
+ if(player.team == thisteam)
+ kh_Scores_Event(player, world, "destroyed", DistributeEvenly_Get(1), 0);
+ }
+
+ bprint("The ", ColoredTeamName(teem), "^7 could not take care of the ", lostkey.netname, "\n");
+ }
+ sound(world, CHAN_AUTO, kh_sound_destroy, 1, ATTN_NONE);
+
+ kh_FinishRound();
+}
+
+void kh_FinishRound()
+{
+ // prepare next round
+ kh_interferemsg_time = 0;
+ entity key;
+ FOR_EACH_KH_KEY(key)
+ kh_Key_Remove(key);
+
+ kh_Controller_SetThink(cvar("g_balance_keyhunt_delay_round"), "Round starts in ", kh_StartRound);
+}
+
+float kh_EnoughPlayers()
+{
+ float i, players, teem;
+ entity player;
+
+ // find a random player per team
+ for(i = 0; i < kh_teams; ++i)
+ {
+ teem = kh_Team_ByID(i);
+ players = 0;
+ FOR_EACH_PLAYER(player)
+ if(player.deadflag == DEAD_NO)
+ if(player.team == teem)
+ ++players;
+ if(players == 0)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void kh_WaitForPlayers()
+{
+ if(kh_EnoughPlayers())
+ kh_Controller_SetThink(cvar("g_balance_keyhunt_delay_round"), "Round starts in ", kh_StartRound);
+ else
+ kh_Controller_SetThink(1, "Waiting for players to join...", kh_WaitForPlayers);
+}
+
+void kh_StartRound()
+{
+ float i, players, teem;
+ entity player;
+
+ if(!kh_EnoughPlayers())
+ {
+ kh_Controller_SetThink(1, "Waiting for players to join...", kh_WaitForPlayers);
+ return;
+ }
+
+ FOR_EACH_PLAYER(player)
+ if(clienttype(player) == CLIENTTYPE_REAL)
+ centerprint_expire(player, CENTERPRIO_SPAM);
+
+ for(i = 0; i < kh_teams; ++i)
+ {
+ teem = kh_Team_ByID(i);
+ players = 0;
+ entity my_player;
+ FOR_EACH_PLAYER(player)
+ if(player.deadflag == DEAD_NO)
+ if(player.team == teem)
+ {
+ ++players;
+ if(random() * players <= 1)
+ my_player = player;
+ }
+ kh_Key_Spawn(my_player, 360 * i / kh_teams);
+ }
+
+ kh_tracking_enabled = FALSE;
+ kh_Controller_SetThink(cvar("g_balance_keyhunt_delay_tracking"), "Scanning frequency range...", kh_EnableTrackingDevice);
+}
+
+void kh_setstatus()
+{
+ if(kh_teams)
+ {
+ float kh_KEY;
+ kh_KEY = (IT_RED_FLAG_TAKEN | IT_RED_FLAG_LOST | IT_BLUE_FLAG_TAKEN | IT_BLUE_FLAG_LOST); // the one impossible combination
+ if(self.kh_next)
+ self.items = self.items | kh_KEY;
+ else
+ self.items = self.items - (self.items & kh_KEY);
+ }
+}
+
+void kh_EnableTrackingDevice()
+{
+ entity player;
+
+ FOR_EACH_PLAYER(player)
+ if(clienttype(player) == CLIENTTYPE_REAL)
+ centerprint_expire(player, CENTERPRIO_SPAM);
+
+ kh_tracking_enabled = TRUE;
+}
+
+float kh_Key_waypointsprite_for_player(entity e)
+{
+ if(!kh_tracking_enabled)
+ return 0;
+ if(!self.owner)
+ return kh_sprite_dropped;
+ if(!self.owner.owner)
+ return kh_sprite_dropped;
+ return 0; // draw only when key is not owned
+}
+
+float kh_KeyCarrier_waypointsprite_for_player(entity e)
+{
+ if(e.classname != "player" || self.team != e.team)
+ if(!kh_tracking_enabled)
+ return 0;
+
+ // e is spectator? That's no team mate...
+ if(e.classname != "player")
+ return kh_GetCarrierSprite(self.team, -1);
+
+ // e is no key carrier: simple case...
+ if(!e.kh_next)
+ return kh_GetCarrierSprite(self.team, e.team);
+
+ // e is a key carrier: if any key is dropped or owned by another team, show
+ // the carrier sprite; otherwise show run here
+ if(kh_Key_AllOwnedByWhichTeam() == e.team)
+ return kh_sprite_finish;
+
+ return kh_GetCarrierSprite(self.team, e.team);
+}
+
+float kh_HandleFrags(entity attacker, entity targ, float f)
+{
+ if(f <= 0)
+ return f;
+ if(attacker == targ)
+ return f;
+
+ if(targ.kh_next)
+ kh_Scores_Event(attacker, targ.kh_next, "carrierfrag", cvar("g_balance_keyhunt_score_carrierfrag")-1, 0);
+
+ return f;
+}
+
+void kh_init()
+{
+ precache_sound(kh_sound_capture);
+ precache_sound(kh_sound_destroy);
+ precache_sound(kh_sound_drop);
+ precache_sound(kh_sound_collect);
+
+ precache_model("models/sprites/key-dropped.sp2");
+ precache_model("models/sprites/keycarrier-finish.sp2");
+ precache_model("models/sprites/keycarrier-friend.sp2");
+ precache_model("models/sprites/keycarrier-red.sp2");
+ precache_model("models/sprites/keycarrier-blue.sp2");
+ precache_model("models/sprites/keycarrier-yellow.sp2");
+ precache_model("models/sprites/keycarrier-pink.sp2");
+ precache_model("models/keyhunt/key.md3");
+
+ // setup variables
+ kh_teams = cvar("g_keyhunt_teams_override");
+ if(kh_teams < 2)
+ kh_teams = cvar("g_keyhunt_teams");
+ kh_teams = bound(2, kh_teams, 4);
+
+ // make a KH entity for controlling the game
+ kh_controller = spawn();
+ kh_controller.think = kh_Controller_Think;
+ kh_Controller_SetThink(0, "", kh_WaitForPlayers);
+
+ setmodel(kh_controller, "models/sprites/key-dropped.sp2");
+ kh_sprite_dropped = kh_controller.modelindex;
+ setmodel(kh_controller, "models/sprites/keycarrier-finish.sp2");
+ kh_sprite_finish = kh_controller.modelindex;
+ setmodel(kh_controller, "models/sprites/keycarrier-friend.sp2");
+ kh_sprite_friend = kh_controller.modelindex;
+ setmodel(kh_controller, "models/sprites/keycarrier-red.sp2");
+ kh_sprite_red = kh_controller.modelindex;
+ setmodel(kh_controller, "models/sprites/keycarrier-blue.sp2");
+ kh_sprite_blue = kh_controller.modelindex;
+ setmodel(kh_controller, "models/sprites/keycarrier-pink.sp2");
+ kh_sprite_pink = kh_controller.modelindex;
+ setmodel(kh_controller, "models/sprites/keycarrier-yellow.sp2");
+ kh_sprite_yellow = kh_controller.modelindex;
+ setmodel(kh_controller, "");
+}
+
+void kh_finalize()
+{
+ // to be called before intermission
+ kh_FinishRound();
+ remove(kh_controller);
+ kh_controller = world;
+}
Copied: branches/nexuiz-2.0/data/qcsrc/server/keyhunt.qh (from rev 2414, trunk/data/qcsrc/server/keyhunt.qh)
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/keyhunt.qh (rev 0)
+++ branches/nexuiz-2.0/data/qcsrc/server/keyhunt.qh 2007-05-02 18:09:25 UTC (rev 2454)
@@ -0,0 +1,25 @@
+float kh_teams;
+float kh_tracking_enabled;
+
+void kh_Scores_Event(entity player, entity key, string what, float frags_player, float frags_owner);
+void kh_Key_Attach(entity key);
+void kh_Key_Detach(entity key);
+void kh_Key_AssignTo(entity key, entity player);
+void kh_Key_Spawn(entity initial_owner, float angle);
+void kh_Key_Remove(entity key);
+void kh_Key_Collect(entity key, entity player);
+void kh_Key_DropAll(entity player);
+void kh_Key_Touch();
+void kh_Key_Think();
+void kh_WinnerTeam(float teem);
+void kh_LoserTeam(float teem, entity lostkey);
+void kh_FinishRound();
+void kh_StartRound();
+void kh_EnableTrackingDevice();
+void kh_init();
+void kh_finalize();
+float kh_KeyCarrier_waypointsprite_for_player(entity e);
+float kh_Key_waypointsprite_for_player(entity e);
+void kh_setstatus();
+float kh_HandleFrags(entity attacker, entity targ, float f);
+float kh_Key_AllOwnedByWhichTeam();
Modified: branches/nexuiz-2.0/data/qcsrc/server/miscfunctions.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/miscfunctions.qc 2007-05-02 17:12:05 UTC (rev 2453)
+++ branches/nexuiz-2.0/data/qcsrc/server/miscfunctions.qc 2007-05-02 18:09:25 UTC (rev 2454)
@@ -1,3 +1,29 @@
+void() info_player_deathmatch; // needed for the other spawnpoints
+string ColoredTeamName(float t);
+
+float DistributeEvenly_amount;
+float DistributeEvenly_totalweight;
+void DistributeEvenly_Init(float amount, float totalweight)
+{
+ if(DistributeEvenly_amount)
+ {
+ dprint("DistributeEvenly_Init: UNFINISHED DISTRIBUTION (", ftos(DistributeEvenly_amount), " for ");
+ dprint(ftos(DistributeEvenly_totalweight), "left!\n");
+ }
+ DistributeEvenly_amount = amount;
+ DistributeEvenly_totalweight = totalweight;
+}
+float DistributeEvenly_Get(float weight)
+{
+ float f;
+ if(weight <= 0)
+ return 0;
+ f = floor(0.5 + DistributeEvenly_amount * weight / DistributeEvenly_totalweight);
+ DistributeEvenly_totalweight -= weight;
+ DistributeEvenly_amount -= f;
+ return f;
+}
+
void move_out_of_solid_expand(entity e, vector by)
{
float eps = 0.0625;
@@ -492,10 +518,9 @@
void DistributeFragsAmongTeam(entity p, float targetteam, float factor)
{
- float f;
- float d;
float nTeam;
entity head;
+ float f;
if(!teams_matter)
return;
@@ -521,20 +546,12 @@
if(nTeam == 0)
return;
+ DistributeEvenly_Init(f, nTeam);
+
FOR_EACH_PLAYER(head)
if(head != p)
if(head.team == targetteam)
- {
- d = floor(f / nTeam);
- head.frags = head.frags + d;
- f = f - d;
- nTeam = nTeam - 1;
- }
-
- if(nTeam != 0)
- error("nPlayers in team changed!");
- if(f != 0)
- error(strcat("There were ", ftos(f), " frags left. BAD!"));
+ head.frags = head.frags + DistributeEvenly_Get(1);
}
string Team_ColorCode(float teamid)
@@ -544,9 +561,9 @@
else if(teamid == COLOR_TEAM2)
return "^4";
else if(teamid == COLOR_TEAM3)
+ return "^3";
+ else if(teamid == COLOR_TEAM4)
return "^6";
- else if(teamid == COLOR_TEAM4)
- return "^3";
else
return "^7";
}
@@ -608,6 +625,7 @@
*/
#define CENTERPRIO_POINT 1
+#define CENTERPRIO_SPAM 2
#define CENTERPRIO_REBALANCE 2
#define CENTERPRIO_VOTE 4
#define CENTERPRIO_NORMAL 5
@@ -703,3 +721,30 @@
g_pickup_healthmega = cvar("g_pickup_healthmega");
g_pickup_healthmega_max = cvar("g_pickup_healthmega_max");
}
+
+/*
+// TODO sound pack system
+string soundpack;
+
+string precache_sound_builtin (string s) = #19;
+void(entity e, float chan, string samp, float vol, float atten) sound_builtin = #8;
+string precache_sound(string s)
+{
+ return precache_sound_builtin(strcat(soundpack, s));
+}
+void play2(entity e, string filename)
+{
+ stuffcmd(e, strcat("play2 ", soundpack, filename, "\n"));
+}
+void sound(entity e, float chan, string samp, float vol, float atten)
+{
+ sound_builtin(e, chan, strcat(soundpack, samp), vol, atten);
+}
+*/
+
+string precache_sound (string s) = #19;
+void(entity e, float chan, string samp, float vol, float atten) sound = #8;
+void play2(entity e, string filename)
+{
+ stuffcmd(e, strcat("play2 ", filename, "\n"));
+}
Modified: branches/nexuiz-2.0/data/qcsrc/server/progs.src
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/progs.src 2007-05-02 17:12:05 UTC (rev 2453)
+++ branches/nexuiz-2.0/data/qcsrc/server/progs.src 2007-05-02 18:09:25 UTC (rev 2454)
@@ -12,6 +12,8 @@
../common/util.qh
../common/util.qc
+keyhunt.qh
+
miscfunctions.qc
waypointsprites.qc
@@ -84,3 +86,5 @@
../common/gamecommand.qc
gamecommand.qc
+
+keyhunt.qc
Modified: branches/nexuiz-2.0/data/qcsrc/server/t_items.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/t_items.qc 2007-05-02 17:12:05 UTC (rev 2453)
+++ branches/nexuiz-2.0/data/qcsrc/server/t_items.qc 2007-05-02 18:09:25 UTC (rev 2454)
@@ -54,12 +54,12 @@
// play some cool sounds ;)
centerprint(other, "\n");
if(other.health <= 5)
- stuffcmd(other, "play2 announcer/robotic/lastsecond.ogg\n");
+ play2(other, "announcer/robotic/lastsecond.ogg");
else if(other.health < 50)
- stuffcmd(other, "play2 announcer/robotic/narrowly.ogg\n");
+ play2(other, "announcer/robotic/narrowly.ogg");
// sound not available
// else if(self.items == IT_CELLS)
- // stuffcmd(other, "play2 announce/robotic/ammo.ogg\n");
+ // play2(other, "announce/robotic/ammo.ogg");
if (self.items & IT_NEX)
W_GiveWeapon (other, IT_NEX, "Nex");
@@ -73,7 +73,7 @@
{
pickedup = TRUE;
// sound not available
- // stuffcmd(other, "play2 announce/robotic/extra.ogg\nplay2 announce/robotic/_lives.ogg\n");
+ // play2(other, "announce/robotic/extra.ogg\nplay2 announce/robotic/_lives.ogg");
other.armorvalue = other.armorvalue + cvar("g_minstagib_extralives");
sprint(other, "^3You picked up some extra lives\n");
}
@@ -83,7 +83,7 @@
{
pickedup = TRUE;
// sound not available
- // stuffcmd(other, "play2 announce/robotic/invisible.ogg\n");
+ // play2(other, "announce/robotic/invisible.ogg");
other.strength_finished = max(other.strength_finished, time) + cvar("g_balance_powerup_strength_time");
}
@@ -92,7 +92,7 @@
{
pickedup = TRUE;
// sound not available
- // stuffcmd(other, "play2 announce/robotic/speed.ogg\n");
+ // play2(other, "announce/robotic/speed.ogg");
other.invincible_finished = max(other.invincible_finished, time) + cvar("g_balance_powerup_strength_time");
}
}
@@ -376,7 +376,10 @@
self.touch = Item_Touch;
setmodel (self, self.mdl); // precision set below
self.effects |= EF_LOWPRECISION;
- setsize (self, '-16 -16 0', '16 16 32');
+ if((itemflags & FL_POWERUP) || self.health || self.armorvalue)
+ setsize (self, '-16 -16 0', '16 16 48');
+ else
+ setsize (self, '-16 -16 0', '16 16 32');
if (itemflags & FL_WEAPON)
{
// neutral team color for pickup weapons
Modified: branches/nexuiz-2.0/data/qcsrc/server/teamplay.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/teamplay.qc 2007-05-02 17:12:05 UTC (rev 2453)
+++ branches/nexuiz-2.0/data/qcsrc/server/teamplay.qc 2007-05-02 18:09:25 UTC (rev 2454)
@@ -5,13 +5,14 @@
float GAME_RUNEMATCH = 5;
float GAME_LMS = 6;
float GAME_ARENA = 7;
+float GAME_KEYHUNT = 8;
// client counts for each team
float c1, c2, c3, c4;
// # of bots on those teams
float cb1, cb2, cb3, cb4;
-float g_domination, g_ctf, g_tdm;
+float g_domination, g_ctf, g_tdm, g_keyhunt;
float audit_teams_time;
@@ -44,9 +45,9 @@
if(t == COLOR_TEAM2)
return "Blue Team";
if(t == COLOR_TEAM3)
+ return "Yellow Team";
+ if(t == COLOR_TEAM4)
return "Pink Team";
- if(t == COLOR_TEAM4)
- return "Yellow Team";
return "Neutral Team";
}
string ColoredTeamName(float t)
@@ -57,9 +58,9 @@
if(t == COLOR_TEAM2)
return "^4Blue Team^7";
if(t == COLOR_TEAM3)
+ return "^3Yellow Team^7";
+ if(t == COLOR_TEAM4)
return "^6Pink Team^7";
- if(t == COLOR_TEAM4)
- return "^3Yellow Team^7";
return "Neutral Team";
}
string TeamNoName(float t)
@@ -70,9 +71,9 @@
if(t == 2)
return "Blue Team";
if(t == 3)
+ return "Yellow Team";
+ if(t == 4)
return "Pink Team";
- if(t == 4)
- return "Yellow Team";
return "Neutral Team";
}
@@ -101,6 +102,7 @@
cvar_set("g_runematch", "0");
cvar_set("g_lms", "0");
cvar_set("g_arena", "0");
+ cvar_set("g_keyhunt", "0");
cvar_set("teamplay", "0");
}
@@ -224,6 +226,16 @@
gamemode_name = "Arena";
teams_matter = 0;
}
+ else if(game == GAME_KEYHUNT || cvar("g_keyhunt"))
+ {
+ ResetGameCvars();
+ game = GAME_KEYHUNT;
+ cvar_set("g_keyhunt", "1");
+ fraglimit_override = cvar("g_keyhunt_point_limit");
+ ActivateTeamplay();
+ gamemode_name = "Key Hunt";
+ teams_matter = 1;
+ }
else
{
// we can only assume...
@@ -260,6 +272,8 @@
runematch_init();
else if (game == GAME_TEAM_DEATHMATCH)//cvar("g_runematch"))
tdm_init();
+ else if (game == GAME_KEYHUNT)//cvar("g_keyhunt"))
+ kh_init();
// those mutators rule each other out
if(cvar("g_minstagib"))
@@ -286,6 +300,7 @@
g_domination = cvar("g_domination");
g_ctf = cvar("g_ctf");
g_tdm = cvar("g_tdm");
+ g_keyhunt = cvar("g_keyhunt");
}
string GetClientVersionMessage(float v) {
@@ -503,7 +518,10 @@
else
{
// cover anything else by treating it like tdm with no teams spawned
- dm = cvar("g_tdm_teams");
+ if(g_keyhunt)
+ dm = kh_teams;
+ else
+ dm = cvar("g_tdm_teams");
if(dm < 2)
error("g_tdm_teams < 2, not enough teams to play team deathmatch\n");
@@ -634,6 +652,8 @@
error("Too few teams available for domination\n");
else if(g_ctf)
error("Too few teams available for ctf\n");
+ else if(g_keyhunt)
+ error("Too few teams available for key hunt\n");
else
error("Too few teams available for team deathmatch\n");
}
@@ -719,7 +739,7 @@
float smallest, selectedteam;
// don't join a team if we're not playing a team game
- if(!cvar("teamplay") && !g_domination && !g_ctf)
+ if(!cvar("teamplay") && !g_domination && !g_ctf && !g_keyhunt)
return 0;
// find out what teams are available
@@ -948,7 +968,6 @@
float smallestteam, smallestteam_count, steam;
float lowest_bot_score, lowest_player_score;
entity head, lowest_bot, lowest_player, selected;
- string m;
smallestteam = 0;
smallestteam_count = 999999999;
@@ -1081,17 +1100,8 @@
SetPlayerTeam(selected, smallestteam, source_team, FALSE);
if(selected.deadflag == DEAD_NO)
- Damage(selected, selected, selected, 100000, DEATH_AUTOTEAMCHANGE, selected.origin, '0 0 0');
- m = "You have been moved into a different team to improve team balance\nYou are now on: ";
- if (selected.team == 5)
- m = strcat(m, "^1Red Team");
- else if (selected.team == 14)
- m = strcat(m, "^4Blue Team");
- else if (selected.team == 10)
- m = strcat(m, "^6Pink Team");
- else if (selected.team == 13)
- m = strcat(m, "^3Yellow Team");
- centerprint(selected, m);
+ Damage(selected, selected, selected, 100000, DEATH_AUTOTEAMCHANGE, selected.origin, '0 0 0');
+ centerprint(selected, strcat("You have been moved into a different team to improve team balance\nYou are now on: ", ColoredTeamName(selected.team)));
}
float lastRebalanceInfo;
@@ -1242,8 +1252,8 @@
numteams = cvar("g_tdm_teams");
- tdm_spawnteam("Red", 4);
- tdm_spawnteam("Blue", 13);
+ tdm_spawnteam("Red", COLOR_TEAM1-1);
+ tdm_spawnteam("Blue", COLOR_TEAM2-1);
};
void() tdm_delayedinit =
Modified: branches/nexuiz-2.0/data/qcsrc/server/w_nex.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/w_nex.qc 2007-05-02 17:12:05 UTC (rev 2453)
+++ branches/nexuiz-2.0/data/qcsrc/server/w_nex.qc 2007-05-02 18:09:25 UTC (rev 2454)
@@ -69,67 +69,67 @@
{
centerprint(self, "you're dead now...\n");
Damage(self, self, self, 5, DEATH_NOAMMO, self.origin, '0 0 0');
- stuffcmd(self, "play2 announcer/robotic/terminated.ogg\n");
+ play2(self, "announcer/robotic/terminated.ogg");
}
if (self.health == 10)
{
centerprint(self, "^11^7 second left to find some ammo\n");
Damage(self, self, self, 5, DEATH_NOAMMO, self.origin, '0 0 0');
- stuffcmd(self, "play2 announcer/robotic/1.ogg\n");
+ play2(self, "announcer/robotic/1.ogg");
}
if (self.health == 20)
{
centerprint(self, "^12^7 seconds left to find some ammo\n");
Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
- stuffcmd(self, "play2 announcer/robotic/2.ogg\n");
+ play2(self, "announcer/robotic/2.ogg");
}
if (self.health == 30)
{
centerprint(self, "^13^7 seconds left to find some ammo\n");
Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
- stuffcmd(self, "play2 announcer/robotic/3.ogg\n");
+ play2(self, "announcer/robotic/3.ogg");
}
if (self.health == 40)
{
centerprint(self, "^14^7 seconds left to find some ammo\n");
Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
- stuffcmd(self, "play2 announcer/robotic/4.ogg\n");
+ play2(self, "announcer/robotic/4.ogg");
}
if (self.health == 50)
{
centerprint(self, "^15^7 seconds left to find some ammo\n");
Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
- stuffcmd(self, "play2 announcer/robotic/5.ogg\n");
+ play2(self, "announcer/robotic/5.ogg");
}
if (self.health == 60)
{
centerprint(self, "^36^7 seconds left to find some ammo\n");
Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
- stuffcmd(self, "play2 announcer/robotic/6.ogg\n");
+ play2(self, "announcer/robotic/6.ogg");
}
if (self.health == 70)
{
centerprint(self, "^37^7 seconds left to find some ammo\n");
Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
- stuffcmd(self, "play2 announcer/robotic/7.ogg\n");
+ play2(self, "announcer/robotic/7.ogg");
}
if (self.health == 80)
{
centerprint(self, "^38^7 seconds left to find some ammo\n");
Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
- stuffcmd(self, "play2 announcer/robotic/8.ogg\n");
+ play2(self, "announcer/robotic/8.ogg");
}
if (self.health == 90)
{
centerprint(self, "^39^7 seconds left to find some ammo\n");
Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
- stuffcmd(self, "play2 announcer/robotic/9.ogg\n");
+ play2(self, "announcer/robotic/9.ogg");
}
if (self.health == 100)
{
centerprint(self, "get some ammo or\nyou'll be dead in ^310^7 seconds...");
Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
- stuffcmd(self, "play2 announcer/robotic/10.ogg\n");
+ play2(self, "announcer/robotic/10.ogg");
}
}
self.minstagib_nextthink = time + 1;
Modified: branches/nexuiz-2.0/data/qcsrc/server/waypointsprites.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/waypointsprites.qc 2007-05-02 17:12:05 UTC (rev 2453)
+++ branches/nexuiz-2.0/data/qcsrc/server/waypointsprites.qc 2007-05-02 18:09:25 UTC (rev 2454)
@@ -9,7 +9,32 @@
float waypointsprite_limitedrange;
..entity owned_by_field;
+.float(entity) waypointsprite_for_player; // returns a model index or 0 for hide
+float waypointsprite_for_player_default(entity e)
+{
+ // personal waypoints
+ if(self.enemy)
+ if(self.enemy != other)
+ return FALSE;
+ // team waypoints
+ if(self.team)
+ {
+ if(self.team != other.team)
+ return FALSE;
+ if(other.classname != "player")
+ return FALSE;
+ }
+
+ // fixed waypoints
+ if(self.currentammo) // hidable?
+ if(other.cvar_cl_hidewaypoints) // wants to hide;
+ return FALSE;
+
+ // otherwise, accept the model
+ return self.modelindex;
+}
+
void WaypointSprite_Init()
{
waypointsprite_fadedistance = vlen(world.maxs - world.mins);
@@ -104,6 +129,7 @@
vector realorigin, porigin;
float distancealpha, timealpha;
float distance;
+ float newmodel;
if(self.health)
{
@@ -115,21 +141,12 @@
else
timealpha = 1;
- if(self.enemy)
- if(self.enemy != other)
- return FALSE;
- if(self.team)
- {
- if(self.team != other.team)
- return FALSE;
- if(other.classname != "player")
- return FALSE;
- }
+ // customize WP
+ newmodel = self.waypointsprite_for_player(other);
+ if(newmodel == 0)
+ return FALSE;
+ self.modelindex = newmodel;
- if(self.currentammo) // hidable?
- if(other.cvar_cl_hidewaypoints) // wants to hide;
- return FALSE;
-
porigin = other.origin + other.view_ofs_z * '0 0 1';
#ifdef ATTACHMENT_WORKS_WITH_EF_NODEPTHTEST
@@ -228,7 +245,12 @@
wp.think = WaypointSprite_Think;
wp.nextthink = time;
wp.effects = EF_NODEPTHTEST | EF_LOWPRECISION;
- setmodel(wp, strcat("models/sprites/", spr, ".sp2")); // precision set above
+ if(spr != "")
+ setmodel(wp, strcat("models/sprites/", spr, ".sp2")); // precision set above
+ else
+ wp.model = "waypoint";
+ setsize(wp, '0 0 0', '0 0 0');
+ wp.waypointsprite_for_player = waypointsprite_for_player_default;
return wp;
}
More information about the nexuiz-commits
mailing list