]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/resources.qc
Purge SetResourceAmountExplicit
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / resources.qc
1 #include "resources.qh"
2
3 /// \file
4 /// \brief Source file that contains implementation of the resource system.
5 /// \author Lyberta
6 /// \copyright GNU GPLv2 or any later version.
7
8 #include "autocvars.qh"
9 #include "miscfunctions.qh"
10
11 float GetResourceLimit(entity e, int resource_type)
12 {
13         if(!IS_PLAYER(e))
14                 return RESOURCE_LIMIT_NONE; // no limits on non-players
15
16         float limit;
17         switch (resource_type)
18         {
19                 case RESOURCE_HEALTH:
20                 {
21                         limit = autocvar_g_balance_health_limit;
22                         break;
23                 }
24                 case RESOURCE_ARMOR:
25                 {
26                         limit = autocvar_g_balance_armor_limit;
27                         break;
28                 }
29                 case RESOURCE_SHELLS:
30                 {
31                         limit = g_pickup_shells_max;
32                         break;
33                 }
34                 case RESOURCE_BULLETS:
35                 {
36                         limit = g_pickup_nails_max;
37                         break;
38                 }
39                 case RESOURCE_ROCKETS:
40                 {
41                         limit = g_pickup_rockets_max;
42                         break;
43                 }
44                 case RESOURCE_CELLS:
45                 {
46                         limit = g_pickup_cells_max;
47                         break;
48                 }
49                 case RESOURCE_PLASMA:
50                 {
51                         limit = g_pickup_plasma_max;
52                         break;
53                 }
54                 case RESOURCE_FUEL:
55                 {
56                         limit = autocvar_g_balance_fuel_limit;
57                         break;
58                 }
59                 default:
60                 {
61                         error("GetResourceLimit: Invalid resource type.");
62                         return 0;
63                 }
64         }
65         MUTATOR_CALLHOOK(GetResourceLimit, e, resource_type, limit);
66         limit = M_ARGV(2, float);
67         if (limit > RESOURCE_AMOUNT_HARD_LIMIT)
68         {
69                 limit = RESOURCE_AMOUNT_HARD_LIMIT;
70         }
71         return limit;
72 }
73
74 float GetResourceAmount(entity e, int resource_type)
75 {
76         .float resource_field = GetResourceField(resource_type);
77         return e.(resource_field);
78 }
79
80 void SetResourceAmount(entity e, int resource_type, float amount)
81 {
82         bool forbid = MUTATOR_CALLHOOK(SetResourceAmount, e, resource_type, amount);
83         if (forbid)
84         {
85                 return;
86         }
87         resource_type = M_ARGV(1, int);
88         amount = M_ARGV(2, float);
89         float max_amount = GetResourceLimit(e, resource_type); // TODO: should allow overriding these limits if cheats are enabled!
90         float amount_wasted = 0;
91         if (amount > max_amount && max_amount != RESOURCE_LIMIT_NONE)
92         {
93                 amount_wasted = amount - max_amount;
94                 amount = max_amount;
95         }
96         .float resource_field = GetResourceField(resource_type);
97         if (e.(resource_field) != amount)
98         {
99                 e.(resource_field) = amount;
100                 MUTATOR_CALLHOOK(ResourceAmountChanged, e, resource_type, amount);
101         }
102         if (amount_wasted == 0)
103         {
104                 return;
105         }
106         MUTATOR_CALLHOOK(ResourceWasted, e, resource_type, amount_wasted);
107 }
108
109 void GiveResource(entity receiver, int resource_type, float amount)
110 {
111         if (amount <= 0)
112         {
113                 return;
114         }
115         bool forbid = MUTATOR_CALLHOOK(GiveResource, receiver, resource_type,
116                 amount);
117         if (forbid)
118         {
119                 return;
120         }
121         resource_type = M_ARGV(1, int);
122         amount = M_ARGV(2, float);
123         if (amount <= 0)
124         {
125                 return;
126         }
127         SetResourceAmount(receiver, resource_type,
128                 GetResourceAmount(receiver, resource_type) + amount);
129         switch (resource_type)
130         {
131                 case RESOURCE_HEALTH:
132                 {
133                         receiver.pauserothealth_finished =
134                                 max(receiver.pauserothealth_finished, time +
135                                 autocvar_g_balance_pause_health_rot);
136                         return;
137                 }
138                 case RESOURCE_ARMOR:
139                 {
140                         receiver.pauserotarmor_finished =
141                                 max(receiver.pauserotarmor_finished, time +
142                                 autocvar_g_balance_pause_armor_rot);
143                         return;
144                 }
145                 case RESOURCE_FUEL:
146                 {
147                         receiver.pauserotfuel_finished = max(receiver.pauserotfuel_finished,
148                                 time + autocvar_g_balance_pause_fuel_rot);
149                         return;
150                 }
151         }
152 }
153
154 void GiveResourceWithLimit(entity receiver, int resource_type, float amount,
155         float limit)
156 {
157         if (amount <= 0)
158         {
159                 return;
160         }
161         bool forbid = MUTATOR_CALLHOOK(GiveResourceWithLimit, receiver,
162                 resource_type, amount, limit);
163         if (forbid)
164         {
165                 return;
166         }
167         resource_type = M_ARGV(1, int);
168         amount = M_ARGV(2, float);
169         limit = M_ARGV(3, float);
170         if (amount <= 0)
171         {
172                 return;
173         }
174         float current_amount = GetResourceAmount(receiver, resource_type);
175         if (current_amount + amount > limit && limit != RESOURCE_LIMIT_NONE)
176         {
177                 amount = limit - current_amount;
178         }
179         GiveResource(receiver, resource_type, amount);
180 }
181
182 void TakeResource(entity receiver, int resource_type, float amount)
183 {
184         if (amount <= 0)
185         {
186                 return;
187         }
188         bool forbid = MUTATOR_CALLHOOK(TakeResource, receiver, resource_type,
189                 amount);
190         if (forbid)
191         {
192                 return;
193         }
194         resource_type = M_ARGV(1, int);
195         amount = M_ARGV(2, float);
196         if (amount <= 0)
197         {
198                 return;
199         }
200         SetResourceAmount(receiver, resource_type,
201                 GetResourceAmount(receiver, resource_type) - amount);
202 }
203
204 void TakeResourceWithLimit(entity receiver, int resource_type, float amount,
205         float limit)
206 {
207         if (amount <= 0)
208         {
209                 return;
210         }
211         bool forbid = MUTATOR_CALLHOOK(TakeResourceWithLimit, receiver,
212                 resource_type, amount, limit);
213         if (forbid)
214         {
215                 return;
216         }
217         resource_type = M_ARGV(1, int);
218         amount = M_ARGV(2, float);
219         limit = M_ARGV(3, float);
220         if (amount <= 0)
221         {
222                 return;
223         }
224         float current_amount = GetResourceAmount(receiver, resource_type);
225         if (current_amount - amount < -limit)
226         {
227                 amount = -limit + current_amount;
228         }
229         TakeResource(receiver, resource_type, amount);
230 }
231
232 void GiveOrTakeResource(entity receiver, int resource_type, float amount)
233 {
234         if(amount < 0)
235         {
236                 TakeResource(receiver, resource_type, amount * -1);
237         }
238         else
239         {
240                 GiveResource(receiver, resource_type, amount);
241         }
242 }
243
244 void GiveOrTakeResourceWithLimit(entity receiver, int resource_type, float amount,
245         float limit)
246 {
247         if(amount < 0)
248         {
249                 TakeResourceWithLimit(receiver, resource_type, amount * -1, limit);
250         }
251         else
252         {
253                 GiveResourceWithLimit(receiver, resource_type, amount, limit);
254         }
255 }
256
257 int GetResourceType(.float resource_field)
258 {
259         switch (resource_field)
260         {
261                 case health: { return RESOURCE_HEALTH; }
262                 case armorvalue: { return RESOURCE_ARMOR; }
263                 case ammo_shells: { return RESOURCE_SHELLS; }
264                 case ammo_nails: { return RESOURCE_BULLETS; }
265                 case ammo_rockets: { return RESOURCE_ROCKETS; }
266                 case ammo_cells: { return RESOURCE_CELLS; }
267                 case ammo_plasma: { return RESOURCE_PLASMA; }
268                 case ammo_fuel: { return RESOURCE_FUEL; }
269         }
270         error("GetResourceType: Invalid field.");
271         return 0;
272 }
273
274 .float GetResourceField(int resource_type)
275 {
276         switch (resource_type)
277         {
278                 case RESOURCE_HEALTH: { return health; }
279                 case RESOURCE_ARMOR: { return armorvalue; }
280                 case RESOURCE_SHELLS: { return ammo_shells; }
281                 case RESOURCE_BULLETS: { return ammo_nails; }
282                 case RESOURCE_ROCKETS: { return ammo_rockets; }
283                 case RESOURCE_CELLS: { return ammo_cells; }
284                 case RESOURCE_PLASMA: { return ammo_plasma; }
285                 case RESOURCE_FUEL: { return ammo_fuel; }
286         }
287         error("GetResourceField: Invalid resource type.");
288         return health;
289 }