#include "autocvars.qh"
#include "miscfunctions.qh"
-float GetResourceLimit(entity e, int resource_type)
+float GetResourceLimit(entity e, int res_type)
{
+ if(!IS_PLAYER(e))
+ return RES_LIMIT_NONE; // no limits on non-players
+
float limit;
- switch (resource_type)
+ switch (res_type)
{
- case RESOURCE_HEALTH:
+ case RES_HEALTH:
{
limit = autocvar_g_balance_health_limit;
break;
}
- case RESOURCE_ARMOR:
+ case RES_ARMOR:
{
limit = autocvar_g_balance_armor_limit;
break;
}
- case RESOURCE_SHELLS:
+ case RES_SHELLS:
{
limit = g_pickup_shells_max;
break;
}
- case RESOURCE_BULLETS:
+ case RES_BULLETS:
{
limit = g_pickup_nails_max;
break;
}
- case RESOURCE_ROCKETS:
+ case RES_ROCKETS:
{
limit = g_pickup_rockets_max;
break;
}
- case RESOURCE_CELLS:
+ case RES_CELLS:
{
limit = g_pickup_cells_max;
break;
}
- case RESOURCE_PLASMA:
+ case RES_PLASMA:
{
limit = g_pickup_plasma_max;
break;
}
- case RESOURCE_FUEL:
+ case RES_FUEL:
{
limit = autocvar_g_balance_fuel_limit;
break;
return 0;
}
}
- MUTATOR_CALLHOOK(GetResourceLimit, e, resource_type, limit);
+ MUTATOR_CALLHOOK(GetResourceLimit, e, res_type, limit);
limit = M_ARGV(2, float);
- if (limit > RESOURCE_AMOUNT_HARD_LIMIT)
+ if (limit > RES_AMOUNT_HARD_LIMIT)
{
- limit = RESOURCE_AMOUNT_HARD_LIMIT;
+ limit = RES_AMOUNT_HARD_LIMIT;
}
return limit;
}
-float GetResourceAmount(entity e, int resource_type)
+float GetResource(entity e, int res_type)
+{
+ return e.(GetResourceField(res_type));
+}
+
+bool SetResourceExplicit(entity e, int res_type, float amount)
{
- .float resource_field = GetResourceField(resource_type);
- return e.(resource_field);
+ .float res_field = GetResourceField(res_type);
+ if (e.(res_field) != amount)
+ {
+ e.(res_field) = amount;
+ return true;
+ }
+ return false;
}
-void SetResourceAmount(entity e, int resource_type, float amount)
+void SetResource(entity e, int res_type, float amount)
{
- bool forbid = MUTATOR_CALLHOOK(SetResourceAmount, e, resource_type, amount);
+ bool forbid = MUTATOR_CALLHOOK(SetResource, e, res_type, amount);
if (forbid)
{
return;
}
- resource_type = M_ARGV(1, int);
+ res_type = M_ARGV(1, int);
amount = M_ARGV(2, float);
- .float resource_field = GetResourceField(resource_type);
- if (e.(resource_field) == amount)
+ float max_amount = GetResourceLimit(e, res_type); // TODO: should allow overriding these limits if cheats are enabled!
+ float amount_wasted = 0;
+ if (amount > max_amount && max_amount != RES_LIMIT_NONE)
{
- return;
+ amount_wasted = amount - max_amount;
+ amount = max_amount;
}
- float max_amount = GetResourceLimit(e, resource_type);
- if (amount > max_amount)
+ bool changed = SetResourceExplicit(e, res_type, amount);
+ if (changed)
{
- amount = max_amount;
+ MUTATOR_CALLHOOK(ResourceAmountChanged, e, res_type, amount);
+ }
+ if (amount_wasted == 0)
+ {
+ return;
}
- e.(resource_field) = amount;
+ MUTATOR_CALLHOOK(ResourceWasted, e, res_type, amount_wasted);
}
-void GiveResource(entity receiver, int resource_type, float amount)
+void GiveResource(entity receiver, int res_type, float amount)
{
- if (amount == 0)
+ if (amount <= 0)
{
return;
}
- bool forbid = MUTATOR_CALLHOOK(GiveResource, receiver, resource_type,
- amount);
+ bool forbid = MUTATOR_CALLHOOK(GiveResource, receiver, res_type, amount);
if (forbid)
{
return;
}
- resource_type = M_ARGV(1, int);
+ res_type = M_ARGV(1, int);
amount = M_ARGV(2, float);
if (amount <= 0)
{
return;
}
- SetResourceAmount(receiver, resource_type,
- GetResourceAmount(receiver, resource_type) + amount);
- switch (resource_type)
+ SetResource(receiver, res_type, GetResource(receiver, res_type) + amount);
+ switch (res_type)
{
- case RESOURCE_HEALTH:
+ case RES_HEALTH:
{
receiver.pauserothealth_finished =
max(receiver.pauserothealth_finished, time +
autocvar_g_balance_pause_health_rot);
return;
}
- case RESOURCE_ARMOR:
+ case RES_ARMOR:
{
receiver.pauserotarmor_finished =
max(receiver.pauserotarmor_finished, time +
autocvar_g_balance_pause_armor_rot);
return;
}
- case RESOURCE_FUEL:
+ case RES_FUEL:
{
receiver.pauserotfuel_finished = max(receiver.pauserotfuel_finished,
time + autocvar_g_balance_pause_fuel_rot);
}
}
-void GiveResourceWithLimit(entity receiver, int resource_type, float amount,
- float limit)
+void GiveResourceWithLimit(entity receiver, int res_type, float amount, float limit)
{
- if (amount == 0)
+ if (amount <= 0)
{
return;
}
- float current_amount = GetResourceAmount(receiver, resource_type);
- if (current_amount + amount > limit)
+ bool forbid = MUTATOR_CALLHOOK(GiveResourceWithLimit, receiver, res_type, amount, limit);
+ if (forbid)
+ {
+ return;
+ }
+ res_type = M_ARGV(1, int);
+ amount = M_ARGV(2, float);
+ limit = M_ARGV(3, float);
+ if (amount <= 0)
+ {
+ return;
+ }
+ float current_amount = GetResource(receiver, res_type);
+ if (current_amount + amount > limit && limit != RES_LIMIT_NONE)
{
amount = limit - current_amount;
}
- GiveResource(receiver, resource_type, amount);
+ GiveResource(receiver, res_type, amount);
+}
+
+void TakeResource(entity receiver, int res_type, float amount)
+{
+ if (amount <= 0)
+ {
+ return;
+ }
+ bool forbid = MUTATOR_CALLHOOK(TakeResource, receiver, res_type, amount);
+ if (forbid)
+ {
+ return;
+ }
+ res_type = M_ARGV(1, int);
+ amount = M_ARGV(2, float);
+ if (amount <= 0)
+ {
+ return;
+ }
+ SetResource(receiver, res_type, GetResource(receiver, res_type) - amount);
}
-int GetResourceType(.float resource_field)
+void TakeResourceWithLimit(entity receiver, int res_type, float amount, float limit)
{
- switch (resource_field)
+ if (amount <= 0)
{
- case health: { return RESOURCE_HEALTH; }
- case armorvalue: { return RESOURCE_ARMOR; }
- case ammo_shells: { return RESOURCE_SHELLS; }
- case ammo_nails: { return RESOURCE_BULLETS; }
- case ammo_rockets: { return RESOURCE_ROCKETS; }
- case ammo_cells: { return RESOURCE_CELLS; }
- case ammo_plasma: { return RESOURCE_PLASMA; }
- case ammo_fuel: { return RESOURCE_FUEL; }
+ return;
+ }
+ bool forbid = MUTATOR_CALLHOOK(TakeResourceWithLimit, receiver, res_type, amount, limit);
+ if (forbid)
+ {
+ return;
+ }
+ res_type = M_ARGV(1, int);
+ amount = M_ARGV(2, float);
+ limit = M_ARGV(3, float);
+ if (amount <= 0)
+ {
+ return;
+ }
+ float current_amount = GetResource(receiver, res_type);
+ if (current_amount - amount < -limit)
+ {
+ amount = -limit + current_amount;
+ }
+ TakeResource(receiver, res_type, amount);
+}
+
+int GetResourceType(.float res_field)
+{
+ switch (res_field)
+ {
+ case health: { return RES_HEALTH; }
+ case armorvalue: { return RES_ARMOR; }
+ case ammo_shells: { return RES_SHELLS; }
+ case ammo_nails: { return RES_BULLETS; }
+ case ammo_rockets: { return RES_ROCKETS; }
+ case ammo_cells: { return RES_CELLS; }
+ case ammo_plasma: { return RES_PLASMA; }
+ case ammo_fuel: { return RES_FUEL; }
}
error("GetResourceType: Invalid field.");
return 0;
}
-.float GetResourceField(int resource_type)
+.float GetResourceField(int res_type)
{
- switch (resource_type)
- {
- case RESOURCE_HEALTH: { return health; }
- case RESOURCE_ARMOR: { return armorvalue; }
- case RESOURCE_SHELLS: { return ammo_shells; }
- case RESOURCE_BULLETS: { return ammo_nails; }
- case RESOURCE_ROCKETS: { return ammo_rockets; }
- case RESOURCE_CELLS: { return ammo_cells; }
- case RESOURCE_PLASMA: { return ammo_plasma; }
- case RESOURCE_FUEL: { return ammo_fuel; }
+ switch (res_type)
+ {
+ case RES_HEALTH: { return health; }
+ case RES_ARMOR: { return armorvalue; }
+ case RES_SHELLS: { return ammo_shells; }
+ case RES_BULLETS: { return ammo_nails; }
+ case RES_ROCKETS: { return ammo_rockets; }
+ case RES_CELLS: { return ammo_cells; }
+ case RES_PLASMA: { return ammo_plasma; }
+ case RES_FUEL: { return ammo_fuel; }
}
error("GetResourceField: Invalid resource type.");
return health;