#include <client/main.qc>
#include <client/mapvoting.qc>
#include <client/player_skeleton.qc>
-#include <client/resources.qc>
#include <client/shownames.qc>
#include <client/teamradar.qc>
#include <client/view.qc>
#include <client/main.qh>
#include <client/mapvoting.qh>
#include <client/player_skeleton.qh>
-#include <client/resources.qh>
#include <client/shownames.qh>
#include <client/teamradar.qh>
#include <client/view.qh>
#include <client/items/items.qh>
#include <client/view.qh>
#include <common/mutators/mutator/nades/nades.qh>
+#include <common/resources/resources.qh>
#include <common/wepent.qh>
// Ammo (#1)
autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
}
-void DrawAmmoItem(vector myPos, vector mySize, int ammoType, bool isCurrent, bool isInfinite)
+void DrawAmmoItem(vector myPos, vector mySize, Resource ammoType, bool isCurrent, bool isInfinite)
{
TC(bool, isCurrent); TC(bool, isInfinite);
if(ammoType == RES_NONE)
}
else
{
- int ammotype;
row = column = 0;
- for(i = 0; i < AMMO_COUNT; ++i)
+ // disabling new-style loop for now to restore original order of ammo types
+ //FOREACH(Resources, it.instanceOfAmmoResource && !it.m_hidden,
+ for(int j = 0; j < AMMO_COUNT; ++j)
{
- ammotype = GetAmmoTypeFromNum(i);
+ Resource ammotype = GetAmmoTypeFromNum(j);
DrawAmmoItem(
pos + vec2(column * (ammo_size.x + offset.x), row * (ammo_size.y + offset.y)),
ammo_size,
#include <client/draw.qh>
#include <client/mapvoting.qh>
-#include <client/resources.qh>
#include <client/teamradar.qh>
#include <common/ent_cs.qh>
#include <common/mutators/mutator/waypoints/all.qh>
+#include <common/resources/cl_resources.qh>
// Radar (#6)
#include <client/draw.qh>
#include <client/hud/panel/racetimer.qh>
-#include <client/resources.qh>
#include <client/view.qh>
#include <common/animdecide.qh>
#include <common/ent_cs.qh>
#include <common/mapinfo.qh>
#include <common/physics/movetypes/movetypes.qh>
#include <common/physics/player.qh>
+#include <common/resources/cl_resources.qh>
#include <lib/csqcmodel/cl_player.qh>
// StrafeHUD (#25)
if(a > 0)
{
+ // TODO: registry handles
switch (it.ammo_type)
{
case RES_SHELLS: ammo_full = autocvar_hud_panel_weapons_ammo_full_shells; break;
+++ /dev/null
-#include "resources.qh"
-
-#include <common/items/item/ammo.qh>
-
-/// \file
-/// \brief Source file that contains implementation of the resource system.
-/// \copyright GNU GPLv2 or any later version.
-
-float GetResource(entity e, int res_type)
-{
- 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 SetResource(entity e, int res_type, float amount)
-{
- SetResourceExplicit(e, res_type, amount);
-}
-
-void TakeResource(entity receiver, int res_type, float amount)
-{
- 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;
- }
- 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 res_type)
-{
- 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;
-}
+++ /dev/null
-#pragma once
-
-/// \file
-/// \brief Header file that describes the resource system.
-/// \copyright GNU GPLv2 or any later version.
-
-#include <common/resources.qh>
-
-// ============================ Public API ====================================
-
-/// \brief Returns the current amount of resource the given entity has.
-/// \param[in] e Entity to check.
-/// \param[in] res_type Type of the resource (a RES_* constant).
-/// \return Current amount of resource the given entity has.
-float GetResource(entity e, int res_type);
-
-/// \brief Sets the resource amount of an entity without calling any hooks.
-/// \param[in,out] e Entity to adjust.
-/// \param[in] res_type Type of the resource (a RES_* constant).
-/// \param[in] amount Amount of resource to set.
-/// \return Boolean for whether the ammo amount was changed
-bool SetResourceExplicit(entity e, int res_type, float amount);
-
-/// \brief Sets the current amount of resource the given entity will have.
-/// \param[in,out] e Entity to adjust.
-/// \param[in] res_type Type of the resource (a RES_* constant).
-/// \param[in] amount Amount of resource to set.
-/// \return No return.
-void SetResource(entity e, int res_type, float amount);
-
-/// \brief Takes an entity some resource.
-/// \param[in,out] receiver Entity to take resource from.
-/// \param[in] res_type Type of the resource (a RES_* constant).
-/// \param[in] amount Amount of resource to take.
-/// \return No return.
-void TakeResource(entity receiver, int res_type, float amount);
-
-/// \brief Takes an entity some resource but not less than a limit.
-/// \param[in,out] receiver Entity to take resource from.
-/// \param[in] res_type Type of the resource (a RES_* constant).
-/// \param[in] amount Amount of resource to take.
-/// \param[in] limit Limit of resources to take.
-/// \return No return.
-void TakeResourceWithLimit(entity receiver, int res_type, float amount, float limit);
-
-// ===================== Legacy and/or internal API ===========================
-
-/// \brief Converts an entity field to resource type.
-/// \param[in] res_field Entity field to convert.
-/// \return Resource type (a RES_* constant).
-int GetResourceType(.float res_field);
-
-/// \brief Converts resource type (a RES_* constant) to entity field.
-/// \param[in] res_type Type of the resource.
-/// \return Entity field for that resource.
-.float GetResourceField(int res_type);
-
-/// \brief Legacy fields for the resources. To be removed.
-.float health;
-.float armorvalue;
#include <client/draw.qh>
#include <client/hud/_mod.qh>
-#include <client/resources.qh>
#include <client/view.qh>
#include <common/constants.qh>
#include <common/ent_cs.qh>
#include <common/net_linked.qh>
+#include <common/resources/cl_resources.qh>
#include <common/teams.qh>
#include <lib/csqcmodel/cl_model.qh>
#include "mutators/_mod.inc"
#include "gamemodes/_mod.inc"
+
+#include "resources/_mod.inc"
#include <common/mapinfo.qc>
#include <common/net_notice.qc>
#include <common/playerstats.qc>
+#include <common/resources.qc>
#include <common/replicate.qc>
#include <common/state.qc>
#include <common/util.qc>
#ifdef CSQC
#include <client/draw.qh>
-#include <client/resources.qh>
#include <client/view.qh>
+#include <common/resources/cl_resources.qh>
#endif
#if defined(CSQC)
#include <common/gamemodes/_mod.qh>
- #include <common/resources.qh>
+ #include <common/resources/resources.qh>
#elif defined(MENUQC)
#elif defined(SVQC)
#include <common/gamemodes/_mod.qh>
- #include <common/resources.qh>
- #include <server/resources.qh>
+ #include <common/resources/resources.qh>
+ #include <common/resources/sv_resources.qh>
#endif
REGISTRY(EntCSProps, BITS(16) - 1)
#include "sv_freezetag.qh"
+#include <common/resources/sv_resources.qh>
#include <server/elimination.qh>
-#include <server/resources.qh>
float autocvar_g_freezetag_frozen_maxtime;
float autocvar_g_freezetag_revive_clearspeed;
#include "pickup.qh"
#include <common/items/all.qh>
+#include <common/resources/resources.qh>
#ifdef SVQC
- #include <common/stats.qh>
+ #include <common/resources/sv_resources.qh>
#include <server/items/items.qh>
- #include <server/resources.qh>
-#endif
-
-#if 1
-.int ammo_none;
-.int ammo_shells;
-.int ammo_nails;
-.int ammo_rockets;
-.int ammo_cells;
-#ifdef SVQC
-const .int ammo_plasma = _STAT(PLASMA);
-const .int ammo_fuel = _STAT(FUEL);
-#else
-.int ammo_plasma;
-.int ammo_fuel;
-#endif
#endif
#ifdef GAMEQC
// get weapon info
entity wpn = REGISTRY_GET(Weapons, nix_weapon);
+ // TODO: registry handles
if(nix_nextchange != this.nix_lastchange_id) // this shall only be called once per round!
{
SetResource(this, RES_SHELLS, 0);
CLASS(OverkillHeavyMachineGun, Weapon)
/* spawnfunc */ ATTRIB(OverkillHeavyMachineGun, m_canonical_spawnfunc, string, "weapon_okhmg");
-/* ammotype */ ATTRIB(OverkillHeavyMachineGun, ammo_type, int, RES_BULLETS);
+/* ammotype */ ATTRIB(OverkillHeavyMachineGun, ammo_type, Resource, RES_BULLETS);
/* impulse */ ATTRIB(OverkillHeavyMachineGun, impulse, int, 3);
/* flags */ ATTRIB(OverkillHeavyMachineGun, spawnflags, int, WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_HIDDEN | WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN | WEP_FLAG_SUPERWEAPON | WEP_FLAG_PENETRATEWALLS);
/* rating */ ATTRIB(OverkillHeavyMachineGun, bot_pickupbasevalue, float, 10000);
CLASS(OverkillMachineGun, Weapon)
/* spawnfunc */ ATTRIB(OverkillMachineGun, m_canonical_spawnfunc, string, "weapon_okmachinegun");
-/* ammotype */ ATTRIB(OverkillMachineGun, ammo_type, int, RES_BULLETS);
+/* ammotype */ ATTRIB(OverkillMachineGun, ammo_type, Resource, RES_BULLETS);
/* impulse */ ATTRIB(OverkillMachineGun, impulse, int, 3);
/* flags */ ATTRIB(OverkillMachineGun, spawnflags, int, WEP_FLAG_HIDDEN | WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN | WEP_FLAG_PENETRATEWALLS | WEP_FLAG_MUTATORBLOCKED);
/* rating */ ATTRIB(OverkillMachineGun, bot_pickupbasevalue, float, 7000);
CLASS(OverkillNex, Weapon)
/* spawnfunc */ ATTRIB(OverkillNex, m_canonical_spawnfunc, string, "weapon_oknex");
-/* ammotype */ ATTRIB(OverkillNex, ammo_type, int, RES_CELLS);
+/* ammotype */ ATTRIB(OverkillNex, ammo_type, Resource, RES_CELLS);
/* impulse */ ATTRIB(OverkillNex, impulse, int, 7);
/* flags */ ATTRIB(OverkillNex, spawnflags, int, WEP_FLAG_HIDDEN | WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN | WEP_FLAG_MUTATORBLOCKED);
/* rating */ ATTRIB(OverkillNex, bot_pickupbasevalue, float, 8000);
CLASS(OverkillRocketPropelledChainsaw, Weapon)
/* spawnfunc */ ATTRIB(OverkillRocketPropelledChainsaw, m_canonical_spawnfunc, string, "weapon_okrpc");
-/* ammotype */ ATTRIB(OverkillRocketPropelledChainsaw, ammo_type, int, RES_ROCKETS);
+/* ammotype */ ATTRIB(OverkillRocketPropelledChainsaw, ammo_type, Resource, RES_ROCKETS);
/* impulse */ ATTRIB(OverkillRocketPropelledChainsaw, impulse, int, 9);
/* flags */ ATTRIB(OverkillRocketPropelledChainsaw, spawnflags, int, WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_HIDDEN | WEP_FLAG_CANCLIMB | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH | WEP_FLAG_SUPERWEAPON);
/* rating */ ATTRIB(OverkillRocketPropelledChainsaw, bot_pickupbasevalue, float, 10000);
CLASS(OverkillShotgun, Weapon)
/* spawnfunc */ ATTRIB(OverkillShotgun, m_canonical_spawnfunc, string, "weapon_okshotgun");
-/* ammotype */ ATTRIB(OverkillShotgun, ammo_type, int, RES_SHELLS);
+/* ammotype */ ATTRIB(OverkillShotgun, ammo_type, Resource, RES_SHELLS);
/* impulse */ ATTRIB(OverkillShotgun, impulse, int, 2);
/* flags */ ATTRIB(OverkillShotgun, spawnflags, int, WEP_FLAG_HIDDEN | WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN | WEP_FLAG_MUTATORBLOCKED);
/* rating */ ATTRIB(OverkillShotgun, bot_pickupbasevalue, float, 6000);
{
string ammoitems = "";
Weapon wep = REGISTRY_GET(Weapons, f1);
+ // TODO: registry handles
switch (wep.ammo_type)
{
case RES_SHELLS: ammoitems = ITEM_Shells.m_name; break;
+++ /dev/null
-#pragma once
-
-/// \file
-/// \brief Header file that describes resource types.
-/// \author Lyberta
-/// \copyright GNU GPLv2 or any later version.
-
-/// \brief Unconditional maximum amount of resources the entity can have.
-const int RES_AMOUNT_HARD_LIMIT = 999;
-const int RES_LIMIT_NONE = -1;
-
-/// \brief Describes the available resource types.
-enum
-{
- RES_NONE, ///< Indicates the lack of resource. Use with caution.
- RES_HEALTH, ///< Health.
- RES_ARMOR, ///< Armor.
- RES_SHELLS, ///< Shells (used by shotgun).
- RES_BULLETS, ///< Bullets (used by machinegun, rifle, HMG)
- RES_ROCKETS, ///< Rockets (used by mortar, hagar, devastator, etc).
- RES_CELLS, ///< Cells (used by electro, crylink, vortex, etc)
- RES_PLASMA, ///< Plasma (unused).
- RES_FUEL ///< Fuel (used by jetpack).
-};
--- /dev/null
+// generated file; do not modify
+#include <common/resources/resources.qc>
+#ifdef CSQC
+ #include <common/resources/cl_resources.qc>
+#endif
+#ifdef SVQC
+ #include <common/resources/sv_resources.qc>
+#endif
--- /dev/null
+// generated file; do not modify
+#include <common/resources/resources.qh>
+#ifdef CSQC
+ #include <common/resources/cl_resources.qh>
+#endif
+#ifdef SVQC
+ #include <common/resources/sv_resources.qh>
+#endif
--- /dev/null
+REGISTER_RESOURCE(HEALTH, NEW(Resource)) {
+ this.netname = "health";
+#ifdef GAMEQC
+ this.m_field = health;
+#endif
+}
+REGISTER_RESOURCE(ARMOR, NEW(Resource)) {
+ this.netname = "armor";
+#ifdef GAMEQC
+ this.m_field = armorvalue;
+#endif
+}
+
+CLASS(AmmoResource, Resource)
+#ifdef CSQC
+ ATTRIB(AmmoResource, m_hidden, bool, false);
+#endif
+ENDCLASS(AmmoResource)
+
+REGISTER_RESOURCE(SHELLS, NEW(AmmoResource)) {
+ this.netname = "shells";
+#ifdef GAMEQC
+ this.m_field = ammo_shells;
+#endif
+}
+REGISTER_RESOURCE(BULLETS, NEW(AmmoResource)) {
+ this.netname = "bullets";
+#ifdef GAMEQC
+ this.m_field = ammo_nails;
+#endif
+}
+REGISTER_RESOURCE(ROCKETS, NEW(AmmoResource)) {
+ this.netname = "rockets";
+#ifdef GAMEQC
+ this.m_field = ammo_rockets;
+#endif
+}
+REGISTER_RESOURCE(CELLS, NEW(AmmoResource)) {
+ this.netname = "cells";
+#ifdef GAMEQC
+ this.m_field = ammo_cells;
+#endif
+}
+REGISTER_RESOURCE(PLASMA, NEW(AmmoResource)) {
+ this.netname = "plasma";
+#ifdef GAMEQC
+ this.m_field = ammo_plasma;
+#endif
+#ifdef CSQC
+ this.m_hidden = true; // WIP ammo type
+#endif
+}
+REGISTER_RESOURCE(FUEL, NEW(AmmoResource)) {
+ this.netname = "fuel";
+#ifdef GAMEQC
+ this.m_field = ammo_fuel;
+#endif
+#ifdef CSQC
+ this.m_hidden = true; // displayed in a separate panel
+#endif
+}
--- /dev/null
+#include "cl_resources.qh"
+
+#include <common/items/item/ammo.qh>
+#include <common/resources/resources.qh>
+
+/// \file
+/// \brief Source file that contains implementation of the resource system.
+/// \copyright GNU GPLv2 or any later version.
+
+float GetResource(entity e, Resource res_type)
+{
+ return e.(GetResourceField(res_type));
+}
+
+bool SetResourceExplicit(entity e, Resource res_type, float amount)
+{
+ .float res_field = GetResourceField(res_type);
+ if (e.(res_field) != amount)
+ {
+ e.(res_field) = amount;
+ return true;
+ }
+ return false;
+}
+
+void SetResource(entity e, Resource res_type, float amount)
+{
+ SetResourceExplicit(e, res_type, amount);
+}
+
+void TakeResource(entity receiver, Resource res_type, float amount)
+{
+ if (amount == 0)
+ {
+ return;
+ }
+ SetResource(receiver, res_type, GetResource(receiver, res_type) - amount);
+}
+
+void TakeResourceWithLimit(entity receiver, Resource res_type, float amount, float limit)
+{
+ 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);
+}
--- /dev/null
+#pragma once
+
+/// \file
+/// \brief Header file that describes the resource system.
+/// \copyright GNU GPLv2 or any later version.
+
+#include <common/resources/resources.qh>
+
+// ============================ Public API ====================================
+
+/// \brief Returns the current amount of resource the given entity has.
+/// \param[in] e Entity to check.
+/// \param[in] res_type Type of the resource (a RES_* constant).
+/// \return Current amount of resource the given entity has.
+float GetResource(entity e, Resource res_type);
+
+/// \brief Sets the resource amount of an entity without calling any hooks.
+/// \param[in,out] e Entity to adjust.
+/// \param[in] res_type Type of the resource (a RES_* constant).
+/// \param[in] amount Amount of resource to set.
+/// \return Boolean for whether the ammo amount was changed
+bool SetResourceExplicit(entity e, Resource res_type, float amount);
+
+/// \brief Sets the current amount of resource the given entity will have.
+/// \param[in,out] e Entity to adjust.
+/// \param[in] res_type Type of the resource (a RES_* constant).
+/// \param[in] amount Amount of resource to set.
+/// \return No return.
+void SetResource(entity e, Resource res_type, float amount);
+
+/// \brief Takes an entity some resource.
+/// \param[in,out] receiver Entity to take resource from.
+/// \param[in] res_type Type of the resource (a RES_* constant).
+/// \param[in] amount Amount of resource to take.
+/// \return No return.
+void TakeResource(entity receiver, Resource res_type, float amount);
+
+/// \brief Takes an entity some resource but not less than a limit.
+/// \param[in,out] receiver Entity to take resource from.
+/// \param[in] res_type Type of the resource (a RES_* constant).
+/// \param[in] amount Amount of resource to take.
+/// \param[in] limit Limit of resources to take.
+/// \return No return.
+void TakeResourceWithLimit(entity receiver, Resource res_type, float amount, float limit);
--- /dev/null
+#include "resources.qh"
+
+#ifdef GAMEQC
+Resource GetResourceType(.float res_field)
+{
+ FOREACH(Resources, it.m_field == res_field, return it);
+ error("GetResourceType: Invalid field.");
+ return RES_NONE;
+}
+
+.float GetResourceField(Resource res_type)
+{
+ return res_type.m_field;
+}
+#endif
--- /dev/null
+#pragma once
+
+#ifdef SVQC
+ #include <common/stats.qh>
+#endif
+
+#ifdef CSQC
+/// \brief Legacy fields for the resources. To be removed.
+.float health;
+.float armorvalue;
+#endif
+
+#if 1
+.int ammo_none;
+.int ammo_shells;
+.int ammo_nails;
+.int ammo_rockets;
+.int ammo_cells;
+#ifdef SVQC
+const .int ammo_plasma = _STAT(PLASMA);
+const .int ammo_fuel = _STAT(FUEL);
+#else
+.int ammo_plasma;
+.int ammo_fuel;
+#endif
+#endif
+
+CLASS(Resource, Object)
+ ATTRIB(Resource, netname, string, "");
+#ifdef GAMEQC
+ ATTRIB(Resource, m_field, .float, health);
+#endif
+ENDCLASS(Resource)
+
+#define REGISTER_RESOURCE(id, inst) REGISTER(Resources, RES, id, m_id, inst)
+REGISTRY(Resources, BITS(4));
+REGISTER_REGISTRY(Resources)
+REGISTRY_SORT(Resources);
+REGISTRY_CHECK(Resources);
+
+REGISTRY_DEFINE_GET(Resources, NULL)
+STATIC_INIT(Resources_renumber) { FOREACH(Resources, true, it.m_id = i); }
+
+/// \brief Unconditional maximum amount of resources the entity can have.
+const int RES_AMOUNT_HARD_LIMIT = 999;
+const int RES_LIMIT_NONE = -1;
+
+/// \brief Describes the available resource types.
+REGISTER_RESOURCE(NONE, NEW(Resource)); ///< Indicates the lack of resource. Use with caution.
+
+#include "all.inc"
+
+#ifdef GAMEQC
+// ===================== Legacy and/or internal API ===========================
+
+/// \brief Converts an entity field to resource type.
+/// \param[in] res_field Entity field to convert.
+/// \return Resource type (a RES_* constant).
+Resource GetResourceType(.float res_field);
+
+/// \brief Converts resource type (a RES_* constant) to entity field.
+/// \param[in] res_type Type of the resource.
+/// \return Entity field for that resource.
+.float GetResourceField(Resource res_type);
+#endif
--- /dev/null
+#include "sv_resources.qh"
+
+/// \file
+/// \brief Source file that contains implementation of the resource system.
+/// \author Lyberta
+/// \copyright GNU GPLv2 or any later version.
+
+#include <common/resources/resources.qh>
+#include <server/mutators/_mod.qh>
+#include <server/world.qh>
+
+float GetResourceLimit(entity e, Resource res_type)
+{
+ if(!IS_PLAYER(e))
+ return RES_LIMIT_NONE; // no limits on non-players
+
+ float limit;
+ // TODO: registry handles
+ switch (res_type)
+ {
+ case RES_HEALTH:
+ {
+ limit = autocvar_g_balance_health_limit;
+ break;
+ }
+ case RES_ARMOR:
+ {
+ limit = autocvar_g_balance_armor_limit;
+ break;
+ }
+ case RES_SHELLS:
+ {
+ limit = g_pickup_shells_max;
+ break;
+ }
+ case RES_BULLETS:
+ {
+ limit = g_pickup_nails_max;
+ break;
+ }
+ case RES_ROCKETS:
+ {
+ limit = g_pickup_rockets_max;
+ break;
+ }
+ case RES_CELLS:
+ {
+ limit = g_pickup_cells_max;
+ break;
+ }
+ case RES_PLASMA:
+ {
+ limit = g_pickup_plasma_max;
+ break;
+ }
+ case RES_FUEL:
+ {
+ limit = autocvar_g_balance_fuel_limit;
+ break;
+ }
+ default:
+ {
+ error("GetResourceLimit: Invalid resource type.");
+ return 0;
+ }
+ }
+ MUTATOR_CALLHOOK(GetResourceLimit, e, res_type, limit);
+ limit = M_ARGV(2, float);
+ if (limit > RES_AMOUNT_HARD_LIMIT)
+ {
+ limit = RES_AMOUNT_HARD_LIMIT;
+ }
+ return limit;
+}
+
+float GetResource(entity e, Resource res_type)
+{
+ return e.(GetResourceField(res_type));
+}
+
+bool SetResourceExplicit(entity e, Resource res_type, float amount)
+{
+ .float res_field = GetResourceField(res_type);
+ if (e.(res_field) != amount)
+ {
+ e.(res_field) = amount;
+ return true;
+ }
+ return false;
+}
+
+void SetResource(entity e, Resource res_type, float amount)
+{
+ bool forbid = MUTATOR_CALLHOOK(SetResource, e, res_type, amount);
+ if (forbid)
+ {
+ return;
+ }
+ res_type = M_ARGV(1, entity);
+ amount = M_ARGV(2, float);
+ 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)
+ {
+ amount_wasted = amount - max_amount;
+ amount = max_amount;
+ }
+ bool changed = SetResourceExplicit(e, res_type, amount);
+ if (changed)
+ {
+ MUTATOR_CALLHOOK(ResourceAmountChanged, e, res_type, amount);
+ }
+ if (amount_wasted == 0)
+ {
+ return;
+ }
+ MUTATOR_CALLHOOK(ResourceWasted, e, res_type, amount_wasted);
+}
+
+void GiveResource(entity receiver, Resource res_type, float amount)
+{
+ if (amount <= 0)
+ {
+ return;
+ }
+ bool forbid = MUTATOR_CALLHOOK(GiveResource, receiver, res_type, amount);
+ if (forbid)
+ {
+ return;
+ }
+ res_type = M_ARGV(1, entity);
+ amount = M_ARGV(2, float);
+ if (amount <= 0)
+ {
+ return;
+ }
+ SetResource(receiver, res_type, GetResource(receiver, res_type) + amount);
+ // TODO: registry handles
+ switch (res_type)
+ {
+ case RES_HEALTH:
+ {
+ receiver.pauserothealth_finished =
+ max(receiver.pauserothealth_finished, time +
+ autocvar_g_balance_pause_health_rot);
+ return;
+ }
+ case RES_ARMOR:
+ {
+ receiver.pauserotarmor_finished =
+ max(receiver.pauserotarmor_finished, time +
+ autocvar_g_balance_pause_armor_rot);
+ return;
+ }
+ case RES_FUEL:
+ {
+ receiver.pauserotfuel_finished = max(receiver.pauserotfuel_finished,
+ time + autocvar_g_balance_pause_fuel_rot);
+ return;
+ }
+ }
+}
+
+void GiveResourceWithLimit(entity receiver, Resource 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, entity);
+ 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, Resource 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, entity);
+ amount = M_ARGV(2, float);
+ if (amount <= 0)
+ {
+ return;
+ }
+ SetResource(receiver, res_type, GetResource(receiver, res_type) - amount);
+}
+
+void TakeResourceWithLimit(entity receiver, Resource 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, entity);
+ 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);
+}
--- /dev/null
+#pragma once
+
+/// \file
+/// \brief Header file that describes the resource system.
+/// \author Lyberta
+/// \copyright GNU GPLv2 or any later version.
+
+#include <common/resources/resources.qh>
+
+// TODO: split resources into their own files, registry based
+float autocvar_g_balance_health_limit;
+int autocvar_g_balance_armor_limit;
+float autocvar_g_balance_fuel_limit;
+float autocvar_g_balance_armor_regen;
+float autocvar_g_balance_armor_regenlinear;
+int autocvar_g_balance_armor_regenstable;
+float autocvar_g_balance_armor_rot;
+float autocvar_g_balance_armor_rotlinear;
+int autocvar_g_balance_armor_rotstable;
+float autocvar_g_balance_fuel_regen;
+float autocvar_g_balance_fuel_regenlinear;
+int autocvar_g_balance_fuel_regenstable;
+float autocvar_g_balance_fuel_rot;
+float autocvar_g_balance_fuel_rotlinear;
+int autocvar_g_balance_fuel_rotstable;
+float autocvar_g_balance_health_regen;
+float autocvar_g_balance_health_regenlinear;
+float autocvar_g_balance_health_regenstable;
+float autocvar_g_balance_health_rot;
+float autocvar_g_balance_health_rotlinear;
+float autocvar_g_balance_health_rotstable;
+float autocvar_g_balance_pause_armor_rot;
+float autocvar_g_balance_pause_fuel_regen;
+float autocvar_g_balance_pause_fuel_rot;
+float autocvar_g_balance_pause_health_regen;
+float autocvar_g_balance_pause_health_rot;
+
+// ============================ Public API ====================================
+
+/// \brief Returns the maximum amount of the given resource.
+/// \param[in] e Entity to check.
+/// \param[in] res_type Type of the resource (a RES_* constant).
+/// \return Maximum amount of the given resource.
+float GetResourceLimit(entity e, Resource res_type);
+
+/// \brief Returns the current amount of resource the given entity has.
+/// \param[in] e Entity to check.
+/// \param[in] res_type Type of the resource (a RES_* constant).
+/// \return Current amount of resource the given entity has.
+float GetResource(entity e, Resource res_type);
+
+/// \brief Sets the resource amount of an entity without calling any hooks.
+/// \param[in,out] e Entity to adjust.
+/// \param[in] res_type Type of the resource (a RES_* constant).
+/// \param[in] amount Amount of resource to set.
+/// \return Boolean for whether the ammo amount was changed
+bool SetResourceExplicit(entity e, Resource res_type, float amount);
+
+/// \brief Sets the current amount of resource the given entity will have
+/// but limited to the max amount allowed for the resource type.
+/// \param[in,out] e Entity to adjust.
+/// \param[in] res_type Type of the resource (a RES_* constant).
+/// \param[in] amount Amount of resource to set.
+/// \return No return.
+void SetResource(entity e, Resource res_type, float amount);
+
+/// \brief Gives an entity some resource.
+/// \param[in,out] receiver Entity to give resource to.
+/// \param[in] res_type Type of the resource (a RES_* constant).
+/// \param[in] amount Amount of resource to give.
+/// \return No return.
+void GiveResource(entity receiver, Resource res_type, float amount);
+
+/// \brief Gives an entity some resource but not more than a limit.
+/// \param[in,out] receiver Entity to give resource to.
+/// \param[in] res_type Type of the resource (a RES_* constant).
+/// \param[in] amount Amount of resource to give.
+/// \param[in] limit Limit of resources to give.
+/// \return No return.
+void GiveResourceWithLimit(entity receiver, Resource res_type, float amount, float limit);
+
+/// \brief Takes an entity some resource.
+/// \param[in,out] receiver Entity to take resource from.
+/// \param[in] res_type Type of the resource (a RES_* constant).
+/// \param[in] amount Amount of resource to take.
+/// \return No return.
+void TakeResource(entity receiver, Resource res_type, float amount);
+
+/// \brief Takes an entity some resource but not less than a limit.
+/// \param[in,out] receiver Entity to take resource from.
+/// \param[in] res_type Type of the resource (a RES_* constant).
+/// \param[in] amount Amount of resource to take.
+/// \param[in] limit Limit of resources to take.
+/// \return No return.
+void TakeResourceWithLimit(entity receiver, Resource res_type, float amount, float limit);
}
}
-void vehicles_regen_resource(entity this, float timer, .float regen_field, float field_max, float rpause, float regen, float delta_time, float _healthscale, int resource)
+void vehicles_regen_resource(entity this, float timer, .float regen_field, float field_max, float rpause, float regen, float delta_time, float _healthscale, Resource resource)
{
float resource_amount = GetResource(this, resource);
return result;
}
-string GetAmmoPicture(int ammotype)
+// TODO: registry handles for below functions
+string GetAmmoPicture(Resource ammotype)
{
switch (ammotype)
{
}
}
-string GetAmmoName(int ammotype)
+string GetAmmoName(Resource ammotype)
{
switch (ammotype)
{
}
}
-entity GetAmmoItem(int ammotype)
+entity GetAmmoItem(Resource ammotype)
{
switch (ammotype)
{
case RES_PLASMA: return ITEM_Plasma;
case RES_FUEL: return ITEM_JetpackFuel;
}
- LOG_WARNF("Invalid ammo type %d ", ammotype);
+ LOG_WARNF("Invalid ammo type %d ", ammotype.m_id);
return NULL;
// WEAPONTODO: use this generic func to reduce duplication ?
// GetAmmoPicture GetAmmoName notif_arg_item_wepammo ammo_pickupevalfunc ?
}
#ifdef CSQC
-int GetAmmoTypeFromNum(int i)
+Resource GetAmmoTypeFromNum(int i)
{
switch (i)
{
}
}
-int GetAmmoStat(int ammotype)
+int GetAmmoStat(Resource ammotype)
{
switch (ammotype)
{
#pragma once
-#include <common/resources.qh>
#include <common/items/item/pickup.qh>
+#include <common/resources/resources.qh>
#include <common/stats.qh>
#ifdef SVQC
/** control what happens when this weapon is spawned */
METHOD(Weapon, m_spawnfunc_hookreplace, Weapon(Weapon this, entity e)) { return this; }
/** M: ammotype : main ammo type */
- ATTRIB(Weapon, ammo_type, int, RES_NONE);
+ ATTRIB(Weapon, ammo_type, Resource, RES_NONE);
/** M: impulse : weapon impulse */
ATTRIB(Weapon, impulse, int, -1);
/** M: flags : WEPSPAWNFLAG_... combined */
string W_FixWeaponOrder_ForceComplete(string order);
WepSet W_RandomWeapons(entity e, WepSet remaining, int n);
-string GetAmmoPicture(int ammotype);
+string GetAmmoPicture(Resource ammotype);
-string GetAmmoName(int ammotype);
+string GetAmmoName(Resource ammotype);
-entity GetAmmoItem(int ammotype);
+entity GetAmmoItem(Resource ammotype);
#ifdef CSQC
-int GetAmmoTypeFromNum(int i);
-int GetAmmoStat(int ammotype);
+Resource GetAmmoTypeFromNum(int i);
+
+int GetAmmoStat(Resource ammotype);
#endif
string W_Sound(string w_snd);
CLASS(Arc, Weapon)
/* spawnfunc */ ATTRIB(Arc, m_canonical_spawnfunc, string, "weapon_arc");
-/* ammotype */ ATTRIB(Arc, ammo_type, int, RES_CELLS);
+/* ammotype */ ATTRIB(Arc, ammo_type, Resource, RES_CELLS);
/* impulse */ ATTRIB(Arc, impulse, int, 3);
/* flags */ ATTRIB(Arc, spawnflags, int, WEP_TYPE_HITSCAN);
/* rating */ ATTRIB(Arc, bot_pickupbasevalue, float, 8000);
CLASS(Blaster, Weapon)
/* spawnfunc */ ATTRIB(Blaster, m_canonical_spawnfunc, string, "weapon_blaster");
-/* ammotype */ //ATTRIB(Blaster, ammo_type, int, RES_NONE);
+/* ammotype */ //ATTRIB(Blaster, ammo_type, Resource, RES_NONE);
/* impulse */ ATTRIB(Blaster, impulse, int, 1);
/* flags */ ATTRIB(Blaster, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH);
/* rating */ ATTRIB(Blaster, bot_pickupbasevalue, float, 0);
CLASS(Crylink, Weapon)
/* spawnfunc */ ATTRIB(Crylink, m_canonical_spawnfunc, string, "weapon_crylink");
-/* ammotype */ ATTRIB(Crylink, ammo_type, int, RES_CELLS);
+/* ammotype */ ATTRIB(Crylink, ammo_type, Resource, RES_CELLS);
/* impulse */ ATTRIB(Crylink, impulse, int, 6);
/* flags */ ATTRIB(Crylink, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH | WEP_FLAG_CANCLIMB);
/* rating */ ATTRIB(Crylink, bot_pickupbasevalue, float, 6000);
CLASS(Devastator, Weapon)
/* spawnfunc */ ATTRIB(Devastator, m_canonical_spawnfunc, string, "weapon_devastator");
-/* ammotype */ ATTRIB(Devastator, ammo_type, int, RES_ROCKETS);
+/* ammotype */ ATTRIB(Devastator, ammo_type, Resource, RES_ROCKETS);
/* impulse */ ATTRIB(Devastator, impulse, int, 9);
/* flags */ ATTRIB(Devastator, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH);
/* rating */ ATTRIB(Devastator, bot_pickupbasevalue, float, 8000);
CLASS(Electro, Weapon)
/* spawnfunc */ ATTRIB(Electro, m_canonical_spawnfunc, string, "weapon_electro");
-/* ammotype */ ATTRIB(Electro, ammo_type, int, RES_CELLS);
+/* ammotype */ ATTRIB(Electro, ammo_type, Resource, RES_CELLS);
/* impulse */ ATTRIB(Electro, impulse, int, 5);
/* flags */ ATTRIB(Electro, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH);
/* rating */ ATTRIB(Electro, bot_pickupbasevalue, float, 5000);
CLASS(Fireball, Weapon)
/* spawnfunc */ ATTRIB(Fireball, m_canonical_spawnfunc, string, "weapon_fireball");
-/* ammotype */ //ATTRIB(Fireball, ammo_type, int, RES_NONE);
+/* ammotype */ //ATTRIB(Fireball, ammo_type, Resource, RES_NONE);
/* impulse */ ATTRIB(Fireball, impulse, int, 9);
/* flags */ ATTRIB(Fireball, spawnflags, int, WEP_FLAG_SUPERWEAPON | WEP_TYPE_SPLASH | WEP_FLAG_NODUAL);
/* rating */ ATTRIB(Fireball, bot_pickupbasevalue, float, 5000);
CLASS(Hagar, Weapon)
/* spawnfunc */ ATTRIB(Hagar, m_canonical_spawnfunc, string, "weapon_hagar");
-/* ammotype */ ATTRIB(Hagar, ammo_type, int, RES_ROCKETS);
+/* ammotype */ ATTRIB(Hagar, ammo_type, Resource, RES_ROCKETS);
/* impulse */ ATTRIB(Hagar, impulse, int, 8);
/* flags */ ATTRIB(Hagar, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH);
/* rating */ ATTRIB(Hagar, bot_pickupbasevalue, float, 6000);
CLASS(HLAC, Weapon)
/* spawnfunc */ ATTRIB(HLAC, m_canonical_spawnfunc, string, "weapon_hlac");
-/* ammotype */ ATTRIB(HLAC, ammo_type, int, RES_CELLS);
+/* ammotype */ ATTRIB(HLAC, ammo_type, Resource, RES_CELLS);
/* impulse */ ATTRIB(HLAC, impulse, int, 6);
/* flags */ ATTRIB(HLAC, spawnflags, int, WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH);
/* rating */ ATTRIB(HLAC, bot_pickupbasevalue, float, 4000);
CLASS(Hook, Weapon)
/* spawnfunc */ ATTRIB(Hook, m_canonical_spawnfunc, string, "weapon_hook");
-/* ammotype */ ATTRIB(Hook, ammo_type, int, RES_FUEL);
+/* ammotype */ ATTRIB(Hook, ammo_type, Resource, RES_FUEL);
/* impulse */ ATTRIB(Hook, impulse, int, 0);
/* flags */ ATTRIB(Hook, spawnflags, int, WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH | WEP_FLAG_NOTRUEAIM);
/* rating */ ATTRIB(Hook, bot_pickupbasevalue, float, 0);
CLASS(MachineGun, Weapon)
/* spawnfunc */ ATTRIB(MachineGun, m_canonical_spawnfunc, string, "weapon_machinegun");
-/* ammotype */ ATTRIB(MachineGun, ammo_type, int, RES_BULLETS);
+/* ammotype */ ATTRIB(MachineGun, ammo_type, Resource, RES_BULLETS);
/* impulse */ ATTRIB(MachineGun, impulse, int, 3);
/* flags */ ATTRIB(MachineGun, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN | WEP_FLAG_PENETRATEWALLS | WEP_FLAG_BLEED);
/* rating */ ATTRIB(MachineGun, bot_pickupbasevalue, float, 7000);
CLASS(MineLayer, Weapon)
/* spawnfunc */ ATTRIB(MineLayer, m_canonical_spawnfunc, string, "weapon_minelayer");
-/* ammotype */ ATTRIB(MineLayer, ammo_type, int, RES_ROCKETS);
+/* ammotype */ ATTRIB(MineLayer, ammo_type, Resource, RES_ROCKETS);
/* impulse */ ATTRIB(MineLayer, impulse, int, 4);
/* flags */ ATTRIB(MineLayer, spawnflags, int, WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH);
/* rating */ ATTRIB(MineLayer, bot_pickupbasevalue, float, 7000);
CLASS(Mortar, Weapon)
/* spawnfunc */ ATTRIB(Mortar, m_canonical_spawnfunc, string, "weapon_mortar");
-/* ammotype */ ATTRIB(Mortar, ammo_type, int, RES_ROCKETS);
+/* ammotype */ ATTRIB(Mortar, ammo_type, Resource, RES_ROCKETS);
/* impulse */ ATTRIB(Mortar, impulse, int, 4);
/* flags */ ATTRIB(Mortar, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH | WEP_FLAG_NOTRUEAIM);
/* rating */ ATTRIB(Mortar, bot_pickupbasevalue, float, 7000);
CLASS(PortoLaunch, Weapon)
/* spawnfunc */ ATTRIB(PortoLaunch, m_canonical_spawnfunc, string, "weapon_porto");
-/* ammotype */ ATTRIB(PortoLaunch, ammo_type, int, RES_NONE);
+/* ammotype */ ATTRIB(PortoLaunch, ammo_type, Resource, RES_NONE);
/* impulse */ ATTRIB(PortoLaunch, impulse, int, 0);
/* flags */ ATTRIB(PortoLaunch, spawnflags, int, WEP_TYPE_OTHER | WEP_FLAG_SUPERWEAPON | WEP_FLAG_NODUAL | WEP_FLAG_NOTRUEAIM);
/* rating */ ATTRIB(PortoLaunch, bot_pickupbasevalue, float, 0);
CLASS(Rifle, Weapon)
/* spawnfunc */ ATTRIB(Rifle, m_canonical_spawnfunc, string, "weapon_rifle");
-/* ammotype */ ATTRIB(Rifle, ammo_type, int, RES_BULLETS);
+/* ammotype */ ATTRIB(Rifle, ammo_type, Resource, RES_BULLETS);
/* impulse */ ATTRIB(Rifle, impulse, int, 7);
/* flags */ ATTRIB(Rifle, spawnflags, int, WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN | WEP_FLAG_PENETRATEWALLS);
/* rating */ ATTRIB(Rifle, bot_pickupbasevalue, float, 7000);
CLASS(Seeker, Weapon)
/* spawnfunc */ ATTRIB(Seeker, m_canonical_spawnfunc, string, "weapon_seeker");
-/* ammotype */ ATTRIB(Seeker, ammo_type, int, RES_ROCKETS);
+/* ammotype */ ATTRIB(Seeker, ammo_type, Resource, RES_ROCKETS);
/* impulse */ ATTRIB(Seeker, impulse, int, 8);
/* flags */ ATTRIB(Seeker, spawnflags, int, WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH);
/* rating */ ATTRIB(Seeker, bot_pickupbasevalue, float, 5000);
CLASS(Shockwave, Weapon)
/* spawnfunc */ ATTRIB(Shockwave, m_canonical_spawnfunc, string, "weapon_shockwave");
-/* ammotype */ //ATTRIB(Shockwave, ammo_type, int, RES_NONE);
+/* ammotype */ //ATTRIB(Shockwave, ammo_type, Resource, RES_NONE);
/* impulse */ ATTRIB(Shockwave, impulse, int, 2);
/* flags */ ATTRIB(Shockwave, spawnflags, int, WEP_FLAG_HIDDEN | WEP_TYPE_HITSCAN | WEP_FLAG_CANCLIMB | WEP_TYPE_MELEE_SEC);
/* rating */ ATTRIB(Shockwave, bot_pickupbasevalue, float, 3000);
CLASS(Shotgun, Weapon)
/* spawnfunc */ ATTRIB(Shotgun, m_canonical_spawnfunc, string, "weapon_shotgun");
-/* ammotype */ ATTRIB(Shotgun, ammo_type, int, RES_SHELLS);
+/* ammotype */ ATTRIB(Shotgun, ammo_type, Resource, RES_SHELLS);
/* impulse */ ATTRIB(Shotgun, impulse, int, 2);
/* flags */ ATTRIB(Shotgun, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN | WEP_TYPE_MELEE_SEC | WEP_FLAG_BLEED);
/* rating */ ATTRIB(Shotgun, bot_pickupbasevalue, float, 6000);
CLASS(Vaporizer, Weapon)
/* spawnfunc */ ATTRIB(Vaporizer, m_canonical_spawnfunc, string, "weapon_vaporizer");
-/* ammotype */ ATTRIB(Vaporizer, ammo_type, int, RES_CELLS);
+/* ammotype */ ATTRIB(Vaporizer, ammo_type, Resource, RES_CELLS);
/* impulse */ ATTRIB(Vaporizer, impulse, int, 7);
/* flags */ ATTRIB(Vaporizer, spawnflags, int, WEP_FLAG_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_FLAG_SUPERWEAPON | WEP_TYPE_HITSCAN | WEP_FLAG_NODUAL);
/* rating */ ATTRIB(Vaporizer, bot_pickupbasevalue, float, 10000);
CLASS(Vortex, Weapon)
/* spawnfunc */ ATTRIB(Vortex, m_canonical_spawnfunc, string, "weapon_vortex");
-/* ammotype */ ATTRIB(Vortex, ammo_type, int, RES_CELLS);
+/* ammotype */ ATTRIB(Vortex, ammo_type, Resource, RES_CELLS);
/* impulse */ ATTRIB(Vortex, impulse, int, 7);
/* flags */ ATTRIB(Vortex, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN);
/* rating */ ATTRIB(Vortex, bot_pickupbasevalue, float, 8000);
#include <server/player.qc>
#include <server/portals.qc>
#include <server/race.qc>
-#include <server/resources.qc>
#include <server/round_handler.qc>
#include <server/scores.qc>
#include <server/scores_rules.qc>
#include <server/player.qh>
#include <server/portals.qh>
#include <server/race.qh>
-#include <server/resources.qh>
#include <server/round_handler.qh>
#include <server/scores.qh>
#include <server/scores_rules.qh>
#include "roles.qh"
+#include <common/resources/sv_resources.qh>
#include <common/stats.qh>
#include <common/mutators/mutator/powerups/_mod.qh>
#include <common/mutators/mutator/status_effects/_mod.qh>
#include <server/items/items.qh>
#include <server/items/spawning.qh>
#include <server/mutators/_mod.qh>
-#include <server/resources.qh>
void havocbot_goalrating_waypoints(entity this, float ratingscale, vector org, float sradius)
{
#include <common/monsters/_mod.qh>
#include <common/mutators/mutator/status_effects/_mod.qh>
#include <common/physics/player.qh>
+#include <common/resources/sv_resources.qh>
#include <common/stats.qh>
#include <common/util.qh>
#include <common/weapons/_all.qh>
#include <server/mutators/_mod.qh>
#include <server/player.qh>
#include <server/race.qh>
-#include <server/resources.qh>
#include <server/world.qh>
#ifdef NOCHEATS
#include <common/notifications/all.qh>
#include <common/physics/player.qh>
#include <common/playerstats.qh>
+#include <common/resources/sv_resources.qh>
#include <common/state.qh>
#include <common/stats.qh>
#include <common/vehicles/all.qh>
#include <server/player.qh>
#include <server/portals.qh>
#include <server/race.qh>
-#include <server/resources.qh>
#include <server/scores.qh>
#include <server/scores_rules.qh>
#include <server/spawnpoints.qh>
return max(stable, current + (stable - current) * rotfactor * rotframetime);
}
-void RotRegen(entity this, int res, float limit_mod,
+void RotRegen(entity this, Resource res, float limit_mod,
float regenstable, float regenfactor, float regenlinear, float regenframetime,
float rotstable, float rotfactor, float rotlinear, float rotframetime)
{
#include "utils.qh"
#include <server/intermission.qh>
+//#include <common/resources/resources.qh>
#include <common/replicate.qh>
#include <common/sounds/all.qh>
void play_countdown(entity this, float finished, Sound samp);
void player_powerups_remove_all(entity this);
-void RotRegen(entity this, float current, float limit_mod,
+// NOTE: current type is Resource (avoiding circular includes!)
+void RotRegen(entity this, entity current, float limit_mod,
float regenstable, float regenfactor, float regenlinear, float regenframetime,
float rotstable, float rotfactor, float rotlinear, float rotframetime);
#include <common/mutators/mutator/powerups/_mod.qh>
#include <common/mutators/mutator/status_effects/_mod.qh>
#include <common/notifications/all.qh>
+#include <common/resources/sv_resources.qh>
#include <common/stats.qh>
#include <common/weapons/_all.qh>
#include <common/weapons/_all.qh>
#include <server/client.qh>
#include <server/items/items.qh>
#include <server/items/spawning.qh>
-#include <server/resources.qh>
#include <server/world.qh>
/***********************
#include <common/physics/movetypes/movetypes.qh>
#include <common/physics/player.qh>
#include <common/playerstats.qh>
+#include <common/resources/sv_resources.qh>
#include <common/state.qh>
#include <common/teams.qh>
#include <common/util.qh>
#include <server/items/items.qh>
#include <server/main.qh>
#include <server/mutators/_mod.qh>
-#include <server/resources.qh>
#include <server/scores.qh>
#include <server/spawnpoints.qh>
#include <server/teamplay.qh>
#include <common/mutators/mutator/powerups/_mod.qh>
#include <common/mutators/mutator/status_effects/_mod.qh>
#include <common/notifications/all.qh>
+#include <common/resources/resources.qh>
#include <common/util.qh>
#include <common/weapons/_all.qh>
#include <common/wepent.qh>
}
}
-bool Item_GiveAmmoTo(entity item, entity player, int res_type, float ammomax)
+bool Item_GiveAmmoTo(entity item, entity player, Resource res_type, float ammomax)
{
float amount = GetResource(item, res_type);
if (amount == 0)
else if(v0 > v1)
e.(regenfield) = max(e.(regenfield), time + regentime);
}
-bool GiveResourceValue(entity e, int res_type, int op, int val)
+bool GiveResourceValue(entity e, Resource res_type, int op, int val)
{
int v0 = GetResource(e, res_type);
float new_val = 0;
#pragma once
+#include <common/resources/resources.qh>
#include <common/sounds/sound.qh>
float autocvar_g_balance_superweapons_time;
/// \return No return.
void GiveRandomWeapons(entity receiver, int num_weapons, string weapon_names, entity ammo_entity);
-bool Item_GiveAmmoTo(entity item, entity player, int res_type, float ammomax);
+bool Item_GiveAmmoTo(entity item, entity player, Resource res_type, float ammomax);
bool Item_GiveTo(entity item, entity player);
resource limit. */
#define EV_GetResourceLimit(i, o) \
/** checked entity */ i(entity, MUTATOR_ARGV_0_entity) \
- /** resource type */ i(int, MUTATOR_ARGV_1_int) \
+ /** resource type */ i(entity, MUTATOR_ARGV_1_entity) \
/** limit */ i(float, MUTATOR_ARGV_2_float) \
/**/ o(float, MUTATOR_ARGV_2_float) \
/**/
constants for resource types. Return true to forbid the change. */
#define EV_SetResource(i, o) \
/** checked entity */ i(entity, MUTATOR_ARGV_0_entity) \
- /** resource type */ i(int, MUTATOR_ARGV_1_int) \
- /**/ o(int, MUTATOR_ARGV_1_int) \
+ /** resource type */ i(entity, MUTATOR_ARGV_1_entity) \
+ /**/ o(entity, MUTATOR_ARGV_1_entity) \
/** amount */ i(float, MUTATOR_ARGV_2_float) \
/**/ o(float, MUTATOR_ARGV_2_float) \
/**/
above resource limit so it was not given. */
#define EV_ResourceAmountChanged(i, o) \
/** checked entity */ i(entity, MUTATOR_ARGV_0_entity) \
- /** resource type */ i(int, MUTATOR_ARGV_1_int) \
+ /** resource type */ i(entity, MUTATOR_ARGV_1_entity) \
/** amount */ i(float, MUTATOR_ARGV_2_float) \
/**/
MUTATOR_HOOKABLE(ResourceAmountChanged, EV_ResourceAmountChanged);
of resource that is above resource limit so it was not given. */
#define EV_ResourceWasted(i, o) \
/** checked entity */ i(entity, MUTATOR_ARGV_0_entity) \
- /** resource type */ i(int, MUTATOR_ARGV_1_int) \
+ /** resource type */ i(entity, MUTATOR_ARGV_1_entity) \
/** amount wasted */ i(float, MUTATOR_ARGV_2_float) \
/**/
MUTATOR_HOOKABLE(ResourceWasted, EV_ResourceWasted);
NOTE: This hook is also called by GiveResourceWithLimit */
#define EV_GiveResource(i, o) \
/** receiver */ i(entity, MUTATOR_ARGV_0_entity) \
- /** resource type */ i(int, MUTATOR_ARGV_1_int) \
- /**/ o(int, MUTATOR_ARGV_1_int) \
+ /** resource type */ i(entity, MUTATOR_ARGV_1_entity) \
+ /**/ o(entity, MUTATOR_ARGV_1_entity) \
/** amount */ i(float, MUTATOR_ARGV_2_float) \
/**/ o(float, MUTATOR_ARGV_2_float) \
/**/
RES_* constants for resource types. Return true to forbid giving. */
#define EV_GiveResourceWithLimit(i, o) \
/** receiver */ i(entity, MUTATOR_ARGV_0_entity) \
- /** resource type */ i(int, MUTATOR_ARGV_1_int) \
- /**/ o(int, MUTATOR_ARGV_1_int) \
+ /** resource type */ i(entity, MUTATOR_ARGV_1_entity) \
+ /**/ o(entity, MUTATOR_ARGV_1_entity) \
/** amount */ i(float, MUTATOR_ARGV_2_float) \
/**/ o(float, MUTATOR_ARGV_2_float) \
/** limit */ i(float, MUTATOR_ARGV_3_float) \
NOTE: This hook is also called by TakeResourceWithLimit */
#define EV_TakeResource(i, o) \
/** receiver */ i(entity, MUTATOR_ARGV_0_entity) \
- /** resource type */ i(int, MUTATOR_ARGV_1_int) \
- /**/ o(int, MUTATOR_ARGV_1_int) \
+ /** resource type */ i(entity, MUTATOR_ARGV_1_entity) \
+ /**/ o(entity, MUTATOR_ARGV_1_entity) \
/** amount */ i(float, MUTATOR_ARGV_2_float) \
/**/ o(float, MUTATOR_ARGV_2_float) \
/**/
RES_* constants for resource types. Return true to forbid giving. */
#define EV_TakeResourceWithLimit(i, o) \
/** receiver */ i(entity, MUTATOR_ARGV_0_entity) \
- /** resource type */ i(int, MUTATOR_ARGV_1_int) \
- /**/ o(int, MUTATOR_ARGV_1_int) \
+ /** resource type */ i(entity, MUTATOR_ARGV_1_entity) \
+ /**/ o(entity, MUTATOR_ARGV_1_entity) \
/** amount */ i(float, MUTATOR_ARGV_2_float) \
/**/ o(float, MUTATOR_ARGV_2_float) \
/** limit */ i(float, MUTATOR_ARGV_3_float) \
+++ /dev/null
-#include "resources.qh"
-
-/// \file
-/// \brief Source file that contains implementation of the resource system.
-/// \author Lyberta
-/// \copyright GNU GPLv2 or any later version.
-
-#include <server/mutators/_mod.qh>
-#include <server/world.qh>
-
-float GetResourceLimit(entity e, int res_type)
-{
- if(!IS_PLAYER(e))
- return RES_LIMIT_NONE; // no limits on non-players
-
- float limit;
- switch (res_type)
- {
- case RES_HEALTH:
- {
- limit = autocvar_g_balance_health_limit;
- break;
- }
- case RES_ARMOR:
- {
- limit = autocvar_g_balance_armor_limit;
- break;
- }
- case RES_SHELLS:
- {
- limit = g_pickup_shells_max;
- break;
- }
- case RES_BULLETS:
- {
- limit = g_pickup_nails_max;
- break;
- }
- case RES_ROCKETS:
- {
- limit = g_pickup_rockets_max;
- break;
- }
- case RES_CELLS:
- {
- limit = g_pickup_cells_max;
- break;
- }
- case RES_PLASMA:
- {
- limit = g_pickup_plasma_max;
- break;
- }
- case RES_FUEL:
- {
- limit = autocvar_g_balance_fuel_limit;
- break;
- }
- default:
- {
- error("GetResourceLimit: Invalid resource type.");
- return 0;
- }
- }
- MUTATOR_CALLHOOK(GetResourceLimit, e, res_type, limit);
- limit = M_ARGV(2, float);
- if (limit > RES_AMOUNT_HARD_LIMIT)
- {
- limit = RES_AMOUNT_HARD_LIMIT;
- }
- return limit;
-}
-
-float GetResource(entity e, int res_type)
-{
- 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 SetResource(entity e, int res_type, float amount)
-{
- bool forbid = MUTATOR_CALLHOOK(SetResource, e, res_type, amount);
- if (forbid)
- {
- return;
- }
- res_type = M_ARGV(1, int);
- amount = M_ARGV(2, float);
- 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)
- {
- amount_wasted = amount - max_amount;
- amount = max_amount;
- }
- bool changed = SetResourceExplicit(e, res_type, amount);
- if (changed)
- {
- MUTATOR_CALLHOOK(ResourceAmountChanged, e, res_type, amount);
- }
- if (amount_wasted == 0)
- {
- return;
- }
- MUTATOR_CALLHOOK(ResourceWasted, e, res_type, amount_wasted);
-}
-
-void GiveResource(entity receiver, int res_type, float amount)
-{
- if (amount <= 0)
- {
- return;
- }
- bool forbid = MUTATOR_CALLHOOK(GiveResource, 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);
- switch (res_type)
- {
- case RES_HEALTH:
- {
- receiver.pauserothealth_finished =
- max(receiver.pauserothealth_finished, time +
- autocvar_g_balance_pause_health_rot);
- return;
- }
- case RES_ARMOR:
- {
- receiver.pauserotarmor_finished =
- max(receiver.pauserotarmor_finished, time +
- autocvar_g_balance_pause_armor_rot);
- return;
- }
- case RES_FUEL:
- {
- receiver.pauserotfuel_finished = max(receiver.pauserotfuel_finished,
- time + autocvar_g_balance_pause_fuel_rot);
- return;
- }
- }
-}
-
-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)
-{
- 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);
-}
-
-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 res_type)
-{
- 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;
-}
+++ /dev/null
-#pragma once
-
-/// \file
-/// \brief Header file that describes the resource system.
-/// \author Lyberta
-/// \copyright GNU GPLv2 or any later version.
-
-#include <common/resources.qh>
-
-// TODO: split resources into their own files, registry based
-float autocvar_g_balance_health_limit;
-int autocvar_g_balance_armor_limit;
-float autocvar_g_balance_fuel_limit;
-float autocvar_g_balance_armor_regen;
-float autocvar_g_balance_armor_regenlinear;
-int autocvar_g_balance_armor_regenstable;
-float autocvar_g_balance_armor_rot;
-float autocvar_g_balance_armor_rotlinear;
-int autocvar_g_balance_armor_rotstable;
-float autocvar_g_balance_fuel_regen;
-float autocvar_g_balance_fuel_regenlinear;
-int autocvar_g_balance_fuel_regenstable;
-float autocvar_g_balance_fuel_rot;
-float autocvar_g_balance_fuel_rotlinear;
-int autocvar_g_balance_fuel_rotstable;
-float autocvar_g_balance_health_regen;
-float autocvar_g_balance_health_regenlinear;
-float autocvar_g_balance_health_regenstable;
-float autocvar_g_balance_health_rot;
-float autocvar_g_balance_health_rotlinear;
-float autocvar_g_balance_health_rotstable;
-float autocvar_g_balance_pause_armor_rot;
-float autocvar_g_balance_pause_fuel_regen;
-float autocvar_g_balance_pause_fuel_rot;
-float autocvar_g_balance_pause_health_regen;
-float autocvar_g_balance_pause_health_rot;
-
-// ============================ Public API ====================================
-
-/// \brief Returns the maximum amount of the given resource.
-/// \param[in] e Entity to check.
-/// \param[in] res_type Type of the resource (a RES_* constant).
-/// \return Maximum amount of the given resource.
-float GetResourceLimit(entity e, int res_type);
-
-/// \brief Returns the current amount of resource the given entity has.
-/// \param[in] e Entity to check.
-/// \param[in] res_type Type of the resource (a RES_* constant).
-/// \return Current amount of resource the given entity has.
-float GetResource(entity e, int res_type);
-
-/// \brief Sets the resource amount of an entity without calling any hooks.
-/// \param[in,out] e Entity to adjust.
-/// \param[in] res_type Type of the resource (a RES_* constant).
-/// \param[in] amount Amount of resource to set.
-/// \return Boolean for whether the ammo amount was changed
-bool SetResourceExplicit(entity e, int res_type, float amount);
-
-/// \brief Sets the current amount of resource the given entity will have
-/// but limited to the max amount allowed for the resource type.
-/// \param[in,out] e Entity to adjust.
-/// \param[in] res_type Type of the resource (a RES_* constant).
-/// \param[in] amount Amount of resource to set.
-/// \return No return.
-void SetResource(entity e, int res_type, float amount);
-
-/// \brief Gives an entity some resource.
-/// \param[in,out] receiver Entity to give resource to.
-/// \param[in] res_type Type of the resource (a RES_* constant).
-/// \param[in] amount Amount of resource to give.
-/// \return No return.
-void GiveResource(entity receiver, int res_type, float amount);
-
-/// \brief Gives an entity some resource but not more than a limit.
-/// \param[in,out] receiver Entity to give resource to.
-/// \param[in] res_type Type of the resource (a RES_* constant).
-/// \param[in] amount Amount of resource to give.
-/// \param[in] limit Limit of resources to give.
-/// \return No return.
-void GiveResourceWithLimit(entity receiver, int res_type, float amount, float limit);
-
-/// \brief Takes an entity some resource.
-/// \param[in,out] receiver Entity to take resource from.
-/// \param[in] res_type Type of the resource (a RES_* constant).
-/// \param[in] amount Amount of resource to take.
-/// \return No return.
-void TakeResource(entity receiver, int res_type, float amount);
-
-/// \brief Takes an entity some resource but not less than a limit.
-/// \param[in,out] receiver Entity to take resource from.
-/// \param[in] res_type Type of the resource (a RES_* constant).
-/// \param[in] amount Amount of resource to take.
-/// \param[in] limit Limit of resources to take.
-/// \return No return.
-void TakeResourceWithLimit(entity receiver, int res_type, float amount, float limit);
-
-// ===================== Legacy and/or internal API ===========================
-
-/// \brief Converts an entity field to resource type.
-/// \param[in] res_field Entity field to convert.
-/// \return Resource type (a RES_* constant).
-int GetResourceType(.float res_field);
-
-/// \brief Converts resource type (a RES_* constant) to entity field.
-/// \param[in] res_type Type of the resource.
-/// \return Entity field for that resource.
-.float GetResourceField(int res_type);
#include "spawning.qh"
+#include <common/resources/sv_resources.qh>
#include <common/weapons/_all.qh>
#include <server/items/items.qh>
#include <server/items/spawning.qh>
#include <server/mutators/_mod.qh>
-#include <server/resources.qh>
#include <server/weapons/weaponsystem.qh>
#include <server/world.qh>
this.superweapons_finished = autocvar_g_balance_superweapons_time;
// if we don't already have ammo, give us some ammo
+ // TODO: registry handles
if ((wpn.ammo_type != RES_NONE) && !GetResource(this, wpn.ammo_type))
{
int ammo = 0;
#include <common/mapobjects/subs.qh>
#include <common/mutators/mutator/status_effects/_mod.qh>
#include <common/notifications/all.qh>
+#include <common/resources/sv_resources.qh>
#include <common/state.qh>
#include <common/util.qh>
#include <common/weapons/_all.qh>
#include <server/items/items.qh>
#include <server/items/spawning.qh>
#include <server/mutators/_mod.qh>
-#include <server/resources.qh>
#include <server/weapons/selection.qh>
#include <server/weapons/weaponsystem.qh>
#include <server/world.qh>
float W_ThrowNewWeapon(entity own, float wpn, float doreduce, vector org, vector velo, .entity weaponentity)
{
Weapon info = REGISTRY_GET(Weapons, wpn);
- int ammotype = info.ammo_type;
+ Resource ammotype = info.ammo_type;
entity wep = spawn();
Item_SetLoot(wep, true);
#include <common/mutators/mutator/status_effects/_mod.qh>
#include <common/net_linked.qh>
#include <common/notifications/all.qh>
+#include <common/resources/sv_resources.qh>
#include <common/state.qh>
#include <common/util.qh>
#include <common/vehicles/all.qh>
#include <server/items/items.qh>
#include <server/hook.qh>
#include <server/mutators/_mod.qh>
-#include <server/resources.qh>
#include <server/round_handler.qh>
#include <server/weapons/selection.qh>
#include <server/world.qh>