From 931d24d4337e58557fa82a68aa8a740e523c2f22 Mon Sep 17 00:00:00 2001 From: Mario Date: Thu, 29 Sep 2016 11:50:28 +1000 Subject: [PATCH] Add a networked entity to hold weapon state --- qcsrc/client/_all.qh | 1 + qcsrc/client/hud/panel/ammo.qc | 4 +- qcsrc/client/hud/panel/weapons.qc | 6 +- qcsrc/client/main.qh | 3 - qcsrc/client/view.qc | 63 ++++---- qcsrc/common/_all.inc | 1 + qcsrc/common/_mod.inc | 1 + .../gamemodes/gamemode/nexball/nexball.qc | 16 ++- qcsrc/common/monsters/monster.qh | 2 +- qcsrc/common/monsters/monster/mage.qc | 3 +- qcsrc/common/monsters/monster/shambler.qc | 2 +- qcsrc/common/monsters/monster/spider.qc | 3 +- qcsrc/common/monsters/monster/wyvern.qc | 3 +- qcsrc/common/monsters/monster/zombie.qc | 2 +- qcsrc/common/monsters/sv_monsters.qc | 22 +-- .../common/mutators/mutator/buffs/sv_buffs.qc | 6 +- qcsrc/common/mutators/mutator/nix/sv_nix.qc | 12 +- qcsrc/common/mutators/mutator/overkill/hmg.qc | 6 +- qcsrc/common/mutators/mutator/overkill/rpc.qc | 2 +- .../mutators/mutator/overkill/sv_overkill.qc | 31 ++-- .../mutators/mutator/pinata/sv_pinata.qc | 6 +- qcsrc/common/state.qc | 4 - qcsrc/common/state.qh | 10 -- qcsrc/common/stats.qh | 2 - qcsrc/common/t_items.qc | 20 +-- .../turrets/turret/machinegun_weapon.qc | 2 +- qcsrc/common/turrets/turret/plasma.qc | 3 +- qcsrc/common/turrets/turret/plasma_dual.qc | 3 +- qcsrc/common/turrets/turret/walker_weapon.qc | 2 +- qcsrc/common/vehicles/sv_vehicles.qc | 14 +- qcsrc/common/vehicles/vehicle/bumblebee.qc | 15 +- qcsrc/common/vehicles/vehicle/spiderbot.qc | 9 +- qcsrc/common/weapons/all.qc | 19 +-- qcsrc/common/weapons/weapon/arc.qc | 6 +- qcsrc/common/weapons/weapon/blaster.qc | 4 +- qcsrc/common/weapons/weapon/crylink.qc | 6 +- qcsrc/common/weapons/weapon/devastator.qc | 13 +- qcsrc/common/weapons/weapon/electro.qc | 4 +- qcsrc/common/weapons/weapon/hagar.qc | 15 +- qcsrc/common/weapons/weapon/hlac.qc | 8 +- qcsrc/common/weapons/weapon/hook.qc | 6 +- qcsrc/common/weapons/weapon/machinegun.qc | 24 ++-- qcsrc/common/weapons/weapon/minelayer.qc | 17 +-- qcsrc/common/weapons/weapon/mortar.qc | 4 +- qcsrc/common/weapons/weapon/porto.qc | 5 +- qcsrc/common/weapons/weapon/rifle.qc | 12 +- qcsrc/common/weapons/weapon/seeker.qc | 13 +- qcsrc/common/weapons/weapon/shotgun.qc | 8 +- qcsrc/common/weapons/weapon/tuba.qc | 13 +- qcsrc/common/weapons/weapon/vaporizer.qc | 24 ++-- qcsrc/common/weapons/weapon/vortex.qc | 7 +- qcsrc/common/wepent.qc | 134 ++++++++++++++++++ qcsrc/common/wepent.qh | 28 ++++ qcsrc/server/bot/default/aim.qc | 6 +- qcsrc/server/bot/default/havocbot/havocbot.qc | 33 +++-- qcsrc/server/bot/default/scripting.qc | 12 +- qcsrc/server/client.qc | 39 ++--- qcsrc/server/defs.qh | 2 +- qcsrc/server/g_damage.qc | 14 +- qcsrc/server/g_damage.qh | 2 +- qcsrc/server/g_world.qc | 4 - qcsrc/server/impulse.qc | 38 +++-- qcsrc/server/miscfunctions.qc | 7 +- qcsrc/server/player.qc | 13 +- qcsrc/server/tests.qc | 3 +- qcsrc/server/weapons/hitplot.qc | 3 +- qcsrc/server/weapons/selection.qc | 77 +++++----- qcsrc/server/weapons/selection.qh | 21 +-- qcsrc/server/weapons/throwing.qc | 20 +-- qcsrc/server/weapons/throwing.qh | 4 +- qcsrc/server/weapons/tracing.qc | 12 +- qcsrc/server/weapons/tracing.qh | 4 +- qcsrc/server/weapons/weaponsystem.qc | 119 +++++++++------- qcsrc/server/weapons/weaponsystem.qh | 2 +- 74 files changed, 670 insertions(+), 414 deletions(-) create mode 100644 qcsrc/common/wepent.qc create mode 100644 qcsrc/common/wepent.qh diff --git a/qcsrc/client/_all.qh b/qcsrc/client/_all.qh index 077b5f450a..5593af1892 100644 --- a/qcsrc/client/_all.qh +++ b/qcsrc/client/_all.qh @@ -13,3 +13,4 @@ #include "miscfunctions.qh" #include +#include diff --git a/qcsrc/client/hud/panel/ammo.qc b/qcsrc/client/hud/panel/ammo.qc index e299d1416e..94545ac4bf 100644 --- a/qcsrc/client/hud/panel/ammo.qc +++ b/qcsrc/client/hud/panel/ammo.qc @@ -169,7 +169,9 @@ void HUD_Ammo() ammo_size.y = newSize; } - Weapon wep = switchweapon; + entity wepent = viewmodels[0]; // TODO: unhardcode + + Weapon wep = wepent.switchweapon; int i; bool infinite_ammo = (STAT(ITEMS) & IT_UNLIMITED_WEAPON_AMMO); row = column = 0; diff --git a/qcsrc/client/hud/panel/weapons.qc b/qcsrc/client/hud/panel/weapons.qc index db25d532a0..69fd82c9e0 100644 --- a/qcsrc/client/hud/panel/weapons.qc +++ b/qcsrc/client/hud/panel/weapons.qc @@ -373,10 +373,12 @@ void HUD_Weapons() switch_speed = frametime * autocvar_hud_panel_weapons_selection_speed; vector radius_size = weapon_size * (autocvar_hud_panel_weapons_selection_radius + 1); - if(switchweapon == WEP_Null) + entity wepent = viewmodels[0]; // TODO: unhardcode + + if(wepent.switchweapon == WEP_Null) panel_switchweapon = NULL; else if(!panel_switchweapon) - panel_switchweapon = switchweapon; + panel_switchweapon = wepent.switchweapon; // draw background behind currently selected weapon // do it earlier to make sure bg is drawn behind every weapon icons while it's moving diff --git a/qcsrc/client/main.qh b/qcsrc/client/main.qh index 54ed9e2c39..bbf69d28d1 100644 --- a/qcsrc/client/main.qh +++ b/qcsrc/client/main.qh @@ -53,9 +53,6 @@ bool button_zoom; bool spectatorbutton_zoom; bool button_attack2; -Weapon activeweapon; -Weapon switchingweapon; -Weapon switchweapon; float current_viewzoom; float zoomin_effect; float warmup_stage; diff --git a/qcsrc/client/view.qc b/qcsrc/client/view.qc index 3134a24ed2..36c0d1bc8c 100644 --- a/qcsrc/client/view.qc +++ b/qcsrc/client/view.qc @@ -283,7 +283,7 @@ void viewmodel_animate(entity this) void viewmodel_draw(entity this) { - if(!activeweapon || !autocvar_r_drawviewmodel) + if(!this.activeweapon || !autocvar_r_drawviewmodel) return; int mask = (intermission || (STAT(HEALTH) <= 0) || autocvar_chase_active) ? 0 : MASK_NORMAL; float a = this.alpha; @@ -292,7 +292,7 @@ void viewmodel_draw(entity this) if (invehicle) a = -1; else if (wasinvehicle) a = 1; wasinvehicle = invehicle; - Weapon wep = activeweapon; + Weapon wep = this.activeweapon; int c = entcs_GetClientColors(current_player); vector g = weaponentity_glowmod(wep, NULL, c); entity me = CSQCModel_server2csqc(player_localentnum - 1); @@ -353,9 +353,10 @@ void viewmodel_draw(entity this) setorigin(this, this.origin); } -entity viewmodel; +entity viewmodels[MAX_WEAPONSLOTS]; STATIC_INIT(viewmodel) { - viewmodel = new(viewmodel); + for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + viewmodels[slot] = new(viewmodel); } void Porto_Draw(entity this); @@ -371,7 +372,8 @@ const int polyline_length = 16; vector polyline[polyline_length]; void Porto_Draw(entity this) { - if (activeweapon != WEP_PORTO) return; + entity wepent = viewmodels[0]; // TODO: unhardcode + if (wepent.activeweapon != WEP_PORTO) return; if (spectatee_status) return; if (WEP_CVAR(porto, secondary)) return; if (intermission == 1) return; @@ -448,9 +450,11 @@ vector GetCurrentFov(float fov) zoomspeed = 3.5; zoomdir = button_zoom; + entity wepent = viewmodels[0]; // TODO: unhardcode + if(hud == HUD_NORMAL && !spectatee_status) - if(switchweapon == activeweapon) - if((activeweapon == WEP_VORTEX && !WEP_CVAR(vortex, secondary)) || (activeweapon == WEP_RIFLE && !WEP_CVAR(rifle, secondary))) // do NOT use switchweapon here + if(wepent.switchweapon == wepent.activeweapon) + if((wepent.activeweapon == WEP_VORTEX && !WEP_CVAR(vortex, secondary)) || (wepent.activeweapon == WEP_RIFLE && !WEP_CVAR(rifle, secondary))) // do NOT use switchweapon here zoomdir += button_attack2; if(spectatee_status > 0 || isdemo()) { @@ -631,7 +635,9 @@ float TrueAimCheck() ta = trueaim; mv = MOVE_NOMONSTERS; - switch(activeweapon) // WEAPONTODO + entity wepent = viewmodels[0]; // TODO: unhardcode + + switch(wepent.activeweapon) // WEAPONTODO { case WEP_TUBA: // no aim case WEP_PORTO: // shoots from eye @@ -806,9 +812,11 @@ void HitSound() { // varying sound pitch + entity wepent = viewmodels[0]; // TODO: unhardcode + static float hitsound_time_prev = 0; // HACK: the only way to get the arc to sound consistent with pitch shift is to ignore cl_hitsound_antispam_time - float arc_hack = activeweapon == WEP_ARC && autocvar_cl_hitsound >= 2; + float arc_hack = wepent.activeweapon == WEP_ARC && autocvar_cl_hitsound >= 2; if (arc_hack || COMPARE_INCREASING(time, hitsound_time_prev) > autocvar_cl_hitsound_antispam_time) { if (autocvar_cl_hitsound && unaccounted_damage) @@ -995,7 +1003,8 @@ void HUD_Crosshair(entity this) entity e = WEP_Null; if(autocvar_crosshair_per_weapon || (autocvar_crosshair_color_special == 1)) { - e = switchingweapon; + entity wepent = viewmodels[0]; // TODO: unhardcode + e = wepent.switchingweapon; if(e) { if(autocvar_crosshair_per_weapon) @@ -1153,9 +1162,10 @@ void HUD_Crosshair(entity this) if(vortex_charge_movingavg == 0) // this should only happen if we have just loaded up the game vortex_charge_movingavg = vortex_charge; + entity wepent = viewmodels[0]; // TODO: unhardcode // handle the values - if (autocvar_crosshair_ring && activeweapon == WEP_VORTEX && vortex_charge && autocvar_crosshair_ring_vortex) // ring around crosshair representing velocity-dependent damage for the vortex + if (autocvar_crosshair_ring && wepent.activeweapon == WEP_VORTEX && vortex_charge && autocvar_crosshair_ring_vortex) // ring around crosshair representing velocity-dependent damage for the vortex { if (vortex_chargepool || use_vortex_chargepool) { use_vortex_chargepool = 1; @@ -1175,14 +1185,14 @@ void HUD_Crosshair(entity this) ring_rgb = wcross_color; ring_image = "gfx/crosshair_ring_nexgun.tga"; } - else if (autocvar_crosshair_ring && activeweapon == WEP_MINE_LAYER && WEP_CVAR(minelayer, limit) && autocvar_crosshair_ring_minelayer) + else if (autocvar_crosshair_ring && wepent.activeweapon == WEP_MINE_LAYER && WEP_CVAR(minelayer, limit) && autocvar_crosshair_ring_minelayer) { ring_value = bound(0, STAT(LAYED_MINES) / WEP_CVAR(minelayer, limit), 1); // if you later need to use the count of bullets in another place, then add a float for it. For now, no need to. ring_alpha = autocvar_crosshair_ring_minelayer_alpha; ring_rgb = wcross_color; ring_image = "gfx/crosshair_ring.tga"; } - else if (activeweapon == WEP_HAGAR && STAT(HAGAR_LOAD) && autocvar_crosshair_ring_hagar) + else if (wepent.activeweapon == WEP_HAGAR && STAT(HAGAR_LOAD) && autocvar_crosshair_ring_hagar) { ring_value = bound(0, STAT(HAGAR_LOAD) / WEP_CVAR_SEC(hagar, load_max), 1); ring_alpha = autocvar_crosshair_ring_hagar_alpha; @@ -1205,12 +1215,12 @@ void HUD_Crosshair(entity this) // Note: This is to stop Taoki from complaining that the image doesn't match all potential balances. // if a new image for another weapon is added, add the code (and its respective file/value) here - if ((activeweapon == WEP_RIFLE) && (weapon_clipsize == 80)) + if ((wepent.activeweapon == WEP_RIFLE) && (weapon_clipsize == 80)) ring_image = "gfx/crosshair_ring_rifle.tga"; else ring_image = "gfx/crosshair_ring.tga"; } - else if ( autocvar_crosshair_ring && autocvar_crosshair_ring_arc && arc_heat && activeweapon == WEP_ARC ) + else if ( autocvar_crosshair_ring && autocvar_crosshair_ring_arc && arc_heat && wepent.activeweapon == WEP_ARC ) { ring_value = arc_heat; ring_alpha = (1-arc_heat)*autocvar_crosshair_ring_arc_cold_alpha + @@ -1699,7 +1709,8 @@ void CSQC_UpdateView(entity this, float w, float h) // run viewmodel_draw before updating view_angles to the angles calculated by WarpZone_FixView // viewmodel_draw needs to use the view_angles set by the engine on every CSQC_UpdateView call - viewmodel_draw(viewmodel); + for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + viewmodel_draw(viewmodels[slot]); // Render the Scene view_origin = getpropertyvec(VF_ORIGIN); @@ -1777,18 +1788,12 @@ void CSQC_UpdateView(entity this, float w, float h) ColorTranslateMode = autocvar_cl_stripcolorcodes; - // currently switching-to weapon (for crosshair) - switchingweapon = Weapons_from(STAT(SWITCHINGWEAPON)); - - // actually active weapon (for zoom) - activeweapon = Weapons_from(STAT(ACTIVEWEAPON)); - - switchweapon = Weapons_from(STAT(SWITCHWEAPON)); + entity wepent = viewmodels[0]; // TODO: unhardcode - if(last_switchweapon != switchweapon) + if(last_switchweapon != wepent.switchweapon) { weapontime = time; - last_switchweapon = switchweapon; + last_switchweapon = wepent.switchweapon; if(button_zoom && autocvar_cl_unpress_zoom_on_weapon_switch) { localcmd("-zoom\n"); @@ -1801,11 +1806,11 @@ void CSQC_UpdateView(entity this, float w, float h) button_attack2 = false; } } - if(last_activeweapon != activeweapon) + if(last_activeweapon != wepent.activeweapon) { - last_activeweapon = activeweapon; + last_activeweapon = wepent.activeweapon; - e = activeweapon; + e = wepent.activeweapon; if(e.netname != "") localcmd(strcat("\ncl_hook_activeweapon ", e.netname), "\n"); else @@ -1937,7 +1942,7 @@ void CSQC_UpdateView(entity this, float w, float h) if(autocvar_cl_reticle) { - Weapon wep = activeweapon; + Weapon wep = wepent.activeweapon; // Draw the aiming reticle for weapons that use it // reticle_type is changed to the item we are zooming / aiming with, to decide which reticle to use // It must be a persisted float for fading out to work properly (you let go of the zoom button for diff --git a/qcsrc/common/_all.inc b/qcsrc/common/_all.inc index 5177c9dfd1..3117f3e6e9 100644 --- a/qcsrc/common/_all.inc +++ b/qcsrc/common/_all.inc @@ -5,6 +5,7 @@ float autocvar_net_connecttimeout = 30; #include "animdecide.qc" #include "ent_cs.qc" #include "net_notice.qc" +#include "wepent.qc" #endif #include "mapinfo.qc" diff --git a/qcsrc/common/_mod.inc b/qcsrc/common/_mod.inc index 90edfa6185..0ac07a19aa 100644 --- a/qcsrc/common/_mod.inc +++ b/qcsrc/common/_mod.inc @@ -11,3 +11,4 @@ #include #include #include +#include diff --git a/qcsrc/common/gamemodes/gamemode/nexball/nexball.qc b/qcsrc/common/gamemodes/gamemode/nexball/nexball.qc index 1d2555e95e..15f1d265eb 100644 --- a/qcsrc/common/gamemodes/gamemode/nexball/nexball.qc +++ b/qcsrc/common/gamemodes/gamemode/nexball/nexball.qc @@ -190,12 +190,12 @@ void GiveBall(entity plyr, entity ball) } plyr.(weaponentity).weapons = plyr.weapons; - plyr.(weaponentity).m_switchweapon = PS(plyr).m_weapon; + plyr.m_switchweapon = plyr.(weaponentity).m_weapon; plyr.weapons = WEPSET(NEXBALL); Weapon w = WEP_NEXBALL; w.wr_resetplayer(w, plyr); - PS(plyr).m_switchweapon = WEP_NEXBALL; - W_SwitchWeapon(plyr, WEP_NEXBALL); + plyr.(weaponentity).m_switchweapon = WEP_NEXBALL; + W_SwitchWeapon(plyr, WEP_NEXBALL, weaponentity); } void DropBall(entity ball, vector org, vector vel) @@ -1000,8 +1000,8 @@ MUTATOR_HOOKFUNCTION(nb, PlayerPreThink) player.weapons = player.(weaponentity).weapons; Weapon w = WEP_NEXBALL; w.wr_resetplayer(w, player); - PS(player).m_switchweapon = player.(weaponentity).m_switchweapon; - W_SwitchWeapon(player, PS(player).m_switchweapon); + player.(weaponentity).m_switchweapon = player.m_switchweapon; + W_SwitchWeapon(player, player.(weaponentity).m_switchweapon, weaponentity); player.(weaponentity).weapons = '0 0 0'; } @@ -1053,15 +1053,17 @@ MUTATOR_HOOKFUNCTION(nb, PlayerPhysics) MUTATOR_HOOKFUNCTION(nb, ForbidThrowCurrentWeapon) { entity player = M_ARGV(0, entity); + .entity weaponentity = weaponentities[0]; // TODO: unhardcode - return PS(player).m_weapon == WEP_NEXBALL; + return player.(weaponentity).m_weapon == WEP_NEXBALL; } MUTATOR_HOOKFUNCTION(nb, ForbidDropCurrentWeapon) { entity player = M_ARGV(0, entity); + .entity weaponentity = weaponentities[0]; // TODO: unhardcode - return PS(player).m_weapon == WEP_MORTAR; // TODO: what is this for? + return player.(weaponentity).m_weapon == WEP_MORTAR; // TODO: what is this for? } MUTATOR_HOOKFUNCTION(nb, FilterItem) diff --git a/qcsrc/common/monsters/monster.qh b/qcsrc/common/monsters/monster.qh index babf6e4faf..8540d5cc2a 100644 --- a/qcsrc/common/monsters/monster.qh +++ b/qcsrc/common/monsters/monster.qh @@ -13,7 +13,7 @@ const int MON_FLAG_RIDE = 4096; // monster can be ridden in special modes const int MONSTER_SIZE_QUAKE = 8192; // entity properties of monsterinfo: -.bool(int, entity actor, entity targ) monster_attackfunc; +.bool(int, entity actor, entity targ, .entity weaponentity) monster_attackfunc; // animations .vector anim_blockend; diff --git a/qcsrc/common/monsters/monster/mage.qc b/qcsrc/common/monsters/monster/mage.qc index 30d09807f2..a39f0a2039 100644 --- a/qcsrc/common/monsters/monster/mage.qc +++ b/qcsrc/common/monsters/monster/mage.qc @@ -323,9 +323,8 @@ void M_Mage_Defend_Shield(entity this) this.anim_finished = time + 1; } -bool M_Mage_Attack(int attack_type, entity actor, entity targ) +bool M_Mage_Attack(int attack_type, entity actor, entity targ, .entity weaponentity) { - .entity weaponentity = weaponentities[0]; switch(attack_type) { case MONSTER_ATTACK_MELEE: diff --git a/qcsrc/common/monsters/monster/shambler.qc b/qcsrc/common/monsters/monster/shambler.qc index 8f84bdce31..38de8627a6 100644 --- a/qcsrc/common/monsters/monster/shambler.qc +++ b/qcsrc/common/monsters/monster/shambler.qc @@ -155,7 +155,7 @@ void M_Shambler_Attack_Lightning(entity this) .int state; -bool M_Shambler_Attack(int attack_type, entity actor, entity targ) +bool M_Shambler_Attack(int attack_type, entity actor, entity targ, .entity weaponentity) { switch(attack_type) { diff --git a/qcsrc/common/monsters/monster/spider.qc b/qcsrc/common/monsters/monster/spider.qc index d2cb8313e3..ed589d1d12 100644 --- a/qcsrc/common/monsters/monster/spider.qc +++ b/qcsrc/common/monsters/monster/spider.qc @@ -169,9 +169,8 @@ void M_Spider_Attack_Web(entity this) CSQCProjectile(proj, true, PROJECTILE_ELECTRO, true); } -bool M_Spider_Attack(int attack_type, entity actor, entity targ) +bool M_Spider_Attack(int attack_type, entity actor, entity targ, .entity weaponentity) { - .entity weaponentity = weaponentities[0]; switch(attack_type) { Weapon wep = WEP_SPIDER_ATTACK; diff --git a/qcsrc/common/monsters/monster/wyvern.qc b/qcsrc/common/monsters/monster/wyvern.qc index 3fd7ec9676..6f2b50e319 100644 --- a/qcsrc/common/monsters/monster/wyvern.qc +++ b/qcsrc/common/monsters/monster/wyvern.qc @@ -88,9 +88,8 @@ void M_Wyvern_Attack_Fireball_Touch(entity this, entity toucher) M_Wyvern_Attack_Fireball_Explode(this); } -bool M_Wyvern_Attack(int attack_type, entity actor, entity targ) +bool M_Wyvern_Attack(int attack_type, entity actor, entity targ, .entity weaponentity) { - .entity weaponentity = weaponentities[0]; switch(attack_type) { case MONSTER_ATTACK_MELEE: diff --git a/qcsrc/common/monsters/monster/zombie.qc b/qcsrc/common/monsters/monster/zombie.qc index c48c2108fa..edf6d92484 100644 --- a/qcsrc/common/monsters/monster/zombie.qc +++ b/qcsrc/common/monsters/monster/zombie.qc @@ -94,7 +94,7 @@ bool M_Zombie_Defend_Block(entity this) return true; } -bool M_Zombie_Attack(int attack_type, entity actor, entity targ) +bool M_Zombie_Attack(int attack_type, entity actor, entity targ, .entity weaponentity) { switch(attack_type) { diff --git a/qcsrc/common/monsters/sv_monsters.qc b/qcsrc/common/monsters/sv_monsters.qc index ff1a5d397e..c1414bfd48 100644 --- a/qcsrc/common/monsters/sv_monsters.qc +++ b/qcsrc/common/monsters/sv_monsters.qc @@ -412,16 +412,18 @@ bool Monster_Attack_Leap(entity this, vector anm, void(entity this, entity touch return true; } -void Monster_Attack_Check(entity this, entity targ) +void Monster_Attack_Check(entity this, entity targ, .entity weaponentity) { + int slot = weaponslot(weaponentity); + if((this == NULL || targ == NULL) || (!this.monster_attackfunc) - || (time < this.attack_finished_single[0]) + || (time < this.attack_finished_single[slot]) ) { return; } if(vdist(targ.origin - this.origin, <=, this.attack_range)) { - bool attack_success = this.monster_attackfunc(MONSTER_ATTACK_MELEE, this, targ); + bool attack_success = this.monster_attackfunc(MONSTER_ATTACK_MELEE, this, targ, weaponentity); if(attack_success == 1) Monster_Sound(this, monstersound_melee, 0, false, CH_VOICE); else if(attack_success > 0) @@ -430,7 +432,7 @@ void Monster_Attack_Check(entity this, entity targ) if(vdist(targ.origin - this.origin, >, this.attack_range)) { - float attack_success = this.monster_attackfunc(MONSTER_ATTACK_RANGED, this, targ); + float attack_success = this.monster_attackfunc(MONSTER_ATTACK_RANGED, this, targ, weaponentity); if(attack_success == 1) Monster_Sound(this, monstersound_melee, 0, false, CH_VOICE); else if(attack_success > 0) @@ -695,7 +697,7 @@ void Monster_Move(entity this, float runspeed, float walkspeed, float stpspeed) // update goal entity if lost if(this.target2 && this.goalentity.targetname != this.target2) { this.goalentity = find(NULL, targetname, this.target2); } - entity targ; + entity targ = this.goalentity; if(STAT(FROZEN, this) == 2) { @@ -781,8 +783,6 @@ void Monster_Move(entity this, float runspeed, float walkspeed, float stpspeed) } } - targ = this.goalentity; - if (MUTATOR_CALLHOOK(MonsterMove, this, runspeed, walkspeed, targ) || gameover || this.draggedby != NULL @@ -895,7 +895,8 @@ void Monster_Move(entity this, float runspeed, float walkspeed, float stpspeed) this.angles_y += turny; } - Monster_Attack_Check(this, this.enemy); + .entity weaponentity = weaponentities[0]; // TODO? + Monster_Attack_Check(this, this.enemy, weaponentity); } void Monster_Remove(entity this) @@ -1037,7 +1038,10 @@ void Monster_Dead(entity this, entity attacker, float gibbed) mon.mr_death(mon, this); if(this.candrop && this.weapon) - W_ThrowNewWeapon(this, this.weapon, 0, this.origin, randomvec() * 150 + '0 0 325'); + { + .entity weaponentity = weaponentities[0]; // TODO: unhardcode + W_ThrowNewWeapon(this, this.weapon, 0, this.origin, randomvec() * 150 + '0 0 325', weaponentity); + } } void Monster_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force) diff --git a/qcsrc/common/mutators/mutator/buffs/sv_buffs.qc b/qcsrc/common/mutators/mutator/buffs/sv_buffs.qc index 82fa2d33cb..0bd8ae98c8 100644 --- a/qcsrc/common/mutators/mutator/buffs/sv_buffs.qc +++ b/qcsrc/common/mutators/mutator/buffs/sv_buffs.qc @@ -841,9 +841,11 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerPreThink) }); } + .entity weaponentity = weaponentities[0]; // TODO: unhardcode + if(player.buffs & BUFF_AMMO.m_itemid) if(player.clip_size) - player.clip_load = player.(weapon_load[PS(player).m_switchweapon.m_id]) = player.clip_size; + player.clip_load = player.(weapon_load[player.(weaponentity).m_switchweapon.m_id]) = player.clip_size; if((player.buffs & BUFF_INVISIBLE.m_itemid) && (player.oldbuffs & BUFF_INVISIBLE.m_itemid)) if(player.alpha != autocvar_g_buffs_invisible_alpha) @@ -872,7 +874,7 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerPreThink) if(player.clip_load) player.buff_ammo_prev_clipload = player.clip_load; - player.clip_load = player.(weapon_load[PS(player).m_switchweapon.m_id]) = player.clip_size; + player.clip_load = player.(weapon_load[player.(weaponentity).m_switchweapon.m_id]) = player.clip_size; } BUFF_ONREM(BUFF_AMMO) diff --git a/qcsrc/common/mutators/mutator/nix/sv_nix.qc b/qcsrc/common/mutators/mutator/nix/sv_nix.qc index 97ed4361ba..9ea34f2894 100644 --- a/qcsrc/common/mutators/mutator/nix/sv_nix.qc +++ b/qcsrc/common/mutators/mutator/nix/sv_nix.qc @@ -63,8 +63,9 @@ REGISTER_MUTATOR(nix, cvar("g_nix") && !cvar("g_instagib") && !cvar("g_overkill" it.ammo_rockets = start_ammo_rockets; it.ammo_fuel = start_ammo_fuel; it.weapons = start_weapons; - if(!client_hasweapon(it, PS(it).m_weapon, true, false)) - PS(it).m_switchweapon = w_getbestweapon(it); + .entity weaponentity = weaponentities[0]; // TODO: unhardcode + if(!client_hasweapon(it, it.(weaponentity).m_weapon, true, false)) + it.(weaponentity).m_switchweapon = w_getbestweapon(it); }); } @@ -204,12 +205,13 @@ void NIX_GiveCurrentWeapon(entity this) this.weapons |= WEPSET(BLASTER); this.weapons |= e.m_wepset; + .entity weaponentity = weaponentities[0]; // TODO: unhardcode Weapon w = Weapons_from(nix_weapon); - if(PS(this).m_switchweapon != w) - if(!client_hasweapon(this, PS(this).m_switchweapon, true, false)) + if(this.(weaponentity).m_switchweapon != w) + if(!client_hasweapon(this, this.(weaponentity).m_switchweapon, true, false)) { if(client_hasweapon(this, w, true, false)) - W_SwitchWeapon(this, w); + W_SwitchWeapon(this, w, weaponentity); } } diff --git a/qcsrc/common/mutators/mutator/overkill/hmg.qc b/qcsrc/common/mutators/mutator/overkill/hmg.qc index 024fdb1cc7..ff9bbf9318 100644 --- a/qcsrc/common/mutators/mutator/overkill/hmg.qc +++ b/qcsrc/common/mutators/mutator/overkill/hmg.qc @@ -22,12 +22,12 @@ void W_HeavyMachineGun_Attack_Auto(Weapon thiswep, entity actor, .entity weapone if((!thiswep.wr_checkammo1(thiswep, actor) && !(actor.items & IT_UNLIMITED_WEAPON_AMMO)) || (!(actor.items & IT_SUPERWEAPON) && !(actor.items & IT_UNLIMITED_SUPERWEAPONS))) { - W_SwitchWeapon_Force(actor, w_getbestweapon(actor)); + W_SwitchWeapon_Force(actor, w_getbestweapon(actor), weaponentity); w_ready(thiswep, actor, weaponentity, fire); return; } - W_DecreaseAmmo(WEP_HMG, actor, WEP_CVAR(hmg, ammo)); + W_DecreaseAmmo(WEP_HMG, actor, WEP_CVAR(hmg, ammo), weaponentity); W_SetupShot (actor, weaponentity, true, 0, SND_UZI_FIRE, CH_WEAPON_A, WEP_CVAR(hmg, damage)); @@ -38,7 +38,7 @@ void W_HeavyMachineGun_Attack_Auto(Weapon thiswep, entity actor, .entity weapone } float hmg_spread = bound(WEP_CVAR(hmg, spread_min), WEP_CVAR(hmg, spread_min) + (WEP_CVAR(hmg, spread_add) * actor.misc_bulletcounter), WEP_CVAR(hmg, spread_max)); - fireBullet(actor, w_shotorg, w_shotdir, hmg_spread, WEP_CVAR(hmg, solidpenetration), WEP_CVAR(hmg, damage), WEP_CVAR(hmg, force), WEP_HMG.m_id, 0); + fireBullet(actor, weaponentity, w_shotorg, w_shotdir, hmg_spread, WEP_CVAR(hmg, solidpenetration), WEP_CVAR(hmg, damage), WEP_CVAR(hmg, force), WEP_HMG.m_id, 0); actor.misc_bulletcounter = actor.misc_bulletcounter + 1; diff --git a/qcsrc/common/mutators/mutator/overkill/rpc.qc b/qcsrc/common/mutators/mutator/overkill/rpc.qc index 122bdfc12c..32d51f9243 100644 --- a/qcsrc/common/mutators/mutator/overkill/rpc.qc +++ b/qcsrc/common/mutators/mutator/overkill/rpc.qc @@ -68,7 +68,7 @@ void W_RocketPropelledChainsaw_Attack (Weapon thiswep, entity actor, .entity wea entity missile = spawn(); //WarpZone_RefSys_SpawnSameRefSys(actor); entity flash = spawn (); - W_DecreaseAmmo(thiswep, actor, WEP_CVAR(rpc, ammo)); + W_DecreaseAmmo(thiswep, actor, WEP_CVAR(rpc, ammo), weaponentity); W_SetupShot_ProjectileSize (actor, weaponentity, '-3 -3 -3', '3 3 3', false, 5, SND_ROCKET_FIRE, CH_WEAPON_A, WEP_CVAR(rpc, damage)); Send_Effect(EFFECT_ROCKET_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1); PROJECTILE_MAKETRIGGER(missile); diff --git a/qcsrc/common/mutators/mutator/overkill/sv_overkill.qc b/qcsrc/common/mutators/mutator/overkill/sv_overkill.qc index ea7ed953ce..20d2ee7815 100644 --- a/qcsrc/common/mutators/mutator/overkill/sv_overkill.qc +++ b/qcsrc/common/mutators/mutator/overkill/sv_overkill.qc @@ -46,7 +46,8 @@ MUTATOR_HOOKFUNCTION(ok, W_DecreaseAmmo) entity actor = M_ARGV(0, entity); if (actor.ok_use_ammocharge) { - ok_DecreaseCharge(actor, PS(actor).m_weapon.m_id); + .entity weaponentity = weaponentities[0]; // TODO: unhardcode + ok_DecreaseCharge(actor, actor.(weaponentity).m_weapon.m_id); return true; } } @@ -152,7 +153,9 @@ MUTATOR_HOOKFUNCTION(ok, PlayerDies) ok_DropItem(frag_target, targ); - frag_target.ok_lastwep = PS(frag_target).m_switchweapon.m_id; + .entity weaponentity = weaponentities[0]; // TODO: unhardcode + + frag_target.ok_lastwep = frag_target.(weaponentity).m_switchweapon.m_id; } MUTATOR_HOOKFUNCTION(ok, MonsterDropItem) @@ -203,6 +206,7 @@ MUTATOR_HOOKFUNCTION(ok, PlayerPreThink) return; entity player = M_ARGV(0, entity); + .entity weaponentity = weaponentities[0]; // TODO: unhardcode if(IS_DEAD(player) || !IS_PLAYER(player) || STAT(FROZEN, player)) return; @@ -214,11 +218,11 @@ MUTATOR_HOOKFUNCTION(ok, PlayerPreThink) newwep = WEP_MACHINEGUN; if(player.ok_lastwep == WEP_RPC.m_id) newwep = WEP_VORTEX; - PS(player).m_switchweapon = newwep; + player.(weaponentity).m_switchweapon = newwep; player.ok_lastwep = 0; } - ok_IncreaseCharge(player, PS(player).m_weapon.m_id); + ok_IncreaseCharge(player, player.(weaponentity).m_weapon.m_id); if(PHYS_INPUT_BUTTON_ATCK2(player)) if(!forbidWeaponUse(player) || player.weapon_blocked) // allow if weapon is blocked @@ -227,11 +231,11 @@ MUTATOR_HOOKFUNCTION(ok, PlayerPreThink) player.jump_interval = time + WEP_CVAR_PRI(blaster, refire) * W_WeaponRateFactor(player); makevectors(player.v_angle); - Weapon oldwep = PS(player).m_weapon; - PS(player).m_weapon = WEP_BLASTER; + Weapon oldwep = player.(weaponentity).m_weapon; + player.(weaponentity).m_weapon = WEP_BLASTER; W_Blaster_Attack( player, - weaponentities[0], // TODO: unhardcode + weaponentity, WEP_BLASTER.m_id | HITTYPE_SECONDARY, WEP_CVAR_SEC(vaporizer, shotangle), WEP_CVAR_SEC(vaporizer, damage), @@ -243,23 +247,23 @@ MUTATOR_HOOKFUNCTION(ok, PlayerPreThink) WEP_CVAR_SEC(vaporizer, delay), WEP_CVAR_SEC(vaporizer, lifetime) ); - PS(player).m_weapon = oldwep; + player.(weaponentity).m_weapon = oldwep; } player.weapon_blocked = false; - player.ok_ammo_charge = player.ammo_charge[PS(player).m_weapon.m_id]; + player.ok_ammo_charge = player.ammo_charge[player.(weaponentity).m_weapon.m_id]; if(player.ok_use_ammocharge) - if(!ok_CheckWeaponCharge(player, PS(player).m_weapon.m_id)) + if(!ok_CheckWeaponCharge(player, player.(weaponentity).m_weapon.m_id)) { - if(autocvar_g_overkill_ammo_charge_notice && time > player.ok_notice_time && PHYS_INPUT_BUTTON_ATCK(player) && IS_REAL_CLIENT(player) && PS(player).m_weapon == PS(player).m_switchweapon) + if(autocvar_g_overkill_ammo_charge_notice && time > player.ok_notice_time && PHYS_INPUT_BUTTON_ATCK(player) && IS_REAL_CLIENT(player) && player.(weaponentity).m_weapon == player.(weaponentity).m_switchweapon) { //Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_OVERKILL_CHARGE); player.ok_notice_time = time + 2; play2(player, SND(DRYFIRE)); } - Weapon wpn = PS(player).m_weapon; + Weapon wpn = player.(weaponentity).m_weapon; .entity weaponentity = weaponentities[0]; // TODO: unhardcode if(player.(weaponentity).state != WS_CLEAR) w_ready(wpn, player, weaponentity, PHYS_INPUT_BUTTON_ATCK(player) | (PHYS_INPUT_BUTTON_ATCK2(player) << 1)); @@ -357,8 +361,9 @@ MUTATOR_HOOKFUNCTION(ok, SpectateCopy) { entity spectatee = M_ARGV(0, entity); entity client = M_ARGV(1, entity); + .entity weaponentity = weaponentities[0]; // TODO: unhardcode - client.ammo_charge[PS(client).m_weapon.m_id] = spectatee.ammo_charge[PS(spectatee).m_weapon.m_id]; + client.ammo_charge[client.(weaponentity).m_weapon.m_id] = spectatee.ammo_charge[spectatee.(weaponentity).m_weapon.m_id]; client.ok_use_ammocharge = spectatee.ok_use_ammocharge; } diff --git a/qcsrc/common/mutators/mutator/pinata/sv_pinata.qc b/qcsrc/common/mutators/mutator/pinata/sv_pinata.qc index bc3887e860..387c1c359f 100644 --- a/qcsrc/common/mutators/mutator/pinata/sv_pinata.qc +++ b/qcsrc/common/mutators/mutator/pinata/sv_pinata.qc @@ -6,11 +6,13 @@ MUTATOR_HOOKFUNCTION(pinata, PlayerDies) { entity frag_target = M_ARGV(2, entity); + .entity weaponentity = weaponentities[0]; // TODO: unhardcode + FOREACH(Weapons, it != WEP_Null, LAMBDA( if(frag_target.weapons & WepSet_FromWeapon(it)) - if(PS(frag_target).m_switchweapon != it) + if(frag_target.(weaponentity).m_switchweapon != it) if(W_IsWeaponThrowable(frag_target, it.m_id)) - W_ThrowNewWeapon(frag_target, it.m_id, false, CENTER_OR_VIEWOFS(frag_target), randomvec() * 175 + '0 0 325'); + W_ThrowNewWeapon(frag_target, it.m_id, false, CENTER_OR_VIEWOFS(frag_target), randomvec() * 175 + '0 0 325', weaponentity); )); return true; diff --git a/qcsrc/common/state.qc b/qcsrc/common/state.qc index 891461c6a4..882b256874 100644 --- a/qcsrc/common/state.qc +++ b/qcsrc/common/state.qc @@ -17,10 +17,6 @@ void PlayerState_detach(entity this) PS(this) = NULL; if (ps.m_client != this) return; // don't own state, spectator - ps.m_switchweapon = WEP_Null; - ps.m_weapon = WEP_Null; - ps.m_switchingweapon = WEP_Null; - ps.ps_push(ps, this); FOREACH_CLIENT(PS(it) == ps, { PS(it) = NULL; }); delete(ps); diff --git a/qcsrc/common/state.qh b/qcsrc/common/state.qh index 94b9bc325f..850e7ac9db 100644 --- a/qcsrc/common/state.qh +++ b/qcsrc/common/state.qh @@ -12,16 +12,6 @@ CLASS(PlayerState, Object) CONSTRUCT(PlayerState); this.m_client = client; } - ATTRIB(PlayerState, m_switchingweapon, Weapon, Weapons_from(-1)); - ATTRIB(PlayerState, m_switchweapon, Weapon, Weapons_from(-1)); - ATTRIB(PlayerState, m_weapon, Weapon, Weapons_from(-1)); - METHOD(PlayerState, ps_push, void(PlayerState this, entity cl)) - { - TC(PlayerState, this); - STAT(ACTIVEWEAPON, cl) = this.m_weapon.m_id; - STAT(SWITCHINGWEAPON, cl) = this.m_switchingweapon.m_id; - STAT(SWITCHWEAPON, cl) = this.m_switchweapon.m_id; - } ENDCLASS(PlayerState) .PlayerState _ps; diff --git a/qcsrc/common/stats.qh b/qcsrc/common/stats.qh index e6cc5530cf..5cc278b04f 100644 --- a/qcsrc/common/stats.qh +++ b/qcsrc/common/stats.qh @@ -59,9 +59,7 @@ REGISTER_STAT(KH_KEYS, int) REGISTER_STAT(SWITCHWEAPON, int) /** weapon currently being switched to (is copied from switchweapon once switch is possible) */ REGISTER_STAT(SWITCHINGWEAPON, int) -REGISTER_STAT(WEAPON_NEXTTHINK, float) #ifdef SVQC -SPECTATE_COPYFIELD(_STAT(WEAPON_NEXTTHINK)) float W_WeaponRateFactor(entity this); #endif REGISTER_STAT(WEAPONRATEFACTOR, float, W_WeaponRateFactor(this)) diff --git a/qcsrc/common/t_items.qc b/qcsrc/common/t_items.qc index f9f89a73fa..6949035771 100644 --- a/qcsrc/common/t_items.qc +++ b/qcsrc/common/t_items.qc @@ -675,6 +675,8 @@ float Item_GiveTo(entity item, entity player) float _switchweapon; float pickedup; + .entity weaponentity = weaponentities[0]; // TODO: unhardcode + // if nothing happens to player, just return without taking the item pickedup = false; _switchweapon = false; @@ -682,10 +684,10 @@ float Item_GiveTo(entity item, entity player) // if the player is using their best weapon before items are given, they // probably want to switch to an even better weapon after items are given if (player.autoswitch) - if (PS(player).m_switchweapon == w_getbestweapon(player)) + if (player.(weaponentity).m_switchweapon == w_getbestweapon(player)) _switchweapon = true; - if (!(player.weapons & WepSet_FromWeapon(PS(player).m_switchweapon))) + if (!(player.weapons & WepSet_FromWeapon(player.(weaponentity).m_switchweapon))) _switchweapon = true; pickedup |= Item_GiveAmmoTo(item, player, ammo_fuel, g_pickup_fuel_max, ITEM_MODE_FUEL); @@ -760,13 +762,13 @@ LABEL(skip) // crude hack to enforce switching weapons if(g_cts && item.itemdef.instanceOfWeaponPickup) { - W_SwitchWeapon_Force(player, Weapons_from(item.weapon)); + W_SwitchWeapon_Force(player, Weapons_from(item.weapon), weaponentity); return 1; } if (_switchweapon) - if (PS(player).m_switchweapon != w_getbestweapon(player)) - W_SwitchWeapon_Force(player, w_getbestweapon(player)); + if (player.(weaponentity).m_switchweapon != w_getbestweapon(player)) + W_SwitchWeapon_Force(player, w_getbestweapon(player), weaponentity); return 1; } @@ -1653,9 +1655,11 @@ float GiveItems(entity e, float beginarg, float endarg) got = 0; + .entity weaponentity = weaponentities[0]; // TODO: unhardcode + _switchweapon = false; if (e.autoswitch) - if (PS(e).m_switchweapon == w_getbestweapon(e)) + if (e.(weaponentity).m_switchweapon == w_getbestweapon(e)) _switchweapon = true; e.strength_finished = max(0, e.strength_finished - time); @@ -1821,10 +1825,10 @@ float GiveItems(entity e, float beginarg, float endarg) else e.superweapons_finished += time; - if (!(e.weapons & WepSet_FromWeapon(PS(e).m_switchweapon))) + if (!(e.weapons & WepSet_FromWeapon(e.(weaponentity).m_switchweapon))) _switchweapon = true; if(_switchweapon) - W_SwitchWeapon_Force(e, w_getbestweapon(e)); + W_SwitchWeapon_Force(e, w_getbestweapon(e), weaponentity); return got; } diff --git a/qcsrc/common/turrets/turret/machinegun_weapon.qc b/qcsrc/common/turrets/turret/machinegun_weapon.qc index 44c8d64599..c60cd3b37e 100644 --- a/qcsrc/common/turrets/turret/machinegun_weapon.qc +++ b/qcsrc/common/turrets/turret/machinegun_weapon.qc @@ -19,7 +19,7 @@ METHOD(MachineGunTurretAttack, wr_think, void(entity thiswep, entity actor, .ent actor.tur_head = actor; weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, 0, w_ready); } - fireBullet (actor, actor.tur_shotorg, actor.tur_shotdir_updated, actor.shot_spread, 0, actor.shot_dmg, actor.shot_force, DEATH_TURRET_MACHINEGUN.m_id, 0); + fireBullet (actor, weaponentity, 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(actor, weaponentity); setattachment(actor.(weaponentity).muzzle_flash, actor.tur_head, "tag_fire"); } diff --git a/qcsrc/common/turrets/turret/plasma.qc b/qcsrc/common/turrets/turret/plasma.qc index d161436ab0..ed7d4f1608 100644 --- a/qcsrc/common/turrets/turret/plasma.qc +++ b/qcsrc/common/turrets/turret/plasma.qc @@ -10,7 +10,8 @@ METHOD(PlasmaTurret, tr_attack, void(PlasmaTurret this, entity it)) { if(g_instagib) { - FireRailgunBullet (it, it.tur_shotorg, it.tur_shotorg + it.tur_shotdir_updated * MAX_SHOT_DISTANCE, 10000000000, + .entity weaponentity = weaponentities[0]; // TODO: unhardcode + FireRailgunBullet (it, weaponentity, it.tur_shotorg, it.tur_shotorg + it.tur_shotdir_updated * MAX_SHOT_DISTANCE, 10000000000, 800, 0, 0, 0, 0, DEATH_TURRET_PLASMA.m_id); Send_Effect(EFFECT_VORTEX_MUZZLEFLASH, it.tur_shotorg, it.tur_shotdir_updated * 1000, 1); diff --git a/qcsrc/common/turrets/turret/plasma_dual.qc b/qcsrc/common/turrets/turret/plasma_dual.qc index 9e6d80b2fd..b1e7d5850a 100644 --- a/qcsrc/common/turrets/turret/plasma_dual.qc +++ b/qcsrc/common/turrets/turret/plasma_dual.qc @@ -9,7 +9,8 @@ spawnfunc(turret_plasma_dual) { if (!turret_initialize(this, TUR_PLASMA_DUAL)) d METHOD(DualPlasmaTurret, tr_attack, void(DualPlasmaTurret thistur, entity it)) { if (g_instagib) { - FireRailgunBullet (it, it.tur_shotorg, it.tur_shotorg + it.tur_shotdir_updated * MAX_SHOT_DISTANCE, 10000000000, + .entity weaponentity = weaponentities[0]; // TODO: unhardcode + FireRailgunBullet (it, weaponentity, it.tur_shotorg, it.tur_shotorg + it.tur_shotdir_updated * MAX_SHOT_DISTANCE, 10000000000, 800, 0, 0, 0, 0, DEATH_TURRET_PLASMA.m_id); diff --git a/qcsrc/common/turrets/turret/walker_weapon.qc b/qcsrc/common/turrets/turret/walker_weapon.qc index 88b18b9198..9bcf902902 100644 --- a/qcsrc/common/turrets/turret/walker_weapon.qc +++ b/qcsrc/common/turrets/turret/walker_weapon.qc @@ -18,7 +18,7 @@ METHOD(WalkerTurretAttack, wr_think, void(entity thiswep, entity actor, .entity weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready); } sound (actor, CH_WEAPON_A, SND_UZI_FIRE, VOL_BASE, ATTEN_NORM); - fireBullet (actor, actor.tur_shotorg, actor.tur_shotdir_updated, actor.shot_spread, 0, actor.shot_dmg, actor.shot_force, DEATH_TURRET_WALK_GUN.m_id, 0); + fireBullet (actor, weaponentity, actor.tur_shotorg, actor.tur_shotdir_updated, actor.shot_spread, 0, actor.shot_dmg, actor.shot_force, DEATH_TURRET_WALK_GUN.m_id, 0); Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, actor.tur_shotorg, actor.tur_shotdir_updated * 1000, 1); } } diff --git a/qcsrc/common/vehicles/sv_vehicles.qc b/qcsrc/common/vehicles/sv_vehicles.qc index cd62f0746b..bcb0631869 100644 --- a/qcsrc/common/vehicles/sv_vehicles.qc +++ b/qcsrc/common/vehicles/sv_vehicles.qc @@ -806,7 +806,12 @@ void vehicles_exit(entity vehic, bool eject) player.view_ofs = STAT(PL_VIEW_OFS, NULL); player.event_damage = PlayerDamage; player.hud = HUD_NORMAL; - PS(player).m_switchweapon = vehic.m_switchweapon; + for(int slot = 0; slot < MAX_WEAPONSLOTS; ++ slot) + { + .entity weaponentity = weaponentities[slot]; + player.(weaponentity).m_switchweapon = vehic.(weaponentity).m_switchweapon; + delete(vehic.(weaponentity)); // no longer needed + } player.last_vehiclecheck = time + 3; player.vehicle_enter_delay = time + 2; @@ -976,7 +981,12 @@ void vehicles_enter(entity pl, entity veh) veh.colormap = pl.colormap; if(veh.tur_head) veh.tur_head.colormap = pl.colormap; - veh.m_switchweapon = PS(pl).m_switchweapon; + for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + { + .entity weaponentity = weaponentities[slot]; + veh.(weaponentity) = new(temp_wepent); + veh.(weaponentity).m_switchweapon = pl.(weaponentity).m_switchweapon; + } pl.hud = veh.vehicleid; pl.PlayerPhysplug = veh.PlayerPhysplug; diff --git a/qcsrc/common/vehicles/vehicle/bumblebee.qc b/qcsrc/common/vehicles/vehicle/bumblebee.qc index 3f5f404358..4f74c86369 100644 --- a/qcsrc/common/vehicles/vehicle/bumblebee.qc +++ b/qcsrc/common/vehicles/vehicle/bumblebee.qc @@ -236,7 +236,12 @@ void bumblebee_gunner_exit(entity this, int _exitflag) player.event_damage = PlayerDamage; player.hud = HUD_NORMAL; player.teleportable = TELEPORT_NORMAL; - PS(player).m_switchweapon = gunner.m_switchweapon; + for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + { + .entity weaponentity = weaponentities[slot]; + player.(weaponentity).m_switchweapon = gunner.(weaponentity).m_switchweapon; + delete(gunner.(weaponentity)); + } player.vehicle_enter_delay = time + 2; fixedmakevectors(vehic.angles); @@ -306,7 +311,13 @@ bool bumblebee_gunner_enter(entity this, entity player) RemoveGrapplingHook(player); - gunner.m_switchweapon = PS(player).m_switchweapon; + for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + { + .entity weaponentity = weaponentities[slot]; + + gunner.(weaponentity) = new(temp_wepent); + gunner.(weaponentity).m_switchweapon = player.(weaponentity).m_switchweapon; + } gunner.vehicle_exit = bumblebee_gunner_exit; gunner.vehicle_hudmodel.viewmodelforclient = player; diff --git a/qcsrc/common/vehicles/vehicle/spiderbot.qc b/qcsrc/common/vehicles/vehicle/spiderbot.qc index 347d2120aa..ddbd6e26d9 100644 --- a/qcsrc/common/vehicles/vehicle/spiderbot.qc +++ b/qcsrc/common/vehicles/vehicle/spiderbot.qc @@ -60,7 +60,11 @@ bool spiderbot_frame(entity this, float dt) PHYS_INPUT_BUTTON_ZOOM(this) = false; PHYS_INPUT_BUTTON_CROUCH(this) = false; - PS(this).m_switchweapon = WEP_Null; + for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + { + .entity weaponentity = weaponentities[slot]; + this.(weaponentity).m_switchweapon = WEP_Null; + } this.vehicle_weapon2mode = vehic.vehicle_weapon2mode; @@ -260,7 +264,8 @@ bool spiderbot_frame(entity this, float dt) v_forward = normalize(v_forward); v += v_forward * 50; - fireBullet(this, v, v_forward, autocvar_g_vehicle_spiderbot_minigun_spread, autocvar_g_vehicle_spiderbot_minigun_solidpenetration, + .entity weaponentity = weaponentities[0]; // TODO: unhardcode + fireBullet(this, weaponentity, v, v_forward, autocvar_g_vehicle_spiderbot_minigun_spread, autocvar_g_vehicle_spiderbot_minigun_solidpenetration, autocvar_g_vehicle_spiderbot_minigun_damage, autocvar_g_vehicle_spiderbot_minigun_force, DEATH_VH_SPID_MINIGUN.m_id, 0); sound (gun, CH_WEAPON_A, SND_UZI_FIRE, VOL_BASE, ATTEN_NORM); diff --git a/qcsrc/common/weapons/all.qc b/qcsrc/common/weapons/all.qc index cf55aa6521..1faa1a0455 100644 --- a/qcsrc/common/weapons/all.qc +++ b/qcsrc/common/weapons/all.qc @@ -557,21 +557,23 @@ NET_HANDLE(wframe, bool isNew) a.x = ReadCoord(); a.y = ReadCoord(); a.z = ReadCoord(); + int slot = ReadByte(); bool restartanim = ReadByte(); - anim_set(viewmodel, a, !restartanim, restartanim, restartanim); - viewmodel.state = ReadByte(); - viewmodel.weapon_nextthink = ReadFloat(); - viewmodel.alpha = ReadByte() / 255; - switch (viewmodel.state) + entity wepent = viewmodels[slot]; + anim_set(wepent, a, !restartanim, restartanim, restartanim); + wepent.state = ReadByte(); + wepent.weapon_nextthink = ReadFloat(); + wepent.alpha = ReadByte() / 255; + switch (wepent.state) { case WS_RAISE: - viewmodel.weapon_switchdelay = activeweapon.switchdelay_raise; + wepent.weapon_switchdelay = wepent.activeweapon.switchdelay_raise; break; case WS_DROP: - viewmodel.weapon_switchdelay = activeweapon.switchdelay_drop; + wepent.weapon_switchdelay = wepent.activeweapon.switchdelay_drop; break; default: - viewmodel.weapon_switchdelay = 0; + wepent.weapon_switchdelay = 0; break; } return true; @@ -588,6 +590,7 @@ void wframe_send(entity actor, entity weaponentity, vector a, bool restartanim) WriteCoord(channel, a.x); WriteCoord(channel, a.y); WriteCoord(channel, a.z); + WriteByte(channel, weaponslot(weaponentity.weaponentity_fld)); WriteByte(channel, restartanim); WriteByte(channel, weaponentity.state); WriteFloat(channel, weaponentity.weapon_nextthink); diff --git a/qcsrc/common/weapons/weapon/arc.qc b/qcsrc/common/weapons/weapon/arc.qc index a61dc0f031..5d2e9e240a 100644 --- a/qcsrc/common/weapons/weapon/arc.qc +++ b/qcsrc/common/weapons/weapon/arc.qc @@ -273,7 +273,7 @@ void W_Arc_Attack_Bolt(Weapon thiswep, entity actor, .entity weaponentity) { entity missile; - W_DecreaseAmmo(thiswep, actor, WEP_CVAR(arc, bolt_ammo)); + W_DecreaseAmmo(thiswep, actor, WEP_CVAR(arc, bolt_ammo), weaponentity); W_SetupShot(actor, weaponentity, false, 2, SND_LASERGUN_FIRE, CH_WEAPON_A, WEP_CVAR(arc, bolt_damage)); @@ -381,7 +381,7 @@ void W_Arc_Beam_Think(entity this) if(!(own.items & IT_UNLIMITED_WEAPON_AMMO)) { // note: this doesn't force the switch - W_SwitchToOtherWeapon(own); + W_SwitchToOtherWeapon(own, weaponentity); } delete(this); return; @@ -728,7 +728,7 @@ void Arc_Smoke(entity actor, .entity weaponentity) } if ( actor.arc_smoke_sound && ( actor.arc_overheat <= time || - !( PHYS_INPUT_BUTTON_ATCK(actor) || PHYS_INPUT_BUTTON_ATCK2(actor) ) ) || PS(actor).m_switchweapon != WEP_ARC ) + !( PHYS_INPUT_BUTTON_ATCK(actor) || PHYS_INPUT_BUTTON_ATCK2(actor) ) ) || actor.(weaponentity).m_switchweapon != WEP_ARC ) { actor.arc_smoke_sound = 0; sound(actor, CH_SHOTS_SINGLE, SND_Null, VOL_BASE, ATTEN_NORM); diff --git a/qcsrc/common/weapons/weapon/blaster.qc b/qcsrc/common/weapons/weapon/blaster.qc index 2eb8f00b41..b669db758a 100644 --- a/qcsrc/common/weapons/weapon/blaster.qc +++ b/qcsrc/common/weapons/weapon/blaster.qc @@ -196,8 +196,8 @@ METHOD(Blaster, wr_think, void(Blaster thiswep, entity actor, .entity weaponenti { case 0: // switch to last used weapon { - if(PS(actor).m_switchweapon == WEP_BLASTER) // don't do this if already switching - W_LastWeapon(actor); + if(actor.(weaponentity).m_switchweapon == WEP_BLASTER) // don't do this if already switching + W_LastWeapon(actor, weaponentity); break; } diff --git a/qcsrc/common/weapons/weapon/crylink.qc b/qcsrc/common/weapons/weapon/crylink.qc index 58214bf390..a6df25064f 100644 --- a/qcsrc/common/weapons/weapon/crylink.qc +++ b/qcsrc/common/weapons/weapon/crylink.qc @@ -354,7 +354,7 @@ void W_Crylink_Attack(Weapon thiswep, entity actor, .entity weaponentity) vector forward, right, up; float maxdmg; - W_DecreaseAmmo(thiswep, actor, WEP_CVAR_PRI(crylink, ammo)); + W_DecreaseAmmo(thiswep, actor, WEP_CVAR_PRI(crylink, ammo), weaponentity); maxdmg = WEP_CVAR_PRI(crylink, damage) * WEP_CVAR_PRI(crylink, shots); maxdmg *= 1 + WEP_CVAR_PRI(crylink, bouncedamagefactor) * WEP_CVAR_PRI(crylink, bounces); @@ -464,7 +464,7 @@ void W_Crylink_Attack2(Weapon thiswep, entity actor, .entity weaponentity) vector forward, right, up; float maxdmg; - W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(crylink, ammo)); + W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(crylink, ammo), weaponentity); maxdmg = WEP_CVAR_SEC(crylink, damage) * WEP_CVAR_SEC(crylink, shots); maxdmg *= 1 + WEP_CVAR_SEC(crylink, bouncedamagefactor) * WEP_CVAR_SEC(crylink, bounces); @@ -631,7 +631,7 @@ METHOD(Crylink, wr_think, void(entity thiswep, entity actor, .entity weaponentit { // ran out of ammo! actor.cnt = WEP_CRYLINK.m_id; - PS(actor).m_switchweapon = w_getbestweapon(actor); + actor.(weaponentity).m_switchweapon = w_getbestweapon(actor); } } } diff --git a/qcsrc/common/weapons/weapon/devastator.qc b/qcsrc/common/weapons/weapon/devastator.qc index 1fdb8d6ad6..35435abb55 100644 --- a/qcsrc/common/weapons/weapon/devastator.qc +++ b/qcsrc/common/weapons/weapon/devastator.qc @@ -115,7 +115,8 @@ void W_Devastator_Explode(entity this, entity directhitentity) ); Weapon thiswep = WEP_DEVASTATOR; - if(PS(this.realowner).m_weapon == thiswep) + .entity weaponentity = weaponentities[0]; // TODO: unhardcode + if(this.realowner.(weaponentity).m_weapon == thiswep) { if(this.realowner.(thiswep.ammo_field) < WEP_CVAR(devastator, ammo)) if(!(this.realowner.items & IT_UNLIMITED_WEAPON_AMMO)) @@ -123,7 +124,7 @@ void W_Devastator_Explode(entity this, entity directhitentity) this.realowner.cnt = WEP_DEVASTATOR.m_id; int slot = 0; // TODO: unhardcode ATTACK_FINISHED(this.realowner, slot) = time; - PS(this.realowner).m_switchweapon = w_getbestweapon(this.realowner); + this.realowner.(weaponentity).m_switchweapon = w_getbestweapon(this.realowner); } } delete(this); @@ -201,7 +202,7 @@ void W_Devastator_DoRemoteExplode(entity this, .entity weaponentity) ); Weapon thiswep = WEP_DEVASTATOR; - if(PS(this.realowner).m_weapon == thiswep) + if(this.realowner.(weaponentity).m_weapon == thiswep) { if(this.realowner.(thiswep.ammo_field) < WEP_CVAR(devastator, ammo)) if(!(this.realowner.items & IT_UNLIMITED_WEAPON_AMMO)) @@ -209,7 +210,7 @@ void W_Devastator_DoRemoteExplode(entity this, .entity weaponentity) this.realowner.cnt = WEP_DEVASTATOR.m_id; int slot = weaponslot(weaponentity); ATTACK_FINISHED(this.realowner, slot) = time; - PS(this.realowner).m_switchweapon = w_getbestweapon(this.realowner); + this.realowner.(weaponentity).m_switchweapon = w_getbestweapon(this.realowner); } } delete(this); @@ -361,7 +362,7 @@ void W_Devastator_Damage(entity this, entity inflictor, entity attacker, float d void W_Devastator_Attack(Weapon thiswep, entity actor, .entity weaponentity) { - W_DecreaseAmmo(thiswep, actor, WEP_CVAR(devastator, ammo)); + W_DecreaseAmmo(thiswep, actor, WEP_CVAR(devastator, ammo), weaponentity); W_SetupShot_ProjectileSize(actor, weaponentity, '-3 -3 -3', '3 3 3', false, 5, SND_ROCKET_FIRE, CH_WEAPON_A, WEP_CVAR(devastator, damage)); Send_Effect(EFFECT_ROCKET_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1); @@ -515,7 +516,7 @@ METHOD(Devastator, wr_think, void(entity thiswep, entity actor, .entity weaponen actor.rl_release[slot] = 1; if(fire & 2) - if(PS(actor).m_switchweapon == WEP_DEVASTATOR) + if(actor.(weaponentity).m_switchweapon == WEP_DEVASTATOR) { bool rockfound = false; IL_EACH(g_projectiles, it.realowner == actor && it.classname == "rocket", diff --git a/qcsrc/common/weapons/weapon/electro.qc b/qcsrc/common/weapons/weapon/electro.qc index 7e05241a49..b5ee5305d0 100644 --- a/qcsrc/common/weapons/weapon/electro.qc +++ b/qcsrc/common/weapons/weapon/electro.qc @@ -265,7 +265,7 @@ void W_Electro_Attack_Bolt(Weapon thiswep, entity actor, .entity weaponentity) { entity proj; - W_DecreaseAmmo(thiswep, actor, WEP_CVAR_PRI(electro, ammo)); + W_DecreaseAmmo(thiswep, actor, WEP_CVAR_PRI(electro, ammo), weaponentity); W_SetupShot_ProjectileSize( actor, @@ -410,7 +410,7 @@ void W_Electro_Orb_Damage(entity this, entity inflictor, entity attacker, float void W_Electro_Attack_Orb(Weapon thiswep, entity actor, .entity weaponentity) { - W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(electro, ammo)); + W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(electro, ammo), weaponentity); W_SetupShot_ProjectileSize( actor, diff --git a/qcsrc/common/weapons/weapon/hagar.qc b/qcsrc/common/weapons/weapon/hagar.qc index 9a178c03bb..5bc2994915 100644 --- a/qcsrc/common/weapons/weapon/hagar.qc +++ b/qcsrc/common/weapons/weapon/hagar.qc @@ -139,7 +139,7 @@ void W_Hagar_Attack(Weapon thiswep, entity actor, .entity weaponentity) { entity missile; - W_DecreaseAmmo(thiswep, actor, WEP_CVAR_PRI(hagar, ammo)); + W_DecreaseAmmo(thiswep, actor, WEP_CVAR_PRI(hagar, ammo), weaponentity); W_SetupShot(actor, weaponentity, false, 2, SND_HAGAR_FIRE, CH_WEAPON_A, WEP_CVAR_PRI(hagar, damage)); @@ -183,7 +183,7 @@ void W_Hagar_Attack2(Weapon thiswep, entity actor, .entity weaponentity) { entity missile; - W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(hagar, ammo)); + W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(hagar, ammo), weaponentity); W_SetupShot(actor, weaponentity, false, 2, SND_HAGAR_FIRE, CH_WEAPON_A, WEP_CVAR_SEC(hagar, damage)); @@ -334,7 +334,7 @@ void W_Hagar_Attack2_Load(Weapon thiswep, entity actor, .entity weaponentity) { // if we pressed primary fire while loading, unload all rockets and abort actor.(weaponentity).state = WS_READY; - W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(hagar, ammo) * actor.hagar_load * -1); // give back ammo + W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(hagar, ammo) * actor.hagar_load * -1, weaponentity); // give back ammo actor.hagar_load = 0; sound(actor, CH_WEAPON_A, SND_HAGAR_BEEP, VOL_BASE, ATTN_NORM); @@ -352,7 +352,7 @@ void W_Hagar_Attack2_Load(Weapon thiswep, entity actor, .entity weaponentity) { if(!actor.hagar_loadblock && actor.hagar_loadstep < time) { - W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(hagar, ammo)); + W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(hagar, ammo), weaponentity); actor.(weaponentity).state = WS_INUSE; actor.hagar_load += 1; sound(actor, CH_WEAPON_B, SND_HAGAR_LOAD, VOL_BASE * 0.8, ATTN_NORM); // sound is too loud according to most @@ -408,7 +408,7 @@ void W_Hagar_Attack2_Load(Weapon thiswep, entity actor, .entity weaponentity) if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO)) { // note: this doesn't force the switch - W_SwitchToOtherWeapon(actor); + W_SwitchToOtherWeapon(actor, weaponentity); return; } } @@ -425,7 +425,7 @@ void W_Hagar_Attack_Auto(Weapon thiswep, entity actor, .entity weaponentity, int if(!thiswep.wr_checkammo1(thiswep, actor)) if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO)) { - W_SwitchWeapon_Force(actor, w_getbestweapon(actor)); + W_SwitchWeapon_Force(actor, w_getbestweapon(actor), weaponentity); w_ready(thiswep, actor, weaponentity, fire); return; } @@ -490,7 +490,8 @@ METHOD(Hagar, wr_setup, void(entity thiswep, entity actor)) if(actor.hagar_load) { - W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(hagar, ammo) * actor.hagar_load * -1); // give back ammo if necessary + .entity weaponentity = weaponentities[0]; // TODO: unhardcode + W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(hagar, ammo) * actor.hagar_load * -1, weaponentity); // give back ammo if necessary actor.hagar_load = 0; } } diff --git a/qcsrc/common/weapons/weapon/hlac.qc b/qcsrc/common/weapons/weapon/hlac.qc index 79bf08193e..beb42d5f68 100644 --- a/qcsrc/common/weapons/weapon/hlac.qc +++ b/qcsrc/common/weapons/weapon/hlac.qc @@ -75,7 +75,7 @@ void W_HLAC_Attack(Weapon thiswep, entity actor, .entity weaponentity) entity missile; float spread; - W_DecreaseAmmo(thiswep, actor, WEP_CVAR_PRI(hlac, ammo)); + W_DecreaseAmmo(thiswep, actor, WEP_CVAR_PRI(hlac, ammo), weaponentity); spread = WEP_CVAR_PRI(hlac, spread_min) + (WEP_CVAR_PRI(hlac, spread_add) * actor.misc_bulletcounter); spread = min(spread,WEP_CVAR_PRI(hlac, spread_max)); @@ -168,7 +168,7 @@ void W_HLAC_Attack2(entity actor, .entity weaponentity) // weapon frames void W_HLAC_Attack_Frame(Weapon thiswep, entity actor, .entity weaponentity, int fire) { - if(PS(actor).m_weapon != PS(actor).m_switchweapon) // abort immediately if switching + if(actor.(weaponentity).m_weapon != actor.(weaponentity).m_switchweapon) // abort immediately if switching { w_ready(thiswep, actor, weaponentity, fire); return; @@ -179,7 +179,7 @@ void W_HLAC_Attack_Frame(Weapon thiswep, entity actor, .entity weaponentity, int if(!thiswep.wr_checkammo1(thiswep, actor)) if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO)) { - W_SwitchWeapon_Force(actor, w_getbestweapon(actor)); + W_SwitchWeapon_Force(actor, w_getbestweapon(actor), weaponentity); w_ready(thiswep, actor, weaponentity, fire); return; } @@ -200,7 +200,7 @@ void W_HLAC_Attack2_Frame(Weapon thiswep, entity actor, .entity weaponentity) { float i; - W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(hlac, ammo)); + W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(hlac, ammo), weaponentity); for(i=WEP_CVAR_SEC(hlac, shots);i>0;--i) W_HLAC_Attack2(actor, weaponentity); diff --git a/qcsrc/common/weapons/weapon/hook.qc b/qcsrc/common/weapons/weapon/hook.qc index 23e7c23ae5..38a4163833 100644 --- a/qcsrc/common/weapons/weapon/hook.qc +++ b/qcsrc/common/weapons/weapon/hook.qc @@ -196,7 +196,7 @@ METHOD(Hook, wr_think, void(entity thiswep, entity actor, .entity weaponentity, if(time > actor.hook_refire) if(weapon_prepareattack(thiswep, actor, weaponentity, false, -1)) { - W_DecreaseAmmo(thiswep, actor, thiswep.ammo_factor * WEP_CVAR_PRI(hook, ammo)); + W_DecreaseAmmo(thiswep, actor, thiswep.ammo_factor * WEP_CVAR_PRI(hook, ammo), weaponentity); actor.hook_state |= HOOK_FIRING; actor.hook_state |= HOOK_WAITING_FOR_RELEASE; weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(hook, animtime), w_ready); @@ -243,7 +243,7 @@ METHOD(Hook, wr_think, void(entity thiswep, entity actor, .entity weaponentity, { if( actor.ammo_fuel >= (time - actor.hook_time_fueldecrease) * hooked_fuel ) { - W_DecreaseAmmo(thiswep, actor, (time - actor.hook_time_fueldecrease) * hooked_fuel); + W_DecreaseAmmo(thiswep, actor, (time - actor.hook_time_fueldecrease) * hooked_fuel, weaponentity); actor.hook_time_fueldecrease = time; // decrease next frame again } @@ -251,7 +251,7 @@ METHOD(Hook, wr_think, void(entity thiswep, entity actor, .entity weaponentity, { actor.ammo_fuel = 0; actor.hook_state |= HOOK_REMOVING; - W_SwitchWeapon_Force(actor, w_getbestweapon(actor)); + W_SwitchWeapon_Force(actor, w_getbestweapon(actor), weaponentity); } } } diff --git a/qcsrc/common/weapons/weapon/machinegun.qc b/qcsrc/common/weapons/weapon/machinegun.qc index 81da28ddb0..dc6d28ad33 100644 --- a/qcsrc/common/weapons/weapon/machinegun.qc +++ b/qcsrc/common/weapons/weapon/machinegun.qc @@ -122,9 +122,9 @@ void W_MachineGun_Attack(Weapon thiswep, int deathtype, entity actor, .entity we ATTACK_FINISHED(actor, slot) = time + WEP_CVAR(machinegun, first_refire) * W_WeaponRateFactor(actor); if(actor.misc_bulletcounter == 1) - fireBullet(actor, 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); + fireBullet(actor, weaponentity, 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); else - fireBullet(actor, w_shotorg, w_shotdir, WEP_CVAR(machinegun, sustained_spread), WEP_CVAR(machinegun, solidpenetration), WEP_CVAR(machinegun, sustained_damage), WEP_CVAR(machinegun, sustained_force), deathtype, 0); + fireBullet(actor, weaponentity, w_shotorg, w_shotdir, WEP_CVAR(machinegun, sustained_spread), WEP_CVAR(machinegun, solidpenetration), WEP_CVAR(machinegun, sustained_damage), WEP_CVAR(machinegun, sustained_force), deathtype, 0); Send_Effect(EFFECT_MACHINEGUN_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1); @@ -139,15 +139,15 @@ void W_MachineGun_Attack(Weapon thiswep, int deathtype, entity actor, .entity we } if(actor.misc_bulletcounter == 1) - W_DecreaseAmmo(thiswep, actor, WEP_CVAR(machinegun, first_ammo)); + W_DecreaseAmmo(thiswep, actor, WEP_CVAR(machinegun, first_ammo), weaponentity); else - W_DecreaseAmmo(thiswep, actor, WEP_CVAR(machinegun, sustained_ammo)); + W_DecreaseAmmo(thiswep, actor, WEP_CVAR(machinegun, sustained_ammo), weaponentity); } // weapon frames void W_MachineGun_Attack_Frame(Weapon thiswep, entity actor, .entity weaponentity, int fire) { - if(PS(actor).m_weapon != PS(actor).m_switchweapon) // abort immediately if switching + if(actor.(weaponentity).m_weapon != actor.(weaponentity).m_switchweapon) // abort immediately if switching { w_ready(thiswep, actor, weaponentity, fire); return; @@ -157,7 +157,7 @@ void W_MachineGun_Attack_Frame(Weapon thiswep, entity actor, .entity weaponentit if(!thiswep.wr_checkammo2(thiswep, actor)) if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO)) { - W_SwitchWeapon_Force(actor, w_getbestweapon(actor)); + W_SwitchWeapon_Force(actor, w_getbestweapon(actor), weaponentity); w_ready(thiswep, actor, weaponentity, fire); return; } @@ -183,12 +183,12 @@ void W_MachineGun_Attack_Auto(Weapon thiswep, entity actor, .entity weaponentity if(!thiswep.wr_checkammo1(thiswep, actor)) if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO)) { - W_SwitchWeapon_Force(actor, w_getbestweapon(actor)); + W_SwitchWeapon_Force(actor, w_getbestweapon(actor), weaponentity); w_ready(thiswep, actor, weaponentity, fire); return; } - W_DecreaseAmmo(WEP_MACHINEGUN, actor, WEP_CVAR(machinegun, sustained_ammo)); + W_DecreaseAmmo(WEP_MACHINEGUN, actor, WEP_CVAR(machinegun, sustained_ammo), weaponentity); W_SetupShot(actor, weaponentity, true, 0, SND_UZI_FIRE, CH_WEAPON_A, WEP_CVAR(machinegun, sustained_damage)); if(!autocvar_g_norecoil) @@ -198,7 +198,7 @@ void W_MachineGun_Attack_Auto(Weapon thiswep, entity actor, .entity weaponentity } machinegun_spread = bound(WEP_CVAR(machinegun, spread_min), WEP_CVAR(machinegun, spread_min) + (WEP_CVAR(machinegun, spread_add) * actor.misc_bulletcounter), WEP_CVAR(machinegun, spread_max)); - fireBullet(actor, w_shotorg, w_shotdir, machinegun_spread, WEP_CVAR(machinegun, solidpenetration), WEP_CVAR(machinegun, sustained_damage), WEP_CVAR(machinegun, sustained_force), WEP_MACHINEGUN.m_id, 0); + fireBullet(actor, weaponentity, w_shotorg, w_shotdir, machinegun_spread, WEP_CVAR(machinegun, solidpenetration), WEP_CVAR(machinegun, sustained_damage), WEP_CVAR(machinegun, sustained_force), WEP_MACHINEGUN.m_id, 0); actor.misc_bulletcounter = actor.misc_bulletcounter + 1; @@ -227,7 +227,7 @@ void W_MachineGun_Attack_Burst(Weapon thiswep, entity actor, .entity weaponentit actor.punchangle_y = random() - 0.5; } - fireBullet(actor, w_shotorg, w_shotdir, WEP_CVAR(machinegun, burst_speed), WEP_CVAR(machinegun, solidpenetration), WEP_CVAR(machinegun, sustained_damage), WEP_CVAR(machinegun, sustained_force), WEP_MACHINEGUN.m_id, 0); + fireBullet(actor, weaponentity, w_shotorg, w_shotdir, WEP_CVAR(machinegun, burst_speed), WEP_CVAR(machinegun, solidpenetration), WEP_CVAR(machinegun, sustained_damage), WEP_CVAR(machinegun, sustained_force), WEP_MACHINEGUN.m_id, 0); Send_Effect(EFFECT_MACHINEGUN_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1); @@ -281,12 +281,12 @@ METHOD(MachineGun, wr_think, void(entity thiswep, entity actor, .entity weaponen if(!thiswep.wr_checkammo2(thiswep, actor)) if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO)) { - W_SwitchWeapon_Force(actor, w_getbestweapon(actor)); + W_SwitchWeapon_Force(actor, w_getbestweapon(actor), weaponentity); w_ready(thiswep, actor, weaponentity, fire); return; } - W_DecreaseAmmo(thiswep, actor, WEP_CVAR(machinegun, burst_ammo)); + W_DecreaseAmmo(thiswep, actor, WEP_CVAR(machinegun, burst_ammo), weaponentity); actor.misc_bulletcounter = WEP_CVAR(machinegun, burst) * -1; W_MachineGun_Attack_Burst(thiswep, actor, weaponentity, fire); diff --git a/qcsrc/common/weapons/weapon/minelayer.qc b/qcsrc/common/weapons/weapon/minelayer.qc index 5f5898aa41..35507c341f 100644 --- a/qcsrc/common/weapons/weapon/minelayer.qc +++ b/qcsrc/common/weapons/weapon/minelayer.qc @@ -126,17 +126,17 @@ void W_MineLayer_Explode(entity this, entity directhitentity) RadiusDamage(this, this.realowner, WEP_CVAR(minelayer, damage), WEP_CVAR(minelayer, edgedamage), WEP_CVAR(minelayer, radius), NULL, NULL, WEP_CVAR(minelayer, force), this.projectiledeathtype, directhitentity); - if(PS(this.realowner).m_weapon == WEP_MINE_LAYER) + .entity weaponentity = this.weaponentity_fld; + if(this.realowner.(weaponentity).m_weapon == WEP_MINE_LAYER) { entity own = this.realowner; Weapon w = WEP_MINE_LAYER; if(!w.wr_checkammo1(w, own)) { own.cnt = WEP_MINE_LAYER.m_id; - .entity weaponentity = this.weaponentity_fld; int slot = weaponslot(weaponentity); ATTACK_FINISHED(own, slot) = time; - PS(own).m_switchweapon = w_getbestweapon(own); + own.(weaponentity).m_switchweapon = w_getbestweapon(own); } } this.realowner.minelayer_mines -= 1; @@ -158,17 +158,17 @@ void W_MineLayer_DoRemoteExplode(entity this) RadiusDamage(this, this.realowner, WEP_CVAR(minelayer, remote_damage), WEP_CVAR(minelayer, remote_edgedamage), WEP_CVAR(minelayer, remote_radius), NULL, NULL, WEP_CVAR(minelayer, remote_force), this.projectiledeathtype | HITTYPE_BOUNCE, NULL); - if(PS(this.realowner).m_weapon == WEP_MINE_LAYER) + .entity weaponentity = this.weaponentity_fld; + if(this.realowner.(weaponentity).m_weapon == WEP_MINE_LAYER) { entity own = this.realowner; Weapon w = WEP_MINE_LAYER; if(!w.wr_checkammo1(w, own)) { own.cnt = WEP_MINE_LAYER.m_id; - .entity weaponentity = this.weaponentity_fld; int slot = weaponslot(weaponentity); ATTACK_FINISHED(own, slot) = time; - PS(own).m_switchweapon = w_getbestweapon(own); + own.(weaponentity).m_switchweapon = w_getbestweapon(own); } } this.realowner.minelayer_mines -= 1; @@ -273,7 +273,8 @@ void W_MineLayer_Think(entity this) } // remote detonation - if(PS(this.realowner).m_weapon == WEP_MINE_LAYER) + .entity weaponentity = this.weaponentity_fld; + if(this.realowner.(weaponentity).m_weapon == WEP_MINE_LAYER) if(!IS_DEAD(this.realowner)) if(this.minelayer_detonate) W_MineLayer_RemoteExplode(this); @@ -336,7 +337,7 @@ void W_MineLayer_Attack(Weapon thiswep, entity actor, .entity weaponentity) } } - W_DecreaseAmmo(thiswep, actor, WEP_CVAR(minelayer, ammo)); + W_DecreaseAmmo(thiswep, actor, WEP_CVAR(minelayer, ammo), weaponentity); W_SetupShot_ProjectileSize(actor, weaponentity, '-4 -4 -4', '4 4 4', false, 5, SND_MINE_FIRE, CH_WEAPON_A, WEP_CVAR(minelayer, damage)); Send_Effect(EFFECT_ROCKET_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1); diff --git a/qcsrc/common/weapons/weapon/mortar.qc b/qcsrc/common/weapons/weapon/mortar.qc index 1428cc4fa9..fa089083d9 100644 --- a/qcsrc/common/weapons/weapon/mortar.qc +++ b/qcsrc/common/weapons/weapon/mortar.qc @@ -212,7 +212,7 @@ void W_Mortar_Grenade_Touch2(entity this, entity toucher) void W_Mortar_Attack(Weapon thiswep, entity actor, .entity weaponentity) { - W_DecreaseAmmo(thiswep, actor, WEP_CVAR_PRI(mortar, ammo)); + W_DecreaseAmmo(thiswep, actor, WEP_CVAR_PRI(mortar, ammo), weaponentity); W_SetupShot_ProjectileSize(actor, weaponentity, '-3 -3 -3', '3 3 3', false, 4, SND_GRENADE_FIRE, CH_WEAPON_A, WEP_CVAR_PRI(mortar, damage)); w_shotdir = v_forward; // no TrueAim for grenades please @@ -262,7 +262,7 @@ void W_Mortar_Attack2(Weapon thiswep, entity actor, .entity weaponentity) { entity gren; - W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(mortar, ammo)); + W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(mortar, ammo), weaponentity); W_SetupShot_ProjectileSize(actor, weaponentity, '-3 -3 -3', '3 3 3', false, 4, SND_GRENADE_FIRE, CH_WEAPON_A, WEP_CVAR_SEC(mortar, damage)); w_shotdir = v_forward; // no TrueAim for grenades please diff --git a/qcsrc/common/weapons/weapon/porto.qc b/qcsrc/common/weapons/weapon/porto.qc index 3e4654fcbb..e47d5dd323 100644 --- a/qcsrc/common/weapons/weapon/porto.qc +++ b/qcsrc/common/weapons/weapon/porto.qc @@ -66,7 +66,7 @@ void W_Porto_Success(entity this) delete(this); } -string W_ThrowNewWeapon(entity own, float wpn, float doreduce, vector org, vector velo); +string W_ThrowNewWeapon(entity own, float wpn, float doreduce, vector org, vector velo, .entity weaponentity); void W_Porto_Fail(entity this, float failhard) { if(this.realowner == NULL) @@ -95,7 +95,8 @@ void W_Porto_Fail(entity this, float failhard) tracetoss(this, this); if(vdist(trace_endpos - this.realowner.origin, <, 128)) { - W_ThrowNewWeapon(this.realowner, WEP_PORTO.m_id, 0, this.origin, this.velocity); + .entity weaponentity = weaponentities[0]; // TODO: unhardcode + W_ThrowNewWeapon(this.realowner, WEP_PORTO.m_id, 0, this.origin, this.velocity, weaponentity); Send_Notification(NOTIF_ONE, this.realowner, MSG_CENTER, CENTER_PORTO_FAILED); } } diff --git a/qcsrc/common/weapons/weapon/rifle.qc b/qcsrc/common/weapons/weapon/rifle.qc index 478a315253..b290728e58 100644 --- a/qcsrc/common/weapons/weapon/rifle.qc +++ b/qcsrc/common/weapons/weapon/rifle.qc @@ -61,7 +61,7 @@ void W_Rifle_FireBullet(Weapon thiswep, .entity weaponentity, float pSpread, flo { float i; - W_DecreaseAmmo(thiswep, actor, pAmmo); + W_DecreaseAmmo(thiswep, actor, pAmmo, weaponentity); W_SetupShot(actor, weaponentity, true, 2, pSound, CH_WEAPON_A, pDamage * pShots); @@ -74,7 +74,7 @@ void W_Rifle_FireBullet(Weapon thiswep, .entity weaponentity, float pSpread, flo } for(i = 0; i < pShots; ++i) - fireBullet(actor, w_shotorg, w_shotdir, pSpread, pSolidPenetration, pDamage, pForce, deathtype, (pTracer ? EF_RED : EF_BLUE)); + fireBullet(actor, weaponentity, w_shotorg, w_shotdir, pSpread, pSolidPenetration, pDamage, pForce, deathtype, (pTracer ? EF_RED : EF_BLUE)); if(autocvar_g_casings >= 2) { @@ -101,14 +101,14 @@ void W_Rifle_BulletHail_Continue(Weapon thiswep, entity actor, .entity weaponent { float r, af; - Weapon sw = PS(actor).m_switchweapon; // make it not detect weapon changes as reason to abort firing + Weapon sw = actor.(weaponentity).m_switchweapon; // make it not detect weapon changes as reason to abort firing int slot = weaponslot(weaponentity); af = ATTACK_FINISHED(actor, slot); - PS(actor).m_switchweapon = PS(actor).m_weapon; + actor.(weaponentity).m_switchweapon = actor.(weaponentity).m_weapon; ATTACK_FINISHED(actor, slot) = time; r = weapon_prepareattack(thiswep, actor, weaponentity, actor.rifle_bullethail_frame == WFRAME_FIRE2, actor.rifle_bullethail_refire); - if(PS(actor).m_switchweapon == PS(actor).m_weapon) - PS(actor).m_switchweapon = sw; + if(actor.(weaponentity).m_switchweapon == actor.(weaponentity).m_weapon) + actor.(weaponentity).m_switchweapon = sw; if(r) { actor.rifle_bullethail_attackfunc(actor, weaponentity); diff --git a/qcsrc/common/weapons/weapon/seeker.qc b/qcsrc/common/weapons/weapon/seeker.qc index 268e1916ed..fb22362328 100644 --- a/qcsrc/common/weapons/weapon/seeker.qc +++ b/qcsrc/common/weapons/weapon/seeker.qc @@ -256,7 +256,7 @@ void W_Seeker_Missile_Animate(entity this) void W_Seeker_Fire_Missile(Weapon thiswep, entity actor, .entity weaponentity, vector f_diff, entity m_target) { - W_DecreaseAmmo(thiswep, actor, WEP_CVAR(seeker, missile_ammo)); + W_DecreaseAmmo(thiswep, actor, WEP_CVAR(seeker, missile_ammo), weaponentity); makevectors(actor.v_angle); W_SetupShot_ProjectileSize(actor, weaponentity, '-2 -2 -2', '2 2 2', false, 2, SND_SEEKER_FIRE, CH_WEAPON_A, 0); @@ -335,7 +335,7 @@ void W_Seeker_Fire_Flac(Weapon thiswep, entity actor, .entity weaponentity) vector f_diff; float c; - W_DecreaseAmmo(thiswep, actor, WEP_CVAR(seeker, flac_ammo)); + W_DecreaseAmmo(thiswep, actor, WEP_CVAR(seeker, flac_ammo), weaponentity); c = actor.bulletcounter % 4; switch(c) @@ -432,7 +432,8 @@ void W_Seeker_Vollycontroller_Think(entity this) // TODO: Merge this with W_Seek this.cnt = this.cnt - 1; Weapon thiswep = WEP_SEEKER; - if((!(this.realowner.items & IT_UNLIMITED_AMMO) && this.realowner.(thiswep.ammo_field) < WEP_CVAR(seeker, missile_ammo)) || (this.cnt <= -1) || (IS_DEAD(this.realowner)) || (PS(this.realowner).m_switchweapon != WEP_SEEKER)) + .entity weaponentity = this.weaponentity_fld; + if((!(this.realowner.items & IT_UNLIMITED_AMMO) && this.realowner.(thiswep.ammo_field) < WEP_CVAR(seeker, missile_ammo)) || (this.cnt <= -1) || (IS_DEAD(this.realowner)) || (this.realowner.(weaponentity).m_switchweapon != WEP_SEEKER)) { delete(this); return; @@ -444,7 +445,6 @@ void W_Seeker_Vollycontroller_Think(entity this) // TODO: Merge this with W_Seek oldenemy = own.enemy; own.enemy = this.enemy; - .entity weaponentity = this.weaponentity_fld; c = own.cnt % 4; switch(c) @@ -469,8 +469,9 @@ void W_Seeker_Vollycontroller_Think(entity this) // TODO: Merge this with W_Seek void W_Seeker_Tracker_Think(entity this) { + .entity weaponentity = weaponentities[0]; // TODO: unhardcode // commit suicide if: You die OR target dies OR you switch away from the seeker OR commit suicide if lifetime is up - if((IS_DEAD(this.realowner)) || (IS_DEAD(this.tag_target)) || (PS(this.realowner).m_switchweapon != WEP_SEEKER) + if((IS_DEAD(this.realowner)) || (IS_DEAD(this.tag_target)) || (this.realowner.(weaponentity).m_switchweapon != WEP_SEEKER) || (time > this.tag_time + WEP_CVAR(seeker, tag_tracker_lifetime))) { if(this) @@ -571,7 +572,7 @@ void W_Seeker_Tag_Touch(entity this, entity toucher) void W_Seeker_Fire_Tag(Weapon thiswep, entity actor, .entity weaponentity) { - W_DecreaseAmmo(thiswep, actor, WEP_CVAR(seeker, tag_ammo)); + W_DecreaseAmmo(thiswep, actor, WEP_CVAR(seeker, tag_ammo), weaponentity); W_SetupShot_ProjectileSize(actor, weaponentity, '-2 -2 -2', '2 2 2', false, 2, SND_TAG_FIRE, CH_WEAPON_A, WEP_CVAR(seeker, missile_damage) * WEP_CVAR(seeker, missile_count)); diff --git a/qcsrc/common/weapons/weapon/shotgun.qc b/qcsrc/common/weapons/weapon/shotgun.qc index 9ae0c6069a..13de3fb255 100644 --- a/qcsrc/common/weapons/weapon/shotgun.qc +++ b/qcsrc/common/weapons/weapon/shotgun.qc @@ -61,11 +61,11 @@ spawnfunc(weapon_shotgun) { weapon_defaultspawnfunc(this, WEP_SHOTGUN); } void W_Shotgun_Attack(Weapon thiswep, entity actor, .entity weaponentity, float isprimary) { - W_DecreaseAmmo(thiswep, actor, WEP_CVAR_PRI(shotgun, ammo)); + W_DecreaseAmmo(thiswep, actor, WEP_CVAR_PRI(shotgun, ammo), weaponentity); W_SetupShot(actor, weaponentity, true, 5, SND_SHOTGUN_FIRE, ((isprimary) ? CH_WEAPON_A : CH_WEAPON_SINGLE), WEP_CVAR_PRI(shotgun, damage) * WEP_CVAR_PRI(shotgun, bullets)); for(int sc = 0;sc < WEP_CVAR_PRI(shotgun, bullets);sc = sc + 1) - fireBullet(actor, w_shotorg, w_shotdir, WEP_CVAR_PRI(shotgun, spread), WEP_CVAR_PRI(shotgun, solidpenetration), WEP_CVAR_PRI(shotgun, damage), WEP_CVAR_PRI(shotgun, force), WEP_SHOTGUN.m_id, 0); + fireBullet(actor, weaponentity, w_shotorg, w_shotdir, WEP_CVAR_PRI(shotgun, spread), WEP_CVAR_PRI(shotgun, solidpenetration), WEP_CVAR_PRI(shotgun, damage), WEP_CVAR_PRI(shotgun, force), WEP_SHOTGUN.m_id, 0); Send_Effect(EFFECT_SHOTGUN_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, WEP_CVAR_PRI(shotgun, ammo)); @@ -202,7 +202,7 @@ void W_Shotgun_Attack3_Frame2(Weapon thiswep, entity actor, .entity weaponentity if (!thiswep.wr_checkammo2(thiswep, actor)) if (!(actor.items & IT_UNLIMITED_WEAPON_AMMO)) { - W_SwitchWeapon_Force(actor, w_getbestweapon(actor)); + W_SwitchWeapon_Force(actor, w_getbestweapon(actor), weaponentity); w_ready(thiswep, actor, weaponentity, fire); return; } @@ -216,7 +216,7 @@ void W_Shotgun_Attack3_Frame1(Weapon thiswep, entity actor, .entity weaponentity if (!thiswep.wr_checkammo2(thiswep, actor)) if (!(actor.items & IT_UNLIMITED_WEAPON_AMMO)) { - W_SwitchWeapon_Force(actor, w_getbestweapon(actor)); + W_SwitchWeapon_Force(actor, w_getbestweapon(actor), weaponentity); w_ready(thiswep, actor, weaponentity, fire); return; } diff --git a/qcsrc/common/weapons/weapon/tuba.qc b/qcsrc/common/weapons/weapon/tuba.qc index 546e59f241..8fa9e7fe5b 100644 --- a/qcsrc/common/weapons/weapon/tuba.qc +++ b/qcsrc/common/weapons/weapon/tuba.qc @@ -412,7 +412,12 @@ NET_HANDLE(tuba_instrument, bool) string s = (i == 0) ? "tuba" : (i == 1) ? "akordeon" : "kleinbottle" ; - CL_WeaponEntity_SetModel(viewmodel, s, true); + for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + { + entity wep = viewmodels[slot]; + if(wep.activeweapon == WEP_TUBA) + CL_WeaponEntity_SetModel(wep, s, true); + } } #endif #ifdef SVQC @@ -437,15 +442,15 @@ METHOD(Tuba, wr_reload, void(Tuba this, entity actor, .entity weaponentity)) { case 0: actor.tuba_instrument = 1; - actor.weaponname = "akordeon"; + actor.(weaponentity).weaponname = "akordeon"; break; case 1: actor.tuba_instrument = 2; - actor.weaponname = "kleinbottle"; + actor.(weaponentity).weaponname = "kleinbottle"; break; case 2: actor.tuba_instrument = 0; - actor.weaponname = "tuba"; + actor.(weaponentity).weaponname = "tuba"; break; } tuba_instrument_send(actor, actor.tuba_instrument); diff --git a/qcsrc/common/weapons/weapon/vaporizer.qc b/qcsrc/common/weapons/weapon/vaporizer.qc index e11e4d8d52..01c884785a 100644 --- a/qcsrc/common/weapons/weapon/vaporizer.qc +++ b/qcsrc/common/weapons/weapon/vaporizer.qc @@ -193,7 +193,7 @@ void W_Vaporizer_Attack(Weapon thiswep, entity actor, .entity weaponentity) yoda = 0; damage_goodhits = 0; - FireRailgunBullet(actor, w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, vaporizer_damage, 800, 0, 0, 0, 0, WEP_VAPORIZER.m_id); + FireRailgunBullet(actor, weaponentity, w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, vaporizer_damage, 800, 0, 0, 0, 0, WEP_VAPORIZER.m_id); // do this now, as goodhits is disabled below SendCSQCVaporizerBeamParticle(actor, damage_goodhits); @@ -212,7 +212,7 @@ void W_Vaporizer_Attack(Weapon thiswep, entity actor, .entity weaponentity) if(!(trace_dphitq3surfaceflags & (Q3SURFACEFLAG_SKY | Q3SURFACEFLAG_NOIMPACT))) W_RocketMinsta_Explosion(actor, trace_endpos); - W_DecreaseAmmo(thiswep, actor, ((g_instagib) ? 1 : WEP_CVAR_PRI(vaporizer, ammo))); + W_DecreaseAmmo(thiswep, actor, ((g_instagib) ? 1 : WEP_CVAR_PRI(vaporizer, ammo)), weaponentity); } void W_RocketMinsta_Laser_Explode (entity this) @@ -253,10 +253,10 @@ void W_RocketMinsta_Attack2(entity actor, .entity weaponentity) float spread = autocvar_g_rm_laser_spread; float rndspread = autocvar_g_rm_laser_spread_random; - Weapon w = PS(actor).m_weapon; - PS(actor).m_weapon = WEP_ELECTRO; + Weapon w = actor.(weaponentity).m_weapon; + actor.(weaponentity).m_weapon = WEP_ELECTRO; W_SetupShot_ProjectileSize (actor, weaponentity, '0 0 -3', '0 0 -3', false, 2, SND_CRYLINK_FIRE, CH_WEAPON_A, autocvar_g_rm_laser_damage); - PS(actor).m_weapon = w; + actor.(weaponentity).m_weapon = w; Send_Effect(EFFECT_ELECTRO_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1); @@ -307,10 +307,10 @@ void W_RocketMinsta_Attack3 (entity actor, .entity weaponentity) float counter = 0; float total = 1; - Weapon w = PS(actor).m_weapon; - PS(actor).m_weapon = WEP_ELECTRO; + Weapon w = actor.(weaponentity).m_weapon; + actor.(weaponentity).m_weapon = WEP_ELECTRO; W_SetupShot_ProjectileSize (actor, weaponentity, '0 0 -3', '0 0 -3', false, 2, SND_ELECTRO_FIRE2, CH_WEAPON_A, autocvar_g_rm_laser_damage); - PS(actor).m_weapon = w; + actor.(weaponentity).m_weapon = w; Send_Effect(EFFECT_ELECTRO_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1); @@ -404,12 +404,12 @@ METHOD(Vaporizer, wr_think, void(entity thiswep, entity actor, .entity weaponent // decrease ammo for the laser? if(WEP_CVAR_SEC(vaporizer, ammo)) - W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(vaporizer, ammo)); + W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(vaporizer, ammo), weaponentity); // ugly instagib hack to reuse the fire mode of the laser makevectors(actor.v_angle); - Weapon oldwep = PS(actor).m_weapon; // we can't avoid this hack - PS(actor).m_weapon = WEP_BLASTER; + Weapon oldwep = actor.(weaponentity).m_weapon; // we can't avoid this hack + actor.(weaponentity).m_weapon = WEP_BLASTER; W_Blaster_Attack( actor, weaponentity, @@ -424,7 +424,7 @@ METHOD(Vaporizer, wr_think, void(entity thiswep, entity actor, .entity weaponent WEP_CVAR_SEC(vaporizer, delay), WEP_CVAR_SEC(vaporizer, lifetime) ); - PS(actor).m_weapon = oldwep; + actor.(weaponentity).m_weapon = oldwep; // now do normal refire weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(vaporizer, animtime), w_ready); diff --git a/qcsrc/common/weapons/weapon/vortex.qc b/qcsrc/common/weapons/weapon/vortex.qc index bf3ce8185f..660c7549fd 100644 --- a/qcsrc/common/weapons/weapon/vortex.qc +++ b/qcsrc/common/weapons/weapon/vortex.qc @@ -148,7 +148,8 @@ MUTATOR_HOOKFUNCTION(vortex_charge, GetPressedKeys) // WEAPONTODO float xyspeed = vlen(vec2(player.velocity)); - if (PS(player).m_weapon == WEP_VORTEX && WEP_CVAR(vortex, charge) && WEP_CVAR(vortex, charge_velocity_rate) && xyspeed > WEP_CVAR(vortex, charge_minspeed)) + .entity weaponentity = weaponentities[0]; // TODO: unhardcode + if (player.(weaponentity).m_weapon == WEP_VORTEX && WEP_CVAR(vortex, charge) && WEP_CVAR(vortex, charge_velocity_rate) && xyspeed > WEP_CVAR(vortex, charge_minspeed)) { // add a maximum of charge_velocity_rate when going fast (f = 1), gradually increasing from minspeed (f = 0) to maxspeed xyspeed = min(xyspeed, WEP_CVAR(vortex, charge_maxspeed)); @@ -193,7 +194,7 @@ void W_Vortex_Attack(Weapon thiswep, entity actor, .entity weaponentity, float i yoda = 0; damage_goodhits = 0; - FireRailgunBullet(actor, w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, mydmg, myforce, mymindist, mymaxdist, myhalflife, myforcehalflife, WEP_VORTEX.m_id); + FireRailgunBullet(actor, weaponentity, w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, mydmg, myforce, mymindist, mymaxdist, myhalflife, myforcehalflife, WEP_VORTEX.m_id); if(yoda && flying) Send_Notification(NOTIF_ONE, actor, MSG_ANNCE, ANNCE_ACHIEVEMENT_YODA); @@ -208,7 +209,7 @@ void W_Vortex_Attack(Weapon thiswep, entity actor, .entity weaponentity, float i //beam and muzzle flash done on client SendCSQCVortexBeamParticle(charge); - W_DecreaseAmmo(thiswep, actor, myammo); + W_DecreaseAmmo(thiswep, actor, myammo, weaponentity); } .float vortex_chargepool_pauseregen_finished; diff --git a/qcsrc/common/wepent.qc b/qcsrc/common/wepent.qc new file mode 100644 index 0000000000..036867888d --- /dev/null +++ b/qcsrc/common/wepent.qc @@ -0,0 +1,134 @@ +#include "wepent.qh" + +#define WEPENT_SET_NORMAL(var, x) MACRO_BEGIN \ + var = x; \ +MACRO_END + +/** the engine player name strings are mutable! */ +#define WEPENT_SET_MUTABLE_STRING(var, x) MACRO_BEGIN \ + if (var) strunzone(var); \ + var = strzone(x); \ +MACRO_END + +.int w_sv_entnum; +.Weapon w_m_switchweapon; +.Weapon w_m_switchingweapon; +.Weapon w_m_weapon; +//.float w_weapon_nextthink; + +// #define PROP(public, fld, set, sv, cl) +#define WEPENT_NETPROPS(PROP) PROP(false, sv_entnum, WEPENT_SET_NORMAL, {}, {}) /* sentinel */ \ + PROP(false, m_switchweapon, WEPENT_SET_NORMAL, \ + { WriteByte(chan, this.m_switchweapon.m_id); }, \ + { (viewmodels[this.m_wepent_slot]).switchweapon = Weapons_from(ReadByte()); }) \ + \ + PROP(false, m_switchingweapon, WEPENT_SET_NORMAL, \ + { WriteByte(chan, this.m_switchingweapon.m_id); }, \ + { (viewmodels[this.m_wepent_slot]).switchingweapon = Weapons_from(ReadByte()); }) \ + \ + PROP(false, m_weapon, WEPENT_SET_NORMAL, \ + { WriteByte(chan, this.m_weapon.m_id); }, \ + { (viewmodels[this.m_wepent_slot]).activeweapon = Weapons_from(ReadByte()); }) \ + \ + /**/ + +#ifdef SVQC + + int WEPENT_PUBLICMASK = 0; + STATIC_INIT(WEPENT_PUBLICMASK) + { + int i = 0; + #define X(public, fld, set, sv, cl) { \ + if (public) { \ + WEPENT_PUBLICMASK |= BIT(i); \ + } \ + i += 1; \ + } + WEPENT_NETPROPS(X); + #undef X + if (i >= BITS(16 - 1)) LOG_FATAL("Exceeded WEPENT_NETPROPS limit"); + } + + bool _wepent_send(entity this, entity to, int sf, int chan) + { + sf |= this.m_forceupdate; + this.m_forceupdate = 0; + if (chan == MSG_ENTITY) + WriteHeader(chan, ENT_CLIENT_WEPENT); + else + WriteHeader(chan, CLIENT_WEPENT); + .entity weaponentity = this.weaponentity_fld; + WriteByte(chan, weaponslot(weaponentity)); + WriteShort(chan, sf); + int i = 0; + #define X(public, fld, set, sv, cl) { \ + if (sf & BIT(i)) { \ + sv; \ + } \ + i += 1; \ + } + WEPENT_NETPROPS(X); + #undef X + return true; + } + + bool wepent_send(entity this, entity to, int sf) + { + return _wepent_send(this, to, sf, MSG_ENTITY); + } + + void wepent_update(entity this) + { + int i = 0; + #define X(public, fld, set, sv, cl) { \ + if (this.w_##fld != this.fld) { \ + set(this.w_##fld, this.fld); \ + this.SendFlags |= BIT(i); \ + } \ + i += 1; \ + } + WEPENT_NETPROPS(X); + #undef X + } + + void wepent_link(entity wep) + { + Net_LinkEntity(wep, false, 0, wepent_send); + } + +#endif + +#ifdef CSQC + + bool ReadWepent(entity this) + { + this.m_wepent_slot = ReadByte(); + int sf = ReadShort(); + int i = 0; + #define X(public, fld, set, sv, cl) { \ + if (sf & BIT(i)) { \ + cl; \ + } \ + i += 1; \ + } + WEPENT_NETPROPS(X); + #undef X + return true; + } + + NET_HANDLE(ENT_CLIENT_WEPENT, bool isnew) + { + if (isnew) + { + make_pure(this); + this.classname = "wepent_receiver"; + } + return ReadWepent(this); + } + + NET_HANDLE(CLIENT_WEPENT, bool isnew) + { + return ReadWepent(NULL); + } + +#endif diff --git a/qcsrc/common/wepent.qh b/qcsrc/common/wepent.qh new file mode 100644 index 0000000000..77296018da --- /dev/null +++ b/qcsrc/common/wepent.qh @@ -0,0 +1,28 @@ +#pragma once + +REGISTER_NET_LINKED(ENT_CLIENT_WEPENT) +REGISTER_NET_TEMP(CLIENT_WEPENT) + +#ifdef SVQC + + bool wepent_send(entity this, entity to, int sf); + + void wepent_update(entity this); + + void wepent_link(entity wep); + + .int m_forceupdate; + + .Weapon m_switchweapon; + .Weapon m_weapon; + .Weapon m_switchingweapon; + +#endif + +#ifdef CSQC + .int m_wepent_slot; + + .Weapon activeweapon; + .Weapon switchingweapon; + .Weapon switchweapon; +#endif diff --git a/qcsrc/server/bot/default/aim.qc b/qcsrc/server/bot/default/aim.qc index 1624676b82..46d1775455 100644 --- a/qcsrc/server/bot/default/aim.qc +++ b/qcsrc/server/bot/default/aim.qc @@ -339,16 +339,18 @@ bool bot_aim(entity this, float shotspeed, float shotspeedupward, float maxshott hf = this.dphitcontentsmask; this.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE; + .entity weaponentity = weaponentities[0]; // TODO: unhardcode + shotspeed *= W_WeaponSpeedFactor(this); shotspeedupward *= W_WeaponSpeedFactor(this); if (!shotspeed) { - LOG_TRACE("bot_aim: WARNING: weapon ", PS(this).m_weapon.m_name, " shotspeed is zero!"); + LOG_TRACE("bot_aim: WARNING: weapon ", this.(weaponentity).m_weapon.m_name, " shotspeed is zero!"); shotspeed = 1000000; } if (!maxshottime) { - LOG_TRACE("bot_aim: WARNING: weapon ", PS(this).m_weapon.m_name, " maxshottime is zero!"); + LOG_TRACE("bot_aim: WARNING: weapon ", this.(weaponentity).m_weapon.m_name, " maxshottime is zero!"); maxshottime = 1; } makevectors(this.v_angle); diff --git a/qcsrc/server/bot/default/havocbot/havocbot.qc b/qcsrc/server/bot/default/havocbot/havocbot.qc index 45051b6c27..b3bc26bbfe 100644 --- a/qcsrc/server/bot/default/havocbot/havocbot.qc +++ b/qcsrc/server/bot/default/havocbot/havocbot.qc @@ -98,7 +98,8 @@ void havocbot_ai(entity this) if(this.weapons) { - Weapon w = PS(this).m_weapon; + .entity weaponentity = weaponentities[0]; // TODO: unhardcode + Weapon w = this.(weaponentity).m_weapon; w.wr_aim(w, this); if (autocvar_bot_nofire || IS_INDEPENDENT_PLAYER(this)) { @@ -108,7 +109,7 @@ void havocbot_ai(entity this) else { if(PHYS_INPUT_BUTTON_ATCK(this) || PHYS_INPUT_BUTTON_ATCK2(this)) - this.lastfiredweapon = PS(this).m_weapon.m_id; + this.lastfiredweapon = this.(weaponentity).m_weapon.m_id; } } else @@ -165,9 +166,10 @@ void havocbot_ai(entity this) if(skill >= 5) // bots can only look for unloaded weapons past this skill if(this.clip_load >= 0) // only if we're not reloading a weapon already { + .entity weaponentity = weaponentities[0]; // TODO: unhardcode FOREACH(Weapons, it != WEP_Null, LAMBDA( if((this.weapons & (it.m_wepset)) && (it.spawnflags & WEP_FLAG_RELOADABLE) && (this.weapon_load[it.m_id] < it.reloading_ammo)) - PS(this).m_switchweapon = it; + this.(weaponentity).m_switchweapon = it; )); } } @@ -598,7 +600,8 @@ void havocbot_movetogoal(entity this) return; } - PS(this).m_switchweapon = WEP_DEVASTATOR; + .entity weaponentity = weaponentities[0]; // TODO: unhardcode + this.(weaponentity).m_switchweapon = WEP_DEVASTATOR; this.v_angle_x = 90; PHYS_INPUT_BUTTON_ATCK(this) = true; this.rocketjumptime = time + WEP_CVAR(devastator, detonatedelay); @@ -1009,10 +1012,12 @@ void havocbot_chooseweapon(entity this) { int i; + .entity weaponentity = weaponentities[0]; // TODO: unhardcode + // ;) if(g_weaponarena_weapons == WEPSET(TUBA)) { - PS(this).m_switchweapon = WEP_TUBA; + this.(weaponentity).m_switchweapon = WEP_TUBA; return; } @@ -1020,11 +1025,11 @@ void havocbot_chooseweapon(entity this) if(this.enemy==NULL) { // If no weapon was chosen get the first available weapon - if(PS(this).m_weapon==WEP_Null) + if(this.(weaponentity).m_weapon==WEP_Null) FOREACH(Weapons, it != WEP_Null, LAMBDA( if(client_hasweapon(this, it, true, false)) { - PS(this).m_switchweapon = it; + this.(weaponentity).m_switchweapon = it; return; } )); @@ -1052,7 +1057,7 @@ void havocbot_chooseweapon(entity this) combo = false; if(autocvar_bot_ai_weapon_combo) - if(PS(this).m_weapon.m_id == this.lastfiredweapon) + if(this.(weaponentity).m_weapon.m_id == this.lastfiredweapon) if(af > combo_time) { combo = true; @@ -1070,9 +1075,9 @@ void havocbot_chooseweapon(entity this) w = bot_weapons_far[i]; if ( client_hasweapon(this, Weapons_from(w), true, false) ) { - if ((PS(this).m_weapon.m_id == w && combo) || havocbot_chooseweapon_checkreload(this, w)) + if ((this.(weaponentity).m_weapon.m_id == w && combo) || havocbot_chooseweapon_checkreload(this, w)) continue; - PS(this).m_switchweapon = Weapons_from(w); + this.(weaponentity).m_switchweapon = Weapons_from(w); return; } } @@ -1084,9 +1089,9 @@ void havocbot_chooseweapon(entity this) w = bot_weapons_mid[i]; if ( client_hasweapon(this, Weapons_from(w), true, false) ) { - if ((PS(this).m_weapon.m_id == w && combo) || havocbot_chooseweapon_checkreload(this, w)) + if ((this.(weaponentity).m_weapon.m_id == w && combo) || havocbot_chooseweapon_checkreload(this, w)) continue; - PS(this).m_switchweapon = Weapons_from(w); + this.(weaponentity).m_switchweapon = Weapons_from(w); return; } } @@ -1097,9 +1102,9 @@ void havocbot_chooseweapon(entity this) w = bot_weapons_close[i]; if ( client_hasweapon(this, Weapons_from(w), true, false) ) { - if ((PS(this).m_weapon.m_id == w && combo) || havocbot_chooseweapon_checkreload(this, w)) + if ((this.(weaponentity).m_weapon.m_id == w && combo) || havocbot_chooseweapon_checkreload(this, w)) continue; - PS(this).m_switchweapon = Weapons_from(w); + this.(weaponentity).m_switchweapon = Weapons_from(w); return; } } diff --git a/qcsrc/server/bot/default/scripting.qc b/qcsrc/server/bot/default/scripting.qc index e8355575ed..19baa587d5 100644 --- a/qcsrc/server/bot/default/scripting.qc +++ b/qcsrc/server/bot/default/scripting.qc @@ -568,8 +568,10 @@ float bot_cmd_select_weapon(entity this) if(id < WEP_FIRST || id > WEP_LAST) return CMD_STATUS_ERROR; + .entity weaponentity = weaponentities[0]; // TODO: unhardcode + if(client_hasweapon(this, Weapons_from(id), true, false)) - PS(this).m_switchweapon = Weapons_from(id); + this.(weaponentity).m_switchweapon = Weapons_from(id); else return CMD_STATUS_ERROR; @@ -1054,7 +1056,7 @@ float bot_cmd_debug_assert_canfire(entity this) if(f) { this.colormod = '0 8 8'; - LOG_INFO("Bot ", this.netname, " using ", this.weaponname, " wants to fire, inhibited by weaponentity state\n"); + LOG_INFO("Bot ", this.netname, " using ", this.(weaponentity).weaponname, " wants to fire, inhibited by weaponentity state\n"); } } else if(ATTACK_FINISHED(this, slot) > time) @@ -1062,7 +1064,7 @@ float bot_cmd_debug_assert_canfire(entity this) if(f) { this.colormod = '8 0 8'; - LOG_INFO("Bot ", this.netname, " using ", this.weaponname, " wants to fire, inhibited by ATTACK_FINISHED (", ftos(ATTACK_FINISHED(this, slot) - time), " seconds left)\n"); + LOG_INFO("Bot ", this.netname, " using ", this.(weaponentity).weaponname, " wants to fire, inhibited by ATTACK_FINISHED (", ftos(ATTACK_FINISHED(this, slot) - time), " seconds left)\n"); } } else if(this.tuba_note) @@ -1070,7 +1072,7 @@ float bot_cmd_debug_assert_canfire(entity this) if(f) { this.colormod = '8 0 0'; - LOG_INFO("Bot ", this.netname, " using ", this.weaponname, " wants to fire, bot still has an active tuba note\n"); + LOG_INFO("Bot ", this.netname, " using ", this.(weaponentity).weaponname, " wants to fire, bot still has an active tuba note\n"); } } else @@ -1078,7 +1080,7 @@ float bot_cmd_debug_assert_canfire(entity this) if(!f) { this.colormod = '8 8 0'; - LOG_INFO("Bot ", this.netname, " using ", this.weaponname, " thinks it has fired, but apparently did not; ATTACK_FINISHED says ", ftos(ATTACK_FINISHED(this, slot) - time), " seconds left\n"); + LOG_INFO("Bot ", this.netname, " using ", this.(weaponentity).weaponname, " thinks it has fired, but apparently did not; ATTACK_FINISHED says ", ftos(ATTACK_FINISHED(this, slot) - time), " seconds left\n"); } } diff --git a/qcsrc/server/client.qc b/qcsrc/server/client.qc index e42807ec5d..b3e87e03b9 100644 --- a/qcsrc/server/client.qc +++ b/qcsrc/server/client.qc @@ -23,6 +23,7 @@ #include "bot/api.qh" #include "../common/ent_cs.qh" +#include "../common/wepent.qh" #include #include @@ -342,10 +343,10 @@ void PutObserverInServer(entity this) this.weapons = '0 0 0'; this.drawonlytoclient = this; - this.weaponname = ""; this.weaponmodel = ""; for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) { + this.weaponentities[slot].weaponname = ""; this.weaponentities[slot] = NULL; } this.exteriorweaponentity = NULL; @@ -691,11 +692,18 @@ void PutClientInServer(entity this) delete(spot); // usefull for checking if there are spawnpoints, that let drop through the floor } - PS(this).m_switchweapon = w_getbestweapon(this); - this.cnt = -1; // W_LastWeapon will not complain - PS(this).m_weapon = WEP_Null; - this.weaponname = ""; - PS(this).m_switchingweapon = WEP_Null; + for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + { + .entity weaponentity = weaponentities[slot]; + if(slot == 0) + this.(weaponentity).m_switchweapon = w_getbestweapon(this); + else + this.(weaponentity).m_switchweapon = WEP_Null; + this.(weaponentity).weaponname = ""; + this.(weaponentity).m_switchingweapon = WEP_Null; + } + + this.cnt = -1; // TODO if (!warmup_stage && !this.alivetime) this.alivetime = time; @@ -2421,13 +2429,11 @@ void PlayerPreThink (entity this) { this.items &= ~this.items_added; - //for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) - //{ - //.entity weaponentity = weaponentities[slot]; - //W_WeaponFrame(this, weaponentity); - //} - .entity weaponentity = weaponentities[0]; // TODO - W_WeaponFrame(this, weaponentity); + for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + { + .entity weaponentity = weaponentities[slot]; + W_WeaponFrame(this, weaponentity); + } this.items_added = 0; if (this.items & ITEM_Jetpack.m_itemid && (this.items & ITEM_JetpackRegen.m_itemid || this.ammo_fuel >= 0.01)) @@ -2465,11 +2471,12 @@ void PlayerPreThink (entity this) } // WEAPONTODO: Add weapon request for this + .entity weaponentity = weaponentities[0]; // TODO: unhardcode if (!zoomstate_set) { SetZoomState(this, PHYS_INPUT_BUTTON_ZOOM(this) || PHYS_INPUT_BUTTON_ZOOMSCRIPT(this) - || (PHYS_INPUT_BUTTON_ATCK2(this) && PS(this).m_weapon == WEP_VORTEX) - || (PHYS_INPUT_BUTTON_ATCK2(this) && PS(this).m_weapon == WEP_RIFLE && WEP_CVAR(rifle, secondary) == 0) + || (PHYS_INPUT_BUTTON_ATCK2(this) && this.(weaponentity).m_weapon == WEP_VORTEX) + || (PHYS_INPUT_BUTTON_ATCK2(this) && this.(weaponentity).m_weapon == WEP_RIFLE && WEP_CVAR(rifle, secondary) == 0) ); } @@ -2493,7 +2500,7 @@ void PlayerPreThink (entity this) // WEAPONTODO: Move into weaponsystem somehow // if a player goes unarmed after holding a loaded weapon, empty his clip size and remove the crosshair ammo ring - if (PS(this).m_weapon == WEP_Null) + if (this.(weaponentity).m_weapon == WEP_Null) this.clip_load = this.clip_size = 0; } diff --git a/qcsrc/server/defs.qh b/qcsrc/server/defs.qh index b034968901..ce9d174035 100644 --- a/qcsrc/server/defs.qh +++ b/qcsrc/server/defs.qh @@ -210,7 +210,7 @@ float bot_waypoints_for_items; #else #define ATTACK_FINISHED_FOR(ent, w, slot) ((ent).attack_finished_single[slot]) #endif -#define ATTACK_FINISHED(ent, slot) ATTACK_FINISHED_FOR(ent, PS(ent).m_weapon.m_id, slot) +#define ATTACK_FINISHED(ent, slot) ATTACK_FINISHED_FOR(ent, ent.(weaponentity).m_weapon.m_id, slot) // assault game mode: Which team is attacking in this round? float assault_attacker_team; diff --git a/qcsrc/server/g_damage.qc b/qcsrc/server/g_damage.qc index cb43861acf..7a28ae7333 100644 --- a/qcsrc/server/g_damage.qc +++ b/qcsrc/server/g_damage.qc @@ -58,13 +58,15 @@ void GiveFrags (entity attacker, entity targ, float f, int deathtype) PlayerScore_Add(targ, SP_DEATHS, 1); + .entity weaponentity = weaponentities[0]; // TODO: unhardcode + if(targ != attacker) // not for suicides if(g_weaponarena_random) { // after a frag, exchange the current weapon (or the culprit, if detectable) by a new random weapon Weapon culprit = DEATH_WEAPONOF(deathtype); - if(!culprit) culprit = PS(attacker).m_weapon; - else if(!(attacker.weapons & (culprit.m_wepset))) culprit = PS(attacker).m_weapon; + if(!culprit) culprit = attacker.(weaponentity).m_weapon; + else if(!(attacker.weapons & (culprit.m_wepset))) culprit = attacker.(weaponentity).m_weapon; if(g_weaponarena_random_with_blaster && culprit == WEP_BLASTER) // WEAPONTODO: Shouldn't this be in a mutator? { @@ -97,8 +99,8 @@ void GiveFrags (entity attacker, entity targ, float f, int deathtype) } // after a frag, choose another random weapon set - if (!(attacker.weapons & WepSet_FromWeapon(PS(attacker).m_weapon))) - W_SwitchWeapon_Force(attacker, w_getbestweapon(attacker)); + if (!(attacker.weapons & WepSet_FromWeapon(attacker.(weaponentity).m_weapon))) + W_SwitchWeapon_Force(attacker, w_getbestweapon(attacker), weaponentity); } // FIXME fix the mess this is (we have REAL points now!) @@ -115,7 +117,9 @@ void GiveFrags (entity attacker, entity targ, float f, int deathtype) string AppendItemcodes(string s, entity player) { - int w = PS(player).m_weapon.m_id; + .entity weaponentity = weaponentities[0]; // TODO: unhardcode + + int w = player.(weaponentity).m_weapon.m_id; //if(w == 0) // w = player.switchweapon; if(w == 0) diff --git a/qcsrc/server/g_damage.qh b/qcsrc/server/g_damage.qh index 019c8fc9a8..9a4a8b95d7 100644 --- a/qcsrc/server/g_damage.qh +++ b/qcsrc/server/g_damage.qh @@ -55,7 +55,7 @@ float IsFlying(entity a); void UpdateFrags(entity player, int f); // NOTE: f=0 means still count as a (positive) kill, but count no frags for it -void W_SwitchWeapon_Force(Player this, Weapon w); +void W_SwitchWeapon_Force(Player this, Weapon w, .entity weaponentity); entity GiveFrags_randomweapons; void GiveFrags (entity attacker, entity targ, float f, int deathtype); diff --git a/qcsrc/server/g_world.qc b/qcsrc/server/g_world.qc index fe7822bc16..4af2430db7 100644 --- a/qcsrc/server/g_world.qc +++ b/qcsrc/server/g_world.qc @@ -2081,10 +2081,6 @@ void EndFrame() { antilag_record(it, it, altime); }); - FOREACH_CLIENT(PS(it), { - PlayerState s = PS(it); - s.ps_push(s, it); - }); systems_update(); IL_ENDFRAME(); } diff --git a/qcsrc/server/impulse.qc b/qcsrc/server/impulse.qc index 8a10a6d752..0324212069 100644 --- a/qcsrc/server/impulse.qc +++ b/qcsrc/server/impulse.qc @@ -60,7 +60,8 @@ this.impulse = IMP_weapon_group_##slot.impulse; \ return; \ } \ - W_NextWeaponOnImpulse(this, slot); \ + .entity weaponentity = weaponentities[0]; \ + W_NextWeaponOnImpulse(this, slot, weaponentity); \ } X(1) X(2) @@ -88,7 +89,8 @@ X(0) noref int prev = -1; \ noref int best = 0; \ noref int next = +1; \ - W_CycleWeapon(this, this.cvar_cl_weaponpriorities[slot], dir); \ + .entity weaponentity = weaponentities[0]; \ + W_CycleWeapon(this, this.cvar_cl_weaponpriorities[slot], dir, weaponentity); \ } X(0, prev) X(1, prev) @@ -135,7 +137,8 @@ X(9, next) this.impulse = IMP_weapon_byid_##i.impulse; \ return; \ } \ - W_SwitchWeapon(this, Weapons_from(WEP_FIRST + i)); \ + .entity weaponentity = weaponentities[0]; \ + W_SwitchWeapon(this, Weapons_from(WEP_FIRST + i), weaponentity); \ } X(0) X(1) @@ -171,7 +174,8 @@ IMPULSE(weapon_next_byid) this.impulse = IMP_weapon_next_byid.impulse; return; } - W_NextWeapon(this, 0); + .entity weaponentity = weaponentities[0]; // TODO: unhardcode + W_NextWeapon(this, 0, weaponentity); } IMPULSE(weapon_prev_byid) @@ -182,7 +186,8 @@ IMPULSE(weapon_prev_byid) this.impulse = IMP_weapon_prev_byid.impulse; return; } - W_PreviousWeapon(this, 0); + .entity weaponentity = weaponentities[0]; // TODO: unhardcode + W_PreviousWeapon(this, 0, weaponentity); } IMPULSE(weapon_next_bygroup) @@ -193,7 +198,8 @@ IMPULSE(weapon_next_bygroup) this.impulse = IMP_weapon_next_bygroup.impulse; return; } - W_NextWeapon(this, 1); + .entity weaponentity = weaponentities[0]; // TODO: unhardcode + W_NextWeapon(this, 1, weaponentity); } IMPULSE(weapon_prev_bygroup) @@ -204,7 +210,8 @@ IMPULSE(weapon_prev_bygroup) this.impulse = IMP_weapon_prev_bygroup.impulse; return; } - W_PreviousWeapon(this, 1); + .entity weaponentity = weaponentities[0]; // TODO: unhardcode + W_PreviousWeapon(this, 1, weaponentity); } IMPULSE(weapon_next_bypriority) @@ -215,7 +222,8 @@ IMPULSE(weapon_next_bypriority) this.impulse = IMP_weapon_next_bypriority.impulse; return; } - W_NextWeapon(this, 2); + .entity weaponentity = weaponentities[0]; // TODO: unhardcode + W_NextWeapon(this, 2, weaponentity); } IMPULSE(weapon_prev_bypriority) @@ -226,28 +234,32 @@ IMPULSE(weapon_prev_bypriority) this.impulse = IMP_weapon_prev_bypriority.impulse; return; } - W_PreviousWeapon(this, 2); + .entity weaponentity = weaponentities[0]; // TODO: unhardcode + W_PreviousWeapon(this, 2, weaponentity); } IMPULSE(weapon_last) { if (this.vehicle) return; if (IS_DEAD(this)) return; - W_LastWeapon(this); + .entity weaponentity = weaponentities[0]; // TODO: unhardcode + W_LastWeapon(this, weaponentity); } IMPULSE(weapon_best) { if (this.vehicle) return; if (IS_DEAD(this)) return; - W_SwitchWeapon(this, w_getbestweapon(this)); + .entity weaponentity = weaponentities[0]; // TODO: unhardcode + W_SwitchWeapon(this, w_getbestweapon(this), weaponentity); } IMPULSE(weapon_drop) { if (this.vehicle) return; if (IS_DEAD(this)) return; - W_ThrowWeapon(this, weaponentities[0], W_CalculateProjectileVelocity(this, this.velocity, v_forward * 750, false), '0 0 0', true); + .entity weaponentity = weaponentities[0]; // TODO: unhardcode + W_ThrowWeapon(this, weaponentity, W_CalculateProjectileVelocity(this, this.velocity, v_forward * 750, false), '0 0 0', true); } IMPULSE(weapon_reload) @@ -255,11 +267,11 @@ IMPULSE(weapon_reload) if (this.vehicle) return; if (IS_DEAD(this)) return; if (forbidWeaponUse(this)) return; - Weapon w = PS(this).m_weapon; entity actor = this; for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) { .entity weaponentity = weaponentities[slot]; + Weapon w = this.(weaponentity).m_weapon; w.wr_reload(w, actor, weaponentity); } } diff --git a/qcsrc/server/miscfunctions.qc b/qcsrc/server/miscfunctions.qc index 4b3d404bf3..00e33f0c4f 100644 --- a/qcsrc/server/miscfunctions.qc +++ b/qcsrc/server/miscfunctions.qc @@ -259,6 +259,8 @@ string formatmessage(entity this, string msg) replacement = substring(msg, p, 2); escape = substring(msg, p + 1, 1); + .entity weaponentity = weaponentities[0]; // TODO: unhardcode + switch(escape) { case "%": replacement = "%"; break; @@ -269,7 +271,7 @@ string formatmessage(entity this, string msg) case "l": replacement = NearestLocation(this.origin); break; case "y": replacement = NearestLocation(cursor); break; case "d": replacement = NearestLocation(this.death_origin); break; - case "w": replacement = ((PS(this).m_weapon == WEP_Null) ? ((PS(this).m_switchweapon == WEP_Null) ? Weapons_from(this.cnt) : PS(this).m_switchweapon) : PS(this).m_weapon).m_name; break; + case "w": replacement = ((this.(weaponentity).m_weapon == WEP_Null) ? ((this.(weaponentity).m_switchweapon == WEP_Null) ? Weapons_from(this.cnt) : this.(weaponentity).m_switchweapon) : this.(weaponentity).m_weapon).m_name; break; case "W": replacement = ammoitems; break; case "x": replacement = ((cursor_ent.netname == "" || !cursor_ent) ? "nothing" : cursor_ent.netname); break; case "s": replacement = ftos(vlen(this.velocity - this.velocity_z * '0 0 1')); break; @@ -446,8 +448,9 @@ void GetCvars(entity this, int f) // fixup of switchweapon (needed for LMS or when spectating is disabled, as PutClientInServer comes too early) if (f > 0) { + .entity weaponentity = weaponentities[0]; // TODO: unhardcode if (s == "cl_weaponpriority") - if (PS(this)) PS(this).m_switchweapon = w_getbestweapon(this); + if (this.(weaponentity)) this.(weaponentity).m_switchweapon = w_getbestweapon(this); if (s == "cl_allow_uidtracking") PlayerStats_GameReport_AddPlayer(this); } diff --git a/qcsrc/server/player.qc b/qcsrc/server/player.qc index e270f38df0..6bfee14b2c 100644 --- a/qcsrc/server/player.qc +++ b/qcsrc/server/player.qc @@ -486,6 +486,7 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage, valid_damage_for_weaponstats = 0; Weapon awep = WEP_Null; + .entity weaponentity = weaponentities[0]; // TODO: unhardcode if(vbot || IS_REAL_CLIENT(this)) if(abot || IS_REAL_CLIENT(attacker)) @@ -493,7 +494,7 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage, if(DIFF_TEAM(this, attacker)) { if(DEATH_ISSPECIAL(deathtype)) - awep = PS(attacker).m_weapon; + awep = attacker.(weaponentity).m_weapon; else awep = DEATH_WEAPONOF(deathtype); valid_damage_for_weaponstats = 1; @@ -503,7 +504,7 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage, da = da - max(this.armorvalue, 0); if(valid_damage_for_weaponstats) { - WeaponStats_LogDamage(awep.m_id, abot, PS(this).m_weapon.m_id, vbot, dh + da); + WeaponStats_LogDamage(awep.m_id, abot, this.(weaponentity).m_weapon.m_id, vbot, dh + da); } if (dh + da) { @@ -522,7 +523,7 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage, } if(valid_damage_for_weaponstats) - WeaponStats_LogKill(awep.m_id, abot, PS(this).m_weapon.m_id, vbot); + WeaponStats_LogKill(awep.m_id, abot, this.(weaponentity).m_weapon.m_id, vbot); if(autocvar_sv_gentle < 1) if(sound_allowed(MSG_BROADCAST, attacker)) @@ -561,13 +562,12 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage, MUTATOR_CALLHOOK(PlayerDies, inflictor, attacker, this, deathtype, damage); excess = M_ARGV(4, float); - Weapon wep = PS(this).m_weapon; + Weapon wep = this.(weaponentity).m_weapon; /*for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) { .entity weaponentity = weaponentities[slot]; wep.wr_playerdeath(wep, this, weaponentity); }*/ - .entity weaponentity = weaponentities[0]; // TODO: unhardcode wep.wr_playerdeath(wep, this, weaponentity); RemoveGrapplingHook(this); @@ -592,7 +592,8 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage, // clear waypoints WaypointSprite_PlayerDead(this); // throw a weapon - SpawnThrownWeapon(this, this.origin + (this.mins + this.maxs) * 0.5, PS(this).m_switchweapon.m_id); + .entity weaponentity = weaponentities[0]; // TODO: unhardcode + SpawnThrownWeapon(this, this.origin + (this.mins + this.maxs) * 0.5, this.(weaponentity).m_switchweapon.m_id, weaponentity); // become fully visible this.alpha = default_player_alpha; diff --git a/qcsrc/server/tests.qc b/qcsrc/server/tests.qc index 96674db702..388c4af7b8 100644 --- a/qcsrc/server/tests.qc +++ b/qcsrc/server/tests.qc @@ -25,8 +25,9 @@ TEST(Weapons, Hurt) PHYS_INPUT_BUTTON_ATCK(it) = true; it.items |= IT_UNLIMITED_AMMO; Weapon wep = WEP_VORTEX; + .entity weaponentity = weaponentities[0]; // TODO: unhardcode W_GiveWeapon(it, wep.m_id); - W_SwitchWeapon_Force(it, wep); + W_SwitchWeapon_Force(it, wep, weaponentity); it = b; PHYS_INPUT_BUTTON_JUMP(it) = true; diff --git a/qcsrc/server/weapons/hitplot.qc b/qcsrc/server/weapons/hitplot.qc index 372f7357b4..2e1c4058df 100644 --- a/qcsrc/server/weapons/hitplot.qc +++ b/qcsrc/server/weapons/hitplot.qc @@ -73,7 +73,8 @@ void W_HitPlotAnalysis(entity player, vector screenforward, vector screenright, antilag_takeback(trace_ent, store, time - lag); hitplot = W_HitPlotNormalizedUntransform(org, trace_ent, screenforward, screenright, screenup, trace_endpos); antilag_restore(trace_ent, store); - fputs(player.hitplotfh, strcat(ftos(hitplot.x), " ", ftos(hitplot.y), " ", ftos(hitplot.z), " ", ftos(PS(player).m_switchweapon.m_id), "\n")); + .entity weaponentity = weaponentities[0]; // TODO: unhardcode + fputs(player.hitplotfh, strcat(ftos(hitplot.x), " ", ftos(hitplot.y), " ", ftos(hitplot.z), " ", ftos(player.(weaponentity).m_switchweapon.m_id), "\n")); //print(strcat(ftos(hitplot_x), " ", ftos(hitplot_y), " ", ftos(hitplot_z), "\n")); } } diff --git a/qcsrc/server/weapons/selection.qc b/qcsrc/server/weapons/selection.qc index 56df6c3a2c..da66310944 100644 --- a/qcsrc/server/weapons/selection.qc +++ b/qcsrc/server/weapons/selection.qc @@ -119,7 +119,7 @@ bool client_hasweapon(entity this, Weapon wpn, float andammo, bool complain) return false; } -float W_GetCycleWeapon(entity this, string weaponorder, float dir, float imp, float complain, float skipmissing) +float W_GetCycleWeapon(entity this, string weaponorder, float dir, float imp, float complain, float skipmissing, .entity weaponentity) { // We cannot tokenize in this function, as GiveItems calls this // function. Thus we must use car/cdr. @@ -130,10 +130,10 @@ float W_GetCycleWeapon(entity this, string weaponorder, float dir, float imp, fl float weaponcur; entity wep; - if(skipmissing || this.selectweapon == 0) - weaponcur = PS(this).m_switchweapon.m_id; + if(skipmissing || this.(weaponentity).selectweapon == 0) + weaponcur = this.(weaponentity).m_switchweapon.m_id; else - weaponcur = this.selectweapon; + weaponcur = this.(weaponentity).selectweapon; if(dir == 0) switchtonext = 1; @@ -231,20 +231,20 @@ float W_GetCycleWeapon(entity this, string weaponorder, float dir, float imp, fl return 0; } -void W_SwitchWeapon_Force(Player this, Weapon wep) +void W_SwitchWeapon_Force(Player this, Weapon wep, .entity weaponentity) { - TC(Player, this); TC(Weapon, wep); - this.cnt = PS(this).m_switchweapon.m_id; - PS(this).m_switchweapon = wep; - this.selectweapon = wep.m_id; + TC(Weapon, wep); + this.(weaponentity).cnt = this.(weaponentity).m_switchweapon.m_id; + this.(weaponentity).m_switchweapon = wep; + this.(weaponentity).selectweapon = wep.m_id; } // perform weapon to attack (weaponstate and attack_finished check is here) -void W_SwitchToOtherWeapon(entity this) +void W_SwitchToOtherWeapon(entity this, .entity weaponentity) { // hack to ensure it switches to an OTHER weapon (in case the other fire mode still has ammo, we want that anyway) Weapon ww; - WepSet set = WepSet_FromWeapon(PS(this).m_weapon); + WepSet set = WepSet_FromWeapon(this.(weaponentity).m_weapon); if (this.weapons & set) { this.weapons &= ~set; @@ -256,72 +256,69 @@ void W_SwitchToOtherWeapon(entity this) ww = w_getbestweapon(this); } if (ww == WEP_Null) return; - W_SwitchWeapon_Force(this, ww); + W_SwitchWeapon_Force(this, ww, weaponentity); } -void W_SwitchWeapon(entity this, Weapon w) +void W_SwitchWeapon(entity this, Weapon w, .entity weaponentity) { - if (PS(this).m_switchweapon != w) + if(this.(weaponentity).m_switchweapon != w) { - if (client_hasweapon(this, w, true, true)) - W_SwitchWeapon_Force(this, w); + if(client_hasweapon(this, w, true, true)) + W_SwitchWeapon_Force(this, w, weaponentity); else - this.selectweapon = w.m_id; // update selectweapon ANYWAY + this.(weaponentity).selectweapon = w.m_id; // update selectweapon anyway } - else if(!forbidWeaponUse(this)) { + else if(!forbidWeaponUse(this)) + { entity actor = this; - for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) - { - .entity weaponentity = weaponentities[slot]; - w.wr_reload(w, actor, weaponentity); - } + w.wr_reload(w, actor, weaponentity); } } -void W_CycleWeapon(entity this, string weaponorder, float dir) +void W_CycleWeapon(entity this, string weaponorder, float dir, .entity weaponentity) { float w; - w = W_GetCycleWeapon(this, weaponorder, dir, -1, 1, true); + w = W_GetCycleWeapon(this, weaponorder, dir, -1, 1, true, weaponentity); if(w > 0) - W_SwitchWeapon(this, Weapons_from(w)); + W_SwitchWeapon(this, Weapons_from(w), weaponentity); } -void W_NextWeaponOnImpulse(entity this, float imp) +void W_NextWeaponOnImpulse(entity this, float imp, .entity weaponentity) { float w; - w = W_GetCycleWeapon(this, this.cvar_cl_weaponpriority, +1, imp, 1, (this.cvar_cl_weaponimpulsemode == 0)); + w = W_GetCycleWeapon(this, this.cvar_cl_weaponpriority, +1, imp, 1, (this.cvar_cl_weaponimpulsemode == 0), weaponentity); if(w > 0) - W_SwitchWeapon(this, Weapons_from(w)); + W_SwitchWeapon(this, Weapons_from(w), weaponentity); } // next weapon -void W_NextWeapon(entity this, int list) +void W_NextWeapon(entity this, int list, .entity weaponentity) { if(list == 0) - W_CycleWeapon(this, weaponorder_byid, -1); + W_CycleWeapon(this, weaponorder_byid, -1, weaponentity); else if(list == 1) - W_CycleWeapon(this, this.weaponorder_byimpulse, -1); + W_CycleWeapon(this, this.weaponorder_byimpulse, -1, weaponentity); else if(list == 2) - W_CycleWeapon(this, this.cvar_cl_weaponpriority, -1); + W_CycleWeapon(this, this.cvar_cl_weaponpriority, -1, weaponentity); } // prev weapon -void W_PreviousWeapon(entity this, float list) +void W_PreviousWeapon(entity this, float list, .entity weaponentity) { if(list == 0) - W_CycleWeapon(this, weaponorder_byid, +1); + W_CycleWeapon(this, weaponorder_byid, +1, weaponentity); else if(list == 1) - W_CycleWeapon(this, this.weaponorder_byimpulse, +1); + W_CycleWeapon(this, this.weaponorder_byimpulse, +1, weaponentity); else if(list == 2) - W_CycleWeapon(this, this.cvar_cl_weaponpriority, +1); + W_CycleWeapon(this, this.cvar_cl_weaponpriority, +1, weaponentity); } // previously used if exists and has ammo, (second) best otherwise -void W_LastWeapon(entity this) +void W_LastWeapon(entity this, .entity weaponentity) { Weapon wep = Weapons_from(this.cnt); if (client_hasweapon(this, wep, true, false)) - W_SwitchWeapon(this, wep); + W_SwitchWeapon(this, wep, weaponentity); else - W_SwitchToOtherWeapon(this); + W_SwitchToOtherWeapon(this, weaponentity); } diff --git a/qcsrc/server/weapons/selection.qh b/qcsrc/server/weapons/selection.qh index 0c30b7c121..336dc1304a 100644 --- a/qcsrc/server/weapons/selection.qh +++ b/qcsrc/server/weapons/selection.qh @@ -7,25 +7,26 @@ void Send_WeaponComplain(entity e, float wpn, float type); bool client_hasweapon(entity this, Weapon wpn, float andammo, bool complain); .int weaponcomplainindex; -float W_GetCycleWeapon(entity this, string weaponorder, float dir, float imp, float complain, float skipmissing); +float W_GetCycleWeapon(entity this, string weaponorder, float dir, float imp, float complain, float skipmissing, .entity weaponentity); -#define w_getbestweapon(ent) Weapons_from(W_GetCycleWeapon(ent, ent.cvar_cl_weaponpriority, 0, -1, false, true)) +// TODO: unhardcode +#define w_getbestweapon(ent) Weapons_from(W_GetCycleWeapon(ent, ent.cvar_cl_weaponpriority, 0, -1, false, true, weaponentities[0])) -void W_SwitchWeapon_Force(Player this, Weapon w); +void W_SwitchWeapon_Force(Player this, Weapon w, .entity weaponentity); // perform weapon to attack (weaponstate and attack_finished check is here) -void W_SwitchToOtherWeapon(entity this); -void W_SwitchWeapon(entity this, Weapon imp); +void W_SwitchToOtherWeapon(entity this, .entity weaponentity); +void W_SwitchWeapon(entity this, Weapon imp, .entity weaponentity); -void W_CycleWeapon(entity this, string weaponorder, float dir); +void W_CycleWeapon(entity this, string weaponorder, float dir, .entity weaponentity); -void W_NextWeaponOnImpulse(entity this, float imp); +void W_NextWeaponOnImpulse(entity this, float imp, .entity weaponentity); // next weapon -void W_NextWeapon(entity this, float list); +void W_NextWeapon(entity this, float list, .entity weaponentity); // prev weapon -void W_PreviousWeapon(entity this, float list); +void W_PreviousWeapon(entity this, float list, .entity weaponentity); // previously used if exists and has ammo, (second) best otherwise -void W_LastWeapon(entity this); +void W_LastWeapon(entity this, .entity weaponentity); diff --git a/qcsrc/server/weapons/throwing.qc b/qcsrc/server/weapons/throwing.qc index bd69e33246..47531ecbbd 100644 --- a/qcsrc/server/weapons/throwing.qc +++ b/qcsrc/server/weapons/throwing.qc @@ -31,7 +31,7 @@ void thrown_wep_think(entity this) } // returns amount of ammo used as string, or -1 for failure, or 0 for no ammo count -string W_ThrowNewWeapon(entity own, float wpn, float doreduce, vector org, vector velo) +string W_ThrowNewWeapon(entity own, float wpn, float doreduce, vector org, vector velo, .entity weaponentity) { float thisammo; string s; @@ -97,7 +97,7 @@ string W_ThrowNewWeapon(entity own, float wpn, float doreduce, vector org, vecto if(doreduce && g_weapon_stay == 2) { // if our weapon is loaded, give its load back to the player - int i = PS(own).m_weapon.m_id; + int i = own.(weaponentity).m_weapon.m_id; if(own.(weapon_load[i]) > 0) { own.(ammotype) += own.(weapon_load[i]); @@ -109,7 +109,7 @@ string W_ThrowNewWeapon(entity own, float wpn, float doreduce, vector org, vecto else if(doreduce) { // if our weapon is loaded, give its load back to the player - int i = PS(own).m_weapon.m_id; + int i = own.(weaponentity).m_weapon.m_id; if(own.(weapon_load[i]) > 0) { own.(ammotype) += own.(weapon_load[i]); @@ -167,7 +167,7 @@ bool W_IsWeaponThrowable(entity this, int w) // toss current weapon void W_ThrowWeapon(entity this, .entity weaponentity, vector velo, vector delta, float doreduce) { - Weapon w = PS(this).m_weapon; + Weapon w = this.(weaponentity).m_weapon; if (w == WEP_Null) return; // just in case if(MUTATOR_CALLHOOK(ForbidThrowCurrentWeapon, this)) @@ -183,16 +183,16 @@ void W_ThrowWeapon(entity this, .entity weaponentity, vector velo, vector delta, if(!(this.weapons & set)) return; this.weapons &= ~set; - W_SwitchWeapon_Force(this, w_getbestweapon(this)); - string a = W_ThrowNewWeapon(this, w.m_id, doreduce, this.origin + delta, velo); + W_SwitchWeapon_Force(this, w_getbestweapon(this), weaponentity); + string a = W_ThrowNewWeapon(this, w.m_id, doreduce, this.origin + delta, velo, weaponentity); if(!a) return; Send_Notification(NOTIF_ONE, this, MSG_MULTI, ITEM_WEAPON_DROP, a, w.m_id); } -void SpawnThrownWeapon(entity this, vector org, float w) +void SpawnThrownWeapon(entity this, vector org, float w, .entity weaponentity) { - if(this.weapons & WepSet_FromWeapon(PS(this).m_weapon)) - if(W_IsWeaponThrowable(this, PS(this).m_weapon.m_id)) - W_ThrowNewWeapon(this, PS(this).m_weapon.m_id, false, org, randomvec() * 125 + '0 0 200'); + if(this.weapons & WepSet_FromWeapon(this.(weaponentity).m_weapon)) + if(W_IsWeaponThrowable(this, this.(weaponentity).m_weapon.m_id)) + W_ThrowNewWeapon(this, this.(weaponentity).m_weapon.m_id, false, org, randomvec() * 125 + '0 0 200', weaponentity); } diff --git a/qcsrc/server/weapons/throwing.qh b/qcsrc/server/weapons/throwing.qh index a03968083e..01ab21ba63 100644 --- a/qcsrc/server/weapons/throwing.qh +++ b/qcsrc/server/weapons/throwing.qh @@ -4,11 +4,11 @@ void thrown_wep_think(entity this); // returns amount of ammo used as string, or -1 for failure, or 0 for no ammo count -string W_ThrowNewWeapon(entity own, float wpn, float doreduce, vector org, vector velo); +string W_ThrowNewWeapon(entity own, float wpn, float doreduce, vector org, vector velo, .entity weaponentity); bool W_IsWeaponThrowable(entity this, int w); // toss current weapon void W_ThrowWeapon(entity this, .entity weaponentity, vector velo, vector delta, float doreduce); -void SpawnThrownWeapon(entity this, vector org, float w); +void SpawnThrownWeapon(entity this, vector org, float w, .entity weaponentity); diff --git a/qcsrc/server/weapons/tracing.qc b/qcsrc/server/weapons/tracing.qc index 3b7aa7bf89..1f7f594675 100644 --- a/qcsrc/server/weapons/tracing.qc +++ b/qcsrc/server/weapons/tracing.qc @@ -27,7 +27,7 @@ void W_SetupShot_Dir_ProjectileSize_Range(entity ent, .entity weaponentity, vect float oldsolid; vector vecs, dv; oldsolid = ent.dphitcontentsmask; - if (IS_PLAYER(ent) && PS(ent).m_weapon == WEP_RIFLE) + if (IS_PLAYER(ent) && ent.(weaponentity).m_weapon == WEP_RIFLE) ent.dphitcontentsmask = DPCONTENTS_BODY | DPCONTENTS_CORPSE; else ent.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE; @@ -53,7 +53,7 @@ void W_SetupShot_Dir_ProjectileSize_Range(entity ent, .entity weaponentity, vect // track max damage if (IS_PLAYER(ent) && accuracy_canbegooddamage(ent)) - accuracy_add(ent, PS(ent).m_weapon.m_id, maxdamage, 0); + accuracy_add(ent, ent.(weaponentity).m_weapon.m_id, maxdamage, 0); if(IS_PLAYER(ent)) W_HitPlotAnalysis(ent, v_forward, v_right, v_up); @@ -196,7 +196,7 @@ void W_SetupProjVelocity_Explicit(entity proj, vector dir, vector upDir, float p // Ballistics Tracing // ==================== -void FireRailgunBullet (entity this, vector start, vector end, float bdamage, float bforce, float mindist, float maxdist, float halflifedist, float forcehalflifedist, int deathtype) +void FireRailgunBullet (entity this, .entity weaponentity, vector start, vector end, float bdamage, float bforce, float mindist, float maxdist, float halflifedist, float forcehalflifedist, int deathtype) { vector hitloc, force, endpoint, dir; entity ent, endent; @@ -333,7 +333,7 @@ void FireRailgunBullet (entity this, vector start, vector end, float bdamage, fl } // calculate hits and fired shots for hitscan - accuracy_add(this, PS(this).m_weapon.m_id, 0, min(bdamage, totaldmg)); + accuracy_add(this, this.(weaponentity).m_weapon.m_id, 0, min(bdamage, totaldmg)); trace_endpos = endpoint; trace_ent = endent; @@ -348,7 +348,7 @@ void fireBullet_trace_callback(vector start, vector hit, vector end) fireBullet_last_hit = NULL; } -void fireBullet(entity this, vector start, vector dir, float spread, float max_solid_penetration, float damage, float force, float dtype, int tracereffects) +void fireBullet(entity this, .entity weaponentity, vector start, vector dir, float spread, float max_solid_penetration, float damage, float force, float dtype, int tracereffects) { vector end; @@ -441,7 +441,7 @@ void fireBullet(entity this, vector start, vector dir, float spread, float max_s // do not exceed 100% float added_damage = min(damage - total_damage, damage * solid_penetration_left); total_damage += damage * solid_penetration_left; - accuracy_add(this, PS(this).m_weapon.m_id, 0, added_damage); + accuracy_add(this, this.(weaponentity).m_weapon.m_id, 0, added_damage); } } diff --git a/qcsrc/server/weapons/tracing.qh b/qcsrc/server/weapons/tracing.qh index 21f12c1e4c..aec274143b 100644 --- a/qcsrc/server/weapons/tracing.qh +++ b/qcsrc/server/weapons/tracing.qh @@ -49,9 +49,9 @@ void W_SetupProjVelocity_Explicit(entity proj, vector dir, vector upDir, float p .float railgundistance; .vector railgunforce; -void FireRailgunBullet (entity this, vector start, vector end, float bdamage, float bforce, float mindist, float maxdist, float halflifedist, float forcehalflifedist, int deathtype); +void FireRailgunBullet (entity this, .entity weaponentity, vector start, vector end, float bdamage, float bforce, float mindist, float maxdist, float halflifedist, float forcehalflifedist, int deathtype); entity fireBullet_trace_callback_eff; entity fireBullet_last_hit; void fireBullet_trace_callback(vector start, vector hit, vector end); -void fireBullet(entity this, vector start, vector dir, float spread, float max_solid_penetration, float damage, float force, float dtype, int tracereffects); +void fireBullet(entity this, .entity weaponentity, vector start, vector dir, float spread, float max_solid_penetration, float damage, float force, float dtype, int tracereffects); diff --git a/qcsrc/server/weapons/weaponsystem.qc b/qcsrc/server/weapons/weaponsystem.qc index 4968d3c31f..3b8047efa1 100644 --- a/qcsrc/server/weapons/weaponsystem.qc +++ b/qcsrc/server/weapons/weaponsystem.qc @@ -62,6 +62,9 @@ vector CL_Weapon_GetShotOrg(int wpn) ..entity weaponentity_fld; .float m_alpha; +.string w_weaponname; +.int w_dmg; +.int w_deadflag; void CL_Weaponentity_Think(entity this) { @@ -82,16 +85,16 @@ void CL_Weaponentity_Think(entity this) if (this.weaponchild) this.weaponchild.model = ""; return; } - if (this.weaponname != this.owner.weaponname - || this.dmg != this.owner.modelindex - || this.deadflag != this.owner.deadflag) + if (this.w_weaponname != this.weaponname + || this.w_dmg != this.modelindex + || this.w_deadflag != this.deadflag) { // owner changed weapons; update appearance - this.weaponname = this.owner.weaponname; - this.dmg = this.owner.modelindex; - this.deadflag = this.owner.deadflag; + this.w_weaponname = this.weaponname; + this.w_dmg = this.modelindex; + this.w_deadflag = this.deadflag; - CL_WeaponEntity_SetModel(this, this.owner.weaponname, true); + CL_WeaponEntity_SetModel(this, this.weaponname, true); } this.alpha = -1; // TODO: don't render this entity at all @@ -105,11 +108,15 @@ void CL_Weaponentity_Think(entity this) this.weaponchild.alpha = this.alpha; this.weaponchild.effects = this.effects; } + + wepent_update(this); } void CL_ExteriorWeaponentity_Think(entity this) { this.nextthink = time; + .entity weaponentity = this.weaponentity_fld; + entity wepent = this.owner.(weaponentity); if (this.owner.exteriorweaponentity != this) { delete(this); @@ -120,15 +127,15 @@ void CL_ExteriorWeaponentity_Think(entity this) this.model = ""; return; } - if (this.weaponname != this.owner.weaponname || this.dmg != this.owner.modelindex - || this.deadflag != this.owner.deadflag) + if (this.weaponname != wepent.weaponname || this.dmg != wepent.modelindex + || this.deadflag != wepent.deadflag) { - this.weaponname = this.owner.weaponname; - this.dmg = this.owner.modelindex; - this.deadflag = this.owner.deadflag; - if (this.owner.weaponname != "") + this.weaponname = wepent.weaponname; + this.dmg = wepent.modelindex; + this.deadflag = wepent.deadflag; + if (wepent.weaponname != "") { - _setmodel(this, W_Model(strcat("v_", this.owner.weaponname, ".md3"))); + _setmodel(this, W_Model(strcat("v_", wepent.weaponname, ".md3"))); setsize(this, '0 0 0', '0 0 0'); } else this.model = ""; @@ -151,7 +158,7 @@ void CL_ExteriorWeaponentity_Think(entity this) else if (this.owner.alpha != 0) this.alpha = this.owner.alpha; else this.alpha = 1; - Weapon wep = PS(this.owner).m_weapon; + Weapon wep = this.owner.(weaponentity).m_weapon; if (wep) this.glowmod = weaponentity_glowmod(wep, this.owner, this.owner.clientcolors); this.colormap = this.owner.colormap; @@ -172,11 +179,14 @@ void CL_SpawnWeaponentity(entity actor, .entity weaponentity) view.viewmodelforclient = actor; setcefc(view, CL_Weaponentity_CustomizeEntityForClient); + wepent_link(view); + if (weaponentity == weaponentities[0]) { entity exterior = actor.exteriorweaponentity = new(exteriorweaponentity); exterior.solid = SOLID_NOT; exterior.owner = actor; + exterior.weaponentity_fld = weaponentity; setorigin(exterior, '0 0 0'); setthink(exterior, CL_ExteriorWeaponentity_Think); exterior.nextthink = time; @@ -188,8 +198,8 @@ void CL_SpawnWeaponentity(entity actor, .entity weaponentity) // Weapon subs void w_clear(Weapon thiswep, entity actor, .entity weaponentity, int fire) { - PS(actor).m_weapon = WEP_Null; - PS(actor).m_switchingweapon = WEP_Null; + actor.(weaponentity).m_weapon = WEP_Null; + actor.(weaponentity).m_switchingweapon = WEP_Null; entity this = actor.(weaponentity); if (this) { @@ -207,7 +217,7 @@ void w_ready(Weapon thiswep, entity actor, .entity weaponentity, int fire) .float prevdryfire; .float prevwarntime; -bool weapon_prepareattack_checkammo(Weapon thiswep, entity actor, bool secondary) +bool weapon_prepareattack_checkammo(Weapon thiswep, entity actor, bool secondary, .entity weaponentity) { if ((actor.items & IT_UNLIMITED_WEAPON_AMMO)) return true; bool ammo = false; @@ -226,7 +236,7 @@ bool weapon_prepareattack_checkammo(Weapon thiswep, entity actor, bool secondary if (thiswep == WEP_SHOTGUN) if (!secondary && WEP_CVAR(shotgun, secondary) == 1) return false; // no clicking, just allow - if (thiswep == PS(actor).m_switchweapon && time - actor.prevdryfire > 1) // only play once BEFORE starting to switch weapons + if (thiswep == actor.(weaponentity).m_switchweapon && time - actor.prevdryfire > 1) // only play once BEFORE starting to switch weapons { sound(actor, CH_WEAPON_A, SND_DRYFIRE, VOL_BASE, ATTEN_NORM); actor.prevdryfire = time; @@ -254,7 +264,7 @@ bool weapon_prepareattack_checkammo(Weapon thiswep, entity actor, bool secondary } else // this weapon is totally unable to fire, switch to another one { - W_SwitchToOtherWeapon(actor); + W_SwitchToOtherWeapon(actor, weaponentity); } return false; @@ -264,7 +274,7 @@ bool weapon_prepareattack_checkammo(Weapon thiswep, entity actor, bool secondary bool weapon_prepareattack_check(Weapon thiswep, entity actor, .entity weaponentity, bool secondary, float attacktime) { if (actor.weaponentity == NULL) return true; - if (!weapon_prepareattack_checkammo(thiswep, actor, secondary)) return false; + if (!weapon_prepareattack_checkammo(thiswep, actor, secondary, weaponentity)) return false; // if sv_ready_restart_after_countdown is set, don't allow the player to shoot // if all players readied up and the countdown is running @@ -274,7 +284,7 @@ bool weapon_prepareattack_check(Weapon thiswep, entity actor, .entity weaponenti return false; // do not even think about shooting if switching - if (PS(actor).m_switchweapon != PS(actor).m_weapon) return false; + if (actor.(weaponentity).m_switchweapon != actor.(weaponentity).m_weapon) return false; if (attacktime >= 0) { @@ -378,7 +388,6 @@ void weapon_thinkf(entity actor, .entity weaponentity, WFRAME fr, float t, void( // dprint("reset weapon animation timer at ", ftos(time), "\n"); } this.weapon_nextthink += t; - if (weaponentity == weaponentities[0]) STAT(WEAPON_NEXTTHINK, actor) = this.weapon_nextthink; this.weapon_think = func; // dprint("next ", ftos(this.weapon_nextthink), "\n"); @@ -392,8 +401,8 @@ void weapon_thinkf(entity actor, .entity weaponentity, WFRAME fr, float t, void( if ((fr == WFRAME_FIRE1 || fr == WFRAME_FIRE2) && t) { - bool primary_melee = boolean(fr == WFRAME_FIRE1 && (PS(actor).m_weapon.spawnflags & WEP_TYPE_MELEE_PRI)); - bool secondary_melee = boolean(fr == WFRAME_FIRE2 && (PS(actor).m_weapon.spawnflags & WEP_TYPE_MELEE_SEC)); + bool primary_melee = boolean(fr == WFRAME_FIRE1 && (actor.(weaponentity).m_weapon.spawnflags & WEP_TYPE_MELEE_PRI)); + bool secondary_melee = boolean(fr == WFRAME_FIRE2 && (actor.(weaponentity).m_weapon.spawnflags & WEP_TYPE_MELEE_SEC)); int act = (primary_melee || secondary_melee) ? ANIMACTION_MELEE : ANIMACTION_SHOOT @@ -434,18 +443,18 @@ void W_WeaponFrame(Player actor, .entity weaponentity) { if (actor.(weaponentity).state != WS_CLEAR) { - Weapon wpn = PS(actor).m_weapon; + Weapon wpn = this.m_weapon; w_ready(wpn, actor, weaponentity, PHYS_INPUT_BUTTON_ATCK(actor) | (PHYS_INPUT_BUTTON_ATCK2(actor) << 1)); return; } } - if (PS(actor).m_switchweapon == WEP_Null) + if (this.m_switchweapon == WEP_Null) { - PS(actor).m_weapon = WEP_Null; - PS(actor).m_switchingweapon = WEP_Null; + this.m_weapon = WEP_Null; + this.m_switchingweapon = WEP_Null; this.state = WS_CLEAR; - actor.weaponname = ""; + this.weaponname = ""; // actor.items &= ~IT_AMMO; return; } @@ -456,7 +465,7 @@ void W_WeaponFrame(Player actor, .entity weaponentity) vector up = v_up; // Change weapon - if (PS(actor).m_weapon != PS(actor).m_switchweapon) + if (this.m_weapon != this.m_switchweapon) { switch (this.state) { @@ -469,12 +478,12 @@ void W_WeaponFrame(Player actor, .entity weaponentity) case WS_CLEAR: { // end switching! - Weapon newwep = PS(actor).m_switchweapon; - PS(actor).m_switchingweapon = newwep; + Weapon newwep = this.m_switchweapon; + this.m_switchingweapon = newwep; // the two weapon entities will notice this has changed and update their models - PS(actor).m_weapon = newwep; - actor.weaponname = newwep.mdl; + this.m_weapon = newwep; + this.weaponname = newwep.mdl; actor.bulletcounter = 0; actor.ammo_field = newwep.ammo_field; newwep.wr_setup(newwep, actor); @@ -483,7 +492,7 @@ void W_WeaponFrame(Player actor, .entity weaponentity) // 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 { - actor.clip_load = actor.(weapon_load[PS(actor).m_switchweapon.m_id]); + actor.clip_load = actor.(weapon_load[this.m_switchweapon.m_id]); actor.clip_size = newwep.reloading_ammo; } else @@ -497,14 +506,14 @@ void W_WeaponFrame(Player actor, .entity weaponentity) case WS_DROP: { // in dropping phase we can switch at any time - PS(actor).m_switchingweapon = PS(actor).m_switchweapon; + this.m_switchingweapon = this.m_switchweapon; break; } case WS_READY: { // start switching! - PS(actor).m_switchingweapon = PS(actor).m_switchweapon; - entity oldwep = PS(actor).m_weapon; + this.m_switchingweapon = this.m_switchweapon; + entity oldwep = this.m_weapon; // set up weapon switch think in the future, and start drop anim if (INDEPENDENT_ATTACK_FINISHED || ATTACK_FINISHED(actor, weaponslot(weaponentity)) <= time + actor.weapon_frametime * 0.5) @@ -522,7 +531,7 @@ void W_WeaponFrame(Player actor, .entity weaponentity) // if (actor.button0) // print(ftos(frametime), " ", ftos(time), " >= ", ftos(ATTACK_FINISHED(actor, slot)), " >= ", ftos(this.weapon_nextthink), "\n"); - Weapon w = PS(actor).m_weapon; + Weapon w = this.m_weapon; // call the think code which may fire the weapon // and do so multiple times to resolve framerate dependency issues if the @@ -531,7 +540,7 @@ void W_WeaponFrame(Player actor, .entity weaponentity) { if (w != WEP_Null && !(actor.weapons & WepSet_FromWeapon(w))) { - if (PS(actor).m_weapon == PS(actor).m_switchweapon) W_SwitchWeapon_Force(actor, w_getbestweapon(actor)); + if (this.m_weapon == this.m_switchweapon) W_SwitchWeapon_Force(actor, w_getbestweapon(actor), weaponentity); w = WEP_Null; } @@ -549,11 +558,11 @@ void W_WeaponFrame(Player actor, .entity weaponentity) } else { - if (key_pressed && PS(actor).m_switchweapon != WEP_HOOK && !actor.hook_switchweapon) - W_SwitchWeapon(actor, WEP_HOOK); + if (key_pressed && this.m_switchweapon != WEP_HOOK && !actor.hook_switchweapon) + W_SwitchWeapon(actor, WEP_HOOK, weaponentity); actor.hook_switchweapon = key_pressed; Weapon h = WEP_HOOK; - block_weapon = (PS(actor).m_weapon == h && (PHYS_INPUT_BUTTON_ATCK(actor) || key_pressed)); + block_weapon = (this.m_weapon == h && (PHYS_INPUT_BUTTON_ATCK(actor) || key_pressed)); h.wr_think(h, actor, weaponentity, block_weapon ? 1 : 0); } } @@ -564,7 +573,7 @@ void W_WeaponFrame(Player actor, .entity weaponentity) if (!block_weapon) { - Weapon e = PS(actor).m_weapon; + Weapon e = this.m_weapon; TC(Weapon, e); if (w != WEP_Null) { @@ -583,7 +592,7 @@ void W_WeaponFrame(Player actor, .entity weaponentity) v_forward = fo; v_right = ri; v_up = up; - Weapon wpn = PS(actor).m_weapon; + Weapon wpn = this.m_weapon; this.weapon_think(wpn, actor, weaponentity, PHYS_INPUT_BUTTON_ATCK(actor) | (PHYS_INPUT_BUTTON_ATCK2(actor) << 1)); } @@ -625,7 +634,7 @@ void W_AttachToShotorg(entity actor, .entity weaponentity, entity flash, vector } } -void W_DecreaseAmmo(Weapon wep, entity actor, float ammo_use) +void W_DecreaseAmmo(Weapon wep, entity actor, float ammo_use, .entity weaponentity) { if (MUTATOR_CALLHOOK(W_DecreaseAmmo, actor)) return; @@ -635,7 +644,7 @@ void W_DecreaseAmmo(Weapon wep, entity actor, float ammo_use) if (wep.reloading_ammo) { actor.clip_load -= ammo_use; - actor.(weapon_load[PS(actor).m_weapon.m_id]) = actor.clip_load; + actor.(weapon_load[actor.(weaponentity).m_weapon.m_id]) = actor.clip_load; } else if (wep.ammo_field != ammo_none) { @@ -679,7 +688,7 @@ void W_ReloadedAndReady(Weapon thiswep, entity actor, .entity weaponentity, int actor.clip_load += load; actor.(actor.ammo_field) -= load; } - actor.(weapon_load[PS(actor).m_weapon.m_id]) = actor.clip_load; + actor.(weapon_load[actor.(weaponentity).m_weapon.m_id]) = actor.clip_load; // do not set ATTACK_FINISHED in reload code any more. This causes annoying delays if eg: You start reloading a weapon, // then quickly switch to another weapon and back. Reloading is canceled, but the reload delay is still there, @@ -687,7 +696,7 @@ void W_ReloadedAndReady(Weapon thiswep, entity actor, .entity weaponentity, int // ATTACK_FINISHED(actor, slot) -= actor.reload_time - 1; - Weapon wpn = Weapons_from(PS(actor).m_weapon.m_id); + Weapon wpn = Weapons_from(actor.(weaponentity).m_weapon.m_id); w_ready(wpn, actor, weaponentity, PHYS_INPUT_BUTTON_ATCK(actor) | (PHYS_INPUT_BUTTON_ATCK2(actor) << 1)); } @@ -695,7 +704,7 @@ void W_Reload(entity actor, .entity weaponentity, float sent_ammo_min, Sound sen { TC(Sound, sent_sound); // set global values to work with - Weapon e = PS(actor).m_weapon; + Weapon e = actor.(weaponentity).m_weapon; if (MUTATOR_CALLHOOK(W_Reload, actor)) return; @@ -729,15 +738,15 @@ void W_Reload(entity actor, .entity weaponentity, float sent_ammo_min, Sound sen if (IS_REAL_CLIENT(actor) && actor.reload_complain < time) { play2(actor, SND(UNAVAILABLE)); - sprint(actor, strcat("You don't have enough ammo to reload the ^2", PS(actor).m_weapon.m_name, "\n")); + sprint(actor, strcat("You don't have enough ammo to reload the ^2", actor.(weaponentity).m_weapon.m_name, "\n")); actor.reload_complain = time + 1; } // switch away if the amount of ammo is not enough to keep using this weapon - Weapon w = PS(actor).m_weapon; + Weapon w = actor.(weaponentity).m_weapon; if (!(w.wr_checkammo1(w, actor) + w.wr_checkammo2(w, actor))) { actor.clip_load = -1; // reload later - W_SwitchToOtherWeapon(actor); + W_SwitchToOtherWeapon(actor, weaponentity); } return; } @@ -767,7 +776,7 @@ void W_Reload(entity actor, .entity weaponentity, float sent_ammo_min, Sound sen if (actor.clip_load < 0) actor.clip_load = 0; actor.old_clip_load = actor.clip_load; - actor.clip_load = actor.(weapon_load[PS(actor).m_weapon.m_id]) = -1; + actor.clip_load = actor.(weapon_load[actor.(weaponentity).m_weapon.m_id]) = -1; } void W_DropEvent(.void(Weapon, entity actor) event, entity player, float weapon_type, entity weapon_item) diff --git a/qcsrc/server/weapons/weaponsystem.qh b/qcsrc/server/weapons/weaponsystem.qh index b7ca597046..bdc261d8e6 100644 --- a/qcsrc/server/weapons/weaponsystem.qh +++ b/qcsrc/server/weapons/weaponsystem.qh @@ -12,7 +12,7 @@ bool forbidWeaponUse(entity player); void W_AttachToShotorg(entity actor, .entity weaponentity, entity flash, vector offset); -void W_DecreaseAmmo(Weapon wep, entity actor, float ammo_use); +void W_DecreaseAmmo(Weapon wep, entity actor, float ammo_use, .entity weaponentity); void W_DropEvent(.void(Weapon, entity actor) event, entity player, float weapon_type, entity weapon_item); -- 2.39.2