Xonotic
sv_resources.qc
Go to the documentation of this file.
1 #include "sv_resources.qh"
2 
7 
10 #include <server/world.qh>
11 
12 float GetResourceLimit(entity e, Resource res_type)
13 {
14  if(!IS_PLAYER(e))
15  return RES_LIMIT_NONE; // no limits on non-players
16 
17  float limit;
18  // TODO: registry handles
19  switch (res_type)
20  {
21  case RES_HEALTH:
22  {
24  break;
25  }
26  case RES_ARMOR:
27  {
29  break;
30  }
31  case RES_SHELLS:
32  {
33  limit = g_pickup_shells_max;
34  break;
35  }
36  case RES_BULLETS:
37  {
38  limit = g_pickup_nails_max;
39  break;
40  }
41  case RES_ROCKETS:
42  {
43  limit = g_pickup_rockets_max;
44  break;
45  }
46  case RES_CELLS:
47  {
48  limit = g_pickup_cells_max;
49  break;
50  }
51  case RES_PLASMA:
52  {
53  limit = g_pickup_plasma_max;
54  break;
55  }
56  case RES_FUEL:
57  {
59  break;
60  }
61  default:
62  {
63  error("GetResourceLimit: Invalid resource type.");
64  return 0;
65  }
66  }
67  MUTATOR_CALLHOOK(GetResourceLimit, e, res_type, limit);
68  limit = M_ARGV(2, float);
69  if (limit > RES_AMOUNT_HARD_LIMIT)
70  {
71  limit = RES_AMOUNT_HARD_LIMIT;
72  }
73  return limit;
74 }
75 
76 float GetResource(entity e, Resource res_type)
77 {
78  return e.(GetResourceField(res_type));
79 }
80 
81 bool SetResourceExplicit(entity e, Resource res_type, float amount)
82 {
83  .float res_field = GetResourceField(res_type);
84  if (e.(res_field) != amount)
85  {
86  e.(res_field) = amount;
87  return true;
88  }
89  return false;
90 }
91 
92 void SetResource(entity e, Resource res_type, float amount)
93 {
94  bool forbid = MUTATOR_CALLHOOK(SetResource, e, res_type, amount);
95  if (forbid)
96  {
97  return;
98  }
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)
104  {
105  amount_wasted = amount - max_amount;
106  amount = max_amount;
107  }
108  bool changed = SetResourceExplicit(e, res_type, amount);
109  if (changed)
110  {
111  MUTATOR_CALLHOOK(ResourceAmountChanged, e, res_type, amount);
112  }
113  if (amount_wasted == 0)
114  {
115  return;
116  }
117  MUTATOR_CALLHOOK(ResourceWasted, e, res_type, amount_wasted);
118 }
119 
120 void GiveResource(entity receiver, Resource res_type, float amount)
121 {
122  if (amount <= 0)
123  {
124  return;
125  }
126  bool forbid = MUTATOR_CALLHOOK(GiveResource, receiver, res_type, amount);
127  if (forbid)
128  {
129  return;
130  }
131  res_type = M_ARGV(1, entity);
132  amount = M_ARGV(2, float);
133  if (amount <= 0)
134  {
135  return;
136  }
137  SetResource(receiver, res_type, GetResource(receiver, res_type) + amount);
138  // TODO: registry handles
139  switch (res_type)
140  {
141  case RES_HEALTH:
142  {
143  receiver.pauserothealth_finished =
144  max(receiver.pauserothealth_finished, time +
146  return;
147  }
148  case RES_ARMOR:
149  {
150  receiver.pauserotarmor_finished =
151  max(receiver.pauserotarmor_finished, time +
153  return;
154  }
155  case RES_FUEL:
156  {
157  receiver.pauserotfuel_finished = max(receiver.pauserotfuel_finished,
159  return;
160  }
161  }
162 }
163 
164 void GiveResourceWithLimit(entity receiver, Resource res_type, float amount, float limit)
165 {
166  if (amount <= 0)
167  {
168  return;
169  }
170  bool forbid = MUTATOR_CALLHOOK(GiveResourceWithLimit, receiver, res_type, amount, limit);
171  if (forbid)
172  {
173  return;
174  }
175  res_type = M_ARGV(1, entity);
176  amount = M_ARGV(2, float);
177  limit = M_ARGV(3, float);
178  if (amount <= 0)
179  {
180  return;
181  }
182  float current_amount = GetResource(receiver, res_type);
183  if (current_amount + amount > limit && limit != RES_LIMIT_NONE)
184  {
185  amount = limit - current_amount;
186  }
187  GiveResource(receiver, res_type, amount);
188 }
189 
190 void TakeResource(entity receiver, Resource res_type, float amount)
191 {
192  if (amount <= 0)
193  {
194  return;
195  }
196  bool forbid = MUTATOR_CALLHOOK(TakeResource, receiver, res_type, amount);
197  if (forbid)
198  {
199  return;
200  }
201  res_type = M_ARGV(1, entity);
202  amount = M_ARGV(2, float);
203  if (amount <= 0)
204  {
205  return;
206  }
207  SetResource(receiver, res_type, GetResource(receiver, res_type) - amount);
208 }
209 
210 void TakeResourceWithLimit(entity receiver, Resource res_type, float amount, float limit)
211 {
212  if (amount <= 0)
213  {
214  return;
215  }
216  bool forbid = MUTATOR_CALLHOOK(TakeResourceWithLimit, receiver, res_type, amount, limit);
217  if (forbid)
218  {
219  return;
220  }
221  res_type = M_ARGV(1, entity);
222  amount = M_ARGV(2, float);
223  limit = M_ARGV(3, float);
224  if (amount <= 0)
225  {
226  return;
227  }
228  float current_amount = GetResource(receiver, res_type);
229  if (current_amount - amount < -limit)
230  {
231  amount = -limit + current_amount;
232  }
233  TakeResource(receiver, res_type, amount);
234 }
float autocvar_g_balance_pause_armor_rot
Definition: sv_resources.qh:32
Header file that describes the resource system.
float g_pickup_nails_max
Definition: world.qh:70
void SetResource(entity e, Resource res_type, float amount)
Sets the current amount of resource the given entity will have.
Definition: sv_resources.qc:92
entity() spawn
float GetResource(entity e, Resource res_type)
Returns the current amount of resource the given entity has.
Definition: sv_resources.qc:76
const int RES_AMOUNT_HARD_LIMIT
Unconditional maximum amount of resources the entity can have.
Definition: resources.qh:45
float autocvar_g_balance_fuel_limit
Definition: sv_resources.qh:13
RES_HEALTH
Definition: ent_cs.qc:126
void GiveResourceWithLimit(entity receiver, Resource res_type, float amount, float limit)
Gives an entity some resource but not more than a limit.
const int RES_LIMIT_NONE
Definition: resources.qh:46
float g_pickup_rockets_max
Definition: world.qh:71
float g_pickup_shells_max
Definition: world.qh:69
int autocvar_g_balance_armor_limit
Definition: sv_resources.qh:12
#define M_ARGV(x, type)
Definition: events.qh:17
float GetResourceLimit(entity e, Resource res_type)
Returns the maximum amount of the given resource.
Definition: sv_resources.qc:12
float autocvar_g_balance_pause_health_rot
Definition: sv_resources.qh:36
void TakeResource(entity receiver, Resource res_type, float amount)
Takes an entity some resource.
void GiveResource(entity receiver, Resource res_type, float amount)
Gives an entity some resource.
void TakeResourceWithLimit(entity receiver, Resource res_type, float amount, float limit)
Takes an entity some resource but not less than a limit.
float g_pickup_plasma_max
Definition: world.qh:73
#define MUTATOR_CALLHOOK(id,...)
Definition: base.qh:140
float autocvar_g_balance_health_limit
Definition: sv_resources.qh:11
bool SetResourceExplicit(entity e, Resource res_type, float amount)
Sets the resource amount of an entity without calling any hooks.
Definition: sv_resources.qc:81
float g_pickup_cells_max
Definition: world.qh:72
float time
Definition: csprogsdefs.qc:16
#define IS_PLAYER(v)
Definition: utils.qh:9
float autocvar_g_balance_pause_fuel_rot
Definition: sv_resources.qh:34