1 #include "resources.qh"
4 /// \brief Source file that contains implementation of the resource system.
6 /// \copyright GNU GPLv2 or any later version.
8 #include "autocvars.qh"
9 #include "miscfunctions.qh"
11 float GetResourceLimit(entity e, int res_type)
14 return RES_LIMIT_NONE; // no limits on non-players
21 limit = autocvar_g_balance_health_limit;
26 limit = autocvar_g_balance_armor_limit;
31 limit = g_pickup_shells_max;
36 limit = g_pickup_nails_max;
41 limit = g_pickup_rockets_max;
46 limit = g_pickup_cells_max;
51 limit = g_pickup_plasma_max;
56 limit = autocvar_g_balance_fuel_limit;
61 error("GetResourceLimit: Invalid resource type.");
65 MUTATOR_CALLHOOK(GetResourceLimit, e, res_type, limit);
66 limit = M_ARGV(2, float);
67 if (limit > RES_AMOUNT_HARD_LIMIT)
69 limit = RES_AMOUNT_HARD_LIMIT;
74 float GetResource(entity e, int res_type)
76 return e.(GetResourceField(res_type));
79 bool SetResourceExplicit(entity e, int res_type, float amount)
81 .float res_field = GetResourceField(res_type);
82 if (e.(res_field) != amount)
84 e.(res_field) = amount;
90 void SetResource(entity e, int res_type, float amount)
92 bool forbid = MUTATOR_CALLHOOK(SetResource, e, res_type, amount);
97 res_type = M_ARGV(1, int);
98 amount = M_ARGV(2, float);
99 float max_amount = GetResourceLimit(e, res_type); // TODO: should allow overriding these limits if cheats are enabled!
100 float amount_wasted = 0;
101 if (amount > max_amount && max_amount != RES_LIMIT_NONE)
103 amount_wasted = amount - max_amount;
106 bool changed = SetResourceExplicit(e, res_type, amount);
109 MUTATOR_CALLHOOK(ResourceAmountChanged, e, res_type, amount);
111 if (amount_wasted == 0)
115 MUTATOR_CALLHOOK(ResourceWasted, e, res_type, amount_wasted);
118 void GiveResource(entity receiver, int res_type, float amount)
124 bool forbid = MUTATOR_CALLHOOK(GiveResource, receiver, res_type, amount);
129 res_type = M_ARGV(1, int);
130 amount = M_ARGV(2, float);
135 SetResource(receiver, res_type, GetResource(receiver, res_type) + amount);
140 receiver.pauserothealth_finished =
141 max(receiver.pauserothealth_finished, time +
142 autocvar_g_balance_pause_health_rot);
147 receiver.pauserotarmor_finished =
148 max(receiver.pauserotarmor_finished, time +
149 autocvar_g_balance_pause_armor_rot);
154 receiver.pauserotfuel_finished = max(receiver.pauserotfuel_finished,
155 time + autocvar_g_balance_pause_fuel_rot);
161 void GiveResourceWithLimit(entity receiver, int res_type, float amount, float limit)
167 bool forbid = MUTATOR_CALLHOOK(GiveResourceWithLimit, receiver, res_type, amount, limit);
172 res_type = M_ARGV(1, int);
173 amount = M_ARGV(2, float);
174 limit = M_ARGV(3, float);
179 float current_amount = GetResource(receiver, res_type);
180 if (current_amount + amount > limit && limit != RES_LIMIT_NONE)
182 amount = limit - current_amount;
184 GiveResource(receiver, res_type, amount);
187 void TakeResource(entity receiver, int res_type, float amount)
193 bool forbid = MUTATOR_CALLHOOK(TakeResource, receiver, res_type, amount);
198 res_type = M_ARGV(1, int);
199 amount = M_ARGV(2, float);
204 SetResource(receiver, res_type, GetResource(receiver, res_type) - amount);
207 void TakeResourceWithLimit(entity receiver, int res_type, float amount, float limit)
213 bool forbid = MUTATOR_CALLHOOK(TakeResourceWithLimit, receiver, res_type, amount, limit);
218 res_type = M_ARGV(1, int);
219 amount = M_ARGV(2, float);
220 limit = M_ARGV(3, float);
225 float current_amount = GetResource(receiver, res_type);
226 if (current_amount - amount < -limit)
228 amount = -limit + current_amount;
230 TakeResource(receiver, res_type, amount);
233 int GetResourceType(.float res_field)
237 case health: { return RES_HEALTH; }
238 case armorvalue: { return RES_ARMOR; }
239 case ammo_shells: { return RES_SHELLS; }
240 case ammo_nails: { return RES_BULLETS; }
241 case ammo_rockets: { return RES_ROCKETS; }
242 case ammo_cells: { return RES_CELLS; }
243 case ammo_plasma: { return RES_PLASMA; }
244 case ammo_fuel: { return RES_FUEL; }
246 error("GetResourceType: Invalid field.");
250 .float GetResourceField(int res_type)
254 case RES_HEALTH: { return health; }
255 case RES_ARMOR: { return armorvalue; }
256 case RES_SHELLS: { return ammo_shells; }
257 case RES_BULLETS: { return ammo_nails; }
258 case RES_ROCKETS: { return ammo_rockets; }
259 case RES_CELLS: { return ammo_cells; }
260 case RES_PLASMA: { return ammo_plasma; }
261 case RES_FUEL: { return ammo_fuel; }
263 error("GetResourceField: Invalid resource type.");