1 #include "sv_resources.qh"
4 /// \brief Source file that contains implementation of the resource system.
6 /// \copyright GNU GPLv2 or any later version.
8 #include <common/resources/resources.qh>
9 #include <server/mutators/_mod.qh>
10 #include <server/world.qh>
12 float GetResourceLimit(entity e, Resource res_type)
15 return RES_LIMIT_NONE; // no limits on non-players
18 // TODO: registry handles
23 limit = autocvar_g_balance_health_limit;
28 limit = autocvar_g_balance_armor_limit;
33 limit = g_pickup_shells_max;
38 limit = g_pickup_nails_max;
43 limit = g_pickup_rockets_max;
48 limit = g_pickup_cells_max;
53 limit = g_pickup_plasma_max;
58 limit = autocvar_g_balance_fuel_limit;
63 error("GetResourceLimit: Invalid resource type.");
67 MUTATOR_CALLHOOK(GetResourceLimit, e, res_type, limit);
68 limit = M_ARGV(2, float);
69 if (limit > RES_AMOUNT_HARD_LIMIT)
71 limit = RES_AMOUNT_HARD_LIMIT;
76 float GetResource(entity e, Resource res_type)
78 return e.(GetResourceField(res_type));
81 bool SetResourceExplicit(entity e, Resource res_type, float amount)
83 .float res_field = GetResourceField(res_type);
84 if (e.(res_field) != amount)
86 e.(res_field) = amount;
92 void SetResource(entity e, Resource res_type, float amount)
94 bool forbid = MUTATOR_CALLHOOK(SetResource, e, res_type, amount);
99 res_type = M_ARGV(1, entity);
100 amount = M_ARGV(2, float);
101 float max_amount = GetResourceLimit(e, res_type); // TODO: should allow overriding these limits if cheats are enabled!
102 float amount_wasted = 0;
103 if (amount > max_amount && max_amount != RES_LIMIT_NONE)
105 amount_wasted = amount - max_amount;
108 bool changed = SetResourceExplicit(e, res_type, amount);
111 MUTATOR_CALLHOOK(ResourceAmountChanged, e, res_type, amount);
113 if (amount_wasted == 0)
117 MUTATOR_CALLHOOK(ResourceWasted, e, res_type, amount_wasted);
120 void GiveResource(entity receiver, Resource res_type, float amount)
126 bool forbid = MUTATOR_CALLHOOK(GiveResource, receiver, res_type, amount);
131 res_type = M_ARGV(1, entity);
132 amount = M_ARGV(2, float);
137 SetResource(receiver, res_type, GetResource(receiver, res_type) + amount);
138 // TODO: registry handles
143 receiver.pauserothealth_finished =
144 max(receiver.pauserothealth_finished, time +
145 autocvar_g_balance_pause_health_rot);
150 receiver.pauserotarmor_finished =
151 max(receiver.pauserotarmor_finished, time +
152 autocvar_g_balance_pause_armor_rot);
157 receiver.pauserotfuel_finished = max(receiver.pauserotfuel_finished,
158 time + autocvar_g_balance_pause_fuel_rot);
164 void GiveResourceWithLimit(entity receiver, Resource res_type, float amount, float limit)
170 bool forbid = MUTATOR_CALLHOOK(GiveResourceWithLimit, receiver, res_type, amount, limit);
175 res_type = M_ARGV(1, entity);
176 amount = M_ARGV(2, float);
177 limit = M_ARGV(3, float);
182 float current_amount = GetResource(receiver, res_type);
183 if (current_amount + amount > limit && limit != RES_LIMIT_NONE)
185 amount = limit - current_amount;
187 GiveResource(receiver, res_type, amount);
190 void TakeResource(entity receiver, Resource res_type, float amount)
196 bool forbid = MUTATOR_CALLHOOK(TakeResource, receiver, res_type, amount);
201 res_type = M_ARGV(1, entity);
202 amount = M_ARGV(2, float);
207 SetResource(receiver, res_type, GetResource(receiver, res_type) - amount);
210 void TakeResourceWithLimit(entity receiver, Resource res_type, float amount, float limit)
216 bool forbid = MUTATOR_CALLHOOK(TakeResourceWithLimit, receiver, res_type, amount, limit);
221 res_type = M_ARGV(1, entity);
222 amount = M_ARGV(2, float);
223 limit = M_ARGV(3, float);
228 float current_amount = GetResource(receiver, res_type);
229 if (current_amount - amount < -limit)
231 amount = -limit + current_amount;
233 TakeResource(receiver, res_type, amount);