X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fweapons%2Fweaponsystem.qc;h=f8949b15601919e1b863084a1e5653ab3f94d9c2;hb=e57fd111a3279a4aa4789e2c72f9c819a56c7be9;hp=3b51adb9986fa511b556321f36d7563ae1d8119c;hpb=bc6fe08d1d10d513d52efb1ab57a27d6086b8397;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/weapons/weaponsystem.qc b/qcsrc/server/weapons/weaponsystem.qc index 3b51adb99..f8949b156 100644 --- a/qcsrc/server/weapons/weaponsystem.qc +++ b/qcsrc/server/weapons/weaponsystem.qc @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -69,12 +70,13 @@ vector CL_Weapon_GetShotOrg(int wpn) void CL_Weaponentity_Think(entity this) { this.nextthink = time; - if (intermission_running) this.frame = this.anim_idle.x; + if (game_stopped) this.frame = this.anim_idle.x; .entity weaponentity = this.weaponentity_fld; if (this.owner.(weaponentity) != this) { // owner has new gun; remove old one if (this.weaponchild) delete(this.weaponchild); + if (this.hook) delete(this.hook); delete(this); return; } @@ -108,15 +110,13 @@ void CL_Weaponentity_Think(entity this) this.weaponchild.alpha = this.alpha; this.weaponchild.effects = this.effects; } - - wepent_update(this); } void CL_ExteriorWeaponentity_Think(entity this) { this.nextthink = time; .entity weaponentity = this.weaponentity_fld; - entity wepent = this.owner.(weaponentity); + entity w_ent = this.owner.(weaponentity); if (this.owner.exteriorweaponentity != this) { delete(this); @@ -127,15 +127,15 @@ void CL_ExteriorWeaponentity_Think(entity this) this.model = ""; return; } - if (this.weaponname != wepent.weaponname || this.dmg != wepent.modelindex - || this.deadflag != wepent.deadflag) + if (this.weaponname != w_ent.weaponname || this.dmg != w_ent.modelindex + || this.deadflag != w_ent.deadflag) { - this.weaponname = wepent.weaponname; - this.dmg = wepent.modelindex; - this.deadflag = wepent.deadflag; - if (wepent.weaponname != "") + this.weaponname = w_ent.weaponname; + this.dmg = w_ent.modelindex; + this.deadflag = w_ent.deadflag; + if (w_ent.weaponname != "") { - _setmodel(this, W_Model(strcat("v_", wepent.weaponname, ".md3"))); + _setmodel(this, W_Model(strcat("v_", w_ent.weaponname, ".md3"))); setsize(this, '0 0 0', '0 0 0'); } else this.model = ""; @@ -393,10 +393,10 @@ void weapon_thinkf(entity actor, .entity weaponentity, WFRAME fr, float t, void( if (this) { - FOREACH_CLIENT(true, LAMBDA( + FOREACH_CLIENT(true, { if(it == actor || (IS_SPEC(it) && it.enemy == actor)) wframe_send(it, this, a, restartanim); - )); + }); } if ((fr == WFRAME_FIRE1 || fr == WFRAME_FIRE2) && t) @@ -418,11 +418,9 @@ void weapon_thinkf(entity actor, .entity weaponentity, WFRAME fr, float t, void( bool forbidWeaponUse(entity player) { if (time < game_starttime && !autocvar_sv_ready_restart_after_countdown) return true; - if (round_handler_IsActive() && !round_handler_IsRoundStarted()) return true; if (player.player_blocked) return true; - if (gameover) return true; + if (game_stopped) return true; if (STAT(FROZEN, player)) return true; - if (player.weapon_blocked) return true; if (MUTATOR_CALLHOOK(ForbidWeaponUse, player)) return true; return false; } @@ -438,13 +436,35 @@ void W_WeaponFrame(Player actor, .entity weaponentity) if (!this || actor.health < 1) return; // Dead player can't use weapons and injure impulse commands + int button_atck = PHYS_INPUT_BUTTON_ATCK(actor); + int button_atck2 = PHYS_INPUT_BUTTON_ATCK2(actor); + + if (round_handler_IsActive() && !round_handler_IsRoundStarted()) + button_atck = button_atck2 = 0; // forbid primary and secondary fire, switching is allowed if (forbidWeaponUse(actor)) { if (this.state != WS_CLEAR) { Weapon wpn = this.m_weapon; - w_ready(wpn, actor, weaponentity, PHYS_INPUT_BUTTON_ATCK(actor) | (PHYS_INPUT_BUTTON_ATCK2(actor) << 1)); + w_ready(wpn, actor, weaponentity, button_atck | (button_atck2 << 1)); + return; + } + } + + if(autocvar_g_weaponswitch_debug == 2 && weaponslot(weaponentity) > 0) + { + .entity wepe1 = weaponentities[0]; + entity wep1 = actor.(wepe1); + this.m_switchweapon = wep1.m_switchweapon; + entity store = IS_PLAYER(actor) ? PS(actor) : actor; + if(!(this.m_switchweapon.spawnflags & WEP_FLAG_DUALWIELD) && !(store.dual_weapons & wep1.m_switchweapon.m_wepset)) + { + this.m_weapon = WEP_Null; + this.m_switchingweapon = WEP_Null; + this.m_switchweapon = WEP_Null; + this.state = WS_CLEAR; + this.weaponname = ""; return; } } @@ -455,7 +475,6 @@ void W_WeaponFrame(Player actor, .entity weaponentity) this.m_switchingweapon = WEP_Null; this.state = WS_CLEAR; this.weaponname = ""; - // actor.items &= ~IT_AMMO; return; } @@ -499,7 +518,7 @@ void W_WeaponFrame(Player actor, .entity weaponentity) this.clip_load = this.clip_size = 0; } - weapon_thinkf(actor, weaponentity, WFRAME_IDLE, newwep.switchdelay_raise, w_ready); + weapon_thinkf(actor, weaponentity, WFRAME_DONTCHANGE, newwep.switchdelay_raise, w_ready); break; } case WS_DROP: @@ -550,6 +569,9 @@ void W_WeaponFrame(Player actor, .entity weaponentity) bool block_weapon = false; { bool key_pressed = PHYS_INPUT_BUTTON_HOOK(actor) && !actor.vehicle; + if (round_handler_IsActive() && !round_handler_IsRoundStarted()) + key_pressed = false; + Weapon off = actor.offhand; if (off && !(actor.weapons & WEPSET(HOOK))) { @@ -561,7 +583,7 @@ void W_WeaponFrame(Player actor, .entity weaponentity) W_SwitchWeapon(actor, WEP_HOOK, weaponentity); actor.hook_switchweapon = key_pressed; Weapon h = WEP_HOOK; - block_weapon = (this.m_weapon == h && (PHYS_INPUT_BUTTON_ATCK(actor) || key_pressed)); + block_weapon = (this.m_weapon == h && (button_atck || key_pressed)); h.wr_think(h, actor, weaponentity, block_weapon ? 1 : 0); } } @@ -576,7 +598,7 @@ void W_WeaponFrame(Player actor, .entity weaponentity) TC(Weapon, e); if (w != WEP_Null) { - e.wr_think(e, actor, weaponentity, PHYS_INPUT_BUTTON_ATCK(actor) | (PHYS_INPUT_BUTTON_ATCK2(actor) << 1)); + e.wr_think(e, actor, weaponentity, button_atck | (button_atck2 << 1)); } else if (e) { @@ -593,7 +615,7 @@ void W_WeaponFrame(Player actor, .entity weaponentity) v_up = up; Weapon wpn = this.m_weapon; this.weapon_think(wpn, actor, weaponentity, - PHYS_INPUT_BUTTON_ATCK(actor) | (PHYS_INPUT_BUTTON_ATCK2(actor) << 1)); + button_atck | (button_atck2 << 1)); } else { @@ -636,14 +658,15 @@ void W_AttachToShotorg(entity actor, .entity weaponentity, entity flash, vector void W_DecreaseAmmo(Weapon wep, entity actor, float ammo_use, .entity weaponentity) { if (MUTATOR_CALLHOOK(W_DecreaseAmmo, actor, actor.(weaponentity))) return; - if ((actor.items & IT_UNLIMITED_WEAPON_AMMO) && !wep.reloading_ammo) return; + entity w_ent = actor.(weaponentity); + // if this weapon is reloadable, decrease its load. Else decrease the player's ammo if (wep.reloading_ammo) { - actor.(weaponentity).clip_load -= ammo_use; - actor.(weaponentity).(weapon_load[actor.(weaponentity).m_weapon.m_id]) = actor.(weaponentity).clip_load; + w_ent.clip_load -= ammo_use; + w_ent.(weapon_load[w_ent.m_weapon.m_id]) = w_ent.clip_load; } else if (wep.ammo_field != ammo_none) { @@ -673,29 +696,30 @@ void W_ReloadedAndReady(Weapon thiswep, entity actor, .entity weaponentity, int { // finish the reloading process, and do the ammo transfer - Weapon wpn = actor.(weaponentity).m_weapon; + entity w_ent = actor.(weaponentity); + Weapon wpn = w_ent.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 + w_ent.clip_load = w_ent.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.(weaponentity).reload_ammo_min || (actor.items & IT_UNLIMITED_WEAPON_AMMO) || wpn.ammo_field == ammo_none) + if (!w_ent.reload_ammo_min || (actor.items & IT_UNLIMITED_WEAPON_AMMO) || wpn.ammo_field == ammo_none) { - actor.(weaponentity).clip_load = actor.(weaponentity).reload_ammo_amount; + w_ent.clip_load = w_ent.reload_ammo_amount; } else { // make sure we don't add more ammo than we have - float load = min(actor.(weaponentity).reload_ammo_amount - actor.(weaponentity).clip_load, actor.(wpn.ammo_field)); - actor.(weaponentity).clip_load += load; + float load = min(w_ent.reload_ammo_amount - w_ent.clip_load, actor.(wpn.ammo_field)); + w_ent.clip_load += load; actor.(wpn.ammo_field) -= load; } - actor.(weaponentity).(weapon_load[actor.(weaponentity).m_weapon.m_id]) = actor.(weaponentity).clip_load; + w_ent.(weapon_load[w_ent.m_weapon.m_id]) = w_ent.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.(weaponentity).reload_time - 1; + // ATTACK_FINISHED(actor, slot) -= w_ent.reload_time - 1; w_ready(wpn, actor, weaponentity, PHYS_INPUT_BUTTON_ATCK(actor) | (PHYS_INPUT_BUTTON_ATCK2(actor) << 1)); } @@ -704,13 +728,14 @@ void W_Reload(entity actor, .entity weaponentity, float sent_ammo_min, Sound sen { TC(Sound, sent_sound); // set global values to work with - Weapon e = actor.(weaponentity).m_weapon; + entity this = actor.(weaponentity); + Weapon e = this.m_weapon; if (MUTATOR_CALLHOOK(W_Reload, actor)) return; - actor.(weaponentity).reload_ammo_min = sent_ammo_min; - actor.(weaponentity).reload_ammo_amount = e.reloading_ammo; - actor.(weaponentity).reload_time = e.reloading_time; + this.reload_ammo_min = sent_ammo_min; + this.reload_ammo_amount = e.reloading_ammo; + this.reload_time = e.reloading_time; if (actor.reload_sound) strunzone(actor.reload_sound); actor.reload_sound = strzone(Sound_fixpath(sent_sound)); @@ -723,28 +748,28 @@ void W_Reload(entity actor, .entity weaponentity, float sent_ammo_min, Sound sen } // return if reloading is disabled for this weapon - if (!actor.(weaponentity).reload_ammo_amount) return; + if (!this.reload_ammo_amount) return; // our weapon is fully loaded, no need to reload - if (actor.(weaponentity).clip_load >= actor.(weaponentity).reload_ammo_amount) return; + if (this.clip_load >= this.reload_ammo_amount) return; // no ammo, so nothing to load if (e.ammo_field != ammo_none) { - if (!actor.(e.ammo_field) && actor.(weaponentity).reload_ammo_min) + if (!actor.(e.ammo_field) && this.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", actor.(weaponentity).m_weapon.m_name, "\n")); + sprint(actor, strcat("You don't have enough ammo to reload the ^2", this.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 if (!(e.wr_checkammo1(e, actor, weaponentity) + e.wr_checkammo2(e, actor, weaponentity))) { - actor.(weaponentity).clip_load = -1; // reload later + this.clip_load = -1; // reload later W_SwitchToOtherWeapon(actor, weaponentity); } return; @@ -752,7 +777,6 @@ void W_Reload(entity actor, .entity weaponentity, float sent_ammo_min, Sound sen } } - entity this = actor.(weaponentity); if (this) { if (this.wframe == WFRAME_RELOAD) return; @@ -769,7 +793,7 @@ void W_Reload(entity actor, .entity weaponentity, float sent_ammo_min, Sound sen // 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.(weaponentity).reload_time + 1; + // ATTACK_FINISHED(actor, slot) = max(time, ATTACK_FINISHED(actor, slot)) + this.reload_time + 1; weapon_thinkf(actor, weaponentity, WFRAME_RELOAD, this.reload_time, W_ReloadedAndReady);