From 733758fd5a2cdbb707b19bd9766524855f457656 Mon Sep 17 00:00:00 2001 From: TimePath Date: Wed, 28 Oct 2015 17:37:01 +1100 Subject: [PATCH] Weapons: add a second .weaponentity --- .../gamemodes/gamemode/nexball/nexball.qc | 39 ++-- qcsrc/common/monsters/monster/mage.qc | 20 +- qcsrc/common/monsters/monster/shambler.qc | 8 +- qcsrc/common/monsters/monster/spider.qc | 10 +- qcsrc/common/monsters/monster/wyvern.qc | 6 +- qcsrc/common/monsters/monster/zombie.qc | 4 +- qcsrc/common/monsters/sv_monsters.qc | 23 +- qcsrc/common/mutators/mutator/casings.qc | 3 +- qcsrc/common/triggers/func/door.qc | 9 +- qcsrc/common/triggers/func/door.qh | 3 +- qcsrc/common/triggers/func/door_secret.qc | 10 +- qcsrc/common/turrets/sv_turrets.qc | 8 +- qcsrc/common/turrets/turret/ewheel_weapon.qc | 4 +- qcsrc/common/turrets/turret/flac_weapon.qc | 4 +- qcsrc/common/turrets/turret/fusionreactor.qc | 2 +- qcsrc/common/turrets/turret/hellion_weapon.qc | 4 +- qcsrc/common/turrets/turret/hk_weapon.qc | 4 +- .../turrets/turret/machinegun_weapon.qc | 4 +- qcsrc/common/turrets/turret/mlrs_weapon.qc | 4 +- qcsrc/common/turrets/turret/phaser_weapon.qc | 12 +- qcsrc/common/turrets/turret/plasma_weapon.qc | 4 +- qcsrc/common/turrets/turret/tesla.qc | 2 +- qcsrc/common/turrets/turret/tesla_weapon.qc | 6 +- qcsrc/common/turrets/turret/walker.qc | 6 +- qcsrc/common/turrets/turret/walker_weapon.qc | 4 +- qcsrc/common/vehicles/vehicle/bumblebee.qc | 4 +- qcsrc/common/vehicles/vehicle/racer_weapon.qc | 8 +- .../common/vehicles/vehicle/raptor_weapons.qc | 12 +- qcsrc/common/vehicles/vehicle/spiderbot.qc | 6 +- .../vehicles/vehicle/spiderbot_weapons.qc | 6 +- qcsrc/common/weapons/weapon.qh | 2 + qcsrc/common/weapons/weapon/arc.qc | 16 +- qcsrc/common/weapons/weapon/blaster.qc | 8 +- qcsrc/common/weapons/weapon/crylink.qc | 8 +- qcsrc/common/weapons/weapon/devastator.qc | 20 +- qcsrc/common/weapons/weapon/electro.qc | 12 +- qcsrc/common/weapons/weapon/fireball.qc | 16 +- qcsrc/common/weapons/weapon/hagar.qc | 34 +-- qcsrc/common/weapons/weapon/hlac.qc | 14 +- qcsrc/common/weapons/weapon/hmg.qc | 6 +- qcsrc/common/weapons/weapon/hook.qc | 8 +- qcsrc/common/weapons/weapon/machinegun.qc | 36 ++-- qcsrc/common/weapons/weapon/minelayer.qc | 13 +- qcsrc/common/weapons/weapon/mortar.qc | 8 +- qcsrc/common/weapons/weapon/porto.qc | 12 +- qcsrc/common/weapons/weapon/rifle.qc | 30 +-- qcsrc/common/weapons/weapon/rpc.qc | 4 +- qcsrc/common/weapons/weapon/seeker.qc | 16 +- qcsrc/common/weapons/weapon/shockwave.qc | 10 +- qcsrc/common/weapons/weapon/shotgun.qc | 18 +- qcsrc/common/weapons/weapon/tuba.qc | 15 +- qcsrc/common/weapons/weapon/vaporizer.qc | 6 +- qcsrc/common/weapons/weapon/vortex.qc | 8 +- qcsrc/server/bot/havocbot/havocbot.qc | 2 +- qcsrc/server/bot/scripting.qc | 12 +- qcsrc/server/cheats.qc | 5 +- qcsrc/server/cl_client.qc | 13 +- qcsrc/server/cl_player.qc | 16 +- qcsrc/server/command/sv_cmd.qc | 6 +- qcsrc/server/defs.qh | 14 +- qcsrc/server/g_world.qc | 11 +- .../server/mutators/mutator/mutator_nades.qc | 3 +- .../mutators/mutator/mutator_overkill.qc | 5 +- qcsrc/server/weapons/throwing.qc | 3 +- qcsrc/server/weapons/tracing.qc | 5 +- qcsrc/server/weapons/weaponsystem.qc | 196 +++++++++--------- qcsrc/server/weapons/weaponsystem.qh | 10 +- 67 files changed, 454 insertions(+), 406 deletions(-) diff --git a/qcsrc/common/gamemodes/gamemode/nexball/nexball.qc b/qcsrc/common/gamemodes/gamemode/nexball/nexball.qc index 5f07c100c..72873b3eb 100644 --- a/qcsrc/common/gamemodes/gamemode/nexball/nexball.qc +++ b/qcsrc/common/gamemodes/gamemode/nexball/nexball.qc @@ -132,16 +132,16 @@ void DropOwner(void) void GiveBall(entity plyr, entity ball) {SELFPARAM(); - entity ownr; - - if((ownr = ball.owner)) + int slot = 0; // TODO: find ballstealer + entity ownr = ball.owner; + if(ownr) { ownr.effects &= ~autocvar_g_nexball_basketball_effects_default; ownr.ballcarried = world; if(ownr.metertime) { ownr.metertime = 0; - ownr.weaponentity.state = WS_READY; + ownr.weaponentity[slot].state = WS_READY; } WaypointSprite_Kill(ownr.waypointsprite_attachedforcarrier); } @@ -179,8 +179,8 @@ void GiveBall(entity plyr, entity ball) ball.nextthink = time + autocvar_g_nexball_basketball_delay_hold; } - plyr.weaponentity.weapons = plyr.weapons; - plyr.weaponentity.switchweapon = plyr.weapon; + plyr.weaponentity[slot].weapons = plyr.weapons; + plyr.weaponentity[slot].switchweapon = plyr.weapon; plyr.weapons = WEPSET(NEXBALL); setself(plyr); Weapon w = WEP_NEXBALL; @@ -210,7 +210,8 @@ void DropBall(entity ball, vector org, vector vel) if(ball.owner.metertime) { ball.owner.metertime = 0; - ball.owner.weaponentity.state = WS_READY; + int slot = 0; // TODO: find ballstealer + ball.owner.weaponentity[slot].state = WS_READY; } WaypointSprite_Kill(ball.owner.waypointsprite_attachedforcarrier); @@ -857,31 +858,31 @@ float ball_customize() METHOD(BallStealer, wr_think, void(BallStealer thiswep, entity actor, int slot, int fire)) { if(fire & 1) - if(weapon_prepareattack(thiswep, actor, false, autocvar_g_balance_nexball_primary_refire)) + if(weapon_prepareattack(thiswep, actor, slot, false, autocvar_g_balance_nexball_primary_refire)) if(autocvar_g_nexball_basketball_meter) { if(self.ballcarried && !self.metertime) self.metertime = time; else - weapon_thinkf(actor, WFRAME_FIRE1, autocvar_g_balance_nexball_primary_animtime, w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, autocvar_g_balance_nexball_primary_animtime, w_ready); } else { W_Nexball_Attack(-1); - weapon_thinkf(actor, WFRAME_FIRE1, autocvar_g_balance_nexball_primary_animtime, w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, autocvar_g_balance_nexball_primary_animtime, w_ready); } if(fire & 2) - if(weapon_prepareattack(thiswep, actor, true, autocvar_g_balance_nexball_secondary_refire)) + if(weapon_prepareattack(thiswep, actor, slot, true, autocvar_g_balance_nexball_secondary_refire)) { W_Nexball_Attack2(); - weapon_thinkf(actor, WFRAME_FIRE2, autocvar_g_balance_nexball_secondary_animtime, w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE2, autocvar_g_balance_nexball_secondary_animtime, w_ready); } if(!(fire & 1) && self.metertime && self.ballcarried) { W_Nexball_Attack(time - self.metertime); // DropBall or stealing will set metertime back to 0 - weapon_thinkf(actor, WFRAME_FIRE1, autocvar_g_balance_nexball_primary_animtime, w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, autocvar_g_balance_nexball_primary_animtime, w_ready); } } METHOD(BallStealer, wr_setup, void(BallStealer thiswep)) @@ -967,15 +968,16 @@ MUTATOR_HOOKFUNCTION(nb, PlayerPreThink) } else { - if(self.weaponentity.weapons) + int slot = 0; // TODO + if(self.weaponentity[slot].weapons) { - self.weapons = self.weaponentity.weapons; + self.weapons = self.weaponentity[slot].weapons; Weapon w = WEP_NEXBALL; w.wr_resetplayer(w); - self.switchweapon = self.weaponentity.switchweapon; + self.switchweapon = self.weaponentity[slot].switchweapon; W_SwitchWeapon(self.switchweapon); - self.weaponentity.weapons = '0 0 0'; + self.weaponentity[slot].weapons = '0 0 0'; } } @@ -996,7 +998,8 @@ MUTATOR_HOOKFUNCTION(nb, PlayerSpawn) { SELFPARAM(); this.metertime = 0; - this.weaponentity.weapons = '0 0 0'; + int slot = 0; + this.weaponentity[slot].weapons = '0 0 0'; if (nexball_mode & NBM_BASKETBALL) this.weapons |= WEPSET(NEXBALL); diff --git a/qcsrc/common/monsters/monster/mage.qc b/qcsrc/common/monsters/monster/mage.qc index f38bd7912..b63c0f73e 100644 --- a/qcsrc/common/monsters/monster/mage.qc +++ b/qcsrc/common/monsters/monster/mage.qc @@ -43,18 +43,18 @@ void M_Mage_Attack_Spike(vector dir); void M_Mage_Attack_Push(); METHOD(MageSpike, wr_think, void(MageSpike thiswep, entity actor, int slot, int fire)) { if (fire & 1) - if (!IS_PLAYER(actor) || weapon_prepareattack(thiswep, actor, false, 0.2)) { + if (!IS_PLAYER(actor) || weapon_prepareattack(thiswep, actor, slot, false, 0.2)) { if (!actor.target_range) actor.target_range = autocvar_g_monsters_target_range; actor.enemy = Monster_FindTarget(actor); W_SetupShot_Dir(actor, v_forward, false, 0, W_Sound("electro_fire"), CH_WEAPON_B, 0); if (!IS_PLAYER(actor)) w_shotdir = normalize((actor.enemy.origin + '0 0 10') - actor.origin); M_Mage_Attack_Spike(w_shotdir); - weapon_thinkf(actor, WFRAME_FIRE1, 0, w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, 0, w_ready); } if (fire & 2) - if (!IS_PLAYER(actor) || weapon_prepareattack(thiswep, actor, true, 0.5)) { + if (!IS_PLAYER(actor) || weapon_prepareattack(thiswep, actor, slot, true, 0.5)) { M_Mage_Attack_Push(); - weapon_thinkf(actor, WFRAME_FIRE2, 0, w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE2, 0, w_ready); } } @@ -297,7 +297,7 @@ void M_Mage_Defend_Heal() if(washealed) { setanim(self, self.anim_shoot, true, true, true); - self.attack_finished_single = time + (autocvar_g_monster_mage_heal_delay); + self.attack_finished_single[0] = time + (autocvar_g_monster_mage_heal_delay); self.anim_finished = time + 1.5; } } @@ -309,7 +309,7 @@ void M_Mage_Attack_Push() Send_Effect(EFFECT_TE_EXPLOSION, self.origin, '0 0 0', 1); setanim(self, self.anim_shoot, true, true, true); - self.attack_finished_single = time + (autocvar_g_monster_mage_attack_push_delay); + self.attack_finished_single[0] = time + (autocvar_g_monster_mage_attack_push_delay); } void M_Mage_Attack_Teleport() @@ -334,7 +334,7 @@ void M_Mage_Attack_Teleport() self.fixangle = true; self.velocity *= 0.5; - self.attack_finished_single = time + 0.2; + self.attack_finished_single[0] = time + 0.2; } void M_Mage_Defend_Shield_Remove() @@ -350,7 +350,7 @@ void M_Mage_Defend_Shield() self.armorvalue = (autocvar_g_monster_mage_shield_blockpercent); self.mage_shield_time = time + (autocvar_g_monster_mage_shield_time); setanim(self, self.anim_shoot, true, true, true); - self.attack_finished_single = time + 1; + self.attack_finished_single[0] = time + 1; self.anim_finished = time + 1; } @@ -382,7 +382,7 @@ float M_Mage_Attack(float attack_type, entity targ) else { setanim(self, self.anim_shoot, true, true, true); - self.attack_finished_single = time + (autocvar_g_monster_mage_attack_spike_delay); + self.attack_finished_single[0] = time + (autocvar_g_monster_mage_attack_spike_delay); self.anim_finished = time + 1; Weapon wep = WEP_MAGE_SPIKE; wep.wr_think(wep, self, 0, 1); @@ -421,7 +421,7 @@ spawnfunc(monster_mage) { Monster_Spawn(MON_MAGE.monsterid); } } if(self.health < (autocvar_g_monster_mage_heal_minhealth) || need_help) - if(time >= self.attack_finished_single) + if(time >= self.attack_finished_single[0]) if(random() < 0.5) M_Mage_Defend_Heal(); diff --git a/qcsrc/common/monsters/monster/shambler.qc b/qcsrc/common/monsters/monster/shambler.qc index 203b597cc..1a1fb450c 100644 --- a/qcsrc/common/monsters/monster/shambler.qc +++ b/qcsrc/common/monsters/monster/shambler.qc @@ -77,8 +77,8 @@ void M_Shambler_Attack_Swing() if(r && Monster_Attack_Melee(self.enemy, (autocvar_g_monster_shambler_attack_claw_damage), ((r) ? self.anim_melee2 : self.anim_melee3), self.attack_range, 0.8, DEATH_MONSTER_SHAMBLER_CLAW.m_id, true)) { Monster_Delay(1, 0, 0.5, M_Shambler_Attack_Swing); - self.attack_finished_single += 0.5; - self.anim_finished = self.attack_finished_single; + self.attack_finished_single[0] += 0.5; + self.anim_finished = self.attack_finished_single[0]; } } @@ -202,7 +202,7 @@ float M_Shambler_Attack(float attack_type, entity targ) { setanim(self, self.anim_melee2, true, true, false); Monster_Delay(1, 0, 0.7, M_Shambler_Attack_Smash); - self.attack_finished_single = time + 1.1; + self.attack_finished_single[0] = time + 1.1; self.anim_finished = time + 1.1; self.state = MONSTER_ATTACK_MELEE; // kinda a melee attack self.shambler_lastattack = time + 3 + random() * 1.5; @@ -212,7 +212,7 @@ float M_Shambler_Attack(float attack_type, entity targ) { setanim(self, self.anim_shoot, true, true, false); self.state = MONSTER_ATTACK_MELEE; // maybe we should rename this to something more general - self.attack_finished_single = time + 1.1; + self.attack_finished_single[0] = time + 1.1; self.anim_finished = 1.1; self.shambler_lastattack = time + 3 + random() * 1.5; Monster_Delay(1, 0, 0.6, M_Shambler_Attack_Lightning); diff --git a/qcsrc/common/monsters/monster/spider.qc b/qcsrc/common/monsters/monster/spider.qc index 1aa1c6020..8f42ca7fa 100644 --- a/qcsrc/common/monsters/monster/spider.qc +++ b/qcsrc/common/monsters/monster/spider.qc @@ -53,28 +53,28 @@ void M_Spider_Attack_Web(); METHOD(SpiderAttack, wr_think, void(SpiderAttack thiswep, entity actor, int slot, int fire)) { bool isPlayer = IS_PLAYER(actor); if (fire & 1) - if ((!isPlayer && time >= actor.spider_web_delay) || weapon_prepareattack(thiswep, actor, false, autocvar_g_monster_spider_attack_web_delay)) { + if ((!isPlayer && time >= actor.spider_web_delay) || weapon_prepareattack(thiswep, actor, slot, false, autocvar_g_monster_spider_attack_web_delay)) { if (!isPlayer) { actor.spider_web_delay = time + 3; setanim(actor, actor.anim_shoot, true, true, true); - actor.attack_finished_single = time + (autocvar_g_monster_spider_attack_web_delay); + actor.attack_finished_single[0] = time + (autocvar_g_monster_spider_attack_web_delay); actor.anim_finished = time + 1; } if (isPlayer) actor.enemy = Monster_FindTarget(actor); W_SetupShot_Dir(actor, v_forward, false, 0, W_Sound("electro_fire"), CH_WEAPON_B, 0); if (!isPlayer) w_shotdir = normalize((actor.enemy.origin + '0 0 10') - actor.origin); M_Spider_Attack_Web(); - weapon_thinkf(actor, WFRAME_FIRE1, 0, w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, 0, w_ready); return; } if (fire & 2) - if (!isPlayer || weapon_prepareattack(thiswep, actor, true, 0.5)) { + if (!isPlayer || weapon_prepareattack(thiswep, actor, slot, true, 0.5)) { if (isPlayer) { actor.enemy = Monster_FindTarget(actor); actor.attack_range = 60; } Monster_Attack_Melee(actor.enemy, (autocvar_g_monster_spider_attack_bite_damage), ((random() > 0.5) ? self.anim_melee : self.anim_shoot), self.attack_range, (autocvar_g_monster_spider_attack_bite_delay), DEATH_MONSTER_SPIDER.m_id, true); - weapon_thinkf(actor, WFRAME_FIRE2, 0, w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE2, 0, w_ready); } } diff --git a/qcsrc/common/monsters/monster/wyvern.qc b/qcsrc/common/monsters/monster/wyvern.qc index e2d9f964c..611a5aa59 100644 --- a/qcsrc/common/monsters/monster/wyvern.qc +++ b/qcsrc/common/monsters/monster/wyvern.qc @@ -50,10 +50,10 @@ void M_Wyvern_Attack_Fireball_Touch(); METHOD(WyvernAttack, wr_think, void(WyvernAttack thiswep, entity actor, int slot, int fire)) { if (fire & 1) - if (time > actor.attack_finished_single || weapon_prepareattack(thiswep, actor, false, 1.2)) { + if (time > actor.attack_finished_single[0] || weapon_prepareattack(thiswep, actor, slot, false, 1.2)) { if (IS_PLAYER(actor)) W_SetupShot_Dir(actor, v_forward, false, 0, W_Sound("electro_fire"), CH_WEAPON_B, 0); if (IS_MONSTER(actor)) { - actor.attack_finished_single = time + 1.2; + actor.attack_finished_single[0] = time + 1.2; actor.anim_finished = time + 1.2; monster_makevectors(actor.enemy); } @@ -73,7 +73,7 @@ METHOD(WyvernAttack, wr_think, void(WyvernAttack thiswep, entity actor, int slot missile.touch = M_Wyvern_Attack_Fireball_Touch; CSQCProjectile(missile, true, PROJECTILE_FIREMINE, true); - weapon_thinkf(actor, WFRAME_FIRE1, 0, w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, 0, w_ready); } } diff --git a/qcsrc/common/monsters/monster/zombie.qc b/qcsrc/common/monsters/monster/zombie.qc index e68b7ff54..b4389231c 100644 --- a/qcsrc/common/monsters/monster/zombie.qc +++ b/qcsrc/common/monsters/monster/zombie.qc @@ -111,8 +111,8 @@ float M_Zombie_Defend_Block() {SELFPARAM(); self.armorvalue = 0.9; self.state = MONSTER_ATTACK_MELEE; // freeze monster - self.attack_finished_single = time + 2.1; - self.anim_finished = self.attack_finished_single; + self.attack_finished_single[0] = time + 2.1; + self.anim_finished = self.attack_finished_single[0]; setanim(self, self.anim_blockstart, false, true, true); Monster_Delay(1, 0, 2, M_Zombie_Defend_Block_End); diff --git a/qcsrc/common/monsters/sv_monsters.qc b/qcsrc/common/monsters/sv_monsters.qc index ac642fd3c..f8294e3f5 100644 --- a/qcsrc/common/monsters/sv_monsters.qc +++ b/qcsrc/common/monsters/sv_monsters.qc @@ -364,9 +364,9 @@ float Monster_Attack_Melee(entity targ, float damg, vector anim, float er, float setanim(self, anim, false, true, false); if(self.animstate_endtime > time && (self.flags & FL_MONSTER)) - self.attack_finished_single = self.anim_finished = self.animstate_endtime; + self.attack_finished_single[0] = self.anim_finished = self.animstate_endtime; else - self.attack_finished_single = self.anim_finished = time + animtime; + self.attack_finished_single[0] = self.anim_finished = time + animtime; monster_makevectors(targ); @@ -386,7 +386,7 @@ float Monster_Attack_Leap_Check(vector vel) return false; // not on the ground if(self.health <= 0) return false; // called when dead? - if(time < self.attack_finished_single) + if(time < self.attack_finished_single[0]) return false; // still attacking vector old = self.velocity; @@ -408,9 +408,9 @@ bool Monster_Attack_Leap(vector anm, void() touchfunc, vector vel, float animtim setanim(self, anm, false, true, false); if(self.animstate_endtime > time && (self.flags & FL_MONSTER)) - self.attack_finished_single = self.anim_finished = self.animstate_endtime; + self.attack_finished_single[0] = self.anim_finished = self.animstate_endtime; else - self.attack_finished_single = self.anim_finished = time + animtime; + self.attack_finished_single[0] = self.anim_finished = time + animtime; if(self.flags & FL_MONSTER) self.state = MONSTER_ATTACK_RANGED; @@ -426,7 +426,7 @@ void Monster_Attack_Check(entity e, entity targ) { if((e == world || targ == world) || (!e.monster_attackfunc) - || (time < e.attack_finished_single) + || (time < e.attack_finished_single[0]) ) { return; } float targ_vlen = vlen(targ.origin - e.origin); @@ -845,7 +845,7 @@ void Monster_Move(float runspeed, float walkspeed, float stpspeed) self.touch = Monster_Touch; } - if(self.state && time >= self.attack_finished_single) + if(self.state && time >= self.attack_finished_single[0]) self.state = 0; // attack is over if(self.state != MONSTER_ATTACK_MELEE) // don't move if set @@ -911,12 +911,13 @@ void Monster_Move(float runspeed, float walkspeed, float stpspeed) void Monster_Remove(entity mon) { + int slot = 0; if(!mon) { return; } if(!MUTATOR_CALLHOOK(MonsterRemove, mon)) Send_Effect(EFFECT_ITEM_PICKUP, mon.origin, '0 0 0', 1); - if(mon.weaponentity) { remove(mon.weaponentity); } + if(mon.weaponentity[slot]) { remove(mon.weaponentity[slot]); } if(mon.iceblock) { remove(mon.iceblock); } WaypointSprite_Kill(mon.sprite); remove(mon); @@ -966,7 +967,7 @@ void Monster_Reset() self.velocity = '0 0 0'; self.enemy = world; self.goalentity = world; - self.attack_finished_single = 0; + self.attack_finished_single[0] = 0; self.moveto = self.origin; } @@ -1028,7 +1029,7 @@ void Monster_Dead(entity attacker, float gibbed) self.touch = Monster_Touch; // reset incase monster was pouncing self.reset = func_null; self.state = 0; - self.attack_finished_single = 0; + self.attack_finished_single[0] = 0; self.effects = 0; if(!((self.flags & FL_FLY) || (self.flags & FL_SWIM))) @@ -1176,7 +1177,7 @@ void Monster_Move_2D(float mspeed, float allow_jumpoff) movelib_move_simple_gravity(v_forward, mspeed, 1); if(time > self.pain_finished) - if(time > self.attack_finished_single) + if(time > self.attack_finished_single[0]) if(vlen(self.velocity) > 10) setanim(self, self.anim_walk, true, false, false); else diff --git a/qcsrc/common/mutators/mutator/casings.qc b/qcsrc/common/mutators/mutator/casings.qc index fe945c9ea..319ab8e77 100644 --- a/qcsrc/common/mutators/mutator/casings.qc +++ b/qcsrc/common/mutators/mutator/casings.qc @@ -12,7 +12,8 @@ REGISTER_MUTATOR(casings, true); #ifdef SVQC void SpawnCasing(vector vel, float randomvel, vector ang, vector avel, float randomavel, int casingtype, entity casingowner) {SELFPARAM(); - vector org = self.origin + self.view_ofs + self.weaponentity.spawnorigin.x * v_forward - self.weaponentity.spawnorigin.y * v_right + self.weaponentity.spawnorigin.z * v_up; + int slot = 0; // TODO: parameter + vector org = self.origin + self.view_ofs + self.weaponentity[slot].spawnorigin.x * v_forward - self.weaponentity[slot].spawnorigin.y * v_right + self.weaponentity[slot].spawnorigin.z * v_up; if (!sound_allowed(MSG_BROADCAST, casingowner)) casingtype |= 0x80; diff --git a/qcsrc/common/triggers/func/door.qc b/qcsrc/common/triggers/func/door.qc index 4ce3d261b..74b0e549f 100644 --- a/qcsrc/common/triggers/func/door.qc +++ b/qcsrc/common/triggers/func/door.qc @@ -293,6 +293,7 @@ void door_damage(entity inflictor, entity attacker, float damage, int deathtype, } } +.float door_finished; /* ================ @@ -306,10 +307,10 @@ void door_touch() {SELFPARAM(); if (!IS_PLAYER(other)) return; - if (self.owner.attack_finished_single > time) + if (self.owner.door_finished > time) return; - self.owner.attack_finished_single = time + 2; + self.owner.door_finished = time + 2; #ifdef SVQC if (!(self.owner.dmg) && (self.owner.message != "")) @@ -437,14 +438,14 @@ void door_trigger_touch() #endif return; - if (time < self.attack_finished_single) + if (time < self.door_finished) return; // check if door is locked if (!door_check_keys(self, other)) return; - self.attack_finished_single = time + 1; + self.door_finished = time + 1; activator = other; diff --git a/qcsrc/common/triggers/func/door.qh b/qcsrc/common/triggers/func/door.qh index adfc060e8..a765e2265 100644 --- a/qcsrc/common/triggers/func/door.qh +++ b/qcsrc/common/triggers/func/door.qh @@ -14,6 +14,5 @@ const int SPAWNFLAGS_SILVER_KEY = 16; // stuff for preload void ent_door(); -// abused -.float attack_finished_single; +.float door_finished; #endif diff --git a/qcsrc/common/triggers/func/door_secret.qc b/qcsrc/common/triggers/func/door_secret.qc index a0b70eceb..4d6b9b48a 100644 --- a/qcsrc/common/triggers/func/door_secret.qc +++ b/qcsrc/common/triggers/func/door_secret.qc @@ -133,11 +133,13 @@ void fd_secret_done() _sound(self, CH_TRIGGER_SINGLE, self.noise3, VOL_BASE, ATTEN_NORM); } +.float door_finished; + void secret_blocked() {SELFPARAM(); - if (time < self.attack_finished_single) + if (time < self.door_finished) return; - self.attack_finished_single = time + 0.5; + self.door_finished = time + 0.5; //T_Damage (other, self, self, self.dmg, self.dmg, self.deathtype, DT_IMPACT, (self.absmin + self.absmax) * 0.5, '0 0 0', Obituary_Generic); } @@ -152,10 +154,10 @@ void secret_touch() {SELFPARAM(); if (!other.iscreature) return; - if (self.attack_finished_single > time) + if (self.door_finished > time) return; - self.attack_finished_single = time + 2; + self.door_finished = time + 2; if (self.message) { diff --git a/qcsrc/common/turrets/sv_turrets.qc b/qcsrc/common/turrets/sv_turrets.qc index ec7ce3711..49bd505ed 100644 --- a/qcsrc/common/turrets/sv_turrets.qc +++ b/qcsrc/common/turrets/sv_turrets.qc @@ -13,7 +13,7 @@ vector turret_aim_generic() if(self.aim_flags & TFL_AIM_SIMPLE) return real_origin(self.enemy); - mintime = max(self.attack_finished_single - time,0) + sys_frametime; + mintime = max(self.attack_finished_single[0] - time,0) + sys_frametime; // Baseline pre_pos = real_origin(self.enemy); @@ -913,7 +913,7 @@ float turret_firecheck() // Ready? if (self.firecheck_flags & TFL_FIRECHECK_REFIRE) - if (self.attack_finished_single > time) return 0; + if (self.attack_finished_single[0] > time) return 0; // Special case: volly fire turret that has to fire a full volly if a shot was fired. if (self.shoot_flags & TFL_SHOOT_VOLLYALWAYS) @@ -996,7 +996,7 @@ void turret_fire() Turret info = get_turretinfo(self.m_id); info.tr_attack(info); - self.attack_finished_single = time + self.shot_refire; + self.attack_finished_single[0] = time + self.shot_refire; self.ammo -= self.shot_dmg; self.volly_counter = self.volly_counter - 1; @@ -1008,7 +1008,7 @@ void turret_fire() self.enemy = world; if (self.shot_volly > 1) - self.attack_finished_single = time + self.shot_volly_refire; + self.attack_finished_single[0] = time + self.shot_volly_refire; } #ifdef TURRET_DEBUG diff --git a/qcsrc/common/turrets/turret/ewheel_weapon.qc b/qcsrc/common/turrets/turret/ewheel_weapon.qc index eb90e253e..5239e2a44 100644 --- a/qcsrc/common/turrets/turret/ewheel_weapon.qc +++ b/qcsrc/common/turrets/turret/ewheel_weapon.qc @@ -19,14 +19,14 @@ void turret_initparams(entity); METHOD(EWheelAttack, wr_think, void(entity thiswep, entity actor, int slot, int fire)) { bool isPlayer = IS_PLAYER(actor); if (fire & 1) - if (!isPlayer || weapon_prepareattack(thiswep, actor, false, WEP_CVAR_PRI(electro, refire))) { + if (!isPlayer || weapon_prepareattack(thiswep, actor, slot, false, WEP_CVAR_PRI(electro, refire))) { if (isPlayer) { turret_initparams(actor); W_SetupShot_Dir(actor, v_forward, false, 0, W_Sound("electro_fire"), CH_WEAPON_B, 0); actor.tur_shotdir_updated = w_shotdir; actor.tur_shotorg = w_shotorg; actor.tur_head = actor; - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready); } turret_do_updates(actor); diff --git a/qcsrc/common/turrets/turret/flac_weapon.qc b/qcsrc/common/turrets/turret/flac_weapon.qc index 5c602e70e..32547d667 100644 --- a/qcsrc/common/turrets/turret/flac_weapon.qc +++ b/qcsrc/common/turrets/turret/flac_weapon.qc @@ -19,7 +19,7 @@ void turret_flac_projectile_think_explode(); METHOD(FlacAttack, wr_think, void(entity thiswep, entity actor, int slot, int fire)) { bool isPlayer = IS_PLAYER(actor); if (fire & 1) - if (!isPlayer || weapon_prepareattack(thiswep, actor, false, WEP_CVAR_PRI(electro, refire))) { + if (!isPlayer || weapon_prepareattack(thiswep, actor, slot, false, WEP_CVAR_PRI(electro, refire))) { if (isPlayer) { turret_initparams(actor); W_SetupShot_Dir(actor, v_forward, false, 0, W_Sound("electro_fire"), CH_WEAPON_B, 0); @@ -27,7 +27,7 @@ METHOD(FlacAttack, wr_think, void(entity thiswep, entity actor, int slot, int fi actor.tur_shotorg = w_shotorg; actor.tur_head = actor; actor.tur_impacttime = 10; - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready); } turret_tag_fire_update(); diff --git a/qcsrc/common/turrets/turret/fusionreactor.qc b/qcsrc/common/turrets/turret/fusionreactor.qc index 1077d5c63..3f51c06c3 100644 --- a/qcsrc/common/turrets/turret/fusionreactor.qc +++ b/qcsrc/common/turrets/turret/fusionreactor.qc @@ -19,7 +19,7 @@ REGISTER_TURRET(FUSIONREACTOR, NEW(FusionReactor)); #ifdef SVQC bool turret_fusionreactor_firecheck() {SELFPARAM(); - if (self.attack_finished_single > time) + if (self.attack_finished_single[0] > time) return false; if (self.enemy.deadflag != DEAD_NO) diff --git a/qcsrc/common/turrets/turret/hellion_weapon.qc b/qcsrc/common/turrets/turret/hellion_weapon.qc index 3f85f85ae..c97690dbd 100644 --- a/qcsrc/common/turrets/turret/hellion_weapon.qc +++ b/qcsrc/common/turrets/turret/hellion_weapon.qc @@ -22,7 +22,7 @@ void turret_hellion_missile_think(); METHOD(HellionAttack, wr_think, void(entity thiswep, entity actor, int slot, int fire)) { bool isPlayer = IS_PLAYER(actor); if (fire & 1) - if (!isPlayer || weapon_prepareattack(thiswep, actor, false, WEP_CVAR_PRI(electro, refire))) { + if (!isPlayer || weapon_prepareattack(thiswep, actor, slot, false, WEP_CVAR_PRI(electro, refire))) { if (isPlayer) { turret_initparams(actor); W_SetupShot_Dir(actor, v_forward, false, 0, W_Sound("electro_fire"), CH_WEAPON_B, 0); @@ -30,7 +30,7 @@ METHOD(HellionAttack, wr_think, void(entity thiswep, entity actor, int slot, int actor.tur_shotorg = w_shotorg; actor.tur_head = actor; actor.shot_radius = 500; - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready); } if (!isPlayer) { if (actor.tur_head.frame != 0) diff --git a/qcsrc/common/turrets/turret/hk_weapon.qc b/qcsrc/common/turrets/turret/hk_weapon.qc index 17d807130..2d03f9545 100644 --- a/qcsrc/common/turrets/turret/hk_weapon.qc +++ b/qcsrc/common/turrets/turret/hk_weapon.qc @@ -27,14 +27,14 @@ METHOD(HunterKillerAttack, wr_think, void(entity thiswep, entity actor, int slot { bool isPlayer = IS_PLAYER(actor); if (fire & 1) - if (!isPlayer || weapon_prepareattack(thiswep, actor, false, WEP_CVAR_PRI(electro, refire))) { + if (!isPlayer || weapon_prepareattack(thiswep, actor, slot, false, WEP_CVAR_PRI(electro, refire))) { if (isPlayer) { turret_initparams(actor); W_SetupShot_Dir(actor, v_forward, false, 0, W_Sound("electro_fire"), CH_WEAPON_B, 0); actor.tur_shotdir_updated = w_shotdir; actor.tur_shotorg = w_shotorg; actor.tur_head = actor; - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready); } entity missile = turret_projectile(SND(ROCKET_FIRE), 6, 10, DEATH_TURRET_HK.m_id, PROJECTILE_ROCKET, FALSE, FALSE); te_explosion (missile.origin); diff --git a/qcsrc/common/turrets/turret/machinegun_weapon.qc b/qcsrc/common/turrets/turret/machinegun_weapon.qc index ac0eae164..3ba43dc26 100644 --- a/qcsrc/common/turrets/turret/machinegun_weapon.qc +++ b/qcsrc/common/turrets/turret/machinegun_weapon.qc @@ -21,14 +21,14 @@ METHOD(MachineGunTurretAttack, wr_think, void(entity thiswep, entity actor, int { bool isPlayer = IS_PLAYER(actor); if (fire & 1) - if (!isPlayer || weapon_prepareattack(thiswep, actor, false, WEP_CVAR(machinegun, sustained_refire))) { + if (!isPlayer || weapon_prepareattack(thiswep, actor, slot, false, WEP_CVAR(machinegun, sustained_refire))) { if (isPlayer) { turret_initparams(actor); W_SetupShot_Dir(actor, v_forward, false, 0, W_Sound("electro_fire"), CH_WEAPON_B, 0); actor.tur_shotdir_updated = w_shotdir; actor.tur_shotorg = w_shotorg; actor.tur_head = actor; - weapon_thinkf(actor, WFRAME_FIRE1, 0, w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, 0, w_ready); } fireBullet (actor.tur_shotorg, actor.tur_shotdir_updated, actor.shot_spread, 0, actor.shot_dmg, actor.shot_force, DEATH_TURRET_MACHINEGUN.m_id, 0); W_MachineGun_MuzzleFlash(); diff --git a/qcsrc/common/turrets/turret/mlrs_weapon.qc b/qcsrc/common/turrets/turret/mlrs_weapon.qc index fa4b1fa6a..1ec121748 100644 --- a/qcsrc/common/turrets/turret/mlrs_weapon.qc +++ b/qcsrc/common/turrets/turret/mlrs_weapon.qc @@ -19,7 +19,7 @@ METHOD(MLRSTurretAttack, wr_think, void(entity thiswep, entity actor, int slot, { bool isPlayer = IS_PLAYER(actor); if (fire & 1) - if (!isPlayer || weapon_prepareattack(thiswep, actor, false, WEP_CVAR(machinegun, sustained_refire))) { + if (!isPlayer || weapon_prepareattack(thiswep, actor, slot, false, WEP_CVAR(machinegun, sustained_refire))) { if (isPlayer) { turret_initparams(actor); W_SetupShot_Dir(actor, v_forward, false, 0, W_Sound("electro_fire"), CH_WEAPON_B, 0); @@ -27,7 +27,7 @@ METHOD(MLRSTurretAttack, wr_think, void(entity thiswep, entity actor, int slot, actor.tur_shotorg = w_shotorg; actor.tur_head = actor; actor.shot_radius = 500; - weapon_thinkf(actor, WFRAME_FIRE1, 0, w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, 0, w_ready); } turret_tag_fire_update(); entity missile = turret_projectile(SND(ROCKET_FIRE), 6, 10, DEATH_TURRET_MLRS.m_id, PROJECTILE_ROCKET, TRUE, TRUE); diff --git a/qcsrc/common/turrets/turret/phaser_weapon.qc b/qcsrc/common/turrets/turret/phaser_weapon.qc index 8e746049b..9511d648c 100644 --- a/qcsrc/common/turrets/turret/phaser_weapon.qc +++ b/qcsrc/common/turrets/turret/phaser_weapon.qc @@ -22,7 +22,7 @@ METHOD(PhaserTurretAttack, wr_think, void(entity thiswep, entity actor, int slot { bool isPlayer = IS_PLAYER(actor); if (fire & 1) - if (!isPlayer || weapon_prepareattack(thiswep, actor, false, WEP_CVAR_PRI(electro, refire))) { + if (!isPlayer || weapon_prepareattack(thiswep, actor, slot, false, WEP_CVAR_PRI(electro, refire))) { if (isPlayer) { turret_initparams(actor); W_SetupShot_Dir(actor, v_forward, false, 0, W_Sound("electro_fire"), CH_WEAPON_B, 0); @@ -30,7 +30,7 @@ METHOD(PhaserTurretAttack, wr_think, void(entity thiswep, entity actor, int slot actor.tur_shotorg = w_shotorg; actor.tur_head = actor; actor.shot_speed = 1; - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready); } entity beam = spawn(); beam.ticrate = 0.1; //autocvar_sys_ticrate; @@ -51,8 +51,8 @@ METHOD(PhaserTurretAttack, wr_think, void(entity thiswep, entity actor, int slot sound (beam, CH_SHOTS_SINGLE, SND_TUR_PHASER, VOL_BASE, ATTEN_NORM); actor.fireflag = 1; - beam.attack_finished_single = actor.attack_finished_single; - actor.attack_finished_single = time; // + autocvar_sys_ticrate; + beam.attack_finished_single[0] = actor.attack_finished_single[0]; + actor.attack_finished_single[0] = time; // + autocvar_sys_ticrate; setattachment(beam,actor.tur_head, "tag_fire"); @@ -67,7 +67,7 @@ void beam_think() {SELFPARAM(); if ((time > self.cnt) || (self.owner.deadflag != DEAD_NO)) { - self.owner.attack_finished_single = time + self.owner.shot_refire; + self.owner.attack_finished_single[0] = time + self.owner.shot_refire; self.owner.fireflag = 2; self.owner.tur_head.frame = 10; sound (self, CH_SHOTS_SINGLE, SND_Null, VOL_BASE, ATTEN_NORM); @@ -86,7 +86,7 @@ void beam_think() self.nextthink = time + self.ticrate; - self.owner.attack_finished_single = time + frametime; + self.owner.attack_finished_single[0] = time + frametime; setself(self.owner); FireImoBeam ( self.tur_shotorg, self.tur_shotorg + self.tur_shotdir_updated * self.target_range, diff --git a/qcsrc/common/turrets/turret/plasma_weapon.qc b/qcsrc/common/turrets/turret/plasma_weapon.qc index 6b47f4015..41e0abb55 100644 --- a/qcsrc/common/turrets/turret/plasma_weapon.qc +++ b/qcsrc/common/turrets/turret/plasma_weapon.qc @@ -18,14 +18,14 @@ REGISTER_WEAPON(PLASMA, NEW(PlasmaAttack)); METHOD(PlasmaAttack, wr_think, void(entity thiswep, entity actor, int slot, int fire)) { bool isPlayer = IS_PLAYER(actor); if (fire & 1) - if (!isPlayer || weapon_prepareattack(thiswep, actor, false, WEP_CVAR_PRI(electro, refire))) { + if (!isPlayer || weapon_prepareattack(thiswep, actor, slot, false, WEP_CVAR_PRI(electro, refire))) { if (isPlayer) { turret_initparams(actor); W_SetupShot_Dir(actor, v_forward, false, 0, W_Sound("electro_fire"), CH_WEAPON_B, 0); actor.tur_shotdir_updated = w_shotdir; actor.tur_shotorg = w_shotorg; actor.tur_head = actor; - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready); } entity missile = turret_projectile(SND(HAGAR_FIRE), 1, 0, DEATH_TURRET_PLASMA.m_id, PROJECTILE_ELECTRO_BEAM, true, true); missile.missile_flags = MIF_SPLASH; diff --git a/qcsrc/common/turrets/turret/tesla.qc b/qcsrc/common/turrets/turret/tesla.qc index 3ae039c3c..16a9e423d 100644 --- a/qcsrc/common/turrets/turret/tesla.qc +++ b/qcsrc/common/turrets/turret/tesla.qc @@ -42,7 +42,7 @@ METHOD(TeslaCoil, tr_think, void(TeslaCoil thistur)) { self.tur_head.avelocity = '0 180 0' * (self.ammo / self.shot_dmg); - if(self.attack_finished_single > time) + if(self.attack_finished_single[0] > time) return; float f; diff --git a/qcsrc/common/turrets/turret/tesla_weapon.qc b/qcsrc/common/turrets/turret/tesla_weapon.qc index 61d3b0efc..63dc2fca6 100644 --- a/qcsrc/common/turrets/turret/tesla_weapon.qc +++ b/qcsrc/common/turrets/turret/tesla_weapon.qc @@ -19,14 +19,14 @@ entity toast(entity from, float range, float damage); METHOD(TeslaCoilTurretAttack, wr_think, void(entity thiswep, entity actor, int slot, int fire)) { bool isPlayer = IS_PLAYER(actor); if (fire & 1) - if (!isPlayer || weapon_prepareattack(thiswep, actor, false, WEP_CVAR_PRI(electro, refire))) { + if (!isPlayer || weapon_prepareattack(thiswep, actor, slot, false, WEP_CVAR_PRI(electro, refire))) { if (isPlayer) { turret_initparams(actor); W_SetupShot_Dir(actor, v_forward, false, 0, W_Sound("electro_fire"), CH_WEAPON_B, 0); actor.tur_shotdir_updated = w_shotdir; actor.tur_shotorg = w_shotorg; actor.tur_head = actor; - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready); } float d = actor.shot_dmg; @@ -43,7 +43,7 @@ METHOD(TeslaCoilTurretAttack, wr_think, void(entity thiswep, entity actor, int s actor.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES | TFL_TARGETSELECT_TEAMCHECK; - actor.attack_finished_single = time + actor.shot_refire; + actor.attack_finished_single[0] = time + actor.shot_refire; for (int i = 0; i < 10; ++i) { d *= 0.75; r *= 0.85; diff --git a/qcsrc/common/turrets/turret/walker.qc b/qcsrc/common/turrets/turret/walker.qc index cbdeb5e8e..43ac006ae 100644 --- a/qcsrc/common/turrets/turret/walker.qc +++ b/qcsrc/common/turrets/turret/walker.qc @@ -429,7 +429,7 @@ spawnfunc(turret_walker) { if(!turret_initialize(TUR_WALKER)) remove(self); } self.animflag = ANIM_MELEE; } } - else if (self.tur_head.attack_finished_single < time) + else if (self.tur_head.attack_finished_single[0] < time) { if(self.tur_head.shot_volly) { @@ -437,9 +437,9 @@ spawnfunc(turret_walker) { if(!turret_initialize(TUR_WALKER)) remove(self); } self.tur_head.shot_volly = self.tur_head.shot_volly -1; if(self.tur_head.shot_volly == 0) - self.tur_head.attack_finished_single = time + (autocvar_g_turrets_unit_walker_rocket_refire); + self.tur_head.attack_finished_single[0] = time + (autocvar_g_turrets_unit_walker_rocket_refire); else - self.tur_head.attack_finished_single = time + 0.2; + self.tur_head.attack_finished_single[0] = time + 0.2; if(self.tur_head.shot_volly > 1) walker_fire_rocket(gettaginfo(self, gettagindex(self, "tag_rocket01"))); diff --git a/qcsrc/common/turrets/turret/walker_weapon.qc b/qcsrc/common/turrets/turret/walker_weapon.qc index 266599791..be9e96b42 100644 --- a/qcsrc/common/turrets/turret/walker_weapon.qc +++ b/qcsrc/common/turrets/turret/walker_weapon.qc @@ -18,14 +18,14 @@ REGISTER_WEAPON(WALKER, NEW(WalkerTurretAttack)); METHOD(WalkerTurretAttack, wr_think, void(entity thiswep, entity actor, int slot, int fire)) { bool isPlayer = IS_PLAYER(actor); if (fire & 1) - if (!isPlayer || weapon_prepareattack(thiswep, actor, false, WEP_CVAR_PRI(electro, refire))) { + if (!isPlayer || weapon_prepareattack(thiswep, actor, slot, false, WEP_CVAR_PRI(electro, refire))) { if (isPlayer) { turret_initparams(actor); W_SetupShot_Dir(actor, v_forward, false, 0, W_Sound("electro_fire"), CH_WEAPON_B, 0); actor.tur_shotdir_updated = w_shotdir; actor.tur_shotorg = w_shotorg; actor.tur_head = actor; - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready); } sound (actor, CH_WEAPON_A, SND_UZI_FIRE, VOL_BASE, ATTEN_NORM); fireBullet (actor.tur_shotorg, actor.tur_shotdir_updated, actor.shot_spread, 0, actor.shot_dmg, actor.shot_force, DEATH_TURRET_WALK_GUN.m_id, 0); diff --git a/qcsrc/common/vehicles/vehicle/bumblebee.qc b/qcsrc/common/vehicles/vehicle/bumblebee.qc index 2eee4dcf5..6e9099a17 100644 --- a/qcsrc/common/vehicles/vehicle/bumblebee.qc +++ b/qcsrc/common/vehicles/vehicle/bumblebee.qc @@ -174,13 +174,13 @@ float bumblebee_gunner_frame() if(!forbidWeaponUse(gunner)) if(gunner.BUTTON_ATCK) - if(time > gun.attack_finished_single) + if(time > gun.attack_finished_single[0]) if(gun.vehicle_energy >= autocvar_g_vehicle_bumblebee_cannon_cost) { gun.vehicle_energy -= autocvar_g_vehicle_bumblebee_cannon_cost; bumblebee_fire_cannon(gun, "fire", gunner); gun.delay = time; - gun.attack_finished_single = time + autocvar_g_vehicle_bumblebee_cannon_refire; + gun.attack_finished_single[0] = time + autocvar_g_vehicle_bumblebee_cannon_refire; } VEHICLE_UPDATE_PLAYER(gunner, health, bumblebee); diff --git a/qcsrc/common/vehicles/vehicle/racer_weapon.qc b/qcsrc/common/vehicles/vehicle/racer_weapon.qc index 528078f8d..b5f0f4eaa 100644 --- a/qcsrc/common/vehicles/vehicle/racer_weapon.qc +++ b/qcsrc/common/vehicles/vehicle/racer_weapon.qc @@ -48,7 +48,7 @@ METHOD(RacerAttack, wr_think, void(entity thiswep, entity actor, int slot, int f entity player = isPlayer ? actor : actor.owner; entity veh = player.vehicle; if (fire & 1) - if (weapon_prepareattack(thiswep, player, false, autocvar_g_vehicle_racer_cannon_refire)) { + if (weapon_prepareattack(thiswep, player, slot, false, autocvar_g_vehicle_racer_cannon_refire)) { if (veh) { veh.vehicle_energy -= autocvar_g_vehicle_racer_cannon_cost; veh.wait = time; @@ -61,13 +61,13 @@ METHOD(RacerAttack, wr_think, void(entity thiswep, entity actor, int slot, int f autocvar_g_vehicle_racer_cannon_damage, autocvar_g_vehicle_racer_cannon_radius, autocvar_g_vehicle_racer_cannon_force, 0, DEATH_VH_WAKI_GUN.m_id, PROJECTILE_WAKICANNON, 0, true, true, player); bolt.velocity = normalize(dir) * autocvar_g_vehicle_racer_cannon_speed; - weapon_thinkf(player, WFRAME_FIRE1, 0, w_ready); + weapon_thinkf(player, slot, WFRAME_FIRE1, 0, w_ready); } if (fire & 2) - if (!isPlayer || weapon_prepareattack(thiswep, actor, false, 0.2)) { + if (!isPlayer || weapon_prepareattack(thiswep, actor, slot, false, 0.2)) { if (isPlayer) W_SetupShot_Dir(actor, v_forward, false, 0, SND(Null), CH_WEAPON_B, 0); racer_fire_rocket(w_shotorg, w_shotdir, NULL); - weapon_thinkf(actor, WFRAME_FIRE2, 0, w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE2, 0, w_ready); } } diff --git a/qcsrc/common/vehicles/vehicle/raptor_weapons.qc b/qcsrc/common/vehicles/vehicle/raptor_weapons.qc index d1d2dd1cb..d5e3fed06 100644 --- a/qcsrc/common/vehicles/vehicle/raptor_weapons.qc +++ b/qcsrc/common/vehicles/vehicle/raptor_weapons.qc @@ -58,7 +58,7 @@ METHOD(RaptorCannon, wr_think, void(entity thiswep, entity actor, int slot, int // 1 [wait] 1 [wait] 2 [wait] 2 [wait] [wait] float t = autocvar_g_vehicle_raptor_cannon_refire * (1 + veh.misc_bulletcounter == 4); if (fire & 1) - if (weapon_prepareattack(thiswep, player, false, t)) { + if (weapon_prepareattack(thiswep, player, slot, false, t)) { if (isPlayer) W_SetupShot_Dir(player, v_forward, false, 0, SND(Null), CH_WEAPON_B, 0); vector org = w_shotorg; vector dir = w_shotdir; @@ -74,7 +74,7 @@ METHOD(RaptorCannon, wr_think, void(entity thiswep, entity actor, int slot, int org, normalize(dir + randomvec() * autocvar_g_vehicle_raptor_cannon_spread) * autocvar_g_vehicle_raptor_cannon_speed, autocvar_g_vehicle_raptor_cannon_damage, autocvar_g_vehicle_raptor_cannon_radius, autocvar_g_vehicle_raptor_cannon_force, 0, DEATH_VH_RAPT_CANNON.m_id, PROJECTILE_RAPTORCANNON, 0, true, true, player); - weapon_thinkf(player, WFRAME_FIRE1, 0, w_ready); + weapon_thinkf(player, slot, WFRAME_FIRE1, 0, w_ready); } } METHOD(RaptorCannon, wr_checkammo1, bool(RacerAttack thiswep)) { @@ -93,10 +93,10 @@ METHOD(RaptorBomb, wr_think, void(entity thiswep, entity actor, int slot, int fi entity player = isPlayer ? actor : actor.owner; entity veh = player.vehicle; if (fire & 2) - if (!isPlayer || weapon_prepareattack(thiswep, player, true, autocvar_g_vehicle_raptor_bombs_refire)) { + if (!isPlayer || weapon_prepareattack(thiswep, player, slot, true, autocvar_g_vehicle_raptor_bombs_refire)) { if (veh) setself(veh); raptor_bombdrop(); - weapon_thinkf(player, WFRAME_FIRE2, 0, w_ready); + weapon_thinkf(player, slot, WFRAME_FIRE2, 0, w_ready); } } @@ -114,7 +114,7 @@ METHOD(RaptorFlare, wr_think, void(entity thiswep, entity actor, int slot, int f entity player = isPlayer ? actor : actor.owner; entity veh = player.vehicle; if (fire & 2) - if (!isPlayer || weapon_prepareattack(thiswep, player, true, autocvar_g_vehicle_raptor_flare_refire)) { + if (!isPlayer || weapon_prepareattack(thiswep, player, slot, true, autocvar_g_vehicle_raptor_flare_refire)) { for(int i = 0; i < 3; ++i) { entity _flare = spawn(); setmodel(_flare, MDL_VEH_RAPTOR_FLARE); @@ -134,7 +134,7 @@ METHOD(RaptorFlare, wr_think, void(entity thiswep, entity actor, int slot, int f _flare.tur_impacttime = time + autocvar_g_vehicle_raptor_flare_lifetime; _flare.touch = raptor_flare_touch; } - weapon_thinkf(player, WFRAME_FIRE2, 0, w_ready); + weapon_thinkf(player, slot, WFRAME_FIRE2, 0, w_ready); } } diff --git a/qcsrc/common/vehicles/vehicle/spiderbot.qc b/qcsrc/common/vehicles/vehicle/spiderbot.qc index 019f5889e..ec479fe9f 100644 --- a/qcsrc/common/vehicles/vehicle/spiderbot.qc +++ b/qcsrc/common/vehicles/vehicle/spiderbot.qc @@ -276,7 +276,7 @@ float spiderbot_frame() if(player.BUTTON_ATCK) { spider.cnt = time; - if(spider.vehicle_ammo1 >= autocvar_g_vehicle_spiderbot_minigun_ammo_cost && spider.tur_head.attack_finished_single <= time) + if(spider.vehicle_ammo1 >= autocvar_g_vehicle_spiderbot_minigun_ammo_cost && spider.tur_head.attack_finished_single[0] <= time) { entity gun; vector v; @@ -300,7 +300,7 @@ float spiderbot_frame() setself(spider); spider.vehicle_ammo1 -= autocvar_g_vehicle_spiderbot_minigun_ammo_cost; - spider.tur_head.attack_finished_single = time + autocvar_g_vehicle_spiderbot_minigun_refire; + spider.tur_head.attack_finished_single[0] = time + autocvar_g_vehicle_spiderbot_minigun_refire; player.vehicle_ammo1 = (spider.vehicle_ammo1 / autocvar_g_vehicle_spiderbot_minigun_ammo_max) * 100; spider.gun1.angles_z += 45; spider.gun2.angles_z -= 45; @@ -332,7 +332,7 @@ float spiderbot_frame() if(spider.gun2.cnt <= time) player.vehicle_reload2 = 100; else - player.vehicle_reload2 = 100 - ((spider.gun2.cnt - time) / spider.attack_finished_single) * 100; + player.vehicle_reload2 = 100 - ((spider.gun2.cnt - time) / spider.attack_finished_single[0]) * 100; setorigin(player, spider.origin + '0 0 1' * spider.maxs_z); player.velocity = spider.velocity; diff --git a/qcsrc/common/vehicles/vehicle/spiderbot_weapons.qc b/qcsrc/common/vehicles/vehicle/spiderbot_weapons.qc index 421a15a91..bccd8b0ae 100644 --- a/qcsrc/common/vehicles/vehicle/spiderbot_weapons.qc +++ b/qcsrc/common/vehicles/vehicle/spiderbot_weapons.qc @@ -271,11 +271,11 @@ void spiderbot_rocket_do() self.tur_head.frame += 1; if (self.tur_head.frame == 9) - self.attack_finished_single = autocvar_g_vehicle_spiderbot_rocket_reload; + self.attack_finished_single[0] = autocvar_g_vehicle_spiderbot_rocket_reload; else - self.attack_finished_single = ((self.vehicle_weapon2mode == SBRM_VOLLY) ? autocvar_g_vehicle_spiderbot_rocket_refire2 : autocvar_g_vehicle_spiderbot_rocket_refire); + self.attack_finished_single[0] = ((self.vehicle_weapon2mode == SBRM_VOLLY) ? autocvar_g_vehicle_spiderbot_rocket_refire2 : autocvar_g_vehicle_spiderbot_rocket_refire); - self.gun2.cnt = time + self.attack_finished_single; + self.gun2.cnt = time + self.attack_finished_single[0]; } #endif diff --git a/qcsrc/common/weapons/weapon.qh b/qcsrc/common/weapons/weapon.qh index 3643b18f8..3d7ae3bb5 100644 --- a/qcsrc/common/weapons/weapon.qh +++ b/qcsrc/common/weapons/weapon.qh @@ -1,6 +1,8 @@ #ifndef WEAPON_H #define WEAPON_H +const int MAX_WEAPONSLOTS = 2; + .int ammo_shells; .int ammo_nails; .int ammo_rockets; diff --git a/qcsrc/common/weapons/weapon/arc.qc b/qcsrc/common/weapons/weapon/arc.qc index 53359ee98..965827f3d 100644 --- a/qcsrc/common/weapons/weapon/arc.qc +++ b/qcsrc/common/weapons/weapon/arc.qc @@ -669,21 +669,21 @@ void Arc_Smoke() { #if 0 if(actor.animstate_startframe == actor.anim_shoot.x && actor.animstate_numframes == actor.anim_shoot.y) - weapon_thinkf(actor, WFRAME_DONTCHANGE, autocvar_g_balance_arc_primary_animtime, w_ready); + weapon_thinkf(actor, slot, WFRAME_DONTCHANGE, autocvar_g_balance_arc_primary_animtime, w_ready); else #endif - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR(arc, beam_animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR(arc, beam_animtime), w_ready); } if((!actor.arc_beam) || wasfreed(actor.arc_beam)) { - if(weapon_prepareattack(thiswep, actor, boolean(fire & 2), 0)) + if(weapon_prepareattack(thiswep, actor, slot, boolean(fire & 2), 0)) { W_Arc_Beam(boolean(fire & 2)); if(!actor.arc_BUTTON_ATCK_prev) { - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR(arc, beam_animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR(arc, beam_animtime), w_ready); actor.arc_BUTTON_ATCK_prev = true; } } @@ -695,18 +695,18 @@ void Arc_Smoke() if(actor.arc_BUTTON_ATCK_prev) { sound(actor, CH_WEAPON_A, SND_ARC_STOP, VOL_BASE, ATTN_NORM); - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR(arc, beam_animtime), w_ready); - ATTACK_FINISHED(actor) = time + WEP_CVAR(arc, beam_refire) * W_WeaponRateFactor(); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR(arc, beam_animtime), w_ready); + ATTACK_FINISHED(actor, slot) = time + WEP_CVAR(arc, beam_refire) * W_WeaponRateFactor(); } actor.arc_BUTTON_ATCK_prev = false; #if 0 if(fire & 2) - if(weapon_prepareattack(thiswep, actor, true, autocvar_g_balance_arc_secondary_refire)) + if(weapon_prepareattack(thiswep, actor, slot, true, autocvar_g_balance_arc_secondary_refire)) { W_Arc_Attack2(); actor.arc_count = autocvar_g_balance_arc_secondary_count; - weapon_thinkf(actor, WFRAME_FIRE2, autocvar_g_balance_arc_secondary_animtime, w_arc_checkattack); + weapon_thinkf(actor, slot, WFRAME_FIRE2, autocvar_g_balance_arc_secondary_animtime, w_arc_checkattack); actor.arc_secondarytime = time + autocvar_g_balance_arc_secondary_refire2 * W_WeaponRateFactor(); } #endif diff --git a/qcsrc/common/weapons/weapon/blaster.qc b/qcsrc/common/weapons/weapon/blaster.qc index 36b08287f..2aa8bbdd6 100644 --- a/qcsrc/common/weapons/weapon/blaster.qc +++ b/qcsrc/common/weapons/weapon/blaster.qc @@ -165,7 +165,7 @@ void W_Blaster_Attack( { if(fire & 1) { - if(weapon_prepareattack(thiswep, actor, false, WEP_CVAR_PRI(blaster, refire))) + if(weapon_prepareattack(thiswep, actor, slot, false, WEP_CVAR_PRI(blaster, refire))) { W_Blaster_Attack( actor, @@ -180,7 +180,7 @@ void W_Blaster_Attack( WEP_CVAR_PRI(blaster, delay), WEP_CVAR_PRI(blaster, lifetime) ); - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR_PRI(blaster, animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR_PRI(blaster, animtime), w_ready); } } else if(fire & 2) @@ -196,7 +196,7 @@ void W_Blaster_Attack( case 1: // normal projectile secondary { - if(weapon_prepareattack(thiswep, actor, true, WEP_CVAR_SEC(blaster, refire))) + if(weapon_prepareattack(thiswep, actor, slot, true, WEP_CVAR_SEC(blaster, refire))) { W_Blaster_Attack( actor, @@ -211,7 +211,7 @@ void W_Blaster_Attack( WEP_CVAR_SEC(blaster, delay), WEP_CVAR_SEC(blaster, lifetime) ); - weapon_thinkf(actor, WFRAME_FIRE2, WEP_CVAR_SEC(blaster, animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE2, WEP_CVAR_SEC(blaster, animtime), w_ready); } break; diff --git a/qcsrc/common/weapons/weapon/crylink.qc b/qcsrc/common/weapons/weapon/crylink.qc index 4b5454c12..083d7e0d0 100644 --- a/qcsrc/common/weapons/weapon/crylink.qc +++ b/qcsrc/common/weapons/weapon/crylink.qc @@ -584,20 +584,20 @@ void W_Crylink_Attack2(Weapon thiswep) if(fire & 1) { if(actor.crylink_waitrelease != 1) - if(weapon_prepareattack(thiswep, actor, false, WEP_CVAR_PRI(crylink, refire))) + if(weapon_prepareattack(thiswep, actor, slot, false, WEP_CVAR_PRI(crylink, refire))) { W_Crylink_Attack(thiswep); - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR_PRI(crylink, animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR_PRI(crylink, animtime), w_ready); } } if((fire & 2) && autocvar_g_balance_crylink_secondary) { if(actor.crylink_waitrelease != 2) - if(weapon_prepareattack(thiswep, actor, true, WEP_CVAR_SEC(crylink, refire))) + if(weapon_prepareattack(thiswep, actor, slot, true, WEP_CVAR_SEC(crylink, refire))) { W_Crylink_Attack2(thiswep); - weapon_thinkf(actor, WFRAME_FIRE2, WEP_CVAR_SEC(crylink, animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE2, WEP_CVAR_SEC(crylink, animtime), w_ready); } } diff --git a/qcsrc/common/weapons/weapon/devastator.qc b/qcsrc/common/weapons/weapon/devastator.qc index 9dd08bb3e..aba119875 100644 --- a/qcsrc/common/weapons/weapon/devastator.qc +++ b/qcsrc/common/weapons/weapon/devastator.qc @@ -111,14 +111,15 @@ void W_Devastator_Explode(void) if(!(self.realowner.items & IT_UNLIMITED_WEAPON_AMMO)) { self.realowner.cnt = WEP_DEVASTATOR.m_id; - ATTACK_FINISHED(self.realowner) = time; + int slot = 0; // TODO: unhardcode + ATTACK_FINISHED(self.realowner, slot) = time; self.realowner.switchweapon = w_getbestweapon(self.realowner); } } remove(self); } -void W_Devastator_DoRemoteExplode(void) +void W_Devastator_DoRemoteExplode(int slot) {SELFPARAM(); W_Devastator_Unregister(); @@ -190,14 +191,14 @@ void W_Devastator_DoRemoteExplode(void) if(!(self.realowner.items & IT_UNLIMITED_WEAPON_AMMO)) { self.realowner.cnt = WEP_DEVASTATOR.m_id; - ATTACK_FINISHED(self.realowner) = time; + ATTACK_FINISHED(self.realowner, slot) = time; self.realowner.switchweapon = w_getbestweapon(self.realowner); } } remove(self); } -void W_Devastator_RemoteExplode(void) +void W_Devastator_RemoteExplode(int slot) {SELFPARAM(); if(self.realowner.deadflag == DEAD_NO) if(self.realowner.lastrocket) @@ -207,7 +208,7 @@ void W_Devastator_RemoteExplode(void) : (vlen(NearestPointOnBox(self.realowner, self.origin) - self.origin) > WEP_CVAR(devastator, remote_radius)) // safety device ) { - W_Devastator_DoRemoteExplode(); + W_Devastator_DoRemoteExplode(slot); } } } @@ -304,8 +305,9 @@ void W_Devastator_Think(void) } } + int slot = 0; // TODO: unhardcode if(self.rl_detonate_later) - W_Devastator_RemoteExplode(); + W_Devastator_RemoteExplode(slot); } if(self.csqcprojectile_clientanimate == 0) @@ -529,10 +531,10 @@ void W_Devastator_Attack(Weapon thiswep) if(fire & 1) { if(actor.rl_release || WEP_CVAR(devastator, guidestop)) - if(weapon_prepareattack(thiswep, actor, false, WEP_CVAR(devastator, refire))) + if(weapon_prepareattack(thiswep, actor, slot, false, WEP_CVAR(devastator, refire))) { W_Devastator_Attack(thiswep); - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR(devastator, animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR(devastator, animtime), w_ready); actor.rl_release = 0; } } @@ -569,7 +571,7 @@ void W_Devastator_Attack(Weapon thiswep) { #if 0 // don't switch while guiding a missile - if(ATTACK_FINISHED(self) <= time || self.weapon != WEP_DEVASTATOR.m_id) + if(ATTACK_FINISHED(self, slot) <= time || self.weapon != WEP_DEVASTATOR.m_id) { ammo_amount = false; if(WEP_CVAR(devastator, reload_ammo)) diff --git a/qcsrc/common/weapons/weapon/electro.qc b/qcsrc/common/weapons/weapon/electro.qc index e353f05f1..63acee37a 100644 --- a/qcsrc/common/weapons/weapon/electro.qc +++ b/qcsrc/common/weapons/weapon/electro.qc @@ -410,11 +410,11 @@ void W_Electro_CheckAttack(Weapon thiswep, entity actor, int slot, int fire) {SELFPARAM(); if(self.electro_count > 1) if(self.BUTTON_ATCK2) - if(weapon_prepareattack(thiswep, actor, true, -1)) + if(weapon_prepareattack(thiswep, actor, slot, true, -1)) { W_Electro_Attack_Orb(WEP_ELECTRO); self.electro_count -= 1; - weapon_thinkf(actor, WFRAME_FIRE2, WEP_CVAR_SEC(electro, animtime), W_Electro_CheckAttack); + weapon_thinkf(actor, slot, WFRAME_FIRE2, WEP_CVAR_SEC(electro, animtime), W_Electro_CheckAttack); return; } // WEAPONTODO: when the player releases the button, cut down the length of refire2? @@ -471,20 +471,20 @@ void W_Electro_CheckAttack(Weapon thiswep, entity actor, int slot, int fire) if(fire & 1) { - if(weapon_prepareattack(thiswep, actor, false, WEP_CVAR_PRI(electro, refire))) + if(weapon_prepareattack(thiswep, actor, slot, false, WEP_CVAR_PRI(electro, refire))) { W_Electro_Attack_Bolt(thiswep); - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready); } } else if(fire & 2) { if(time >= actor.electro_secondarytime) - if(weapon_prepareattack(thiswep, actor, true, WEP_CVAR_SEC(electro, refire))) + if(weapon_prepareattack(thiswep, actor, slot, true, WEP_CVAR_SEC(electro, refire))) { W_Electro_Attack_Orb(thiswep); actor.electro_count = WEP_CVAR_SEC(electro, count); - weapon_thinkf(actor, WFRAME_FIRE2, WEP_CVAR_SEC(electro, animtime), W_Electro_CheckAttack); + weapon_thinkf(actor, slot, WFRAME_FIRE2, WEP_CVAR_SEC(electro, animtime), W_Electro_CheckAttack); actor.electro_secondarytime = time + WEP_CVAR_SEC(electro, refire2) * W_WeaponRateFactor(); } } diff --git a/qcsrc/common/weapons/weapon/fireball.qc b/qcsrc/common/weapons/weapon/fireball.qc index 7a7ff9dee..477aef833 100644 --- a/qcsrc/common/weapons/weapon/fireball.qc +++ b/qcsrc/common/weapons/weapon/fireball.qc @@ -229,32 +229,32 @@ void W_Fireball_AttackEffect(float i, vector f_diff) void W_Fireball_Attack1_Frame4(Weapon thiswep, entity actor, int slot, int fire) { W_Fireball_Attack1(); - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR_PRI(fireball, animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR_PRI(fireball, animtime), w_ready); } void W_Fireball_Attack1_Frame3(Weapon thiswep, entity actor, int slot, int fire) { W_Fireball_AttackEffect(0, '+1.25 +3.75 0'); - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR_PRI(fireball, animtime), W_Fireball_Attack1_Frame4); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR_PRI(fireball, animtime), W_Fireball_Attack1_Frame4); } void W_Fireball_Attack1_Frame2(Weapon thiswep, entity actor, int slot, int fire) { W_Fireball_AttackEffect(0, '-1.25 +3.75 0'); - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR_PRI(fireball, animtime), W_Fireball_Attack1_Frame3); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR_PRI(fireball, animtime), W_Fireball_Attack1_Frame3); } void W_Fireball_Attack1_Frame1(Weapon thiswep, entity actor, int slot, int fire) { W_Fireball_AttackEffect(1, '+1.25 -3.75 0'); - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR_PRI(fireball, animtime), W_Fireball_Attack1_Frame2); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR_PRI(fireball, animtime), W_Fireball_Attack1_Frame2); } void W_Fireball_Attack1_Frame0(Weapon thiswep, entity actor, int slot, int fire) {SELFPARAM(); W_Fireball_AttackEffect(0, '-1.25 -3.75 0'); sound(self, CH_WEAPON_SINGLE, SND_FIREBALL_PREFIRE2, VOL_BASE, ATTEN_NORM); - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR_PRI(fireball, animtime), W_Fireball_Attack1_Frame1); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR_PRI(fireball, animtime), W_Fireball_Attack1_Frame1); } void W_Fireball_Firemine_Think(void) @@ -376,7 +376,7 @@ void W_Fireball_Attack2(void) if(fire & 1) { if(time >= actor.fireball_primarytime) - if(weapon_prepareattack(thiswep, actor, false, WEP_CVAR_PRI(fireball, refire))) + if(weapon_prepareattack(thiswep, actor, slot, false, WEP_CVAR_PRI(fireball, refire))) { W_Fireball_Attack1_Frame0(thiswep, actor, slot, fire); actor.fireball_primarytime = time + WEP_CVAR_PRI(fireball, refire2) * W_WeaponRateFactor(); @@ -384,10 +384,10 @@ void W_Fireball_Attack2(void) } else if(fire & 2) { - if(weapon_prepareattack(thiswep, actor, true, WEP_CVAR_SEC(fireball, refire))) + if(weapon_prepareattack(thiswep, actor, slot, true, WEP_CVAR_SEC(fireball, refire))) { W_Fireball_Attack2(); - weapon_thinkf(actor, WFRAME_FIRE2, WEP_CVAR_SEC(fireball, animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE2, WEP_CVAR_SEC(fireball, animtime), w_ready); } } } diff --git a/qcsrc/common/weapons/weapon/hagar.qc b/qcsrc/common/weapons/weapon/hagar.qc index e1dcffe83..c9d1c520c 100644 --- a/qcsrc/common/weapons/weapon/hagar.qc +++ b/qcsrc/common/weapons/weapon/hagar.qc @@ -211,7 +211,7 @@ void W_Hagar_Attack2(Weapon thiswep) } .float hagar_loadstep, hagar_loadblock, hagar_loadbeep, hagar_warning; -void W_Hagar_Attack2_Load_Release(void) +void W_Hagar_Attack2_Load_Release(int slot) {SELFPARAM(); // time to release the rockets we've loaded @@ -223,7 +223,7 @@ void W_Hagar_Attack2_Load_Release(void) if(!self.hagar_load) return; - weapon_prepareattack_do(self, true, WEP_CVAR_SEC(hagar, refire)); + weapon_prepareattack_do(self, true, WEP_CVAR_SEC(hagar, refire), slot); W_SetupShot(self, false, 2, SND(HAGAR_FIRE), CH_WEAPON_A, WEP_CVAR_SEC(hagar, damage)); Send_Effect(EFFECT_HAGAR_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1); @@ -286,12 +286,12 @@ void W_Hagar_Attack2_Load_Release(void) MUTATOR_CALLHOOK(EditProjectile, self, missile); } - weapon_thinkf(self, WFRAME_FIRE2, WEP_CVAR_SEC(hagar, load_animtime), w_ready); + weapon_thinkf(self, slot, WFRAME_FIRE2, WEP_CVAR_SEC(hagar, load_animtime), w_ready); self.hagar_loadstep = time + WEP_CVAR_SEC(hagar, refire) * W_WeaponRateFactor(); self.hagar_load = 0; } -void W_Hagar_Attack2_Load(Weapon thiswep) +void W_Hagar_Attack2_Load(Weapon thiswep, int slot) {SELFPARAM(); // loadable hagar secondary attack, must always run each frame @@ -318,7 +318,7 @@ void W_Hagar_Attack2_Load(Weapon thiswep) if(self.hagar_load) { // if we pressed primary fire while loading, unload all rockets and abort - self.weaponentity.state = WS_READY; + self.weaponentity[slot].state = WS_READY; W_DecreaseAmmo(thiswep, self, WEP_CVAR_SEC(hagar, ammo) * self.hagar_load * -1); // give back ammo self.hagar_load = 0; sound(self, CH_WEAPON_A, SND_HAGAR_BEEP, VOL_BASE, ATTN_NORM); @@ -338,7 +338,7 @@ void W_Hagar_Attack2_Load(Weapon thiswep) if(!self.hagar_loadblock && self.hagar_loadstep < time) { W_DecreaseAmmo(thiswep, self, WEP_CVAR_SEC(hagar, ammo)); - self.weaponentity.state = WS_INUSE; + self.weaponentity[slot].state = WS_INUSE; self.hagar_load += 1; sound(self, CH_WEAPON_B, SND_HAGAR_LOAD, VOL_BASE * 0.8, ATTN_NORM); // sound is too loud according to most @@ -379,8 +379,8 @@ void W_Hagar_Attack2_Load(Weapon thiswep) // release if player let go of button or if they've held it in too long if(!self.BUTTON_ATCK2 || (stopped && self.hagar_loadstep < time && WEP_CVAR_SEC(hagar, load_hold) >= 0)) { - self.weaponentity.state = WS_READY; - W_Hagar_Attack2_Load_Release(); + self.weaponentity[slot].state = WS_READY; + W_Hagar_Attack2_Load_Release(slot); } } else @@ -413,24 +413,24 @@ void W_Hagar_Attack2_Load(Weapon thiswep) loadable_secondary = (WEP_CVAR_SEC(hagar, load) && WEP_CVAR(hagar, secondary)); if(loadable_secondary) - W_Hagar_Attack2_Load(thiswep); // must always run each frame + W_Hagar_Attack2_Load(thiswep, slot); // must always run each frame if(autocvar_g_balance_hagar_reload_ammo && actor.clip_load < min(WEP_CVAR_PRI(hagar, ammo), WEP_CVAR_SEC(hagar, ammo))) { // forced reload Weapon w = get_weaponinfo(actor.weapon); w.wr_reload(w); } else if((fire & 1) && !actor.hagar_load && !actor.hagar_loadblock) // not while secondary is loaded or awaiting reset { - if(weapon_prepareattack(thiswep, actor, false, WEP_CVAR_PRI(hagar, refire))) + if(weapon_prepareattack(thiswep, actor, slot, false, WEP_CVAR_PRI(hagar, refire))) { W_Hagar_Attack(thiswep); - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR_PRI(hagar, refire), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR_PRI(hagar, refire), w_ready); } } else if((fire & 2) && !loadable_secondary && WEP_CVAR(hagar, secondary)) { - if(weapon_prepareattack(thiswep, actor, true, WEP_CVAR_SEC(hagar, refire))) + if(weapon_prepareattack(thiswep, actor, slot, true, WEP_CVAR_SEC(hagar, refire))) { W_Hagar_Attack2(thiswep); - weapon_thinkf(actor, WFRAME_FIRE2, WEP_CVAR_SEC(hagar, refire), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE2, WEP_CVAR_SEC(hagar, refire), w_ready); } } } @@ -439,8 +439,9 @@ void W_Hagar_Attack2_Load(Weapon thiswep) // we lost the weapon and want to prepare switching away if(self.hagar_load) { - self.weaponentity.state = WS_READY; - W_Hagar_Attack2_Load_Release(); + int slot = 0; // TODO: unhardcode + self.weaponentity[slot].state = WS_READY; + W_Hagar_Attack2_Load_Release(slot); } } METHOD(Hagar, wr_init, void(entity thiswep)) @@ -479,9 +480,10 @@ void W_Hagar_Attack2_Load(Weapon thiswep) } METHOD(Hagar, wr_playerdeath, void(entity thiswep)) { + int slot = 0; // TODO: unhardcode // if we have any rockets loaded when we die, release them if(self.hagar_load && WEP_CVAR_SEC(hagar, load_releasedeath)) - W_Hagar_Attack2_Load_Release(); + W_Hagar_Attack2_Load_Release(slot); } METHOD(Hagar, wr_reload, void(entity thiswep)) { diff --git a/qcsrc/common/weapons/weapon/hlac.qc b/qcsrc/common/weapons/weapon/hlac.qc index ec95a988b..639847a7e 100644 --- a/qcsrc/common/weapons/weapon/hlac.qc +++ b/qcsrc/common/weapons/weapon/hlac.qc @@ -180,14 +180,14 @@ void W_HLAC_Attack_Frame(Weapon thiswep, entity actor, int slot, int fire) return; } - ATTACK_FINISHED(actor) = time + WEP_CVAR_PRI(hlac, refire) * W_WeaponRateFactor(); + ATTACK_FINISHED(actor, slot) = time + WEP_CVAR_PRI(hlac, refire) * W_WeaponRateFactor(); W_HLAC_Attack(WEP_HLAC); actor.misc_bulletcounter = actor.misc_bulletcounter + 1; - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR_PRI(hlac, refire), W_HLAC_Attack_Frame); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR_PRI(hlac, refire), W_HLAC_Attack_Frame); } else { - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR_PRI(hlac, animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR_PRI(hlac, animtime), w_ready); } } @@ -218,20 +218,20 @@ void W_HLAC_Attack2_Frame(Weapon thiswep) w.wr_reload(w); } else if(fire & 1) { - if(weapon_prepareattack(thiswep, actor, false, WEP_CVAR_PRI(hlac, refire))) + if(weapon_prepareattack(thiswep, actor, slot, false, WEP_CVAR_PRI(hlac, refire))) { actor.misc_bulletcounter = 0; W_HLAC_Attack(thiswep); - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR_PRI(hlac, refire), W_HLAC_Attack_Frame); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR_PRI(hlac, refire), W_HLAC_Attack_Frame); } } else if((fire & 2) && WEP_CVAR(hlac, secondary)) { - if(weapon_prepareattack(thiswep, actor, true, WEP_CVAR_SEC(hlac, refire))) + if(weapon_prepareattack(thiswep, actor, slot, true, WEP_CVAR_SEC(hlac, refire))) { W_HLAC_Attack2_Frame(thiswep); - weapon_thinkf(actor, WFRAME_FIRE2, WEP_CVAR_SEC(hlac, animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE2, WEP_CVAR_SEC(hlac, animtime), w_ready); } } } diff --git a/qcsrc/common/weapons/weapon/hmg.qc b/qcsrc/common/weapons/weapon/hmg.qc index 3a00de313..c420cf08b 100644 --- a/qcsrc/common/weapons/weapon/hmg.qc +++ b/qcsrc/common/weapons/weapon/hmg.qc @@ -85,8 +85,8 @@ void W_HeavyMachineGun_Attack_Auto(Weapon thiswep, entity actor, int slot, int f if (autocvar_g_casings >= 2) // casing code SpawnCasing (((random () * 50 + 50) * v_right) - (v_forward * (random () * 25 + 25)) - ((random () * 5 - 70) * v_up), 2, vectoangles(v_forward),'0 250 0', 100, 3, actor); - ATTACK_FINISHED(actor) = time + WEP_CVAR(hmg, refire) * W_WeaponRateFactor(); - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR(hmg, refire), W_HeavyMachineGun_Attack_Auto); + ATTACK_FINISHED(actor, slot) = time + WEP_CVAR(hmg, refire) * W_WeaponRateFactor(); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR(hmg, refire), W_HeavyMachineGun_Attack_Auto); } METHOD(HeavyMachineGun, wr_aim, void(entity thiswep)) @@ -104,7 +104,7 @@ void W_HeavyMachineGun_Attack_Auto(Weapon thiswep, entity actor, int slot, int f } else { if (fire & 1) - if (weapon_prepareattack(thiswep, actor, false, 0)) + if (weapon_prepareattack(thiswep, actor, slot, false, 0)) { actor.misc_bulletcounter = 0; W_HeavyMachineGun_Attack_Auto(thiswep, actor, slot, fire); diff --git a/qcsrc/common/weapons/weapon/hook.qc b/qcsrc/common/weapons/weapon/hook.qc index 93aa633b4..6dd821517 100644 --- a/qcsrc/common/weapons/weapon/hook.qc +++ b/qcsrc/common/weapons/weapon/hook.qc @@ -180,12 +180,12 @@ void W_Hook_Attack2(Weapon thiswep, entity actor) if(!actor.hook) if(!(actor.hook_state & HOOK_WAITING_FOR_RELEASE)) if(time > actor.hook_refire) - if(weapon_prepareattack(thiswep, actor, false, -1)) + if(weapon_prepareattack(thiswep, actor, slot, false, -1)) { W_DecreaseAmmo(thiswep, actor, thiswep.ammo_factor * WEP_CVAR_PRI(hook, ammo)); actor.hook_state |= HOOK_FIRING; actor.hook_state |= HOOK_WAITING_FOR_RELEASE; - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR_PRI(hook, animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR_PRI(hook, animtime), w_ready); } } else { actor.hook_state |= HOOK_REMOVING; @@ -194,10 +194,10 @@ void W_Hook_Attack2(Weapon thiswep, entity actor) if(fire & 2) { - if(weapon_prepareattack(thiswep, actor, true, WEP_CVAR_SEC(hook, refire))) + if(weapon_prepareattack(thiswep, actor, slot, true, WEP_CVAR_SEC(hook, refire))) { W_Hook_Attack2(thiswep, actor); - weapon_thinkf(actor, WFRAME_FIRE2, WEP_CVAR_SEC(hook, animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE2, WEP_CVAR_SEC(hook, animtime), w_ready); } } diff --git a/qcsrc/common/weapons/weapon/machinegun.qc b/qcsrc/common/weapons/weapon/machinegun.qc index 62287acb2..1d780d18e 100644 --- a/qcsrc/common/weapons/weapon/machinegun.qc +++ b/qcsrc/common/weapons/weapon/machinegun.qc @@ -104,7 +104,7 @@ void W_MachineGun_MuzzleFlash(void) self.muzzle_flash.owner = self.muzzle_flash.realowner = self; } -void W_MachineGun_Attack(Weapon thiswep, int deathtype) +void W_MachineGun_Attack(Weapon thiswep, int deathtype, int slot) {SELFPARAM(); W_SetupShot(self, true, 0, SND(UZI_FIRE), CH_WEAPON_A, ((self.misc_bulletcounter == 1) ? WEP_CVAR(machinegun, first_damage) : WEP_CVAR(machinegun, sustained_damage))); if(!autocvar_g_norecoil) @@ -114,7 +114,7 @@ void W_MachineGun_Attack(Weapon thiswep, int deathtype) } // this attack_finished just enforces a cooldown at the end of a burst - ATTACK_FINISHED(self) = time + WEP_CVAR(machinegun, first_refire) * W_WeaponRateFactor(); + ATTACK_FINISHED(self, slot) = time + WEP_CVAR(machinegun, first_refire) * W_WeaponRateFactor(); if(self.misc_bulletcounter == 1) fireBullet(w_shotorg, w_shotdir, WEP_CVAR(machinegun, first_spread), WEP_CVAR(machinegun, solidpenetration), WEP_CVAR(machinegun, first_damage), WEP_CVAR(machinegun, first_force), deathtype, 0); @@ -155,11 +155,11 @@ void W_MachineGun_Attack_Frame(Weapon thiswep, entity actor, int slot, int fire) return; } actor.misc_bulletcounter = actor.misc_bulletcounter + 1; - W_MachineGun_Attack(WEP_MACHINEGUN, WEP_MACHINEGUN.m_id); - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR(machinegun, sustained_refire), W_MachineGun_Attack_Frame); + W_MachineGun_Attack(WEP_MACHINEGUN, WEP_MACHINEGUN.m_id, slot); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR(machinegun, sustained_refire), W_MachineGun_Attack_Frame); } else - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR(machinegun, sustained_refire), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR(machinegun, sustained_refire), w_ready); } @@ -204,8 +204,8 @@ void W_MachineGun_Attack_Auto(Weapon thiswep, entity actor, int slot, int fire) if(autocvar_g_casings >= 2) // casing code SpawnCasing(((random() * 50 + 50) * v_right) - (v_forward * (random() * 25 + 25)) - ((random() * 5 - 70) * v_up), 2, vectoangles(v_forward),'0 250 0', 100, 3, actor); - ATTACK_FINISHED(actor) = time + WEP_CVAR(machinegun, first_refire) * W_WeaponRateFactor(); - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR(machinegun, sustained_refire), W_MachineGun_Attack_Auto); + ATTACK_FINISHED(actor, slot) = time + WEP_CVAR(machinegun, first_refire) * W_WeaponRateFactor(); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR(machinegun, sustained_refire), W_MachineGun_Attack_Auto); } void W_MachineGun_Attack_Burst(Weapon thiswep, entity actor, int slot, int fire) @@ -230,12 +230,12 @@ void W_MachineGun_Attack_Burst(Weapon thiswep, entity actor, int slot, int fire) actor.misc_bulletcounter = actor.misc_bulletcounter + 1; if(actor.misc_bulletcounter == 0) { - ATTACK_FINISHED(actor) = time + WEP_CVAR(machinegun, burst_refire2) * W_WeaponRateFactor(); - weapon_thinkf(actor, WFRAME_FIRE2, WEP_CVAR(machinegun, burst_animtime), w_ready); + ATTACK_FINISHED(actor, slot) = time + WEP_CVAR(machinegun, burst_refire2) * W_WeaponRateFactor(); + weapon_thinkf(actor, slot, WFRAME_FIRE2, WEP_CVAR(machinegun, burst_animtime), w_ready); } else { - weapon_thinkf(actor, WFRAME_FIRE2, WEP_CVAR(machinegun, burst_refire), W_MachineGun_Attack_Burst); + weapon_thinkf(actor, slot, WFRAME_FIRE2, WEP_CVAR(machinegun, burst_refire), W_MachineGun_Attack_Burst); } } @@ -256,14 +256,14 @@ void W_MachineGun_Attack_Burst(Weapon thiswep, entity actor, int slot, int fire) if(WEP_CVAR(machinegun, mode) == 1) { if(fire & 1) - if(weapon_prepareattack(thiswep, actor, false, 0)) + if(weapon_prepareattack(thiswep, actor, slot, false, 0)) { actor.misc_bulletcounter = 0; W_MachineGun_Attack_Auto(thiswep, actor, slot, fire); } if(fire & 2) - if(weapon_prepareattack(thiswep, actor, true, 0)) + if(weapon_prepareattack(thiswep, actor, slot, true, 0)) { Weapon w = get_weaponinfo(actor.weapon); if(!w.wr_checkammo2(w)) @@ -284,19 +284,19 @@ void W_MachineGun_Attack_Burst(Weapon thiswep, entity actor, int slot, int fire) { if(fire & 1) - if(weapon_prepareattack(thiswep, actor, false, 0)) + if(weapon_prepareattack(thiswep, actor, slot, false, 0)) { actor.misc_bulletcounter = 1; - W_MachineGun_Attack(WEP_MACHINEGUN, WEP_MACHINEGUN.m_id); // sets attack_finished - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR(machinegun, sustained_refire), W_MachineGun_Attack_Frame); + W_MachineGun_Attack(WEP_MACHINEGUN, WEP_MACHINEGUN.m_id, slot); // sets attack_finished + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR(machinegun, sustained_refire), W_MachineGun_Attack_Frame); } if((fire & 2) && WEP_CVAR(machinegun, first)) - if(weapon_prepareattack(thiswep, actor, true, 0)) + if(weapon_prepareattack(thiswep, actor, slot, true, 0)) { actor.misc_bulletcounter = 1; - W_MachineGun_Attack(WEP_MACHINEGUN, WEP_MACHINEGUN.m_id | HITTYPE_SECONDARY); // sets attack_finished - weapon_thinkf(actor, WFRAME_FIRE2, WEP_CVAR(machinegun, first_refire), w_ready); + W_MachineGun_Attack(WEP_MACHINEGUN, WEP_MACHINEGUN.m_id | HITTYPE_SECONDARY, slot); // sets attack_finished + weapon_thinkf(actor, slot, WFRAME_FIRE2, WEP_CVAR(machinegun, first_refire), w_ready); } } } diff --git a/qcsrc/common/weapons/weapon/minelayer.qc b/qcsrc/common/weapons/weapon/minelayer.qc index abed99b8d..fa12ace6a 100644 --- a/qcsrc/common/weapons/weapon/minelayer.qc +++ b/qcsrc/common/weapons/weapon/minelayer.qc @@ -129,7 +129,8 @@ void W_MineLayer_Explode(void) if(!w.wr_checkammo1(w)) { self.cnt = WEP_MINE_LAYER.m_id; - ATTACK_FINISHED(self) = time; + int slot = 0; // TODO: unhardcode + ATTACK_FINISHED(self, slot) = time; self.switchweapon = w_getbestweapon(self); } setself(this); @@ -155,7 +156,8 @@ void W_MineLayer_DoRemoteExplode(void) if(!w.wr_checkammo1(w)) { self.cnt = WEP_MINE_LAYER.m_id; - ATTACK_FINISHED(self) = time; + int slot = 0; // TODO: unhardcode + ATTACK_FINISHED(self, slot) = time; self.switchweapon = w_getbestweapon(self); } setself(this); @@ -511,10 +513,10 @@ float W_MineLayer_PlacedMines(float detonate) } else if(fire & 1) { - if(weapon_prepareattack(thiswep, actor, false, WEP_CVAR(minelayer, refire))) + if(weapon_prepareattack(thiswep, actor, slot, false, WEP_CVAR(minelayer, refire))) { W_MineLayer_Attack(thiswep); - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR(minelayer, animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR(minelayer, animtime), w_ready); } } @@ -530,8 +532,9 @@ float W_MineLayer_PlacedMines(float detonate) } METHOD(MineLayer, wr_checkammo1, bool(entity thiswep)) { + int slot = 0; // TODO: unhardcode // don't switch while placing a mine - if(ATTACK_FINISHED(self) <= time || self.weapon != WEP_MINE_LAYER.m_id) + if(ATTACK_FINISHED(self, slot) <= time || self.weapon != WEP_MINE_LAYER.m_id) { float ammo_amount = self.WEP_AMMO(MINE_LAYER) >= WEP_CVAR(minelayer, ammo); ammo_amount += self.(weapon_load[WEP_MINE_LAYER.m_id]) >= WEP_CVAR(minelayer, ammo); diff --git a/qcsrc/common/weapons/weapon/mortar.qc b/qcsrc/common/weapons/weapon/mortar.qc index 043f8f63b..e1a295936 100644 --- a/qcsrc/common/weapons/weapon/mortar.qc +++ b/qcsrc/common/weapons/weapon/mortar.qc @@ -341,10 +341,10 @@ void W_Mortar_Attack2(Weapon thiswep) w.wr_reload(w); } else if(fire & 1) { - if(weapon_prepareattack(thiswep, actor, false, WEP_CVAR_PRI(mortar, refire))) + if(weapon_prepareattack(thiswep, actor, slot, false, WEP_CVAR_PRI(mortar, refire))) { W_Mortar_Attack(thiswep); - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR_PRI(mortar, animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR_PRI(mortar, animtime), w_ready); } } else if(fire & 2) @@ -364,10 +364,10 @@ void W_Mortar_Attack2(Weapon thiswep) if(nadefound) sound(actor, CH_WEAPON_B, SND_ROCKET_DET, VOL_BASE, ATTN_NORM); } - else if(weapon_prepareattack(thiswep, actor, true, WEP_CVAR_SEC(mortar, refire))) + else if(weapon_prepareattack(thiswep, actor, slot, true, WEP_CVAR_SEC(mortar, refire))) { W_Mortar_Attack2(thiswep); - weapon_thinkf(actor, WFRAME_FIRE2, WEP_CVAR_SEC(mortar, animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE2, WEP_CVAR_SEC(mortar, animtime), w_ready); } } } diff --git a/qcsrc/common/weapons/weapon/porto.qc b/qcsrc/common/weapons/weapon/porto.qc index 8761040b3..89019c40c 100644 --- a/qcsrc/common/weapons/weapon/porto.qc +++ b/qcsrc/common/weapons/weapon/porto.qc @@ -313,19 +313,19 @@ void W_Porto_Attack(float type) if(fire & 1) if(!actor.porto_current) if(!actor.porto_forbidden) - if(weapon_prepareattack(thiswep, actor, false, WEP_CVAR_PRI(porto, refire))) + if(weapon_prepareattack(thiswep, actor, slot, false, WEP_CVAR_PRI(porto, refire))) { W_Porto_Attack(0); - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR_PRI(porto, animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR_PRI(porto, animtime), w_ready); } if(fire & 2) if(!actor.porto_current) if(!actor.porto_forbidden) - if(weapon_prepareattack(thiswep, actor, true, WEP_CVAR_SEC(porto, refire))) + if(weapon_prepareattack(thiswep, actor, slot, true, WEP_CVAR_SEC(porto, refire))) { W_Porto_Attack(1); - weapon_thinkf(actor, WFRAME_FIRE2, WEP_CVAR_SEC(porto, animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE2, WEP_CVAR_SEC(porto, animtime), w_ready); } } else @@ -355,10 +355,10 @@ void W_Porto_Attack(float type) if(fire & 1) if(!actor.porto_current) if(!actor.porto_forbidden) - if(weapon_prepareattack(thiswep, actor, false, WEP_CVAR_PRI(porto, refire))) + if(weapon_prepareattack(thiswep, actor, slot, false, WEP_CVAR_PRI(porto, refire))) { W_Porto_Attack(-1); - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR_PRI(porto, animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR_PRI(porto, animtime), w_ready); } } } diff --git a/qcsrc/common/weapons/weapon/rifle.qc b/qcsrc/common/weapons/weapon/rifle.qc index 6b5ed1997..a8aa5432a 100644 --- a/qcsrc/common/weapons/weapon/rifle.qc +++ b/qcsrc/common/weapons/weapon/rifle.qc @@ -95,27 +95,27 @@ void W_Rifle_BulletHail_Continue(Weapon thiswep, entity actor, int slot, int fir float r, sw, af; sw = actor.switchweapon; // make it not detect weapon changes as reason to abort firing - af = ATTACK_FINISHED(actor); + af = ATTACK_FINISHED(actor, slot); actor.switchweapon = actor.weapon; - ATTACK_FINISHED(actor) = time; + ATTACK_FINISHED(actor, slot) = time; LOG_INFO(ftos(actor.WEP_AMMO(RIFLE)), "\n"); - r = weapon_prepareattack(thiswep, actor, actor.rifle_bullethail_frame == WFRAME_FIRE2, actor.rifle_bullethail_refire); + r = weapon_prepareattack(thiswep, actor, slot, actor.rifle_bullethail_frame == WFRAME_FIRE2, actor.rifle_bullethail_refire); if(actor.switchweapon == actor.weapon) actor.switchweapon = sw; if(r) { actor.rifle_bullethail_attackfunc(); - weapon_thinkf(actor, actor.rifle_bullethail_frame, actor.rifle_bullethail_animtime, W_Rifle_BulletHail_Continue); + weapon_thinkf(actor, slot, actor.rifle_bullethail_frame, actor.rifle_bullethail_animtime, W_Rifle_BulletHail_Continue); LOG_INFO("thinkf set\n"); } else { - ATTACK_FINISHED(actor) = af; // reset attack_finished if we didn't fire, so the last shot enforces the refire time - LOG_INFO("out of ammo... ", ftos(actor.weaponentity.state), "\n"); + ATTACK_FINISHED(actor, slot) = af; // reset attack_finished if we didn't fire, so the last shot enforces the refire time + LOG_INFO("out of ammo... ", ftos(actor.weaponentity[slot].state), "\n"); } } -void W_Rifle_BulletHail(float mode, void(void) AttackFunc, float fr, float animtime, float refire) +void W_Rifle_BulletHail(int slot, float mode, void(void) AttackFunc, float fr, float animtime, float refire) {SELFPARAM(); // if we get here, we have at least one bullet to fire AttackFunc(); @@ -126,12 +126,12 @@ void W_Rifle_BulletHail(float mode, void(void) AttackFunc, float fr, float animt self.rifle_bullethail_frame = fr; self.rifle_bullethail_animtime = animtime; self.rifle_bullethail_refire = refire; - weapon_thinkf(self, fr, animtime, W_Rifle_BulletHail_Continue); + weapon_thinkf(self, slot, fr, animtime, W_Rifle_BulletHail_Continue); } else { // just one shot - weapon_thinkf(self, fr, animtime, w_ready); + weapon_thinkf(self, slot, fr, animtime, w_ready); } } @@ -169,11 +169,11 @@ void W_Rifle_BulletHail(float mode, void(void) AttackFunc, float fr, float animt { actor.rifle_accumulator = bound(time - WEP_CVAR(rifle, bursttime), actor.rifle_accumulator, time); if(fire & 1) - if(weapon_prepareattack_check(thiswep, actor, false, WEP_CVAR_PRI(rifle, refire))) + if(weapon_prepareattack_check(thiswep, actor, slot, false, WEP_CVAR_PRI(rifle, refire))) if(time >= actor.rifle_accumulator + WEP_CVAR_PRI(rifle, burstcost)) { - weapon_prepareattack_do(actor, false, WEP_CVAR_PRI(rifle, refire)); - W_Rifle_BulletHail(WEP_CVAR_PRI(rifle, bullethail), W_Rifle_Attack, WFRAME_FIRE1, WEP_CVAR_PRI(rifle, animtime), WEP_CVAR_PRI(rifle, refire)); + weapon_prepareattack_do(actor, slot, false, WEP_CVAR_PRI(rifle, refire)); + W_Rifle_BulletHail(slot, WEP_CVAR_PRI(rifle, bullethail), W_Rifle_Attack, WFRAME_FIRE1, WEP_CVAR_PRI(rifle, animtime), WEP_CVAR_PRI(rifle, refire)); actor.rifle_accumulator += WEP_CVAR_PRI(rifle, burstcost); } if(fire & 2) @@ -185,11 +185,11 @@ void W_Rifle_BulletHail(float mode, void(void) AttackFunc, float fr, float animt w.wr_reload(w); } else { - if(weapon_prepareattack_check(thiswep, actor, true, WEP_CVAR_SEC(rifle, refire))) + if(weapon_prepareattack_check(thiswep, actor, slot, true, WEP_CVAR_SEC(rifle, refire))) if(time >= actor.rifle_accumulator + WEP_CVAR_SEC(rifle, burstcost)) { - weapon_prepareattack_do(actor, true, WEP_CVAR_SEC(rifle, refire)); - W_Rifle_BulletHail(WEP_CVAR_SEC(rifle, bullethail), W_Rifle_Attack2, WFRAME_FIRE2, WEP_CVAR_SEC(rifle, animtime), WEP_CVAR_PRI(rifle, refire)); + weapon_prepareattack_do(actor, slot, true, WEP_CVAR_SEC(rifle, refire)); + W_Rifle_BulletHail(slot, WEP_CVAR_SEC(rifle, bullethail), W_Rifle_Attack2, WFRAME_FIRE2, WEP_CVAR_SEC(rifle, animtime), WEP_CVAR_PRI(rifle, refire)); actor.rifle_accumulator += WEP_CVAR_SEC(rifle, burstcost); } } diff --git a/qcsrc/common/weapons/weapon/rpc.qc b/qcsrc/common/weapons/weapon/rpc.qc index b87b3371b..d48d54153 100644 --- a/qcsrc/common/weapons/weapon/rpc.qc +++ b/qcsrc/common/weapons/weapon/rpc.qc @@ -162,10 +162,10 @@ void W_RocketPropelledChainsaw_Attack (Weapon thiswep) { if (fire & 1) { - if(weapon_prepareattack(thiswep, actor, false, WEP_CVAR(rpc, refire))) + if(weapon_prepareattack(thiswep, actor, slot, false, WEP_CVAR(rpc, refire))) { W_RocketPropelledChainsaw_Attack(thiswep); - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR(rpc, animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR(rpc, animtime), w_ready); } } diff --git a/qcsrc/common/weapons/weapon/seeker.qc b/qcsrc/common/weapons/weapon/seeker.qc index 303c563fe..9bac67321 100644 --- a/qcsrc/common/weapons/weapon/seeker.qc +++ b/qcsrc/common/weapons/weapon/seeker.qc @@ -617,18 +617,18 @@ void W_Seeker_Fire_Tag(Weapon thiswep) { if(WEP_CVAR(seeker, type) == 1) { - if(weapon_prepareattack(thiswep, actor, false, WEP_CVAR(seeker, missile_refire))) + if(weapon_prepareattack(thiswep, actor, slot, false, WEP_CVAR(seeker, missile_refire))) { W_Seeker_Attack(); - weapon_thinkf(actor, WFRAME_FIRE2, WEP_CVAR(seeker, missile_animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE2, WEP_CVAR(seeker, missile_animtime), w_ready); } } else { - if(weapon_prepareattack(thiswep, actor, false, WEP_CVAR(seeker, tag_refire))) + if(weapon_prepareattack(thiswep, actor, slot, false, WEP_CVAR(seeker, tag_refire))) { W_Seeker_Fire_Tag(thiswep); - weapon_thinkf(actor, WFRAME_FIRE2, WEP_CVAR(seeker, tag_animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE2, WEP_CVAR(seeker, tag_animtime), w_ready); } } } @@ -637,18 +637,18 @@ void W_Seeker_Fire_Tag(Weapon thiswep) { if(WEP_CVAR(seeker, type) == 1) { - if(weapon_prepareattack(thiswep, actor, false, WEP_CVAR(seeker, tag_refire))) + if(weapon_prepareattack(thiswep, actor, slot, false, WEP_CVAR(seeker, tag_refire))) { W_Seeker_Fire_Tag(thiswep); - weapon_thinkf(actor, WFRAME_FIRE2, WEP_CVAR(seeker, tag_animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE2, WEP_CVAR(seeker, tag_animtime), w_ready); } } else { - if(weapon_prepareattack(thiswep, actor, false, WEP_CVAR(seeker, flac_refire))) + if(weapon_prepareattack(thiswep, actor, slot, false, WEP_CVAR(seeker, flac_refire))) { W_Seeker_Fire_Flac(thiswep); - weapon_thinkf(actor, WFRAME_FIRE2, WEP_CVAR(seeker, flac_animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE2, WEP_CVAR(seeker, flac_animtime), w_ready); } } } diff --git a/qcsrc/common/weapons/weapon/shockwave.qc b/qcsrc/common/weapons/weapon/shockwave.qc index bd220ff7c..97061567c 100644 --- a/qcsrc/common/weapons/weapon/shockwave.qc +++ b/qcsrc/common/weapons/weapon/shockwave.qc @@ -232,7 +232,7 @@ void W_Shockwave_Melee_Think(void) void W_Shockwave_Melee(Weapon thiswep, entity actor, int slot, int fire) { sound(actor, CH_WEAPON_A, SND_SHOTGUN_MELEE, VOL_BASE, ATTN_NORM); - weapon_thinkf(actor, WFRAME_FIRE2, WEP_CVAR(shockwave, melee_animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE2, WEP_CVAR(shockwave, melee_animtime), w_ready); entity meleetemp; meleetemp = spawn(); @@ -681,11 +681,11 @@ void W_Shockwave_Attack(void) { if(time >= actor.shockwave_blasttime) // handle refire separately so the secondary can be fired straight after a primary { - if(weapon_prepareattack(thiswep, actor, false, WEP_CVAR(shockwave, blast_animtime))) + if(weapon_prepareattack(thiswep, actor, slot, false, WEP_CVAR(shockwave, blast_animtime))) { W_Shockwave_Attack(); actor.shockwave_blasttime = time + WEP_CVAR(shockwave, blast_refire) * W_WeaponRateFactor(); - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR(shockwave, blast_animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR(shockwave, blast_animtime), w_ready); } } } @@ -693,10 +693,10 @@ void W_Shockwave_Attack(void) { //if(actor.clip_load >= 0) // we are not currently reloading if(!actor.crouch) // no crouchmelee please - if(weapon_prepareattack(thiswep, actor, true, WEP_CVAR(shockwave, melee_refire))) + if(weapon_prepareattack(thiswep, actor, slot, true, WEP_CVAR(shockwave, melee_refire))) { // attempt forcing playback of the anim by switching to another anim (that we never play) here... - weapon_thinkf(actor, WFRAME_FIRE1, 0, W_Shockwave_Melee); + weapon_thinkf(actor, slot, WFRAME_FIRE1, 0, W_Shockwave_Melee); } } } diff --git a/qcsrc/common/weapons/weapon/shotgun.qc b/qcsrc/common/weapons/weapon/shotgun.qc index 42b99969a..e3f85daa1 100644 --- a/qcsrc/common/weapons/weapon/shotgun.qc +++ b/qcsrc/common/weapons/weapon/shotgun.qc @@ -184,7 +184,7 @@ void W_Shotgun_Melee_Think(void) void W_Shotgun_Attack2(Weapon thiswep, entity actor, int slot, int fire) { sound(actor, CH_WEAPON_A, SND_SHOTGUN_MELEE, VOL_BASE, ATTEN_NORM); - weapon_thinkf(actor, WFRAME_FIRE2, WEP_CVAR_SEC(shotgun, animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE2, WEP_CVAR_SEC(shotgun, animtime), w_ready); entity meleetemp; meleetemp = spawn(); @@ -208,7 +208,7 @@ void W_Shotgun_Attack3_Frame2(Weapon thiswep, entity actor, int slot, int fire) sound(actor, CH_WEAPON_SINGLE, SND_Null, VOL_BASE, ATTN_NORM); // kill previous sound W_Shotgun_Attack(WEP_SHOTGUN, true); // actually is secondary, but we trick the last shot into playing full reload sound - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR_SEC(shotgun, alt_animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR_SEC(shotgun, alt_animtime), w_ready); } void W_Shotgun_Attack3_Frame1(Weapon thiswep, entity actor, int slot, int fire) { @@ -222,7 +222,7 @@ void W_Shotgun_Attack3_Frame1(Weapon thiswep, entity actor, int slot, int fire) } W_Shotgun_Attack(WEP_SHOTGUN, false); - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR_SEC(shotgun, alt_animtime), W_Shotgun_Attack3_Frame2); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR_SEC(shotgun, alt_animtime), W_Shotgun_Attack3_Frame2); } .float shotgun_primarytime; @@ -250,11 +250,11 @@ void W_Shotgun_Attack3_Frame1(Weapon thiswep, entity actor, int slot, int fire) { if(time >= actor.shotgun_primarytime) // handle refire separately so the secondary can be fired straight after a primary { - if(weapon_prepareattack(thiswep, actor, false, WEP_CVAR_PRI(shotgun, animtime))) + if(weapon_prepareattack(thiswep, actor, slot, false, WEP_CVAR_PRI(shotgun, animtime))) { W_Shotgun_Attack(thiswep, true); actor.shotgun_primarytime = time + WEP_CVAR_PRI(shotgun, refire) * W_WeaponRateFactor(); - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR_PRI(shotgun, animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR_PRI(shotgun, animtime), w_ready); } } } @@ -262,11 +262,11 @@ void W_Shotgun_Attack3_Frame1(Weapon thiswep, entity actor, int slot, int fire) { if(time >= actor.shotgun_primarytime) // handle refire separately so the secondary can be fired straight after a primary { - if(weapon_prepareattack(thiswep, actor, false, WEP_CVAR_SEC(shotgun, alt_animtime))) + if(weapon_prepareattack(thiswep, actor, slot, false, WEP_CVAR_SEC(shotgun, alt_animtime))) { W_Shotgun_Attack(thiswep, false); actor.shotgun_primarytime = time + WEP_CVAR_SEC(shotgun, alt_refire) * W_WeaponRateFactor(); - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR_SEC(shotgun, alt_animtime), W_Shotgun_Attack3_Frame1); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR_SEC(shotgun, alt_animtime), W_Shotgun_Attack3_Frame1); } } } @@ -275,10 +275,10 @@ void W_Shotgun_Attack3_Frame1(Weapon thiswep, entity actor, int slot, int fire) if(!actor.crouch) // no crouchmelee please if(WEP_CVAR(shotgun, secondary) == 1) if(((fire & 1) && actor.WEP_AMMO(SHOTGUN) <= 0 && !(actor.items & IT_UNLIMITED_WEAPON_AMMO)) || (fire & 2)) - if(weapon_prepareattack(thiswep, actor, true, WEP_CVAR_SEC(shotgun, refire))) + if(weapon_prepareattack(thiswep, actor, slot, true, WEP_CVAR_SEC(shotgun, refire))) { // attempt forcing playback of the anim by switching to another anim (that we never play) here... - weapon_thinkf(actor, WFRAME_FIRE1, 0, W_Shotgun_Attack2); + weapon_thinkf(actor, slot, WFRAME_FIRE1, 0, W_Shotgun_Attack2); } } METHOD(Shotgun, wr_init, void(entity thiswep)) diff --git a/qcsrc/common/weapons/weapon/tuba.qc b/qcsrc/common/weapons/weapon/tuba.qc index 688152e0a..a1e1a7164 100644 --- a/qcsrc/common/weapons/weapon/tuba.qc +++ b/qcsrc/common/weapons/weapon/tuba.qc @@ -382,18 +382,18 @@ void W_Tuba_NoteOn(float hittype) METHOD(Tuba, wr_think, void(entity thiswep, entity actor, int slot, int fire)) { if(fire & 1) - if(weapon_prepareattack(thiswep, actor, false, WEP_CVAR(tuba, refire))) + if(weapon_prepareattack(thiswep, actor, slot, false, WEP_CVAR(tuba, refire))) { W_Tuba_NoteOn(0); //weapon_thinkf(actor, WFRAME_FIRE1, autocvar_g_balance_tuba_animtime, w_ready); - weapon_thinkf(actor, WFRAME_IDLE, WEP_CVAR(tuba, animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_IDLE, WEP_CVAR(tuba, animtime), w_ready); } if(fire & 2) - if(weapon_prepareattack(thiswep, actor, true, WEP_CVAR(tuba, refire))) + if(weapon_prepareattack(thiswep, actor, slot, true, WEP_CVAR(tuba, refire))) { W_Tuba_NoteOn(HITTYPE_SECONDARY); //weapon_thinkf(actor, WFRAME_FIRE2, autocvar_g_balance_tuba_animtime, w_ready); - weapon_thinkf(actor, WFRAME_IDLE, WEP_CVAR(tuba, animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_IDLE, WEP_CVAR(tuba, animtime), w_ready); } if(actor.tuba_note) { @@ -414,8 +414,9 @@ void W_Tuba_NoteOn(float hittype) } METHOD(Tuba, wr_reload, void(entity thiswep)) { + int slot = 0; // TODO: unhardcode // switch to alternate instruments :) - if(self.weaponentity.state == WS_READY) + if(self.weaponentity[slot].state == WS_READY) { switch(self.tuba_instrument) { @@ -434,8 +435,8 @@ void W_Tuba_NoteOn(float hittype) } W_SetupShot(self, false, 0, "", 0, 0); Send_Effect(EFFECT_TELEPORT, w_shotorg, '0 0 0', 1); - self.weaponentity.state = WS_INUSE; - weapon_thinkf(self, WFRAME_RELOAD, 0.5, w_ready); + self.weaponentity[slot].state = WS_INUSE; + weapon_thinkf(self, slot, WFRAME_RELOAD, 0.5, w_ready); } } METHOD(Tuba, wr_checkammo1, bool(entity thiswep)) diff --git a/qcsrc/common/weapons/weapon/vaporizer.qc b/qcsrc/common/weapons/weapon/vaporizer.qc index c7de3881b..d4208501b 100644 --- a/qcsrc/common/weapons/weapon/vaporizer.qc +++ b/qcsrc/common/weapons/weapon/vaporizer.qc @@ -257,10 +257,10 @@ void W_RocketMinsta_Attack3 (void) } if((fire & 1) && (actor.ammo_cells || !autocvar_g_rm) && !forbidWeaponUse(actor)) { - if(weapon_prepareattack(thiswep, actor, false, WEP_CVAR_PRI(vaporizer, refire))) + if(weapon_prepareattack(thiswep, actor, slot, false, WEP_CVAR_PRI(vaporizer, refire))) { W_Vaporizer_Attack(thiswep); - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR_PRI(vaporizer, animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR_PRI(vaporizer, animtime), w_ready); } } if((fire & 2) || ((fire & 1) && !actor.ammo_cells && autocvar_g_rm)) @@ -314,7 +314,7 @@ void W_RocketMinsta_Attack3 (void) actor.weapon = oldwep; // now do normal refire - weapon_thinkf(actor, WFRAME_FIRE2, WEP_CVAR_SEC(vaporizer, animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE2, WEP_CVAR_SEC(vaporizer, animtime), w_ready); } } else diff --git a/qcsrc/common/weapons/weapon/vortex.qc b/qcsrc/common/weapons/weapon/vortex.qc index a3843dae1..e82509050 100644 --- a/qcsrc/common/weapons/weapon/vortex.qc +++ b/qcsrc/common/weapons/weapon/vortex.qc @@ -163,10 +163,10 @@ void W_Vortex_Attack(Weapon thiswep, float issecondary) { if(fire & 1) { - if(weapon_prepareattack(thiswep, actor, false, WEP_CVAR_PRI(vortex, refire))) + if(weapon_prepareattack(thiswep, actor, slot, false, WEP_CVAR_PRI(vortex, refire))) { W_Vortex_Attack(thiswep, 0); - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR_PRI(vortex, animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR_PRI(vortex, animtime), w_ready); } } if((WEP_CVAR(vortex, charge) && !WEP_CVAR(vortex, secondary)) ? (actor.BUTTON_ZOOM | actor.BUTTON_ZOOMSCRIPT) : (fire & 2)) @@ -235,10 +235,10 @@ void W_Vortex_Attack(Weapon thiswep, float issecondary) } else if(WEP_CVAR(vortex, secondary)) { - if(weapon_prepareattack(thiswep, actor, false, WEP_CVAR_SEC(vortex, refire))) + if(weapon_prepareattack(thiswep, actor, slot, false, WEP_CVAR_SEC(vortex, refire))) { W_Vortex_Attack(thiswep, 1); - weapon_thinkf(actor, WFRAME_FIRE1, WEP_CVAR_SEC(vortex, animtime), w_ready); + weapon_thinkf(actor, slot, WFRAME_FIRE1, WEP_CVAR_SEC(vortex, animtime), w_ready); } } } diff --git a/qcsrc/server/bot/havocbot/havocbot.qc b/qcsrc/server/bot/havocbot/havocbot.qc index ced6463c2..696de21dc 100644 --- a/qcsrc/server/bot/havocbot/havocbot.qc +++ b/qcsrc/server/bot/havocbot/havocbot.qc @@ -1045,7 +1045,7 @@ void havocbot_chooseweapon() // Should it do a weapon combo? float af, ct, combo_time, combo; - af = ATTACK_FINISHED(self); + af = ATTACK_FINISHED(self, 0); ct = autocvar_bot_ai_weapon_combo_threshold; // Bots with no skill will be 4 times more slower than "godlike" bots when doing weapon combos diff --git a/qcsrc/server/bot/scripting.qc b/qcsrc/server/bot/scripting.qc index 76cda90d9..9dfc26de7 100644 --- a/qcsrc/server/bot/scripting.qc +++ b/qcsrc/server/bot/scripting.qc @@ -1059,10 +1059,10 @@ float bot_cmd_sound() .entity tuba_note; float bot_cmd_debug_assert_canfire() {SELFPARAM(); - float f; - f = bot_cmd.bot_cmd_parm_float; + float f = bot_cmd.bot_cmd_parm_float; - if(self.weaponentity.state != WS_READY) + int slot = 0; + if(self.weaponentity[slot].state != WS_READY) { if(f) { @@ -1070,12 +1070,12 @@ float bot_cmd_debug_assert_canfire() LOG_INFO("Bot ", self.netname, " using ", self.weaponname, " wants to fire, inhibited by weaponentity state\n"); } } - else if(ATTACK_FINISHED(self) > time) + else if(ATTACK_FINISHED(self, slot) > time) { if(f) { self.colormod = '8 0 8'; - LOG_INFO("Bot ", self.netname, " using ", self.weaponname, " wants to fire, inhibited by ATTACK_FINISHED (", ftos(ATTACK_FINISHED(self) - time), " seconds left)\n"); + LOG_INFO("Bot ", self.netname, " using ", self.weaponname, " wants to fire, inhibited by ATTACK_FINISHED (", ftos(ATTACK_FINISHED(self, slot) - time), " seconds left)\n"); } } else if(self.tuba_note) @@ -1091,7 +1091,7 @@ float bot_cmd_debug_assert_canfire() if(!f) { self.colormod = '8 8 0'; - LOG_INFO("Bot ", self.netname, " using ", self.weaponname, " thinks it has fired, but apparently did not; ATTACK_FINISHED says ", ftos(ATTACK_FINISHED(self) - time), " seconds left\n"); + LOG_INFO("Bot ", self.netname, " using ", self.weaponname, " thinks it has fired, but apparently did not; ATTACK_FINISHED says ", ftos(ATTACK_FINISHED(self, slot) - time), " seconds left\n"); } } diff --git a/qcsrc/server/cheats.qc b/qcsrc/server/cheats.qc index 8f34a7798..4b6405581 100644 --- a/qcsrc/server/cheats.qc +++ b/qcsrc/server/cheats.qc @@ -1025,8 +1025,9 @@ void Drag_Update(entity dragger) draggee.ltime = max(servertime + serverframetime, draggee.ltime); // fixes func_train breakage vector vecs = '0 0 0'; - if(dragger.weaponentity.movedir_x > 0) - vecs = dragger.weaponentity.movedir; + int slot = 0; // TODO: unhardcode + if(dragger.weaponentity[slot].movedir_x > 0) + vecs = dragger.weaponentity[slot].movedir; vector dv = v_right * -vecs_y + v_up * vecs_z; diff --git a/qcsrc/server/cl_client.qc b/qcsrc/server/cl_client.qc index d6522285b..2e1a43c98 100644 --- a/qcsrc/server/cl_client.qc +++ b/qcsrc/server/cl_client.qc @@ -304,7 +304,10 @@ void PutObserverInServer() self.weaponname = ""; self.switchingweapon = 0; self.weaponmodel = ""; - self.weaponentity = world; + for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + { + self.weaponentity[slot] = NULL; + } self.exteriorweaponentity = world; self.killcount = FRAGS_SPECTATOR; self.velocity = '0 0 0'; @@ -568,7 +571,10 @@ void PutClientInServer() this.killcount = 0; } - CL_SpawnWeaponentity(this); + for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + { + CL_SpawnWeaponentity(this, slot); + } this.alpha = default_player_alpha; this.colormod = '1 1 1' * autocvar_g_player_brightness; this.exteriorweaponentity.alpha = default_weapon_alpha; @@ -2427,7 +2433,8 @@ void PlayerPreThink (void) // WEAPONTODO: THIS SHIT NEEDS TO GO EVENTUALLY // It cannot be predicted by the engine! - if((self.weapon == WEP_SHOCKWAVE.m_id || self.weapon == WEP_SHOTGUN.m_id) && self.weaponentity.wframe == WFRAME_FIRE2 && time < self.weapon_nextthink) + int slot = 0; // TODO: unhardcode + if((self.weapon == WEP_SHOCKWAVE.m_id || self.weapon == WEP_SHOTGUN.m_id) && self.weaponentity[slot].wframe == WFRAME_FIRE2 && time < self.weapon_nextthink) do_crouch = 0; if (do_crouch) diff --git a/qcsrc/server/cl_player.qc b/qcsrc/server/cl_player.qc index ecbafc40b..205c2a035 100644 --- a/qcsrc/server/cl_player.qc +++ b/qcsrc/server/cl_player.qc @@ -168,11 +168,14 @@ void player_anim (void) animdecide_setstate(self, animbits, false); animdecide_setimplicitstate(self, (self.flags & FL_ONGROUND)); - if (self.weaponentity) + int slot = 0; // TODO: unhardcode { - updateanim(self.weaponentity); - if (!self.weaponentity.animstate_override) - setanim(self.weaponentity, self.weaponentity.anim_idle, true, false, false); + if (self.weaponentity[slot]) + { + updateanim(self.weaponentity[slot]); + if (!self.weaponentity[slot].animstate_override) + setanim(self.weaponentity[slot], self.weaponentity[slot].anim_idle, true, false, false); + } } } @@ -652,7 +655,10 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, int deathtyp { Weapon w = get_weaponinfo(j); w.wr_resetplayer(w); - ATTACK_FINISHED_FOR(self, j) = 0; + for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + { + ATTACK_FINISHED_FOR(self, j, slot) = 0; + } } } } diff --git a/qcsrc/server/command/sv_cmd.qc b/qcsrc/server/command/sv_cmd.qc index 98127d198..c65bd8fa9 100644 --- a/qcsrc/server/command/sv_cmd.qc +++ b/qcsrc/server/command/sv_cmd.qc @@ -831,7 +831,8 @@ void GameCommand_gettaginfo(float request, float argc) tmp_entity = spawn(); if (argv(1) == "w") { - _setmodel(tmp_entity, (nextent(world)).weaponentity.model); + int slot = 0; + _setmodel(tmp_entity, (nextent(world)).weaponentity[slot].model); } else { @@ -891,7 +892,8 @@ void GameCommand_animbench(float request, float argc) tmp_entity = spawn(); if (argv(1) == "w") { - _setmodel(tmp_entity, (nextent(world)).weaponentity.model); + int slot = 0; + _setmodel(tmp_entity, (nextent(world)).weaponentity[slot].model); } else { diff --git a/qcsrc/server/defs.qh b/qcsrc/server/defs.qh index 99814e015..0e5fd6776 100644 --- a/qcsrc/server/defs.qh +++ b/qcsrc/server/defs.qh @@ -151,7 +151,7 @@ const float MAX_DAMAGEEXTRARADIUS = 16; // definitions for weaponsystem // more WEAPONTODO: move these to their proper files -.entity weaponentity; +.entity weaponentity[MAX_WEAPONSLOTS]; .entity exteriorweaponentity; .vector weaponentity_glowmod; @@ -261,14 +261,14 @@ WepSet weaponsInMap; float bot_waypoints_for_items; -.float attack_finished_for[Weapons_MAX]; -.float attack_finished_single; -#ifdef INDEPENDENT_ATTACK_FINISHED -#define ATTACK_FINISHED_FOR(ent,w) ((ent).(attack_finished_for[(w) - WEP_FIRST])) +.float attack_finished_for[Weapons_MAX * MAX_WEAPONSLOTS]; +.float attack_finished_single[MAX_WEAPONSLOTS]; +#if INDEPENDENT_ATTACK_FINISHED +#define ATTACK_FINISHED_FOR(ent, w, slot) ((ent).(attack_finished_for[((w) - WEP_FIRST) * MAX_WEAPONSLOTS + (slot)])) #else -#define ATTACK_FINISHED_FOR(ent,w) ((ent).attack_finished_single) +#define ATTACK_FINISHED_FOR(ent, w, slot) ((ent).attack_finished_single[slot]) #endif -#define ATTACK_FINISHED(ent) ATTACK_FINISHED_FOR(ent,(ent).weapon) +#define ATTACK_FINISHED(ent, slot) ATTACK_FINISHED_FOR(ent, (ent).weapon, slot) // assault game mode: Which team is attacking in this round? float assault_attacker_team; diff --git a/qcsrc/server/g_world.qc b/qcsrc/server/g_world.qc index c706a1bdd..01e69f4be 100644 --- a/qcsrc/server/g_world.qc +++ b/qcsrc/server/g_world.qc @@ -1485,11 +1485,14 @@ void FixIntermissionClient(entity e) e.solid = SOLID_NOT; e.movetype = MOVETYPE_NONE; e.takedamage = DAMAGE_NO; - if(e.weaponentity) + for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) { - e.weaponentity.effects = EF_NODRAW; - if (e.weaponentity.weaponentity) - e.weaponentity.weaponentity.effects = EF_NODRAW; + if(e.weaponentity[slot]) + { + e.weaponentity[slot].effects = EF_NODRAW; + if (e.weaponentity[slot].weaponentity[slot]) + e.weaponentity[slot].weaponentity[slot].effects = EF_NODRAW; + } } if(IS_REAL_CLIENT(e)) { diff --git a/qcsrc/server/mutators/mutator/mutator_nades.qc b/qcsrc/server/mutators/mutator/mutator_nades.qc index d9fd1c8b6..cc567d2b8 100644 --- a/qcsrc/server/mutators/mutator/mutator_nades.qc +++ b/qcsrc/server/mutators/mutator/mutator_nades.qc @@ -864,7 +864,8 @@ void nade_prime() n.projectiledeathtype = DEATH_NADE.m_id; setmodel(fn, MDL_NADE_VIEW); - setattachment(fn, self.weaponentity, ""); + int slot = 0; // TODO: unhardcode + setattachment(fn, self.weaponentity[slot], ""); fn.realowner = fn.owner = self; fn.colormod = Nades[n.nade_type].m_color; fn.colormap = self.colormap; diff --git a/qcsrc/server/mutators/mutator/mutator_overkill.qc b/qcsrc/server/mutators/mutator/mutator_overkill.qc index a07c18e13..0df6accdd 100644 --- a/qcsrc/server/mutators/mutator/mutator_overkill.qc +++ b/qcsrc/server/mutators/mutator/mutator_overkill.qc @@ -207,8 +207,9 @@ MUTATOR_HOOKFUNCTION(ok, PlayerPreThink) play2(self, SND(DRYFIRE)); } Weapon wpn = get_weaponinfo(self.weapon); - if(self.weaponentity.state != WS_CLEAR) - w_ready(wpn, self, 0, (self.BUTTON_ATCK ? 1 : 0) | (self.BUTTON_ATCK2 ? 2 : 0)); + int slot = 0; // TODO: unhardcode + if(self.weaponentity[slot].state != WS_CLEAR) + w_ready(wpn, self, slot, (self.BUTTON_ATCK ? 1 : 0) | (self.BUTTON_ATCK2 ? 2 : 0)); self.weapon_blocked = true; } diff --git a/qcsrc/server/weapons/throwing.qc b/qcsrc/server/weapons/throwing.qc index 9e1b3e4dc..900b45018 100644 --- a/qcsrc/server/weapons/throwing.qc +++ b/qcsrc/server/weapons/throwing.qc @@ -171,7 +171,8 @@ void W_ThrowWeapon(vector velo, vector delta, float doreduce) return; if(!autocvar_g_weapon_throwable) return; - if(self.weaponentity.state != WS_READY) + int slot = 0; // TODO: unhardcode + if(self.weaponentity[slot].state != WS_READY) return; if(!W_IsWeaponThrowable(w)) return; diff --git a/qcsrc/server/weapons/tracing.qc b/qcsrc/server/weapons/tracing.qc index 4c9e0e34c..6b7054f95 100644 --- a/qcsrc/server/weapons/tracing.qc +++ b/qcsrc/server/weapons/tracing.qc @@ -55,8 +55,9 @@ void W_SetupShot_Dir_ProjectileSize_Range(entity ent, vector s_forward, vector m W_HitPlotAnalysis(ent, v_forward, v_right, v_up); - if(ent.weaponentity.movedir.x > 0) - vecs = ent.weaponentity.movedir; + int slot = 0; // TODO: unhardcode + if(ent.weaponentity[slot].movedir.x > 0) + vecs = ent.weaponentity[slot].movedir; else vecs = '0 0 0'; diff --git a/qcsrc/server/weapons/weaponsystem.qc b/qcsrc/server/weapons/weaponsystem.qc index f47916e1d..7966e073b 100644 --- a/qcsrc/server/weapons/weaponsystem.qc +++ b/qcsrc/server/weapons/weaponsystem.qc @@ -92,7 +92,8 @@ float W_WeaponSpeedFactor() } -void weapon_thinkf(entity actor, float fr, float t, void(Weapon thiswep, entity actor, int slot, int fire) func); +void weapon_thinkf(entity actor, int slot, float fr, float t, + void(Weapon thiswep, entity actor, int slot, int fire) func); bool CL_Weaponentity_CustomizeEntityForClient() { @@ -153,12 +154,12 @@ bool CL_Weaponentity_CustomizeEntityForClient() // to free: // call again with "" // remove the ent -void CL_WeaponEntity_SetModel(entity this, string name) +void CL_WeaponEntity_SetModel(entity this, int slot, string name) { if (name != "") { // if there is a child entity, hide it until we're sure we use it - if (this.weaponentity) this.weaponentity.model = ""; + if (this.weaponentity[slot]) this.weaponentity[slot].model = ""; _setmodel(this, W_Model(strcat("v_", name, ".md3"))); int v_shot_idx = gettagindex(this, "shot"); // used later if (!v_shot_idx) v_shot_idx = gettagindex(this, "tag_shot"); @@ -174,32 +175,32 @@ void CL_WeaponEntity_SetModel(entity this, string name) // if we don't, this is a "real" animated model if (gettagindex(this, "weapon")) { - if (!this.weaponentity) this.weaponentity = spawn(); - _setmodel(this.weaponentity, W_Model(strcat("v_", name, ".md3"))); - setattachment(this.weaponentity, this, "weapon"); + if (!this.weaponentity[slot]) this.weaponentity[slot] = spawn(); + _setmodel(this.weaponentity[slot], W_Model(strcat("v_", name, ".md3"))); + setattachment(this.weaponentity[slot], this, "weapon"); } else if (gettagindex(this, "tag_weapon")) { - if (!this.weaponentity) this.weaponentity = spawn(); - _setmodel(this.weaponentity, W_Model(strcat("v_", name, ".md3"))); - setattachment(this.weaponentity, this, "tag_weapon"); + if (!this.weaponentity[slot]) this.weaponentity[slot] = spawn(); + _setmodel(this.weaponentity[slot], W_Model(strcat("v_", name, ".md3"))); + setattachment(this.weaponentity[slot], this, "tag_weapon"); } else { - if (this.weaponentity) remove(this.weaponentity); - this.weaponentity = world; + if (this.weaponentity[slot]) remove(this.weaponentity[slot]); + this.weaponentity[slot] = NULL; } setorigin(this, '0 0 0'); this.angles = '0 0 0'; this.frame = 0; - this.viewmodelforclient = world; + this.viewmodelforclient = NULL; float idx; if (v_shot_idx) // v_ model attached to invisible h_ model { - this.movedir = gettaginfo(this.weaponentity, v_shot_idx); + this.movedir = gettaginfo(this.weaponentity[slot], v_shot_idx); } else { @@ -217,11 +218,11 @@ void CL_WeaponEntity_SetModel(entity this, string name) } } - if (this.weaponentity) // v_ model attached to invisible h_ model + if (this.weaponentity[slot]) // v_ model attached to invisible h_ model { - idx = gettagindex(this.weaponentity, "shell"); - if (!idx) idx = gettagindex(this.weaponentity, "tag_shell"); - if (idx) this.spawnorigin = gettaginfo(this.weaponentity, idx); + idx = gettagindex(this.weaponentity[slot], "shell"); + if (!idx) idx = gettagindex(this.weaponentity[slot], "tag_shell"); + if (idx) this.spawnorigin = gettaginfo(this.weaponentity[slot], idx); } else { @@ -249,7 +250,7 @@ void CL_WeaponEntity_SetModel(entity this, string name) } else { - if (this.weaponentity) + if (this.weaponentity[slot]) { idx = gettagindex(this, "weapon"); if (!idx) idx = gettagindex(this, "tag_weapon"); @@ -276,8 +277,8 @@ void CL_WeaponEntity_SetModel(entity this, string name) else { this.model = ""; - if (this.weaponentity) remove(this.weaponentity); - this.weaponentity = world; + if (this.weaponentity[slot]) remove(this.weaponentity[slot]); + this.weaponentity[slot] = NULL; this.movedir = '0 0 0'; this.spawnorigin = '0 0 0'; this.oldorigin = '0 0 0'; @@ -311,9 +312,9 @@ vector CL_Weapon_GetShotOrg(float wpn) { entity wi = get_weaponinfo(wpn); entity e = spawn(); - CL_WeaponEntity_SetModel(e, wi.mdl); + CL_WeaponEntity_SetModel(e, 0, wi.mdl); vector ret = e.movedir; - CL_WeaponEntity_SetModel(e, ""); + CL_WeaponEntity_SetModel(e, 0, ""); remove(e); return ret; } @@ -323,16 +324,17 @@ void CL_Weaponentity_Think() SELFPARAM(); this.nextthink = time; if (intermission_running) this.frame = this.anim_idle.x; - if (this.owner.weaponentity != this) + int slot = 0; // TODO: unhardcode + if (this.owner.weaponentity[slot] != this) { - if (this.weaponentity) remove(this.weaponentity); + if (this.weaponentity[slot]) remove(this.weaponentity[slot]); remove(this); return; } if (this.owner.deadflag != DEAD_NO) { this.model = ""; - if (this.weaponentity) this.weaponentity.model = ""; + if (this.weaponentity[slot]) this.weaponentity[slot].model = ""; return; } if (this.weaponname != this.owner.weaponname || this.dmg != this.owner.modelindex @@ -342,7 +344,7 @@ void CL_Weaponentity_Think() this.dmg = this.owner.modelindex; this.deadflag = this.owner.deadflag; - CL_WeaponEntity_SetModel(this, this.owner.weaponname); + CL_WeaponEntity_SetModel(this, slot, this.owner.weaponname); } int tb = (this.effects & (EF_TELEPORT_BIT | EF_RESTARTANIM_BIT)); @@ -359,12 +361,12 @@ void CL_Weaponentity_Think() this.glowmod = this.owner.weaponentity_glowmod; this.colormap = this.owner.colormap; - if (this.weaponentity) + if (this.weaponentity[slot]) { - this.weaponentity.effects = this.effects; - this.weaponentity.alpha = this.alpha; - this.weaponentity.colormap = this.colormap; - this.weaponentity.glowmod = this.glowmod; + this.weaponentity[slot].effects = this.effects; + this.weaponentity[slot].alpha = this.alpha; + this.weaponentity[slot].colormap = this.colormap; + this.weaponentity[slot].glowmod = this.glowmod; } this.angles = '0 0 0'; @@ -437,10 +439,9 @@ void CL_ExteriorWeaponentity_Think() } // spawning weaponentity for client -void CL_SpawnWeaponentity(entity e) +void CL_SpawnWeaponentity(entity e, int slot) { - entity view = e.weaponentity = spawn(); - view.classname = "weaponentity"; + entity view = e.weaponentity[slot] = new(weaponentity); view.solid = SOLID_NOT; view.owner = e; setmodel(view, MDL_Null); // precision set when changed @@ -452,17 +453,20 @@ void CL_SpawnWeaponentity(entity e) view.customizeentityforclient = CL_Weaponentity_CustomizeEntityForClient; view.nextthink = time; - entity exterior = e.exteriorweaponentity = spawn(); - exterior.classname = "exteriorweaponentity"; - exterior.solid = SOLID_NOT; - exterior.exteriorweaponentity = exterior; - exterior.owner = e; - setorigin(exterior, '0 0 0'); - exterior.angles = '0 0 0'; - exterior.think = CL_ExteriorWeaponentity_Think; - exterior.nextthink = time; - - CSQCMODEL_AUTOINIT(exterior); + if (slot == 0) + { + entity exterior = e.exteriorweaponentity = spawn(); + exterior.classname = "exteriorweaponentity"; + exterior.solid = SOLID_NOT; + exterior.exteriorweaponentity = exterior; + exterior.owner = e; + setorigin(exterior, '0 0 0'); + exterior.angles = '0 0 0'; + exterior.think = CL_ExteriorWeaponentity_Think; + exterior.nextthink = time; + + CSQCMODEL_AUTOINIT(exterior); + } } // Weapon subs @@ -473,17 +477,17 @@ void w_clear(Weapon thiswep, entity actor, int slot, int fire) actor.weapon = 0; actor.switchingweapon = 0; } - if (actor.weaponentity) + if (actor.weaponentity[slot]) { - actor.weaponentity.state = WS_CLEAR; - actor.weaponentity.effects = 0; + actor.weaponentity[slot].state = WS_CLEAR; + actor.weaponentity[slot].effects = 0; } } void w_ready(Weapon thiswep, entity actor, int slot, int fire) { - if (actor.weaponentity) actor.weaponentity.state = WS_READY; - weapon_thinkf(actor, WFRAME_IDLE, 1000000, w_ready); + if (actor.weaponentity[slot]) actor.weaponentity[slot].state = WS_READY; + weapon_thinkf(actor, slot, WFRAME_IDLE, 1000000, w_ready); } .float prevdryfire; @@ -538,7 +542,7 @@ bool weapon_prepareattack_checkammo(Weapon thiswep, entity actor, bool secondary } .float race_penalty; -bool weapon_prepareattack_check(Weapon thiswep, entity actor, bool secondary, float attacktime) +bool weapon_prepareattack_check(Weapon thiswep, entity actor, int slot, bool secondary, float attacktime) { if (!weapon_prepareattack_checkammo(thiswep, actor, secondary)) return false; @@ -555,49 +559,50 @@ bool weapon_prepareattack_check(Weapon thiswep, entity actor, bool secondary, fl if (attacktime >= 0) { // don't fire if previous attack is not finished - if (ATTACK_FINISHED(actor) > time + actor.weapon_frametime * 0.5) return false; + if (ATTACK_FINISHED(actor, slot) > time + actor.weapon_frametime * 0.5) return false; // don't fire while changing weapon - if (actor.weaponentity.state != WS_READY) return false; + if (actor.weaponentity[slot].state != WS_READY) return false; } return true; } -void weapon_prepareattack_do(entity actor, bool secondary, float attacktime) +void weapon_prepareattack_do(entity actor, int slot, bool secondary, float attacktime) { - actor.weaponentity.state = WS_INUSE; + actor.weaponentity[slot].state = WS_INUSE; actor.spawnshieldtime = min(actor.spawnshieldtime, time); // kill spawn shield when you fire // if the weapon hasn't been firing continuously, reset the timer if (attacktime >= 0) { - if (ATTACK_FINISHED(actor) < time - actor.weapon_frametime * 1.5) + if (ATTACK_FINISHED(actor, slot) < time - actor.weapon_frametime * 1.5) { - ATTACK_FINISHED(actor) = time; + ATTACK_FINISHED(actor, slot) = time; // dprint("resetting attack finished to ", ftos(time), "\n"); } - ATTACK_FINISHED(actor) = ATTACK_FINISHED(actor) + attacktime * W_WeaponRateFactor(); + ATTACK_FINISHED(actor, slot) = ATTACK_FINISHED(actor, slot) + attacktime * W_WeaponRateFactor(); } actor.bulletcounter += 1; - // dprint("attack finished ", ftos(ATTACK_FINISHED(actor)), "\n"); + // dprint("attack finished ", ftos(ATTACK_FINISHED(actor, slot)), "\n"); } -bool weapon_prepareattack(Weapon thiswep, entity actor, bool secondary, float attacktime) +bool weapon_prepareattack(Weapon thiswep, entity actor, int slot, bool secondary, float attacktime) { - if (weapon_prepareattack_check(thiswep, actor, secondary, attacktime)) + if (weapon_prepareattack_check(thiswep, actor, slot, secondary, attacktime)) { - weapon_prepareattack_do(actor, secondary, attacktime); + weapon_prepareattack_do(actor, slot, secondary, attacktime); return true; } return false; } -void weapon_thinkf(entity actor, float fr, float t, void(Weapon thiswep, entity actor, int slot, int fire) func) +void weapon_thinkf(entity actor, int slot, float fr, float t, + void(Weapon thiswep, entity actor, int slot, int fire) func) { bool restartanim; if (fr == WFRAME_DONTCHANGE) { - fr = actor.weaponentity.wframe; + fr = actor.weaponentity[slot].wframe; restartanim = false; } else if (fr == WFRAME_IDLE) @@ -613,24 +618,24 @@ void weapon_thinkf(entity actor, float fr, float t, void(Weapon thiswep, entity vector or = v_right; vector ou = v_up; - if (actor.weaponentity) + if (actor.weaponentity[slot]) { - actor.weaponentity.wframe = fr; + actor.weaponentity[slot].wframe = fr; vector a = '0 0 0'; - if (fr == WFRAME_IDLE) a = actor.weaponentity.anim_idle; - else if (fr == WFRAME_FIRE1) a = actor.weaponentity.anim_fire1; - else if (fr == WFRAME_FIRE2) a = actor.weaponentity.anim_fire2; + if (fr == WFRAME_IDLE) a = actor.weaponentity[slot].anim_idle; + else if (fr == WFRAME_FIRE1) a = actor.weaponentity[slot].anim_fire1; + else if (fr == WFRAME_FIRE2) a = actor.weaponentity[slot].anim_fire2; else // if (fr == WFRAME_RELOAD) - a = actor.weaponentity.anim_reload; + a = actor.weaponentity[slot].anim_reload; a.z *= g_weaponratefactor; - setanim(actor.weaponentity, a, restartanim == false, restartanim, restartanim); + setanim(actor.weaponentity[slot], a, restartanim == false, restartanim, restartanim); } v_forward = of; v_right = or; v_up = ou; - if (actor.weapon_think == w_ready && func != w_ready && actor.weaponentity.state == WS_RAISE) backtrace( + if (actor.weapon_think == w_ready && func != w_ready && actor.weaponentity[slot].state == WS_RAISE) backtrace( "Tried to override initial weapon think function - should this really happen?"); t *= W_WeaponRateFactor(); @@ -678,13 +683,14 @@ bool forbidWeaponUse(entity player) void W_WeaponFrame(entity actor) { + int slot = 0; // TODO: unhardcode if (frametime) actor.weapon_frametime = frametime; - if (!actor.weaponentity || actor.health < 1) return; // Dead player can't use weapons and injure impulse commands + if (!actor.weaponentity[slot] || actor.health < 1) return; // Dead player can't use weapons and injure impulse commands if (forbidWeaponUse(actor)) { - if (actor.weaponentity.state != WS_CLEAR) + if (actor.weaponentity[slot].state != WS_CLEAR) { Weapon wpn = get_weaponinfo(actor.weapon); w_ready(wpn, actor, 0, (actor.BUTTON_ATCK ? 1 : 0) | (actor.BUTTON_ATCK2 ? 2 : 0)); @@ -696,7 +702,7 @@ void W_WeaponFrame(entity actor) { actor.weapon = 0; actor.switchingweapon = 0; - actor.weaponentity.state = WS_CLEAR; + actor.weaponentity[slot].state = WS_CLEAR; actor.weaponname = ""; // actor.items &= ~IT_AMMO; return; @@ -710,7 +716,7 @@ void W_WeaponFrame(entity actor) // Change weapon if (actor.weapon != actor.switchweapon) { - if (actor.weaponentity.state == WS_CLEAR) + if (actor.weaponentity[slot].state == WS_CLEAR) { // end switching! actor.switchingweapon = actor.switchweapon; @@ -723,7 +729,7 @@ void W_WeaponFrame(entity actor) actor.ammo_field = newwep.ammo_field; Weapon w = get_weaponinfo(actor.switchweapon); w.wr_setup(w); - actor.weaponentity.state = WS_RAISE; + actor.weaponentity[slot].state = WS_RAISE; // set our clip load to the load of the weapon we switched to, if it's reloadable if (newwep.spawnflags & WEP_FLAG_RELOADABLE && newwep.reloading_ammo) // prevent accessing undefined cvars @@ -736,14 +742,14 @@ void W_WeaponFrame(entity actor) actor.clip_load = actor.clip_size = 0; } - weapon_thinkf(actor, WFRAME_IDLE, newwep.switchdelay_raise, w_ready); + weapon_thinkf(actor, slot, WFRAME_IDLE, newwep.switchdelay_raise, w_ready); } - else if (actor.weaponentity.state == WS_DROP) + else if (actor.weaponentity[slot].state == WS_DROP) { // in dropping phase we can switch at any time actor.switchingweapon = actor.switchweapon; } - else if (actor.weaponentity.state == WS_READY) + else if (actor.weaponentity[slot].state == WS_READY) { // start switching! actor.switchingweapon = actor.switchweapon; @@ -754,20 +760,20 @@ void W_WeaponFrame(entity actor) #if INDEPENDENT_ATTACK_FINISHED true #else - ATTACK_FINISHED(actor) <= time + actor.weapon_frametime * 0.5 + ATTACK_FINISHED(actor, slot) <= time + actor.weapon_frametime * 0.5 #endif ) { sound(actor, CH_WEAPON_SINGLE, SND_WEAPON_SWITCH, VOL_BASE, ATTN_NORM); - actor.weaponentity.state = WS_DROP; - weapon_thinkf(actor, WFRAME_DONTCHANGE, oldwep.switchdelay_drop, w_clear); + actor.weaponentity[slot].state = WS_DROP; + weapon_thinkf(actor, slot, WFRAME_DONTCHANGE, oldwep.switchdelay_drop, w_clear); } } } // LordHavoc: network timing test code // if (actor.button0) - // print(ftos(frametime), " ", ftos(time), " >= ", ftos(ATTACK_FINISHED(actor)), " >= ", ftos(actor.weapon_nextthink), "\n"); + // print(ftos(frametime), " ", ftos(time), " >= ", ftos(ATTACK_FINISHED(actor, slot)), " >= ", ftos(actor.weapon_nextthink), "\n"); int w = actor.weapon; @@ -841,11 +847,12 @@ void W_WeaponFrame(entity actor) void W_AttachToShotorg(entity actor, entity flash, vector offset) { + int slot = 0; flash.owner = actor; flash.angles_z = random() * 360; - if (gettagindex(actor.weaponentity, "shot")) setattachment(flash, actor.weaponentity, "shot"); - else setattachment(flash, actor.weaponentity, "tag_shot"); + if (gettagindex(actor.weaponentity[slot], "shot")) setattachment(flash, actor.weaponentity[slot], "shot"); + else setattachment(flash, actor.weaponentity[slot], "tag_shot"); setorigin(flash, offset); entity xflash = spawn(); @@ -853,10 +860,10 @@ void W_AttachToShotorg(entity actor, entity flash, vector offset) flash.viewmodelforclient = actor; - if (actor.weaponentity.oldorigin.x > 0) + if (actor.weaponentity[slot].oldorigin.x > 0) { setattachment(xflash, actor.exteriorweaponentity, ""); - setorigin(xflash, actor.weaponentity.oldorigin + offset); + setorigin(xflash, actor.weaponentity[slot].oldorigin + offset); } else { @@ -933,7 +940,7 @@ void W_ReloadedAndReady(Weapon thiswep, entity actor, int slot, int fire) // then quickly switch to another weapon and back. Reloading is canceled, but the reload delay is still there, // so your weapon is disabled for a few seconds without reason - // ATTACK_FINISHED(actor) -= actor.reload_time - 1; + // ATTACK_FINISHED(actor, slot) -= actor.reload_time - 1; Weapon wpn = get_weaponinfo(actor.weapon); w_ready(wpn, actor, slot, (actor.BUTTON_ATCK ? 1 : 0) | (actor.BUTTON_ATCK2 ? 2 : 0)); @@ -941,6 +948,7 @@ void W_ReloadedAndReady(Weapon thiswep, entity actor, int slot, int fire) void W_Reload(entity actor, float sent_ammo_min, string sent_sound) { + int slot = 0; // set global values to work with entity e = get_weaponinfo(actor.weapon); @@ -992,12 +1000,12 @@ void W_Reload(entity actor, float sent_ammo_min, string sent_sound) } } - if (actor.weaponentity) + if (actor.weaponentity[slot]) { - if (actor.weaponentity.wframe == WFRAME_RELOAD) return; + if (actor.weaponentity[slot].wframe == WFRAME_RELOAD) return; // allow switching away while reloading, but this will cause a new reload! - actor.weaponentity.state = WS_READY; + actor.weaponentity[slot].state = WS_READY; } // now begin the reloading process @@ -1008,9 +1016,9 @@ void W_Reload(entity actor, float sent_ammo_min, string sent_sound) // then quickly switch to another weapon and back. Reloading is canceled, but the reload delay is still there, // so your weapon is disabled for a few seconds without reason - // ATTACK_FINISHED(actor) = max(time, ATTACK_FINISHED(actor)) + actor.reload_time + 1; + // ATTACK_FINISHED(actor, slot) = max(time, ATTACK_FINISHED(actor, slot)) + actor.reload_time + 1; - weapon_thinkf(actor, WFRAME_RELOAD, actor.reload_time, W_ReloadedAndReady); + weapon_thinkf(actor, slot, WFRAME_RELOAD, actor.reload_time, W_ReloadedAndReady); if (actor.clip_load < 0) actor.clip_load = 0; actor.old_clip_load = actor.clip_load; diff --git a/qcsrc/server/weapons/weaponsystem.qh b/qcsrc/server/weapons/weaponsystem.qh index 28f934406..c5ee7abb6 100644 --- a/qcsrc/server/weapons/weaponsystem.qh +++ b/qcsrc/server/weapons/weaponsystem.qh @@ -18,7 +18,7 @@ vector shotorg_adjust(vector vecs, bool y_is_right, bool visual, int algn); vector shotorg_adjust_values(vector vecs, bool y_is_right, bool visual, int algn); -void CL_SpawnWeaponentity(entity e); +void CL_SpawnWeaponentity(entity e, int slot); vector CL_Weapon_GetShotOrg(float wpn); @@ -38,12 +38,12 @@ float W_WeaponRateFactor(); float W_WeaponSpeedFactor(); -bool weapon_prepareattack(Weapon thiswep, entity actor, bool secondary, float attacktime); +bool weapon_prepareattack(Weapon thiswep, entity actor, int slot, bool secondary, float attacktime); -bool weapon_prepareattack_check(Weapon thiswep, entity actor, float secondary, float attacktime); +bool weapon_prepareattack_check(Weapon thiswep, entity actor, int slot, float secondary, float attacktime); -void weapon_prepareattack_do(entity actor, float secondary, float attacktime); +void weapon_prepareattack_do(entity actor, int slot, float secondary, float attacktime); -void weapon_thinkf(entity actor, float fr, float t, void(Weapon thiswep, entity actor, int slot, int fire) func); +void weapon_thinkf(entity actor, int slot, float fr, float t, void(Weapon thiswep, entity actor, int slot, int fire) func); #endif -- 2.39.2