set g_overkill_powerups_replace 1
set g_overkill_superguns_respawn_time 120
-set g_overkill_ammo_charge 0
-set g_overkill_ammo_charge_notice 1
-set g_overkill_ammo_charge_limit 1
-set g_overkill_ammo_charge_rate 0.5
-set g_overkill_ammo_charge_rate_vortex 0.5
-set g_overkill_ammo_charge_rate_machinegun 0.5
-set g_overkill_ammo_charge_rate_shotgun 0.5
-set g_overkill_ammo_charge_rate_hmg 0.25
-set g_overkill_ammo_charge_rate_rpc 1.5
-set g_overkill_ammo_decharge 0.1
-set g_overkill_ammo_decharge_machinegun 0.025
-set g_overkill_ammo_decharge_shotgun 0.15
-set g_overkill_ammo_decharge_vortex 0.2
-set g_overkill_ammo_decharge_rpc 1
-set g_overkill_ammo_decharge_hmg 0.01
-
// =========
// vampire
#include "miscfunctions.qh"
#include <common/ent_cs.qh>
+#include <common/wepent.qh>
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;
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
bool spectatorbutton_zoom;
bool button_attack2;
-Weapon activeweapon;
-Weapon switchingweapon;
-Weapon switchweapon;
float current_viewzoom;
float zoomin_effect;
float warmup_stage;
.float weapon_eta_last;
.float weapon_switchdelay;
+.string name_last;
+
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;
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);
+ vector g = weaponentity_glowmod(wep, NULL, c, this);
entity me = CSQCModel_server2csqc(player_localentnum - 1);
int fx = ((me.csqcmodel_effects & EFMASK_CHEAP)
| EF_NODEPTHTEST)
CSQCModel_Effects_Apply(e);
}
{
- static string name_last;
string name = wep.mdl;
- bool swap = name != name_last;
+ bool swap = name != this.name_last;
// if (swap)
{
- name_last = name;
+ this.name_last = name;
CL_WeaponEntity_SetModel(this, name, swap);
this.viewmodel_origin = this.origin;
this.viewmodel_angles = this.angles;
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);
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;
zoomspeed = 3.5;
zoomdir = button_zoom;
+
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
- zoomdir += button_attack2;
+ {
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ entity wepent = viewmodels[slot];
+ 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())
{
if(spectatorbutton_zoom)
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
const float CAMERA_FREE = 1;
const float CAMERA_CHASE = 2;
float reticle_type;
-string reticle_image;
string NextFrameCommand;
vector freeze_org, freeze_ang;
{
// 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)
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)
weapon_clipload = STAT(WEAPON_CLIPLOAD);
weapon_clipsize = STAT(WEAPON_CLIPSIZE);
- float ok_ammo_charge, ok_ammo_chargepool;
- ok_ammo_charge = STAT(OK_AMMO_CHARGE);
- ok_ammo_chargepool = STAT(OK_AMMO_CHARGEPOOL);
-
float vortex_charge, vortex_chargepool;
vortex_charge = STAT(VORTEX_CHARGE);
vortex_chargepool = STAT(VORTEX_CHARGEPOOL);
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;
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;
ring_rgb = wcross_color;
ring_image = "gfx/crosshair_ring.tga";
}
- else if (ok_ammo_charge)
- {
- ring_value = ok_ammo_chargepool;
- ring_alpha = autocvar_crosshair_ring_reload_alpha;
- ring_rgb = wcross_color;
- ring_image = "gfx/crosshair_ring.tga";
- }
else if(autocvar_crosshair_ring_reload && weapon_clipsize) // forces there to be only an ammo ring
{
ring_value = bound(0, weapon_clipload / weapon_clipsize, 1);
// 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 +
// 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);
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));
+ entity wepent = viewmodels[0]; // TODO: unhardcode
- switchweapon = Weapons_from(STAT(SWITCHWEAPON));
-
- 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");
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
if(autocvar_cl_reticle)
{
- Weapon wep = activeweapon;
+ string reticle_image = wepent.activeweapon.w_reticle;
+ bool wep_zoomed = false;
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ entity wepe = viewmodels[slot];
+ Weapon wep = wepe.activeweapon;
+ if(wep != WEP_Null && wep.wr_zoom)
+ {
+ bool do_zoom = wep.wr_zoom(wep, NULL);
+ reticle_image = wep.w_reticle;
+ wep_zoomed += do_zoom;
+ }
+ }
// 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
// no zoom reticle while dead
reticle_type = 0;
}
- else if(wep.wr_zoomreticle(wep) && autocvar_cl_reticle_weapon)
+ else if(wep_zoomed && autocvar_cl_reticle_weapon)
{
- if(reticle_image != "") { reticle_type = 2; }
+ if(reticle_image && reticle_image != "") { reticle_type = 2; }
else { reticle_type = 0; }
}
else if(button_zoom || zoomscript_caught)
#include "animdecide.qc"
#include "ent_cs.qc"
#include "net_notice.qc"
+#include "wepent.qc"
#endif
#include "mapinfo.qc"
#include <common/t_items.qc>
#include <common/util.qc>
#include <common/viewloc.qc>
+#include <common/wepent.qc>
ball.teamtime = time + autocvar_g_nexball_basketball_delay_hold_forteam;
ball.owner = ball.pusher = plyr; //"owner" is set to the player carrying, "pusher" to the last player who touched it
+ ball.weaponentity_fld = weaponentity;
ball.team = plyr.team;
plyr.ballcarried = ball;
ball.nb_dropper = plyr;
}
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)
if(ball.owner.metertime)
{
ball.owner.metertime = 0;
- .entity weaponentity = weaponentities[0]; // TODO: find ballstealer
+ .entity weaponentity = ball.weaponentity_fld;
ball.owner.(weaponentity).state = WS_READY;
}
}
}
-METHOD(BallStealer, wr_setup, void(BallStealer this, entity actor))
+METHOD(BallStealer, wr_setup, void(BallStealer this, entity actor, .entity weaponentity))
{
TC(BallStealer, this);
//weapon_setup(WEP_PORTO.m_id);
}
-METHOD(BallStealer, wr_checkammo1, bool(BallStealer this, entity actor))
+METHOD(BallStealer, wr_checkammo1, bool(BallStealer this, entity actor, .entity weaponentity))
{
TC(BallStealer, this);
return true;
}
-METHOD(BallStealer, wr_checkammo2, bool(BallStealer this, entity actor))
+METHOD(BallStealer, wr_checkammo2, bool(BallStealer this, entity actor, .entity weaponentity))
{
TC(BallStealer, this);
return true;
}
else
{
- .entity weaponentity = weaponentities[0]; // TODO
- if(player.(weaponentity).weapons)
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
{
- 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);
+ .entity weaponentity = weaponentities[slot];
- player.(weaponentity).weapons = '0 0 0';
+ if(player.(weaponentity).weapons)
+ {
+ player.weapons = player.(weaponentity).weapons;
+ Weapon w = WEP_NEXBALL;
+ w.wr_resetplayer(w, player);
+ player.(weaponentity).m_switchweapon = player.m_switchweapon;
+ W_SwitchWeapon(player, player.(weaponentity).m_switchweapon, weaponentity);
+
+ player.(weaponentity).weapons = '0 0 0';
+ }
}
}
entity player = M_ARGV(0, entity);
player.metertime = 0;
- .entity weaponentity = weaponentities[0];
- player.(weaponentity).weapons = '0 0 0';
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ player.(weaponentity).weapons = '0 0 0';
+ }
if (nexball_mode & NBM_BASKETBALL)
player.weapons |= WEPSET(NEXBALL);
MUTATOR_HOOKFUNCTION(nb, ForbidThrowCurrentWeapon)
{
- entity player = M_ARGV(0, entity);
+ //entity player = M_ARGV(0, entity);
+ entity wepent = M_ARGV(1, entity);
- return PS(player).m_weapon == WEP_NEXBALL;
+ return wepent.m_weapon == WEP_NEXBALL;
}
MUTATOR_HOOKFUNCTION(nb, ForbidDropCurrentWeapon)
{
- entity player = M_ARGV(0, entity);
+ //entity player = M_ARGV(0, entity);
+ int wep = M_ARGV(1, int);
- return PS(player).m_weapon == WEP_MORTAR; // TODO: what is this for?
+ return wep == WEP_MORTAR.m_id; // TODO: what is this for?
}
MUTATOR_HOOKFUNCTION(nb, FilterItem)
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;
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:
.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)
{
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;
}
}
-METHOD(WyvernAttack, wr_checkammo1, bool(WyvernAttack this, entity actor)) {
+METHOD(WyvernAttack, wr_checkammo1, bool(WyvernAttack this, entity actor, .entity weaponentity)) {
TC(WyvernAttack, this);
return true;
}
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:
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)
{
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)
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)
// 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)
{
}
}
- targ = this.goalentity;
-
if (MUTATOR_CALLHOOK(MonsterMove, this, runspeed, walkspeed, targ)
|| gameover
|| this.draggedby != NULL
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)
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)
if(DIFF_TEAM(frag_attacker, frag_target.realowner))
{
Damage (frag_target.realowner, frag_attacker, frag_attacker, 5, WEP_HOOK.m_id | HITTYPE_SPLASH, frag_target.realowner.origin, '0 0 0');
- RemoveGrapplingHook(frag_target.realowner);
+ RemoveHook(frag_target);
return; // dead
}
}
}
if(player.buffs & BUFF_AMMO.m_itemid)
- if(player.clip_size)
- player.clip_load = player.(weapon_load[PS(player).m_switchweapon.m_id]) = player.clip_size;
+ {
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(player.(weaponentity).clip_size)
+ player.(weaponentity).clip_load = player.(weaponentity).(weapon_load[player.(weaponentity).m_switchweapon.m_id]) = player.(weaponentity).clip_size;
+ }
+ }
if((player.buffs & BUFF_INVISIBLE.m_itemid) && (player.oldbuffs & BUFF_INVISIBLE.m_itemid))
if(player.alpha != autocvar_g_buffs_invisible_alpha)
player.buff_ammo_prev_infitems = (player.items & IT_UNLIMITED_WEAPON_AMMO);
player.items |= IT_UNLIMITED_WEAPON_AMMO;
- if(player.clip_load)
- player.buff_ammo_prev_clipload = player.clip_load;
- player.clip_load = player.(weapon_load[PS(player).m_switchweapon.m_id]) = player.clip_size;
+ if(player.buffs & BUFF_AMMO.m_itemid)
+ {
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(player.(weaponentity).clip_load)
+ player.(weaponentity).buff_ammo_prev_clipload = player.(weaponentity).clip_load;
+ if(player.(weaponentity).clip_size)
+ player.(weaponentity).clip_load = player.(weaponentity).(weapon_load[player.(weaponentity).m_switchweapon.m_id]) = player.(weaponentity).clip_size;
+ }
+ }
}
BUFF_ONREM(BUFF_AMMO)
else
player.items &= ~IT_UNLIMITED_WEAPON_AMMO;
- if(player.buff_ammo_prev_clipload)
- player.clip_load = player.buff_ammo_prev_clipload;
+ if(player.buffs & BUFF_AMMO.m_itemid)
+ {
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(player.(weaponentity).buff_ammo_prev_clipload)
+ player.(weaponentity).clip_load = player.(weaponentity).buff_ammo_prev_clipload;
+ }
+ }
}
BUFF_ONADD(BUFF_INVISIBLE)
IL_EACH(g_projectiles, it.classname == "grapplinghook" && it.aiment == this,
{
- RemoveGrapplingHook(it.realowner);
+ RemoveHook(it);
});
delete(this);
{
IL_EACH(g_projectiles, it.classname == "grapplinghook" && it.aiment == this,
{
- RemoveGrapplingHook(it.realowner);
+ RemoveHook(it);
});
delete(this);
return;
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);
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(it.(weaponentity).m_weapon == WEP_Null && slot != 0)
+ continue;
+ if(!client_hasweapon(it, it.(weaponentity).m_weapon, weaponentity, true, false))
+ it.(weaponentity).m_switchweapon = w_getbestweapon(it, weaponentity);
+ }
});
}
// all weapons must be fully loaded when we spawn
if(e.spawnflags & WEP_FLAG_RELOADABLE) // prevent accessing undefined cvars
- this.(weapon_load[nix_weapon]) = e.reloading_ammo;
+ {
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ this.(weaponentity).(weapon_load[nix_weapon]) = e.reloading_ammo;
+ }
+ }
// vortex too
if(WEP_CVAR(vortex, charge))
{
if(WEP_CVAR_SEC(vortex, chargepool))
this.vortex_chargepool_ammo = 1;
- this.vortex_charge = WEP_CVAR(vortex, charge_start);
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ this.(weaponentity).vortex_charge = WEP_CVAR(vortex, charge_start);
+ }
}
// set last change info
this.weapons |= e.m_wepset;
Weapon w = Weapons_from(nix_weapon);
- if(PS(this).m_switchweapon != w)
- if(!client_hasweapon(this, PS(this).m_switchweapon, true, false))
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(this.(weaponentity).m_weapon == WEP_Null && slot != 0)
+ continue;
+
+ if(this.(weaponentity).m_switchweapon != w)
+ if(!client_hasweapon(this, this.(weaponentity).m_switchweapon, weaponentity, true, false))
{
- if(client_hasweapon(this, w, true, false))
- W_SwitchWeapon(this, w);
+ if(client_hasweapon(this, w, weaponentity, true, false))
+ W_SwitchWeapon(this, w, weaponentity);
}
+ }
}
MUTATOR_HOOKFUNCTION(nix, ForbidThrowCurrentWeapon)
return;
}
- if((!thiswep.wr_checkammo1(thiswep, actor) && !(actor.items & IT_UNLIMITED_WEAPON_AMMO)) || (!(actor.items & IT_SUPERWEAPON) && !(actor.items & IT_UNLIMITED_SUPERWEAPONS)))
+ if((!thiswep.wr_checkammo1(thiswep, actor, weaponentity) && !(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), 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));
actor.punchangle_y = random () - 0.5;
}
- 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);
+ float hmg_spread = bound(WEP_CVAR(hmg, spread_min), WEP_CVAR(hmg, spread_min) + (WEP_CVAR(hmg, spread_add) * actor.(weaponentity).misc_bulletcounter), WEP_CVAR(hmg, spread_max));
+ 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;
+ actor.(weaponentity).misc_bulletcounter = actor.(weaponentity).misc_bulletcounter + 1;
Send_Effect(EFFECT_MACHINEGUN_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(hmg, refire), W_HeavyMachineGun_Attack_Auto);
}
-METHOD(HeavyMachineGun, wr_aim, void(entity thiswep, entity actor))
+METHOD(HeavyMachineGun, wr_aim, void(entity thiswep, entity actor, .entity weaponentity))
{
if(vdist(actor.origin - actor.enemy.origin, <, 3000 - bound(0, skill, 10) * 200))
- PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, 1000000, 0, 0.001, false);
+ PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, 1000000, 0, 0.001, false);
else
- PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, 1000000, 0, 0.001, false);
+ PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, weaponentity, 1000000, 0, 0.001, false);
}
METHOD(HeavyMachineGun, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
{
- if(WEP_CVAR(hmg, reload_ammo) && actor.clip_load < WEP_CVAR(hmg, ammo)) { // forced reload
+ if(WEP_CVAR(hmg, reload_ammo) && actor.(weaponentity).clip_load < WEP_CVAR(hmg, ammo)) { // forced reload
thiswep.wr_reload(thiswep, actor, weaponentity);
} else
{
if (fire & 1)
if (weapon_prepareattack(thiswep, actor, weaponentity, false, 0))
{
- actor.misc_bulletcounter = 0;
+ actor.(weaponentity).misc_bulletcounter = 0;
W_HeavyMachineGun_Attack_Auto(thiswep, actor, weaponentity, fire);
}
}
}
-METHOD(HeavyMachineGun, wr_checkammo1, bool(entity thiswep, entity actor))
+METHOD(HeavyMachineGun, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity))
{
float ammo_amount = actor.ammo_nails >= WEP_CVAR(hmg, ammo);
if(autocvar_g_balance_hmg_reload_ammo)
- ammo_amount += actor.(weapon_load[WEP_HMG.m_id]) >= WEP_CVAR(hmg, ammo);
+ ammo_amount += actor.(weaponentity).(weapon_load[WEP_HMG.m_id]) >= WEP_CVAR(hmg, ammo);
return ammo_amount;
}
-METHOD(HeavyMachineGun, wr_checkammo2, bool(entity thiswep, entity actor))
+METHOD(HeavyMachineGun, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity))
{
float ammo_amount = actor.ammo_nails >= WEP_CVAR(hmg, ammo);
if(autocvar_g_balance_hmg_reload_ammo)
- ammo_amount += actor.(weapon_load[WEP_HMG.m_id]) >= WEP_CVAR(hmg, ammo);
+ ammo_amount += actor.(weaponentity).(weapon_load[WEP_HMG.m_id]) >= WEP_CVAR(hmg, ammo);
return ammo_amount;
}
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);
MUTATOR_CALLHOOK(EditProjectile, actor, missile);
}
-METHOD(RocketPropelledChainsaw, wr_aim, void(entity thiswep, entity actor))
+METHOD(RocketPropelledChainsaw, wr_aim, void(entity thiswep, entity actor, .entity weaponentity))
{
- PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, WEP_CVAR(rpc, speed), 0, WEP_CVAR(rpc, lifetime), false);
+ PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, WEP_CVAR(rpc, speed), 0, WEP_CVAR(rpc, lifetime), false);
}
METHOD(RocketPropelledChainsaw, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
{
- if(WEP_CVAR(rpc, reload_ammo) && actor.clip_load < WEP_CVAR(rpc, ammo)) {
+ if(WEP_CVAR(rpc, reload_ammo) && actor.(weaponentity).clip_load < WEP_CVAR(rpc, ammo)) {
thiswep.wr_reload(thiswep, actor, weaponentity);
} else
{
}
}
-METHOD(RocketPropelledChainsaw, wr_checkammo1, bool(entity thiswep, entity actor))
+METHOD(RocketPropelledChainsaw, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity))
{
float ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR(rpc, ammo);
- ammo_amount += actor.(weapon_load[WEP_RPC.m_id]) >= WEP_CVAR(rpc, ammo);
+ ammo_amount += actor.(weaponentity).(weapon_load[WEP_RPC.m_id]) >= WEP_CVAR(rpc, ammo);
return ammo_amount;
}
-METHOD(RocketPropelledChainsaw, wr_checkammo2, bool(entity thiswep, entity actor))
+METHOD(RocketPropelledChainsaw, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity))
{
return false;
}
float autocvar_g_overkill_superguns_respawn_time;
bool autocvar_g_overkill_100h_anyway;
bool autocvar_g_overkill_100a_anyway;
-bool autocvar_g_overkill_ammo_charge;
-float autocvar_g_overkill_ammo_charge_notice;
-float autocvar_g_overkill_ammo_charge_limit;
.vector ok_deathloc;
.float ok_spawnsys_timer;
-.float ok_lastwep;
+.Weapon ok_lastwep[MAX_WEAPONSLOTS];
.float ok_item;
-.float ok_notice_time;
-.float ammo_charge[Weapons_MAX];
-.float ok_use_ammocharge = _STAT(OK_AMMO_CHARGE);
-.float ok_ammo_charge = _STAT(OK_AMMO_CHARGEPOOL);
-
.float ok_pauseregen_finished;
-void(entity ent, float wep) ok_DecreaseCharge;
-
void ok_Initialize();
REGISTER_MUTATOR(ok, cvar("g_overkill") && !cvar("g_instagib") && !g_nexball && cvar_string("g_mod_balance") == "Overkill")
}
}
-MUTATOR_HOOKFUNCTION(ok, W_DecreaseAmmo)
-{
- entity actor = M_ARGV(0, entity);
- if (actor.ok_use_ammocharge)
- {
- ok_DecreaseCharge(actor, PS(actor).m_weapon.m_id);
- return true;
- }
-}
-
-MUTATOR_HOOKFUNCTION(ok, W_Reload)
-{
- entity actor = M_ARGV(0, entity);
- return actor.ok_use_ammocharge;
-}
-
void W_Blaster_Attack(entity, .entity, float, float, float, float, float, float, float, float, float, float);
spawnfunc(weapon_hmg);
spawnfunc(weapon_rpc);
-void ok_DecreaseCharge(entity ent, int wep)
-{
- if(!ent.ok_use_ammocharge) return;
-
- entity wepent = Weapons_from(wep);
-
- if (wepent == WEP_Null) return; // dummy
-
- ent.ammo_charge[wep] -= max(0, cvar(sprintf("g_overkill_ammo_decharge_%s", wepent.netname)));
-}
-
-void ok_IncreaseCharge(entity ent, int wep)
-{
- entity wepent = Weapons_from(wep);
-
- if (wepent == WEP_Null) return; // dummy
-
- if(ent.ok_use_ammocharge)
- if(!PHYS_INPUT_BUTTON_ATCK(ent)) // not while attacking?
- ent.ammo_charge[wep] = min(autocvar_g_overkill_ammo_charge_limit, ent.ammo_charge[wep] + cvar(sprintf("g_overkill_ammo_charge_rate_%s", wepent.netname)) * frametime / W_TICSPERFRAME);
-}
-
-float ok_CheckWeaponCharge(entity ent, int wep)
-{
- if(!ent.ok_use_ammocharge) return true;
-
- entity wepent = Weapons_from(wep);
-
- if(wepent == WEP_Null) return false; // dummy
-
- return (ent.ammo_charge[wep] >= cvar(sprintf("g_overkill_ammo_decharge_%s", wepent.netname)));
-}
-
MUTATOR_HOOKFUNCTION(ok, PlayerDamage_Calculate, CBC_ORDER_LAST)
{
entity frag_attacker = M_ARGV(1, entity);
ok_DropItem(frag_target, targ);
- frag_target.ok_lastwep = PS(frag_target).m_switchweapon.m_id;
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+
+ frag_target.ok_lastwep[slot] = frag_target.(weaponentity).m_switchweapon;
+ }
}
MUTATOR_HOOKFUNCTION(ok, MonsterDropItem)
if(IS_DEAD(player) || !IS_PLAYER(player) || STAT(FROZEN, player))
return;
- if(player.ok_lastwep)
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
{
- Weapon newwep = Weapons_from(player.ok_lastwep);
- if(player.ok_lastwep == WEP_HMG.m_id)
- newwep = WEP_MACHINEGUN;
- if(player.ok_lastwep == WEP_RPC.m_id)
- newwep = WEP_VORTEX;
- PS(player).m_switchweapon = newwep;
- player.ok_lastwep = 0;
- }
+ .entity weaponentity = weaponentities[slot];
+ entity thiswep = player.(weaponentity);
- ok_IncreaseCharge(player, PS(player).m_weapon.m_id);
+ if(player.ok_lastwep[slot] && player.ok_lastwep[slot] != WEP_Null)
+ {
+ Weapon newwep = player.ok_lastwep[slot];
+ if(player.ok_lastwep[slot] == WEP_HMG)
+ newwep = WEP_MACHINEGUN;
+ if(player.ok_lastwep[slot] == WEP_RPC)
+ newwep = WEP_VORTEX;
+ thiswep.m_switchweapon = newwep;
+ player.ok_lastwep[slot] = WEP_Null;
+ }
+ }
if(PHYS_INPUT_BUTTON_ATCK2(player))
if(!forbidWeaponUse(player) || player.weapon_blocked) // allow if weapon is blocked
player.jump_interval = time + WEP_CVAR_PRI(blaster, refire) * W_WeaponRateFactor(player);
makevectors(player.v_angle);
- Weapon oldwep = PS(player).m_weapon;
- PS(player).m_weapon = WEP_BLASTER;
- W_Blaster_Attack(
- player,
- weaponentities[0], // TODO: unhardcode
- WEP_BLASTER.m_id | HITTYPE_SECONDARY,
- WEP_CVAR_SEC(vaporizer, shotangle),
- WEP_CVAR_SEC(vaporizer, damage),
- WEP_CVAR_SEC(vaporizer, edgedamage),
- WEP_CVAR_SEC(vaporizer, radius),
- WEP_CVAR_SEC(vaporizer, force),
- WEP_CVAR_SEC(vaporizer, speed),
- WEP_CVAR_SEC(vaporizer, spread),
- WEP_CVAR_SEC(vaporizer, delay),
- WEP_CVAR_SEC(vaporizer, lifetime)
- );
- PS(player).m_weapon = oldwep;
- }
-
- player.weapon_blocked = false;
-
- player.ok_ammo_charge = player.ammo_charge[PS(player).m_weapon.m_id];
-
- if(player.ok_use_ammocharge)
- if(!ok_CheckWeaponCharge(player, PS(player).m_weapon.m_id))
- {
- if(autocvar_g_overkill_ammo_charge_notice && time > player.ok_notice_time && PHYS_INPUT_BUTTON_ATCK(player) && IS_REAL_CLIENT(player) && PS(player).m_weapon == PS(player).m_switchweapon)
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
{
- //Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_OVERKILL_CHARGE);
- player.ok_notice_time = time + 2;
- play2(player, SND(DRYFIRE));
+ .entity weaponentity = weaponentities[slot];
+
+ if(player.(weaponentity).m_weapon == WEP_Null && slot != 0)
+ continue;
+
+ Weapon oldwep = player.(weaponentity).m_weapon;
+ player.(weaponentity).m_weapon = WEP_BLASTER;
+ W_Blaster_Attack(
+ player,
+ weaponentity,
+ WEP_BLASTER.m_id | HITTYPE_SECONDARY,
+ WEP_CVAR_SEC(vaporizer, shotangle),
+ WEP_CVAR_SEC(vaporizer, damage),
+ WEP_CVAR_SEC(vaporizer, edgedamage),
+ WEP_CVAR_SEC(vaporizer, radius),
+ WEP_CVAR_SEC(vaporizer, force),
+ WEP_CVAR_SEC(vaporizer, speed),
+ WEP_CVAR_SEC(vaporizer, spread),
+ WEP_CVAR_SEC(vaporizer, delay),
+ WEP_CVAR_SEC(vaporizer, lifetime)
+ );
+ player.(weaponentity).m_weapon = oldwep;
}
- Weapon wpn = PS(player).m_weapon;
- .entity weaponentity = weaponentities[0]; // TODO: unhardcode
- if(player.(weaponentity).state != WS_CLEAR)
- w_ready(wpn, player, weaponentity, PHYS_INPUT_BUTTON_ATCK(player) | (PHYS_INPUT_BUTTON_ATCK2(player) << 1));
-
- player.weapon_blocked = true;
}
PHYS_INPUT_BUTTON_ATCK2(player) = false;
{
entity player = M_ARGV(0, entity);
- if(autocvar_g_overkill_ammo_charge)
- {
- FOREACH(Weapons, it != WEP_Null, LAMBDA(player.ammo_charge[it.m_id] = autocvar_g_overkill_ammo_charge_limit));
-
- player.ok_use_ammocharge = 1;
- player.ok_notice_time = time;
- }
- else
- player.ok_use_ammocharge = 0;
-
// if player changed their weapon while dead, don't switch to their death weapon
if(player.impulse)
- player.ok_lastwep = 0;
+ {
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ player.ok_lastwep[slot] = WEP_Null;
+ }
+ }
player.ok_pauseregen_finished = time + 2;
}
return true;
}
-MUTATOR_HOOKFUNCTION(ok, SpectateCopy)
-{
- entity spectatee = M_ARGV(0, entity);
- entity client = M_ARGV(1, entity);
-
- client.ammo_charge[PS(client).m_weapon.m_id] = spectatee.ammo_charge[PS(spectatee).m_weapon.m_id];
- client.ok_use_ammocharge = spectatee.ok_use_ammocharge;
-}
-
MUTATOR_HOOKFUNCTION(ok, SetStartItems, CBC_ORDER_LAST)
{
WepSet ok_start_items = (WEPSET(MACHINEGUN) | WEPSET(VORTEX) | WEPSET(SHOTGUN));
{
entity frag_target = M_ARGV(2, entity);
- FOREACH(Weapons, it != WEP_Null, LAMBDA(
- if(frag_target.weapons & WepSet_FromWeapon(it))
- if(PS(frag_target).m_switchweapon != it)
- 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');
- ));
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+
+ if(frag_target.(weaponentity).m_weapon == WEP_Null && slot != 0)
+ continue;
+
+ FOREACH(Weapons, it != WEP_Null, LAMBDA(
+ if(frag_target.weapons & WepSet_FromWeapon(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', weaponentity);
+ ));
+ }
return true;
}
// set crouched
bool do_crouch = PHYS_INPUT_BUTTON_CROUCH(this);
- if(this.hook && !wasfreed(this.hook))
- do_crouch = false;
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ entity wep = viewmodels[slot];
+ if(wep.hook && !wasfreed(wep.hook))
+ {
+ do_crouch = false;
+ break; // don't bother checking the others
+ }
+ }
if(this.waterlevel >= WATERLEVEL_SWIMMING)
do_crouch = false;
if(hud != HUD_NORMAL)
this.wasFlying = false;
if (this.waterlevel >= WATERLEVEL_SWIMMING) return;
if (time < this.ladder_time) return;
- if (this.hook) return;
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(this.(weaponentity).hook)
+ return;
+ }
this.nextstep = time + 0.3 + random() * 0.1;
trace_dphitq3surfaceflags = 0;
tracebox(this.origin, this.mins, this.maxs, this.origin - '0 0 1', MOVE_NOMONSTERS, 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);
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;
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))
REGISTER_STAT(HEALING_ORB, float)
REGISTER_STAT(HEALING_ORB_ALPHA, float)
REGISTER_STAT(PLASMA, int)
-REGISTER_STAT(OK_AMMO_CHARGE, float)
-REGISTER_STAT(OK_AMMO_CHARGEPOOL, float)
REGISTER_STAT(FROZEN, int)
REGISTER_STAT(REVIVE_PROGRESS, float)
REGISTER_STAT(ROUNDLOST, int)
float Item_GiveTo(entity item, entity player)
{
- float _switchweapon;
float pickedup;
// if nothing happens to player, just return without taking the item
pickedup = false;
- _switchweapon = false;
+ int _switchweapon = 0;
// in case the player has autoswitch enabled do the following:
// if the player is using their best weapon before items are given, they
// probably want to switch to an even better weapon after items are given
- if (player.autoswitch)
- if (PS(player).m_switchweapon == w_getbestweapon(player))
- _switchweapon = true;
- if (!(player.weapons & WepSet_FromWeapon(PS(player).m_switchweapon)))
- _switchweapon = true;
+ if(player.autoswitch)
+ {
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(player.(weaponentity).m_weapon != WEP_Null || slot == 0)
+ {
+ if(player.(weaponentity).m_switchweapon == w_getbestweapon(player, weaponentity))
+ _switchweapon |= BIT(slot);
+
+ if(!(player.weapons & WepSet_FromWeapon(player.(weaponentity).m_switchweapon)))
+ _switchweapon |= BIT(slot);
+ }
+ }
+ }
pickedup |= Item_GiveAmmoTo(item, player, ammo_fuel, g_pickup_fuel_max, ITEM_MODE_FUEL);
pickedup |= Item_GiveAmmoTo(item, player, ammo_shells, g_pickup_shells_max, ITEM_MODE_NONE);
FOREACH(Weapons, it != WEP_Null, {
if(w & (it.m_wepset))
{
- W_DropEvent(wr_pickup, player, it.m_id, item);
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(player.(weaponentity).m_weapon != WEP_Null || slot == 0)
+ W_DropEvent(wr_pickup, player, it.m_id, item, weaponentity);
+ }
W_GiveWeapon(player, it.m_id);
}
});
// crude hack to enforce switching weapons
if(g_cts && item.itemdef.instanceOfWeaponPickup)
{
- W_SwitchWeapon_Force(player, Weapons_from(item.weapon));
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(player.(weaponentity).m_weapon != WEP_Null || slot == 0)
+ W_SwitchWeapon_Force(player, Weapons_from(item.weapon), weaponentity);
+ }
return 1;
}
- if (_switchweapon)
- if (PS(player).m_switchweapon != w_getbestweapon(player))
- W_SwitchWeapon_Force(player, w_getbestweapon(player));
+ if(_switchweapon)
+ {
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(_switchweapon & BIT(slot))
+ if(player.(weaponentity).m_switchweapon != w_getbestweapon(player, weaponentity))
+ W_SwitchWeapon_Force(player, w_getbestweapon(player, weaponentity), weaponentity);
+ }
+ }
return 1;
}
float GiveItems(entity e, float beginarg, float endarg)
{
float got, i, val, op;
- float _switchweapon;
string cmd;
val = 999;
got = 0;
- _switchweapon = false;
- if (e.autoswitch)
- if (PS(e).m_switchweapon == w_getbestweapon(e))
- _switchweapon = true;
+ int _switchweapon = 0;
+
+ if(e.autoswitch)
+ {
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(e.(weaponentity).m_weapon != WEP_Null || slot == 0)
+ if(e.(weaponentity).m_switchweapon == w_getbestweapon(e, weaponentity))
+ _switchweapon |= BIT(slot);
+ }
+ }
e.strength_finished = max(0, e.strength_finished - time);
e.invincible_finished = max(0, e.invincible_finished - time);
else
e.superweapons_finished += time;
- if (!(e.weapons & WepSet_FromWeapon(PS(e).m_switchweapon)))
- _switchweapon = true;
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(e.(weaponentity).m_weapon != WEP_Null || slot == 0)
+ if(!(e.weapons & WepSet_FromWeapon(e.(weaponentity).m_switchweapon)))
+ _switchweapon |= BIT(slot);
+ }
+
if(_switchweapon)
- W_SwitchWeapon_Force(e, w_getbestweapon(e));
+ {
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(_switchweapon & BIT(slot))
+ W_SwitchWeapon_Force(e, w_getbestweapon(e, weaponentity), weaponentity);
+ }
+ }
return got;
}
#include "magicear.qh"
#ifdef SVQC
float magicear_matched;
-float W_Tuba_HasPlayed(entity pl, string melody, float instrument, float ignorepitch, float mintempo, float maxtempo);
+float W_Tuba_HasPlayed(entity pl, .entity weaponentity, string melody, float instrument, float ignorepitch, float mintempo, float maxtempo);
string trigger_magicear_processmessage(entity ear, entity source, float teamsay, entity privatesay, string msgin)
{
float domatch, dotrigger, matchstart, l;
if (!(ear.spawnflags & 256))
return msgin;
- if(!W_Tuba_HasPlayed(source, ear.message, ear.movedir_x, !(ear.spawnflags & 512), ear.movedir_y, ear.movedir_z))
- return msgin;
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(!W_Tuba_HasPlayed(source, weaponentity, ear.message, ear.movedir_x, !(ear.spawnflags & 512), ear.movedir_y, ear.movedir_z))
+ return msgin;
+ }
magicear_matched = true;
#ifdef SVQC
if(IS_PLAYER(toucher))
- RemoveGrapplingHook(toucher);
+ RemoveGrapplingHooks(toucher);
#endif
entity e;
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");
}
{
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);
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);
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);
}
}
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;
}
else return;
- RemoveGrapplingHook(pl);
+ RemoveGrapplingHooks(pl);
veh.vehicle_ammo1 = 0;
veh.vehicle_ammo2 = 0;
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;
if(this.vehicle_controller)
this.team = this.vehicle_controller.team;
- FOREACH_CLIENT(IS_PLAYER(it) && it.hook.aiment == this, RemoveGrapplingHook(it));
+ FOREACH_CLIENT(IS_PLAYER(it),
+ {
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(it.(weaponentity).hook.aiment == this)
+ RemoveHook(it.(weaponentity).hook);
+ }
+ });
vehicles_reset_colors(this);
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);
player.vehicle_energy = vehic.vehicle_energy;
UNSET_ONGROUND(player);
- RemoveGrapplingHook(player);
+ RemoveGrapplingHooks(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;
#ifdef SVQC
Weapon wep1 = WEP_RACER;
+ .entity weaponentity = weaponentities[0]; // TODO: unhardcode
if (!forbidWeaponUse(this))
if (PHYS_INPUT_BUTTON_ATCK(this))
- if (wep1.wr_checkammo1(wep1, vehic))
+ if (wep1.wr_checkammo1(wep1, vehic, weaponentity))
{
string tagname = (vehic.cnt)
? (vehic.cnt = 0, "tag_fire1")
// Fix z-aim (for chase mode)
crosshair_trace(this);
w_shotdir.z = normalize(trace_endpos - org).z * 0.5;
- .entity weaponentity = weaponentities[0];
wep1.wr_think(wep1, vehic, weaponentity, 1);
}
}
}
-METHOD(RacerAttack, wr_checkammo1, bool(RacerAttack thiswep, entity actor))
+METHOD(RacerAttack, wr_checkammo1, bool(RacerAttack thiswep, entity actor, .entity weaponentity))
{
bool isPlayer = IS_PLAYER(actor);
entity player = isPlayer ? actor : actor.owner;
*/
Weapon wep1 = WEP_RAPTOR;
+ .entity weaponentity = weaponentities[0];
if(!forbidWeaponUse(this))
if(PHYS_INPUT_BUTTON_ATCK(this))
- if (wep1.wr_checkammo1(wep1, vehic))
+ if (wep1.wr_checkammo1(wep1, vehic, weaponentity))
{
- .entity weaponentity = weaponentities[0];
wep1.wr_think(wep1, vehic, weaponentity, 1);
}
weapon_thinkf(player, weaponentity, WFRAME_FIRE1, 0, w_ready);
}
}
-METHOD(RaptorCannon, wr_checkammo1, bool(RacerAttack thiswep, entity actor)) {
+METHOD(RaptorCannon, wr_checkammo1, bool(RacerAttack thiswep, entity actor, .entity weaponentity)) {
bool isPlayer = IS_PLAYER(actor);
entity player = isPlayer ? actor : actor.owner;
entity veh = player.vehicle;
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;
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);
{
if (name == "")
{
- this.model = "";
+ vector oldmin = this.mins, oldmax = this.maxs;
+ setmodel(this, MDL_Null);
+ setsize(this, oldmin, oldmax);
if (this.weaponchild) delete(this.weaponchild);
this.weaponchild = NULL;
this.movedir = '0 0 0';
if (this.movedir.x >= 0)
{
- int algn = STAT(GUNALIGN, this.owner);
+ //int algn = STAT(GUNALIGN, this.owner);
+ int algn = W_GunAlign(this, STAT(GUNALIGN, this.owner));
+ #ifdef SVQC
+ this.m_gunalign = algn;
+ #endif
vector v = this.movedir;
this.movedir = shotorg_adjust(v, false, false, algn);
this.view_ofs = shotorg_adjust(v, false, true, algn) - v;
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();
+ 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;
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);
- WriteByte(channel, weaponentity.m_alpha * 255);
}
#endif
.entity weaponchild;
.entity exteriorweaponentity;
-vector weaponentity_glowmod(Weapon wep, entity actor, int c)
+vector weaponentity_glowmod(Weapon wep, entity actor, int c, entity wepent)
{
vector g;
- if (!(g = wep.wr_glow(wep, actor))) g = colormapPaletteColor(c & 0x0F, true) * 2;
+ if (!(g = wep.wr_glow(wep, actor, wepent))) g = colormapPaletteColor(c & 0x0F, true) * 2;
return g;
}
+.int m_gunalign;
+
//.int weapon; // current weapon
.string weaponname; // name of .weapon
return normalize(cliptoplane(p, v));
}
+#ifdef SVQC
+ int W_GunAlign(entity this, int preferred_align)
+ {
+ if(this.m_gunalign)
+ return this.m_gunalign; // no adjustment needed
+
+ entity own = this.owner;
+
+ if(preferred_align < 1 || preferred_align > 4)
+ preferred_align = 3; // default
+
+ for(int j = 4; j > 1; --j) // > 1 as 1 is just center again
+ {
+ int taken = 0;
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(own.(weaponentity).m_gunalign == j) // we know it can't be ours thanks to the above check
+ taken |= BIT(j);
+ if(own.(weaponentity).m_gunalign == preferred_align)
+ taken |= BIT(preferred_align);
+ }
+
+ if(!(taken & BIT(preferred_align)))
+ return preferred_align; // prefer the recommended
+ if(!(taken & BIT(j)))
+ return j; // or fall back if it's not available
+ }
+
+ return preferred_align; // return it anyway
+ }
+#else
+ int W_GunAlign(entity this, int preferred_align)
+ {
+ return this.m_gunalign > 0 ? this.m_gunalign : preferred_align;
+ }
+#endif
+
+#if 0
int W_GetGunAlignment(entity player)
{
int gunalign = STAT(GUNALIGN, player);
return gunalign;
}
+#endif
vector W_CalculateSpread(vector forward, float spread, float spreadfactor, float spreadstyle)
{
vector damage_explosion_calcpush(vector explosion_f, vector target_v, float speedfactor);
vector W_CalculateSpread(vector forward, float spread, float spreadfactor, float spreadstyle);
-int W_GetGunAlignment(entity player);
+int W_GunAlign(entity this, int preferred_align);
+//int W_GetGunAlignment(entity player);
float explosion_calcpush_getmultiplier(vector explosion_v, vector target_v);
ATTRIB(Weapon, w_crosshair, string, "gfx/crosshair1");
/** A: crosshair : per-weapon crosshair size (argument two of "crosshair" field) */
ATTRIB(Weapon, w_crosshair_size, float, 1);
+ /** A: reticle : per-weapon zoom reticle */
+ ATTRIB(Weapon, w_reticle, string, "");
/** M: wepimg : "weaponfoobar" side view image file of weapon. WEAPONTODO: Move out of skin files, move to common files */
ATTRIB(Weapon, model2, string, "");
/** M: refname : reference name name */
ATTRIB(Weapon, m_pickup, entity);
/** (SERVER) setup weapon data */
- METHOD(Weapon, wr_setup, void(Weapon this, entity actor)) {}
+ METHOD(Weapon, wr_setup, void(Weapon this, entity actor, .entity weaponentity)) {}
/** (SERVER) logic to run every frame */
METHOD(Weapon, wr_think, void(Weapon this, entity actor, .entity weaponentity, int fire)) {}
/** (SERVER) checks ammo for weapon primary */
- METHOD(Weapon, wr_checkammo1, bool(Weapon this, entity actor)) {return false;}
+ METHOD(Weapon, wr_checkammo1, bool(Weapon this, entity actor, .entity weaponentity)) {return false;}
/** (SERVER) checks ammo for weapon second */
- METHOD(Weapon, wr_checkammo2, bool(Weapon this, entity actor)) {return false;}
+ METHOD(Weapon, wr_checkammo2, bool(Weapon this, entity actor, .entity weaponentity)) {return false;}
/** (SERVER) runs bot aiming code for this weapon */
- METHOD(Weapon, wr_aim, void(Weapon this, entity actor)) {}
+ METHOD(Weapon, wr_aim, void(Weapon this, entity actor, .entity weaponentity)) {}
/** (BOTH) precaches models/sounds used by this weapon, also sets up weapon properties */
METHOD(Weapon, wr_init, void(Weapon this)) {}
/** (SERVER) notification number for suicide message (may inspect w_deathtype for details) */
METHOD(Weapon, wr_gonethink, void(Weapon this, entity actor, .entity weaponentity)) {}
/** (ALL) dump weapon cvars to config in data directory (see: sv_cmd dumpweapons) */
METHOD(Weapon, wr_config, void(Weapon this)) {}
- /** (CLIENT) weapon specific zoom reticle */
- METHOD(Weapon, wr_zoomreticle, bool(Weapon this)) {
+ /** (BOTH) weapon specific zoom reticle */
+ METHOD(Weapon, wr_zoom, bool(Weapon this, entity actor)) {
// no weapon specific image for this weapon
return false;
}
/** (CLIENT) weapon specific glow */
- METHOD(Weapon, wr_glow, vector(Weapon this, entity actor)) { return '0 0 0'; }
+ METHOD(Weapon, wr_glow, vector(Weapon this, entity actor, entity wepent)) { return '0 0 0'; }
/** (SERVER) the weapon is dropped */
- METHOD(Weapon, wr_drop, void(Weapon this, entity actor)) {}
+ METHOD(Weapon, wr_drop, void(Weapon this, entity actor, .entity weaponentity)) {}
/** (SERVER) a weapon is picked up */
- METHOD(Weapon, wr_pickup, void(Weapon this, entity actor)) {}
+ METHOD(Weapon, wr_pickup, void(Weapon this, entity actor, .entity weaponentity)) {}
/** (SERVER) update cvar based properties */
METHOD(Weapon, wr_update, void(Weapon this)) {}
METHOD(Weapon, display, void(entity this, void(string name, string icon) returns)) {
#endif
#ifdef SVQC
.entity arc_beam;
-.bool arc_BUTTON_ATCK_prev[MAX_WEAPONSLOTS]; // for better animation control
+.bool arc_BUTTON_ATCK_prev; // for better animation control
.float beam_prev;
.float beam_initialized;
.float beam_bursting;
if(drawlocal) { sf &= ~ARC_SF_LOCALMASK; }
WriteByte(MSG_ENTITY, sf);
+ WriteByte(MSG_ENTITY, weaponslot(this.weaponentity_fld));
if(sf & ARC_SF_SETTINGS) // settings information
{
{
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));
if(this == this.owner.(weaponentity).arc_beam) { this.owner.(weaponentity).arc_beam = NULL; }
entity own = this.owner;
Weapon w = WEP_ARC;
- if(!w.wr_checkammo1(w, own) && !w.wr_checkammo2(w, own))
+ if(!w.wr_checkammo1(w, own, weaponentity) && !w.wr_checkammo2(w, own, weaponentity))
if(!(own.items & IT_UNLIMITED_WEAPON_AMMO))
{
// note: this doesn't force the switch
- W_SwitchToOtherWeapon(own);
+ W_SwitchToOtherWeapon(own, weaponentity);
}
delete(this);
return;
this.beam_type = new_beam_type;
}
- this.owner.beam_prev = time;
+ this.owner.(weaponentity).beam_prev = time;
this.nextthink = time;
}
{
// only play fire sound if 1 sec has passed since player let go the fire button
- if(time - actor.beam_prev > 1)
+ if(time - actor.(weaponentity).beam_prev > 1)
sound(actor, CH_WEAPON_A, SND_ARC_FIRE, VOL_BASE, ATTN_NORM);
entity beam = actor.(weaponentity).arc_beam = new(W_Arc_Beam);
}
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);
}
}
-METHOD(Arc, wr_aim, void(entity thiswep, entity actor))
+METHOD(Arc, wr_aim, void(entity thiswep, entity actor, .entity weaponentity))
{
if(WEP_CVAR(arc, beam_botaimspeed))
{
PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(
actor,
+ weaponentity,
WEP_CVAR(arc, beam_botaimspeed),
0,
WEP_CVAR(arc, beam_botaimlifetime),
{
PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(
actor,
+ weaponentity,
1000000,
0,
0.001,
Arc_Smoke(actor, weaponentity);
bool beam_fire2 = ((fire & 2) && !WEP_CVAR(arc, bolt));
- int slot = weaponslot(weaponentity);
if (time >= actor.arc_overheat)
if ((fire & 1) || beam_fire2 || actor.(weaponentity).arc_beam.beam_bursting)
{
- if(actor.arc_BUTTON_ATCK_prev[slot])
+ if(actor.(weaponentity).arc_BUTTON_ATCK_prev)
{
#if 0
if(actor.animstate_startframe == actor.anim_shoot.x && actor.animstate_numframes == actor.anim_shoot.y)
{
W_Arc_Beam(boolean(beam_fire2), actor, weaponentity);
- if(!actor.arc_BUTTON_ATCK_prev[slot])
+ if(!actor.(weaponentity).arc_BUTTON_ATCK_prev)
{
weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(arc, beam_animtime), w_ready);
- actor.arc_BUTTON_ATCK_prev[slot] = true;
+ actor.(weaponentity).arc_BUTTON_ATCK_prev = true;
}
}
}
}
}
- if(actor.arc_BUTTON_ATCK_prev[slot])
+ if(actor.(weaponentity).arc_BUTTON_ATCK_prev)
{
+ int slot = weaponslot(weaponentity);
sound(actor, CH_WEAPON_A, SND_ARC_STOP, VOL_BASE, ATTN_NORM);
weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(arc, beam_animtime), w_ready);
ATTACK_FINISHED(actor, slot) = time + WEP_CVAR(arc, beam_refire) * W_WeaponRateFactor(actor);
}
- actor.arc_BUTTON_ATCK_prev[slot] = false;
+ actor.(weaponentity).arc_BUTTON_ATCK_prev = false;
#if 0
if(fire & 2)
arc_shotorigin[3] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC.m_id), false, false, 4);
}
}
-METHOD(Arc, wr_checkammo1, bool(entity thiswep, entity actor))
+METHOD(Arc, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity))
{
return ((!WEP_CVAR(arc, beam_ammo)) || (actor.(thiswep.ammo_field) > 0));
}
-METHOD(Arc, wr_checkammo2, bool(entity thiswep, entity actor))
+METHOD(Arc, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity))
{
if(WEP_CVAR(arc, bolt))
{
float ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR(arc, bolt_ammo);
- ammo_amount += actor.(weapon_load[WEP_ARC.m_id]) >= WEP_CVAR(arc, bolt_ammo);
+ ammo_amount += actor.(weaponentity).(weapon_load[WEP_ARC.m_id]) >= WEP_CVAR(arc, bolt_ammo);
return ammo_amount;
}
else
else
return WEAPON_ARC_MURDER;
}
-METHOD(Arc, wr_drop, void(entity thiswep, entity actor))
+METHOD(Arc, wr_drop, void(entity thiswep, entity actor, .entity weaponentity))
{
weapon_dropevent_item.arc_overheat = actor.arc_overheat;
weapon_dropevent_item.arc_cooldown = actor.arc_cooldown;
actor.arc_overheat = 0;
actor.arc_cooldown = 0;
- for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
- actor.arc_BUTTON_ATCK_prev[slot] = false;
+ actor.(weaponentity).arc_BUTTON_ATCK_prev = false;
}
-METHOD(Arc, wr_pickup, void(entity thiswep, entity actor))
+METHOD(Arc, wr_pickup, void(entity thiswep, entity actor, .entity weaponentity))
{
- if ( !client_hasweapon(actor, thiswep, false, false) &&
+ if ( !client_hasweapon(actor, thiswep, weaponentity, false, false) &&
weapon_dropevent_item.arc_overheat > time )
{
actor.arc_overheat = weapon_dropevent_item.arc_overheat;
actor.arc_overheat = 0;
actor.arc_cooldown = 0;
for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
- actor.arc_BUTTON_ATCK_prev[slot] = false;
+ {
+ .entity weaponentity = weaponentities[slot];
+ actor.(weaponentity).arc_BUTTON_ATCK_prev = false;
+ }
}
METHOD(Arc, wr_playerdeath, void(entity thiswep, entity actor, .entity weaponentity))
{
actor.arc_overheat = 0;
actor.arc_cooldown = 0;
- int slot = weaponslot(weaponentity);
- actor.arc_BUTTON_ATCK_prev[slot] = false;
+ actor.(weaponentity).arc_BUTTON_ATCK_prev = false;
}
#endif
#ifdef CSQC
NET_HANDLE(ENT_CLIENT_ARC_BEAM, bool isnew)
{
int sf = ReadByte();
+ int slot = ReadByte();
entity flash;
if(isnew)
{
- int gunalign = W_GetGunAlignment(NULL);
+ int gunalign = W_GunAlign(viewmodels[slot], STAT(GUNALIGN)) - 1;
this.beam_shotorigin = arc_shotorigin[gunalign];
}
}
-METHOD(Blaster, wr_aim, void(entity thiswep, entity actor))
+METHOD(Blaster, wr_aim, void(entity thiswep, entity actor, .entity weaponentity))
{
if(WEP_CVAR(blaster, secondary))
{
if((random() * (WEP_CVAR_PRI(blaster, damage) + WEP_CVAR_SEC(blaster, damage))) > WEP_CVAR_PRI(blaster, damage))
- { PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, WEP_CVAR_SEC(blaster, speed), 0, WEP_CVAR_SEC(blaster, lifetime), false); }
+ { PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, weaponentity, WEP_CVAR_SEC(blaster, speed), 0, WEP_CVAR_SEC(blaster, lifetime), false); }
else
- { PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, WEP_CVAR_PRI(blaster, speed), 0, WEP_CVAR_PRI(blaster, lifetime), false); }
+ { PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, WEP_CVAR_PRI(blaster, speed), 0, WEP_CVAR_PRI(blaster, lifetime), false); }
}
else
- { PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, WEP_CVAR_PRI(blaster, speed), 0, WEP_CVAR_PRI(blaster, lifetime), false); }
+ { PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, WEP_CVAR_PRI(blaster, speed), 0, WEP_CVAR_PRI(blaster, lifetime), false); }
}
METHOD(Blaster, wr_think, void(Blaster thiswep, entity actor, .entity weaponentity, int fire))
{
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;
}
}
}
-METHOD(Blaster, wr_setup, void(entity thiswep, entity actor))
-{
- actor.ammo_field = ammo_none;
-}
-
-METHOD(Blaster, wr_checkammo1, bool(entity thiswep, entity actor))
+METHOD(Blaster, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity))
{
return true; // infinite ammo
}
-METHOD(Blaster, wr_checkammo2, bool(entity thiswep, entity actor))
+METHOD(Blaster, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity))
{
return true; // blaster has infinite ammo
}
void W_Crylink_Dequeue_Raw(entity own, entity prev, entity me, entity next)
{
W_Crylink_CheckLinks(next);
- if(me == own.crylink_lastgroup)
- own.crylink_lastgroup = ((me == next) ? NULL : next);
+ .entity weaponentity = me.weaponentity_fld;
+ if(me == own.(weaponentity).crylink_lastgroup)
+ own.(weaponentity).crylink_lastgroup = ((me == next) ? NULL : next);
prev.queuenext = next;
next.queueprev = prev;
me.classname = "spike_oktoremove";
a = bound(0, 1 - (time - e.fade_time) * e.fade_rate, 1);
- if(e == e.realowner.crylink_lastgroup)
- e.realowner.crylink_lastgroup = NULL;
+ .entity weaponentity = e.weaponentity_fld;
+ if(e == e.realowner.(weaponentity).crylink_lastgroup)
+ e.realowner.(weaponentity).crylink_lastgroup = NULL;
float isprimary = !(e.projectiledeathtype & HITTYPE_SECONDARY);
// is there at least 2 projectiles very close?
entity e, p;
float n;
- e = this.owner.crylink_lastgroup;
+ .entity weaponentity = this.weaponentity_fld;
+ e = this.owner.(weaponentity).crylink_lastgroup;
n = 0;
if(e)
{
if(totaldamage && ((WEP_CVAR_BOTH(crylink, isprimary, linkexplode) == 2) || ((WEP_CVAR_BOTH(crylink, isprimary, linkexplode) == 1) && !W_Crylink_Touch_WouldHitFriendly(this, WEP_CVAR_BOTH(crylink, isprimary, radius)))))
{
- if(this == this.realowner.crylink_lastgroup)
- this.realowner.crylink_lastgroup = NULL;
+ .entity weaponentity = this.weaponentity_fld;
+ if(this == this.realowner.(weaponentity).crylink_lastgroup)
+ this.realowner.(weaponentity).crylink_lastgroup = NULL;
W_Crylink_LinkExplode(this.queuenext, this, toucher);
this.classname = "spike_oktoremove";
delete(this);
vector forward, right, up;
float maxdmg;
- W_DecreaseAmmo(thiswep, actor, WEP_CVAR_PRI(crylink, ammo));
+ W_DecreaseAmmo(thiswep, actor, WEP_CVAR_PRI(crylink, ammo), weaponentity);
maxdmg = WEP_CVAR_PRI(crylink, damage) * WEP_CVAR_PRI(crylink, shots);
maxdmg *= 1 + WEP_CVAR_PRI(crylink, bouncedamagefactor) * WEP_CVAR_PRI(crylink, bounces);
proj = new(spike);
proj.reset = W_Crylink_Reset;
proj.realowner = proj.owner = actor;
+ proj.weaponentity_fld = weaponentity;
proj.bot_dodge = true;
proj.bot_dodgerating = WEP_CVAR_PRI(crylink, damage);
if(shots == 1) {
}
if(WEP_CVAR_PRI(crylink, joinspread) != 0)
{
- actor.crylink_lastgroup = proj;
+ actor.(weaponentity).crylink_lastgroup = proj;
W_Crylink_CheckLinks(proj);
- actor.crylink_waitrelease = 1;
+ actor.(weaponentity).crylink_waitrelease = 1;
}
}
vector forward, right, up;
float maxdmg;
- W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(crylink, ammo));
+ W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(crylink, ammo), weaponentity);
maxdmg = WEP_CVAR_SEC(crylink, damage) * WEP_CVAR_SEC(crylink, shots);
maxdmg *= 1 + WEP_CVAR_SEC(crylink, bouncedamagefactor) * WEP_CVAR_SEC(crylink, bounces);
for(counter = 0; counter < shots; ++counter)
{
proj = new(spike);
+ proj.weaponentity_fld = weaponentity;
proj.reset = W_Crylink_Reset;
proj.realowner = proj.owner = actor;
proj.bot_dodge = true;
}
if(WEP_CVAR_SEC(crylink, joinspread) != 0)
{
- actor.crylink_lastgroup = proj;
+ actor.(weaponentity).crylink_lastgroup = proj;
W_Crylink_CheckLinks(proj);
- actor.crylink_waitrelease = 2;
+ actor.(weaponentity).crylink_waitrelease = 2;
}
}
-METHOD(Crylink, wr_aim, void(entity thiswep, entity actor))
+METHOD(Crylink, wr_aim, void(entity thiswep, entity actor, .entity weaponentity))
{
if(random() < 0.10)
- PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, WEP_CVAR_PRI(crylink, speed), 0, WEP_CVAR_PRI(crylink, middle_lifetime), false);
+ PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, WEP_CVAR_PRI(crylink, speed), 0, WEP_CVAR_PRI(crylink, middle_lifetime), false);
else
- PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, WEP_CVAR_SEC(crylink, speed), 0, WEP_CVAR_SEC(crylink, middle_lifetime), false);
+ PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, weaponentity, WEP_CVAR_SEC(crylink, speed), 0, WEP_CVAR_SEC(crylink, middle_lifetime), false);
}
METHOD(Crylink, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
{
- if(autocvar_g_balance_crylink_reload_ammo && actor.clip_load < min(WEP_CVAR_PRI(crylink, ammo), WEP_CVAR_SEC(crylink, ammo))) { // forced reload
+ if(autocvar_g_balance_crylink_reload_ammo && actor.(weaponentity).clip_load < min(WEP_CVAR_PRI(crylink, ammo), WEP_CVAR_SEC(crylink, ammo))) { // forced reload
thiswep.wr_reload(thiswep, actor, weaponentity);
}
if(fire & 1)
{
- if(actor.crylink_waitrelease != 1)
+ if(actor.(weaponentity).crylink_waitrelease != 1)
if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(crylink, refire)))
{
W_Crylink_Attack(thiswep, actor, weaponentity);
if((fire & 2) && autocvar_g_balance_crylink_secondary)
{
- if(actor.crylink_waitrelease != 2)
+ if(actor.(weaponentity).crylink_waitrelease != 2)
if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(crylink, refire)))
{
W_Crylink_Attack2(thiswep, actor, weaponentity);
}
}
- if((actor.crylink_waitrelease == 1 && !(fire & 1)) || (actor.crylink_waitrelease == 2 && !(fire & 2)))
+ if((actor.(weaponentity).crylink_waitrelease == 1 && !(fire & 1)) || (actor.(weaponentity).crylink_waitrelease == 2 && !(fire & 2)))
{
- if(!actor.crylink_lastgroup || time > actor.crylink_lastgroup.teleport_time)
+ if(!actor.(weaponentity).crylink_lastgroup || time > actor.(weaponentity).crylink_lastgroup.teleport_time)
{
// fired and released now!
- if(actor.crylink_lastgroup)
+ if(actor.(weaponentity).crylink_lastgroup)
{
vector pos;
entity linkjoineffect;
- float isprimary = (actor.crylink_waitrelease == 1);
+ float isprimary = (actor.(weaponentity).crylink_waitrelease == 1);
- pos = W_Crylink_LinkJoin(actor.crylink_lastgroup, WEP_CVAR_BOTH(crylink, isprimary, joinspread) * WEP_CVAR_BOTH(crylink, isprimary, speed));
+ pos = W_Crylink_LinkJoin(actor.(weaponentity).crylink_lastgroup, WEP_CVAR_BOTH(crylink, isprimary, joinspread) * WEP_CVAR_BOTH(crylink, isprimary, speed));
linkjoineffect = new(linkjoineffect);
+ linkjoineffect.weaponentity_fld = weaponentity;
setthink(linkjoineffect, W_Crylink_LinkJoinEffect_Think);
linkjoineffect.nextthink = time + w_crylink_linkjoin_time;
linkjoineffect.owner = actor;
setorigin(linkjoineffect, pos);
}
- actor.crylink_waitrelease = 0;
- if(!thiswep.wr_checkammo1(thiswep, actor) && !thiswep.wr_checkammo2(thiswep, actor))
+ actor.(weaponentity).crylink_waitrelease = 0;
+ if(!thiswep.wr_checkammo1(thiswep, actor, weaponentity) && !thiswep.wr_checkammo2(thiswep, actor, weaponentity))
if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
{
// ran out of ammo!
actor.cnt = WEP_CRYLINK.m_id;
- PS(actor).m_switchweapon = w_getbestweapon(actor);
+ actor.(weaponentity).m_switchweapon = w_getbestweapon(actor, weaponentity);
}
}
}
}
-METHOD(Crylink, wr_checkammo1, bool(entity thiswep, entity actor))
+METHOD(Crylink, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity))
{
// don't "run out of ammo" and switch weapons while waiting for release
- if(actor.crylink_lastgroup && actor.crylink_waitrelease)
+ if(actor.(weaponentity).crylink_lastgroup && actor.(weaponentity).crylink_waitrelease)
return true;
float ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR_PRI(crylink, ammo);
- ammo_amount += actor.(weapon_load[WEP_CRYLINK.m_id]) >= WEP_CVAR_PRI(crylink, ammo);
+ ammo_amount += actor.(weaponentity).(weapon_load[WEP_CRYLINK.m_id]) >= WEP_CVAR_PRI(crylink, ammo);
return ammo_amount;
}
-METHOD(Crylink, wr_checkammo2, bool(entity thiswep, entity actor))
+METHOD(Crylink, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity))
{
// don't "run out of ammo" and switch weapons while waiting for release
- if(actor.crylink_lastgroup && actor.crylink_waitrelease)
+ if(actor.(weaponentity).crylink_lastgroup && actor.(weaponentity).crylink_waitrelease)
return true;
float ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR_SEC(crylink, ammo);
- ammo_amount += actor.(weapon_load[WEP_CRYLINK.m_id]) >= WEP_CVAR_SEC(crylink, ammo);
+ ammo_amount += actor.(weaponentity).(weapon_load[WEP_CRYLINK.m_id]) >= WEP_CVAR_SEC(crylink, ammo);
return ammo_amount;
}
METHOD(Crylink, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
REGISTER_WEAPON(DEVASTATOR, devastator, NEW(Devastator));
#ifdef SVQC
-.float rl_release[MAX_WEAPONSLOTS];
+.float rl_release;
.float rl_detonate_later;
#endif
#endif
);
Weapon thiswep = WEP_DEVASTATOR;
- if(PS(this.realowner).m_weapon == thiswep)
+ .entity weaponentity = this.weaponentity_fld;
+ 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))
{
this.realowner.cnt = WEP_DEVASTATOR.m_id;
- int slot = 0; // TODO: unhardcode
+ 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, weaponentity);
}
}
delete(this);
);
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))
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, weaponentity);
}
}
delete(this);
this.velocity = this.velocity + v_forward * min(WEP_CVAR(devastator, speedaccel) * W_WeaponSpeedFactor(this.realowner) * frametime, velspeed);
// laser guided, or remote detonation
- if(PS(this.realowner).m_weapon == WEP_DEVASTATOR)
+ .entity weaponentity = this.weaponentity_fld;
+ if(this.realowner.(weaponentity).m_weapon == WEP_DEVASTATOR)
{
- .entity weaponentity = this.weaponentity_fld;
- int slot = weaponslot(weaponentity);
-
if(this == this.realowner.(weaponentity).lastrocket)
- if(!this.realowner.rl_release[slot])
+ if(!this.realowner.(weaponentity).rl_release)
if(!PHYS_INPUT_BUTTON_ATCK2(this))
if(WEP_CVAR(devastator, guiderate))
if(time > this.pushltime)
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);
MUTATOR_CALLHOOK(EditProjectile, actor, missile);
}
-METHOD(Devastator, wr_aim, void(entity thiswep, entity actor))
+METHOD(Devastator, wr_aim, void(entity thiswep, entity actor, .entity weaponentity))
{
// aim and decide to fire if appropriate
- PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, WEP_CVAR(devastator, speed), 0, WEP_CVAR(devastator, lifetime), false);
+ PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, WEP_CVAR(devastator, speed), 0, WEP_CVAR(devastator, lifetime), false);
if(skill >= 2) // skill 0 and 1 bots won't detonate rockets!
{
// decide whether to detonate rockets
METHOD(Devastator, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
{
- if(WEP_CVAR(devastator, reload_ammo) && actor.clip_load < WEP_CVAR(devastator, ammo)) { // forced reload
+ if(WEP_CVAR(devastator, reload_ammo) && actor.(weaponentity).clip_load < WEP_CVAR(devastator, ammo)) { // forced reload
thiswep.wr_reload(thiswep, actor, weaponentity);
} else {
- int slot = weaponslot(weaponentity);
if(fire & 1)
{
- if(actor.rl_release[slot] || WEP_CVAR(devastator, guidestop))
+ if(actor.(weaponentity).rl_release || WEP_CVAR(devastator, guidestop))
if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(devastator, refire)))
{
W_Devastator_Attack(thiswep, actor, weaponentity);
weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(devastator, animtime), w_ready);
- actor.rl_release[slot] = 0;
+ actor.(weaponentity).rl_release = 0;
}
}
else
- actor.rl_release[slot] = 1;
+ actor.(weaponentity).rl_release = 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",
}
}
}
-METHOD(Devastator, wr_setup, void(entity thiswep, entity actor))
+METHOD(Devastator, wr_setup, void(entity thiswep, entity actor, .entity weaponentity))
{
- for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
- actor.rl_release[slot] = 1;
+ actor.(weaponentity).rl_release = 1;
}
-METHOD(Devastator, wr_checkammo1, bool(entity thiswep, entity actor))
+METHOD(Devastator, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity))
{
#if 0
// don't switch while guiding a missile
ammo_amount = false;
if(WEP_CVAR(devastator, reload_ammo))
{
- if(actor.(thiswep.ammo_field) < WEP_CVAR(devastator, ammo) && actor.(weapon_load[WEP_DEVASTATOR.m_id]) < WEP_CVAR(devastator, ammo))
+ if(actor.(thiswep.ammo_field) < WEP_CVAR(devastator, ammo) && actor.(weaponentity).(weapon_load[WEP_DEVASTATOR.m_id]) < WEP_CVAR(devastator, ammo))
ammo_amount = true;
}
else if(actor.(thiswep.ammo_field) < WEP_CVAR(devastator, ammo))
else
{
ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR(devastator, ammo);
- ammo_amount += actor.(weapon_load[WEP_DEVASTATOR.m_id]) >= WEP_CVAR(devastator, ammo);
+ ammo_amount += actor.(weaponentity).(weapon_load[WEP_DEVASTATOR.m_id]) >= WEP_CVAR(devastator, ammo);
LOG_INFOF("W_Devastator(WR_CHECKAMMO1): %d, %.2f, %d: %s\n", actor.rl_release, actor.(thiswep.ammo_field), WEP_CVAR(devastator, ammo), (ammo_amount ? "TRUE" : "FALSE"));
return ammo_amount;
}
#else
float ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR(devastator, ammo);
- ammo_amount += actor.(weapon_load[WEP_DEVASTATOR.m_id]) >= WEP_CVAR(devastator, ammo);
+ ammo_amount += actor.(weaponentity).(weapon_load[WEP_DEVASTATOR.m_id]) >= WEP_CVAR(devastator, ammo);
return ammo_amount;
#endif
}
-METHOD(Devastator, wr_checkammo2, bool(entity thiswep, entity actor))
+METHOD(Devastator, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity))
{
return false;
}
{
.entity weaponentity = weaponentities[slot];
actor.(weaponentity).lastrocket = NULL; // stop rocket guiding, no revenge from the grave!
- actor.rl_release[slot] = 0;
+ actor.(weaponentity).rl_release = 0;
}
}
METHOD(Devastator, wr_reload, void(entity 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,
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,
void W_Electro_CheckAttack(Weapon thiswep, entity actor, .entity weaponentity, int fire)
{
- if(actor.electro_count > 1)
+ if(actor.(weaponentity).electro_count > 1)
if(PHYS_INPUT_BUTTON_ATCK2(actor))
if(weapon_prepareattack(thiswep, actor, weaponentity, true, -1))
{
W_Electro_Attack_Orb(WEP_ELECTRO, actor, weaponentity);
- actor.electro_count -= 1;
+ actor.(weaponentity).electro_count -= 1;
weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(electro, animtime), W_Electro_CheckAttack);
return;
}
.float bot_secondary_electromooth;
-METHOD(Electro, wr_aim, void(entity thiswep, entity actor))
+METHOD(Electro, wr_aim, void(entity thiswep, entity actor, .entity weaponentity))
{
PHYS_INPUT_BUTTON_ATCK(actor) = PHYS_INPUT_BUTTON_ATCK2(actor) = false;
if(vdist(actor.origin - actor.enemy.origin, >, 1000)) { actor.bot_secondary_electromooth = 0; }
float shoot;
if(WEP_CVAR_PRI(electro, speed))
- shoot = bot_aim(actor, WEP_CVAR_PRI(electro, speed), 0, WEP_CVAR_PRI(electro, lifetime), false);
+ shoot = bot_aim(actor, weaponentity, WEP_CVAR_PRI(electro, speed), 0, WEP_CVAR_PRI(electro, lifetime), false);
else
- shoot = bot_aim(actor, 1000000, 0, 0.001, false);
+ shoot = bot_aim(actor, weaponentity, 1000000, 0, 0.001, false);
if(shoot)
{
}
else
{
- if(bot_aim(actor, WEP_CVAR_SEC(electro, speed), WEP_CVAR_SEC(electro, speed_up), WEP_CVAR_SEC(electro, lifetime), true))
+ if(bot_aim(actor, weaponentity, WEP_CVAR_SEC(electro, speed), WEP_CVAR_SEC(electro, speed_up), WEP_CVAR_SEC(electro, lifetime), true))
{
PHYS_INPUT_BUTTON_ATCK2(actor) = true;
if(random() < 0.03) actor.bot_secondary_electromooth = 0;
if(autocvar_g_balance_electro_reload_ammo) // forced reload // WEAPONTODO
{
float ammo_amount = 0;
- if(actor.clip_load >= WEP_CVAR_PRI(electro, ammo))
+ if(actor.(weaponentity).clip_load >= WEP_CVAR_PRI(electro, ammo))
ammo_amount = 1;
- if(actor.clip_load >= WEP_CVAR_SEC(electro, ammo))
+ if(actor.(weaponentity).clip_load >= WEP_CVAR_SEC(electro, ammo))
ammo_amount += 1;
if(!ammo_amount)
}
else if(fire & 2)
{
- if(time >= actor.electro_secondarytime)
+ if(time >= actor.(weaponentity).electro_secondarytime)
if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(electro, refire)))
{
W_Electro_Attack_Orb(thiswep, actor, weaponentity);
- actor.electro_count = WEP_CVAR_SEC(electro, count);
+ actor.(weaponentity).electro_count = WEP_CVAR_SEC(electro, count);
weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(electro, animtime), W_Electro_CheckAttack);
- actor.electro_secondarytime = time + WEP_CVAR_SEC(electro, refire2) * W_WeaponRateFactor(actor);
+ actor.(weaponentity).electro_secondarytime = time + WEP_CVAR_SEC(electro, refire2) * W_WeaponRateFactor(actor);
}
}
}
-METHOD(Electro, wr_checkammo1, bool(entity thiswep, entity actor))
+METHOD(Electro, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity))
{
float ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR_PRI(electro, ammo);
- ammo_amount += actor.(weapon_load[WEP_ELECTRO.m_id]) >= WEP_CVAR_PRI(electro, ammo);
+ ammo_amount += actor.(weaponentity).(weapon_load[WEP_ELECTRO.m_id]) >= WEP_CVAR_PRI(electro, ammo);
return ammo_amount;
}
-METHOD(Electro, wr_checkammo2, bool(entity thiswep, entity actor))
+METHOD(Electro, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity))
{
float ammo_amount;
if(WEP_CVAR(electro, combo_safeammocheck)) // true if you can fire at least one secondary blob AND one primary shot after it, otherwise false.
{
ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR_SEC(electro, ammo) + WEP_CVAR_PRI(electro, ammo);
- ammo_amount += actor.(weapon_load[WEP_ELECTRO.m_id]) >= WEP_CVAR_SEC(electro, ammo) + WEP_CVAR_PRI(electro, ammo);
+ ammo_amount += actor.(weaponentity).(weapon_load[WEP_ELECTRO.m_id]) >= WEP_CVAR_SEC(electro, ammo) + WEP_CVAR_PRI(electro, ammo);
}
else
{
ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR_SEC(electro, ammo);
- ammo_amount += actor.(weapon_load[WEP_ELECTRO.m_id]) >= WEP_CVAR_SEC(electro, ammo);
+ ammo_amount += actor.(weaponentity).(weapon_load[WEP_ELECTRO.m_id]) >= WEP_CVAR_SEC(electro, ammo);
}
return ammo_amount;
}
METHOD(Electro, wr_resetplayer, void(entity thiswep, entity actor))
{
- actor.electro_secondarytime = time;
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ actor.(weaponentity).electro_secondarytime = time;
+ }
}
METHOD(Electro, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
{
#ifdef SVQC
.float bot_primary_fireballmooth; // whatever a mooth is
.vector fireball_impactvec;
-.float fireball_primarytime[MAX_WEAPONSLOTS];
+.float fireball_primarytime;
#endif
#endif
#ifdef IMPLEMENTATION
vector f_diff;
float c;
- c = actor.bulletcounter % 4;
+ c = actor.(weaponentity).bulletcounter % 4;
switch(c)
{
case 0:
MUTATOR_CALLHOOK(EditProjectile, actor, proj);
}
-METHOD(Fireball, wr_aim, void(entity thiswep, entity actor))
+METHOD(Fireball, wr_aim, void(entity thiswep, entity actor, .entity weaponentity))
{
PHYS_INPUT_BUTTON_ATCK(actor) = false;
PHYS_INPUT_BUTTON_ATCK2(actor) = false;
if(actor.bot_primary_fireballmooth == 0)
{
- if(bot_aim(actor, WEP_CVAR_PRI(fireball, speed), 0, WEP_CVAR_PRI(fireball, lifetime), false))
+ if(bot_aim(actor, weaponentity, WEP_CVAR_PRI(fireball, speed), 0, WEP_CVAR_PRI(fireball, lifetime), false))
{
PHYS_INPUT_BUTTON_ATCK(actor) = true;
if(random() < 0.02) actor.bot_primary_fireballmooth = 0;
}
else
{
- if(bot_aim(actor, WEP_CVAR_SEC(fireball, speed), WEP_CVAR_SEC(fireball, speed_up), WEP_CVAR_SEC(fireball, lifetime), true))
+ if(bot_aim(actor, weaponentity, WEP_CVAR_SEC(fireball, speed), WEP_CVAR_SEC(fireball, speed_up), WEP_CVAR_SEC(fireball, lifetime), true))
{
PHYS_INPUT_BUTTON_ATCK2(actor) = true;
if(random() < 0.01) actor.bot_primary_fireballmooth = 1;
{
if(fire & 1)
{
- int slot = weaponslot(weaponentity);
- if(time >= actor.fireball_primarytime[slot])
+ if(time >= actor.(weaponentity).fireball_primarytime)
if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(fireball, refire)))
{
W_Fireball_Attack1_Frame0(thiswep, actor, weaponentity, fire);
- actor.fireball_primarytime[slot] = time + WEP_CVAR_PRI(fireball, refire2) * W_WeaponRateFactor(actor);
+ actor.(weaponentity).fireball_primarytime = time + WEP_CVAR_PRI(fireball, refire2) * W_WeaponRateFactor(actor);
}
}
else if(fire & 2)
}
}
}
-METHOD(Fireball, wr_setup, void(entity thiswep, entity actor))
-{
- actor.ammo_field = ammo_none;
-}
-METHOD(Fireball, wr_checkammo1, bool(entity thiswep, entity actor))
+METHOD(Fireball, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity))
{
return true; // infinite ammo
}
-METHOD(Fireball, wr_checkammo2, bool(entity thiswep, entity actor))
+METHOD(Fireball, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity))
{
return true; // fireball has infinite ammo
}
METHOD(Fireball, wr_resetplayer, void(entity thiswep, entity actor))
{
for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
- actor.fireball_primarytime[slot] = time;
+ {
+ .entity weaponentity = weaponentities[slot];
+ actor.(weaponentity).fireball_primarytime = time;
+ }
}
METHOD(Fireball, wr_suicidemessage, Notification(entity thiswep))
{
{
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));
{
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));
vector s;
vector forward, right, up;
- if(!actor.hagar_load)
+ if(!actor.(weaponentity).hagar_load)
return;
weapon_prepareattack_do(actor, weaponentity, true, WEP_CVAR_SEC(hagar, refire));
right = v_right;
up = v_up;
- shots = actor.hagar_load;
+ shots = actor.(weaponentity).hagar_load;
missile = NULL;
for(counter = 0; counter < shots; ++counter)
{
}
weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(hagar, load_animtime), w_ready);
- actor.hagar_loadstep = time + WEP_CVAR_SEC(hagar, refire) * W_WeaponRateFactor(actor);
- actor.hagar_load = 0;
+ actor.(weaponentity).hagar_loadstep = time + WEP_CVAR_SEC(hagar, refire) * W_WeaponRateFactor(actor);
+ actor.(weaponentity).hagar_load = 0;
+
+ if(weaponslot(weaponentity) == 0)
+ actor.hagar_load = 0;
}
void W_Hagar_Attack2_Load(Weapon thiswep, entity actor, .entity weaponentity)
if(time < game_starttime)
return;
- bool loaded = actor.hagar_load >= WEP_CVAR_SEC(hagar, load_max);
+ bool loaded = actor.(weaponentity).hagar_load >= WEP_CVAR_SEC(hagar, load_max);
// this is different than WR_CHECKAMMO when it comes to reloading
bool enough_ammo;
if(actor.items & IT_UNLIMITED_WEAPON_AMMO)
enough_ammo = true;
else if(autocvar_g_balance_hagar_reload_ammo)
- enough_ammo = actor.(weapon_load[WEP_HAGAR.m_id]) >= WEP_CVAR_SEC(hagar, ammo);
+ enough_ammo = actor.(weaponentity).(weapon_load[WEP_HAGAR.m_id]) >= WEP_CVAR_SEC(hagar, ammo);
else
enough_ammo = actor.(thiswep.ammo_field) >= WEP_CVAR_SEC(hagar, ammo);
{
if(PHYS_INPUT_BUTTON_ATCK(actor) && WEP_CVAR_SEC(hagar, load_abort))
{
- if(actor.hagar_load)
+ if(actor.(weaponentity).hagar_load)
{
// 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
- actor.hagar_load = 0;
+ W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(hagar, ammo) * actor.(weaponentity).hagar_load * -1, weaponentity); // give back ammo
+ actor.(weaponentity).hagar_load = 0;
+ if(weaponslot(weaponentity) == 0)
+ actor.hagar_load = 0;
sound(actor, CH_WEAPON_A, SND_HAGAR_BEEP, VOL_BASE, ATTN_NORM);
// pause until we can load rockets again, once we re-press the alt fire button
- actor.hagar_loadstep = time + WEP_CVAR_SEC(hagar, load_speed) * W_WeaponRateFactor(actor);
+ actor.(weaponentity).hagar_loadstep = time + WEP_CVAR_SEC(hagar, load_speed) * W_WeaponRateFactor(actor);
// require letting go of the alt fire button before we can load again
- actor.hagar_loadblock = true;
+ actor.(weaponentity).hagar_loadblock = true;
}
}
else
// check if we can attempt to load another rocket
if(!stopped)
{
- if(!actor.hagar_loadblock && actor.hagar_loadstep < time)
+ if(!actor.(weaponentity).hagar_loadblock && actor.(weaponentity).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;
+ actor.(weaponentity).hagar_load += 1;
sound(actor, CH_WEAPON_B, SND_HAGAR_LOAD, VOL_BASE * 0.8, ATTN_NORM); // sound is too loud according to most
- if(actor.hagar_load >= WEP_CVAR_SEC(hagar, load_max))
+ if(actor.(weaponentity).hagar_load >= WEP_CVAR_SEC(hagar, load_max))
stopped = true;
else
- actor.hagar_loadstep = time + WEP_CVAR_SEC(hagar, load_speed) * W_WeaponRateFactor(actor);
+ actor.(weaponentity).hagar_loadstep = time + WEP_CVAR_SEC(hagar, load_speed) * W_WeaponRateFactor(actor);
}
}
- if(stopped && !actor.hagar_loadbeep && actor.hagar_load) // prevents the beep from playing each frame
+ if(stopped && !actor.(weaponentity).hagar_loadbeep && actor.(weaponentity).hagar_load) // prevents the beep from playing each frame
{
// if this is the last rocket we can load, play a beep sound to notify the player
sound(actor, CH_WEAPON_A, SND_HAGAR_BEEP, VOL_BASE, ATTN_NORM);
- actor.hagar_loadbeep = true;
- actor.hagar_loadstep = time + WEP_CVAR_SEC(hagar, load_hold) * W_WeaponRateFactor(actor);
+ actor.(weaponentity).hagar_loadbeep = true;
+ actor.(weaponentity).hagar_loadstep = time + WEP_CVAR_SEC(hagar, load_hold) * W_WeaponRateFactor(actor);
}
}
}
- else if(actor.hagar_loadblock)
+ else if(actor.(weaponentity).hagar_loadblock)
{
// the alt fire button has been released, so re-enable loading if blocked
- actor.hagar_loadblock = false;
+ actor.(weaponentity).hagar_loadblock = false;
}
- if(actor.hagar_load)
+ if(actor.(weaponentity).hagar_load)
{
// play warning sound if we're about to release
- if(stopped && actor.hagar_loadstep - 0.5 < time && WEP_CVAR_SEC(hagar, load_hold) >= 0)
+ if(stopped && actor.(weaponentity).hagar_loadstep - 0.5 < time && WEP_CVAR_SEC(hagar, load_hold) >= 0)
{
- if(!actor.hagar_warning) // prevents the beep from playing each frame
+ if(!actor.(weaponentity).hagar_warning) // prevents the beep from playing each frame
{
// we're about to automatically release after holding time, play a beep sound to notify the player
sound(actor, CH_WEAPON_A, SND_HAGAR_BEEP, VOL_BASE, ATTN_NORM);
- actor.hagar_warning = true;
+ actor.(weaponentity).hagar_warning = true;
}
}
// release if player let go of button or if they've held it in too long
- if(!PHYS_INPUT_BUTTON_ATCK2(actor) || (stopped && actor.hagar_loadstep < time && WEP_CVAR_SEC(hagar, load_hold) >= 0))
+ if(!PHYS_INPUT_BUTTON_ATCK2(actor) || (stopped && actor.(weaponentity).hagar_loadstep < time && WEP_CVAR_SEC(hagar, load_hold) >= 0))
{
actor.(weaponentity).state = WS_READY;
W_Hagar_Attack2_Load_Release(actor, weaponentity);
}
else
{
- actor.hagar_loadbeep = false;
- actor.hagar_warning = false;
+ actor.(weaponentity).hagar_loadbeep = false;
+ actor.(weaponentity).hagar_warning = false;
// we aren't checking ammo during an attack, so we must do it here
- if(!(thiswep.wr_checkammo1(thiswep, actor) + thiswep.wr_checkammo2(thiswep, actor)))
+ if(!(thiswep.wr_checkammo1(thiswep, actor, weaponentity) + thiswep.wr_checkammo2(thiswep, actor, weaponentity)))
if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
{
// note: this doesn't force the switch
- W_SwitchToOtherWeapon(actor);
+ W_SwitchToOtherWeapon(actor, weaponentity);
return;
}
}
void W_Hagar_Attack_Auto(Weapon thiswep, entity actor, .entity weaponentity, int fire)
{
- if(!(fire & 1) || actor.hagar_load || actor.hagar_loadblock)
+ if(!(fire & 1) || actor.(weaponentity).hagar_load || actor.(weaponentity).hagar_loadblock)
{
w_ready(thiswep, actor, weaponentity, fire);
return;
}
- if(!thiswep.wr_checkammo1(thiswep, actor))
+ if(!thiswep.wr_checkammo1(thiswep, actor, weaponentity))
if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
{
- W_SwitchWeapon_Force(actor, w_getbestweapon(actor));
+ W_SwitchWeapon_Force(actor, w_getbestweapon(actor, weaponentity), weaponentity);
w_ready(thiswep, actor, weaponentity, fire);
return;
}
weapon_thinkf(actor, weaponentity, theframe, WEP_CVAR_PRI(hagar, refire), W_Hagar_Attack_Auto);
}
-METHOD(Hagar, wr_aim, void(entity thiswep, entity actor))
+METHOD(Hagar, wr_aim, void(entity thiswep, entity actor, .entity weaponentity))
{
if(random()>0.15)
- PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, WEP_CVAR_PRI(hagar, speed), 0, WEP_CVAR_PRI(hagar, lifetime), false);
+ PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, WEP_CVAR_PRI(hagar, speed), 0, WEP_CVAR_PRI(hagar, lifetime), false);
else // not using secondary_speed since these are only 15% and should cause some ricochets without re-aiming
- PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, WEP_CVAR_PRI(hagar, speed), 0, WEP_CVAR_PRI(hagar, lifetime), false);
+ PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, weaponentity, WEP_CVAR_PRI(hagar, speed), 0, WEP_CVAR_PRI(hagar, lifetime), false);
}
METHOD(Hagar, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
{
float loadable_secondary;
loadable_secondary = (WEP_CVAR_SEC(hagar, load) && WEP_CVAR(hagar, secondary));
+ if(weaponslot(weaponentity) == 0)
+ actor.hagar_load = actor.(weaponentity).hagar_load;
if(loadable_secondary)
W_Hagar_Attack2_Load(thiswep, actor, weaponentity); // must always run each frame
- if(autocvar_g_balance_hagar_reload_ammo && actor.clip_load < min(WEP_CVAR_PRI(hagar, ammo), WEP_CVAR_SEC(hagar, ammo))) { // forced reload
+ if(autocvar_g_balance_hagar_reload_ammo && actor.(weaponentity).clip_load < min(WEP_CVAR_PRI(hagar, ammo), WEP_CVAR_SEC(hagar, ammo))) { // forced reload
thiswep.wr_reload(thiswep, actor, weaponentity);
}
- else if((fire & 1) && !actor.hagar_load && !actor.hagar_loadblock) // not while secondary is loaded or awaiting reset
+ else if((fire & 1) && !actor.(weaponentity).hagar_load && !actor.(weaponentity).hagar_loadblock) // not while secondary is loaded or awaiting reset
{
if(weapon_prepareattack(thiswep, actor, weaponentity, false, 0))
W_Hagar_Attack_Auto(thiswep, actor, weaponentity, fire);
METHOD(Hagar, wr_gonethink, void(entity thiswep, entity actor, .entity weaponentity))
{
// we lost the weapon and want to prepare switching away
- if(actor.hagar_load)
+ if(actor.(weaponentity).hagar_load)
{
actor.(weaponentity).state = WS_READY;
W_Hagar_Attack2_Load_Release(actor, weaponentity);
}
}
-METHOD(Hagar, wr_setup, void(entity thiswep, entity actor))
+METHOD(Hagar, wr_setup, void(entity thiswep, entity actor, .entity weaponentity))
{
- actor.hagar_loadblock = false;
-
- if(actor.hagar_load)
+ actor.hagar_load = 0;
+ actor.(weaponentity).hagar_loadblock = false;
+ if(actor.(weaponentity).hagar_load)
{
- W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(hagar, ammo) * actor.hagar_load * -1); // give back ammo if necessary
- actor.hagar_load = 0;
+ W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(hagar, ammo) * actor.(weaponentity).hagar_load * -1, weaponentity); // give back ammo if necessary
+ actor.(weaponentity).hagar_load = 0;
}
}
-METHOD(Hagar, wr_checkammo1, bool(entity thiswep, entity actor))
+METHOD(Hagar, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity))
{
float ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR_PRI(hagar, ammo);
- ammo_amount += actor.(weapon_load[WEP_HAGAR.m_id]) >= WEP_CVAR_PRI(hagar, ammo);
+ ammo_amount += actor.(weaponentity).(weapon_load[WEP_HAGAR.m_id]) >= WEP_CVAR_PRI(hagar, ammo);
return ammo_amount;
}
-METHOD(Hagar, wr_checkammo2, bool(entity thiswep, entity actor))
+METHOD(Hagar, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity))
{
float ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR_SEC(hagar, ammo);
- ammo_amount += actor.(weapon_load[WEP_HAGAR.m_id]) >= WEP_CVAR_SEC(hagar, ammo);
+ ammo_amount += actor.(weaponentity).(weapon_load[WEP_HAGAR.m_id]) >= WEP_CVAR_SEC(hagar, ammo);
return ammo_amount;
}
METHOD(Hagar, wr_resetplayer, void(entity thiswep, entity actor))
{
actor.hagar_load = 0;
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ actor.(weaponentity).hagar_load = 0;
+ }
}
METHOD(Hagar, wr_playerdeath, void(entity thiswep, entity actor, .entity weaponentity))
{
// if we have any rockets loaded when we die, release them
- if(actor.hagar_load && WEP_CVAR_SEC(hagar, load_releasedeath))
+ if(actor.(weaponentity).hagar_load && WEP_CVAR_SEC(hagar, load_releasedeath))
W_Hagar_Attack2_Load_Release(actor, weaponentity);
}
METHOD(Hagar, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
{
- if(!actor.hagar_load) // require releasing loaded rockets first
+ if(!actor.(weaponentity).hagar_load) // require releasing loaded rockets first
W_Reload(actor, weaponentity, min(WEP_CVAR_PRI(hagar, ammo), WEP_CVAR_SEC(hagar, ammo)), SND_RELOAD);
}
METHOD(Hagar, wr_suicidemessage, Notification(entity thiswep))
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 = WEP_CVAR_PRI(hlac, spread_min) + (WEP_CVAR_PRI(hlac, spread_add) * actor.(weaponentity).misc_bulletcounter);
spread = min(spread,WEP_CVAR_PRI(hlac, spread_max));
if(actor.crouch)
spread = spread * WEP_CVAR_PRI(hlac, spread_crouchmod);
// 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;
if(PHYS_INPUT_BUTTON_ATCK(actor))
{
- if(!thiswep.wr_checkammo1(thiswep, actor))
+ if(!thiswep.wr_checkammo1(thiswep, actor, weaponentity))
if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
{
- W_SwitchWeapon_Force(actor, w_getbestweapon(actor));
+ W_SwitchWeapon_Force(actor, w_getbestweapon(actor, weaponentity), weaponentity);
w_ready(thiswep, actor, weaponentity, fire);
return;
}
int slot = weaponslot(weaponentity);
ATTACK_FINISHED(actor, slot) = time + WEP_CVAR_PRI(hlac, refire) * W_WeaponRateFactor(actor);
W_HLAC_Attack(WEP_HLAC, actor, weaponentity);
- actor.misc_bulletcounter = actor.misc_bulletcounter + 1;
+ actor.(weaponentity).misc_bulletcounter = actor.(weaponentity).misc_bulletcounter + 1;
weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(hlac, refire), W_HLAC_Attack_Frame);
}
else
{
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);
}
}
-METHOD(HLAC, wr_aim, void(entity thiswep, entity actor))
+METHOD(HLAC, wr_aim, void(entity thiswep, entity actor, .entity weaponentity))
{
- PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, WEP_CVAR_PRI(hlac, speed), 0, WEP_CVAR_PRI(hlac, lifetime), false);
+ PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, WEP_CVAR_PRI(hlac, speed), 0, WEP_CVAR_PRI(hlac, lifetime), false);
}
METHOD(HLAC, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
{
- if(autocvar_g_balance_hlac_reload_ammo && actor.clip_load < min(WEP_CVAR_PRI(hlac, ammo), WEP_CVAR_SEC(hlac, ammo))) { // forced reload
+ if(autocvar_g_balance_hlac_reload_ammo && actor.(weaponentity).clip_load < min(WEP_CVAR_PRI(hlac, ammo), WEP_CVAR_SEC(hlac, ammo))) { // forced reload
thiswep.wr_reload(thiswep, actor, weaponentity);
} else if(fire & 1)
{
if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(hlac, refire)))
{
- actor.misc_bulletcounter = 0;
+ actor.(weaponentity).misc_bulletcounter = 0;
W_HLAC_Attack(thiswep, actor, weaponentity);
weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(hlac, refire), W_HLAC_Attack_Frame);
}
}
}
}
-METHOD(HLAC, wr_checkammo1, bool(entity thiswep, entity actor))
+METHOD(HLAC, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity))
{
float ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR_PRI(hlac, ammo);
- ammo_amount += actor.(weapon_load[WEP_HLAC.m_id]) >= WEP_CVAR_PRI(hlac, ammo);
+ ammo_amount += actor.(weaponentity).(weapon_load[WEP_HLAC.m_id]) >= WEP_CVAR_PRI(hlac, ammo);
return ammo_amount;
}
-METHOD(HLAC, wr_checkammo2, bool(entity thiswep, entity actor))
+METHOD(HLAC, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity))
{
float ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR_SEC(hlac, ammo);
- ammo_amount += actor.(weapon_load[WEP_HLAC.m_id]) >= WEP_CVAR_SEC(hlac, ammo);
+ ammo_amount += actor.(weaponentity).(weapon_load[WEP_HLAC.m_id]) >= WEP_CVAR_SEC(hlac, ammo);
return ammo_amount;
}
METHOD(HLAC, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
METHOD(Hook, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
{
if (fire & 1) {
- if(!actor.hook)
- if(!(actor.hook_state & HOOK_WAITING_FOR_RELEASE))
- if(time > actor.hook_refire)
+ if(!actor.(weaponentity).hook)
+ if(!(actor.(weaponentity).hook_state & HOOK_WAITING_FOR_RELEASE))
+ if(time > actor.(weaponentity).hook_refire)
if(weapon_prepareattack(thiswep, actor, weaponentity, false, -1))
{
- W_DecreaseAmmo(thiswep, actor, thiswep.ammo_factor * WEP_CVAR_PRI(hook, ammo));
- actor.hook_state |= HOOK_FIRING;
- actor.hook_state |= HOOK_WAITING_FOR_RELEASE;
+ W_DecreaseAmmo(thiswep, actor, thiswep.ammo_factor * WEP_CVAR_PRI(hook, ammo), weaponentity);
+ actor.(weaponentity).hook_state |= HOOK_FIRING;
+ actor.(weaponentity).hook_state |= HOOK_WAITING_FOR_RELEASE;
weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(hook, animtime), w_ready);
}
} else {
- actor.hook_state |= HOOK_REMOVING;
- actor.hook_state &= ~HOOK_WAITING_FOR_RELEASE;
+ actor.(weaponentity).hook_state |= HOOK_REMOVING;
+ actor.(weaponentity).hook_state &= ~HOOK_WAITING_FOR_RELEASE;
}
if(fire & 2)
}
}
- if(actor.hook)
+ if(actor.(weaponentity).hook)
{
// if hooked, no bombs, and increase the timer
- actor.hook_refire = max(actor.hook_refire, time + WEP_CVAR_PRI(hook, refire) * W_WeaponRateFactor(actor));
+ actor.(weaponentity).hook_refire = max(actor.(weaponentity).hook_refire, time + WEP_CVAR_PRI(hook, refire) * W_WeaponRateFactor(actor));
// hook also inhibits health regeneration, but only for 1 second
if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
actor.pauseregen_finished = max(actor.pauseregen_finished, time + autocvar_g_balance_pause_fuel_regen);
}
- if(actor.hook && actor.hook.state == 1)
+ if(actor.(weaponentity).hook && actor.(weaponentity).hook.state == 1)
{
float hooked_time_max = WEP_CVAR_PRI(hook, hooked_time_max);
if(hooked_time_max > 0)
{
- if( time > actor.hook_time_hooked + hooked_time_max )
- actor.hook_state |= HOOK_REMOVING;
+ if( time > actor.(weaponentity).hook_time_hooked + hooked_time_max )
+ actor.(weaponentity).hook_state |= HOOK_REMOVING;
}
float hooked_fuel = thiswep.ammo_factor * WEP_CVAR_PRI(hook, hooked_ammo);
if(hooked_fuel > 0)
{
- if( time > actor.hook_time_fueldecrease )
+ if( time > actor.(weaponentity).hook_time_fueldecrease )
{
if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
{
- if( actor.ammo_fuel >= (time - actor.hook_time_fueldecrease) * hooked_fuel )
+ if( actor.ammo_fuel >= (time - actor.(weaponentity).hook_time_fueldecrease) * hooked_fuel )
{
- W_DecreaseAmmo(thiswep, actor, (time - actor.hook_time_fueldecrease) * hooked_fuel);
- actor.hook_time_fueldecrease = time;
+ W_DecreaseAmmo(thiswep, actor, (time - actor.(weaponentity).hook_time_fueldecrease) * hooked_fuel, weaponentity);
+ actor.(weaponentity).hook_time_fueldecrease = time;
// decrease next frame again
}
else
{
actor.ammo_fuel = 0;
- actor.hook_state |= HOOK_REMOVING;
- W_SwitchWeapon_Force(actor, w_getbestweapon(actor));
+ actor.(weaponentity).hook_state |= HOOK_REMOVING;
+ W_SwitchWeapon_Force(actor, w_getbestweapon(actor, weaponentity), weaponentity);
}
}
}
}
else
{
- actor.hook_time_hooked = time;
- actor.hook_time_fueldecrease = time + WEP_CVAR_PRI(hook, hooked_time_free);
+ actor.(weaponentity).hook_time_hooked = time;
+ actor.(weaponentity).hook_time_fueldecrease = time + WEP_CVAR_PRI(hook, hooked_time_free);
}
- actor.hook_state = BITSET(actor.hook_state, HOOK_PULLING, (!PHYS_INPUT_BUTTON_CROUCH(actor) || !autocvar_g_balance_grapplehook_crouchslide));
+ actor.(weaponentity).hook_state = BITSET(actor.(weaponentity).hook_state, HOOK_PULLING, (!PHYS_INPUT_BUTTON_CROUCH(actor) || !autocvar_g_balance_grapplehook_crouchslide));
- if (actor.hook_state & HOOK_FIRING)
+ if (actor.(weaponentity).hook_state & HOOK_FIRING)
{
- if (actor.hook)
- RemoveGrapplingHook(actor);
- FireGrapplingHook(actor);
- actor.hook_state &= ~HOOK_FIRING;
- actor.hook_refire = max(actor.hook_refire, time + autocvar_g_balance_grapplehook_refire * W_WeaponRateFactor(actor));
+ if (actor.(weaponentity).hook)
+ RemoveHook(actor.(weaponentity).hook);
+ FireGrapplingHook(actor, weaponentity);
+ actor.(weaponentity).hook_state &= ~HOOK_FIRING;
+ actor.(weaponentity).hook_refire = max(actor.(weaponentity).hook_refire, time + autocvar_g_balance_grapplehook_refire * W_WeaponRateFactor(actor));
}
- else if (actor.hook_state & HOOK_REMOVING)
+ else if (actor.(weaponentity).hook_state & HOOK_REMOVING)
{
- if (actor.hook)
- RemoveGrapplingHook(actor);
- actor.hook_state &= ~HOOK_REMOVING;
+ if (actor.(weaponentity).hook)
+ RemoveHook(actor.(weaponentity).hook);
+ actor.(weaponentity).hook_state &= ~HOOK_REMOVING;
}
}
-METHOD(Hook, wr_setup, void(entity thiswep, entity actor))
+METHOD(Hook, wr_setup, void(entity thiswep, entity actor, .entity weaponentity))
{
- actor.hook_state &= ~HOOK_WAITING_FOR_RELEASE;
+ actor.(weaponentity).hook_state &= ~HOOK_WAITING_FOR_RELEASE;
}
-METHOD(Hook, wr_checkammo1, bool(Hook thiswep, entity actor))
+METHOD(Hook, wr_checkammo1, bool(Hook thiswep, entity actor, .entity weaponentity))
{
if (!thiswep.ammo_factor) return true;
- if(actor.hook)
- return actor.ammo_fuel > 0;
- else
- return actor.ammo_fuel >= WEP_CVAR_PRI(hook, ammo);
+
+ if(actor.(weaponentity).hook)
+ return actor.ammo_fuel > 0;
+
+ return actor.ammo_fuel >= WEP_CVAR_PRI(hook, ammo);
}
-METHOD(Hook, wr_checkammo2, bool(Hook thiswep, entity actor))
+METHOD(Hook, wr_checkammo2, bool(Hook thiswep, entity actor, .entity weaponentity))
{
// infinite ammo for now
return true; // actor.ammo_cells >= WEP_CVAR_SEC(hook, ammo); // WEAPONTODO: see above
}
METHOD(Hook, wr_resetplayer, void(entity thiswep, entity actor))
{
- RemoveGrapplingHook(actor);
- actor.hook_time = 0;
- actor.hook_refire = time;
+ RemoveGrapplingHooks(actor);
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ actor.(weaponentity).hook_time = 0;
+ actor.(weaponentity).hook_refire = time;
+ }
}
METHOD(Hook, wr_killmessage, Notification(entity thiswep))
{
InterpolateOrigin_Do(this);
- int s = W_GetGunAlignment(NULL);
+ int s = W_GunAlign(viewmodels[this.cnt], STAT(GUNALIGN)) - 1;
switch(this.HookType)
{
if(sf & 1)
{
int myowner = ReadByte();
+ int slot = ReadByte();
this.owner = playerslots[myowner - 1];
this.sv_entnum = myowner;
- if(csqcplayer && myowner == player_localentnum)
- csqcplayer.hook = this;
+ if(myowner == player_localentnum)
+ viewmodels[slot].hook = this;
+ this.cnt = slot;
switch(this.HookType)
{
default:
void W_MachineGun_Attack(Weapon thiswep, int deathtype, entity actor, .entity weaponentity)
{
- W_SetupShot(actor, weaponentity, true, 0, SND_UZI_FIRE, CH_WEAPON_A, ((actor.misc_bulletcounter == 1) ? WEP_CVAR(machinegun, first_damage) : WEP_CVAR(machinegun, sustained_damage)));
+ W_SetupShot(actor, weaponentity, true, 0, SND_UZI_FIRE, CH_WEAPON_A, ((actor.(weaponentity).misc_bulletcounter == 1) ? WEP_CVAR(machinegun, first_damage) : WEP_CVAR(machinegun, sustained_damage)));
if(!autocvar_g_norecoil)
{
actor.punchangle_x = random() - 0.5;
// this attack_finished just enforces a cooldown at the end of a burst
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);
+ if(actor.(weaponentity).misc_bulletcounter == 1)
+ 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);
SpawnCasing(((random() * 50 + 50) * v_right) - (v_forward * (random() * 25 + 25)) - ((random() * 5 - 70) * v_up), 2, vectoangles(v_forward),'0 250 0', 100, 3, actor, weaponentity);
}
- if(actor.misc_bulletcounter == 1)
- W_DecreaseAmmo(thiswep, actor, WEP_CVAR(machinegun, first_ammo));
+ if(actor.(weaponentity).misc_bulletcounter == 1)
+ 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;
}
if(PHYS_INPUT_BUTTON_ATCK(actor))
{
- if(!thiswep.wr_checkammo2(thiswep, actor))
+ if(!thiswep.wr_checkammo2(thiswep, actor, weaponentity))
if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
{
- W_SwitchWeapon_Force(actor, w_getbestweapon(actor));
+ W_SwitchWeapon_Force(actor, w_getbestweapon(actor, weaponentity), weaponentity);
w_ready(thiswep, actor, weaponentity, fire);
return;
}
- actor.misc_bulletcounter = actor.misc_bulletcounter + 1;
+ actor.(weaponentity).misc_bulletcounter = actor.(weaponentity).misc_bulletcounter + 1;
W_MachineGun_Attack(WEP_MACHINEGUN, WEP_MACHINEGUN.m_id, actor, weaponentity);
weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(machinegun, sustained_refire), W_MachineGun_Attack_Frame);
}
return;
}
- if(!thiswep.wr_checkammo1(thiswep, actor))
+ if(!thiswep.wr_checkammo1(thiswep, actor, weaponentity))
if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
{
- W_SwitchWeapon_Force(actor, w_getbestweapon(actor));
+ W_SwitchWeapon_Force(actor, w_getbestweapon(actor, weaponentity), 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)
actor.punchangle_y = random() - 0.5;
}
- 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);
+ machinegun_spread = bound(WEP_CVAR(machinegun, spread_min), WEP_CVAR(machinegun, spread_min) + (WEP_CVAR(machinegun, spread_add) * actor.(weaponentity).misc_bulletcounter), WEP_CVAR(machinegun, spread_max));
+ 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;
+ actor.(weaponentity).misc_bulletcounter = actor.(weaponentity).misc_bulletcounter + 1;
Send_Effect(EFFECT_MACHINEGUN_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
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);
SpawnCasing(((random() * 50 + 50) * v_right) - (v_forward * (random() * 25 + 25)) - ((random() * 5 - 70) * v_up), 2, vectoangles(v_forward),'0 250 0', 100, 3, actor, weaponentity);
}
- actor.misc_bulletcounter = actor.misc_bulletcounter + 1;
- if(actor.misc_bulletcounter == 0)
+ actor.(weaponentity).misc_bulletcounter = actor.(weaponentity).misc_bulletcounter + 1;
+ if(actor.(weaponentity).misc_bulletcounter == 0)
{
int slot = weaponslot(weaponentity);
ATTACK_FINISHED(actor, slot) = time + WEP_CVAR(machinegun, burst_refire2) * W_WeaponRateFactor(actor);
}
-METHOD(MachineGun, wr_aim, void(entity thiswep, entity actor))
+METHOD(MachineGun, wr_aim, void(entity thiswep, entity actor, .entity weaponentity))
{
if(vdist(actor.origin - actor.enemy.origin, <, 3000 - bound(0, skill, 10) * 200))
- PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, 1000000, 0, 0.001, false);
+ PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, 1000000, 0, 0.001, false);
else
- PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, 1000000, 0, 0.001, false);
+ PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, weaponentity, 1000000, 0, 0.001, false);
}
METHOD(MachineGun, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
{
- if(WEP_CVAR(machinegun, reload_ammo) && actor.clip_load < min(max(WEP_CVAR(machinegun, sustained_ammo), WEP_CVAR(machinegun, first_ammo)), WEP_CVAR(machinegun, burst_ammo))) { // forced reload
+ if(WEP_CVAR(machinegun, reload_ammo) && actor.(weaponentity).clip_load < min(max(WEP_CVAR(machinegun, sustained_ammo), WEP_CVAR(machinegun, first_ammo)), WEP_CVAR(machinegun, burst_ammo))) { // forced reload
thiswep.wr_reload(thiswep, actor, weaponentity);
} else
if(WEP_CVAR(machinegun, mode) == 1)
if(fire & 1)
if(weapon_prepareattack(thiswep, actor, weaponentity, false, 0))
{
- actor.misc_bulletcounter = 0;
+ actor.(weaponentity).misc_bulletcounter = 0;
W_MachineGun_Attack_Auto(thiswep, actor, weaponentity, fire);
}
if(fire & 2)
if(weapon_prepareattack(thiswep, actor, weaponentity, true, 0))
{
- if(!thiswep.wr_checkammo2(thiswep, actor))
+ if(!thiswep.wr_checkammo2(thiswep, actor, weaponentity))
if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
{
- W_SwitchWeapon_Force(actor, w_getbestweapon(actor));
+ W_SwitchWeapon_Force(actor, w_getbestweapon(actor, weaponentity), 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;
+ actor.(weaponentity).misc_bulletcounter = WEP_CVAR(machinegun, burst) * -1;
W_MachineGun_Attack_Burst(thiswep, actor, weaponentity, fire);
}
}
if(fire & 1)
if(weapon_prepareattack(thiswep, actor, weaponentity, false, 0))
{
- actor.misc_bulletcounter = 1;
+ actor.(weaponentity).misc_bulletcounter = 1;
W_MachineGun_Attack(WEP_MACHINEGUN, WEP_MACHINEGUN.m_id, actor, weaponentity); // sets attack_finished
weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(machinegun, sustained_refire), W_MachineGun_Attack_Frame);
}
if((fire & 2) && WEP_CVAR(machinegun, first))
if(weapon_prepareattack(thiswep, actor, weaponentity, true, 0))
{
- actor.misc_bulletcounter = 1;
+ actor.(weaponentity).misc_bulletcounter = 1;
W_MachineGun_Attack(WEP_MACHINEGUN, WEP_MACHINEGUN.m_id | HITTYPE_SECONDARY, actor, weaponentity); // sets attack_finished
weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR(machinegun, first_refire), w_ready);
}
}
}
-METHOD(MachineGun, wr_checkammo1, bool(entity thiswep, entity actor))
+METHOD(MachineGun, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity))
{
float ammo_amount;
if(WEP_CVAR(machinegun, mode) == 1)
if(WEP_CVAR(machinegun, reload_ammo))
{
if(WEP_CVAR(machinegun, mode) == 1)
- ammo_amount += actor.(weapon_load[WEP_MACHINEGUN.m_id]) >= WEP_CVAR(machinegun, sustained_ammo);
+ ammo_amount += actor.(weaponentity).(weapon_load[WEP_MACHINEGUN.m_id]) >= WEP_CVAR(machinegun, sustained_ammo);
else
- ammo_amount += actor.(weapon_load[WEP_MACHINEGUN.m_id]) >= WEP_CVAR(machinegun, first_ammo);
+ ammo_amount += actor.(weaponentity).(weapon_load[WEP_MACHINEGUN.m_id]) >= WEP_CVAR(machinegun, first_ammo);
}
return ammo_amount;
}
-METHOD(MachineGun, wr_checkammo2, bool(entity thiswep, entity actor))
+METHOD(MachineGun, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity))
{
float ammo_amount;
if(WEP_CVAR(machinegun, mode) == 1)
if(WEP_CVAR(machinegun, reload_ammo))
{
if(WEP_CVAR(machinegun, mode) == 1)
- ammo_amount += actor.(weapon_load[WEP_MACHINEGUN.m_id]) >= WEP_CVAR(machinegun, burst_ammo);
+ ammo_amount += actor.(weaponentity).(weapon_load[WEP_MACHINEGUN.m_id]) >= WEP_CVAR(machinegun, burst_ammo);
else
- ammo_amount += actor.(weapon_load[WEP_MACHINEGUN.m_id]) >= WEP_CVAR(machinegun, first_ammo);
+ ammo_amount += actor.(weaponentity).(weapon_load[WEP_MACHINEGUN.m_id]) >= WEP_CVAR(machinegun, first_ammo);
}
return ammo_amount;
}
entity newmine = spawn();
IL_PUSH(g_mines, newmine);
+ newmine.weaponentity_fld = this.weaponentity_fld;
newmine.classname = this.classname;
newmine.bot_dodge = this.bot_dodge;
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))
+ if(!w.wr_checkammo1(w, own, weaponentity))
{
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, weaponentity);
}
}
- this.realowner.minelayer_mines -= 1;
+ this.realowner.(weaponentity).minelayer_mines -= 1;
delete(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))
+ if(!w.wr_checkammo1(w, own, weaponentity))
{
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, weaponentity);
}
}
- this.realowner.minelayer_mines -= 1;
+ this.realowner.(weaponentity).minelayer_mines -= 1;
delete(this);
}
W_MineLayer_Explode(this, NULL);
}
-int W_MineLayer_Count(entity e)
+int W_MineLayer_Count(entity e, .entity weaponentity)
{
int minecount = 0;
- IL_EACH(g_mines, it.realowner == e,
+ IL_EACH(g_mines, it.realowner == e && it.weaponentity_fld == weaponentity,
{
minecount += 1;
});
}
// 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);
if(WarpZone_Projectile_Touch(this, toucher))
{
if(wasfreed(this))
- this.realowner.minelayer_mines -= 1;
+ {
+ .entity weaponentity = this.weaponentity_fld;
+ this.realowner.(weaponentity).minelayer_mines -= 1;
+ }
return;
}
- if(toucher && IS_PLAYER(toucher) && !IS_DEAD(toucher))
+ if((toucher && IS_PLAYER(toucher) && !IS_DEAD(toucher)) || toucher.owner == this.owner)
{
- // hit a player
+ // hit a player or other mine
// don't stick
}
else
// scan how many mines we placed, and return if we reached our limit
if(WEP_CVAR(minelayer, limit))
{
- if(actor.minelayer_mines >= WEP_CVAR(minelayer, limit))
+ if(actor.(weaponentity).minelayer_mines >= WEP_CVAR(minelayer, limit))
{
// the refire delay keeps this message from being spammed
Send_Notification(NOTIF_ONE, actor, MSG_MULTI, WEAPON_MINELAYER_LIMIT, WEP_CVAR(minelayer, limit));
}
}
- 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);
MUTATOR_CALLHOOK(EditProjectile, actor, mine);
- actor.minelayer_mines = W_MineLayer_Count(actor);
+ actor.(weaponentity).minelayer_mines = W_MineLayer_Count(actor, weaponentity);
}
-bool W_MineLayer_PlacedMines(entity this, bool detonate)
+bool W_MineLayer_PlacedMines(entity this, .entity weaponentity, bool detonate)
{
bool minfound = false;
- IL_EACH(g_mines, it.realowner == this,
+ IL_EACH(g_mines, it.realowner == this && it.weaponentity_fld == weaponentity,
{
if(detonate)
{
return minfound;
}
-METHOD(MineLayer, wr_aim, void(entity thiswep, entity actor))
+METHOD(MineLayer, wr_aim, void(entity thiswep, entity actor, .entity weaponentity))
{
// aim and decide to fire if appropriate
- if(actor.minelayer_mines >= WEP_CVAR(minelayer, limit))
+ if(actor.(weaponentity).minelayer_mines >= WEP_CVAR(minelayer, limit))
PHYS_INPUT_BUTTON_ATCK(actor) = false;
else
- PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, WEP_CVAR(minelayer, speed), 0, WEP_CVAR(minelayer, lifetime), false);
+ PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, WEP_CVAR(minelayer, speed), 0, WEP_CVAR(minelayer, lifetime), false);
if(skill >= 2) // skill 0 and 1 bots won't detonate mines!
{
// decide whether to detonate mines
}
METHOD(MineLayer, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
{
- if(autocvar_g_balance_minelayer_reload_ammo && actor.clip_load < WEP_CVAR(minelayer, ammo)) // forced reload
+ if(weaponslot(weaponentity) == 0)
+ actor.minelayer_mines = actor.(weaponentity).minelayer_mines;
+
+ if(autocvar_g_balance_minelayer_reload_ammo && actor.(weaponentity).clip_load < WEP_CVAR(minelayer, ammo)) // forced reload
{
// not if we're holding the minelayer without enough ammo, but can detonate existing mines
- if(!(W_MineLayer_PlacedMines(actor, false) && actor.(thiswep.ammo_field) < WEP_CVAR(minelayer, ammo))) {
+ if(!(W_MineLayer_PlacedMines(actor, weaponentity, false) && actor.(thiswep.ammo_field) < WEP_CVAR(minelayer, ammo))) {
thiswep.wr_reload(thiswep, actor, weaponentity);
}
}
if(fire & 2)
{
- if(W_MineLayer_PlacedMines(actor, true))
+ if(W_MineLayer_PlacedMines(actor, weaponentity, true))
sound(actor, CH_WEAPON_B, SND_MINE_DET, VOL_BASE, ATTN_NORM);
}
}
-METHOD(MineLayer, wr_checkammo1, bool(entity thiswep, entity actor))
+METHOD(MineLayer, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity))
{
//int slot = 0; // TODO: unhardcode
// actually do // don't switch while placing a mine
//if(ATTACK_FINISHED(actor, slot) <= time || PS(actor).m_weapon != WEP_MINE_LAYER)
//{
float ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR(minelayer, ammo);
- ammo_amount += actor.(weapon_load[WEP_MINE_LAYER.m_id]) >= WEP_CVAR(minelayer, ammo);
+ ammo_amount += actor.(weaponentity).(weapon_load[WEP_MINE_LAYER.m_id]) >= WEP_CVAR(minelayer, ammo);
return ammo_amount;
//}
//return true;
}
-METHOD(MineLayer, wr_checkammo2, bool(entity thiswep, entity actor))
+METHOD(MineLayer, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity))
{
- if(W_MineLayer_PlacedMines(actor, false))
+ if(W_MineLayer_PlacedMines(actor, weaponentity, false))
return true;
else
return false;
METHOD(MineLayer, wr_resetplayer, void(entity thiswep, entity actor))
{
actor.minelayer_mines = 0;
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ actor.(weaponentity).minelayer_mines = 0;
+ }
}
METHOD(MineLayer, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
{
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
{
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
.float bot_secondary_grenademooth;
-METHOD(Mortar, wr_aim, void(entity thiswep, entity actor))
+METHOD(Mortar, wr_aim, void(entity thiswep, entity actor, .entity weaponentity))
{
PHYS_INPUT_BUTTON_ATCK(actor) = false;
PHYS_INPUT_BUTTON_ATCK2(actor) = false;
if(actor.bot_secondary_grenademooth == 0) // WEAPONTODO: merge this into using WEP_CVAR_BOTH
{
- if(bot_aim(actor, WEP_CVAR_PRI(mortar, speed), WEP_CVAR_PRI(mortar, speed_up), WEP_CVAR_PRI(mortar, lifetime), true))
+ if(bot_aim(actor, weaponentity, WEP_CVAR_PRI(mortar, speed), WEP_CVAR_PRI(mortar, speed_up), WEP_CVAR_PRI(mortar, lifetime), true))
{
PHYS_INPUT_BUTTON_ATCK(actor) = true;
if(random() < 0.01) actor.bot_secondary_grenademooth = 1;
}
else
{
- if(bot_aim(actor, WEP_CVAR_SEC(mortar, speed), WEP_CVAR_SEC(mortar, speed_up), WEP_CVAR_SEC(mortar, lifetime), true))
+ if(bot_aim(actor, weaponentity, WEP_CVAR_SEC(mortar, speed), WEP_CVAR_SEC(mortar, speed_up), WEP_CVAR_SEC(mortar, lifetime), true))
{
PHYS_INPUT_BUTTON_ATCK2(actor) = true;
if(random() < 0.02) actor.bot_secondary_grenademooth = 0;
*/
METHOD(Mortar, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
{
- if(autocvar_g_balance_mortar_reload_ammo && actor.clip_load < min(WEP_CVAR_PRI(mortar, ammo), WEP_CVAR_SEC(mortar, ammo))) { // forced reload
+ if(autocvar_g_balance_mortar_reload_ammo && actor.(weaponentity).clip_load < min(WEP_CVAR_PRI(mortar, ammo), WEP_CVAR_SEC(mortar, ammo))) { // forced reload
thiswep.wr_reload(thiswep, actor, weaponentity);
} else if(fire & 1)
{
}
}
}
-METHOD(Mortar, wr_checkammo1, bool(entity thiswep, entity actor))
+METHOD(Mortar, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity))
{
float ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR_PRI(mortar, ammo);
- ammo_amount += actor.(weapon_load[WEP_MORTAR.m_id]) >= WEP_CVAR_PRI(mortar, ammo);
+ ammo_amount += actor.(weaponentity).(weapon_load[WEP_MORTAR.m_id]) >= WEP_CVAR_PRI(mortar, ammo);
return ammo_amount;
}
-METHOD(Mortar, wr_checkammo2, bool(entity thiswep, entity actor))
+METHOD(Mortar, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity))
{
float ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR_SEC(mortar, ammo);
- ammo_amount += actor.(weapon_load[WEP_MORTAR.m_id]) >= WEP_CVAR_SEC(mortar, ammo);
+ ammo_amount += actor.(weaponentity).(weapon_load[WEP_MORTAR.m_id]) >= WEP_CVAR_SEC(mortar, ammo);
return ammo_amount;
}
METHOD(Mortar, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
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)
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 = this.weaponentity_fld;
+ 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);
}
}
sound(this, CH_SHOTS, SND_PORTO_UNSUPPORTED, VOL_BASE, ATTEN_NORM);
delete(this);
}
- else if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SLICK || trace_dphitcontents & DPCONTENTS_PLAYERCLIP)
+ else if((trace_dphitq3surfaceflags & Q3SURFACEFLAG_SLICK) || (trace_dphitcontents & DPCONTENTS_PLAYERCLIP))
{
spamsound(this, CH_SHOTS, SND(PORTO_BOUNCE), VOL_BASE, ATTEN_NORM);
// just reflect
//Send_Effect(EFFECT_GRENADE_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
gren = new(porto);
+ gren.weaponentity_fld = weaponentity;
gren.cnt = type;
gren.owner = gren.realowner = actor;
gren.playerid = actor.playerid;
MUTATOR_CALLHOOK(EditProjectile, actor, gren);
}
-METHOD(PortoLaunch, wr_aim, void(entity thiswep, entity actor))
+METHOD(PortoLaunch, wr_aim, void(entity thiswep, entity actor, .entity weaponentity))
{
PHYS_INPUT_BUTTON_ATCK(actor) = false;
PHYS_INPUT_BUTTON_ATCK2(actor) = false;
if(!WEP_CVAR(porto, secondary))
- if(bot_aim(actor, WEP_CVAR_PRI(porto, speed), 0, WEP_CVAR_PRI(porto, lifetime), false))
+ if(bot_aim(actor, weaponentity, WEP_CVAR_PRI(porto, speed), 0, WEP_CVAR_PRI(porto, lifetime), false))
PHYS_INPUT_BUTTON_ATCK(actor) = true;
}
METHOD(PortoLaunch, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
}
}
}
-METHOD(PortoLaunch, wr_checkammo1, bool(entity thiswep, entity this))
+METHOD(PortoLaunch, wr_checkammo1, bool(entity thiswep, entity this, .entity weaponentity))
{
// always allow infinite ammo
return true;
}
-METHOD(PortoLaunch, wr_checkammo2, bool(entity thiswep, entity this))
+METHOD(PortoLaunch, wr_checkammo2, bool(entity thiswep, entity this, .entity weaponentity))
{
// always allow infinite ammo
return true;
}
-METHOD(PortoLaunch, wr_setup, void(entity thiswep, entity actor))
-{
- actor.ammo_field = ammo_none;
-}
METHOD(PortoLaunch, wr_resetplayer, void(entity thiswep, entity actor))
{
actor.porto_current = NULL;
#endif
/* crosshair */ ATTRIB(Rifle, w_crosshair, string, "gfx/crosshairrifle");
/* crosshair */ ATTRIB(Rifle, w_crosshair_size, float, 0.6);
+/* reticle */ ATTRIB(Rifle, w_reticle, string, "gfx/reticle_nex");
/* wepimg */ ATTRIB(Rifle, model2, string, "weaponrifle");
/* refname */ ATTRIB(Rifle, netname, string, "rifle");
/* wepname */ ATTRIB(Rifle, m_name, string, _("Rifle"));
{
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);
}
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)
{
{
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);
.float bot_secondary_riflemooth;
-METHOD(Rifle, wr_aim, void(entity thiswep, entity actor))
+METHOD(Rifle, wr_aim, void(entity thiswep, entity actor, .entity weaponentity))
{
PHYS_INPUT_BUTTON_ATCK(actor) = false;
PHYS_INPUT_BUTTON_ATCK2(actor) = false;
actor.bot_secondary_riflemooth = 0;
if(actor.bot_secondary_riflemooth == 0)
{
- if(bot_aim(actor, 1000000, 0, 0.001, false))
+ if(bot_aim(actor, weaponentity, 1000000, 0, 0.001, false))
{
PHYS_INPUT_BUTTON_ATCK(actor) = true;
if(random() < 0.01) actor.bot_secondary_riflemooth = 1;
}
else
{
- if(bot_aim(actor, 1000000, 0, 0.001, false))
+ if(bot_aim(actor, weaponentity, 1000000, 0, 0.001, false))
{
PHYS_INPUT_BUTTON_ATCK2(actor) = true;
if(random() < 0.03) actor.bot_secondary_riflemooth = 0;
}
METHOD(Rifle, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
{
- if(autocvar_g_balance_rifle_reload_ammo && actor.clip_load < min(WEP_CVAR_PRI(rifle, ammo), WEP_CVAR_SEC(rifle, ammo))) { // forced reload
+ if(autocvar_g_balance_rifle_reload_ammo && actor.(weaponentity).clip_load < min(WEP_CVAR_PRI(rifle, ammo), WEP_CVAR_SEC(rifle, ammo))) { // forced reload
thiswep.wr_reload(thiswep, actor, weaponentity);
} else
{
}
}
}
-METHOD(Rifle, wr_checkammo1, bool(entity thiswep, entity actor))
+METHOD(Rifle, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity))
{
float ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR_PRI(rifle, ammo);
- ammo_amount += actor.(weapon_load[WEP_RIFLE.m_id]) >= WEP_CVAR_PRI(rifle, ammo);
+ ammo_amount += actor.(weaponentity).(weapon_load[WEP_RIFLE.m_id]) >= WEP_CVAR_PRI(rifle, ammo);
return ammo_amount;
}
-METHOD(Rifle, wr_checkammo2, bool(entity thiswep, entity actor))
+METHOD(Rifle, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity))
{
float ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR_SEC(rifle, ammo);
- ammo_amount += actor.(weapon_load[WEP_RIFLE.m_id]) >= WEP_CVAR_SEC(rifle, ammo);
+ ammo_amount += actor.(weaponentity).(weapon_load[WEP_RIFLE.m_id]) >= WEP_CVAR_SEC(rifle, ammo);
return ammo_amount;
}
METHOD(Rifle, wr_resetplayer, void(entity thiswep, entity actor))
return WEAPON_RIFLE_MURDER;
}
}
+METHOD(Rifle, wr_zoom, bool(entity thiswep, entity actor))
+{
+ return PHYS_INPUT_BUTTON_ATCK2(actor) && WEP_CVAR(rifle, secondary) == 0;
+}
#endif
#ifdef CSQC
precache_pic("gfx/reticle_nex");
}
}
-METHOD(Rifle, wr_zoomreticle, bool(entity thiswep))
+METHOD(Rifle, wr_zoom, bool(entity thiswep, entity actor))
{
if(button_zoom || zoomscript_caught)
{
- reticle_image = "gfx/reticle_nex";
return true;
}
else
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);
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;
+ c = actor.(weaponentity).bulletcounter % 4;
switch(c)
{
case 0:
// ============================
// Begin: Tag and rocket controllers
// ============================
-entity W_Seeker_Tagged_Info(entity isowner, entity istarget)
+entity W_Seeker_Tagged_Info(entity isowner, .entity weaponentity, entity istarget)
{
entity tag;
for(tag = NULL; (tag = find(tag, classname, "tag_tracker")); )
- if((tag.realowner == isowner) && (tag.tag_target == istarget))
+ if((tag.realowner == isowner) && (tag.tag_target == istarget) && (tag.weaponentity_fld == weaponentity))
return tag;
return NULL;
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;
oldenemy = own.enemy;
own.enemy = this.enemy;
- .entity weaponentity = this.weaponentity_fld;
c = own.cnt % 4;
switch(c)
void W_Seeker_Tracker_Think(entity this)
{
+ .entity weaponentity = this.weaponentity_fld;
// 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)
if(toucher.takedamage == DAMAGE_AIM && !IS_DEAD(toucher))
{
// check to see if this person is already tagged by me
- entity tag = W_Seeker_Tagged_Info(this.realowner, toucher);
+ .entity weaponentity = this.weaponentity_fld;
+ entity tag = W_Seeker_Tagged_Info(this.realowner, weaponentity, toucher);
if(tag != NULL)
{
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));
// Begin: Genereal weapon functions
// ============================
-METHOD(Seeker, wr_aim, void(entity thiswep, entity actor))
+METHOD(Seeker, wr_aim, void(entity thiswep, entity actor, .entity weaponentity))
{
if(WEP_CVAR(seeker, type) == 1)
- if(W_Seeker_Tagged_Info(actor, actor.enemy) != NULL)
- PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, WEP_CVAR(seeker, missile_speed_max), 0, WEP_CVAR(seeker, missile_lifetime), false);
+ if(W_Seeker_Tagged_Info(actor, weaponentity, actor.enemy) != NULL)
+ PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, WEP_CVAR(seeker, missile_speed_max), 0, WEP_CVAR(seeker, missile_lifetime), false);
else
- PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, WEP_CVAR(seeker, tag_speed), 0, WEP_CVAR(seeker, tag_lifetime), false);
+ PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, weaponentity, WEP_CVAR(seeker, tag_speed), 0, WEP_CVAR(seeker, tag_lifetime), false);
else
- PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, WEP_CVAR(seeker, tag_speed), 0, WEP_CVAR(seeker, tag_lifetime), false);
+ PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, WEP_CVAR(seeker, tag_speed), 0, WEP_CVAR(seeker, tag_lifetime), false);
}
METHOD(Seeker, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
{
- if(autocvar_g_balance_seeker_reload_ammo && actor.clip_load < min(WEP_CVAR(seeker, missile_ammo), WEP_CVAR(seeker, tag_ammo))) { // forced reload
+ if(autocvar_g_balance_seeker_reload_ammo && actor.(weaponentity).clip_load < min(WEP_CVAR(seeker, missile_ammo), WEP_CVAR(seeker, tag_ammo))) { // forced reload
thiswep.wr_reload(thiswep, actor, weaponentity);
} else if(fire & 1)
{
}
}
}
-METHOD(Seeker, wr_checkammo1, bool(entity thiswep, entity actor))
+METHOD(Seeker, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity))
{
float ammo_amount;
if(WEP_CVAR(seeker, type) == 1)
{
ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR(seeker, missile_ammo);
- ammo_amount += actor.(weapon_load[WEP_SEEKER.m_id]) >= WEP_CVAR(seeker, missile_ammo);
+ ammo_amount += actor.(weaponentity).(weapon_load[WEP_SEEKER.m_id]) >= WEP_CVAR(seeker, missile_ammo);
}
else
{
ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR(seeker, tag_ammo);
- ammo_amount += actor.(weapon_load[WEP_SEEKER.m_id]) >= WEP_CVAR(seeker, tag_ammo);
+ ammo_amount += actor.(weaponentity).(weapon_load[WEP_SEEKER.m_id]) >= WEP_CVAR(seeker, tag_ammo);
}
return ammo_amount;
}
-METHOD(Seeker, wr_checkammo2, bool(entity thiswep, entity actor))
+METHOD(Seeker, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity))
{
float ammo_amount;
if(WEP_CVAR(seeker, type) == 1)
{
ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR(seeker, tag_ammo);
- ammo_amount += actor.(weapon_load[WEP_SEEKER.m_id]) >= WEP_CVAR(seeker, tag_ammo);
+ ammo_amount += actor.(weaponentity).(weapon_load[WEP_SEEKER.m_id]) >= WEP_CVAR(seeker, tag_ammo);
}
else
{
ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR(seeker, flac_ammo);
- ammo_amount += actor.(weapon_load[WEP_SEEKER.m_id]) >= WEP_CVAR(seeker, flac_ammo);
+ ammo_amount += actor.(weaponentity).(weapon_load[WEP_SEEKER.m_id]) >= WEP_CVAR(seeker, flac_ammo);
}
return ammo_amount;
}
}
}
-METHOD(Shockwave, wr_aim, void(entity thiswep, entity actor))
+METHOD(Shockwave, wr_aim, void(entity thiswep, entity actor, .entity weaponentity))
{
if(vdist(actor.origin - actor.enemy.origin, <=, WEP_CVAR(shockwave, melee_range)))
- { PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, 1000000, 0, 0.001, false); }
+ { PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, weaponentity, 1000000, 0, 0.001, false); }
else
- { PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, 1000000, 0, 0.001, false); }
+ { PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, 1000000, 0, 0.001, false); }
}
METHOD(Shockwave, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
{
if(fire & 1)
{
- if(time >= actor.shockwave_blasttime) // handle refire separately so the secondary can be fired straight after a primary
+ if(time >= actor.(weaponentity).shockwave_blasttime) // handle refire separately so the secondary can be fired straight after a primary
{
if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(shockwave, blast_animtime)))
{
W_Shockwave_Attack(actor, weaponentity);
- actor.shockwave_blasttime = time + WEP_CVAR(shockwave, blast_refire) * W_WeaponRateFactor(actor);
+ actor.(weaponentity).shockwave_blasttime = time + WEP_CVAR(shockwave, blast_refire) * W_WeaponRateFactor(actor);
weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(shockwave, blast_animtime), w_ready);
}
}
}
}
}
-METHOD(Shockwave, wr_checkammo1, bool(entity thiswep, entity actor))
+METHOD(Shockwave, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity))
{
return true; // infinite ammo
}
-METHOD(Shockwave, wr_checkammo2, bool(entity thiswep, entity actor))
+METHOD(Shockwave, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity))
{
// shockwave has infinite ammo
return true;
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));
// alternate secondary weapon frames
void W_Shotgun_Attack3_Frame2(Weapon thiswep, entity actor, .entity weaponentity, int fire)
{
- if (!thiswep.wr_checkammo2(thiswep, actor))
+ if (!thiswep.wr_checkammo2(thiswep, actor, weaponentity))
if (!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
{
- W_SwitchWeapon_Force(actor, w_getbestweapon(actor));
+ W_SwitchWeapon_Force(actor, w_getbestweapon(actor, weaponentity), weaponentity);
w_ready(thiswep, actor, weaponentity, fire);
return;
}
}
void W_Shotgun_Attack3_Frame1(Weapon thiswep, entity actor, .entity weaponentity, int fire)
{
- if (!thiswep.wr_checkammo2(thiswep, actor))
+ if (!thiswep.wr_checkammo2(thiswep, actor, weaponentity))
if (!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
{
- W_SwitchWeapon_Force(actor, w_getbestweapon(actor));
+ W_SwitchWeapon_Force(actor, w_getbestweapon(actor, weaponentity), weaponentity);
w_ready(thiswep, actor, weaponentity, fire);
return;
}
weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_SEC(shotgun, alt_animtime), W_Shotgun_Attack3_Frame2);
}
-.float shotgun_primarytime[MAX_WEAPONSLOTS];
+.float shotgun_primarytime;
-METHOD(Shotgun, wr_aim, void(entity thiswep, entity actor))
+METHOD(Shotgun, wr_aim, void(entity thiswep, entity actor, .entity weaponentity))
{
if(vdist(actor.origin - actor.enemy.origin, <=, WEP_CVAR_SEC(shotgun, melee_range)))
- PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, 1000000, 0, 0.001, false);
+ PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, weaponentity, 1000000, 0, 0.001, false);
else
- PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, 1000000, 0, 0.001, false);
+ PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, 1000000, 0, 0.001, false);
}
METHOD(Shotgun, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
{
- if(WEP_CVAR(shotgun, reload_ammo) && actor.clip_load < WEP_CVAR_PRI(shotgun, ammo)) // forced reload
+ if(WEP_CVAR(shotgun, reload_ammo) && actor.(weaponentity).clip_load < WEP_CVAR_PRI(shotgun, ammo)) // forced reload
{
// don't force reload an empty shotgun if its melee attack is active
if(WEP_CVAR(shotgun, secondary) < 2) {
{
if(fire & 1)
{
- int slot = weaponslot(weaponentity);
- if(time >= actor.shotgun_primarytime[slot]) // handle refire separately so the secondary can be fired straight after a primary
+ if(time >= actor.(weaponentity).shotgun_primarytime) // handle refire separately so the secondary can be fired straight after a primary
{
if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(shotgun, animtime)))
{
W_Shotgun_Attack(thiswep, actor, weaponentity, true);
- actor.shotgun_primarytime[slot] = time + WEP_CVAR_PRI(shotgun, refire) * W_WeaponRateFactor(actor);
+ actor.(weaponentity).shotgun_primarytime = time + WEP_CVAR_PRI(shotgun, refire) * W_WeaponRateFactor(actor);
weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(shotgun, animtime), w_ready);
}
}
}
else if((fire & 2) && WEP_CVAR(shotgun, secondary) == 2)
{
- int slot = weaponslot(weaponentity);
- if(time >= actor.shotgun_primarytime[slot]) // handle refire separately so the secondary can be fired straight after a primary
+ if(time >= actor.(weaponentity).shotgun_primarytime) // handle refire separately so the secondary can be fired straight after a primary
{
if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_SEC(shotgun, alt_animtime)))
{
W_Shotgun_Attack(thiswep, actor, weaponentity, false);
- actor.shotgun_primarytime[slot] = time + WEP_CVAR_SEC(shotgun, alt_refire) * W_WeaponRateFactor(actor);
+ actor.(weaponentity).shotgun_primarytime = time + WEP_CVAR_SEC(shotgun, alt_refire) * W_WeaponRateFactor(actor);
weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_SEC(shotgun, alt_animtime), W_Shotgun_Attack3_Frame1);
}
}
}
}
- if(actor.clip_load >= 0) // we are not currently reloading
+ if(actor.(weaponentity).clip_load >= 0) // we are not currently reloading
if(WEP_CVAR(shotgun, secondary) == 1)
if(((fire & 1) && actor.(thiswep.ammo_field) <= 0 && !(actor.items & IT_UNLIMITED_WEAPON_AMMO)) || (fire & 2))
if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(shotgun, refire)))
weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, 0, W_Shotgun_Attack2);
}
}
-METHOD(Shotgun, wr_setup, void(entity thiswep, entity actor))
-{
- actor.ammo_field = ammo_none;
-}
-METHOD(Shotgun, wr_checkammo1, bool(entity thiswep, entity actor))
+METHOD(Shotgun, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity))
{
float ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR_PRI(shotgun, ammo);
- ammo_amount += actor.(weapon_load[WEP_SHOTGUN.m_id]) >= WEP_CVAR_PRI(shotgun, ammo);
+ ammo_amount += actor.(weaponentity).(weapon_load[WEP_SHOTGUN.m_id]) >= WEP_CVAR_PRI(shotgun, ammo);
return ammo_amount;
}
-METHOD(Shotgun, wr_checkammo2, bool(entity thiswep, entity actor))
+METHOD(Shotgun, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity))
{
if(IS_BOT_CLIENT(actor))
if(vdist(actor.origin - actor.enemy.origin, >, WEP_CVAR_SEC(shotgun, melee_range)))
case 2: // secondary triple shot
{
float ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR_PRI(shotgun, ammo);
- ammo_amount += actor.(weapon_load[WEP_SHOTGUN.m_id]) >= WEP_CVAR_PRI(shotgun, ammo);
+ ammo_amount += actor.(weaponentity).(weapon_load[WEP_SHOTGUN.m_id]) >= WEP_CVAR_PRI(shotgun, ammo);
return ammo_amount;
}
default: return false; // secondary unavailable
spawnfunc(weapon_tuba) { weapon_defaultspawnfunc(this, WEP_TUBA); }
-bool W_Tuba_HasPlayed(entity pl, string melody, int instrument, bool ignorepitch, float mintempo, float maxtempo)
+bool W_Tuba_HasPlayed(entity pl, .entity weaponentity, string melody, int instrument, bool ignorepitch, float mintempo, float maxtempo)
{
float i, j, mmin, mmax, nolength;
float n = tokenize_console(melody);
- if(n > pl.tuba_lastnotes_cnt)
+ if(n > pl.(weaponentity).tuba_lastnotes_cnt)
return false;
float pitchshift = 0;
if(instrument >= 0)
- if(pl.tuba_instrument != instrument)
+ if(pl.(weaponentity).tuba_instrument != instrument)
return false;
// verify notes...
nolength = false;
for(i = 0; i < n; ++i)
{
- vector v = pl.(tuba_lastnotes[(pl.tuba_lastnotes_last - i + MAX_TUBANOTES) % MAX_TUBANOTES]);
+ vector v = pl.(weaponentity).(tuba_lastnotes[(pl.(weaponentity).tuba_lastnotes_last - i + MAX_TUBANOTES) % MAX_TUBANOTES]);
float ai = stof(argv(n - i - 1));
float np = floor(ai);
if(ai == np)
for(i = 0; i < n; ++i)
{
- vector vi = pl.(tuba_lastnotes[(pl.tuba_lastnotes_last - i + MAX_TUBANOTES) % MAX_TUBANOTES]);
+ vector vi = pl.(weaponentity).(tuba_lastnotes[(pl.(weaponentity).tuba_lastnotes_last - i + MAX_TUBANOTES) % MAX_TUBANOTES]);
float ai = stof(argv(n - i - 1));
ti -= 1 / (ai - floor(ai));
float tj = ti;
for(j = i+1; j < n; ++j)
{
- vector vj = pl.(tuba_lastnotes[(pl.tuba_lastnotes_last - j + MAX_TUBANOTES) % MAX_TUBANOTES]);
+ vector vj = pl.(weaponentity).(tuba_lastnotes[(pl.(weaponentity).tuba_lastnotes_last - j + MAX_TUBANOTES) % MAX_TUBANOTES]);
float aj = stof(argv(n - j - 1));
tj -= (aj - floor(aj));
return false;
}
- pl.tuba_lastnotes_cnt = 0;
+ pl.(weaponentity).tuba_lastnotes_cnt = 0;
return true;
}
// on: this.spawnshieldtime
// off: time
// note: this.cnt
- if (actor.tuba_note == this)
+ .entity weaponentity = this.weaponentity_fld;
+ if (actor.(weaponentity).tuba_note == this)
{
- actor.tuba_lastnotes_last = (actor.tuba_lastnotes_last + 1) % MAX_TUBANOTES;
- actor.(tuba_lastnotes[actor.tuba_lastnotes_last]) = eX * this.spawnshieldtime + eY * time + eZ * this.cnt;
- actor.tuba_note = NULL;
- actor.tuba_lastnotes_cnt = bound(0, actor.tuba_lastnotes_cnt + 1, MAX_TUBANOTES);
+ actor.(weaponentity).tuba_lastnotes_last = (actor.(weaponentity).tuba_lastnotes_last + 1) % MAX_TUBANOTES;
+ actor.(weaponentity).(tuba_lastnotes[actor.(weaponentity).tuba_lastnotes_last]) = eX * this.spawnshieldtime + eY * time + eZ * this.cnt;
+ actor.(weaponentity).tuba_note = NULL;
+ actor.(weaponentity).tuba_lastnotes_cnt = bound(0, actor.(weaponentity).tuba_lastnotes_cnt + 1, MAX_TUBANOTES);
string s = trigger_magicear_processmessage_forallears(actor, 0, NULL, string_null);
if (s != "")
n = W_Tuba_GetNote(actor, hittype);
hittype = 0;
- if(actor.tuba_instrument & 1)
+ if(actor.(weaponentity).tuba_instrument & 1)
hittype |= HITTYPE_SECONDARY;
- if(actor.tuba_instrument & 2)
+ if(actor.(weaponentity).tuba_instrument & 2)
hittype |= HITTYPE_BOUNCE;
- if(actor.tuba_note)
+ if(actor.(weaponentity).tuba_note)
{
- if(actor.tuba_note.cnt != n || actor.tuba_note.tuba_instrument != actor.tuba_instrument)
+ if(actor.(weaponentity).tuba_note.cnt != n || actor.(weaponentity).tuba_note.tuba_instrument != actor.(weaponentity).tuba_instrument)
{
- W_Tuba_NoteOff(actor.tuba_note);
+ W_Tuba_NoteOff(actor.(weaponentity).tuba_note);
}
}
- if(!actor.tuba_note)
+ if(!actor.(weaponentity).tuba_note)
{
- actor.tuba_note = new(tuba_note);
- actor.tuba_note.owner = actor.tuba_note.realowner = actor;
- actor.tuba_note.cnt = n;
- actor.tuba_note.tuba_instrument = actor.tuba_instrument;
- setthink(actor.tuba_note, W_Tuba_NoteThink);
- actor.tuba_note.nextthink = time;
- actor.tuba_note.spawnshieldtime = time;
- Net_LinkEntity(actor.tuba_note, false, 0, W_Tuba_NoteSendEntity);
+ entity note = new(tuba_note);
+ note.weaponentity_fld = weaponentity;
+ actor.(weaponentity).tuba_note = note;
+ note.owner = note.realowner = actor;
+ note.cnt = n;
+ note.tuba_instrument = actor.(weaponentity).tuba_instrument;
+ setthink(note, W_Tuba_NoteThink);
+ note.nextthink = time;
+ note.spawnshieldtime = time;
+ Net_LinkEntity(note, false, 0, W_Tuba_NoteSendEntity);
}
- actor.tuba_note.teleport_time = time + WEP_CVAR(tuba, refire) * 2 * W_WeaponRateFactor(actor); // so it can get prolonged safely
+ actor.(weaponentity).tuba_note.teleport_time = time + WEP_CVAR(tuba, refire) * 2 * W_WeaponRateFactor(actor); // so it can get prolonged safely
//sound(actor, c, TUBA_NOTE(n), bound(0, VOL_BASE * cvar("g_balance_tuba_volume"), 1), autocvar_g_balance_tuba_attenuation);
RadiusDamage(actor, actor, WEP_CVAR(tuba, damage), WEP_CVAR(tuba, edgedamage), WEP_CVAR(tuba, radius), NULL, NULL, WEP_CVAR(tuba, force), hittype | WEP_TUBA.m_id, NULL);
o = gettaginfo(actor.exteriorweaponentity, 0);
- if(time > actor.tuba_smoketime)
+ if(time > actor.(weaponentity).tuba_smoketime)
{
Send_Effect(EFFECT_SMOKE_RING, o + v_up * 45 + v_right * -6 + v_forward * 8, v_up * 100, 1);
- actor.tuba_smoketime = time + 0.25;
+ actor.(weaponentity).tuba_smoketime = time + 0.25;
}
}
#endif
#ifdef SVQC
-METHOD(Tuba, wr_aim, void(Tuba this, entity actor))
+METHOD(Tuba, wr_aim, void(Tuba this, entity actor, .entity weaponentity))
{
// bots cannot play the Tuba well yet
// I think they should start with the recorder first
W_Tuba_NoteOn(actor, weaponentity, HITTYPE_SECONDARY);
weapon_thinkf(actor, weaponentity, WFRAME_IDLE, WEP_CVAR(tuba, animtime), w_ready);
}
- if (actor.tuba_note)
+ if (actor.(weaponentity).tuba_note)
{
if (!(fire & 1) && !(fire & 2))
{
- W_Tuba_NoteOff(actor.tuba_note);
+ W_Tuba_NoteOff(actor.(weaponentity).tuba_note);
}
}
}
-METHOD(Tuba, wr_setup, void(Tuba this, entity actor))
+METHOD(Tuba, wr_setup, void(Tuba this, entity actor, .entity weaponentity))
{
- actor.ammo_field = ammo_none;
- actor.tuba_instrument = 0;
+ actor.(weaponentity).tuba_instrument = 0;
}
#endif
NET_HANDLE(tuba_instrument, bool)
{
int i = ReadByte();
+ int slot = ReadByte();
return = true;
string s = (i == 0) ? "tuba" :
(i == 1) ? "akordeon" :
"kleinbottle" ;
- CL_WeaponEntity_SetModel(viewmodel, s, true);
+
+ entity wep = viewmodels[slot];
+ CL_WeaponEntity_SetModel(wep, s, true);
}
#endif
#ifdef SVQC
-void tuba_instrument_send(entity this, int instr)
+void tuba_instrument_send(entity this, .entity weaponentity, int instr)
{
msg_entity = this;
int chan = MSG_ONE;
WriteHeader(chan, tuba_instrument);
WriteByte(chan, instr);
+ WriteByte(chan, weaponslot(weaponentity));
}
SPECTATE_COPY()
{
- if (this.tuba_instrument != spectatee.tuba_instrument)
- tuba_instrument_send(this, this.tuba_instrument = spectatee.tuba_instrument);
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(this.(weaponentity).tuba_instrument != spectatee.(weaponentity).tuba_instrument)
+ tuba_instrument_send(this, weaponentity, this.(weaponentity).tuba_instrument = spectatee.(weaponentity).tuba_instrument);
+ }
}
METHOD(Tuba, wr_reload, void(Tuba this, entity actor, .entity weaponentity))
{
// switch to alternate instruments :)
if (actor.(weaponentity).state == WS_READY)
{
- switch (actor.tuba_instrument)
+ switch (actor.(weaponentity).tuba_instrument)
{
case 0:
- actor.tuba_instrument = 1;
- actor.weaponname = "akordeon";
+ actor.(weaponentity).tuba_instrument = 1;
+ actor.(weaponentity).weaponname = "akordeon";
break;
case 1:
- actor.tuba_instrument = 2;
- actor.weaponname = "kleinbottle";
+ actor.(weaponentity).tuba_instrument = 2;
+ actor.(weaponentity).weaponname = "kleinbottle";
break;
case 2:
- actor.tuba_instrument = 0;
- actor.weaponname = "tuba";
+ actor.(weaponentity).tuba_instrument = 0;
+ actor.(weaponentity).weaponname = "tuba";
break;
}
- tuba_instrument_send(actor, actor.tuba_instrument);
+ tuba_instrument_send(actor, weaponentity, actor.(weaponentity).tuba_instrument);
W_SetupShot(actor, weaponentity, false, 0, SND_Null, 0, 0);
Send_Effect(EFFECT_TELEPORT, w_shotorg, '0 0 0', 1);
actor.(weaponentity).state = WS_INUSE;
#ifdef SVQC
// infinite ammo
-METHOD(Tuba, wr_checkammo1, bool(Tuba this, entity actor)) { return true; }
-METHOD(Tuba, wr_checkammo2, bool(Tuba this, entity actor)) { return true; }
+METHOD(Tuba, wr_checkammo1, bool(Tuba this, entity actor, .entity weaponentity)) { return true; }
+METHOD(Tuba, wr_checkammo2, bool(Tuba this, entity actor, .entity weaponentity)) { return true; }
METHOD(Tuba, wr_suicidemessage, Notification(Tuba this))
{
#endif
/* crosshair */ ATTRIB(Vaporizer, w_crosshair, string, "gfx/crosshairminstanex");
/* crosshair */ ATTRIB(Vaporizer, w_crosshair_size, float, 0.6);
+/* reticle */ ATTRIB(Vaporizer, w_reticle, string, "gfx/reticle_nex");
/* wepimg */ ATTRIB(Vaporizer, model2, string, "weaponminstanex");
/* refname */ ATTRIB(Vaporizer, netname, string, "vaporizer");
/* wepname */ ATTRIB(Vaporizer, m_name, string, _("Vaporizer"));
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);
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)
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);
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);
}
}
-METHOD(Vaporizer, wr_aim, void(entity thiswep, entity actor))
+METHOD(Vaporizer, wr_aim, void(entity thiswep, entity actor, .entity weaponentity))
{
if(actor.(thiswep.ammo_field) > 0)
- PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, 1000000, 0, 1, false);
+ PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, 1000000, 0, 1, false);
else
- PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, WEP_CVAR_SEC(vaporizer, speed), 0, WEP_CVAR_SEC(vaporizer, lifetime), false); // WEAPONTODO: replace with proper vaporizer cvars
+ PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, weaponentity, WEP_CVAR_SEC(vaporizer, speed), 0, WEP_CVAR_SEC(vaporizer, lifetime), false); // WEAPONTODO: replace with proper vaporizer cvars
}
METHOD(Vaporizer, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
{
float vaporizer_ammo = ((g_instagib) ? 1 : WEP_CVAR_PRI(vaporizer, ammo));
// if the laser uses load, we also consider its ammo for reloading
- if(WEP_CVAR(vaporizer, reload_ammo) && WEP_CVAR_SEC(vaporizer, ammo) && actor.clip_load < min(vaporizer_ammo, WEP_CVAR_SEC(vaporizer, ammo))) { // forced reload
+ if(WEP_CVAR(vaporizer, reload_ammo) && WEP_CVAR_SEC(vaporizer, ammo) && actor.(weaponentity).clip_load < min(vaporizer_ammo, WEP_CVAR_SEC(vaporizer, ammo))) { // forced reload
thiswep.wr_reload(thiswep, actor, weaponentity);
- } else if(WEP_CVAR(vaporizer, reload_ammo) && actor.clip_load < vaporizer_ammo) { // forced reload
+ } else if(WEP_CVAR(vaporizer, reload_ammo) && actor.(weaponentity).clip_load < vaporizer_ammo) { // forced reload
thiswep.wr_reload(thiswep, actor, weaponentity);
}
if((fire & 1) && (actor.ammo_cells || !autocvar_g_rm) && !forbidWeaponUse(actor))
if((autocvar_g_rm && autocvar_g_rm_laser) || autocvar_g_rm_laser == 2)
{
bool rapid = autocvar_g_rm_laser_rapid;
- if(actor.jump_interval <= time && !actor.held_down)
+ if(actor.(weaponentity).jump_interval <= time && !actor.(weaponentity).held_down)
{
if(rapid)
- actor.held_down = true;
- actor.jump_interval = time + autocvar_g_rm_laser_refire;
- actor.jump_interval2 = time + autocvar_g_rm_laser_rapid_delay;
+ actor.(weaponentity).held_down = true;
+ actor.(weaponentity).jump_interval = time + autocvar_g_rm_laser_refire;
+ actor.(weaponentity).jump_interval2 = time + autocvar_g_rm_laser_rapid_delay;
damage_goodhits = 0;
W_RocketMinsta_Attack2(actor, weaponentity);
}
- else if(rapid && actor.jump_interval2 <= time && actor.held_down)
+ else if(rapid && actor.(weaponentity).jump_interval2 <= time && actor.(weaponentity).held_down)
{
- actor.jump_interval2 = time + autocvar_g_rm_laser_rapid_refire;
+ actor.(weaponentity).jump_interval2 = time + autocvar_g_rm_laser_rapid_refire;
damage_goodhits = 0;
W_RocketMinsta_Attack3(actor, weaponentity);
//weapon_thinkf(actor, WFRAME_FIRE2, autocvar_g_rm_laser_rapid_animtime, w_ready);
}
}
- else if (actor.jump_interval <= time)
+ else if (actor.(weaponentity).jump_interval <= time)
{
// handle refire manually, so that primary and secondary can be fired without conflictions (important for instagib)
- actor.jump_interval = time + WEP_CVAR_SEC(vaporizer, refire) * W_WeaponRateFactor(actor);
+ actor.(weaponentity).jump_interval = time + WEP_CVAR_SEC(vaporizer, refire) * W_WeaponRateFactor(actor);
// 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,
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);
}
}
else
- actor.held_down = false;
+ actor.(weaponentity).held_down = false;
}
-METHOD(Vaporizer, wr_setup, void(entity thiswep, entity actor))
+METHOD(Vaporizer, wr_setup, void(entity thiswep, entity actor, .entity weaponentity))
{
- actor.ammo_field = (thiswep.ammo_field);
actor.vaporizer_lasthit = 0;
}
-METHOD(Vaporizer, wr_checkammo1, bool(entity thiswep, entity actor))
+METHOD(Vaporizer, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity))
{
float vaporizer_ammo = ((g_instagib) ? 1 : WEP_CVAR_PRI(vaporizer, ammo));
float ammo_amount = actor.(thiswep.ammo_field) >= vaporizer_ammo;
- ammo_amount += actor.(weapon_load[WEP_VAPORIZER.m_id]) >= vaporizer_ammo;
+ ammo_amount += actor.(weaponentity).(weapon_load[WEP_VAPORIZER.m_id]) >= vaporizer_ammo;
return ammo_amount;
}
-METHOD(Vaporizer, wr_checkammo2, bool(entity thiswep, entity actor))
+METHOD(Vaporizer, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity))
{
if(!WEP_CVAR_SEC(vaporizer, ammo))
return true;
float ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR_SEC(vaporizer, ammo);
- ammo_amount += actor.(weapon_load[WEP_VAPORIZER.m_id]) >= WEP_CVAR_SEC(vaporizer, ammo);
+ ammo_amount += actor.(weaponentity).(weapon_load[WEP_VAPORIZER.m_id]) >= WEP_CVAR_SEC(vaporizer, ammo);
return ammo_amount;
}
METHOD(Vaporizer, wr_resetplayer, void(entity thiswep, entity actor))
precache_pic("gfx/reticle_nex");
}
}
-METHOD(Vaporizer, wr_zoomreticle, bool(entity thiswep))
+METHOD(Vaporizer, wr_zoom, bool(entity thiswep, entity actor))
{
if(button_zoom || zoomscript_caught)
{
- reticle_image = "gfx/reticle_nex";
return true;
}
else
#endif
/* crosshair */ ATTRIB(Vortex, w_crosshair, string, "gfx/crosshairnex");
/* crosshair */ ATTRIB(Vortex, w_crosshair_size, float, 0.65);
+/* reticle */ ATTRIB(Vortex, w_reticle, string, "gfx/reticle_nex");
/* wepimg */ ATTRIB(Vortex, model2, string, "weaponnex");
/* refname */ ATTRIB(Vortex, netname, string, "vortex");
/* wepname */ ATTRIB(Vortex, m_name, string, _("Vortex"));
float autocvar_g_weapon_charge_colormod_green_half;
float autocvar_g_weapon_charge_colormod_hdrmultiplier;
-METHOD(Vortex, wr_glow, vector(Vortex this, entity actor))
+METHOD(Vortex, wr_glow, vector(Vortex this, entity actor, entity wepent))
{
if (!STAT(WEP_CVAR_vortex_charge, actor)) return '0 0 0';
- float charge = STAT(VORTEX_CHARGE, actor);
+ float charge = wepent.vortex_charge;
float animlimit = STAT(WEP_CVAR_vortex_charge_animlimit, actor);
vector g;
g.x = autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_red_half * min(1, charge / animlimit);
entity player = M_ARGV(0, entity);
// 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))
- {
- // 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));
- float f = (xyspeed - WEP_CVAR(vortex, charge_minspeed)) / (WEP_CVAR(vortex, charge_maxspeed) - WEP_CVAR(vortex, charge_minspeed));
- // add the extra charge
- player.vortex_charge = min(1, player.vortex_charge + WEP_CVAR(vortex, charge_velocity_rate) * f * PHYS_INPUT_TIMELENGTH);
- }
+ if(!WEP_CVAR(vortex, charge) || !WEP_CVAR(vortex, charge_velocity_rate))
+ return;
+
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+
+ if (player.(weaponentity).m_weapon == WEP_VORTEX && WEP_CVAR(vortex, charge) && WEP_CVAR(vortex, charge_velocity_rate) && vdist(vec2(player.velocity), >, WEP_CVAR(vortex, charge_minspeed)))
+ {
+ float xyspeed = vlen(vec2(player.velocity));
+ // 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));
+ float f = (xyspeed - WEP_CVAR(vortex, charge_minspeed)) / (WEP_CVAR(vortex, charge_maxspeed) - WEP_CVAR(vortex, charge_minspeed));
+ // add the extra charge
+ player.(weaponentity).vortex_charge = min(1, player.(weaponentity).vortex_charge + WEP_CVAR(vortex, charge_velocity_rate) * f * PHYS_INPUT_TIMELENGTH);
+ }
+ }
}
void W_Vortex_Attack(Weapon thiswep, entity actor, .entity weaponentity, float issecondary)
if(WEP_CVAR(vortex, charge))
{
- charge = WEP_CVAR(vortex, charge_mindmg) / mydmg + (1 - WEP_CVAR(vortex, charge_mindmg) / mydmg) * actor.vortex_charge;
- actor.vortex_charge *= WEP_CVAR(vortex, charge_shot_multiplier); // do this AFTER setting mydmg/myforce
+ charge = WEP_CVAR(vortex, charge_mindmg) / mydmg + (1 - WEP_CVAR(vortex, charge_mindmg) / mydmg) * actor.(weaponentity).vortex_charge;
+ actor.(weaponentity).vortex_charge *= WEP_CVAR(vortex, charge_shot_multiplier); // do this AFTER setting mydmg/myforce
// O RLY? -- divVerent
// YA RLY -- FruitieX
}
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);
//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;
-METHOD(Vortex, wr_aim, void(entity thiswep, entity actor))
+METHOD(Vortex, wr_aim, void(entity thiswep, entity actor, .entity weaponentity))
{
- if(bot_aim(actor, 1000000, 0, 1, false))
+ if(bot_aim(actor, weaponentity, 1000000, 0, 1, false))
PHYS_INPUT_BUTTON_ATCK(actor) = true;
else
{
}
METHOD(Vortex, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
{
- if(WEP_CVAR(vortex, charge) && actor.vortex_charge < WEP_CVAR(vortex, charge_limit))
- actor.vortex_charge = min(1, actor.vortex_charge + WEP_CVAR(vortex, charge_rate) * frametime / W_TICSPERFRAME);
+ if(WEP_CVAR(vortex, charge) && actor.(weaponentity).vortex_charge < WEP_CVAR(vortex, charge_limit))
+ actor.(weaponentity).vortex_charge = min(1, actor.(weaponentity).vortex_charge + WEP_CVAR(vortex, charge_rate) * frametime / W_TICSPERFRAME);
+
+ if(weaponslot(weaponentity) == 0)
+ actor.vortex_charge = actor.(weaponentity).vortex_charge;
if(WEP_CVAR_SEC(vortex, chargepool))
- if(actor.vortex_chargepool_ammo < 1)
+ if(actor.(weaponentity).vortex_chargepool_ammo < 1)
{
if(actor.vortex_chargepool_pauseregen_finished < time)
- actor.vortex_chargepool_ammo = min(1, actor.vortex_chargepool_ammo + WEP_CVAR_SEC(vortex, chargepool_regen) * frametime / W_TICSPERFRAME);
+ actor.(weaponentity).vortex_chargepool_ammo = min(1, actor.(weaponentity).vortex_chargepool_ammo + WEP_CVAR_SEC(vortex, chargepool_regen) * frametime / W_TICSPERFRAME);
actor.pauseregen_finished = max(actor.pauseregen_finished, time + WEP_CVAR_SEC(vortex, chargepool_pause_regen));
}
- if(autocvar_g_balance_vortex_reload_ammo && actor.clip_load < min(WEP_CVAR_PRI(vortex, ammo), WEP_CVAR_SEC(vortex, ammo))) { // forced reload
+ if(weaponslot(weaponentity) == 0)
+ actor.vortex_chargepool_ammo = actor.(weaponentity).vortex_chargepool_ammo;
+
+ if(autocvar_g_balance_vortex_reload_ammo && actor.(weaponentity).clip_load < min(WEP_CVAR_PRI(vortex, ammo), WEP_CVAR_SEC(vortex, ammo))) { // forced reload
thiswep.wr_reload(thiswep, actor, weaponentity);
} else
{
{
if(WEP_CVAR(vortex, charge))
{
- actor.vortex_charge_rottime = time + WEP_CVAR(vortex, charge_rot_pause);
+ actor.(weaponentity).vortex_charge_rottime = time + WEP_CVAR(vortex, charge_rot_pause);
float dt = frametime / W_TICSPERFRAME;
- if(actor.vortex_charge < 1)
+ if(actor.(weaponentity).vortex_charge < 1)
{
if(WEP_CVAR_SEC(vortex, chargepool))
{
// always deplete if secondary is held
actor.vortex_chargepool_ammo = max(0, actor.vortex_chargepool_ammo - WEP_CVAR_SEC(vortex, ammo) * dt);
- dt = min(dt, (1 - actor.vortex_charge) / WEP_CVAR(vortex, charge_rate));
+ dt = min(dt, (1 - actor.(weaponentity).vortex_charge) / WEP_CVAR(vortex, charge_rate));
actor.vortex_chargepool_pauseregen_finished = time + WEP_CVAR_SEC(vortex, chargepool_pause_regen);
dt = min(dt, actor.vortex_chargepool_ammo);
dt = max(0, dt);
- actor.vortex_charge += dt * WEP_CVAR(vortex, charge_rate);
+ actor.(weaponentity).vortex_charge += dt * WEP_CVAR(vortex, charge_rate);
}
}
{
if(fire & 2) // only eat ammo when the button is pressed
{
- dt = min(dt, (1 - actor.vortex_charge) / WEP_CVAR(vortex, charge_rate));
+ dt = min(dt, (1 - actor.(weaponentity).vortex_charge) / WEP_CVAR(vortex, charge_rate));
if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
{
// if this weapon is reloadable, decrease its load. Else decrease the player's ammo
if(autocvar_g_balance_vortex_reload_ammo)
{
- dt = min(dt, (actor.clip_load - WEP_CVAR_PRI(vortex, ammo)) / WEP_CVAR_SEC(vortex, ammo));
+ dt = min(dt, (actor.(weaponentity).clip_load - WEP_CVAR_PRI(vortex, ammo)) / WEP_CVAR_SEC(vortex, ammo));
dt = max(0, dt);
if(dt > 0)
{
- actor.clip_load = max(WEP_CVAR_SEC(vortex, ammo), actor.clip_load - WEP_CVAR_SEC(vortex, ammo) * dt);
+ actor.(weaponentity).clip_load = max(WEP_CVAR_SEC(vortex, ammo), actor.(weaponentity).clip_load - WEP_CVAR_SEC(vortex, ammo) * dt);
}
- actor.(weapon_load[WEP_VORTEX.m_id]) = actor.clip_load;
+ actor.(weaponentity).(weapon_load[WEP_VORTEX.m_id]) = actor.(weaponentity).clip_load;
}
else
{
}
}
}
- actor.vortex_charge += dt * WEP_CVAR(vortex, charge_rate);
+ actor.(weaponentity).vortex_charge += dt * WEP_CVAR(vortex, charge_rate);
}
}
else
{
- dt = min(dt, (1 - actor.vortex_charge) / WEP_CVAR(vortex, charge_rate));
- actor.vortex_charge += dt * WEP_CVAR(vortex, charge_rate);
+ dt = min(dt, (1 - actor.(weaponentity).vortex_charge) / WEP_CVAR(vortex, charge_rate));
+ actor.(weaponentity).vortex_charge += dt * WEP_CVAR(vortex, charge_rate);
}
}
}
}
}
}
-METHOD(Vortex, wr_setup, void(entity thiswep, entity actor))
+METHOD(Vortex, wr_setup, void(entity thiswep, entity actor, .entity weaponentity))
{
actor.vortex_lasthit = 0;
}
-METHOD(Vortex, wr_checkammo1, bool(entity thiswep, entity actor))
+METHOD(Vortex, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity))
{
float ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR_PRI(vortex, ammo);
- ammo_amount += (autocvar_g_balance_vortex_reload_ammo && actor.(weapon_load[WEP_VORTEX.m_id]) >= WEP_CVAR_PRI(vortex, ammo));
+ ammo_amount += (autocvar_g_balance_vortex_reload_ammo && actor.(weaponentity).(weapon_load[WEP_VORTEX.m_id]) >= WEP_CVAR_PRI(vortex, ammo));
return ammo_amount;
}
-METHOD(Vortex, wr_checkammo2, bool(entity thiswep, entity actor))
+METHOD(Vortex, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity))
{
if(WEP_CVAR(vortex, secondary))
{
// don't allow charging if we don't have enough ammo
float ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR_SEC(vortex, ammo);
- ammo_amount += actor.(weapon_load[WEP_VORTEX.m_id]) >= WEP_CVAR_SEC(vortex, ammo);
+ ammo_amount += actor.(weaponentity).(weapon_load[WEP_VORTEX.m_id]) >= WEP_CVAR_SEC(vortex, ammo);
return ammo_amount;
}
else
actor.vortex_chargepool_ammo = 1;
}
actor.vortex_charge = WEP_CVAR(vortex, charge_start);
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ actor.(weaponentity).vortex_charge = WEP_CVAR(vortex, charge_start);
+
+ if (WEP_CVAR_SEC(vortex, chargepool))
+ actor.(weaponentity).vortex_chargepool_ammo = 1;
+ }
}
actor.vortex_lasthit = 0;
}
{
return WEAPON_VORTEX_MURDER;
}
+METHOD(Vortex, wr_zoom, bool(entity thiswep, entity actor))
+{
+ return PHYS_INPUT_BUTTON_ATCK2(actor) && !WEP_CVAR(vortex, secondary);
+}
#endif
#ifdef CSQC
precache_pic("gfx/reticle_nex");
}
}
-METHOD(Vortex, wr_zoomreticle, bool(entity thiswep))
+METHOD(Vortex, wr_zoom, bool(entity thiswep, entity actor))
{
if(button_zoom || zoomscript_caught || (!WEP_CVAR(vortex, secondary) && button_attack2))
{
- reticle_image = "gfx/reticle_nex";
return true;
}
else
--- /dev/null
+#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;
+.float w_m_alpha;
+.float w_vortex_charge;
+.int w_m_gunalign;
+
+// #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()); }) \
+ \
+ PROP(false, m_alpha, WEPENT_SET_NORMAL, \
+ { WriteByte(chan, this.m_alpha * 16); }, \
+ { (viewmodels[this.m_wepent_slot]).alpha = ReadByte() / 16; }) \
+ \
+ PROP(false, vortex_charge, WEPENT_SET_NORMAL, \
+ { WriteByte(chan, this.vortex_charge * 16); }, \
+ { (viewmodels[this.m_wepent_slot]).vortex_charge = ReadByte() / 16; }) \
+ \
+ PROP(false, m_gunalign, WEPENT_SET_NORMAL, \
+ { WriteByte(chan, this.m_gunalign); }, \
+ { (viewmodels[this.m_wepent_slot]).m_gunalign = 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
--- /dev/null
+#pragma once
+
+REGISTER_NET_LINKED(ENT_CLIENT_WEPENT)
+REGISTER_NET_TEMP(CLIENT_WEPENT)
+
+.float vortex_charge;
+
+#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
.float wpcost;
.int wpflags;
-bool bot_aim(entity this, float shotspeed, float shotspeedupward, float maxshottime, float applygravity);
+bool bot_aim(entity this, .entity weaponentity, float shotspeed, float shotspeedupward, float maxshottime, float applygravity);
void bot_clientconnect(entity this);
void bot_clientdisconnect(entity this);
void bot_cmdhelp(string scmd);
return targorigin + targvelocity * (shotdelay + vlen(targorigin - shotorg) / shotspeed);
}
-bool bot_aim(entity this, float shotspeed, float shotspeedupward, float maxshottime, bool applygravity)
+bool bot_aim(entity this, .entity weaponentity, float shotspeed, float shotspeedupward, float maxshottime, bool applygravity)
{
float f, r, hf, distanceratio;
vector v;
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);
float bot_shouldattack(entity this, entity targ);
float bot_aimdir(entity this, vector v, float maxfiredeviation);
-bool bot_aim(entity this, float shotspeed, float shotspeedupward, float maxshottime, bool applygravity);
+bool bot_aim(entity this, .entity weaponentity, float shotspeed, float shotspeedupward, float maxshottime, bool applygravity);
float findtrajectorywithleading(vector org, vector m1, vector m2, entity targ, float shotspeed, float shotspeedupward, float maxtime, float shotdelay, entity ignore);
vector bot_shotlead(vector targorigin, vector targvelocity, float shotspeed, float shotdelay);
return;
havocbot_chooseenemy(this);
- if (this.bot_chooseweapontime < time )
+
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
{
- this.bot_chooseweapontime = time + autocvar_bot_ai_chooseweaponinterval;
- havocbot_chooseweapon(this);
+ .entity weaponentity = weaponentities[slot];
+ if(this.(weaponentity).m_weapon != WEP_Null || slot == 0)
+ if(this.(weaponentity).bot_chooseweapontime < time)
+ {
+ this.(weaponentity).bot_chooseweapontime = time + autocvar_bot_ai_chooseweaponinterval;
+ havocbot_chooseweapon(this, weaponentity);
+ }
}
havocbot_aim(this);
lag_update(this);
if(this.weapons)
{
- Weapon w = PS(this).m_weapon;
- w.wr_aim(w, this);
if (autocvar_bot_nofire || IS_INDEPENDENT_PLAYER(this))
{
PHYS_INPUT_BUTTON_ATCK(this) = false;
}
else
{
- if(PHYS_INPUT_BUTTON_ATCK(this) || PHYS_INPUT_BUTTON_ATCK2(this))
- this.lastfiredweapon = PS(this).m_weapon.m_id;
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ Weapon w = this.(weaponentity).m_weapon;
+ if(w == WEP_Null && slot != 0)
+ continue;
+ w.wr_aim(w, this, weaponentity);
+ if(PHYS_INPUT_BUTTON_ATCK(this) || PHYS_INPUT_BUTTON_ATCK2(this)) // TODO: what if we didn't fire this weapon, but the previous?
+ this.(weaponentity).lastfiredweapon = this.(weaponentity).m_weapon.m_id;
+ }
}
}
else
// if the bot is not attacking, consider reloading weapons
if (!(this.aistatus & AI_STATUS_ATTACKING))
{
- // we are currently holding a weapon that's not fully loaded, reload it
- if(skill >= 2) // bots can only reload the held weapon on purpose past this skill
- if(this.clip_load < this.clip_size)
- this.impulse = 20; // "press" the reload button, not sure if this is done right
-
- // if we're not reloading a weapon, switch to any weapon in our invnetory that's not fully loaded to reload it next
- // the code above executes next frame, starting the reloading then
- 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
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
{
- 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;
- ));
+ .entity weaponentity = weaponentities[slot];
+
+ if(this.(weaponentity).m_weapon == WEP_Null && slot != 0)
+ continue;
+
+ // we are currently holding a weapon that's not fully loaded, reload it
+ if(skill >= 2) // bots can only reload the held weapon on purpose past this skill
+ if(this.(weaponentity).clip_load < this.(weaponentity).clip_size)
+ this.impulse = 20; // "press" the reload button, not sure if this is done right
+
+ // if we're not reloading a weapon, switch to any weapon in our invnetory that's not fully loaded to reload it next
+ // the code above executes next frame, starting the reloading then
+ if(skill >= 5) // bots can only look for unloaded weapons past this skill
+ if(this.(weaponentity).clip_load >= 0) // only if we're not reloading a weapon already
+ {
+ FOREACH(Weapons, it != WEP_Null, LAMBDA(
+ if((this.weapons & (it.m_wepset)) && (it.spawnflags & WEP_FLAG_RELOADABLE) && (this.(weaponentity).weapon_load[it.m_id] < it.reloading_ammo))
+ this.(weaponentity).m_switchweapon = it;
+ ));
+ }
}
}
}
else if(this.health>WEP_CVAR(devastator, damage)*0.5)
{
if(this.velocity.z < 0)
- if(client_hasweapon(this, WEP_DEVASTATOR, true, false))
{
- this.movement_x = maxspeed;
-
- if(this.rocketjumptime)
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
{
- if(time > this.rocketjumptime)
+ .entity weaponentity = weaponentities[slot];
+
+ if(this.(weaponentity).m_weapon == WEP_Null && slot != 0)
+ continue;
+
+ if(client_hasweapon(this, WEP_DEVASTATOR, weaponentity, true, false))
{
- PHYS_INPUT_BUTTON_ATCK2(this) = true;
- this.rocketjumptime = 0;
+ this.movement_x = maxspeed;
+
+ if(this.rocketjumptime)
+ {
+ if(time > this.rocketjumptime)
+ {
+ PHYS_INPUT_BUTTON_ATCK2(this) = true;
+ this.rocketjumptime = 0;
+ }
+ return;
+ }
+
+ this.(weaponentity).m_switchweapon = WEP_DEVASTATOR;
+ this.v_angle_x = 90;
+ PHYS_INPUT_BUTTON_ATCK(this) = true;
+ this.rocketjumptime = time + WEP_CVAR(devastator, detonatedelay);
+ return;
}
- return;
}
-
- PS(this).m_switchweapon = WEP_DEVASTATOR;
- this.v_angle_x = 90;
- PHYS_INPUT_BUTTON_ATCK(this) = true;
- this.rocketjumptime = time + WEP_CVAR(devastator, detonatedelay);
- return;
}
}
else
this.havocbot_stickenemy = false;
}
-float havocbot_chooseweapon_checkreload(entity this, int new_weapon)
+float havocbot_chooseweapon_checkreload(entity this, .entity weaponentity, int new_weapon)
{
// bots under this skill cannot find unloaded weapons to reload idly when not in combat,
// so skip this for them, or they'll never get to reload their weapons at all.
return false;
// if this weapon is scheduled for reloading, don't switch to it during combat
- if (this.weapon_load[new_weapon] < 0)
+ if (this.(weaponentity).weapon_load[new_weapon] < 0)
{
bool other_weapon_available = false;
FOREACH(Weapons, it != WEP_Null, LAMBDA(
- if(it.wr_checkammo1(it, this) + it.wr_checkammo2(it, this))
+ if(it.wr_checkammo1(it, this, weaponentity) + it.wr_checkammo2(it, this, weaponentity))
other_weapon_available = true;
));
if(other_weapon_available)
return false;
}
-void havocbot_chooseweapon(entity this)
+void havocbot_chooseweapon(entity this, .entity weaponentity)
{
int i;
// ;)
if(g_weaponarena_weapons == WEPSET(TUBA))
{
- PS(this).m_switchweapon = WEP_TUBA;
+ this.(weaponentity).m_switchweapon = WEP_TUBA;
return;
}
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))
+ if(client_hasweapon(this, it, weaponentity, true, false))
{
- PS(this).m_switchweapon = it;
+ this.(weaponentity).m_switchweapon = it;
return;
}
));
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.(weaponentity).lastfiredweapon)
if(af > combo_time)
{
combo = true;
if ( distance > bot_distance_far ) {
for(i=0; i < Weapons_COUNT && bot_weapons_far[i] != -1 ; ++i){
w = bot_weapons_far[i];
- if ( client_hasweapon(this, Weapons_from(w), true, false) )
+ if ( client_hasweapon(this, Weapons_from(w), weaponentity, 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, weaponentity, w))
continue;
- PS(this).m_switchweapon = Weapons_from(w);
+ this.(weaponentity).m_switchweapon = Weapons_from(w);
return;
}
}
if ( distance > bot_distance_close) {
for(i=0; i < Weapons_COUNT && bot_weapons_mid[i] != -1 ; ++i){
w = bot_weapons_mid[i];
- if ( client_hasweapon(this, Weapons_from(w), true, false) )
+ if ( client_hasweapon(this, Weapons_from(w), weaponentity, 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, weaponentity, w))
continue;
- PS(this).m_switchweapon = Weapons_from(w);
+ this.(weaponentity).m_switchweapon = Weapons_from(w);
return;
}
}
// Choose weapons for close distance
for(i=0; i < Weapons_COUNT && bot_weapons_close[i] != -1 ; ++i){
w = bot_weapons_close[i];
- if ( client_hasweapon(this, Weapons_from(w), true, false) )
+ if ( client_hasweapon(this, Weapons_from(w), weaponentity, 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, weaponentity, w))
continue;
- PS(this).m_switchweapon = Weapons_from(w);
+ this.(weaponentity).m_switchweapon = Weapons_from(w);
return;
}
}
void havocbot_movetogoal(entity this);
void havocbot_chooserole(entity this);
void havocbot_chooseenemy(entity this);
-void havocbot_chooseweapon(entity this);
+void havocbot_chooseweapon(entity this, .entity weaponentity);
void havocbot_bunnyhop(entity this, vector dir);
void havocbot_keyboard_movement(entity this, vector destorg);
if(id < WEP_FIRST || id > WEP_LAST)
return CMD_STATUS_ERROR;
- if(client_hasweapon(this, Weapons_from(id), true, false))
- PS(this).m_switchweapon = Weapons_from(id);
+ .entity weaponentity = weaponentities[0]; // TODO: unhardcode
+
+ if(client_hasweapon(this, Weapons_from(id), weaponentity, true, false))
+ this.(weaponentity).m_switchweapon = Weapons_from(id);
else
return CMD_STATUS_ERROR;
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)
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)
+ else if(this.(weaponentity).tuba_note)
{
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
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");
}
}
#include "bot_null.qh"
#if 0
-bool bot_aim(entity this, float shotspeed, float shotspeedupward, float maxshottime, float applygravity) { return false; }
+bool bot_aim(entity this, .entity weaponentity, float shotspeed, float shotspeedupward, float maxshottime, float applygravity) { return false; }
void bot_clientconnect(entity this) { }
void bot_clientdisconnect(entity this) { }
void bot_cmdhelp(string scmd) { }
#include "bot/api.qh"
#include "../common/ent_cs.qh"
+#include "../common/wepent.qh"
#include <common/state.qh>
#include <common/effects/qc/globalsound.qh>
this.view_ofs = '0 0 0';
}
- RemoveGrapplingHook(this);
+ RemoveGrapplingHooks(this);
Portal_ClearAll(this);
Unfreeze(this);
SetSpectatee(this, NULL);
this.istypefrag = 0;
setthink(this, func_null);
this.nextthink = 0;
- this.hook_time = 0;
this.deadflag = DEAD_NO;
this.crouch = false;
this.revival_time = 0;
this.weapons = '0 0 0';
this.drawonlytoclient = this;
- this.weaponname = "";
this.weaponmodel = "";
for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
{
+ this.weaponentities[slot].hook_time = 0;
+ this.weaponentities[slot].weaponname = "";
this.weaponentities[slot] = NULL;
}
this.exteriorweaponentity = NULL;
for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
{
- CL_SpawnWeaponentity(this, weaponentities[slot]);
+ .entity weaponentity = weaponentities[slot];
+ CL_SpawnWeaponentity(this, weaponentity);
}
this.alpha = default_player_alpha;
this.colormod = '1 1 1' * autocvar_g_player_brightness;
it.wr_resetplayer(it, this);
// reload all reloadable weapons
if (it.spawnflags & WEP_FLAG_RELOADABLE) {
- this.weapon_load[it.m_id] = it.reloading_ammo;
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ this.(weaponentity).weapon_load[it.m_id] = it.reloading_ammo;
+ }
}
));
delete(spot); // usefull for checking if there are spawnpoints, that let drop through the floor
}
- PS(this).m_switchweapon = w_getbestweapon(this);
- this.cnt = -1; // W_LastWeapon will not complain
- PS(this).m_weapon = WEP_Null;
- this.weaponname = "";
- PS(this).m_switchingweapon = WEP_Null;
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(slot == 0)
+ this.(weaponentity).m_switchweapon = w_getbestweapon(this, weaponentity);
+ else
+ this.(weaponentity).m_switchweapon = WEP_Null;
+ this.(weaponentity).m_weapon = WEP_Null;
+ this.(weaponentity).weaponname = "";
+ this.(weaponentity).m_switchingweapon = WEP_Null;
+ this.(weaponentity).cnt = -1;
+ }
if (!warmup_stage && !this.alivetime)
this.alivetime = time;
Unfreeze(this);
- RemoveGrapplingHook(this);
+ RemoveGrapplingHooks(this);
// Here, everything has been done that requires this player to be a client.
{
this.items &= ~this.items_added;
- //for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
- //{
- //.entity weaponentity = weaponentities[slot];
- //W_WeaponFrame(this, weaponentity);
- //}
- .entity weaponentity = weaponentities[0]; // TODO
- W_WeaponFrame(this, weaponentity);
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ W_WeaponFrame(this, weaponentity);
+
+ if(slot == 0)
+ {
+ this.clip_load = this.(weaponentity).clip_load;
+ this.clip_size = this.(weaponentity).clip_size;
+ }
+ }
this.items_added = 0;
if (this.items & ITEM_Jetpack.m_itemid && (this.items & ITEM_JetpackRegen.m_itemid || this.ammo_fuel >= 0.01))
// WEAPONTODO: Add a weapon request for this
// rot vortex charge to the charge limit
- if (WEP_CVAR(vortex, charge_rot_rate) && this.vortex_charge > WEP_CVAR(vortex, charge_limit) && this.vortex_charge_rottime < time)
- this.vortex_charge = bound(WEP_CVAR(vortex, charge_limit), this.vortex_charge - WEP_CVAR(vortex, charge_rot_rate) * frametime / W_TICSPERFRAME, 1);
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if (WEP_CVAR(vortex, charge_rot_rate) && this.(weaponentity).vortex_charge > WEP_CVAR(vortex, charge_limit) && this.(weaponentity).vortex_charge_rottime < time)
+ this.(weaponentity).vortex_charge = bound(WEP_CVAR(vortex, charge_limit), this.(weaponentity).vortex_charge - WEP_CVAR(vortex, charge_rot_rate) * frametime / W_TICSPERFRAME, 1);
+ }
if (frametime) player_anim(this);
// WEAPONTODO: Add weapon request for this
if (!zoomstate_set) {
- SetZoomState(this,
- PHYS_INPUT_BUTTON_ZOOM(this) || PHYS_INPUT_BUTTON_ZOOMSCRIPT(this)
- || (PHYS_INPUT_BUTTON_ATCK2(this) && PS(this).m_weapon == WEP_VORTEX)
- || (PHYS_INPUT_BUTTON_ATCK2(this) && PS(this).m_weapon == WEP_RIFLE && WEP_CVAR(rifle, secondary) == 0)
- );
+ bool wep_zoomed = false;
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ Weapon thiswep = this.(weaponentity).m_weapon;
+ if(thiswep != WEP_Null && thiswep.wr_zoom)
+ wep_zoomed += thiswep.wr_zoom(thiswep, this);
+ }
+ SetZoomState(this, PHYS_INPUT_BUTTON_ZOOM(this) || PHYS_INPUT_BUTTON_ZOOMSCRIPT(this) || wep_zoomed);
}
if (this.teamkill_soundtime && time > this.teamkill_soundtime)
// WEAPONTODO: Move into weaponsystem somehow
// if a player goes unarmed after holding a loaded weapon, empty his clip size and remove the crosshair ammo ring
- if (PS(this).m_weapon == WEP_Null)
- this.clip_load = this.clip_size = 0;
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(this.(weaponentity).m_weapon == WEP_Null)
+ this.(weaponentity).clip_load = this.(weaponentity).clip_size = 0;
+ }
}
void DrownPlayer(entity this)
// WEAPONTODO
.float autoswitch;
-bool client_hasweapon(entity this, Weapon wpn, float andammo, bool complain);
+bool client_hasweapon(entity this, Weapon wpn, .entity weaponentity, float andammo, bool complain);
void w_clear(Weapon thiswep, entity actor, .entity weaponentity, int fire);
void w_ready(Weapon thiswep, entity actor, .entity weaponentity, int fire);
// VorteX: standalone think for weapons, so normal think on weaponentity can be reserved by weaponflashes (which needs update even player dies)
#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;
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?
{
}
// 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), weaponentity);
}
// FIXME fix the mess this is (we have REAL points now!)
string AppendItemcodes(string s, entity player)
{
- int w = PS(player).m_weapon.m_id;
- //if(w == 0)
- // w = player.switchweapon;
- if(w == 0)
- w = player.cnt; // previous weapon!
- s = strcat(s, ftos(w));
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ int w = player.(weaponentity).m_weapon.m_id;
+ if(w == 0)
+ w = player.(weaponentity).cnt; // previous weapon
+ if(w != 0 || slot == 0)
+ s = strcat(s, ftos(w));
+ }
if(time < player.strength_finished)
s = strcat(s, "S");
if(time < player.invincible_finished)
Ice_Think(ice);
- RemoveGrapplingHook(targ);
+ RemoveGrapplingHooks(targ);
- FOREACH_CLIENT(IS_PLAYER(it) && it.hook.aiment == targ, LAMBDA(RemoveGrapplingHook(it)));
+ FOREACH_CLIENT(IS_PLAYER(it),
+ {
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(it.(weaponentity).hook.aiment == targ)
+ RemoveHook(it.(weaponentity).hook);
+ }
+ });
// add waypoint
if(show_waypoint)
WaypointSprite_Kill(targ.waypointsprite_attached);
- FOREACH_CLIENT(IS_PLAYER(it) && it.hook.aiment == targ, LAMBDA(RemoveGrapplingHook(it)));
+ FOREACH_CLIENT(IS_PLAYER(it),
+ {
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(it.(weaponentity).hook.aiment == targ)
+ RemoveHook(it.(weaponentity).hook);
+ }
+ });
// remove the ice block
if(targ.iceblock)
attacker_save = attacker;
if(IS_PLAYER(targ))
- if(targ.hook)
- if(targ.hook.aiment)
- if(targ.hook.aiment == attacker)
- RemoveGrapplingHook(targ); // STOP THAT, you parasite!
+ {
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(targ.(weaponentity).hook && targ.(weaponentity).hook.aiment == attacker)
+ RemoveHook(targ.(weaponentity).hook);
+ }
+ }
// special rule: gravity bomb does not hit team mates (other than for disconnecting the hook)
if(DEATH_ISWEAPON(deathtype, WEP_HOOK) || DEATH_ISWEAPON(deathtype, WEP_TUBA))
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);
.float hook_length;
-void RemoveGrapplingHook(entity pl)
+void RemoveGrapplingHooks(entity pl)
{
- if(pl.hook == NULL)
- return;
- delete(pl.hook);
- pl.hook = NULL;
if(pl.move_movetype == MOVETYPE_FLY)
set_movetype(pl, MOVETYPE_WALK);
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(pl.(weaponentity).hook)
+ {
+ delete(pl.(weaponentity).hook);
+ pl.(weaponentity).hook = NULL;
+ }
+ }
+
//pl.disableclientprediction = false;
}
+void RemoveHook(entity this)
+{
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(this.realowner.(weaponentity).hook == this)
+ this.realowner.(weaponentity).hook = NULL;
+ }
+
+ if(this.realowner.move_movetype == MOVETYPE_FLY)
+ set_movetype(this.realowner, MOVETYPE_WALK);
+ delete(this);
+}
+
void GrapplingHookReset(entity this)
{
- if(this.realowner.hook == this)
- RemoveGrapplingHook(this.owner);
- else // in any case:
- delete(this);
+ RemoveHook(this);
}
void GrapplingHookThink(entity this);
if(sf & 1)
{
WriteByte(MSG_ENTITY, etof(this.realowner));
+ WriteByte(MSG_ENTITY, weaponslot(this.weaponentity_fld));
}
if(sf & 2)
{
{
float spd, dist, minlength, pullspeed, ropestretch, ropeairfriction, rubberforce, newlength, rubberforce_overstretch;
vector dir, org, end, v0, dv, v, myorg, vs;
- if(this.realowner.hook != this) // how did that happen?
+ .entity weaponentity = this.weaponentity_fld;
+ if(this.realowner.(weaponentity).hook != this) // how did that happen?
{
error("Owner lost the hook!\n");
return;
}
if(LostMovetypeFollow(this) || intermission_running || (round_handler_IsActive() && !round_handler_IsRoundStarted()) || ((this.aiment.flags & FL_PROJECTILE) && this.aiment.classname != "nade"))
{
- RemoveGrapplingHook(this.realowner);
+ RemoveHook(this);
return;
}
if(this.aiment)
this.nextthink = time;
- int s = W_GetGunAlignment(this.realowner);
+ int s = W_GunAlign(this.realowner.(weaponentity), STAT(GUNALIGN, this.realowner)) - 1;
vs = hook_shotorigin[s];
makevectors(this.realowner.v_angle);
v = v0 = WarpZone_RefSys_TransformVelocity(pull_entity, this, pull_entity.velocity);
// first pull the rope...
- if(this.realowner.hook_state & HOOK_PULLING)
+ if(this.realowner.(weaponentity).hook_state & HOOK_PULLING)
{
newlength = this.hook_length;
newlength = max(newlength - pullspeed * frametime, minlength);
if(pull_entity.move_movetype == MOVETYPE_FLY)
set_movetype(pull_entity, MOVETYPE_WALK);
- if(this.realowner.hook_state & HOOK_RELEASING)
+ if(this.realowner.(weaponentity).hook_state & HOOK_RELEASING)
{
newlength = dist;
this.hook_length = newlength;
if(frozen_pulling && autocvar_g_balance_grapplehook_pull_frozen == 2 && !STAT(FROZEN, this.aiment))
{
- RemoveGrapplingHook(this.realowner);
+ RemoveHook(this);
return;
}
}
this.realowner.pushltime = time + autocvar_g_maxpushtime;
this.realowner.istypefrag = PHYS_INPUT_BUTTON_CHAT(this.realowner);
}
- RemoveGrapplingHook(this.realowner);
+ RemoveHook(this);
}
}
-void FireGrapplingHook(entity actor)
+void FireGrapplingHook(entity actor, .entity weaponentity)
{
- entity missile;
- vector org;
- vector vs;
-
if(forbidWeaponUse(actor)) return;
if(actor.vehicle) return;
makevectors(actor.v_angle);
- int s = W_GetGunAlignment(actor);
- vs = hook_shotorigin[s];
+ int s = W_GunAlign(actor.(weaponentity), STAT(GUNALIGN, actor)) - 1;
+ vector vs = hook_shotorigin[s];
// UGLY WORKAROUND: play this on CH_WEAPON_B so it can't cut off fire sounds
sound (actor, CH_WEAPON_B, SND_HOOK_FIRE, VOL_BASE, ATTEN_NORM);
- org = actor.origin + actor.view_ofs + v_forward * vs.x + v_right * -vs.y + v_up * vs.z;
+ vector org = actor.origin + actor.view_ofs + v_forward * vs.x + v_right * -vs.y + v_up * vs.z;
tracebox(actor.origin + actor.view_ofs, '-3 -3 -3', '3 3 3', org, MOVE_NORMAL, actor);
org = trace_endpos;
Send_Effect(EFFECT_HOOK_MUZZLEFLASH, org, '0 0 0', 1);
- missile = WarpZone_RefSys_SpawnSameRefSys(actor);
+ entity missile = WarpZone_RefSys_SpawnSameRefSys(actor);
missile.owner = missile.realowner = actor;
- actor.hook = missile;
+ actor.(weaponentity).hook = missile;
+ missile.weaponentity_fld = weaponentity;
missile.reset = GrapplingHookReset;
missile.classname = "grapplinghook";
missile.flags = FL_PROJECTILE;
// Wazat's grappling hook
.entity hook;
-void RemoveGrapplingHook(entity pl);
+void RemoveGrapplingHooks(entity pl);
+void RemoveHook(entity this);
// (note: you can change the hook impulse #'s to whatever you please)
.float hook_time;
{
antilag_record(it, it, altime);
});
- FOREACH_CLIENT(PS(it), {
- PlayerState s = PS(it);
- s.ps_push(s, it);
- });
systems_update();
IL_ENDFRAME();
}
// weapon switching impulses
+bool autocvar_g_weaponswitch_debug;
+
#define X(slot) \
IMPULSE(weapon_group_##slot) \
{ \
this.impulse = IMP_weapon_group_##slot.impulse; \
return; \
} \
- W_NextWeaponOnImpulse(this, slot); \
+ for(int wepslot = 0; wepslot < MAX_WEAPONSLOTS; ++wepslot) \
+ { \
+ .entity weaponentity = weaponentities[wepslot]; \
+ W_NextWeaponOnImpulse(this, slot, weaponentity); \
+ if(wepslot == 0 && !autocvar_g_weaponswitch_debug) \
+ break; \
+ } \
}
X(1)
X(2)
noref int prev = -1; \
noref int best = 0; \
noref int next = +1; \
- W_CycleWeapon(this, this.cvar_cl_weaponpriorities[slot], dir); \
+ for(int wepslot = 0; wepslot < MAX_WEAPONSLOTS; ++wepslot) \
+ { \
+ .entity weaponentity = weaponentities[wepslot]; \
+ W_CycleWeapon(this, this.cvar_cl_weaponpriorities[slot], dir, weaponentity); \
+ if(wepslot == 0 && !autocvar_g_weaponswitch_debug) \
+ break; \
+ } \
}
X(0, prev)
X(1, prev)
this.impulse = IMP_weapon_byid_##i.impulse; \
return; \
} \
- W_SwitchWeapon(this, Weapons_from(WEP_FIRST + i)); \
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) \
+ { \
+ .entity weaponentity = weaponentities[slot]; \
+ W_SwitchWeapon(this, Weapons_from(WEP_FIRST + i), weaponentity); \
+ if(slot == 0 && !autocvar_g_weaponswitch_debug) \
+ break; \
+ } \
}
X(0)
X(1)
this.impulse = IMP_weapon_next_byid.impulse;
return;
}
- W_NextWeapon(this, 0);
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ W_NextWeapon(this, 0, weaponentity);
+
+ if(slot == 0 && !autocvar_g_weaponswitch_debug)
+ break;
+ }
}
IMPULSE(weapon_prev_byid)
this.impulse = IMP_weapon_prev_byid.impulse;
return;
}
- W_PreviousWeapon(this, 0);
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ W_PreviousWeapon(this, 0, weaponentity);
+
+ if(slot == 0 && !autocvar_g_weaponswitch_debug)
+ break;
+ }
}
IMPULSE(weapon_next_bygroup)
this.impulse = IMP_weapon_next_bygroup.impulse;
return;
}
- W_NextWeapon(this, 1);
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ W_NextWeapon(this, 1, weaponentity);
+
+ if(slot == 0 && !autocvar_g_weaponswitch_debug)
+ break;
+ }
}
IMPULSE(weapon_prev_bygroup)
this.impulse = IMP_weapon_prev_bygroup.impulse;
return;
}
- W_PreviousWeapon(this, 1);
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ W_PreviousWeapon(this, 1, weaponentity);
+
+ if(slot == 0 && !autocvar_g_weaponswitch_debug)
+ break;
+ }
}
IMPULSE(weapon_next_bypriority)
this.impulse = IMP_weapon_next_bypriority.impulse;
return;
}
- W_NextWeapon(this, 2);
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ W_NextWeapon(this, 2, weaponentity);
+
+ if(slot == 0 && !autocvar_g_weaponswitch_debug)
+ break;
+ }
}
IMPULSE(weapon_prev_bypriority)
this.impulse = IMP_weapon_prev_bypriority.impulse;
return;
}
- W_PreviousWeapon(this, 2);
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ W_PreviousWeapon(this, 2, weaponentity);
+
+ if(slot == 0 && !autocvar_g_weaponswitch_debug)
+ break;
+ }
}
IMPULSE(weapon_last)
{
if (this.vehicle) return;
if (IS_DEAD(this)) return;
- W_LastWeapon(this);
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ W_LastWeapon(this, weaponentity);
+
+ if(slot == 0 && !autocvar_g_weaponswitch_debug)
+ break;
+ }
}
IMPULSE(weapon_best)
{
if (this.vehicle) return;
if (IS_DEAD(this)) return;
- W_SwitchWeapon(this, w_getbestweapon(this));
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ W_SwitchWeapon(this, w_getbestweapon(this, weaponentity), weaponentity);
+
+ if(slot == 0 && !autocvar_g_weaponswitch_debug)
+ break;
+ }
}
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);
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ W_ThrowWeapon(this, weaponentity, W_CalculateProjectileVelocity(this, this.velocity, v_forward * 750, false), '0 0 0', true);
+
+ if(slot == 0 && !autocvar_g_weaponswitch_debug)
+ break;
+ }
}
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);
+
+ if(slot == 0 && !autocvar_g_weaponswitch_debug)
+ break;
}
}
replacement = substring(msg, p, 2);
escape = substring(msg, p + 1, 1);
+ .entity weaponentity = weaponentities[0]; // TODO: unhardcode
+
switch(escape)
{
case "%": replacement = "%"; break;
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.(weaponentity).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;
if (f > 0)
{
if (s == "cl_weaponpriority")
- if (PS(this)) PS(this).m_switchweapon = w_getbestweapon(this);
+ {
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if (this.(weaponentity) && (this.(weaponentity).m_weapon != WEP_Null || slot == 0))
+ this.(weaponentity).m_switchweapon = w_getbestweapon(this, weaponentity);
+ }
+ }
if (s == "cl_allow_uidtracking")
PlayerStats_GameReport_AddPlayer(this);
}
if(this.classname == "nade")
return false; // no checks here
else if(this.classname == "grapplinghook")
- RemoveGrapplingHook(this.realowner);
+ RemoveHook(this);
else if(this.classname == "spike")
{
W_Crylink_Dequeue(this);
/** returns true if throwing the current weapon shall not be allowed */
#define EV_ForbidThrowCurrentWeapon(i, o) \
/** player */ i(entity, MUTATOR_ARGV_0_entity) \
+ /** weapon entity */ i(entity, MUTATOR_ARGV_1_entity) \
/**/
MUTATOR_HOOKABLE(ForbidThrowCurrentWeapon, EV_ForbidThrowCurrentWeapon);
/** returns true if dropping the current weapon shall not be allowed at any time including death */
#define EV_ForbidDropCurrentWeapon(i, o) \
- /** player */ i(entity, MUTATOR_ARGV_0_entity) \
+ /** player */ i(entity, MUTATOR_ARGV_0_entity) \
+ /** weapon id */ i(int, MUTATOR_ARGV_1_int) \
/**/
MUTATOR_HOOKABLE(ForbidDropCurrentWeapon, EV_ForbidDropCurrentWeapon);
* Called by W_DecreaseAmmo
*/
#define EV_W_DecreaseAmmo(i, o) \
- /** actor */ i(entity, MUTATOR_ARGV_0_entity) \
+ /** actor */ i(entity, MUTATOR_ARGV_0_entity) \
+ /** weapon entity */ i(entity, MUTATOR_ARGV_1_entity) \
/**/
MUTATOR_HOOKABLE(W_DecreaseAmmo, EV_W_DecreaseAmmo);
valid_damage_for_weaponstats = 0;
Weapon awep = WEP_Null;
+ .entity weaponentity = weaponentities[0]; // TODO: unhardcode
if(vbot || IS_REAL_CLIENT(this))
if(abot || IS_REAL_CLIENT(attacker))
if(DIFF_TEAM(this, attacker))
{
if(DEATH_ISSPECIAL(deathtype))
- awep = PS(attacker).m_weapon;
+ awep = attacker.(weaponentity).m_weapon;
else
awep = DEATH_WEAPONOF(deathtype);
valid_damage_for_weaponstats = 1;
da = da - max(this.armorvalue, 0);
if(valid_damage_for_weaponstats)
{
- WeaponStats_LogDamage(awep.m_id, abot, PS(this).m_weapon.m_id, vbot, dh + da);
+ WeaponStats_LogDamage(awep.m_id, abot, this.(weaponentity).m_weapon.m_id, vbot, dh + da);
}
if (dh + da)
{
}
if(valid_damage_for_weaponstats)
- WeaponStats_LogKill(awep.m_id, abot, PS(this).m_weapon.m_id, vbot);
+ WeaponStats_LogKill(awep.m_id, abot, this.(weaponentity).m_weapon.m_id, vbot);
if(autocvar_sv_gentle < 1)
if(sound_allowed(MSG_BROADCAST, attacker))
MUTATOR_CALLHOOK(PlayerDies, inflictor, attacker, this, deathtype, damage);
excess = M_ARGV(4, float);
- Weapon wep = PS(this).m_weapon;
- /*for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ Weapon wep = this.(weaponentity).m_weapon;
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
{
- .entity weaponentity = weaponentities[slot];
- wep.wr_playerdeath(wep, this, weaponentity);
- }*/
- .entity weaponentity = weaponentities[0]; // TODO: unhardcode
- wep.wr_playerdeath(wep, this, weaponentity);
+ .entity wepent = weaponentities[slot];
+ wep.wr_playerdeath(wep, this, wepent);
+ }
- RemoveGrapplingHook(this);
+ RemoveGrapplingHooks(this);
Portal_ClearAllLater(this);
// clear waypoints
WaypointSprite_PlayerDead(this);
// throw a weapon
- SpawnThrownWeapon(this, this.origin + (this.mins + this.maxs) * 0.5, PS(this).m_switchweapon.m_id);
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity wepent = weaponentities[slot];
+ SpawnThrownWeapon(this, this.origin + (this.mins + this.maxs) * 0.5, this.(wepent).m_switchweapon.m_id, wepent);
+ }
// become fully visible
this.alpha = default_player_alpha;
if(it != o || time >= this.portal_activatetime)
Portal_Think_TryTeleportPlayer(this, it, g);
- if(it.hook)
- Portal_Think_TryTeleportPlayer(this, it.hook, g);
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(it.(weaponentity).hook)
+ Portal_Think_TryTeleportPlayer(this, it.(weaponentity).hook, g);
+ }
));
this.solid = SOLID_TRIGGER;
this.aiment = o;
{
// check for falling damage
float velocity_len = vlen(this.velocity);
- if(!this.hook.state)
+ bool have_hook = false;
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(this.(weaponentity).hook && this.(weaponentity).hook.state)
+ {
+ have_hook = true;
+ break;
+ }
+ }
+ if(!have_hook)
{
float dm = vlen(this.oldvelocity) - velocity_len; // dm is now the velocity DECREASE. Velocity INCREASE should never cause a sound or any damage.
if (IS_DEAD(this))
it.items |= IT_UNLIMITED_AMMO;
Weapon wep = WEP_VORTEX;
W_GiveWeapon(it, wep.m_id);
- W_SwitchWeapon_Force(it, wep);
+ W_SwitchWeapon_Force(it, wep, weaponentities[0]);
it = b;
PHYS_INPUT_BUTTON_JUMP(it) = true;
return ret;
}
-void W_HitPlotAnalysis(entity player, vector screenforward, vector screenright, vector screenup)
+void W_HitPlotAnalysis(entity player, .entity weaponentity, vector screenforward, vector screenright, vector screenup)
{
vector hitplot;
vector org;
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"));
+ 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"));
}
}
.float hitplotfh;
-void W_HitPlotAnalysis(entity player, vector screenforward, vector screenright, vector screenup);
+void W_HitPlotAnalysis(entity player, .entity weaponentity, vector screenforward, vector screenright, vector screenup);
void W_HitPlotOpen(entity player);
void W_HitPlotClose(entity player);
});
}
-bool client_hasweapon(entity this, Weapon wpn, float andammo, bool complain)
+bool client_hasweapon(entity this, Weapon wpn, .entity weaponentity, float andammo, bool complain)
{
float f = 0;
}
else
{
- f = wpn.wr_checkammo1(wpn, this) + wpn.wr_checkammo2(wpn, this);
+ f = wpn.wr_checkammo1(wpn, this, weaponentity) + wpn.wr_checkammo2(wpn, this, weaponentity);
// always allow selecting the Mine Layer if we placed mines, so that we can detonate them
if(wpn == WEP_MINE_LAYER)
- IL_EACH(g_mines, it.owner == this,
+ IL_EACH(g_mines, it.owner == this && it.weaponentity_fld == weaponentity,
{
f = 1;
break; // no need to continue
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.
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;
++c;
- if(!skipmissing || client_hasweapon(this, wep, true, false))
+ if(!skipmissing || client_hasweapon(this, wep, weaponentity, true, false))
{
if(switchtonext)
return weaponwant;
--c;
if(c == 0)
{
- client_hasweapon(this, wep, true, true);
+ client_hasweapon(this, wep, weaponentity, true, true);
break;
}
}
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;
- ww = w_getbestweapon(this);
+ ww = w_getbestweapon(this, weaponentity);
this.weapons |= set;
}
else
{
- ww = w_getbestweapon(this);
+ ww = w_getbestweapon(this, weaponentity);
}
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, weaponentity, 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);
+ Weapon wep = Weapons_from(this.(weaponentity).cnt);
+ if (client_hasweapon(this, wep, weaponentity, true, false))
+ W_SwitchWeapon(this, wep, weaponentity);
else
- W_SwitchToOtherWeapon(this);
+ W_SwitchToOtherWeapon(this, weaponentity);
}
void Send_WeaponComplain(entity e, float wpn, float type);
.float hasweapon_complain_spam;
-bool client_hasweapon(entity this, Weapon wpn, float andammo, bool complain);
+bool client_hasweapon(entity this, Weapon wpn, .entity weaponentity, 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))
+#define w_getbestweapon(ent,wepent) Weapons_from(W_GetCycleWeapon(ent, ent.cvar_cl_weaponpriority, 0, -1, false, true, wepent))
-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);
}
// 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;
wep.owner = wep.enemy = own;
wep.flags |= FL_TOSSED;
wep.colormap = own.colormap;
- wep.glowmod = weaponentity_glowmod(info, own, own.clientcolors);
+ wep.glowmod = weaponentity_glowmod(info, own, own.clientcolors, own.(weaponentity));
- W_DropEvent(wr_drop,own,wpn,wep);
+ W_DropEvent(wr_drop,own,wpn,wep,weaponentity);
if(WepSet_FromWeapon(Weapons_from(wpn)) & WEPSET_SUPERWEAPONS)
{
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;
- if(own.(weapon_load[i]) > 0)
+ int i = own.(weaponentity).m_weapon.m_id;
+ if(own.(weaponentity).(weapon_load[i]) > 0)
{
- own.(ammotype) += own.(weapon_load[i]);
- own.(weapon_load[i]) = -1; // schedule the weapon for reloading
+ own.(ammotype) += own.(weaponentity).(weapon_load[i]);
+ own.(weaponentity).(weapon_load[i]) = -1; // schedule the weapon for reloading
}
wep.(ammotype) = 0;
else if(doreduce)
{
// if our weapon is loaded, give its load back to the player
- int i = PS(own).m_weapon.m_id;
- if(own.(weapon_load[i]) > 0)
+ int i = own.(weaponentity).m_weapon.m_id;
+ if(own.(weaponentity).(weapon_load[i]) > 0)
{
- own.(ammotype) += own.(weapon_load[i]);
- own.(weapon_load[i]) = -1; // schedule the weapon for reloading
+ own.(ammotype) += own.(weaponentity).(weapon_load[i]);
+ own.(weaponentity).(weapon_load[i]) = -1; // schedule the weapon for reloading
}
thisammo = min(own.(ammotype), wep.(ammotype));
bool W_IsWeaponThrowable(entity this, int w)
{
- if (MUTATOR_CALLHOOK(ForbidDropCurrentWeapon, this))
+ if (MUTATOR_CALLHOOK(ForbidDropCurrentWeapon, this, w))
return false;
if (!autocvar_g_pickup_items)
return false;
// 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))
+ if(MUTATOR_CALLHOOK(ForbidThrowCurrentWeapon, this, this.(weaponentity)))
return;
if(!autocvar_g_weapon_throwable)
return;
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), 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');
+ entity wep = this.(weaponentity).m_weapon;
+
+ if(this.weapons & WepSet_FromWeapon(wep))
+ if(W_IsWeaponThrowable(this, wep.m_id))
+ W_ThrowNewWeapon(this, wep.m_id, false, org, randomvec() * 125 + '0 0 200', weaponentity);
}
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);
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;
// 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);
+ W_HitPlotAnalysis(ent, weaponentity, v_forward, v_right, v_up);
vector md = ent.(weaponentity).movedir;
if(md.x > 0)
// 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;
}
// 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;
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;
// 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);
}
}
.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);
return ret;
}
-..entity weaponentity_fld;
.float m_alpha;
+.string w_weaponname;
+.int w_dmg;
+.int w_deadflag;
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
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);
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 = "";
else if (this.owner.alpha != 0) this.alpha = this.owner.alpha;
else this.alpha = 1;
- Weapon wep = PS(this.owner).m_weapon;
- if (wep) this.glowmod = weaponentity_glowmod(wep, this.owner, this.owner.clientcolors);
+ Weapon wep = this.owner.(weaponentity).m_weapon;
+ if (wep) this.glowmod = weaponentity_glowmod(wep, this.owner, this.owner.clientcolors, this.owner.(weaponentity));
this.colormap = this.owner.colormap;
CSQCMODEL_AUTOUPDATE(this);
view.viewmodelforclient = actor;
setcefc(view, CL_Weaponentity_CustomizeEntityForClient);
- if (weaponentity == weaponentities[0])
+ wepent_link(view);
+
+ if (weaponentity == weaponentities[0]) // only one exterior model, thank you very much
{
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;
// 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)
{
.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;
- if (secondary) ammo = thiswep.wr_checkammo2(thiswep, actor);
- else ammo = thiswep.wr_checkammo1(thiswep, actor);
+ if (secondary) ammo = thiswep.wr_checkammo2(thiswep, actor, weaponentity);
+ else ammo = thiswep.wr_checkammo1(thiswep, actor, weaponentity);
if (ammo) return true;
// always keep the Mine Layer if we placed mines, so that we can detonate them
if (thiswep == WEP_MINE_LAYER)
{
- IL_EACH(g_mines, it.owner == actor,
+ IL_EACH(g_mines, it.owner == actor && it.weaponentity_fld == weaponentity,
{
return false;
});
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;
// check if the other firing mode has enough ammo
bool ammo_other = false;
- if (secondary) ammo_other = thiswep.wr_checkammo1(thiswep, actor);
- else ammo_other = thiswep.wr_checkammo2(thiswep, actor);
+ if (secondary) ammo_other = thiswep.wr_checkammo1(thiswep, actor, weaponentity);
+ else ammo_other = thiswep.wr_checkammo2(thiswep, actor, weaponentity);
if (ammo_other)
{
if (time - actor.prevwarntime > 1)
}
else // this weapon is totally unable to fire, switch to another one
{
- W_SwitchToOtherWeapon(actor);
+ W_SwitchToOtherWeapon(actor, weaponentity);
}
return false;
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
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)
{
int slot = weaponslot(weaponentity);
// don't fire if previous attack is not finished
- if (ATTACK_FINISHED(actor, slot) > time + actor.weapon_frametime * 0.5) return false;
+ if (ATTACK_FINISHED(actor, slot) > time + actor.(weaponentity).weapon_frametime * 0.5) return false;
entity this = actor.(weaponentity);
// don't fire while changing weapon
if (this.state != WS_READY) return false;
if (attacktime >= 0)
{
int slot = weaponslot(weaponentity);
- if (ATTACK_FINISHED(actor, slot) < time - actor.weapon_frametime * 1.5)
+ if (ATTACK_FINISHED(actor, slot) < time - this.weapon_frametime * 1.5)
{
ATTACK_FINISHED(actor, slot) = time;
// dprint("resetting attack finished to ", ftos(time), "\n");
}
ATTACK_FINISHED(actor, slot) = ATTACK_FINISHED(actor, slot) + attacktime * W_WeaponRateFactor(actor);
}
- actor.bulletcounter += 1;
+ this.bulletcounter += 1;
// dprint("attack finished ", ftos(ATTACK_FINISHED(actor, slot)), "\n");
}
this.weapon_nextthink = time;
// dprint("started firing at ", ftos(time), "\n");
}
- if (this.weapon_nextthink < time - actor.weapon_frametime * 1.5
- || this.weapon_nextthink > time + actor.weapon_frametime * 1.5)
+ if (this.weapon_nextthink < time - this.weapon_frametime * 1.5
+ || this.weapon_nextthink > time + this.weapon_frametime * 1.5)
{
this.weapon_nextthink = time;
// 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");
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 && (this.m_weapon.spawnflags & WEP_TYPE_MELEE_PRI));
+ bool secondary_melee = boolean(fr == WFRAME_FIRE2 && (this.m_weapon.spawnflags & WEP_TYPE_MELEE_SEC));
int act = (primary_melee || secondary_melee)
? ANIMACTION_MELEE
: ANIMACTION_SHOOT
TC(Player, actor);
TC(PlayerState, PS(actor));
entity this = actor.(weaponentity);
- if (frametime) actor.weapon_frametime = frametime;
+ if (frametime) this.weapon_frametime = frametime;
if (!this || actor.health < 1) return; // Dead player can't use weapons and injure impulse commands
if (forbidWeaponUse(actor))
{
- if (actor.(weaponentity).state != WS_CLEAR)
+ if (this.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;
}
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)
{
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;
- actor.bulletcounter = 0;
- actor.ammo_field = newwep.ammo_field;
- newwep.wr_setup(newwep, actor);
+ this.m_weapon = newwep;
+ this.weaponname = newwep.mdl;
+ this.bulletcounter = 0;
+ newwep.wr_setup(newwep, actor, weaponentity);
this.state = WS_RAISE;
// set our clip load to the load of the weapon we switched to, if it's reloadable
if ((newwep.spawnflags & WEP_FLAG_RELOADABLE) && newwep.reloading_ammo) // prevent accessing undefined cvars
{
- actor.clip_load = actor.(weapon_load[PS(actor).m_switchweapon.m_id]);
- actor.clip_size = newwep.reloading_ammo;
+ this.clip_load = this.(weapon_load[this.m_switchweapon.m_id]);
+ this.clip_size = newwep.reloading_ammo;
}
else
{
- actor.clip_load = actor.clip_size = 0;
+ this.clip_load = this.clip_size = 0;
}
weapon_thinkf(actor, weaponentity, WFRAME_IDLE, newwep.switchdelay_raise, w_ready);
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)
+ if (INDEPENDENT_ATTACK_FINISHED || ATTACK_FINISHED(actor, weaponslot(weaponentity)) <= time + this.weapon_frametime * 0.5)
{
sound(actor, CH_WEAPON_SINGLE, SND_WEAPON_SWITCH, VOL_BASE, ATTN_NORM);
this.state = WS_DROP;
// 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
{
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), weaponentity);
w = WEP_Null;
}
}
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);
}
}
if (!block_weapon)
{
- Weapon e = PS(actor).m_weapon;
+ Weapon e = this.m_weapon;
TC(Weapon, e);
if (w != WEP_Null)
{
}
}
- if (time + actor.weapon_frametime * 0.5 >= this.weapon_nextthink)
+ if (time + this.weapon_frametime * 0.5 >= this.weapon_nextthink)
{
if (this.weapon_think)
{
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));
}
}
}
-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;
+ if (MUTATOR_CALLHOOK(W_DecreaseAmmo, actor, actor.(weaponentity))) return;
if ((actor.items & IT_UNLIMITED_WEAPON_AMMO) && !wep.reloading_ammo) return;
// if this weapon is reloadable, decrease its load. Else decrease the player's ammo
if (wep.reloading_ammo)
{
- actor.clip_load -= ammo_use;
- actor.(weapon_load[PS(actor).m_weapon.m_id]) = actor.clip_load;
+ actor.(weaponentity).clip_load -= ammo_use;
+ actor.(weaponentity).(weapon_load[actor.(weaponentity).m_weapon.m_id]) = actor.(weaponentity).clip_load;
}
else if (wep.ammo_field != ammo_none)
{
{
// finish the reloading process, and do the ammo transfer
- actor.clip_load = actor.old_clip_load; // restore the ammo counter, in case we still had ammo in the weapon before reloading
+ Weapon wpn = actor.(weaponentity).m_weapon;
+
+ actor.(weaponentity).clip_load = actor.(weaponentity).old_clip_load; // restore the ammo counter, in case we still had ammo in the weapon before reloading
// if the gun uses no ammo, max out weapon load, else decrease ammo as we increase weapon load
- if (!actor.reload_ammo_min || actor.items & IT_UNLIMITED_WEAPON_AMMO || actor.ammo_field == ammo_none)
+ if (!actor.(weaponentity).reload_ammo_min || (actor.items & IT_UNLIMITED_WEAPON_AMMO) || wpn.ammo_field == ammo_none)
{
- actor.clip_load = actor.reload_ammo_amount;
+ actor.(weaponentity).clip_load = actor.(weaponentity).reload_ammo_amount;
}
else
{
// make sure we don't add more ammo than we have
- float load = min(actor.reload_ammo_amount - actor.clip_load, actor.(actor.ammo_field));
- actor.clip_load += load;
- actor.(actor.ammo_field) -= load;
+ float load = min(actor.(weaponentity).reload_ammo_amount - actor.(weaponentity).clip_load, actor.(wpn.ammo_field));
+ actor.(weaponentity).clip_load += load;
+ actor.(wpn.ammo_field) -= load;
}
- actor.(weapon_load[PS(actor).m_weapon.m_id]) = actor.clip_load;
+ actor.(weaponentity).(weapon_load[actor.(weaponentity).m_weapon.m_id]) = actor.(weaponentity).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,
// so your weapon is disabled for a few seconds without reason
- // ATTACK_FINISHED(actor, slot) -= actor.reload_time - 1;
+ // ATTACK_FINISHED(actor, slot) -= actor.(weaponentity).reload_time - 1;
- Weapon wpn = Weapons_from(PS(actor).m_weapon.m_id);
w_ready(wpn, actor, weaponentity, PHYS_INPUT_BUTTON_ATCK(actor) | (PHYS_INPUT_BUTTON_ATCK2(actor) << 1));
}
{
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;
- actor.reload_ammo_min = sent_ammo_min;
- actor.reload_ammo_amount = e.reloading_ammo;
- actor.reload_time = e.reloading_time;
+ actor.(weaponentity).reload_ammo_min = sent_ammo_min;
+ actor.(weaponentity).reload_ammo_amount = e.reloading_ammo;
+ actor.(weaponentity).reload_time = e.reloading_time;
if (actor.reload_sound) strunzone(actor.reload_sound);
actor.reload_sound = strzone(Sound_fixpath(sent_sound));
}
// return if reloading is disabled for this weapon
- if (!actor.reload_ammo_amount) return;
+ if (!actor.(weaponentity).reload_ammo_amount) return;
// our weapon is fully loaded, no need to reload
- if (actor.clip_load >= actor.reload_ammo_amount) return;
+ if (actor.(weaponentity).clip_load >= actor.(weaponentity).reload_ammo_amount) return;
// no ammo, so nothing to load
- if (actor.ammo_field != ammo_none)
+ if (e.ammo_field != ammo_none)
{
- if (!actor.(actor.ammo_field) && actor.reload_ammo_min)
+ if (!actor.(e.ammo_field) && actor.(weaponentity).reload_ammo_min)
{
if (!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
{
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;
- if (!(w.wr_checkammo1(w, actor) + w.wr_checkammo2(w, actor)))
+ if (!(e.wr_checkammo1(e, actor, weaponentity) + e.wr_checkammo2(e, actor, weaponentity)))
{
- actor.clip_load = -1; // reload later
- W_SwitchToOtherWeapon(actor);
+ actor.(weaponentity).clip_load = -1; // reload later
+ W_SwitchToOtherWeapon(actor, weaponentity);
}
return;
}
// then quickly switch to another weapon and back. Reloading is canceled, but the reload delay is still there,
// so your weapon is disabled for a few seconds without reason
- // ATTACK_FINISHED(actor, slot) = max(time, ATTACK_FINISHED(actor, slot)) + actor.reload_time + 1;
+ // ATTACK_FINISHED(actor, slot) = max(time, ATTACK_FINISHED(actor, slot)) + actor.(weaponentity).reload_time + 1;
- weapon_thinkf(actor, weaponentity, WFRAME_RELOAD, actor.reload_time, W_ReloadedAndReady);
+ weapon_thinkf(actor, weaponentity, WFRAME_RELOAD, this.reload_time, W_ReloadedAndReady);
- 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;
+ if (this.clip_load < 0) this.clip_load = 0;
+ this.old_clip_load = this.clip_load;
+ this.clip_load = this.(weapon_load[this.m_weapon.m_id]) = -1;
}
-void W_DropEvent(.void(Weapon, entity actor) event, entity player, float weapon_type, entity weapon_item)
+void W_DropEvent(.void(Weapon, entity actor, .entity) event, entity player, float weapon_type, entity weapon_item, .entity weaponentity)
{
Weapon w = Weapons_from(weapon_type);
weapon_dropevent_item = weapon_item;
- w.event(w, player);
+ w.event(w, player, weaponentity);
}
float weaponswapping;
entity weapon_dropevent_item;
+..entity weaponentity_fld;
+
void CL_SpawnWeaponentity(entity e, .entity weaponentity);
vector CL_Weapon_GetShotOrg(float wpn);
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);
+void W_DropEvent(.void(Weapon, entity actor, .entity) event, entity player, float weapon_type, entity weapon_item, .entity weaponentity);
void W_Reload(entity actor, .entity weaponentity, float sent_ammo_min, Sound sent_sound);