]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/weapons/weaponsystem.qc
Fix HMG
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / weapons / weaponsystem.qc
index 833d04ef1a33581cef1a102f26a1547ae640aacc..762f9a0e3dc12b619b531128366b6d9f0c36506f 100644 (file)
@@ -14,6 +14,10 @@ float W_WeaponRateFactor()
        float t;
        t = 1.0 / g_weaponratefactor;
 
+       weapon_rate = t;
+       MUTATOR_CALLHOOK(WeaponRateFactor);
+       t = weapon_rate;
+
        return t;
 }
 
@@ -87,25 +91,20 @@ float CL_Weaponentity_CustomizeEntityForClient()
 // to free:
 //   call again with ""
 //   remove the ent
-
-#define WEP_MODEL_FIRSTPERSON model // h_ // wep.WEP_MODEL_FIRSTPERSON
-#define WEP_MODEL_THIRDPERSON model2 // v_ // wep.WEP_MODEL_THIRDPERSON
-#define WEP_MODEL_PICKUP model3 // g_ // wep.WEP_MODEL_PICKUP
-#define WEP_MODEL_SIMPLE mdl
-void CL_WeaponEntity_SetModel(entity wep)
+void CL_WeaponEntity_SetModel(string name)
 {
        float v_shot_idx;
-       if(wep)
+       if (name != "")
        {
                // if there is a child entity, hide it until we're sure we use it
                if (self.weaponentity)
                        self.weaponentity.model = "";
-               setmodel(self, wep.WEP_MODEL_THIRDPERSON); // precision set below
+               setmodel(self, strcat("models/weapons/v_", name, ".md3")); // precision set below
                v_shot_idx = gettagindex(self, "shot"); // used later
                if(!v_shot_idx)
                        v_shot_idx = gettagindex(self, "tag_shot");
 
-               setmodel(self, wep.WEP_MODEL_FIRSTPERSON); // precision set below
+               setmodel(self, strcat("models/weapons/h_", name, ".iqm")); // precision set below
                // preset some defaults that work great for renamed zym files (which don't need an animinfo)
                self.anim_fire1  = animfixfps(self, '0 1 0.01', '0 0 0');
                self.anim_fire2  = animfixfps(self, '1 1 0.01', '0 0 0');
@@ -118,14 +117,14 @@ void CL_WeaponEntity_SetModel(entity wep)
                {
                        if (!self.weaponentity)
                                self.weaponentity = spawn();
-                       setmodel(self.weaponentity, wep.WEP_MODEL_THIRDPERSON); // precision does not matter
+                       setmodel(self.weaponentity, strcat("models/weapons/v_", name, ".md3")); // precision does not matter
                        setattachment(self.weaponentity, self, "weapon");
                }
                else if(gettagindex(self, "tag_weapon"))
                {
                        if (!self.weaponentity)
                                self.weaponentity = spawn();
-                       setmodel(self.weaponentity, wep.WEP_MODEL_THIRDPERSON); // precision does not matter
+                       setmodel(self.weaponentity, strcat("models/weapons/v_", name, ".md3")); // precision does not matter
                        setattachment(self.weaponentity, self, "tag_weapon");
                }
                else
@@ -253,13 +252,14 @@ void CL_WeaponEntity_SetModel(entity wep)
 
 vector CL_Weapon_GetShotOrg(float wpn)
 {
-       entity oldself;
+       entity wi, oldself;
        vector ret;
+       wi = get_weaponinfo(wpn);
        oldself = self;
        self = spawn();
-       CL_WeaponEntity_SetModel(get_weaponinfo(wpn));
+       CL_WeaponEntity_SetModel(wi.mdl);
        ret = self.movedir;
-       CL_WeaponEntity_SetModel(world);
+       CL_WeaponEntity_SetModel("");
        remove(self);
        self = oldself;
        return ret;
@@ -285,14 +285,13 @@ void CL_Weaponentity_Think()
                        self.weaponentity.model = "";
                return;
        }
-       if (self.weaponname != self.owner.weaponname || self.dmg != self.owner.modelindex || self.deadflag != self.owner.deadflag) // WEAPONTODO: get rid of .weaponname, handle model directly
+       if (self.weaponname != self.owner.weaponname || self.dmg != self.owner.modelindex || self.deadflag != self.owner.deadflag)
        {
                self.weaponname = self.owner.weaponname;
                self.dmg = self.owner.modelindex;
                self.deadflag = self.owner.deadflag;
 
-               // WEAPONTODO: get weapon entity from here!
-               //CL_WeaponEntity_SetModel(self.owner.weaponname);
+               CL_WeaponEntity_SetModel(self.owner.weaponname);
        }
 
        tb = (self.effects & (EF_TELEPORT_BIT | EF_RESTARTANIM_BIT));
@@ -459,6 +458,10 @@ float weapon_prepareattack_checkammo(float secondary)
                for(mine = world; (mine = find(mine, classname, "mine")); ) if(mine.owner == self)
                        return FALSE;
 
+               if(self.weapon == WEP_SHOTGUN)
+               if(!secondary && WEP_CVAR(shotgun, secondary) == 1)
+                       return FALSE; // no clicking, just allow
+
                if(self.weapon == self.switchweapon && time - self.prevdryfire > 1) // only play once BEFORE starting to switch weapons
                {
                        sound (self, CH_WEAPON_A, "weapons/dryfire.wav", VOL_BASE, ATTEN_NORM);
@@ -636,7 +639,9 @@ float forbidWeaponUse()
                return 1;
        if(self.player_blocked)
                return 1;
-       if(self.freezetag_frozen)
+       if(self.frozen)
+               return 1;
+       if(self.weapon_blocked)
                return 1;
        return 0;
 }
@@ -682,13 +687,10 @@ void W_WeaponFrame()
                        self.switchingweapon = self.switchweapon;
                        entity newwep = get_weaponinfo(self.switchweapon);
 
-                       //self.items &= ~IT_AMMO;
-                       //self.items = self.items | (newwep.items & IT_AMMO);
-
                        // the two weapon entities will notice this has changed and update their models
                        self.weapon = self.switchweapon;
                        self.weaponname = newwep.mdl;
-                       self.bulletcounter = 0; // WEAPONTODO
+                       self.bulletcounter = 0;
                        //self.ammo_field = newwep.ammo_field;
                        WEP_ACTION(self.switchweapon, WR_SETUP);
                        self.weaponentity.state = WS_RAISE;
@@ -702,10 +704,7 @@ void W_WeaponFrame()
                        else
                                self.clip_load = self.clip_size = 0;
 
-                       // VorteX: add player model weapon select frame here
-                       // setcustomframe(PlayerWeaponRaise);
                        weapon_thinkf(WFRAME_IDLE, newwep.switchdelay_raise, w_ready);
-                       //print(sprintf("W_WeaponFrame(): cvar: %s, value: %f\n", sprintf("g_balance_%s_switchdelay_raise", newwep.netname), cvar(sprintf("g_balance_%s_switchdelay_raise", newwep.netname))));
                }
                else if (self.weaponentity.state == WS_DROP)
                {
@@ -716,21 +715,19 @@ void W_WeaponFrame()
                {
                        // start switching!
                        self.switchingweapon = self.switchweapon;
-
                        entity oldwep = get_weaponinfo(self.weapon);
-                       
-#ifndef INDEPENDENT_ATTACK_FINISHED
+
+                       // set up weapon switch think in the future, and start drop anim
+                       #ifndef INDEPENDENT_ATTACK_FINISHED
                        if(ATTACK_FINISHED(self) <= time + self.weapon_frametime * 0.5)
                        {
-#endif
-                       sound (self, CH_WEAPON_SINGLE, "weapons/weapon_switch.wav", VOL_BASE, ATTN_NORM);
-                       self.weaponentity.state = WS_DROP;
-                       // set up weapon switch think in the future, and start drop anim
-                       weapon_thinkf(WFRAME_DONTCHANGE, oldwep.switchdelay_drop, w_clear);
-                       //print(sprintf("W_WeaponFrame(): cvar: %s, value: %f\n", sprintf("g_balance_%s_switchdelay_drop", oldwep.netname), cvar(sprintf("g_balance_%s_switchdelay_drop", oldwep.netname))));
-#ifndef INDEPENDENT_ATTACK_FINISHED
+                       #endif
+                               sound(self, CH_WEAPON_SINGLE, "weapons/weapon_switch.wav", VOL_BASE, ATTN_NORM);
+                               self.weaponentity.state = WS_DROP;
+                               weapon_thinkf(WFRAME_DONTCHANGE, oldwep.switchdelay_drop, w_clear);
+                       #ifndef INDEPENDENT_ATTACK_FINISHED
                        }
-#endif
+                       #endif
                }
        }
 
@@ -816,6 +813,13 @@ void W_DecreaseAmmo(float ammo_use)
 {
        entity wep = get_weaponinfo(self.weapon);
 
+       if(cvar("g_overkill"))
+       if(self.ok_use_ammocharge)
+       {
+               ok_DecreaseCharge(self, self.weapon);
+               return; // TODO
+       }
+
        if((self.items & IT_UNLIMITED_WEAPON_AMMO) && !wep.reloading_ammo)
                return;
 
@@ -825,8 +829,22 @@ void W_DecreaseAmmo(float ammo_use)
                self.clip_load -= ammo_use;
                self.(weapon_load[self.weapon]) = self.clip_load;
        }
-       else
+       else if(wep.ammo_field != ammo_none)
+       {
                self.(wep.ammo_field) -= ammo_use;
+               if(self.(wep.ammo_field) < 0)
+               {
+                       backtrace(sprintf(
+                               "W_DecreaseAmmo(%.2f): '%s' subtracted too much %s from '%s', resulting with '%.2f' left... "
+                               "Please notify Samual immediately with a copy of this backtrace!\n",
+                               ammo_use,
+                               wep.netname,
+                               GetAmmoPicture(wep.ammo_field),
+                               self.netname,
+                               self.(wep.ammo_field)
+                       ));
+               }
+       }
 }
 
 // weapon reloading code
@@ -869,6 +887,10 @@ void W_Reload(float sent_ammo_min, string sent_sound)
        entity e;
        e = get_weaponinfo(self.weapon);
 
+       if(cvar("g_overkill"))
+       if(self.ok_use_ammocharge)
+               return; // TODO
+
        self.reload_ammo_min = sent_ammo_min;
        self.reload_ammo_amount = e.reloading_ammo;;
        self.reload_time = e.reloading_time;
@@ -935,3 +957,13 @@ void W_Reload(float sent_ammo_min, string sent_sound)
        self.old_clip_load = self.clip_load;
        self.clip_load = self.(weapon_load[self.weapon]) = -1;
 }
+
+entity weapon_dropevent_item;
+void W_DropEvent(float event, entity player, float weapon_type, entity weapon_item)
+{
+       entity oldself = self;
+       self = player;
+       weapon_dropevent_item = weapon_item;
+       WEP_ACTION(weapon_type, event);
+       self = oldself;
+}