]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/weapons/spawning.qc
b14579e24e3bbae667b168caa110e2b7ad7fdd81
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / weapons / spawning.qc
1 #include "spawning.qh"
2
3 #include <common/resources/sv_resources.qh>
4 #include <common/weapons/_all.qh>
5 #include <server/items/items.qh>
6 #include <server/items/spawning.qh>
7 #include <server/mutators/_mod.qh>
8 #include <server/weapons/weaponsystem.qh>
9 #include <server/world.qh>
10
11 .bool m_isreplaced; ///< Holds whether the weapon has been replaced.
12
13 string W_Apply_Weaponreplace(string in)
14 {
15         string out = "";
16         FOREACH_WORD(in, true, {
17                 string replacement = "";
18                 Weapon w = Weapon_from_name(it);
19                 if (w)
20                 {
21             replacement = w.weaponreplace;
22             if (replacement == "") replacement = it;
23                 }
24                 if (replacement == "0") continue;
25                 out = cons(out, replacement);
26         });
27         return out;
28 }
29
30 void weapon_defaultspawnfunc(entity this, Weapon wpn)
31 {
32         wpn = wpn.m_spawnfunc_hookreplace(wpn, this);
33         this.classname = wpn.m_canonical_spawnfunc;
34         if (!Item_IsLoot(this) && !this.m_isreplaced)
35         {
36                 if (wpn.spawnflags & WEP_FLAG_MUTATORBLOCKED)
37                 {
38                         //LOG_WARNF("Attempted to spawn a mutator-blocked weapon rejected: prvm_edict server %i", this);
39                         startitem_failed = true;
40                         return;
41                 }
42
43                 string s = W_Apply_Weaponreplace(wpn.netname);
44                 MUTATOR_CALLHOOK(SetWeaponreplace, this, wpn, s);
45                 s = M_ARGV(2, string);
46                 if (s == "")
47                 {
48                         delete(this);
49                         startitem_failed = true;
50                         return;
51                 }
52                 int t = tokenize_console(s);
53                 if (t >= 2)
54                 {
55                         this.team = --internalteam;
56                         for (int i = 1; i < t; ++i)
57                         {
58                                 s = argv(i);
59                                 Weapon wep = Weapon_from_name(s);
60                                 if(wep != WEP_Null)
61                                 {
62                                         entity replacement = spawn();
63                                         Item_CopyFields(this, replacement);
64                                         // copyentity is an engine function which unintentionally copies intrusive list data
65                                         // DO NOTE USE, causes #2792
66                                         //copyentity(this, replacement);
67                                         replacement.m_isreplaced = true;
68                                         weapon_defaultspawnfunc(replacement, wep);
69                                 }
70                         }
71                 }
72                 if (t >= 1) // always the case!
73                 {
74                         s = argv(0);
75                         wpn = Weapon_from_name(s);
76                 }
77                 if (wpn == WEP_Null)
78                 {
79                         delete(this);
80                         startitem_failed = true;
81                         return;
82                 }
83         }
84
85         if(!Item_IsLoot(this))
86                 weaponsInMapAll |= WepSet_FromWeapon(wpn);
87
88         if (!Item_IsDefinitionAllowed(wpn.m_pickup))
89         {
90                 delete(this);
91                 startitem_failed = true;
92                 return;
93         }
94
95         if (!this.respawntime)
96         {
97                 if (wpn.spawnflags & WEP_FLAG_SUPERWEAPON)
98                 {
99                         this.respawntime = g_pickup_respawntime_superweapon;
100                         this.respawntimejitter = g_pickup_respawntimejitter_superweapon;
101                 }
102                 else
103                 {
104                         this.respawntime = g_pickup_respawntime_weapon;
105                         this.respawntimejitter = g_pickup_respawntimejitter_weapon;
106                 }
107         }
108
109         if (wpn.spawnflags & WEP_FLAG_SUPERWEAPON)
110                 if (!this.superweapons_finished)
111                         this.superweapons_finished = autocvar_g_balance_superweapons_time;
112
113         // if we don't already have ammo, give us some ammo
114         // TODO: registry handles
115         if ((wpn.ammo_type != RES_NONE) && !GetResource(this, wpn.ammo_type))
116         {
117                 int ammo = 0;
118                 if (q3compat && this.count > 0)
119                         ammo = this.count * GetAmmoConsumptionQ3(wpn.netname);
120                         // WEAPONTODO: magazines of MG, rifle and OK weapons are unaccounted for
121                 else
122                 {
123                         switch (wpn.ammo_type)
124                         {
125                                 case RES_SHELLS:  ammo = cvar("g_pickup_shells_weapon");  break;
126                                 case RES_BULLETS: ammo = cvar("g_pickup_nails_weapon");   break;
127                                 case RES_ROCKETS: ammo = cvar("g_pickup_rockets_weapon"); break;
128                                 case RES_CELLS:   ammo = cvar("g_pickup_cells_weapon");   break;
129                                 case RES_PLASMA:  ammo = cvar("g_pickup_plasma_weapon");  break;
130                                 case RES_FUEL:    ammo = cvar("g_pickup_fuel_weapon");    break;
131                         }
132                 }
133
134                 SetResource(this, wpn.ammo_type, ammo);
135         }
136
137         #if 0 // WEAPONTODO
138         if (wpn.items)
139         {
140                 for (int i = 0, j = 1; i < 24; ++i, j <<= 1)
141                 {
142                         if (wpn.items & j)
143                         {
144                                 ammotype = Item_CounterField(j);
145                                 if (!this.ammotype)
146                                         this.ammotype = cvar(strcat("g_pickup_", Item_CounterFieldName(j), "_weapon"));
147                         }
148                 }
149         }
150         #endif
151
152         // pickup anyway
153         if (g_pickup_weapons_anyway)
154                 this.pickup_anyway = true;
155
156         if(!this.owner)
157                 this.glowmod = wpn.wpcolor;
158         else
159                 this.glowmod = colormapPaletteColor(this.owner.clientcolors & 0x0F, true);
160
161         GameItem def = wpn.m_pickup;
162         _StartItem(
163                 this,
164                 this.itemdef = def,
165                 this.respawntime, // defaultrespawntime
166                 this.respawntimejitter // defaultrespawntimejitter
167         );
168         #if 0 // WEAPONTODO
169         if (this.modelindex) { // don't precache if this was removed
170                 wpn.wr_init(wpn);
171         }
172         #endif
173 }