X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fserver%2Fresources.qc;h=e36eb57508680f7d4b9fd8e980aaa3c9d59b9864;hp=6526e2f11d262f80dd888a66d6bfbad60a904d60;hb=e0012447bfce1b551df3dc01b043655aa93dafad;hpb=b9b8b4108c199c86cbae0924162966312c14b3e0 diff --git a/qcsrc/server/resources.qc b/qcsrc/server/resources.qc index 6526e2f11d..e36eb57508 100644 --- a/qcsrc/server/resources.qc +++ b/qcsrc/server/resources.qc @@ -1,54 +1,57 @@ +#include "resources.qh" + /// \file /// \brief Source file that contains implementation of the resource system. /// \author Lyberta -/// \copyright GNU GPLv3 or any later version. - -#include "resources.qh" +/// \copyright GNU GPLv2 or any later version. #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; @@ -59,80 +62,94 @@ float GetResourceLimit(entity e, int resource_type) 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) { - .float resource_field = GetResourceField(resource_type); - return e.(resource_field); + return e.(GetResourceField(res_type)); +} + +bool SetResourceExplicit(entity e, int res_type, float amount) +{ + .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); } - e.(resource_field) = amount; + if (amount_wasted == 0) + { + return; + } + 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); @@ -141,35 +158,107 @@ void GiveResource(entity receiver, int resource_type, float amount) } } -int GetResourceType(.float resource_field) +void GiveResourceWithLimit(entity receiver, int res_type, float amount, float limit) +{ + if (amount <= 0) + { + return; + } + 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, res_type, amount); +} + +void TakeResource(entity receiver, int res_type, float amount) { - switch (resource_field) + 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) { - 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; + } + SetResource(receiver, res_type, GetResource(receiver, res_type) - amount); +} + +void TakeResourceWithLimit(entity receiver, int res_type, float amount, float limit) +{ + if (amount <= 0) + { + 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;