]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/weapons/common.qc
Merge branch 'terencehill/cl_forceplayercolors_3' into 'master'
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / weapons / common.qc
1 #include "common.qh"
2
3 #include <common/weapons/_all.qh>
4 #include <common/stats.qh>
5 #include <server/damage.qh>
6 #include <server/items/items.qh>
7 #include <server/miscfunctions.qh>
8 #include <common/constants.qh>
9 #include <common/net_linked.qh>
10 #include <common/deathtypes/all.qh>
11 #include <common/notifications/all.qh>
12 #include <common/state.qh>
13 #include <common/util.qh>
14 #include <common/weapons/_all.qh>
15 #include <common/wepent.qh>
16 #include <common/items/_mod.qh>
17
18 bool W_DualWielding(entity player)
19 {
20         int held_weapons = 0;
21         for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
22         {
23                 .entity weaponentity = weaponentities[slot];
24                 if(player.(weaponentity) && player.(weaponentity).m_switchweapon != WEP_Null)
25                         ++held_weapons;
26         }
27
28         return held_weapons > 1;
29 }
30
31 void W_GiveWeapon(entity e, int wep)
32 {
33         if (!wep) return;
34
35         STAT(WEAPONS, e) |= WepSet_FromWeapon(REGISTRY_GET(Weapons, wep));
36
37         if (IS_PLAYER(e)) {
38             Send_Notification(NOTIF_ONE, e, MSG_MULTI, ITEM_WEAPON_GOT, wep);
39     }
40 }
41
42 void W_PlayStrengthSound(entity player)
43 {
44         entity store = IS_PLAYER(player) ? PS(player) : player; // because non-player entities can fire, but can they have items? TODO
45
46         if((player.items & ITEM_Strength.m_itemid)
47                 && ((time > store.prevstrengthsound + autocvar_sv_strengthsound_antispam_time) // prevent insane sound spam
48                 || (time > store.prevstrengthsoundattempt + autocvar_sv_strengthsound_antispam_refire_threshold)))
49                 {
50                         sound(player, CH_TRIGGER, SND_STRENGTH_FIRE, VOL_BASE, ATTEN_NORM);
51                         store.prevstrengthsound = time;
52                 }
53                 store.prevstrengthsoundattempt = time;
54 }
55
56 float W_CheckProjectileDamage(entity inflictor, entity projowner, int deathtype, float exception)
57 {
58         float is_from_contents = (deathtype == DEATH_SLIME.m_id || deathtype == DEATH_LAVA.m_id);
59         float is_from_owner = (inflictor == projowner);
60         float is_from_exception = (exception != -1);
61
62         //dprint(strcat("W_CheckProjectileDamage: from_contents ", ftos(is_from_contents), " : from_owner ", ftos(is_from_owner), " : exception ", strcat(ftos(is_from_exception), " (", ftos(exception), "). \n")));
63
64         if(autocvar_g_projectiles_damage <= -2)
65         {
66                 return false; // no damage to projectiles at all, not even with the exceptions
67         }
68         else if(autocvar_g_projectiles_damage == -1)
69         {
70                 if(is_from_exception)
71                         return (exception); // if exception is detected, allow it to override
72                 else
73                         return false; // otherwise, no other damage is allowed
74         }
75         else if(autocvar_g_projectiles_damage == 0)
76         {
77                 if(is_from_exception)
78                         return (exception); // if exception is detected, allow it to override
79                 else if(!is_from_contents)
80                         return false; // otherwise, only allow damage from contents
81         }
82         else if(autocvar_g_projectiles_damage == 1)
83         {
84                 if(is_from_exception)
85                         return (exception); // if exception is detected, allow it to override
86                 else if(!(is_from_contents || is_from_owner))
87                         return false; // otherwise, only allow self damage and damage from contents
88         }
89         else if(autocvar_g_projectiles_damage == 2) // allow any damage, but override for exceptions
90         {
91                 if(is_from_exception)
92                         return (exception); // if exception is detected, allow it to override
93         }
94
95         return true; // if none of these return, then allow damage anyway.
96 }
97
98 void W_PrepareExplosionByDamage(entity this, entity attacker, void(entity this) explode)
99 {
100         this.takedamage = DAMAGE_NO;
101         this.event_damage = func_null;
102
103         MUTATOR_CALLHOOK(PrepareExplosionByDamage, this, attacker);
104
105         if(IS_CLIENT(attacker) && !autocvar_g_projectiles_keep_owner)
106         {
107                 this.owner = attacker;
108                 this.realowner = attacker;
109         }
110
111         // do not explode NOW but in the NEXT FRAME!
112         // because recursive calls to RadiusDamage are not allowed
113         this.nextthink = time;
114         setthink(this, explode);
115 }