-// load engine's idea of vid_con*
-seta menu_vid_conwidth $vid_conwidth
-seta menu_vid_conheight $vid_conheight
+// updates for Nexuiz $OLD to 2.4 (also run on first startup, so be careful with what you put in here)
+alias _update_configversion_0 "_update_configversion_1"
-// fix cvar settings of the engine that Xonotic is not compatible with
-alias _update_generic_r_dynamic_0 "r_dynamic 1; r_shadow_realtime_dlight 1"
-alias _update_generic_r_dynamic_1 ""
-alias _update_generic "_update_generic_r_dynamic_$r_dynamic"
+// Updates for Nexuiz 2.4.1 to 2.4.2
+alias _update_configversion_1 "_update_configversion_2"
-// updates for ... to 2.4 (also run on first startup, so be careful with what you put in here)
-alias _update_configversion_0 ""
+// Updates for Nexuiz to Xonotic
+alias _update_configversion_2 "volume 1; cl_gunalign 1; _update_configversion_3"
-// Updates for 2.4.1 to 2.4.2
-alias _update_configversion_1 ""
+// Updates for gunalign fix
+alias _update_configversion_3 "cl_gunalign 3; menu_cl_gunalign 3; _update_configversion_4"
-// Updates for 2.5 to ...
-alias _update_configversion_2 ""
+// place to put further updates
+alias _update_configversion_4 ""
_update_configversion_$g_configversion
-_update_generic
-set g_configversion 2
-
-// we now use mastervolume
-volume 1
+set g_configversion 4
// other aliases
alias +hook +button6
alias -hook -button6
+alias use "impulse 21"
alias ready "cmd ready"
alias lockteams "sv_cmd lockteams"
alias unlockteams "sv_cmd unlockteams"
set g_trueaim_minrange 44 "TrueAim minimum range (TrueAim adjusts shots so they hit the crosshair point even though the gun is not at the screen center)"
set g_antilag_nudge 0 "don't touch"
set g_antilag_bullets 1 "Bullets AntiLag (0 = no AntiLag, 1 = server side hit scan in the past) - DO NOT TOUCH (severely changes weapon balance)"
-set g_shootfromclient 1 "let client decide if it has the gun left or right; if set to 2, center handedness is allowed, and defaulted to, too; see also cl_gunalign"
+set g_shootfromclient 2 "let client decide if it has the gun left or right; if set to 2, center handedness is allowed; see also cl_gunalign"
set g_shootfromeye 0 "shots are fired from your eye/crosshair; visual gun position can still be influenced by cl_gunalign 1 and 2"
set g_shootfromcenter 0 "weapon gets moved to the center, shots still come from the barrel of your weapon; visual gun position can still be influenced by cl_gunalign 1 and 2"
set g_shootfromfixedorigin "" "if set to a string like 0 y z, the gun is moved to the given y and z coordinates. If set to a string like x y z, the whole shot origin is used"
seta r_ambient 4
cl_decals_fadetime 5
cl_decals_time 2
-seta cl_gunalign 3 "Gun alignment; 1 = right, 2 = left, 3 = center or right, 4 = center or left"
+seta cl_gunalign 3 "Gun alignment; 1 = center (if allowed by g_shootfromclient) or right, 2 = center (if allowed by g_shootfromclient) or left, 3 = right only, 4 = left only"
seta cl_nogibs 0 "reduce number of violence effects, or remove them totally"
seta cl_particlegibs 0 "simpler gibs"
seta cl_gibs_damageforcescale 3.5 "force to push around gibs"
bind r reload
bind BACKSPACE dropweapon
bind g dropweapon
+// TODO change this to "use" once we can
bind f +use
// misc
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
seta "userbind12_press" "say_team killed flagcarrier (l:%y^7); g_waypointsprite_team_p"; seta "userbind12_release" ""; seta "userbind12_description" "team: killed flag, icon"
seta "userbind13_press" "say_team dropped flag (l:%d^7); g_waypointsprite_team_here_d"; seta "userbind13_release" ""; seta "userbind13_description" "team: dropped flag, icon"
seta "userbind14_press" "say_team dropped gun %w^7 (l:%l^7); g_waypointsprite_team_here; wait; dropweapon"; seta "userbind14_release" ""; seta "userbind14_description" "team: drop gun, icon"
+// TODO change this to "use" once we can
seta "userbind15_press" "say_team dropped flag/key %w^7 (l:%l^7); g_waypointsprite_team_here; wait; +use"; seta "userbind15_release" "-use"; seta "userbind15_description" "team: drop flag/key, icon"
seta "userbind16_press" "say :-) / nice one"; seta "userbind16_release" ""; seta "userbind16_description" "chat: nice one"
seta "userbind17_press" "say good game"; seta "userbind17_release" ""; seta "userbind17_description" "chat: good game"
seta cl_vehicle_spiderbot_cross_size 1
//cl_gunalign calculator
-seta menu_cl_gunalign 3 "Gun alignment; 1 = right, 2 = left, 3 = center or right, 4 = center or left"
+seta menu_cl_gunalign 3 "Gun alignment; 1 = center (if allowed by g_shootfromclient) or right, 2 = center (if allowed by g_shootfromclient) or left, 3 = right only, 4 = left only"
alias _gunalign_01 "cl_gunalign 1"
alias _gunalign_02 "cl_gunalign 2"
alias _gunalign_03 "cl_gunalign 3"
nags = ReadByte();
+ if(!(nags & 4))
+ {
+ if(vote_called_vote)
+ strunzone(vote_called_vote);
+ vote_called_vote = string_null;
+ }
+
if(nags & 128)
{
if(vote_called_vote)
return s;
return substring(s, p+1, -1);
}
+
+// x-encoding (encoding as zero length invisible string)
+const string XENCODE_2 = "xX";
+const string XENCODE_22 = "0123456789abcdefABCDEF";
+string xencode(float f)
+{
+ float a, b, c, d;
+ d = mod(f, 22); f = floor(f / 22);
+ c = mod(f, 22); f = floor(f / 22);
+ b = mod(f, 22); f = floor(f / 22);
+ a = mod(f, 2); // f = floor(f / 2);
+ return strcat(
+ "^",
+ substring(XENCODE_2, a, 1),
+ substring(XENCODE_22, b, 1),
+ substring(XENCODE_22, c, 1),
+ substring(XENCODE_22, d, 1)
+ );
+}
+float xdecode(string s)
+{
+ float a, b, c, d;
+ if(substring(s, 0, 1) != "^")
+ return -1;
+ if(strlen(s) < 5)
+ return -1;
+ a = strstrofs(XENCODE_2, substring(s, 1, 1), 0);
+ b = strstrofs(XENCODE_22, substring(s, 2, 1), 0);
+ c = strstrofs(XENCODE_22, substring(s, 3, 1), 0);
+ d = strstrofs(XENCODE_22, substring(s, 4, 1), 0);
+ if(a < 0 || b < 0 || c < 0 || d < 0)
+ return -1;
+ return ((a * 22 + b) * 22 + c) * 22 + d;
+}
string language_filename(string s);
string CTX(string s);
#define ZCTX(s) strzone(CTX(s))
+
+// x-encoding (encoding as zero length invisible string)
+// encodes approx. 14 bits into 5 bytes of color code string
+const float XENCODE_MAX = 21295; // 2*22*22*22-1
+const float XENCODE_LEN = 5;
+string xencode(float f);
+float xdecode(string s);
me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "r_drawviewmodel", _("Draw 1st person weapon model")));
me.TR(me);
me.TDempty(me, 0.2);
- me.TD(me, 1, 1.4, e = makeXonoticRadioButton(1, "cl_gunalign", "4", _("Left align")));
+ me.TD(me, 1, 0.9, e = makeXonoticRadioButton(1, "cl_gunalign", "4", _("Left align")));
setDependent(e, "r_drawviewmodel", 1, 1);
- me.TD(me, 1, 1.4, e = makeXonoticRadioButton(1, "cl_gunalign", "3", _("Right align")));
+ me.TD(me, 1, 0.9, e = makeXonoticRadioButton(1, "cl_gunalign", "1", _("Center")));
+ setDependent(e, "r_drawviewmodel", 1, 1);
+ me.TD(me, 1, 1.0, e = makeXonoticRadioButton(1, "cl_gunalign", "3", _("Right align")));
setDependent(e, "r_drawviewmodel", 1, 1);
me.TR(me);
me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "v_flipped", _("Flip view horizontally")));
me.TD(me, 1, 1.2, e = makeXonoticCheckBox(1, "mod_q3bsp_nolightmaps", _("Use lightmaps")));
me.TD(me, 1, 1.2, e = makeXonoticCheckBox(0, "r_glsl_deluxemapping", _("Deluxe mapping")));
setDependentAND(e, "vid_gl20", 1, 1, "mod_q3bsp_nolightmaps", 0, 0);
- me.TD(me, 1, 0.6, e = makeXonoticCheckBox(0, "r_shadow_gloss", _("Gloss")));
- setDependentAND3(e, "vid_gl20", 1, 1, "r_glsl_deluxemapping", 1, 2, "mod_q3bsp_nolightmaps", 0, 0);
+ me.TD(me, 1, 0.6, e = makeXonoticCheckBox(0, "r_shadow_gloss", _("Gloss"))); // FIXME move this box elsewhere, it has nothing to do with Q3BSP lightmaps
+ setDependent(e, "vid_gl20", 1, 1);
me.TR(me);
me.TD(me, 1, 1.2, e = makeXonoticCheckBox(0, "r_glsl_offsetmapping", _("Offset mapping")));
setDependent(e, "vid_gl20", 1, 1);
}
void assault_objective_use() {
- if(other.classname == "info_player_deathmatch") // a spawn, a spawn
- return;
-
// activate objective
self.health = 100;
//print("^2Activated objective ", self.targetname, "=", etos(self), "\n");
float autocvar_g_balance_hook_secondary_speed;
float autocvar_g_balance_keyhunt_damageforcescale;
float autocvar_g_balance_keyhunt_delay_collect;
-float autocvar_g_balance_keyhunt_delay_drop;
float autocvar_g_balance_keyhunt_delay_return;
float autocvar_g_balance_keyhunt_delay_round;
float autocvar_g_balance_keyhunt_delay_tracking;
{
if (e == self)
return FALSE;
- if (teams_matter)
+ if (teamplay)
if (e.team != 0)
return FALSE;
}
if(e.freezetag_frozen)
return FALSE;
- if(teams_matter)
+ if(teamplay)
{
if(e.team==0)
return FALSE;
local float besttime;
local entity best, head;
- if(teams_matter)
+ if(teamplay)
{
bot_removefromlargestteam();
return;
// But don't remove bots immediately on level change, as the real players
// usually haven't rejoined yet
bots_would_leave = FALSE;
- if (teams_matter && autocvar_bot_vs_human && (c3==-1 && c4==-1))
+ if (teamplay && autocvar_bot_vs_human && (c3==-1 && c4==-1))
bots = min(ceil(fabs(autocvar_bot_vs_human) * activerealplayers), maxclients - realplayers);
else if ((realplayers || autocvar_bot_join_empty || (currentbots > 0 && time < 5)))
{
float havocbot_ctf_teamcount(entity bot, vector org, float radius)
{
- if not(teams_matter)
+ if not(teamplay)
return 0;
float c;
}
}
- if(teams_matter)
+ if(teamplay)
{
discard = FALSE;
{
local entity head;
local float t, noteam, distance;
- noteam = ((self.team == 0) || !teams_matter); // fteqcc sucks
+ noteam = ((self.team == 0) || !teamplay); // fteqcc sucks
if (autocvar_bot_nofire)
return;
void spawnpoint_use()
{
- if(teams_matter)
+ if(teamplay)
if(have_team_spawns > 0)
{
self.team = activator.team;
if(autocvar_sv_defaultcharacter == 1) {
defaultskin = 0;
- if(teams_matter)
+ if(teamplay)
{
string s;
s = Team_ColorNameLowerCase(self.team);
if(chmdl || oldskin != self.skinindex)
self.species = player_getspecies(); // model or skin has changed
- if(!teams_matter)
+ if(!teamplay)
if(strlen(autocvar_sv_defaultplayercolors))
if(self.clientcolors != stof(autocvar_sv_defaultplayercolors))
setcolor(self, stof(autocvar_sv_defaultplayercolors));
oldself = self;
self = spot;
activator = oldself;
+ string s;
+ s = self.target;
+ self.target = string_null;
SUB_UseTargets();
+ self.target = s;
activator = world;
self = oldself;
void DoTeamChange(float destteam)
{
float t, c0;
- if(!teams_matter)
+ if(!teamplay)
{
if(destteam >= 0)
SetPlayerColors(self, destteam);
else
self.team_forced = 0;
- if(!teams_matter)
+ if(!teamplay)
if(self.team_forced > 0)
self.team_forced = 0;
if((autocvar_sv_spectate == 1 && !g_lms) || autocvar_g_campaign || self.team_forced < 0) {
self.classname = "observer";
} else {
- if(teams_matter)
+ if(teamplay)
{
if(autocvar_g_balance_teams || autocvar_g_balance_teams_force)
{
GetCvars(0);
// notify about available teams
- if(teams_matter)
+ if(teamplay)
{
CheckAllowedTeams(self);
t = 0; if(c1 >= 0) t |= 1; if(c2 >= 0) t |= 2; if(c3 >= 0) t |= 4; if(c4 >= 0) t |= 8;
local float c;
c = self.clientcolors & 15;
// LordHavoc: only bothering to support white, green, red, yellow, blue
- if (!teams_matter) self.colormod = '0 0 0';
+ if (!teamplay) self.colormod = '0 0 0';
else if (c == 0) self.colormod = '1.00 1.00 1.00';
else if (c == 3) self.colormod = '0.10 1.73 0.10';
else if (c == 4) self.colormod = '1.73 0.10 0.10';
void LeaveSpectatorMode()
{
if(nJoinAllowed(1)) {
- if(!teams_matter || autocvar_g_campaign || autocvar_g_balance_teams || (self.wasplayer && autocvar_g_changeteam_banned) || self.team_forced > 0) {
+ if(!teamplay || autocvar_g_campaign || autocvar_g_balance_teams || (self.wasplayer && autocvar_g_changeteam_banned) || self.team_forced > 0) {
self.classname = "player";
if(autocvar_g_campaign || autocvar_g_balance_teams || autocvar_g_balance_teams_force)
self.flags |= FL_CLIENT | FL_NOTARGET;
}
+float ctf_usekey();
+void PlayerUseKey()
+{
+ if(self.classname != "player")
+ return;
+
+ // a use key was pressed; call handlers
+ if(ctf_usekey())
+ return;
+
+ MUTATOR_CALLHOOK(PlayerUseKey);
+}
+
.float touchexplode_time;
/*
Called every frame for each client before the physics are run
=============
*/
+.float usekeypressed;
void() ctf_setstatus;
void() nexball_setstatus;
.float items_added;
MUTATOR_CALLHOOK(PlayerPreThink);
+ if(self.BUTTON_USE && !self.usekeypressed)
+ PlayerUseKey();
+ self.usekeypressed = self.BUTTON_USE;
+
if(self.classname == "player") {
// if(self.netname == "Wazat")
// bprint(self.classname, "\n");
else
self.impulse = imp; // retry in next frame
}
+ else if(imp == 21)
+ {
+ PlayerUseKey ();
+ }
else if(imp >= 200 && imp <= 229)
{
if(self.deadflag == DEAD_NO)
}
break;
case 33:
- if(self.deadflag == DEAD_NO && teams_matter)
+ if(self.deadflag == DEAD_NO && teamplay)
{
wp = WaypointSprite_Attach("helpme", TRUE);
if(wp)
if(source.classname != "player")
colorstr = "^0"; // black for spectators
- else if(teams_matter)
+ else if(teamplay)
colorstr = Team_ColorCode(source.team);
else
teamsay = FALSE;
break;
case VOICETYPE_TEAMRADIO:
FOR_EACH_REALCLIENT(msg_entity)
- if(!teams_matter || msg_entity.team == self.team)
+ if(!teamplay || msg_entity.team == self.team)
{
if(msg_entity.cvar_cl_voice_directional == 1)
soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTN_MIN);
if(sendflags & 128)
nags |= 128;
+ if(!(nags & 4)) // no vote called? send no string
+ nags &~= 128;
+
WriteByte(MSG_ENTITY, nags);
if(nags & 128)
ClientKill_TeamChange(-2); // observe
} else if(autocvar_g_campaign || autocvar_g_balance_teams || autocvar_g_balance_teams_force) {
//JoinBestTeam(self, FALSE, TRUE);
- } else if(teams_matter && !autocvar_sv_spectate && !(self.team_forced > 0)) {
+ } else if(teamplay && !autocvar_sv_spectate && !(self.team_forced > 0)) {
self.classname = "observer";
stuffcmd(self,"menu_showteamselect\n");
}
} else if( cmd == "selectteam" ) {
if not(self.flags & FL_CLIENT)
return;
- if( !teams_matter ) {
+ if( !teamplay ) {
sprint( self, "selectteam can only be used in teamgames\n");
} else if(autocvar_g_campaign) {
//JoinBestTeam(self, 0);
readycount = 0;
Nagger_ReadyCounted(); // NOTE: this causes a resend of that entity, and will also turn off warmup state on the client
- if(autocvar_teamplay_lockonrestart && teams_matter) {
+ if(autocvar_teamplay_lockonrestart && teamplay) {
lockteams = 1;
bprint("^1The teams are now locked.\n");
}
DropFlag(self, world, world);
return;
}
-
- if(autocvar_g_ctf_allow_drop)
- if(e.BUTTON_USE)
- DropFlag(self, e, world);
};
+float ctf_usekey()
+{
+ if(self.flagcarried)
+ {
+ DropFlag(self.flagcarried, self, world);
+ return TRUE;
+ }
+ return FALSE;
+}
+
void flag_cap_ring_spawn(vector org)
{
shockwave_spawn("models/ctf/shockwavetransring.md3", org - '0 0 15', -0.8, 0, 1);
.entity jumppadsused[NUM_JUMPPADSUSED];
string gamemode_name;
-float teams_matter;
float startitem_failed;
.string target2;
.string target3;
.string target4;
+.float target_random;
.float trigger_reverse;
// Nexball
.entity muzzle_flash;
.float misc_bulletcounter; // replaces uzi & hlac bullet counter.
+
+void PlayerUseKey();
if(other == o)
return FALSE;
if(other.classname == "player")
- if(!teams_matter || o.team != other.team)
+ if(!teamplay || o.team != other.team)
if not (radar_showennemies)
return FALSE;
return TRUE;
float IsDifferentTeam(entity a, entity b)
{
- if(teams_matter)
+ if(teamplay)
{
if(a.team == b.team)
return 0;
if (targ.killcount > 2)
msg = ftos(targ.killcount);
- if(teams_matter && deathtype == DEATH_MIRRORDAMAGE)
+ if(teamplay && deathtype == DEATH_MIRRORDAMAGE)
{
if(attacker.team == COLOR_TEAM1)
deathtype = KILL_TEAM_RED;
}
else if (attacker.classname == "player" || attacker.classname == "gib")
{
- if(teams_matter && attacker.team == targ.team)
+ if(teamplay && attacker.team == targ.team)
{
if(attacker.team == COLOR_TEAM1)
type = KILL_TEAM_RED;
damage = 0;
force = '0 0 0';
}
- else if(teams_matter && attacker.team == targ.team)
+ else if(teamplay && attacker.team == targ.team)
{
if(autocvar_teamplay_mode == 1)
damage = 0;
void g_model_setcolormaptoactivator (void)
{
- if(teams_matter)
+ if(teamplay)
{
if(activator.team)
self.colormap = (activator.team - 1) * 0x11;
stemp = self;
otemp = other;
+ if(stemp.target_random)
+ RandomSelection_Init();
+
for(i = 0; i < 4; ++i)
{
switch(i)
for(t = world; (t = find(t, targetname, s)); )
if(t.use)
{
- //print(stemp.classname, " ", stemp.targetname, " -> ", t.classname, " ", t.targetname, "\n");
- self = t;
- other = stemp;
- activator = act;
- self.use();
+ if(stemp.target_random)
+ {
+ RandomSelection_Add(t, 0, string_null, 1, 0);
+ }
+ else
+ {
+ self = t;
+ other = stemp;
+ activator = act;
+ self.use();
+ }
}
}
}
+ if(stemp.target_random && RandomSelection_chosen_ent)
+ {
+ self = RandomSelection_chosen_ent;
+ other = stemp;
+ activator = act;
+ self.use();
+ }
+
activator = act;
self = stemp;
other = otemp;
}
}
- if(teams_matter)
+ if(teamplay)
{
s = strcat(":labels:teamscores:", GetTeamScoreString(0, 0));
if(to_console)
// TODO make everything use THIS winning condition (except LMS)
WinningConditionHelper();
- if(teams_matter)
+ if(teamplay)
{
team1_score = TeamScore_GetCompareValue(COLOR_TEAM1);
team2_score = TeamScore_GetCompareValue(COLOR_TEAM2);
return;
}
- cvar_set("timelimit", ftos(new));
+ cvar_set("timelimit", ftos(new / 60));
}
void GameCommand(string command)
if (argv(0) == "lockteams")
{
- if(teams_matter)
+ if(teamplay)
{
lockteams = 1;
bprint("^1The teams are now locked.\n");
if (argv(0) == "unlockteams")
{
- if(teams_matter)
+ if(teamplay)
{
lockteams = 0;
bprint("^1The teams are now unlocked.\n");
// 2 (10) no centerprint, admin message
// 3 (11) no centerprint, no admin message
- if(!teams_matter) { // death match
+ if(!teamplay) { // death match
print("Currently not playing a team game\n");
return;
}
string playername(entity p)
{
string t;
- if (teams_matter && !intermission_running && p.classname == "player")
+ if (teamplay && !intermission_running && p.classname == "player")
{
t = Team_ColorCode(p.team);
return strcat(t, strdecolorize(p.netname));
{
switch(algn)
{
- case 1: // right
+ default:
+ case 3: // right
break;
- case 2: // left
+ case 4: // left
vecs_y = -vecs_y;
break;
- default:
- case 3:
+ case 1:
if(allowcenter) // 2: allow center handedness
{
// center
}
break;
- case 4:
+ case 2:
if(allowcenter) // 2: allow center handedness
{
// center
{
if (visual)
{
- vecs = shotorg_adjustfromclient(vecs, y_is_right, TRUE, algn);
+ vecs_y = 0;
+ vecs_z -= 2;
}
else
{
}
else if (autocvar_g_shootfromcenter)
{
- if (visual)
- {
- vecs = shotorg_adjustfromclient(vecs, y_is_right, TRUE, algn);
- }
- else
- {
- vecs_y = 0;
- vecs_z -= 2;
- }
+ vecs_y = 0;
+ vecs_z -= 2;
}
else if ((s = autocvar_g_shootfromfixedorigin) != "")
{
entity e;
r = 0;
for(e = cb; e.cbc_next; e = e.cbc_next)
+ {
+ CallbackChain_ReturnValue = r;
r |= e.cbc_next.cbc_func();
+ }
return r; // callbacks return an error status, so 0 is default return value
}
#define CBC_ORDER_LAST 2
#define CBC_ORDER_ANY 4
+float CallbackChain_ReturnValue; // read-only field of the current return value
+
entity CallbackChain_New(string name);
float CallbackChain_Add(entity cb, float() func, float order)
float CallbackChain_Remove(entity cb, float() func);
#define MUTATOR_HOOKABLE(cb) entity HOOK_##cb
#define MUTATOR_CALLHOOK(cb) CallbackChain_Call(HOOK_##cb)
+#define MUTATOR_RETURNVALUE CallbackChain_ReturnValue
// INPUT
entity self;
float olditems; // also technically output, but since it is at the end of the function it's useless for that :P
+
+MUTATOR_HOOKABLE(PlayerUseKey);
+ // called when the use key is pressed
+ // if MUTATOR_RETURNVALUE is 1, don't do anything
+ // return 1 if the use key actually did something
if(self.ballcarried)
self.items |= IT_KEY1;
- // drop the ball if the player presses the use button
- if(self.BUTTON_USE)
- if(self.ballcarried) { ka_DropEvent(self); }
+ return 0;
+}
+MUTATOR_HOOKFUNCTION(ka_PlayerUseKey)
+{
+ if(MUTATOR_RETURNVALUE == 0)
+ if(self.ballcarried)
+ {
+ ka_DropEvent(self);
+ return 1;
+ }
return 0;
}
MUTATOR_HOOK(PlayerPreThink, ka_PlayerPreThink, CBC_ORDER_ANY);
MUTATOR_HOOK(PlayerDamage_Calculate, ka_PlayerDamage, CBC_ORDER_ANY);
MUTATOR_HOOK(PlayerPowerups, ka_PlayerPowerups, CBC_ORDER_ANY);
+ MUTATOR_HOOK(PlayerUseKey, ka_PlayerUseKey, CBC_ORDER_ANY);
MUTATOR_ONADD
{
makevectors('0 1 0' * (self.cnt + mod(time, 360) * KH_KEY_XYSPEED));
setorigin(self, v_forward * KH_KEY_XYDIST + '0 0 1' * self.origin_z);
#endif
-
- if(self.owner.BUTTON_USE)
- if(time >= self.owner.kh_droptime + autocvar_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, VOL_BASE, ATTN_NORM);
- makevectors(self.owner.v_angle);
- self.velocity = W_CalculateProjectileVelocity(self.owner.velocity, autocvar_g_balance_keyhunt_throwvelocity * v_forward, FALSE);
- kh_Key_AssignTo(self, world);
- self.pushltime = time + autocvar_g_balance_keyhunt_protecttime;
- self.kh_dropperteam = self.team;
- }
}
// if in nodrop or time over, end the round
return teem;
}
+void kh_Key_DropOne(entity key)
+{
+ // prevent collecting this one for some time
+ entity player;
+ player = key.owner;
+
+ key.kh_droptime = time;
+ key.enemy = player;
+
+ kh_Scores_Event(player, key, "dropkey", 0, 0);
+ PlayerScore_Add(player, SP_KH_LOSSES, 1);
+ bprint(player.netname, "^7 dropped the ", key.netname, "\n");
+ kh_Key_AssignTo(key, world);
+ makevectors(player.v_angle);
+ key.velocity = W_CalculateProjectileVelocity(player.velocity, autocvar_g_balance_keyhunt_throwvelocity * v_forward, FALSE);
+ key.pusher = world;
+ key.pushltime = time + autocvar_g_balance_keyhunt_protecttime;
+ key.kh_dropperteam = key.team;
+
+ sound(player, CHAN_AUTO, kh_sound_drop, VOL_BASE, ATTN_NORM);
+}
+
void kh_Key_DropAll(entity player, float suicide) // runs whenever a player dies
{
entity key;
return 0;
}
+MUTATOR_HOOKFUNCTION(kh_PlayerUseKey)
+{
+ if(MUTATOR_RETURNVALUE == 0)
+ {
+ entity k;
+ k = self.kh_next;
+ if(k)
+ {
+ kh_Key_DropOne(k);
+ return 1;
+ }
+ }
+ return 0;
+}
+
MUTATOR_DEFINITION(gamemode_keyhunt)
{
MUTATOR_HOOK(MakePlayerObserver, kh_Key_DropAll, CBC_ORDER_ANY);
MUTATOR_HOOK(MatchEnd, kh_finalize, CBC_ORDER_ANY);
MUTATOR_HOOK(GetTeamCount, kh_GetTeamCount, CBC_ORDER_EXCLUSIVE);
MUTATOR_HOOK(SpectateCopy, kh_SpectateCopy, CBC_ORDER_ANY);
+ MUTATOR_HOOK(PlayerUseKey, kh_PlayerUseKey, CBC_ORDER_ANY);
MUTATOR_ONADD
{
nn = db_get(playerstats_db, sprintf("%s:_netname", p));
if(nn != "")
bufstr_set(b, i++, sprintf("n %s", nn));
- if(teams_matter)
+ if(teamplay)
{
tt = db_get(playerstats_db, sprintf("%s:_team", p));
bufstr_set(b, i++, sprintf("t %s", tt));
if(p.cvar_cl_allow_uid2name == 1 || clienttype(p) == CLIENTTYPE_BOT)
db_put(playerstats_db, sprintf("%s:_netname", p.playerstats_id), p.netname);
- if(teams_matter)
+ if(teamplay)
db_put(playerstats_db, sprintf("%s:_team", p.playerstats_id), ftos(p.team));
if(p.alivetime > 0)
}
void ScoreRules_generic()
{
- if(teams_matter)
+ if(teamplay)
{
CheckAllowedTeams(world);
ScoreRules_basics(((c4>=0) ? 4 : (c3>=0) ? 3 : 2), SFL_SORT_PRIO_PRIMARY, SFL_SORT_PRIO_PRIMARY, TRUE);
void SV_OnEntityPreSpawnFunction()
{
if(self.gametypefilter != "")
- if not(isGametypeInFilter(game, teams_matter, have_team_spawns, self.gametypefilter))
+ if not(isGametypeInFilter(game, teamplay, have_team_spawns, self.gametypefilter))
{
remove(self);
return;
void trigger_push_use()
{
- if(teams_matter)
+ if(teamplay)
self.team = activator.team;
}
// Q3 style filters (DO NOT USE, THIS IS COMPAT ONLY)
if(self.notq3a)
- if(!teams_matter || g_tdm || g_ctf)
+ if(!teamplay || g_tdm || g_ctf)
return 1;
if(self.notta)
- if not(!teams_matter || g_tdm || g_ctf)
+ if not(!teamplay || g_tdm || g_ctf)
return 1;
if(self.notsingle)
return 1;
if(self.notteam)
- if(teams_matter)
+ if(teamplay)
return 1;
if(self.notfree)
- if(!teams_matter)
+ if(!teamplay)
return 1;
if(self.gametype)
string gametypename;
// static char *gametypeNames[] = {"ffa", "tournament", "single", "team", "ctf", "oneflag", "obelisk", "harvester", "teamtournament"};
gametypename = "ffa";
- if(teams_matter)
+ if(teamplay)
gametypename = "team";
if(g_arena)
gametypename = "tournament";
void trigger_teleport_use()
{
- if(teams_matter)
+ if(teamplay)
self.team = activator.team;
}
{
TDEATHLOOP(org)
{
- if not(teams_matter && autocvar_g_telefrags_teamplay && head.team == player.team)
+ if not(teamplay && autocvar_g_telefrags_teamplay && head.team == player.team)
if(head.classname == "player")
if(head.health >= 1)
return 1;
{
if (player.classname == "player" && player.health >= 1)
{
- if not(teams_matter && autocvar_g_telefrags_teamplay && head.team == player.team)
+ if not(teamplay && autocvar_g_telefrags_teamplay && head.team == player.team)
{
if(head.classname == "player")
if(head.health >= 1)
{
if(intermission_running)
return 0; // no rebalancing whatsoever please
- if(!teams_matter)
+ if(!teamplay)
return 0;
if(autocvar_g_campaign)
return 0;
g_tdm = 1;
}
- teams_matter = 0;
+ teamplay = 0;
serverflags &~= SERVERFLAG_TEAMPLAY;
}
void ActivateTeamplay()
{
serverflags |= SERVERFLAG_TEAMPLAY;
- teams_matter = 1;
+ teamplay = 1;
}
void InitGameplayMode()
MUTATOR_ADD(gamemode_keepaway);
}
- if(teams_matter)
+ if(teamplay)
entcs_init();
// save it (for the next startup)
shirt = _color & 0xF0;
- if(teams_matter) {
+ if(teamplay) {
setcolor(pl, 16*pants + pants);
} else {
setcolor(pl, shirt + pants);
float smallest, selectedteam;
// don't join a team if we're not playing a team game
- if(!teams_matter)
+ if(!teamplay)
return 0;
// find out what teams are available
float scolor, dcolor, steam, dteam, dbotcount, scount, dcount;
// in normal deathmatch we can just apply the color and we're done
- if(!teams_matter) {
+ if(!teamplay) {
SetPlayerColors(self, _color);
return;
}
if not (self.tur_active)
return;
- if (teams_matter)
+ if (teamplay)
if (self.team == attacker.team)
{
// This does not happen anymore. Re-enable if you fix that.
self.nextthink = time + self.ticrate;
// ONS uses somewhat backwards linking.
- if (teams_matter)
+ if (teamplay)
{
if not (g_onslaught)
if (self.target)
if not (self.team)
self.team = 14; // Assume turrets are on the defending side if not explicitly set otehrwize
}
- else if not (teams_matter)
+ else if not (teamplay)
self.team = MAX_SHOT_DISTANCE; // Group all turrets into the same team, so they dont kill eachother.
else if(g_onslaught && self.targetname)
{
if (clienttype(other) != CLIENTTYPE_REAL)
return;
- if(teams_matter)
+ if(teamplay)
if(self.team)
if(self.team != other.team)
return;
self.colormod = self.tur_head.colormod = '0 0 0';
- if(teams_matter)
+ if(teamplay)
if(self.team)
if(self.team != other.team)
return;
self.colormap = 1024;
self.tur_head.colormap = 1024;
- if not (teams_matter)
+ if not (teamplay)
self.team = 0;
else
{
tracebox(self.origin + '0 0 100', spiderbot_MIN, spiderbot_MAX, self.origin - '0 0 10000', MOVE_WORLDONLY, self);
setorigin(self.spiderbot_spawnpnt,trace_endpos);
- if(self.team && !teams_matter)
+ if(self.team && !teamplay)
self.team = 0;
else
self.spiderbot_spawnpnt.team = self.team;
votecalled = FALSE;
votecalledmaster = FALSE;
votefinished = 0;
+ votecalledvote = string_null;
+ votecalledvote_display = string_null;
}
void VoteAccept() {
// count potential damage according to type of target
if (targ == self)
selfdamage = selfdamage + d;
- else if (targ.team == self.team && teams_matter)
+ else if (targ.team == self.team && teamplay)
teamdamage = teamdamage + d;
else if (bot_shouldattack(targ))
enemydamage = enemydamage + d;
desirabledamage = enemydamage;
if (time > self.invincible_finished && time > self.spawnshieldtime)
desirabledamage = desirabledamage - selfdamage * autocvar_g_balance_selfdamagepercent;
- if (teams_matter && self.team)
+ if (teamplay && self.team)
desirabledamage = desirabledamage - teamdamage;
mine = find(world, classname, "mine");
// teamcolor / hit beam effect
vector v;
v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
- if(teams_matter)
+ if(teamplay)
{
switch(self.team)
{
// count potential damage according to type of target
if (targ == self)
selfdamage = selfdamage + d;
- else if (targ.team == self.team && teams_matter)
+ else if (targ.team == self.team && teamplay)
teamdamage = teamdamage + d;
else if (bot_shouldattack(targ))
enemydamage = enemydamage + d;
desirabledamage = enemydamage;
if (time > self.invincible_finished && time > self.spawnshieldtime)
desirabledamage = desirabledamage - selfdamage * autocvar_g_balance_selfdamagepercent;
- if (teams_matter && self.team)
+ if (teamplay && self.team)
desirabledamage = desirabledamage - teamdamage;
missile = find(world, classname, "rocket");
// kind of tuba currently is player slot number, or team number if in
// teamplay
// that way, holes in the range of notes are "plugged"
- if(teams_matter)
+ if(teamplay)
{
if(pl.team == COLOR_TEAM2 || pl.team == COLOR_TEAM4)
note += 3;
)
{
float t, maxdistance;
- if(teams_matter)
+ if(teamplay)
t = self.team;
else
t = 0;
float t, maxdistance;
if(self.waypointsprite_attachedforcarrier)
return world; // can't attach to FC
- if(teams_matter)
+ if(teamplay)
t = self.team;
else
t = 0;
exec data/campaign.cfg
exec config_update.cfg
exec font-xolonium.cfg
+exec autoexec/*.cfg
exec autoexec.cfg
stuffcmds
//startdemos demos/demo1 demos/demo2 demos/demo3