.float buff_time = _STAT(BUFF_TIME);
void buffs_DelayedInit(entity this);
- AUTOCVAR(g_buffs, int, -1, _("Enable buffs, -1: enabled but no auto location or replacing powerups, 1: enabled and can replace them"));
+ AUTOCVAR(g_buffs, int, -1, "Enable buffs, -1: enabled but no auto location or replacing powerups, 1: enabled and can replace them");
REGISTER_MUTATOR(buffs, autocvar_g_buffs)
{
}
if(player.buffs & BUFF_AMMO.m_itemid)
- if(player.clip_size)
- player.clip_load = player.(weapon_load[PS(player).m_switchweapon.m_id]) = player.clip_size;
+ {
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(player.(weaponentity).clip_size)
+ player.(weaponentity).clip_load = player.(weaponentity).(weapon_load[player.(weaponentity).m_switchweapon.m_id]) = player.(weaponentity).clip_size;
+ }
+ }
if((player.buffs & BUFF_INVISIBLE.m_itemid) && (player.oldbuffs & BUFF_INVISIBLE.m_itemid))
if(player.alpha != autocvar_g_buffs_invisible_alpha)
player.buff_ammo_prev_infitems = (player.items & IT_UNLIMITED_WEAPON_AMMO);
player.items |= IT_UNLIMITED_WEAPON_AMMO;
- if(player.clip_load)
- player.buff_ammo_prev_clipload = player.clip_load;
- player.clip_load = player.(weapon_load[PS(player).m_switchweapon.m_id]) = player.clip_size;
+ if(player.buffs & BUFF_AMMO.m_itemid)
+ {
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(player.(weaponentity).clip_load)
+ player.(weaponentity).buff_ammo_prev_clipload = player.(weaponentity).clip_load;
+ if(player.(weaponentity).clip_size)
+ player.(weaponentity).clip_load = player.(weaponentity).(weapon_load[player.(weaponentity).m_switchweapon.m_id]) = player.(weaponentity).clip_size;
+ }
+ }
}
BUFF_ONREM(BUFF_AMMO)
else
player.items &= ~IT_UNLIMITED_WEAPON_AMMO;
- if(player.buff_ammo_prev_clipload)
- player.clip_load = player.buff_ammo_prev_clipload;
+ if(player.buffs & BUFF_AMMO.m_itemid)
+ {
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(player.(weaponentity).buff_ammo_prev_clipload)
+ player.(weaponentity).clip_load = player.(weaponentity).buff_ammo_prev_clipload;
+ }
+ }
}
BUFF_ONADD(BUFF_INVISIBLE)
#include "rpc.qh"
bool autocvar_g_overkill_powerups_replace;
-bool autocvar_g_overkill_ammo_charge;
-float autocvar_g_overkill_ammo_charge_notice;
-float autocvar_g_overkill_ammo_charge_limit;
bool autocvar_g_overkill_filter_healthmega;
bool autocvar_g_overkill_filter_armormedium;
bool autocvar_g_overkill_filter_armorbig;
bool autocvar_g_overkill_filter_armormega;
-.float ok_lastwep;
.float ok_item;
-.float ok_notice_time;
-.float ammo_charge[Weapons_MAX];
-.float ok_use_ammocharge = _STAT(OK_AMMO_CHARGE);
-.float ok_ammo_charge = _STAT(OK_AMMO_CHARGEPOOL);
-
-void(entity ent, float wep) ok_DecreaseCharge;
+.Weapon ok_lastwep[MAX_WEAPONSLOTS];
void ok_Initialize();
}
}
-MUTATOR_HOOKFUNCTION(ok, W_DecreaseAmmo)
-{
- entity actor = M_ARGV(0, entity);
- if (actor.ok_use_ammocharge)
- {
- ok_DecreaseCharge(actor, PS(actor).m_weapon.m_id);
- return true;
- }
-}
-
-MUTATOR_HOOKFUNCTION(ok, W_Reload)
-{
- entity actor = M_ARGV(0, entity);
- return actor.ok_use_ammocharge;
-}
-
void W_Blaster_Attack(entity, .entity, float, float, float, float, float, float, float, float, float, float);
spawnfunc(weapon_hmg);
spawnfunc(weapon_rpc);
-void ok_DecreaseCharge(entity ent, int wep)
-{
- if(!ent.ok_use_ammocharge) return;
-
- entity wepent = Weapons_from(wep);
-
- if (wepent == WEP_Null) return; // dummy
-
- ent.ammo_charge[wep] -= max(0, cvar(sprintf("g_overkill_ammo_decharge_%s", wepent.netname)));
-}
-
-void ok_IncreaseCharge(entity ent, int wep)
-{
- entity wepent = Weapons_from(wep);
-
- if (wepent == WEP_Null) return; // dummy
-
- if(ent.ok_use_ammocharge)
- if(!PHYS_INPUT_BUTTON_ATCK(ent)) // not while attacking?
- ent.ammo_charge[wep] = min(autocvar_g_overkill_ammo_charge_limit, ent.ammo_charge[wep] + cvar(sprintf("g_overkill_ammo_charge_rate_%s", wepent.netname)) * frametime / W_TICSPERFRAME);
-}
-
-float ok_CheckWeaponCharge(entity ent, int wep)
-{
- if(!ent.ok_use_ammocharge) return true;
-
- entity wepent = Weapons_from(wep);
-
- if(wepent == WEP_Null) return false; // dummy
-
- return (ent.ammo_charge[wep] >= cvar(sprintf("g_overkill_ammo_decharge_%s", wepent.netname)));
-}
-
MUTATOR_HOOKFUNCTION(ok, Damage_Calculate, CBC_ORDER_LAST)
{
entity frag_attacker = M_ARGV(1, entity);
ok_DropItem(frag_target, targ);
- frag_target.ok_lastwep = PS(frag_target).m_switchweapon.m_id;
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+
+ frag_target.ok_lastwep[slot] = frag_target.(weaponentity).m_switchweapon;
+ }
}
MUTATOR_HOOKFUNCTION(ok, MonsterDropItem)
if(IS_DEAD(player) || !IS_PLAYER(player) || STAT(FROZEN, player))
return;
- for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
- {
- .entity weaponentity = weaponentities[slot];
- entity thiswep = player.(weaponentity);
-
- if(player.ok_lastwep[slot] && player.ok_lastwep[slot] != WEP_Null)
- {
- Weapon newwep = player.ok_lastwep[slot];
- if(player.ok_lastwep[slot] == WEP_HMG)
- newwep = WEP_MACHINEGUN;
- if(player.ok_lastwep[slot] == WEP_RPC)
- newwep = WEP_VORTEX;
- thiswep.m_switchweapon = newwep;
- player.ok_lastwep[slot] = WEP_Null;
- }
- }
- ok_IncreaseCharge(player, PS(player).m_weapon.m_id);
--
if(PHYS_INPUT_BUTTON_ATCK2(player))
if( !forbidWeaponUse(player) || player.weapon_blocked // allow if weapon is blocked
|| (round_handler_IsActive() && !round_handler_IsRoundStarted()) )
player.jump_interval = time + WEP_CVAR_PRI(blaster, refire) * W_WeaponRateFactor(player);
makevectors(player.v_angle);
- Weapon oldwep = PS(player).m_weapon;
- PS(player).m_weapon = WEP_BLASTER;
- W_Blaster_Attack(
- player,
- weaponentities[0], // TODO: unhardcode
- WEP_BLASTER.m_id | HITTYPE_SECONDARY,
- WEP_CVAR_SEC(vaporizer, shotangle),
- WEP_CVAR_SEC(vaporizer, damage),
- WEP_CVAR_SEC(vaporizer, edgedamage),
- WEP_CVAR_SEC(vaporizer, radius),
- WEP_CVAR_SEC(vaporizer, force),
- WEP_CVAR_SEC(vaporizer, speed),
- WEP_CVAR_SEC(vaporizer, spread),
- WEP_CVAR_SEC(vaporizer, delay),
- WEP_CVAR_SEC(vaporizer, lifetime)
- );
- PS(player).m_weapon = oldwep;
- }
-
- player.weapon_blocked = false;
-
- player.ok_ammo_charge = player.ammo_charge[PS(player).m_weapon.m_id];
-
- if(player.ok_use_ammocharge)
- if(!ok_CheckWeaponCharge(player, PS(player).m_weapon.m_id))
- {
- if(autocvar_g_overkill_ammo_charge_notice && time > player.ok_notice_time && PHYS_INPUT_BUTTON_ATCK(player) && IS_REAL_CLIENT(player) && PS(player).m_weapon == PS(player).m_switchweapon)
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
{
- //Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_OVERKILL_CHARGE);
- player.ok_notice_time = time + 2;
- play2(player, SND(DRYFIRE));
+ .entity weaponentity = weaponentities[slot];
+
+ if(player.(weaponentity).m_weapon == WEP_Null && slot != 0)
+ continue;
+
+ Weapon oldwep = player.(weaponentity).m_weapon;
+ player.(weaponentity).m_weapon = WEP_BLASTER;
+ W_Blaster_Attack(
+ player,
+ weaponentity,
+ WEP_BLASTER.m_id | HITTYPE_SECONDARY,
+ WEP_CVAR_SEC(vaporizer, shotangle),
+ WEP_CVAR_SEC(vaporizer, damage),
+ WEP_CVAR_SEC(vaporizer, edgedamage),
+ WEP_CVAR_SEC(vaporizer, radius),
+ WEP_CVAR_SEC(vaporizer, force),
+ WEP_CVAR_SEC(vaporizer, speed),
+ WEP_CVAR_SEC(vaporizer, spread),
+ WEP_CVAR_SEC(vaporizer, delay),
+ WEP_CVAR_SEC(vaporizer, lifetime)
+ );
+ player.(weaponentity).m_weapon = oldwep;
}
- Weapon wpn = PS(player).m_weapon;
- .entity weaponentity = weaponentities[0]; // TODO: unhardcode
- if(player.(weaponentity).state != WS_CLEAR)
- w_ready(wpn, player, weaponentity, PHYS_INPUT_BUTTON_ATCK(player) | (PHYS_INPUT_BUTTON_ATCK2(player) << 1));
-
- player.weapon_blocked = true;
}
PHYS_INPUT_BUTTON_ATCK2(player) = false;
}
--MUTATOR_HOOKFUNCTION(ok, PlayerSpawn)
-{
- entity player = M_ARGV(0, entity);
-
- if(autocvar_g_overkill_ammo_charge)
- {
- FOREACH(Weapons, it != WEP_Null, LAMBDA(player.ammo_charge[it.m_id] = autocvar_g_overkill_ammo_charge_limit));
-
- player.ok_use_ammocharge = 1;
- player.ok_notice_time = time;
- }
- else
- player.ok_use_ammocharge = 0;
-}
-
+ MUTATOR_HOOKFUNCTION(ok, PlayerWeaponSelect)
{
entity player = M_ARGV(0, entity);
- // if player changed their weapon while dead, don't switch to their death weapon
- if(player.impulse)
- if(player.ok_lastwep)
++ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
{
- for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
- Weapon newwep = Weapons_from(player.ok_lastwep);
- if(player.ok_lastwep == WEP_HMG.m_id)
- newwep = WEP_MACHINEGUN;
- if(player.ok_lastwep == WEP_RPC.m_id)
- newwep = WEP_VORTEX;
- PS(player).m_switchweapon = newwep;
- player.ok_lastwep = 0;
++ .entity weaponentity = weaponentities[slot];
++ entity thiswep = player.(weaponentity);
++
++ if(player.ok_lastwep[slot] && player.ok_lastwep[slot] != WEP_Null)
+ {
++ Weapon newwep = player.ok_lastwep[slot];
++ if(player.ok_lastwep[slot] == WEP_HMG)
++ newwep = WEP_MACHINEGUN;
++ if(player.ok_lastwep[slot] == WEP_RPC)
++ newwep = WEP_VORTEX;
++ thiswep.m_switchweapon = newwep;
+ player.ok_lastwep[slot] = WEP_Null;
+ }
}
}
return true;
}
-MUTATOR_HOOKFUNCTION(ok, SpectateCopy)
-{
- entity spectatee = M_ARGV(0, entity);
- entity client = M_ARGV(1, entity);
-
- client.ammo_charge[PS(client).m_weapon.m_id] = spectatee.ammo_charge[PS(spectatee).m_weapon.m_id];
- client.ok_use_ammocharge = spectatee.ok_use_ammocharge;
-}
-
MUTATOR_HOOKFUNCTION(ok, SetStartItems, CBC_ORDER_LAST)
{
WepSet ok_start_items = (WEPSET(MACHINEGUN) | WEPSET(VORTEX) | WEPSET(SHOTGUN));
float Item_GiveTo(entity item, entity player)
{
- float _switchweapon;
float pickedup;
// if nothing happens to player, just return without taking the item
pickedup = false;
- _switchweapon = false;
+ int _switchweapon = 0;
// in case the player has autoswitch enabled do the following:
// if the player is using their best weapon before items are given, they
// probably want to switch to an even better weapon after items are given
- if (player.autoswitch)
- if (PS(player).m_switchweapon == w_getbestweapon(player))
- _switchweapon = true;
- if (!(player.weapons & WepSet_FromWeapon(PS(player).m_switchweapon)))
- _switchweapon = true;
+ if(player.autoswitch)
+ {
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(player.(weaponentity).m_weapon != WEP_Null || slot == 0)
+ {
+ if(player.(weaponentity).m_switchweapon == w_getbestweapon(player, weaponentity))
+ _switchweapon |= BIT(slot);
+
+ if(!(player.weapons & WepSet_FromWeapon(player.(weaponentity).m_switchweapon)))
+ _switchweapon |= BIT(slot);
+ }
+ }
+ }
pickedup |= Item_GiveAmmoTo(item, player, ammo_fuel, g_pickup_fuel_max, ITEM_MODE_FUEL);
pickedup |= Item_GiveAmmoTo(item, player, ammo_shells, g_pickup_shells_max, ITEM_MODE_NONE);
FOREACH(Weapons, it != WEP_Null, {
if(w & (it.m_wepset))
{
- W_DropEvent(wr_pickup, player, it.m_id, item);
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(player.(weaponentity).m_weapon != WEP_Null || slot == 0)
+ W_DropEvent(wr_pickup, player, it.m_id, item, weaponentity);
+ }
W_GiveWeapon(player, it.m_id);
}
});
// crude hack to enforce switching weapons
if(g_cts && item.itemdef.instanceOfWeaponPickup)
{
- W_SwitchWeapon_Force(player, Weapons_from(item.weapon));
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(player.(weaponentity).m_weapon != WEP_Null || slot == 0)
+ W_SwitchWeapon_Force(player, Weapons_from(item.weapon), weaponentity);
+ }
return 1;
}
- if (_switchweapon)
- if (PS(player).m_switchweapon != w_getbestweapon(player))
- W_SwitchWeapon_Force(player, w_getbestweapon(player));
+ if(_switchweapon)
+ {
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(_switchweapon & BIT(slot))
+ if(player.(weaponentity).m_switchweapon != w_getbestweapon(player, weaponentity))
+ W_SwitchWeapon_Force(player, w_getbestweapon(player, weaponentity), weaponentity);
+ }
+ }
return 1;
}
RemoveItem(this);
}
+ void item_use(entity this, entity actor, entity trigger)
+ {
+ // use the touch function to handle collection
+ gettouch(this)(this, actor);
+ }
+
void _StartItem(entity this, entity def, float defaultrespawntime, float defaultrespawntimejitter)
{
string itemname = def.m_name;
}
*/
+ if(this.targetname != "" && (this.spawnflags & 16))
+ this.use = item_use;
+
if(autocvar_spawn_debug >= 2)
{
// why not flags & fl_item?
float GiveItems(entity e, float beginarg, float endarg)
{
float got, i, val, op;
- float _switchweapon;
string cmd;
val = 999;
got = 0;
- _switchweapon = false;
- if (e.autoswitch)
- if (PS(e).m_switchweapon == w_getbestweapon(e))
- _switchweapon = true;
+ int _switchweapon = 0;
+
+ if(e.autoswitch)
+ {
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(e.(weaponentity).m_weapon != WEP_Null || slot == 0)
+ if(e.(weaponentity).m_switchweapon == w_getbestweapon(e, weaponentity))
+ _switchweapon |= BIT(slot);
+ }
+ }
e.strength_finished = max(0, e.strength_finished - time);
e.invincible_finished = max(0, e.invincible_finished - time);
else
e.superweapons_finished += time;
- if (!(e.weapons & WepSet_FromWeapon(PS(e).m_switchweapon)))
- _switchweapon = true;
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(e.(weaponentity).m_weapon != WEP_Null || slot == 0)
+ if(!(e.weapons & WepSet_FromWeapon(e.(weaponentity).m_switchweapon)))
+ _switchweapon |= BIT(slot);
+ }
+
if(_switchweapon)
- W_SwitchWeapon_Force(e, w_getbestweapon(e));
+ {
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(_switchweapon & BIT(slot))
+ W_SwitchWeapon_Force(e, w_getbestweapon(e, weaponentity), weaponentity);
+ }
+ }
return got;
}
CLASS(Crylink, Weapon)
/* ammotype */ ATTRIB(Crylink, ammo_field, .int, ammo_cells);
/* impulse */ ATTRIB(Crylink, impulse, int, 6);
- /* flags */ ATTRIB(Crylink, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH);
+ /* flags */ ATTRIB(Crylink, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH | WEP_FLAG_CANCLIMB);
/* rating */ ATTRIB(Crylink, bot_pickupbasevalue, float, BOT_PICKUP_RATING_MID);
/* color */ ATTRIB(Crylink, wpcolor, vector, '1 0.5 1');
/* modelname */ ATTRIB(Crylink, mdl, string, "crylink");
void W_Crylink_Dequeue_Raw(entity own, entity prev, entity me, entity next)
{
W_Crylink_CheckLinks(next);
- if(me == own.crylink_lastgroup)
- own.crylink_lastgroup = ((me == next) ? NULL : next);
+ .entity weaponentity = me.weaponentity_fld;
+ if(me == own.(weaponentity).crylink_lastgroup)
+ own.(weaponentity).crylink_lastgroup = ((me == next) ? NULL : next);
prev.queuenext = next;
next.queueprev = prev;
me.classname = "spike_oktoremove";
a = bound(0, 1 - (time - e.fade_time) * e.fade_rate, 1);
- if(e == e.realowner.crylink_lastgroup)
- e.realowner.crylink_lastgroup = NULL;
+ .entity weaponentity = e.weaponentity_fld;
+ if(e == e.realowner.(weaponentity).crylink_lastgroup)
+ e.realowner.(weaponentity).crylink_lastgroup = NULL;
float isprimary = !(e.projectiledeathtype & HITTYPE_SECONDARY);
// is there at least 2 projectiles very close?
entity e, p;
float n;
- e = this.owner.crylink_lastgroup;
+ .entity weaponentity = this.weaponentity_fld;
+ e = this.owner.(weaponentity).crylink_lastgroup;
n = 0;
if(e)
{
if(totaldamage && ((WEP_CVAR_BOTH(crylink, isprimary, linkexplode) == 2) || ((WEP_CVAR_BOTH(crylink, isprimary, linkexplode) == 1) && !W_Crylink_Touch_WouldHitFriendly(this, WEP_CVAR_BOTH(crylink, isprimary, radius)))))
{
- if(this == this.realowner.crylink_lastgroup)
- this.realowner.crylink_lastgroup = NULL;
+ .entity weaponentity = this.weaponentity_fld;
+ if(this == this.realowner.(weaponentity).crylink_lastgroup)
+ this.realowner.(weaponentity).crylink_lastgroup = NULL;
W_Crylink_LinkExplode(this.queuenext, this, toucher);
this.classname = "spike_oktoremove";
delete(this);
vector forward, right, up;
float maxdmg;
- W_DecreaseAmmo(thiswep, actor, WEP_CVAR_PRI(crylink, ammo));
+ W_DecreaseAmmo(thiswep, actor, WEP_CVAR_PRI(crylink, ammo), weaponentity);
maxdmg = WEP_CVAR_PRI(crylink, damage) * WEP_CVAR_PRI(crylink, shots);
maxdmg *= 1 + WEP_CVAR_PRI(crylink, bouncedamagefactor) * WEP_CVAR_PRI(crylink, bounces);
proj = new(spike);
proj.reset = W_Crylink_Reset;
proj.realowner = proj.owner = actor;
+ proj.weaponentity_fld = weaponentity;
proj.bot_dodge = true;
proj.bot_dodgerating = WEP_CVAR_PRI(crylink, damage);
if(shots == 1) {
}
if(WEP_CVAR_PRI(crylink, joinspread) != 0)
{
- actor.crylink_lastgroup = proj;
+ actor.(weaponentity).crylink_lastgroup = proj;
W_Crylink_CheckLinks(proj);
- actor.crylink_waitrelease = 1;
+ actor.(weaponentity).crylink_waitrelease = 1;
}
}
vector forward, right, up;
float maxdmg;
- W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(crylink, ammo));
+ W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(crylink, ammo), weaponentity);
maxdmg = WEP_CVAR_SEC(crylink, damage) * WEP_CVAR_SEC(crylink, shots);
maxdmg *= 1 + WEP_CVAR_SEC(crylink, bouncedamagefactor) * WEP_CVAR_SEC(crylink, bounces);
for(counter = 0; counter < shots; ++counter)
{
proj = new(spike);
+ proj.weaponentity_fld = weaponentity;
proj.reset = W_Crylink_Reset;
proj.realowner = proj.owner = actor;
proj.bot_dodge = true;
}
if(WEP_CVAR_SEC(crylink, joinspread) != 0)
{
- actor.crylink_lastgroup = proj;
+ actor.(weaponentity).crylink_lastgroup = proj;
W_Crylink_CheckLinks(proj);
- actor.crylink_waitrelease = 2;
+ actor.(weaponentity).crylink_waitrelease = 2;
}
}
-METHOD(Crylink, wr_aim, void(entity thiswep, entity actor))
+METHOD(Crylink, wr_aim, void(entity thiswep, entity actor, .entity weaponentity))
{
if(random() < 0.10)
- PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, WEP_CVAR_PRI(crylink, speed), 0, WEP_CVAR_PRI(crylink, middle_lifetime), false);
+ PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, WEP_CVAR_PRI(crylink, speed), 0, WEP_CVAR_PRI(crylink, middle_lifetime), false);
else
- PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, WEP_CVAR_SEC(crylink, speed), 0, WEP_CVAR_SEC(crylink, middle_lifetime), false);
+ PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, weaponentity, WEP_CVAR_SEC(crylink, speed), 0, WEP_CVAR_SEC(crylink, middle_lifetime), false);
}
METHOD(Crylink, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
{
- if(autocvar_g_balance_crylink_reload_ammo && actor.clip_load < min(WEP_CVAR_PRI(crylink, ammo), WEP_CVAR_SEC(crylink, ammo))) { // forced reload
+ if(autocvar_g_balance_crylink_reload_ammo && actor.(weaponentity).clip_load < min(WEP_CVAR_PRI(crylink, ammo), WEP_CVAR_SEC(crylink, ammo))) { // forced reload
thiswep.wr_reload(thiswep, actor, weaponentity);
}
if(fire & 1)
{
- if(actor.crylink_waitrelease != 1)
+ if(actor.(weaponentity).crylink_waitrelease != 1)
if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(crylink, refire)))
{
W_Crylink_Attack(thiswep, actor, weaponentity);
if((fire & 2) && autocvar_g_balance_crylink_secondary)
{
- if(actor.crylink_waitrelease != 2)
+ if(actor.(weaponentity).crylink_waitrelease != 2)
if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(crylink, refire)))
{
W_Crylink_Attack2(thiswep, actor, weaponentity);
}
}
- if((actor.crylink_waitrelease == 1 && !(fire & 1)) || (actor.crylink_waitrelease == 2 && !(fire & 2)))
+ if((actor.(weaponentity).crylink_waitrelease == 1 && !(fire & 1)) || (actor.(weaponentity).crylink_waitrelease == 2 && !(fire & 2)))
{
- if(!actor.crylink_lastgroup || time > actor.crylink_lastgroup.teleport_time)
+ if(!actor.(weaponentity).crylink_lastgroup || time > actor.(weaponentity).crylink_lastgroup.teleport_time)
{
// fired and released now!
- if(actor.crylink_lastgroup)
+ if(actor.(weaponentity).crylink_lastgroup)
{
vector pos;
entity linkjoineffect;
- float isprimary = (actor.crylink_waitrelease == 1);
+ float isprimary = (actor.(weaponentity).crylink_waitrelease == 1);
- pos = W_Crylink_LinkJoin(actor.crylink_lastgroup, WEP_CVAR_BOTH(crylink, isprimary, joinspread) * WEP_CVAR_BOTH(crylink, isprimary, speed));
+ pos = W_Crylink_LinkJoin(actor.(weaponentity).crylink_lastgroup, WEP_CVAR_BOTH(crylink, isprimary, joinspread) * WEP_CVAR_BOTH(crylink, isprimary, speed));
linkjoineffect = new(linkjoineffect);
+ linkjoineffect.weaponentity_fld = weaponentity;
setthink(linkjoineffect, W_Crylink_LinkJoinEffect_Think);
linkjoineffect.nextthink = time + w_crylink_linkjoin_time;
linkjoineffect.owner = actor;
setorigin(linkjoineffect, pos);
}
- actor.crylink_waitrelease = 0;
- if(!thiswep.wr_checkammo1(thiswep, actor) && !thiswep.wr_checkammo2(thiswep, actor))
+ actor.(weaponentity).crylink_waitrelease = 0;
+ if(!thiswep.wr_checkammo1(thiswep, actor, weaponentity) && !thiswep.wr_checkammo2(thiswep, actor, weaponentity))
if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
{
// ran out of ammo!
actor.cnt = WEP_CRYLINK.m_id;
- PS(actor).m_switchweapon = w_getbestweapon(actor);
+ actor.(weaponentity).m_switchweapon = w_getbestweapon(actor, weaponentity);
}
}
}
}
-METHOD(Crylink, wr_checkammo1, bool(entity thiswep, entity actor))
+METHOD(Crylink, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity))
{
// don't "run out of ammo" and switch weapons while waiting for release
- if(actor.crylink_lastgroup && actor.crylink_waitrelease)
+ if(actor.(weaponentity).crylink_lastgroup && actor.(weaponentity).crylink_waitrelease)
return true;
float ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR_PRI(crylink, ammo);
- ammo_amount += actor.(weapon_load[WEP_CRYLINK.m_id]) >= WEP_CVAR_PRI(crylink, ammo);
+ ammo_amount += actor.(weaponentity).(weapon_load[WEP_CRYLINK.m_id]) >= WEP_CVAR_PRI(crylink, ammo);
return ammo_amount;
}
-METHOD(Crylink, wr_checkammo2, bool(entity thiswep, entity actor))
+METHOD(Crylink, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity))
{
// don't "run out of ammo" and switch weapons while waiting for release
- if(actor.crylink_lastgroup && actor.crylink_waitrelease)
+ if(actor.(weaponentity).crylink_lastgroup && actor.(weaponentity).crylink_waitrelease)
return true;
float ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR_SEC(crylink, ammo);
- ammo_amount += actor.(weapon_load[WEP_CRYLINK.m_id]) >= WEP_CVAR_SEC(crylink, ammo);
+ ammo_amount += actor.(weaponentity).(weapon_load[WEP_CRYLINK.m_id]) >= WEP_CVAR_SEC(crylink, ammo);
return ammo_amount;
}
METHOD(Crylink, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
#include "bot/api.qh"
#include "../common/ent_cs.qh"
+#include "../common/wepent.qh"
#include <common/state.qh>
#include <common/effects/qc/globalsound.qh>
if (e.race_completed) sf |= 1; // forced scoreboard
if (to.spectatee_status) sf |= 2; // spectator ent number follows
if (e.zoomstate) sf |= 4; // zoomed
- if (e.porto_v_angle_held) sf |= 8; // angles held
if (autocvar_sv_showspectators) sf |= 16; // show spectators
WriteHeader(MSG_ENTITY, ENT_CLIENT_CLIENTDATA);
{
WriteByte(MSG_ENTITY, to.spectatee_status);
}
- if (sf & 8)
- {
- WriteAngle(MSG_ENTITY, e.v_angle.x);
- WriteAngle(MSG_ENTITY, e.v_angle.y);
- }
if(sf & 16)
{
this.view_ofs = '0 0 0';
}
- RemoveGrapplingHook(this);
+ RemoveGrapplingHooks(this);
Portal_ClearAll(this);
Unfreeze(this);
SetSpectatee(this, NULL);
this.istypefrag = 0;
setthink(this, func_null);
this.nextthink = 0;
- this.hook_time = 0;
this.deadflag = DEAD_NO;
this.crouch = false;
this.revive_progress = 0;
this.weapons = '0 0 0';
this.drawonlytoclient = this;
- this.weaponname = "";
this.weaponmodel = "";
for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
{
this.oldvelocity = this.velocity;
this.fire_endtime = -1;
this.event_damage = func_null;
-
- STAT(ACTIVEWEAPON, this) = WEP_Null.m_id;
- STAT(SWITCHINGWEAPON, this) = WEP_Null.m_id;
- STAT(SWITCHWEAPON, this) = WEP_Null.m_id;
}
int player_getspecies(entity this)
for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
{
- CL_SpawnWeaponentity(this, weaponentities[slot]);
+ .entity weaponentity = weaponentities[slot];
+ CL_SpawnWeaponentity(this, weaponentity);
}
this.alpha = default_player_alpha;
this.colormod = '1 1 1' * autocvar_g_player_brightness;
it.wr_resetplayer(it, this);
// reload all reloadable weapons
if (it.spawnflags & WEP_FLAG_RELOADABLE) {
- this.weapon_load[it.m_id] = it.reloading_ammo;
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ this.(weaponentity).weapon_load[it.m_id] = it.reloading_ammo;
+ }
}
));
delete(spot); // usefull for checking if there are spawnpoints, that let drop through the floor
}
- PS(this).m_switchweapon = w_getbestweapon(this);
- this.cnt = -1; // W_LastWeapon will not complain
- PS(this).m_weapon = WEP_Null;
- this.weaponname = "";
- PS(this).m_switchingweapon = WEP_Null;
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(slot == 0)
+ this.(weaponentity).m_switchweapon = w_getbestweapon(this, weaponentity);
+ else
+ this.(weaponentity).m_switchweapon = WEP_Null;
+ this.(weaponentity).m_weapon = WEP_Null;
+ this.(weaponentity).weaponname = "";
+ this.(weaponentity).m_switchingweapon = WEP_Null;
+ this.(weaponentity).cnt = -1;
+ }
+ MUTATOR_CALLHOOK(PlayerWeaponSelect, this);
+
if (!warmup_stage && !this.alivetime)
this.alivetime = time;
Unfreeze(this);
- RemoveGrapplingHook(this);
+ RemoveGrapplingHooks(this);
// Here, everything has been done that requires this player to be a client.
setsize(this, spectatee.mins, spectatee.maxs);
SetZoomState(this, spectatee.zoomstate);
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ this.(weaponentity) = spectatee.(weaponentity);
+ }
+
anticheat_spectatecopy(this, spectatee);
this.hud = spectatee.hud;
if(spectatee.vehicle)
this.prevorigin = this.origin;
+ bool have_hook = false;
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(this.(weaponentity).hook.state)
+ {
+ have_hook = true;
+ break;
+ }
+ }
bool do_crouch = PHYS_INPUT_BUTTON_CROUCH(this);
- if (this.hook.state) {
+ if (have_hook) {
do_crouch = false;
} else if (this.waterlevel >= WATERLEVEL_SWIMMING) {
do_crouch = false;
{
this.items &= ~this.items_added;
- //for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
- //{
- //.entity weaponentity = weaponentities[slot];
- //W_WeaponFrame(this, weaponentity);
- //}
- .entity weaponentity = weaponentities[0]; // TODO
- W_WeaponFrame(this, weaponentity);
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ W_WeaponFrame(this, weaponentity);
+
+ if(slot == 0)
+ {
+ this.clip_load = this.(weaponentity).clip_load;
+ this.clip_size = this.(weaponentity).clip_size;
+ }
+ }
this.items_added = 0;
if (this.items & ITEM_Jetpack.m_itemid && (this.items & ITEM_JetpackRegen.m_itemid || this.ammo_fuel >= 0.01))
// WEAPONTODO: Add a weapon request for this
// rot vortex charge to the charge limit
- if (WEP_CVAR(vortex, charge_rot_rate) && this.vortex_charge > WEP_CVAR(vortex, charge_limit) && this.vortex_charge_rottime < time)
- this.vortex_charge = bound(WEP_CVAR(vortex, charge_limit), this.vortex_charge - WEP_CVAR(vortex, charge_rot_rate) * frametime / W_TICSPERFRAME, 1);
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if (WEP_CVAR(vortex, charge_rot_rate) && this.(weaponentity).vortex_charge > WEP_CVAR(vortex, charge_limit) && this.(weaponentity).vortex_charge_rottime < time)
+ this.(weaponentity).vortex_charge = bound(WEP_CVAR(vortex, charge_limit), this.(weaponentity).vortex_charge - WEP_CVAR(vortex, charge_rot_rate) * frametime / W_TICSPERFRAME, 1);
+ }
if (frametime) player_anim(this);
// WEAPONTODO: Add weapon request for this
if (!zoomstate_set) {
- SetZoomState(this,
- PHYS_INPUT_BUTTON_ZOOM(this) || PHYS_INPUT_BUTTON_ZOOMSCRIPT(this)
- || (PHYS_INPUT_BUTTON_ATCK2(this) && PS(this).m_weapon == WEP_VORTEX)
- || (PHYS_INPUT_BUTTON_ATCK2(this) && PS(this).m_weapon == WEP_RIFLE && WEP_CVAR(rifle, secondary) == 0)
- );
+ bool wep_zoomed = false;
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ Weapon thiswep = this.(weaponentity).m_weapon;
+ if(thiswep != WEP_Null && thiswep.wr_zoom)
+ wep_zoomed += thiswep.wr_zoom(thiswep, this);
+ }
+ SetZoomState(this, PHYS_INPUT_BUTTON_ZOOM(this) || PHYS_INPUT_BUTTON_ZOOMSCRIPT(this) || wep_zoomed);
}
if (this.teamkill_soundtime && time > this.teamkill_soundtime)
// WEAPONTODO: Move into weaponsystem somehow
// if a player goes unarmed after holding a loaded weapon, empty his clip size and remove the crosshair ammo ring
- if (PS(this).m_weapon == WEP_Null)
- this.clip_load = this.clip_size = 0;
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(this.(weaponentity).m_weapon == WEP_Null)
+ this.(weaponentity).clip_load = this.(weaponentity).clip_size = 0;
+ }
}
void DrownPlayer(entity this)
/**/
MUTATOR_HOOKABLE(PlayerSpawn, EV_PlayerSpawn);
+ /** called after a player's weapon is chosen so it can be overriden here */
+ #define EV_PlayerWeaponSelect(i, o) \
+ /** player spawning */ i(entity, MUTATOR_ARGV_0_entity) \
+ /**/
+ MUTATOR_HOOKABLE(PlayerWeaponSelect, EV_PlayerWeaponSelect);
+
/** called in reset_map */
#define EV_reset_map_global(i, o) \
/**/
/** returns true if throwing the current weapon shall not be allowed */
#define EV_ForbidThrowCurrentWeapon(i, o) \
/** player */ i(entity, MUTATOR_ARGV_0_entity) \
+ /** weapon entity */ i(entity, MUTATOR_ARGV_1_entity) \
/**/
MUTATOR_HOOKABLE(ForbidThrowCurrentWeapon, EV_ForbidThrowCurrentWeapon);
/** returns true if dropping the current weapon shall not be allowed at any time including death */
#define EV_ForbidDropCurrentWeapon(i, o) \
- /** player */ i(entity, MUTATOR_ARGV_0_entity) \
+ /** player */ i(entity, MUTATOR_ARGV_0_entity) \
+ /** weapon id */ i(int, MUTATOR_ARGV_1_int) \
/**/
MUTATOR_HOOKABLE(ForbidDropCurrentWeapon, EV_ForbidDropCurrentWeapon);
* Called by W_DecreaseAmmo
*/
#define EV_W_DecreaseAmmo(i, o) \
- /** actor */ i(entity, MUTATOR_ARGV_0_entity) \
+ /** actor */ i(entity, MUTATOR_ARGV_0_entity) \
+ /** weapon entity */ i(entity, MUTATOR_ARGV_1_entity) \
/**/
MUTATOR_HOOKABLE(W_DecreaseAmmo, EV_W_DecreaseAmmo);
#include "../common/effects/qc/all.qh"
#include "../common/mutators/mutator/waypoints/waypointsprites.qh"
#include "../common/triggers/include.qh"
+#include "../common/wepent.qh"
#include "weapons/weaponstats.qh"
}
if(sound_allowed(MSG_BROADCAST, attacker))
- if((this.health < 2 * WEP_CVAR_PRI(blaster, damage) * autocvar_g_balance_selfdamagepercent + 1) || !(DEATH_WEAPONOF(deathtype).spawnflags & WEP_FLAG_CANCLIMB) || attacker != this) // WEAPONTODO: create separate limit for pain notification with laser
+ if(this.health < 25 || !(DEATH_WEAPONOF(deathtype).spawnflags & WEP_FLAG_CANCLIMB) || take > 20 || attacker != this)
if(this.health > 1)
// exclude pain sounds for laserjumps as long as you aren't REALLY low on health and would die of the next two
{
valid_damage_for_weaponstats = 0;
Weapon awep = WEP_Null;
+ .entity weaponentity = weaponentities[0]; // TODO: unhardcode
if(vbot || IS_REAL_CLIENT(this))
if(abot || IS_REAL_CLIENT(attacker))
if(DIFF_TEAM(this, attacker))
{
if(DEATH_ISSPECIAL(deathtype))
- awep = PS(attacker).m_weapon;
+ awep = attacker.(weaponentity).m_weapon;
else
awep = DEATH_WEAPONOF(deathtype);
valid_damage_for_weaponstats = 1;
da = da - max(this.armorvalue, 0);
if(valid_damage_for_weaponstats)
{
- WeaponStats_LogDamage(awep.m_id, abot, PS(this).m_weapon.m_id, vbot, dh + da);
+ WeaponStats_LogDamage(awep.m_id, abot, this.(weaponentity).m_weapon.m_id, vbot, dh + da);
}
if (damage)
{
}
if(valid_damage_for_weaponstats)
- WeaponStats_LogKill(awep.m_id, abot, PS(this).m_weapon.m_id, vbot);
+ WeaponStats_LogKill(awep.m_id, abot, this.(weaponentity).m_weapon.m_id, vbot);
if(autocvar_sv_gentle < 1)
if(sound_allowed(MSG_BROADCAST, attacker))
MUTATOR_CALLHOOK(PlayerDies, inflictor, attacker, this, deathtype, damage);
excess = M_ARGV(4, float);
- Weapon wep = PS(this).m_weapon;
- /*for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ Weapon wep = this.(weaponentity).m_weapon;
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
{
- .entity weaponentity = weaponentities[slot];
- wep.wr_playerdeath(wep, this, weaponentity);
- }*/
- .entity weaponentity = weaponentities[0]; // TODO: unhardcode
- wep.wr_playerdeath(wep, this, weaponentity);
+ .entity went = weaponentities[slot];
+ wep.wr_playerdeath(wep, this, went);
+ }
- RemoveGrapplingHook(this);
+ RemoveGrapplingHooks(this);
Portal_ClearAllLater(this);
// clear waypoints
WaypointSprite_PlayerDead(this);
// throw a weapon
- SpawnThrownWeapon(this, this.origin + (this.mins + this.maxs) * 0.5, PS(this).m_switchweapon.m_id);
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity went = weaponentities[slot];
+ SpawnThrownWeapon(this, this.origin + (this.mins + this.maxs) * 0.5, this.(went).m_switchweapon.m_id, went);
+ }
// become fully visible
this.alpha = default_player_alpha;