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=4ad66bb98ed2169380e7074ea23147a503e652cf;hb=e0012447bfce1b551df3dc01b043655aa93dafad;hpb=305b0940055e40fe94f93a30464bf8e7991f00a9 diff --git a/qcsrc/server/resources.qc b/qcsrc/server/resources.qc index 4ad66bb98e..e36eb57508 100644 --- a/qcsrc/server/resources.qc +++ b/qcsrc/server/resources.qc @@ -8,47 +8,50 @@ #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,87 +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) +{ + 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 max_amount = GetResourceLimit(e, resource_type); + 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) + if (amount > max_amount && max_amount != RES_LIMIT_NONE) { amount_wasted = amount - max_amount; amount = max_amount; } - .float resource_field = GetResourceField(resource_type); - if (e.(resource_field) != amount) + bool changed = SetResourceExplicit(e, res_type, amount); + if (changed) { - e.(resource_field) = amount; - MUTATOR_CALLHOOK(ResourceAmountChanged, e, resource_type, amount); + MUTATOR_CALLHOOK(ResourceAmountChanged, e, res_type, amount); } if (amount_wasted == 0) { return; } - MUTATOR_CALLHOOK(ResourceWasted, e, resource_type, amount_wasted); + 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); @@ -148,63 +158,107 @@ void GiveResource(entity receiver, int resource_type, float amount) } } -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; } - bool forbid = MUTATOR_CALLHOOK(GiveResourceWithLimit, receiver, - resource_type, amount, limit); + bool forbid = MUTATOR_CALLHOOK(GiveResourceWithLimit, receiver, res_type, amount, limit); if (forbid) { return; } - resource_type = M_ARGV(1, int); + res_type = M_ARGV(1, int); amount = M_ARGV(2, float); limit = M_ARGV(3, float); - if (amount == 0) + if (amount <= 0) { return; } - float current_amount = GetResourceAmount(receiver, resource_type); - if (current_amount + amount > limit) + 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); } -int GetResourceType(.float resource_field) +void TakeResource(entity receiver, int res_type, float amount) { - 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(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); +} + +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;