#include "resources.qh"
-//#include <server/autocvars.qh>
+/// \file
+/// \brief Source file that contains implementation of the resource system.
+/// \author Lyberta
+/// \copyright GNU GPLv2 or any later version.
+
+#include "autocvars.qh"
+#include "miscfunctions.qh"
float GetResourceLimit(entity e, int resource_type)
{
+ if(!IS_PLAYER(e))
+ return RESOURCE_LIMIT_NONE; // no limits on non-players
+
float limit;
switch (resource_type)
{
return limit;
}
+float GetResourceAmount(entity e, int resource_type)
+{
+ .float resource_field = GetResourceField(resource_type);
+ return e.(resource_field);
+}
+
+bool SetResourceAmountExplicit(entity e, int resource_type, float amount)
+{
+ .float resource_field = GetResourceField(resource_type);
+ if (e.(resource_field) != amount)
+ {
+ e.(resource_field) = amount;
+ return true;
+ }
+ return false;
+}
+
+void SetResourceAmount(entity e, int resource_type, float amount)
+{
+ bool forbid = MUTATOR_CALLHOOK(SetResourceAmount, e, resource_type, amount);
+ if (forbid)
+ {
+ return;
+ }
+ resource_type = M_ARGV(1, int);
+ amount = M_ARGV(2, float);
+ float max_amount = GetResourceLimit(e, resource_type); // TODO: should allow overriding these limits if cheats are enabled!
+ float amount_wasted = 0;
+ if (amount > max_amount && max_amount != RESOURCE_LIMIT_NONE)
+ {
+ amount_wasted = amount - max_amount;
+ amount = max_amount;
+ }
+ bool changed = SetResourceAmountExplicit(e, resource_type, amount);
+ if (changed)
+ {
+ MUTATOR_CALLHOOK(ResourceAmountChanged, e, resource_type, amount);
+ }
+ if (amount_wasted == 0)
+ {
+ return;
+ }
+ MUTATOR_CALLHOOK(ResourceWasted, e, resource_type, amount_wasted);
+}
+
void GiveResource(entity receiver, int resource_type, float amount)
{
- if (amount == 0)
+ if (amount <= 0)
{
return;
}
}
resource_type = M_ARGV(1, int);
amount = M_ARGV(2, float);
- .float resource_property = GetResourceProperty(resource_type);
- float max_amount = GetResourceLimit(receiver, resource_type);
- receiver.(resource_property) = bound(receiver.(resource_property),
- receiver.(resource_property) + amount, max_amount);
+ if (amount <= 0)
+ {
+ return;
+ }
+ SetResourceAmount(receiver, resource_type,
+ GetResourceAmount(receiver, resource_type) + amount);
switch (resource_type)
{
case RESOURCE_HEALTH:
}
}
-int GetResourceType(.float resource_property)
+void GiveResourceWithLimit(entity receiver, int resource_type, float amount,
+ float limit)
+{
+ if (amount <= 0)
+ {
+ return;
+ }
+ bool forbid = MUTATOR_CALLHOOK(GiveResourceWithLimit, receiver,
+ resource_type, amount, limit);
+ if (forbid)
+ {
+ return;
+ }
+ resource_type = M_ARGV(1, int);
+ amount = M_ARGV(2, float);
+ limit = M_ARGV(3, float);
+ if (amount <= 0)
+ {
+ return;
+ }
+ float current_amount = GetResourceAmount(receiver, resource_type);
+ if (current_amount + amount > limit && limit != RESOURCE_LIMIT_NONE)
+ {
+ amount = limit - current_amount;
+ }
+ GiveResource(receiver, resource_type, amount);
+}
+
+void TakeResource(entity receiver, int resource_type, float amount)
+{
+ if (amount <= 0)
+ {
+ return;
+ }
+ bool forbid = MUTATOR_CALLHOOK(TakeResource, receiver, resource_type,
+ amount);
+ if (forbid)
+ {
+ return;
+ }
+ resource_type = M_ARGV(1, int);
+ amount = M_ARGV(2, float);
+ if (amount <= 0)
+ {
+ return;
+ }
+ SetResourceAmount(receiver, resource_type,
+ GetResourceAmount(receiver, resource_type) - amount);
+}
+
+void TakeResourceWithLimit(entity receiver, int resource_type, float amount,
+ float limit)
+{
+ if (amount <= 0)
+ {
+ return;
+ }
+ bool forbid = MUTATOR_CALLHOOK(TakeResourceWithLimit, receiver,
+ resource_type, amount, limit);
+ if (forbid)
+ {
+ return;
+ }
+ resource_type = M_ARGV(1, int);
+ amount = M_ARGV(2, float);
+ limit = M_ARGV(3, float);
+ if (amount <= 0)
+ {
+ return;
+ }
+ float current_amount = GetResourceAmount(receiver, resource_type);
+ if (current_amount - amount < -limit)
+ {
+ amount = -limit + current_amount;
+ }
+ TakeResource(receiver, resource_type, amount);
+}
+
+void GiveOrTakeResource(entity receiver, int resource_type, float amount)
+{
+ if(amount < 0)
+ {
+ TakeResource(receiver, resource_type, amount * -1);
+ }
+ else
+ {
+ GiveResource(receiver, resource_type, amount);
+ }
+}
+
+void GiveOrTakeResourceWithLimit(entity receiver, int resource_type, float amount,
+ float limit)
+{
+ if(amount < 0)
+ {
+ TakeResourceWithLimit(receiver, resource_type, amount * -1, limit);
+ }
+ else
+ {
+ GiveResourceWithLimit(receiver, resource_type, amount, limit);
+ }
+}
+
+int GetResourceType(.float resource_field)
{
- switch (resource_property)
+ switch (resource_field)
{
case health: { return RESOURCE_HEALTH; }
case armorvalue: { return RESOURCE_ARMOR; }
case ammo_plasma: { return RESOURCE_PLASMA; }
case ammo_fuel: { return RESOURCE_FUEL; }
}
- error("GetResourceType: Invalid property.");
+ error("GetResourceType: Invalid field.");
return 0;
}
-.float GetResourceProperty(int resource_type)
+.float GetResourceField(int resource_type)
{
switch (resource_type)
{
case RESOURCE_PLASMA: { return ammo_plasma; }
case RESOURCE_FUEL: { return ammo_fuel; }
}
- error("GetResourceProperty: Invalid resource type.");
+ error("GetResourceField: Invalid resource type.");
return health;
}