MUTATOR_HOOKFUNCTION(nb, PlayerDies)
{
+ entity frag_target = M_ARGV(2, entity);
+
nb_DropBall(frag_target);
- return false;
}
MUTATOR_HOOKFUNCTION(nb, MakePlayerObserver)
MUTATOR_HOOKFUNCTION(nb, DropSpecialItems)
{
+ entity frag_target = M_ARGV(0, entity);
+
if(frag_target.ballcarried)
DropBall(frag_target.ballcarried, frag_target.origin, frag_target.velocity);
* Find control point or generator owned by the same team self which is nearest to pos
* if max_dist is positive, only control points within this range will be considered
*/
-entity ons_Nearest_ControlPoint(vector pos, float max_dist)
-{SELFPARAM();
+entity ons_Nearest_ControlPoint(entity this, vector pos, float max_dist)
+{
entity tmp_entity, closest_target = world;
tmp_entity = findchain(classname, "onslaught_controlpoint");
while(tmp_entity)
{
- if(SAME_TEAM(tmp_entity, self))
+ if(SAME_TEAM(tmp_entity, this))
if(tmp_entity.iscaptured)
if(max_dist <= 0 || vdist(tmp_entity.origin - pos, <=, max_dist))
if(vlen2(tmp_entity.origin - pos) <= vlen2(closest_target.origin - pos) || closest_target == world)
tmp_entity = findchain(classname, "onslaught_generator");
while(tmp_entity)
{
- if(SAME_TEAM(tmp_entity, self))
+ if(SAME_TEAM(tmp_entity, this))
if(max_dist <= 0 || vdist(tmp_entity.origin - pos, <, max_dist))
if(vlen2(tmp_entity.origin - pos) <= vlen2(closest_target.origin - pos) || closest_target == world)
closest_target = tmp_entity;
* if max_dist is positive, only control points within this range will be considered
* This function only check distances on the XY plane, disregarding Z
*/
-entity ons_Nearest_ControlPoint_2D(vector pos, float max_dist)
-{SELFPARAM();
+entity ons_Nearest_ControlPoint_2D(entity this, vector pos, float max_dist)
+{
entity tmp_entity, closest_target = world;
vector delta;
float smallest_distance = 0, distance;
delta_z = 0;
distance = vlen(delta);
- if(SAME_TEAM(tmp_entity, self))
+ if(SAME_TEAM(tmp_entity, this))
if(tmp_entity.iscaptured)
if(max_dist <= 0 || distance <= max_dist)
if(closest_target == world || distance <= smallest_distance )
delta_z = 0;
distance = vlen(delta);
- if(SAME_TEAM(tmp_entity, self))
+ if(SAME_TEAM(tmp_entity, this))
if(max_dist <= 0 || distance <= max_dist)
if(closest_target == world || distance <= smallest_distance )
{
MUTATOR_HOOKFUNCTION(ons, PlayerDies)
{
+ entity frag_target = M_ARGV(2, entity);
+
frag_target.ons_deathloc = frag_target.origin;
entity l;
for(l = ons_worldgeneratorlist; l; l = l.ons_worldgeneratornext)
}
MUTATOR_HOOKFUNCTION(ons, SV_ParseClientCommand)
-{SELFPARAM();
+{
if(MUTATOR_RETURNVALUE) // command was already handled?
return false;
+ entity player = M_ARGV(0, entity);
+ string cmd_name = M_ARGV(1, string);
+ int cmd_argc = M_ARGV(2, int);
+
if ( cmd_name == "ons_spawn" )
{
- vector pos = self.origin;
+ vector pos = player.origin;
if(cmd_argc > 1)
pos_x = stof(argv(1));
if(cmd_argc > 2)
if(cmd_argc > 3)
pos_z = stof(argv(3));
- if ( IS_PLAYER(self) )
+ if ( IS_PLAYER(player) )
{
- if ( !STAT(FROZEN, self) )
+ if ( !STAT(FROZEN, player) )
{
- entity source_point = ons_Nearest_ControlPoint(self.origin, autocvar_g_onslaught_teleport_radius);
+ entity source_point = ons_Nearest_ControlPoint(player, player.origin, autocvar_g_onslaught_teleport_radius);
- if ( !source_point && self.health > 0 )
+ if ( !source_point && player.health > 0 )
{
- sprint(self, "\nYou need to be next to a control point\n");
- return 1;
+ sprint(player, "\nYou need to be next to a control point\n");
+ return true;
}
- entity closest_target = ons_Nearest_ControlPoint_2D(pos, autocvar_g_onslaught_click_radius);
+ entity closest_target = ons_Nearest_ControlPoint_2D(player, pos, autocvar_g_onslaught_click_radius);
if ( closest_target == world )
{
- sprint(self, "\nNo control point found\n");
- return 1;
+ sprint(player, "\nNo control point found\n");
+ return true;
}
- if ( self.health <= 0 )
+ if ( player.health <= 0 )
{
- self.ons_spawn_by = closest_target;
- self.respawn_flags = self.respawn_flags | RESPAWN_FORCE;
+ player.ons_spawn_by = closest_target;
+ player.respawn_flags = player.respawn_flags | RESPAWN_FORCE;
}
else
{
if ( source_point == closest_target )
{
- sprint(self, "\nTeleporting to the same point\n");
- return 1;
+ sprint(player, "\nTeleporting to the same point\n");
+ return true;
}
- if ( !ons_Teleport(self,closest_target,autocvar_g_onslaught_teleport_radius,true) )
- sprint(self, "\nUnable to teleport there\n");
+ if ( !ons_Teleport(player,closest_target,autocvar_g_onslaught_teleport_radius,true) )
+ sprint(player, "\nUnable to teleport there\n");
}
- return 1;
+ return true;
}
- sprint(self, "\nNo teleportation for you\n");
+ sprint(player, "\nNo teleportation for you\n");
}
- return 1;
+ return true;
}
- return 0;
+ return false;
}
MUTATOR_HOOKFUNCTION(ons, PlayerUseKey)
if((time > self.teleport_antispam) && (!IS_DEAD(self)) && !self.vehicle)
{
- entity source_point = ons_Nearest_ControlPoint(self.origin, autocvar_g_onslaught_teleport_radius);
+ entity source_point = ons_Nearest_ControlPoint(self, self.origin, autocvar_g_onslaught_teleport_radius);
if ( source_point )
{
stuffcmd(self, "qc_cmd_cl hud clickradar\n");
/** (BOTH) precaches models/sounds used by this monster */
METHOD(Monster, mr_precache, bool(Monster this)) { TC(Monster, this); return false; }
/** (SERVER) called when monster is damaged */
- METHOD(Monster, mr_pain, bool(Monster this, entity actor)) { TC(Monster, this); return false; }
+ METHOD(Monster, mr_pain, float(Monster this, entity actor, float damage_take, entity attacker, float deathtype)) { TC(Monster, this); return damage_take; }
/** (BOTH?) sets animations for monster */
METHOD(Monster, mr_anim, bool(Monster this, entity actor)) { TC(Monster, this); return false; }
return true;
}
-METHOD(Mage, mr_pain, bool(Mage this, entity actor))
+METHOD(Mage, mr_pain, float(Mage this, entity actor, float damage_take, entity attacker, float deathtype))
{
TC(Mage, this);
- return true;
+ return damage_take;
}
METHOD(Mage, mr_death, bool(Mage this, entity actor))
return true;
}
-METHOD(Shambler, mr_pain, bool(Shambler this, entity actor))
+METHOD(Shambler, mr_pain, float(Shambler this, entity actor, float damage_take, entity attacker, float deathtype))
{
TC(Shambler, this);
actor.pain_finished = time + 0.5;
setanim(actor, actor.anim_pain1, true, true, false);
- return true;
+ return damage_take;
}
METHOD(Shambler, mr_death, bool(Shambler this, entity actor))
return true;
}
-METHOD(Spider, mr_pain, bool(Spider this, entity actor))
+METHOD(Spider, mr_pain, float(Spider this, entity actor, float damage_take, entity attacker, float deathtype))
{
TC(Spider, this);
- return true;
+ return damage_take;
}
METHOD(Spider, mr_death, bool(Spider this, entity actor))
return true;
}
-METHOD(Wyvern, mr_pain, bool(Wyvern this, entity actor))
+METHOD(Wyvern, mr_pain, float(Wyvern this, entity actor, float damage_take, entity attacker, float deathtype))
{
TC(Wyvern, this);
actor.pain_finished = time + 0.5;
setanim(actor, actor.anim_pain1, true, true, false);
- return true;
+ return damage_take;
}
METHOD(Wyvern, mr_death, bool(Wyvern this, entity actor))
return true;
}
-METHOD(Zombie, mr_pain, bool(Zombie this, entity actor))
+METHOD(Zombie, mr_pain, float(Zombie this, entity actor, float damage_take, entity attacker, float deathtype))
{
TC(Zombie, this);
actor.pain_finished = time + 0.34;
setanim(actor, ((random() > 0.5) ? actor.anim_pain1 : actor.anim_pain2), true, true, false);
- return true;
+ return damage_take;
}
METHOD(Zombie, mr_death, bool(Zombie this, entity actor))
this.stat_monsters_killed = monsters_killed;
}
-void monster_dropitem(entity this)
+void monster_dropitem(entity this, entity attacker)
{
if(!this.candrop || !this.monster_loot)
return;
e.monster_loot = this.monster_loot;
- MUTATOR_CALLHOOK(MonsterDropItem, e);
- e = other;
+ MUTATOR_CALLHOOK(MonsterDropItem, this, e, attacker);
+ e = M_ARGV(1, entity);
if(e && e.monster_loot)
{
this.health = 0; // reset by Unfreeze
}
- monster_dropitem(this);
+ monster_dropitem(this, attacker);
Monster_Sound(this, monstersound_death, 0, false, CH_VOICE);
take = v_x;
save = v_y;
- damage_take = take;
- frag_attacker = attacker;
- frag_deathtype = deathtype;
Monster mon = get_monsterinfo(this.monsterid);
- mon.mr_pain(mon, this);
- take = damage_take;
+ take = mon.mr_pain(mon, this, take, attacker, deathtype);
if(take)
{
WaypointSprite_Kill(this.sprite);
- MUTATOR_CALLHOOK(MonsterDies, this, attacker);
+ MUTATOR_CALLHOOK(MonsterDies, this, attacker, deathtype);
if(this.health <= -100 || deathtype == DEATH_KILL.m_id) // check if we're already gibbed
{
// mutator hooks
MUTATOR_HOOKFUNCTION(buffs, PlayerDamage_SplitHealthArmor)
{
+ entity frag_target = M_ARGV(2, entity);
+ float frag_deathtype = M_ARGV(6, float);
+ float frag_damage = M_ARGV(7, float);
+
if(frag_deathtype == DEATH_BUFF.m_id) { return false; }
if(frag_target.buffs & BUFF_RESISTANCE.m_itemid)
{
vector v = healtharmor_applydamage(50, autocvar_g_buffs_resistance_blockpercent, frag_deathtype, frag_damage);
- damage_take = v.x;
- damage_save = v.y;
+ M_ARGV(4, float) = v.x; // take
+ M_ARGV(5, float) = v.y; // save
}
return false;
MUTATOR_HOOKFUNCTION(buffs, PlayerDies)
{
+ entity frag_target = M_ARGV(2, entity);
+
if(frag_target.buffs)
{
int buffid = buff_FirstFromFlags(frag_target.buffs).m_id;
MUTATOR_HOOKFUNCTION(campcheck, PlayerDies)
{
+ entity frag_target = M_ARGV(2, entity);
+
Kill_Notification(NOTIF_ONE, frag_target, MSG_CENTER, CPID_CAMPCHECK);
return false;
}
MUTATOR_HOOKFUNCTION(mutator_instagib, MonsterDropItem)
{
- other.monster_loot = spawnfunc_item_minst_cells;
+ entity item = M_ARGV(1, entity);
+
+ item.monster_loot = spawnfunc_item_minst_cells;
return false;
}
MUTATOR_HOOKFUNCTION(mutator_instagib, PlayerDamage_SplitHealthArmor)
{
- damage_save = 0;
- damage_take = frag_damage;
-
- return false;
+ M_ARGV(4, float) = M_ARGV(7, float); // take = damage
+ M_ARGV(5, float) = 0; // save
}
MUTATOR_HOOKFUNCTION(mutator_instagib, ForbidThrowCurrentWeapon)
MUTATOR_HOOKFUNCTION(mutator_instagib, PlayerDies)
{
+ float frag_deathtype = M_ARGV(3, float);
+ float frag_damage = M_ARGV(4, float);
+
if(DEATH_ISWEAPON(frag_deathtype, WEP_VAPORIZER))
frag_damage = 1000; // always gib if it was a vaporizer death
MUTATOR_HOOKFUNCTION(nades, PlayerDies, CBC_ORDER_LAST)
{
+ entity frag_attacker = M_ARGV(1, entity);
+ entity frag_target = M_ARGV(2, entity);
+
if(frag_target.nade)
if(!STAT(FROZEN, frag_target) || !autocvar_g_freezetag_revive_nade)
toss_nade(frag_target, true, '0 0 100', max(frag_target.nade.wait, time + 0.05));
}
nades_RemoveBonus(frag_target);
-
- return false;
}
MUTATOR_HOOKFUNCTION(nades, PlayerDamage_Calculate)
{
+ entity frag_inflictor = M_ARGV(0, entity);
entity frag_attacker = M_ARGV(1, entity);
entity frag_target = M_ARGV(2, entity);
float frag_deathtype = M_ARGV(3, float);
- float frag_damage = M_ARGV(4, float);
- vector frag_force = M_ARGV(6, vector);
if(STAT(FROZEN, frag_target))
if(autocvar_g_freezetag_revive_nade)
Unfreeze(frag_target);
frag_target.health = autocvar_g_freezetag_revive_nade_health;
Send_Effect(EFFECT_ICEORGLASS, frag_target.origin, '0 0 0', 3);
- frag_damage = 0;
- frag_force = '0 0 0';
+ M_ARGV(4, float) = 0;
+ M_ARGV(6, vector) = '0 0 0';
Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_FREEZETAG_REVIVED_NADE, frag_target.netname);
Send_Notification(NOTIF_ONE, frag_target, MSG_CENTER, CENTER_FREEZETAG_REVIVE_SELF);
-
- M_ARGV(4, float) = frag_damage;
- M_ARGV(6, vector) = frag_force;
}
return false;
MUTATOR_HOOKFUNCTION(nades, MonsterDies)
{
+ entity frag_target = M_ARGV(0, entity);
+ entity frag_attacker = M_ARGV(1, entity);
+
if(IS_PLAYER(frag_attacker))
if(DIFF_TEAM(frag_attacker, frag_target))
if(!(frag_target.spawnflags & MONSTERFLAG_SPAWNED))
MUTATOR_HOOKFUNCTION(nades, DropSpecialItems)
{
+ entity frag_target = M_ARGV(0, entity);
+
if(frag_target.nade)
toss_nade(frag_target, true, '0 0 0', time + 0.05);
MUTATOR_HOOKFUNCTION(ok, PlayerDamage_SplitHealthArmor)
{
+ entity frag_target = M_ARGV(2, entity);
+ float damage_take = M_ARGV(4, float);
+
if(damage_take)
frag_target.ok_pauseregen_finished = max(frag_target.ok_pauseregen_finished, time + 2);
- return false;
}
-MUTATOR_HOOKFUNCTION(ok, PlayerDies)
+void ok_DropItem(entity this, entity targ)
{
- entity targ = ((frag_attacker) ? frag_attacker : frag_target);
-
- if(IS_MONSTER(frag_target))
- {
- remove(other); // remove default item
- other = NULL;
- }
-
entity e = new(droppedweapon); // hax
e.ok_item = true;
e.noalign = true;
e.pickup_anyway = true;
e.spawnfunc_checked = true;
- spawnfunc_item_armor_small(e);
+ WITHSELF(e, spawnfunc_item_armor_small(e));
if (!wasfreed(e)) { // might have been blocked by a mutator
e.movetype = MOVETYPE_TOSS;
e.gravity = 1;
e.reset = SUB_Remove;
- setorigin(e, frag_target.origin + '0 0 32');
- e.velocity = '0 0 200' + normalize(targ.origin - frag_target.origin) * 500;
+ setorigin(e, this.origin + '0 0 32');
+ e.velocity = '0 0 200' + normalize(targ.origin - this.origin) * 500;
SUB_SetFade(e, time + 5, 1);
}
+}
+
+MUTATOR_HOOKFUNCTION(ok, PlayerDies)
+{
+ entity frag_attacker = M_ARGV(1, entity);
+ entity frag_target = M_ARGV(2, entity);
+
+ entity targ = ((frag_attacker) ? frag_attacker : frag_target);
+
+ ok_DropItem(frag_target, targ);
frag_target.ok_lastwep = PS(frag_target).m_switchweapon.m_id;
+}
- return false;
+MUTATOR_HOOKFUNCTION(ok, MonsterDropItem)
+{
+ entity mon = M_ARGV(0, entity);
+ entity olditem = M_ARGV(1, entity);
+ entity frag_attacker = M_ARGV(2, entity);
+
+ remove(olditem);
+
+ M_ARGV(1, entity) = NULL;
+
+ ok_DropItem(mon, frag_attacker);
}
-MUTATOR_HOOKFUNCTION(ok, MonsterDropItem) { ok_PlayerDies(); }
MUTATOR_HOOKFUNCTION(ok, PlayerRegen)
{SELFPARAM();
MUTATOR_HOOKFUNCTION(pinata, PlayerDies)
{
+ entity frag_target = M_ARGV(2, entity);
+
FOREACH(Weapons, it != WEP_Null, LAMBDA(
if(frag_target.weapons & WepSet_FromWeapon(it))
if(PS(frag_target).m_switchweapon != it)
// we do it this way, so rm can be toggled during the match
if(!autocvar_g_rm) { return false; }
+ float frag_deathtype = M_ARGV(3, float);
+ float frag_damage = M_ARGV(4, float);
+
if(DEATH_ISWEAPON(frag_deathtype, WEP_DEVASTATOR) || DEATH_ISWEAPON(frag_deathtype, WEP_ELECTRO))
frag_damage = 1000; // always gib if it was a vaporizer death
}
MUTATOR_HOOKFUNCTION(sandbox, SV_ParseClientCommand)
-{SELFPARAM();
+{
if(MUTATOR_RETURNVALUE) // command was already handled?
return false;
+
+ entity player = M_ARGV(0, entity);
+ string cmd_name = M_ARGV(1, string);
+ int cmd_argc = M_ARGV(2, int);
+
if(cmd_name == "g_sandbox")
{
if(autocvar_g_sandbox_readonly)
{
- print_to(self, "^2SANDBOX - INFO: ^7Sandbox mode is active, but in read-only mode. Sandbox commands cannot be used");
+ print_to(player, "^2SANDBOX - INFO: ^7Sandbox mode is active, but in read-only mode. Sandbox commands cannot be used");
return true;
}
if(cmd_argc < 2)
{
- print_to(self, "^2SANDBOX - INFO: ^7Sandbox mode is active. For usage information, type 'sandbox help'");
+ print_to(player, "^2SANDBOX - INFO: ^7Sandbox mode is active. For usage information, type 'sandbox help'");
return true;
}
// ---------------- COMMAND: HELP ----------------
case "help":
- print_to(self, "You can use the following sandbox commands:");
- print_to(self, "^7\"^2object_spawn ^3models/foo/bar.md3^7\" spawns a new object in front of the player, and gives it the specified model");
- print_to(self, "^7\"^2object_remove^7\" removes the object the player is looking at. Players can only remove their own objects");
- print_to(self, "^7\"^2object_duplicate ^3value^7\" duplicates the object, if the player has copying rights over the original");
- print_to(self, "^3copy value ^7- copies the properties of the object to the specified client cvar");
- print_to(self, "^3paste value ^7- spawns an object with the given properties. Properties or cvars must be specified as follows; eg1: \"0 1 2 ...\", eg2: \"$cl_cvar\"");
- print_to(self, "^7\"^2object_attach ^3property value^7\" attaches one object to another. Players can only attach their own objects");
- print_to(self, "^3get ^7- selects the object you are facing as the object to be attached");
- print_to(self, "^3set value ^7- attaches the previously selected object to the object you are facing, on the specified bone");
- print_to(self, "^3remove ^7- detaches all objects from the object you are facing");
- print_to(self, "^7\"^2object_edit ^3property value^7\" edits the given property of the object. Players can only edit their own objects");
- print_to(self, "^3skin value ^7- changes the skin of the object");
- print_to(self, "^3alpha value ^7- sets object transparency");
- print_to(self, "^3colormod \"value_x value_y value_z\" ^7- main object color");
- print_to(self, "^3glowmod \"value_x value_y value_z\" ^7- glow object color");
- print_to(self, "^3frame value ^7- object animation frame, for self-animated models");
- print_to(self, "^3scale value ^7- changes object scale. 0.5 is half size and 2 is double size");
- print_to(self, "^3solidity value ^7- object collisions, 0 = non-solid, 1 = solid");
- print_to(self, "^3physics value ^7- object physics, 0 = static, 1 = movable, 2 = physical");
- print_to(self, "^3force value ^7- amount of force applied to objects that are shot");
- print_to(self, "^3material value ^7- sets the material of the object. Default materials are: metal, stone, wood, flesh");
- print_to(self, "^7\"^2object_claim^7\" sets the player as the owner of the object, if he has the right to edit it");
- print_to(self, "^7\"^2object_info ^3value^7\" shows public information about the object");
- print_to(self, "^3object ^7- prints general information about the object, such as owner and creation / editing date");
- print_to(self, "^3mesh ^7- prints information about the object's mesh, including skeletal bones");
- print_to(self, "^3attachments ^7- prints information about the object's attachments");
- print_to(self, "^7The ^1drag object ^7key can be used to grab and carry objects. Players can only grab their own objects");
+ print_to(player, "You can use the following sandbox commands:");
+ print_to(player, "^7\"^2object_spawn ^3models/foo/bar.md3^7\" spawns a new object in front of the player, and gives it the specified model");
+ print_to(player, "^7\"^2object_remove^7\" removes the object the player is looking at. Players can only remove their own objects");
+ print_to(player, "^7\"^2object_duplicate ^3value^7\" duplicates the object, if the player has copying rights over the original");
+ print_to(player, "^3copy value ^7- copies the properties of the object to the specified client cvar");
+ print_to(player, "^3paste value ^7- spawns an object with the given properties. Properties or cvars must be specified as follows; eg1: \"0 1 2 ...\", eg2: \"$cl_cvar\"");
+ print_to(player, "^7\"^2object_attach ^3property value^7\" attaches one object to another. Players can only attach their own objects");
+ print_to(player, "^3get ^7- selects the object you are facing as the object to be attached");
+ print_to(player, "^3set value ^7- attaches the previously selected object to the object you are facing, on the specified bone");
+ print_to(player, "^3remove ^7- detaches all objects from the object you are facing");
+ print_to(player, "^7\"^2object_edit ^3property value^7\" edits the given property of the object. Players can only edit their own objects");
+ print_to(player, "^3skin value ^7- changes the skin of the object");
+ print_to(player, "^3alpha value ^7- sets object transparency");
+ print_to(player, "^3colormod \"value_x value_y value_z\" ^7- main object color");
+ print_to(player, "^3glowmod \"value_x value_y value_z\" ^7- glow object color");
+ print_to(player, "^3frame value ^7- object animation frame, for self-animated models");
+ print_to(player, "^3scale value ^7- changes object scale. 0.5 is half size and 2 is double size");
+ print_to(player, "^3solidity value ^7- object collisions, 0 = non-solid, 1 = solid");
+ print_to(player, "^3physics value ^7- object physics, 0 = static, 1 = movable, 2 = physical");
+ print_to(player, "^3force value ^7- amount of force applied to objects that are shot");
+ print_to(player, "^3material value ^7- sets the material of the object. Default materials are: metal, stone, wood, flesh");
+ print_to(player, "^7\"^2object_claim^7\" sets the player as the owner of the object, if he has the right to edit it");
+ print_to(player, "^7\"^2object_info ^3value^7\" shows public information about the object");
+ print_to(player, "^3object ^7- prints general information about the object, such as owner and creation / editing date");
+ print_to(player, "^3mesh ^7- prints information about the object's mesh, including skeletal bones");
+ print_to(player, "^3attachments ^7- prints information about the object's attachments");
+ print_to(player, "^7The ^1drag object ^7key can be used to grab and carry objects. Players can only grab their own objects");
return true;
// ---------------- COMMAND: OBJECT, SPAWN ----------------
case "object_spawn":
- if(time < self.object_flood)
+ if(time < player.object_flood)
{
- print_to(self, strcat("^1SANDBOX - WARNING: ^7Flood protection active. Please wait ^3", ftos(self.object_flood - time), " ^7seconds beofore spawning another object"));
+ print_to(player, strcat("^1SANDBOX - WARNING: ^7Flood protection active. Please wait ^3", ftos(player.object_flood - time), " ^7seconds beofore spawning another object"));
return true;
}
- self.object_flood = time + autocvar_g_sandbox_editor_flood;
+ player.object_flood = time + autocvar_g_sandbox_editor_flood;
if(object_count >= autocvar_g_sandbox_editor_maxobjects)
{
- print_to(self, strcat("^1SANDBOX - WARNING: ^7Cannot spawn any more objects. Up to ^3", ftos(autocvar_g_sandbox_editor_maxobjects), " ^7objects may exist at a time"));
+ print_to(player, strcat("^1SANDBOX - WARNING: ^7Cannot spawn any more objects. Up to ^3", ftos(autocvar_g_sandbox_editor_maxobjects), " ^7objects may exist at a time"));
return true;
}
if(cmd_argc < 3)
{
- print_to(self, "^1SANDBOX - WARNING: ^7Attempted to spawn an object without specifying a model. Please specify the path to your model file after the 'object_spawn' command");
+ print_to(player, "^1SANDBOX - WARNING: ^7Attempted to spawn an object without specifying a model. Please specify the path to your model file after the 'object_spawn' command");
return true;
}
if (!(fexists(argv(2))))
{
- print_to(self, "^1SANDBOX - WARNING: ^7Attempted to spawn an object with a non-existent model. Make sure the path to your model file is correct");
+ print_to(player, "^1SANDBOX - WARNING: ^7Attempted to spawn an object with a non-existent model. Make sure the path to your model file is correct");
return true;
}
_setmodel(e, argv(2));
if(autocvar_g_sandbox_info > 0)
- LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", self.netname, " spawned an object at origin ^3", vtos(e.origin), "\n"));
+ LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", player.netname, " spawned an object at origin ^3", vtos(e.origin), "\n"));
return true;
// ---------------- COMMAND: OBJECT, REMOVE ----------------
if(e != world)
{
if(autocvar_g_sandbox_info > 0)
- LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", self.netname, " removed an object at origin ^3", vtos(e.origin), "\n"));
+ LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", player.netname, " removed an object at origin ^3", vtos(e.origin), "\n"));
sandbox_ObjectRemove(e);
return true;
}
- print_to(self, "^1SANDBOX - WARNING: ^7Object could not be removed. Make sure you are facing an object that you have edit rights over");
+ print_to(player, "^1SANDBOX - WARNING: ^7Object could not be removed. Make sure you are facing an object that you have edit rights over");
return true;
// ---------------- COMMAND: OBJECT, DUPLICATE ----------------
{
s = sandbox_ObjectPort_Save(e, false);
s = strreplace("\"", "\\\"", s);
- stuffcmd(self, strcat("set ", argv(3), " \"", s, "\""));
+ stuffcmd(player, strcat("set ", argv(3), " \"", s, "\""));
- print_to(self, "^2SANDBOX - INFO: ^7Object copied to clipboard");
+ print_to(player, "^2SANDBOX - INFO: ^7Object copied to clipboard");
return true;
}
- print_to(self, "^1SANDBOX - WARNING: ^7Object could not be copied. Make sure you are facing an object that you have copy rights over");
+ print_to(player, "^1SANDBOX - WARNING: ^7Object could not be copied. Make sure you are facing an object that you have copy rights over");
return true;
case "paste":
// spawns a new object using the properties in the player's clipboard cvar
- if(time < self.object_flood)
+ if(time < player.object_flood)
{
- print_to(self, strcat("^1SANDBOX - WARNING: ^7Flood protection active. Please wait ^3", ftos(self.object_flood - time), " ^7seconds beofore spawning another object"));
+ print_to(player, strcat("^1SANDBOX - WARNING: ^7Flood protection active. Please wait ^3", ftos(player.object_flood - time), " ^7seconds beofore spawning another object"));
return true;
}
- self.object_flood = time + autocvar_g_sandbox_editor_flood;
+ player.object_flood = time + autocvar_g_sandbox_editor_flood;
if(argv(3) == "") // no object in clipboard
{
- print_to(self, "^1SANDBOX - WARNING: ^7No object in clipboard. You must copy an object before you can paste it");
+ print_to(player, "^1SANDBOX - WARNING: ^7No object in clipboard. You must copy an object before you can paste it");
return true;
}
if(object_count >= autocvar_g_sandbox_editor_maxobjects)
{
- print_to(self, strcat("^1SANDBOX - WARNING: ^7Cannot spawn any more objects. Up to ^3", ftos(autocvar_g_sandbox_editor_maxobjects), " ^7objects may exist at a time"));
+ print_to(player, strcat("^1SANDBOX - WARNING: ^7Cannot spawn any more objects. Up to ^3", ftos(autocvar_g_sandbox_editor_maxobjects), " ^7objects may exist at a time"));
return true;
}
e = sandbox_ObjectPort_Load(argv(3), false);
- print_to(self, "^2SANDBOX - INFO: ^7Object pasted successfully");
+ print_to(player, "^2SANDBOX - INFO: ^7Object pasted successfully");
if(autocvar_g_sandbox_info > 0)
- LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", self.netname, " pasted an object at origin ^3", vtos(e.origin), "\n"));
+ LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", player.netname, " pasted an object at origin ^3", vtos(e.origin), "\n"));
return true;
}
return true;
e = sandbox_ObjectEdit_Get(true);
if(e != world)
{
- self.object_attach = e;
- print_to(self, "^2SANDBOX - INFO: ^7Object selected for attachment");
+ player.object_attach = e;
+ print_to(player, "^2SANDBOX - INFO: ^7Object selected for attachment");
return true;
}
- print_to(self, "^1SANDBOX - WARNING: ^7Object could not be selected for attachment. Make sure you are facing an object that you have edit rights over");
+ print_to(player, "^1SANDBOX - WARNING: ^7Object could not be selected for attachment. Make sure you are facing an object that you have edit rights over");
return true;
case "set":
- if(self.object_attach == world)
+ if(player.object_attach == world)
{
- print_to(self, "^1SANDBOX - WARNING: ^7No object selected for attachment. Please select an object to be attached first.");
+ print_to(player, "^1SANDBOX - WARNING: ^7No object selected for attachment. Please select an object to be attached first.");
return true;
}
e = sandbox_ObjectEdit_Get(true);
if(e != world)
{
- sandbox_ObjectAttach_Set(self.object_attach, e, argv(3));
- self.object_attach = world; // object was attached, no longer keep it scheduled for attachment
- print_to(self, "^2SANDBOX - INFO: ^7Object attached successfully");
+ sandbox_ObjectAttach_Set(player.object_attach, e, argv(3));
+ player.object_attach = world; // object was attached, no longer keep it scheduled for attachment
+ print_to(player, "^2SANDBOX - INFO: ^7Object attached successfully");
if(autocvar_g_sandbox_info > 1)
- LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", self.netname, " attached objects at origin ^3", vtos(e.origin), "\n"));
+ LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", player.netname, " attached objects at origin ^3", vtos(e.origin), "\n"));
return true;
}
- print_to(self, "^1SANDBOX - WARNING: ^7Object could not be attached to the parent. Make sure you are facing an object that you have edit rights over");
+ print_to(player, "^1SANDBOX - WARNING: ^7Object could not be attached to the parent. Make sure you are facing an object that you have edit rights over");
return true;
case "remove":
// removes e if it was attached
if(e != world)
{
sandbox_ObjectAttach_Remove(e);
- print_to(self, "^2SANDBOX - INFO: ^7Child objects detached successfully");
+ print_to(player, "^2SANDBOX - INFO: ^7Child objects detached successfully");
if(autocvar_g_sandbox_info > 1)
- LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", self.netname, " detached objects at origin ^3", vtos(e.origin), "\n"));
+ LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", player.netname, " detached objects at origin ^3", vtos(e.origin), "\n"));
return true;
}
- print_to(self, "^1SANDBOX - WARNING: ^7Child objects could not be detached. Make sure you are facing an object that you have edit rights over");
+ print_to(player, "^1SANDBOX - WARNING: ^7Child objects could not be detached. Make sure you are facing an object that you have edit rights over");
return true;
}
return true;
case "object_edit":
if(argv(2) == "")
{
- print_to(self, "^1SANDBOX - WARNING: ^7Too few parameters. You must specify a property to edit");
+ print_to(player, "^1SANDBOX - WARNING: ^7Too few parameters. You must specify a property to edit");
return true;
}
e.material = string_null; // no material
break;
default:
- print_to(self, "^1SANDBOX - WARNING: ^7Invalid object property. For usage information, type 'sandbox help'");
+ print_to(player, "^1SANDBOX - WARNING: ^7Invalid object property. For usage information, type 'sandbox help'");
return true;
}
e.message2 = strzone(strftime(true, "%d-%m-%Y %H:%M:%S"));
if(autocvar_g_sandbox_info > 1)
- LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", self.netname, " edited property ^3", argv(2), " ^7of an object at origin ^3", vtos(e.origin), "\n"));
+ LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", player.netname, " edited property ^3", argv(2), " ^7of an object at origin ^3", vtos(e.origin), "\n"));
return true;
}
- print_to(self, "^1SANDBOX - WARNING: ^7Object could not be edited. Make sure you are facing an object that you have edit rights over");
+ print_to(player, "^1SANDBOX - WARNING: ^7Object could not be edited. Make sure you are facing an object that you have edit rights over");
return true;
// ---------------- COMMAND: OBJECT, CLAIM ----------------
case "object_claim":
// if the player can edit an object but is not its owner, this can be used to claim that object
- if(self.crypto_idfp == "")
+ if(player.crypto_idfp == "")
{
- print_to(self, "^1SANDBOX - WARNING: ^7You do not have a player UID, and cannot claim objects");
+ print_to(player, "^1SANDBOX - WARNING: ^7You do not have a player UID, and cannot claim objects");
return true;
}
e = sandbox_ObjectEdit_Get(true);
// update the owner's name
// Do this before checking if you're already the owner and skipping if such, so we
// also update the player's nickname if he changed it (but has the same player UID)
- if(e.netname != self.netname)
+ if(e.netname != player.netname)
{
if(e.netname) strunzone(e.netname);
- e.netname = strzone(self.netname);
- print_to(self, "^2SANDBOX - INFO: ^7Object owner name updated");
+ e.netname = strzone(player.netname);
+ print_to(player, "^2SANDBOX - INFO: ^7Object owner name updated");
}
- if(e.crypto_idfp == self.crypto_idfp)
+ if(e.crypto_idfp == player.crypto_idfp)
{
- print_to(self, "^2SANDBOX - INFO: ^7Object is already yours, nothing to claim");
+ print_to(player, "^2SANDBOX - INFO: ^7Object is already yours, nothing to claim");
return true;
}
if(e.crypto_idfp) strunzone(e.crypto_idfp);
- e.crypto_idfp = strzone(self.crypto_idfp);
+ e.crypto_idfp = strzone(player.crypto_idfp);
- print_to(self, "^2SANDBOX - INFO: ^7Object claimed successfully");
+ print_to(player, "^2SANDBOX - INFO: ^7Object claimed successfully");
}
- print_to(self, "^1SANDBOX - WARNING: ^7Object could not be claimed. Make sure you are facing an object that you have edit rights over");
+ print_to(player, "^1SANDBOX - WARNING: ^7Object could not be claimed. Make sure you are facing an object that you have edit rights over");
return true;
// ---------------- COMMAND: OBJECT, INFO ----------------
switch(argv(2))
{
case "object":
- print_to(self, strcat("^2SANDBOX - INFO: ^7Object is owned by \"^7", e.netname, "^7\", created \"^3", e.message, "^7\", last edited \"^3", e.message2, "^7\""));
+ print_to(player, strcat("^2SANDBOX - INFO: ^7Object is owned by \"^7", e.netname, "^7\", created \"^3", e.message, "^7\", last edited \"^3", e.message2, "^7\""));
return true;
case "mesh":
s = "";
FOR_EACH_TAG(e)
s = strcat(s, "^7\"^5", gettaginfo_name, "^7\", ");
- print_to(self, strcat("^2SANDBOX - INFO: ^7Object mesh is \"^3", e.model, "^7\" at animation frame ^3", ftos(e.frame), " ^7containing the following tags: ", s));
+ print_to(player, strcat("^2SANDBOX - INFO: ^7Object mesh is \"^3", e.model, "^7\" at animation frame ^3", ftos(e.frame), " ^7containing the following tags: ", s));
return true;
case "attachments":
// this should show the same info as 'mesh' but for attachments
}
}
if(i) // object contains attachments
- print_to(self, strcat("^2SANDBOX - INFO: ^7Object contains the following ^1", ftos(i), "^7 attachment(s): ", s));
+ print_to(player, strcat("^2SANDBOX - INFO: ^7Object contains the following ^1", ftos(i), "^7 attachment(s): ", s));
else
- print_to(self, "^2SANDBOX - INFO: ^7Object contains no attachments");
+ print_to(player, "^2SANDBOX - INFO: ^7Object contains no attachments");
return true;
}
}
- print_to(self, "^1SANDBOX - WARNING: ^7No information could be found. Make sure you are facing an object");
+ print_to(player, "^1SANDBOX - WARNING: ^7No information could be found. Make sure you are facing an object");
return true;
// ---------------- COMMAND: DEFAULT ----------------
default:
- print_to(self, "Invalid command. For usage information, type 'sandbox help'");
+ print_to(player, "Invalid command. For usage information, type 'sandbox help'");
return true;
}
}
.float cvar_cl_spawn_near_teammate;
MUTATOR_HOOKFUNCTION(spawn_near_teammate, Spawn_Score)
-{SELFPARAM();
- if(autocvar_g_spawn_near_teammate_ignore_spawnpoint == 1 || (autocvar_g_spawn_near_teammate_ignore_spawnpoint == 2 && self.cvar_cl_spawn_near_teammate))
+{
+ entity player = M_ARGV(0, entity);
+ entity spawn_spot = M_ARGV(1, entity);
+ vector spawn_score = M_ARGV(2, vector);
+
+ if(autocvar_g_spawn_near_teammate_ignore_spawnpoint == 1 || (autocvar_g_spawn_near_teammate_ignore_spawnpoint == 2 && player.cvar_cl_spawn_near_teammate))
return false;
spawn_spot.msnt_lookat = world;
return false;
RandomSelection_Init();
- FOREACH_CLIENT(IS_PLAYER(it) && it != self && SAME_TEAM(it, self) && !IS_DEAD(it), LAMBDA(
+ FOREACH_CLIENT(IS_PLAYER(it) && it != player && SAME_TEAM(it, player) && !IS_DEAD(it), LAMBDA(
if(vdist(spawn_spot.origin - it.origin, >, autocvar_g_spawn_near_teammate_distance))
continue;
if(vdist(spawn_spot.origin - it.origin, <, 48))
spawn_spot.msnt_lookat = RandomSelection_chosen_ent;
spawn_score.x += SPAWN_PRIO_NEAR_TEAMMATE_FOUND;
}
- else if(self.team == spawn_spot.team)
+ else if(player.team == spawn_spot.team)
spawn_score.x += SPAWN_PRIO_NEAR_TEAMMATE_SAMETEAM; // prefer same team, if we can't find a spawn near teammate
+ M_ARGV(2, vector) = spawn_score;
+
return false;
}
{
if(!teamplay) { return false; }
entity player = M_ARGV(0, entity);
+ entity spawn_spot = M_ARGV(1, entity);
int num_red = 0, num_blue = 0, num_yellow = 0, num_pink = 0;
FOREACH_CLIENT(IS_PLAYER(it),
MUTATOR_HOOKFUNCTION(spawn_near_teammate, PlayerDies)
{
+ entity frag_target = M_ARGV(0, entity);
+
frag_target.msnt_deathloc = frag_target.origin;
return false;
}
}
MUTATOR_HOOKFUNCTION(superspec, SV_ParseClientCommand)
-{SELFPARAM();
+{
#define OPTIONINFO(flag,var,test,text,long,short) \
var = strcat(var, ((flag & test) ? "^2[ON] ^7" : "^1[OFF] ^7")); \
var = strcat(var, text," ^7(^3 ", long, "^7 | ^3", short, " ^7)\n")
if(MUTATOR_RETURNVALUE) // command was already handled?
return false;
- if(IS_PLAYER(self))
+ entity player = M_ARGV(0, entity);
+ string cmd_name = M_ARGV(1, string);
+ int cmd_argc = M_ARGV(2, int);
+
+ if(IS_PLAYER(player))
return false;
if(cmd_name == "superspec_itemfilter")
_aspeco = "^7 superspec_itemfilter ^3\"item_classname1 item_classname2\"^7 only show thise items when ^2superspec ^3item_message^7 is on\n";
_aspeco = strcat(_aspeco, "^3 clear^7 Remove the filter (show all pickups)\n");
_aspeco = strcat(_aspeco, "^3 show ^7 Display current filter\n");
- superspec_msg("^3superspec_itemfilter help:\n\n\n", "\n^3superspec_itemfilter help:\n", self, _aspeco, 1);
+ superspec_msg("^3superspec_itemfilter help:\n\n\n", "\n^3superspec_itemfilter help:\n", player, _aspeco, 1);
}
else if(argv(1) == "clear")
{
- if(self.superspec_itemfilter != "")
- strunzone(self.superspec_itemfilter);
+ if(player.superspec_itemfilter != "")
+ strunzone(player.superspec_itemfilter);
- self.superspec_itemfilter = "";
+ player.superspec_itemfilter = "";
}
else if(argv(1) == "show" || argv(1) == "")
{
- if(self.superspec_itemfilter == "")
+ if(player.superspec_itemfilter == "")
{
- superspec_msg("^3superspec_itemfilter^7 is ^1not^7 set", "\n^3superspec_itemfilter^7 is ^1not^7 set\n", self, "", 1);
+ superspec_msg("^3superspec_itemfilter^7 is ^1not^7 set", "\n^3superspec_itemfilter^7 is ^1not^7 set\n", player, "", 1);
return true;
}
float i;
- float l = tokenize_console(self.superspec_itemfilter);
+ float l = tokenize_console(player.superspec_itemfilter);
string _msg = "";
for(i = 0; i < l; ++i)
_msg = strcat(_msg, "^3#", ftos(i), " ^7", argv(i), "\n");
_msg = strcat(_msg,"\n");
- superspec_msg("^3superspec_itemfilter is:\n\n\n", "\n^3superspec_itemfilter is:\n", self, _msg, 1);
+ superspec_msg("^3superspec_itemfilter is:\n\n\n", "\n^3superspec_itemfilter is:\n", player, _msg, 1);
}
else
{
- if(self.superspec_itemfilter != "")
- strunzone(self.superspec_itemfilter);
+ if(player.superspec_itemfilter != "")
+ strunzone(player.superspec_itemfilter);
- self.superspec_itemfilter = strzone(argv(1));
+ player.superspec_itemfilter = strzone(argv(1));
}
return true;
_aspeco = strcat(_aspeco, "^3 verbose ^7(short^5 ve^7) makes superspectate print some additional information.\n");
_aspeco = strcat(_aspeco, "^3 item_message ^7(short^5 im^7) makes superspectate print items that were picked up.\n");
_aspeco = strcat(_aspeco, "^7 Use cmd superspec_itemfilter \"item_class1 item_class2\" to set up a filter of what to show with ^3item_message.\n");
- superspec_msg("^2Available Super Spectate ^3options:\n\n\n", "\n^2Available Super Spectate ^3options:\n", self, _aspeco, 1);
+ superspec_msg("^2Available Super Spectate ^3options:\n\n\n", "\n^2Available Super Spectate ^3options:\n", player, _aspeco, 1);
return true;
}
if(argv(1) == "clear")
{
- self.superspec_flags = 0;
+ player.superspec_flags = 0;
_start = 2;
}
{
if(argv(i) == "on" || argv(i) == "1")
{
- self.superspec_flags |= _bits;
+ player.superspec_flags |= _bits;
_bits = 0;
}
else if(argv(i) == "off" || argv(i) == "0")
{
if(_start == 1)
- self.superspec_flags &= ~_bits;
+ player.superspec_flags &= ~_bits;
_bits = 0;
}
}
_aspeco = "";
- OPTIONINFO(self.superspec_flags, _aspeco, SSF_SILENT, "Silent", "silent", "si");
- OPTIONINFO(self.superspec_flags, _aspeco, SSF_VERBOSE, "Verbose", "verbose", "ve");
- OPTIONINFO(self.superspec_flags, _aspeco, SSF_ITEMMSG, "Item pickup messages", "item_message", "im");
+ OPTIONINFO(player.superspec_flags, _aspeco, SSF_SILENT, "Silent", "silent", "si");
+ OPTIONINFO(player.superspec_flags, _aspeco, SSF_VERBOSE, "Verbose", "verbose", "ve");
+ OPTIONINFO(player.superspec_flags, _aspeco, SSF_ITEMMSG, "Item pickup messages", "item_message", "im");
- superspec_msg("^3Current Super Spectate options are:\n\n\n\n\n", "\n^3Current Super Spectate options are:\n", self, _aspeco, 1);
+ superspec_msg("^3Current Super Spectate options are:\n\n\n\n\n", "\n^3Current Super Spectate options are:\n", player, _aspeco, 1);
return true;
}
_aspeco = strcat(_aspeco, "^3 item_msg ^7(short^5 im^7) to autospec when item_message in superspectate is triggered\n");
_aspeco = strcat(_aspeco, "^3 followkiller ^7(short ^5fk^7) to autospec the killer/off\n");
_aspeco = strcat(_aspeco, "^3 all ^7(short ^5aa^7) to turn everything on/off\n");
- superspec_msg("^2Available Auto Spectate ^3options:\n\n\n", "\n^2Available Auto Spectate ^3options:\n", self, _aspeco, 1);
+ superspec_msg("^2Available Auto Spectate ^3options:\n\n\n", "\n^2Available Auto Spectate ^3options:\n", player, _aspeco, 1);
return true;
}
float i, _bits = 0, _start = 1;
if(argv(1) == "clear")
{
- self.autospec_flags = 0;
+ player.autospec_flags = 0;
_start = 2;
}
{
if(argv(i) == "on" || argv(i) == "1")
{
- self.autospec_flags |= _bits;
+ player.autospec_flags |= _bits;
_bits = 0;
}
else if(argv(i) == "off" || argv(i) == "0")
{
if(_start == 1)
- self.autospec_flags &= ~_bits;
+ player.autospec_flags &= ~_bits;
_bits = 0;
}
}
_aspeco = "";
- OPTIONINFO(self.autospec_flags, _aspeco, ASF_STRENGTH, "Strength", "strength", "st");
- OPTIONINFO(self.autospec_flags, _aspeco, ASF_SHIELD, "Shield", "shield", "sh");
- OPTIONINFO(self.autospec_flags, _aspeco, ASF_MEGA_HP, "Mega Health", "mega_health", "mh");
- OPTIONINFO(self.autospec_flags, _aspeco, ASF_MEGA_AR, "Mega Armor", "mega_armor", "ma");
- OPTIONINFO(self.autospec_flags, _aspeco, ASF_FLAG_GRAB, "Flag grab", "flag_grab","fg");
- OPTIONINFO(self.autospec_flags, _aspeco, ASF_OBSERVER_ONLY, "Only switch if observer", "observer_only", "oo");
- OPTIONINFO(self.autospec_flags, _aspeco, ASF_SHOWWHAT, "Show what item triggered spectate", "show_what", "sw");
- OPTIONINFO(self.autospec_flags, _aspeco, ASF_SSIM, "Switch on superspec item message", "item_msg", "im");
- OPTIONINFO(self.autospec_flags, _aspeco, ASF_FOLLOWKILLER, "Followkiller", "followkiller", "fk");
-
- superspec_msg("^3Current auto spectate options are:\n\n\n\n\n", "\n^3Current auto spectate options are:\n", self, _aspeco, 1);
+ OPTIONINFO(player.autospec_flags, _aspeco, ASF_STRENGTH, "Strength", "strength", "st");
+ OPTIONINFO(player.autospec_flags, _aspeco, ASF_SHIELD, "Shield", "shield", "sh");
+ OPTIONINFO(player.autospec_flags, _aspeco, ASF_MEGA_HP, "Mega Health", "mega_health", "mh");
+ OPTIONINFO(player.autospec_flags, _aspeco, ASF_MEGA_AR, "Mega Armor", "mega_armor", "ma");
+ OPTIONINFO(player.autospec_flags, _aspeco, ASF_FLAG_GRAB, "Flag grab", "flag_grab","fg");
+ OPTIONINFO(player.autospec_flags, _aspeco, ASF_OBSERVER_ONLY, "Only switch if observer", "observer_only", "oo");
+ OPTIONINFO(player.autospec_flags, _aspeco, ASF_SHOWWHAT, "Show what item triggered spectate", "show_what", "sw");
+ OPTIONINFO(player.autospec_flags, _aspeco, ASF_SSIM, "Switch on superspec item message", "item_msg", "im");
+ OPTIONINFO(player.autospec_flags, _aspeco, ASF_FOLLOWKILLER, "Followkiller", "followkiller", "fk");
+
+ superspec_msg("^3Current auto spectate options are:\n\n\n\n\n", "\n^3Current auto spectate options are:\n", player, _aspeco, 1);
return true;
}
{
FOREACH_CLIENT(IS_PLAYER(it) && (it.strength_finished > time || it.invincible_finished > time), LAMBDA(return superspec_Spectate(it)));
- superspec_msg("", "", self, "No active powerup\n", 1);
+ superspec_msg("", "", player, "No active powerup\n", 1);
return true;
}
{
FOREACH_CLIENT(IS_PLAYER(it) && it.strength_finished > time, LAMBDA(return superspec_Spectate(it)));
- superspec_msg("", "", self, "No active Strength\n", 1);
+ superspec_msg("", "", player, "No active Strength\n", 1);
return true;
}
{
FOREACH_CLIENT(IS_PLAYER(it) && it.invincible_finished > time, LAMBDA(return superspec_Spectate(it)));
- superspec_msg("", "", self, "No active Shield\n", 1);
+ superspec_msg("", "", player, "No active Shield\n", 1);
return true;
}
MUTATOR_HOOKFUNCTION(superspec, PlayerDies)
{
+ entity frag_attacker = M_ARGV(1, entity);
+ entity frag_target = M_ARGV(2, entity);
+
FOREACH_CLIENT(IS_SPEC(it), LAMBDA(
if(it.autospec_flags & ASF_FOLLOWKILLER && IS_PLAYER(frag_attacker) && it.enemy == frag_target)
{
MUTATOR_HOOKFUNCTION(vampire, PlayerDamage_SplitHealthArmor)
{
+ entity frag_attacker = M_ARGV(1, entity);
+ entity frag_target = M_ARGV(2, entity);
+ float damage_take = M_ARGV(4, float);
+
if(time >= frag_target.spawnshieldtime)
if(frag_target != frag_attacker)
if(!IS_DEAD(frag_target))
save = v.y;
}
- frag_damage = damage;
- MUTATOR_CALLHOOK(PlayerDamage_SplitHealthArmor, inflictor, attacker, this, force, take, save);
- take = bound(0, damage_take, this.health);
- save = bound(0, damage_save, this.armorvalue);
+ MUTATOR_CALLHOOK(PlayerDamage_SplitHealthArmor, inflictor, attacker, this, force, take, save, deathtype, damage);
+ take = bound(0, M_ARGV(4, float), this.health);
+ save = bound(0, M_ARGV(5, float), this.armorvalue);
excess = max(0, damage - take - save);
if(sound_allowed(MSG_BROADCAST, attacker))
if(accuracy_isgooddamage(attacker, this))
attacker.accuracy.(accuracy_frags[w.m_id-1]) += 1;
- MUTATOR_CALLHOOK(PlayerDies, inflictor, attacker, this, deathtype);
- excess = frag_damage;
+ MUTATOR_CALLHOOK(PlayerDies, inflictor, attacker, this, deathtype, excess);
+ excess = M_ARGV(4, float);
Weapon wep = PS(this).m_weapon;
WITHSELF(this, wep.wr_playerdeath(wep, this));
return;
}
}
- else if (MUTATOR_CALLHOOK(SV_ParseClientCommand, strtolower(argv(0)), argc, command))
+ else if (MUTATOR_CALLHOOK(SV_ParseClientCommand, this, strtolower(argv(0)), argc, command))
{
return; // handled by a mutator
}
}
void GiveFrags (entity attacker, entity targ, float f, int deathtype)
-{SELFPARAM();
+{
// TODO route through PlayerScores instead
if(gameover) return;
}
// FIXME fix the mess this is (we have REAL points now!)
- if(MUTATOR_CALLHOOK(GiveFragsForKill, self, attacker, targ, f))
+ if(MUTATOR_CALLHOOK(GiveFragsForKill, attacker, targ, f))
{
- f = frag_score;
+ f = M_ARGV(2, float);
}
attacker.totalfrags += f;
/** called when a player dies to e.g. remove stuff he was carrying. */
#define EV_PlayerDies(i, o) \
- /**/ i(entity, frag_inflictor) \
- /**/ i(entity, frag_attacker) \
- /** same as self */ i(entity, frag_target) \
- /**/ i(int, frag_deathtype) \
- /**/
-entity frag_inflictor;
-entity frag_attacker;
-entity frag_target;
-int frag_deathtype;
+ /** inflictor */ i(entity, MUTATOR_ARGV_0_entity) \
+ /** attacker */ i(entity, MUTATOR_ARGV_1_entity) \
+ /** target */ i(entity, MUTATOR_ARGV_2_entity) \
+ /** deathtype */ i(float, MUTATOR_ARGV_3_float) \
+ /** damage */ i(float, MUTATOR_ARGV_4_float) \
+ /** damage */ o(float, MUTATOR_ARGV_4_float) \
+ /**/
MUTATOR_HOOKABLE(PlayerDies, EV_PlayerDies);
/** called when a player dies to e.g. remove stuff he was carrying */
/** called when someone was fragged by "self", and is expected to change frag_score to adjust scoring for the kill */
#define EV_GiveFragsForKill(i, o) \
- /**/ i(entity, __self) \
- /** same as self */ i(entity, frag_attacker) \
- /**/ i(entity, frag_target) \
- /**/ i(float, frag_score) \
- /**/ o(float, frag_score) \
+ /** attacker */ i(entity, MUTATOR_ARGV_0_entity) \
+ /** target */ i(entity, MUTATOR_ARGV_1_entity) \
+ /** frag score */ i(float, MUTATOR_ARGV_2_float) \
+ /** */ o(float, MUTATOR_ARGV_2_float) \
/**/
-float frag_score;
MUTATOR_HOOKABLE(GiveFragsForKill, EV_GiveFragsForKill);
/** called when the match ends */
/** called when a monster dies */
#define EV_MonsterDies(i, o) \
- /**/ i(entity, frag_target) \
- /**/ i(entity, frag_attacker) \
+ /** target */ i(entity, MUTATOR_ARGV_0_entity) \
+ /** attacker */ i(entity, MUTATOR_ARGV_1_entity) \
+ /** deathtype */ i(float, MUTATOR_ARGV_2_float) \
/**/
MUTATOR_HOOKABLE(MonsterDies, EV_MonsterDies);
/** called when a monster is dropping loot */
#define EV_MonsterDropItem(i, o) \
- /**/ i(entity, other) \
- /**/ o(entity, other) \
+ /* monster */ i(entity, MUTATOR_ARGV_0_entity) \
+ /* item (can be removed or changed) */ i(entity, MUTATOR_ARGV_1_entity) \
+ /**/ o(entity, MUTATOR_ARGV_1_entity) \
+ /* attacker */ i(entity, MUTATOR_ARGV_2_entity) \
/**/
.void(entity this) monster_loot;
MUTATOR_HOOKABLE(MonsterDropItem, EV_MonsterDropItem);
/** called when a player gets damaged to e.g. remove stuff he was carrying. */
#define EV_PlayerDamage_SplitHealthArmor(i, o) \
- /**/ i(entity, frag_inflictor) \
- /**/ i(entity, frag_attacker) \
- /** same as self */ i(entity, frag_target) \
- /** NOTE: this force already HAS been applied */ i(vector, damage_force) \
- /**/ i(float, damage_take) \
- /**/ o(float, damage_take) \
- /**/ i(float, damage_save) \
- /**/ o(float, damage_save) \
- /**/
-vector damage_force;
-float damage_take;
-float damage_save;
+ /** inflictor */ i(entity, MUTATOR_ARGV_0_entity) \
+ /** attacker */ i(entity, MUTATOR_ARGV_1_entity) \
+ /** target */ i(entity, MUTATOR_ARGV_2_entity) \
+ /** force (no out) */ i(vector, MUTATOR_ARGV_3_vector) \
+ /** damage take */ i(float, MUTATOR_ARGV_4_float) \
+ /** damage take */ o(float, MUTATOR_ARGV_4_float) \
+ /** damage save */ i(float, MUTATOR_ARGV_5_float) \
+ /** damage save */ o(float, MUTATOR_ARGV_5_float) \
+ /** deathtype */ i(float, MUTATOR_ARGV_6_float) \
+ /** damage */ i(float, MUTATOR_ARGV_7_float) \
+ /**/
MUTATOR_HOOKABLE(PlayerDamage_SplitHealthArmor, EV_PlayerDamage_SplitHealthArmor);
/**
* }
*/
#define EV_SV_ParseClientCommand(i, o) \
- /** command name */ i(string, cmd_name) \
- /** also, argv() can be used */ i(int, cmd_argc) \
- /** whole command, use only if you really have to */ i(string, cmd_string) \
+ /** client sending the command */ i(entity, MUTATOR_ARGV_0_entity) \
+ /** command name */ i(string, MUTATOR_ARGV_1_string) \
+ /** argc (also, argv() can be used) */ i(int, MUTATOR_ARGV_2_int) \
+ /** whole command, use only if you really have to */ i(string, MUTATOR_ARGV_3_string) \
/**/
-string cmd_name;
-int cmd_argc;
-string cmd_string;
MUTATOR_HOOKABLE(SV_ParseClientCommand, EV_SV_ParseClientCommand);
/** please read EV_SV_ParseClientCommand description before using */
#define EV_SV_ParseServerCommand(i, o) \
- /** command name */ i(string, cmd_name) \
- /** also, argv() can be used */ i(int, cmd_argc) \
- /** whole command, use only if you really have to */ i(string, cmd_string) \
+ /** command name */ i(string, MUTATOR_ARGV_0_string) \
+ /** argc (also, argv() can be used) */ i(int, MUTATOR_ARGV_1_int) \
+ /** whole command, use only if you really have to */ i(string, MUTATOR_ARGV_2_string) \
/**/
-//string cmd_name;
-//int cmd_argc;
-//string cmd_string;
MUTATOR_HOOKABLE(SV_ParseServerCommand, EV_SV_ParseServerCommand);
/**
* return 1 to make the spawnpoint unusable
*/
#define EV_Spawn_Score(i, o) \
- /** player wanting to spawn */ i(entity, __self) \
- /** spot to be evaluated */ i(entity, spawn_spot) \
- /** _x is priority, _y is "distance" */ i(vector, spawn_score) \
- /**/ o(vector, spawn_score) \
+ /** player wanting to spawn */ i(entity, MUTATOR_ARGV_0_entity) \
+ /** spot to be evaluated */ i(entity, MUTATOR_ARGV_1_entity) \
+ /** spot score, _x is priority, _y is "distance" */ i(vector, MUTATOR_ARGV_0_vector) \
+ /**/ o(vector, MUTATOR_ARGV_0_vector) \
/**/
-entity spawn_spot;
-vector spawn_score;
MUTATOR_HOOKABLE(Spawn_Score, EV_Spawn_Score);
/** runs globally each server frame */
/** called when a target is checked for accuracy */
#define EV_AccuracyTargetValid(i, o) \
- /** attacker */ i(entity, frag_attacker) \
- /** target */ i(entity, frag_target) \
+ /** attacker */ i(entity, MUTATOR_ARGV_0_entity) \
+ /** target */ i(entity, MUTATOR_ARGV_1_entity) \
/**/
MUTATOR_HOOKABLE(AccuracyTargetValid, EV_AccuracyTargetValid);
enum {
MUTATOR_HOOKABLE(SetWeaponArena, EV_SetWeaponArena);
#define EV_DropSpecialItems(i, o) \
- /**/ i(entity, frag_target) \
+ /** target */ i(entity, MUTATOR_ARGV_0_entity) \
/**/
MUTATOR_HOOKABLE(DropSpecialItems, EV_DropSpecialItems);
/** */
#define EV_PrepareExplosionByDamage(i, o) \
- /**/ i(entity, __self) \
- /**/ i(entity, frag_attacker) \
+ /** projectile */ i(entity, MUTATOR_ARGV_0_entity) \
+ /** attacker */ i(entity, MUTATOR_ARGV_1_entity) \
/**/
MUTATOR_HOOKABLE(PrepareExplosionByDamage, EV_PrepareExplosionByDamage);
MUTATOR_HOOKFUNCTION(ca, PlayerDies)
{
+ entity frag_target = M_ARGV(2, entity);
+
ca_LastPlayerForTeam_Notify();
if (!allowed_to_spawn)
frag_target.respawn_flags = RESPAWN_SILENT;
MUTATOR_HOOKFUNCTION(ca, GiveFragsForKill, CBC_ORDER_FIRST)
{
- frag_score = 0; // score will be given to the winner team when the round ends
- return 1;
+ M_ARGV(2, float) = 0; // score will be given to the winner team when the round ends
+ return true;
}
MUTATOR_HOOKFUNCTION(ca, SetStartItems)
MUTATOR_HOOKFUNCTION(ca, PlayerDamage_SplitHealthArmor)
{
+ entity frag_attacker = M_ARGV(1, entity);
+ entity frag_target = M_ARGV(2, entity);
+ float frag_damage = M_ARGV(7, float);
+ float damage_take = M_ARGV(4, float);
+ float damage_save = M_ARGV(5, float);
+
float excess = max(0, frag_damage - damage_take - damage_save);
if (frag_target != frag_attacker && IS_PLAYER(frag_attacker))
PlayerTeamScore_Add(frag_attacker, SP_SCORE, ST_SCORE, (frag_damage - excess) * autocvar_g_ca_damage2score_multiplier);
-
- return false;
}
MUTATOR_HOOKFUNCTION(ca, PlayerRegen)
MUTATOR_HOOKFUNCTION(ctf, PlayerDies)
{
+ entity frag_attacker = M_ARGV(1, entity);
+ entity frag_target = M_ARGV(2, entity);
+
if((frag_attacker != frag_target) && (IS_PLAYER(frag_attacker)) && (frag_target.flagcarried))
{
PlayerTeamScore_AddScore(frag_attacker, ((SAME_TEAM(frag_attacker, frag_target)) ? -autocvar_g_ctf_score_kill : autocvar_g_ctf_score_kill));
MUTATOR_HOOKFUNCTION(ctf, GiveFragsForKill)
{
- frag_score = 0;
+ M_ARGV(2, float) = 0; // frag score
return (autocvar_g_ctf_ignore_frags); // no frags counted in ctf if this is true
}
void superspec_msg(string _center_title, string _con_title, entity _to, string _msg, float _spamlevel); // TODO
MUTATOR_HOOKFUNCTION(ctf, SV_ParseClientCommand)
{
- SELFPARAM();
- if(IS_PLAYER(self) || MUTATOR_RETURNVALUE || !cvar("g_superspectate")) { return false; }
+ entity player = M_ARGV(0, entity);
+ string cmd_name = M_ARGV(1, string);
+ int cmd_argc = M_ARGV(2, int);
+
+ if(IS_PLAYER(player) || MUTATOR_RETURNVALUE || !cvar("g_superspectate")) { return false; }
if(cmd_name == "followfc")
{
if(it.flagcarried && (it.team == _team || _team == 0))
{
found = true;
- if(_team == 0 && IS_SPEC(self) && self.enemy == it)
+ if(_team == 0 && IS_SPEC(player) && player.enemy == it)
continue; // already spectating this fc, try another
return superspec_Spectate(it);
}
));
if(!found)
- superspec_msg("", "", self, "No active flag carrier\n", 1);
+ superspec_msg("", "", player, "No active flag carrier\n", 1);
return true;
}
MUTATOR_HOOKFUNCTION(ctf, DropSpecialItems)
{
+ entity frag_target = M_ARGV(0, entity);
+
if(frag_target.flagcarried)
ctf_Handle_Throw(frag_target, world, DROP_THROW);
MUTATOR_HOOKFUNCTION(cts, PlayerDies)
{
+ entity frag_target = M_ARGV(2, entity);
+
frag_target.respawn_flags |= RESPAWN_FORCE;
race_AbandonRaceCheck(frag_target);
return false;
MUTATOR_HOOKFUNCTION(ft, PlayerDies)
{
+ entity frag_attacker = M_ARGV(1, entity);
+ entity frag_target = M_ARGV(2, entity);
+ float frag_deathtype = M_ARGV(2, float);
+
if(round_handler_IsActive())
if(round_handler_CountdownRunning())
{
MUTATOR_HOOKFUNCTION(ft, GiveFragsForKill, CBC_ORDER_FIRST)
{
- frag_score = 0; // no frags counted in Freeze Tag
+ M_ARGV(2, float) = 0; // no frags counted in Freeze Tag
return 1;
}
MUTATOR_HOOKFUNCTION(inv, MonsterDies)
{
+ entity frag_target = M_ARGV(0, entity);
+ entity frag_attacker = M_ARGV(1, entity);
+
if(!(frag_target.spawnflags & MONSTERFLAG_RESPAWNED))
{
inv_numkilled += 1;
}
MUTATOR_HOOKFUNCTION(inv, SV_ParseClientCommand)
-{SELFPARAM();
+{
if(MUTATOR_RETURNVALUE) // command was already handled?
return false;
+ entity player = M_ARGV(0, entity);
+ string cmd_name = M_ARGV(1, string);
+
if(cmd_name == "debuginvasion")
{
- sprint(self, strcat("inv_maxspawned = ", ftos(inv_maxspawned), "\n"));
- sprint(self, strcat("inv_numspawned = ", ftos(inv_numspawned), "\n"));
- sprint(self, strcat("inv_numkilled = ", ftos(inv_numkilled), "\n"));
- sprint(self, strcat("inv_roundcnt = ", ftos(inv_roundcnt), "\n"));
- sprint(self, strcat("monsters_total = ", ftos(monsters_total), "\n"));
- sprint(self, strcat("monsters_killed = ", ftos(monsters_killed), "\n"));
- sprint(self, strcat("inv_monsterskill = ", ftos(inv_monsterskill), "\n"));
+ sprint(player, strcat("inv_maxspawned = ", ftos(inv_maxspawned), "\n"));
+ sprint(player, strcat("inv_numspawned = ", ftos(inv_numspawned), "\n"));
+ sprint(player, strcat("inv_numkilled = ", ftos(inv_numkilled), "\n"));
+ sprint(player, strcat("inv_roundcnt = ", ftos(inv_roundcnt), "\n"));
+ sprint(player, strcat("monsters_total = ", ftos(monsters_total), "\n"));
+ sprint(player, strcat("monsters_killed = ", ftos(monsters_killed), "\n"));
+ sprint(player, strcat("inv_monsterskill = ", ftos(inv_monsterskill), "\n"));
return true;
}
MUTATOR_HOOKFUNCTION(inv, AccuracyTargetValid)
{
+ entity frag_target = M_ARGV(1, entity);
+
if(IS_MONSTER(frag_target))
return MUT_ACCADD_INVALID;
return MUT_ACCADD_INDIFFERENT;
MUTATOR_HOOKFUNCTION(ka, PlayerDies)
{
+ entity frag_attacker = M_ARGV(1, entity);
+ entity frag_target = M_ARGV(2, entity);
+
if((frag_attacker != frag_target) && (IS_PLAYER(frag_attacker)))
{
if(frag_target.ballcarried) { // add to amount of times killing carrier
MUTATOR_HOOKFUNCTION(ka, GiveFragsForKill)
{
- frag_score = 0; // no frags counted in keepaway
- return 1; // you deceptive little bugger ;3 This needs to be true in order for this function to even count.
+ M_ARGV(2, float) = 0; // no frags counted in keepaway
+ return true; // you deceptive little bugger ;3 This needs to be true in order for this function to even count.
}
MUTATOR_HOOKFUNCTION(ka, PlayerPreThink)
MUTATOR_HOOKFUNCTION(ka, DropSpecialItems)
{
+ entity frag_target = M_ARGV(0, entity);
+
if(frag_target.ballcarried)
ka_DropEvent(frag_target);
MUTATOR_HOOKFUNCTION(kh, PlayerDies)
{
- if(frag_target == other)
+ entity frag_attacker = M_ARGV(1, entity);
+ entity frag_target = M_ARGV(2, entity);
+
+ if(frag_target == frag_attacker)
kh_Key_DropAll(frag_target, true);
- else if(IS_PLAYER(other))
+ else if(IS_PLAYER(frag_attacker))
kh_Key_DropAll(frag_target, false);
else
kh_Key_DropAll(frag_target, true);
MUTATOR_HOOKFUNCTION(kh, GiveFragsForKill, CBC_ORDER_FIRST)
{
- frag_score = kh_HandleFrags(frag_attacker, frag_target, frag_score);
- return 0;
+ entity frag_attacker = M_ARGV(0, entity);
+ entity frag_target = M_ARGV(1, entity);
+ float frag_score = M_ARGV(2, float);
+ M_ARGV(2, float) = kh_HandleFrags(frag_attacker, frag_target, frag_score);
+ return false;
}
MUTATOR_HOOKFUNCTION(kh, MatchEnd)
MUTATOR_HOOKFUNCTION(kh, DropSpecialItems)
{
+ entity frag_target = M_ARGV(0, entity);
+
kh_Key_DropAll(frag_target, false);
return false;
}
MUTATOR_HOOKFUNCTION(lms, PlayerDies)
{
+ entity frag_target = M_ARGV(2, entity);
+
frag_target.respawn_flags |= RESPAWN_FORCE;
return false;
}
MUTATOR_HOOKFUNCTION(lms, GiveFragsForKill)
{
+ entity frag_target = M_ARGV(1, entity);
+
// remove a life
float tl;
tl = PlayerScore_Add(frag_target, SP_LMS_LIVES, -1);
PlayerScore_Add(frag_target, SP_LMS_RANK, lms_next_place); // won't ever spawn again
--lms_next_place;
}
- frag_score = 0;
+ M_ARGV(2, float) = 0;
return true;
}
MUTATOR_HOOKFUNCTION(rc, PlayerDies)
{
+ entity frag_target = M_ARGV(2, entity);
+
frag_target.respawn_flags |= RESPAWN_FORCE;
race_AbandonRaceCheck(frag_target);
return false;
if(shortest > mindist)
prio += SPAWN_PRIO_GOOD_DISTANCE;
- spawn_score = prio * '1 0 0' + shortest * '0 1 0';
- spawn_spot = spot;
+ vector spawn_score = prio * '1 0 0' + shortest * '0 1 0';
// filter out spots for assault
if(spot.target != "") {
}
}
- MUTATOR_CALLHOOK(Spawn_Score, this, spawn_spot, spawn_score);
+ MUTATOR_CALLHOOK(Spawn_Score, this, spot, spawn_score);
+ spawn_score = M_ARGV(2, vector);
return spawn_score;
}