]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/resources.qc
Merge branch 'Mario/crouch' into 'master'
[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         float limit;
14         switch (resource_type)
15         {
16                 case RESOURCE_HEALTH:
17                 {
18                         limit = autocvar_g_balance_health_limit;
19                         break;
20                 }
21                 case RESOURCE_ARMOR:
22                 {
23                         limit = autocvar_g_balance_armor_limit;
24                         break;
25                 }
26                 case RESOURCE_SHELLS:
27                 {
28                         limit = g_pickup_shells_max;
29                         break;
30                 }
31                 case RESOURCE_BULLETS:
32                 {
33                         limit = g_pickup_nails_max;
34                         break;
35                 }
36                 case RESOURCE_ROCKETS:
37                 {
38                         limit = g_pickup_rockets_max;
39                         break;
40                 }
41                 case RESOURCE_CELLS:
42                 {
43                         limit = g_pickup_cells_max;
44                         break;
45                 }
46                 case RESOURCE_PLASMA:
47                 {
48                         limit = g_pickup_plasma_max;
49                         break;
50                 }
51                 case RESOURCE_FUEL:
52                 {
53                         limit = autocvar_g_balance_fuel_limit;
54                         break;
55                 }
56                 default:
57                 {
58                         error("GetResourceLimit: Invalid resource type.");
59                         return 0;
60                 }
61         }
62         MUTATOR_CALLHOOK(GetResourceLimit, e, resource_type, limit);
63         limit = M_ARGV(2, float);
64         if (limit > RESOURCE_AMOUNT_HARD_LIMIT)
65         {
66                 limit = RESOURCE_AMOUNT_HARD_LIMIT;
67         }
68         return limit;
69 }
70
71 float GetResourceAmount(entity e, int resource_type)
72 {
73         .float resource_field = GetResourceField(resource_type);
74         return e.(resource_field);
75 }
76
77 void SetResourceAmount(entity e, int resource_type, float amount)
78 {
79         bool forbid = MUTATOR_CALLHOOK(SetResourceAmount, e, resource_type, amount);
80         if (forbid)
81         {
82                 return;
83         }
84         resource_type = M_ARGV(1, int);
85         amount = M_ARGV(2, float);
86         float max_amount = GetResourceLimit(e, resource_type);
87         float amount_wasted = 0;
88         if (amount > max_amount)
89         {
90                 amount_wasted = amount - max_amount;
91                 amount = max_amount;
92         }
93         .float resource_field = GetResourceField(resource_type);
94         if (e.(resource_field) != amount)
95         {
96                 e.(resource_field) = amount;
97                 MUTATOR_CALLHOOK(ResourceAmountChanged, e, resource_type, amount);
98         }
99         if (amount_wasted == 0)
100         {
101                 return;
102         }
103         MUTATOR_CALLHOOK(ResourceWasted, e, resource_type, amount_wasted);
104 }
105
106 void GiveResource(entity receiver, int resource_type, float amount)
107 {
108         if (amount == 0)
109         {
110                 return;
111         }
112         bool forbid = MUTATOR_CALLHOOK(GiveResource, receiver, resource_type,
113                 amount);
114         if (forbid)
115         {
116                 return;
117         }
118         resource_type = M_ARGV(1, int);
119         amount = M_ARGV(2, float);
120         if (amount <= 0)
121         {
122                 return;
123         }
124         SetResourceAmount(receiver, resource_type,
125                 GetResourceAmount(receiver, resource_type) + amount);
126         switch (resource_type)
127         {
128                 case RESOURCE_HEALTH:
129                 {
130                         receiver.pauserothealth_finished =
131                                 max(receiver.pauserothealth_finished, time +
132                                 autocvar_g_balance_pause_health_rot);
133                         return;
134                 }
135                 case RESOURCE_ARMOR:
136                 {
137                         receiver.pauserotarmor_finished =
138                                 max(receiver.pauserotarmor_finished, time +
139                                 autocvar_g_balance_pause_armor_rot);
140                         return;
141                 }
142                 case RESOURCE_FUEL:
143                 {
144                         receiver.pauserotfuel_finished = max(receiver.pauserotfuel_finished,
145                                 time + autocvar_g_balance_pause_fuel_rot);
146                         return;
147                 }
148         }
149 }
150
151 void GiveResourceWithLimit(entity receiver, int resource_type, float amount,
152         float limit)
153 {
154         if (amount == 0)
155         {
156                 return;
157         }
158         bool forbid = MUTATOR_CALLHOOK(GiveResourceWithLimit, receiver,
159                 resource_type, amount, limit);
160         if (forbid)
161         {
162                 return;
163         }
164         resource_type = M_ARGV(1, int);
165         amount = M_ARGV(2, float);
166         limit = M_ARGV(3, float);
167         if (amount == 0)
168         {
169                 return;
170         }
171         float current_amount = GetResourceAmount(receiver, resource_type);
172         if (current_amount + amount > limit)
173         {
174                 amount = limit - current_amount;
175         }
176         GiveResource(receiver, resource_type, amount);
177 }
178
179 int GetResourceType(.float resource_field)
180 {
181         switch (resource_field)
182         {
183                 case health: { return RESOURCE_HEALTH; }
184                 case armorvalue: { return RESOURCE_ARMOR; }
185                 case ammo_shells: { return RESOURCE_SHELLS; }
186                 case ammo_nails: { return RESOURCE_BULLETS; }
187                 case ammo_rockets: { return RESOURCE_ROCKETS; }
188                 case ammo_cells: { return RESOURCE_CELLS; }
189                 case ammo_plasma: { return RESOURCE_PLASMA; }
190                 case ammo_fuel: { return RESOURCE_FUEL; }
191         }
192         error("GetResourceType: Invalid field.");
193         return 0;
194 }
195
196 .float GetResourceField(int resource_type)
197 {
198         switch (resource_type)
199         {
200                 case RESOURCE_HEALTH: { return health; }
201                 case RESOURCE_ARMOR: { return armorvalue; }
202                 case RESOURCE_SHELLS: { return ammo_shells; }
203                 case RESOURCE_BULLETS: { return ammo_nails; }
204                 case RESOURCE_ROCKETS: { return ammo_rockets; }
205                 case RESOURCE_CELLS: { return ammo_cells; }
206                 case RESOURCE_PLASMA: { return ammo_plasma; }
207                 case RESOURCE_FUEL: { return ammo_fuel; }
208         }
209         error("GetResourceField: Invalid resource type.");
210         return health;
211 }