ImpulseCommands();
if (intermission_running)
return; // intermission or finale
-
GetPressedKeys();
} else if (self.classname == "observer") {
//do nothing
float not_allowed_to_move;
string c;
- MUTATOR_CALLHOOK(PlayerPhysics);
-
if(self.PlayerPhysplug)
if(self.PlayerPhysplug())
return;
bot_think();
}
+ MUTATOR_CALLHOOK(PlayerPhysics);
+
self.items &~= IT_USING_JETPACK;
if(self.classname == "player")
Obituary (attacker, inflictor, self, deathtype);
race_PreDie();
DropAllRunes(self);
- frag_attacker = attacker; MUTATOR_CALLHOOK(PlayerDies);
+
+ frag_attacker = attacker;
+ frag_inflictor = inflictor;
+ MUTATOR_CALLHOOK(PlayerDies);
+
if(self.flagcarried)
{
if(attacker.classname != "player" && attacker.classname != "gib")
DropFlag(self.flagcarried, world, world);
if(self.ballcarried)
DropBall(self.ballcarried, self.origin, self.velocity);
- MUTATOR_CALLHOOK(MakePlayerSpectator);
WaypointSprite_PlayerDead();
self.classname = "observer";
if(g_ca)
}
// FIXME fix the mess this is (we have REAL points now!)
- frag_attacker = attacker;
+ entity oldself;
+ oldself = self;
+ self = attacker;
frag_target = targ;
frag_score = f;
if(MUTATOR_CALLHOOK(GiveFragsForKill))
{
f = frag_score;
+ self = oldself;
}
- else if(g_runematch)
- {
- f = RunematchHandleFrags(attacker, targ, f);
- }
- else if(g_lms)
+ else
{
- // remove a life
- float tl;
- tl = PlayerScore_Add(targ, SP_LMS_LIVES, -1);
- if(tl < lms_lowest_lives)
- lms_lowest_lives = tl;
- if(tl <= 0)
+ self = oldself;
+ if(g_runematch)
{
- if(!lms_next_place)
- lms_next_place = player_count;
- PlayerScore_Add(targ, SP_LMS_RANK, lms_next_place); // won't ever spawn again
- --lms_next_place;
+ f = RunematchHandleFrags(attacker, targ, f);
}
- f = 0;
- }
- else if(g_ctf)
- {
- if(g_ctf_ignore_frags)
+ else if(g_lms)
+ {
+ // remove a life
+ float tl;
+ tl = PlayerScore_Add(targ, SP_LMS_LIVES, -1);
+ if(tl < lms_lowest_lives)
+ lms_lowest_lives = tl;
+ if(tl <= 0)
+ {
+ if(!lms_next_place)
+ lms_next_place = player_count;
+ PlayerScore_Add(targ, SP_LMS_RANK, lms_next_place); // won't ever spawn again
+ --lms_next_place;
+ }
f = 0;
+ }
+ else if(g_ctf)
+ {
+ if(g_ctf_ignore_frags)
+ f = 0;
+ }
}
attacker.totalfrags += f;
{
string s;
- get_cvars_f = f;
- MUTATOR_CALLHOOK(GetCvars);
-
if (f > 0)
s = strcat1(argv(f));
+
+ get_cvars_f = f;
+ MUTATOR_CALLHOOK(GetCvars);
GetCvars_handleFloat(s, f, autoswitch, "cl_autoswitch");
GetCvars_handleFloat(s, f, cvar_cl_playerdetailreduction, "cl_playerdetailreduction");
GetCvars_handleFloat(s, f, cvar_scr_centertime, "scr_centertime");
// register all possible hooks here
+
MUTATOR_HOOKABLE(MakePlayerObserver);
-MUTATOR_HOOKABLE(MakePlayerSpectator);
+ // called when a player becomes observer, after shared setup
+
MUTATOR_HOOKABLE(PlayerSpawn);
+ // called when a player spawns as player, after shared setup, before his weapon is chosen (so items may be changed in here)
+
MUTATOR_HOOKABLE(ClientDisconnect);
-MUTATOR_HOOKABLE(PlayerDies); entity other; entity frag_attacker;
-MUTATOR_HOOKABLE(GiveFragsForKill); entity frag_attacker, frag_target; float frag_score;
+ // called when a player disconnects
+
+MUTATOR_HOOKABLE(PlayerDies);
+ // called when a player dies to e.g. remove stuff he was carrying.
+ // INPUT:
+ entity frag_inflictor;
+ entity frag_attacker;
+
+MUTATOR_HOOKABLE(GiveFragsForKill);
+ // called when someone was fragged by "self", and is expected to change frag_score to adjust scoring for the kill
+ // INPUT:
+ entity frag_target;
+ // INPUT, OUTPUT:
+ float frag_score;
+
MUTATOR_HOOKABLE(MatchEnd);
-MUTATOR_HOOKABLE(GetTeamCount); float ret_float;
-MUTATOR_HOOKABLE(SpectateCopy); entity other;
+ // called when the match ends
+
+MUTATOR_HOOKABLE(GetTeamCount);
+ // should adjust ret_float to contain the team count
+ // INPUT, OUTPUT:
+ float ret_float;
+
+MUTATOR_HOOKABLE(SpectateCopy);
+ // copies variables for spectating "other" to "self"
+ // INPUT:
+ entity other;
+
MUTATOR_HOOKABLE(ForbidThrowCurrentWeapon);
+ // returns 1 if throwing the current weapon shall not be allowed
+
MUTATOR_HOOKABLE(SetStartItems);
-MUTATOR_HOOKABLE(BuildMutatorsString); string ret_string;
-MUTATOR_HOOKABLE(BuildMutatorsPrettyString); string ret_string;
-MUTATOR_HOOKABLE(FilterItem); // return error to request removal, or change self.items or self.weapons
-MUTATOR_HOOKABLE(OnEntityPreSpawn); // return error to prevent entity spawn, or modify the entity
+ // adjusts {warmup_}start_{items,weapons,ammo_{cells,rockets,nails,shells,fuel}}
+
+MUTATOR_HOOKABLE(BuildMutatorsString);
+ // appends ":mutatorname" to ret_string for logging
+ // INPUT, OUTPUT:
+ string ret_string;
+
+MUTATOR_HOOKABLE(BuildMutatorsPrettyString);
+ // appends ", Mutator name" to ret_string for display
+ // INPUT, OUTPUT:
+ string ret_string;
+
+MUTATOR_HOOKABLE(FilterItem);
+ // checks if the current item may be spawned (self.items and self.weapons may be read and written to, as well as the ammo_ fields)
+ // return error to request removal
+
+MUTATOR_HOOKABLE(OnEntityPreSpawn);
+ // return error to prevent entity spawn, or modify the entity
+
MUTATOR_HOOKABLE(PlayerPreThink);
+ // runs in the event loop for players; is called for ALL player entities, also bots, also the dead, or spectators
+
MUTATOR_HOOKABLE(GetPressedKeys);
+ // TODO change this into a general PlayerPostThink hook?
+
MUTATOR_HOOKABLE(PlayerPhysics);
-MUTATOR_HOOKABLE(GetCvars); float get_cvars_f;
+ // called before any player physics, may adjust variables for movement,
+ // is run AFTER bot code and idle checking
+
+MUTATOR_HOOKABLE(GetCvars);
+ // is meant to call GetCvars_handle*(get_cvars_s, get_cvars_f, cvarfield, "cvarname") for cvars this mutator needs from the client
+ // INPUT:
+ float get_cvars_f;
+ string get_cvars_s;
MUTATOR_DEFINITION(gamemode_keyhunt)
{
MUTATOR_HOOK(MakePlayerObserver, kh_Key_DropAll, CBC_ORDER_ANY);
- MUTATOR_HOOK(MakePlayerSpectator, kh_Key_DropAll, CBC_ORDER_ANY);
MUTATOR_HOOK(ClientDisconnect, kh_Key_DropAll, CBC_ORDER_ANY);
MUTATOR_HOOK(PlayerDies, kh_PlayerDies, CBC_ORDER_ANY);
- MUTATOR_HOOK(GiveFragsForKill, kh_GiveFragsForKill, CBC_ORDER_EXCLUSIVE);
+ MUTATOR_HOOK(GiveFragsForKill, kh_GiveFragsForKill, CBC_ORDER_FIRST);
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_HOOKFUNCTION(dodging_GetCvars) {
- // print("dodging_GetCvars\n");
-
- string s;
- s = strcat1(argv(get_cvars_f));
-
- GetCvars_handleFloat(s, get_cvars_f, cvar_cl_dodging_timeout, "cl_dodging_timeout");
-
+ GetCvars_handleFloat(get_cvars_s, get_cvars_f, cvar_cl_dodging_timeout, "cl_dodging_timeout");
return 0;
}
-float g_nix, g_nix_with_laser;
+float g_nix_with_laser;
float nix_weapon;
float nix_weapon_ammo;
.float nix_lastinfotime;
.float nix_nextincr;
+.float nix_save_cells;
+.float nix_save_shells;
+.float nix_save_nails;
+.float nix_save_rockets;
+.float nix_save_fuel;
+.float nix_save_weapons;
+
float NIX_CanChooseWeapon(float wpn)
{
entity e;
MUTATOR_DEFINITION(mutator_nix)
{
+ entity e;
+
MUTATOR_HOOK(ForbidThrowCurrentWeapon, nix_ForbidThrowCurrentWeapon, CBC_ORDER_ANY);
MUTATOR_HOOK(SetStartItems, nix_SetStartItems, CBC_ORDER_EXCLUSIVE);
MUTATOR_HOOK(BuildMutatorsString, nix_BuildMutatorsString, CBC_ORDER_ANY);
MUTATOR_ONADD
{
- g_nix = 1;
g_nix_with_laser = cvar("g_nix_with_laser");
nix_nextchange = time;
nix_nextweapon = 0;
NIX_precache();
+
+ FOR_EACH_PLAYER(e)
+ {
+ if(e.deadflag == DEAD_NO)
+ {
+ e.nix_save_cells = e.ammo_cells;
+ e.nix_save_shells = e.ammo_shells;
+ e.nix_save_nails = e.ammo_nails;
+ e.nix_save_rockets = e.ammo_rockets;
+ e.nix_save_fuel = e.ammo_fuel;
+ e.nix_save_weapons = e.weapons;
+ }
+ else
+ {
+ e.nix_save_cells = 0;
+ e.nix_save_shells = 0;
+ e.nix_save_nails = 0;
+ e.nix_save_rockets = 0;
+ e.nix_save_fuel = 0;
+ e.nix_save_weapons = 0;
+ }
+ }
}
MUTATOR_ONREMOVE
{
- g_nix = 0;
// as the PlayerSpawn hook will no longer run, NIX is turned off by this!
+
+ FOR_EACH_PLAYER(e) if(e.deadflag == DEAD_NO)
+ {
+ e.ammo_cells = max(start_ammo_cells, e.nix_save_cells);
+ e.ammo_shells = max(start_ammo_shells, e.nix_save_shells);
+ e.ammo_nails = max(start_ammo_nails, e.nix_save_nails);
+ e.ammo_rockets = max(start_ammo_rockets, e.nix_save_rockets);
+ e.ammo_fuel = max(start_ammo_fuel, e.nix_save_fuel);
+ e.weapons = (start_weapons | e.nix_save_weapons);
+ if(!client_hasweapon(e, e.weapon, TRUE, FALSE))
+ e.switchweapon = w_getbestweapon(self);
+ }
}
return 0;