From 6ef9fe4c272147a1b3f63a21cb37f13492d84063 Mon Sep 17 00:00:00 2001 From: bones_was_here Date: Mon, 19 Jun 2023 11:04:31 +1000 Subject: [PATCH] Add a more optimised and generic function to initialise items (loot or permanent) It's faster when an itemdef is provided, which avoids a classname search. --- qcsrc/server/items/items.qh | 2 +- qcsrc/server/items/spawning.qc | 47 ++++++++++++++++++++++++++++++++++ qcsrc/server/items/spawning.qh | 12 +++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/qcsrc/server/items/items.qh b/qcsrc/server/items/items.qh index bd26ce4b6..a38765c27 100644 --- a/qcsrc/server/items/items.qh +++ b/qcsrc/server/items/items.qh @@ -36,7 +36,7 @@ const float ITEM_RESPAWN_TICKS = 10; .float item_respawncounter; -.float noalign; // if set to 1, the item or spawnpoint won't be dropped to the floor +.bool noalign; // if set to 1, the item or spawnpoint won't be dropped to the floor .float superweapons_finished; // NOTE: this field is used only by map entities, it does not directly apply the superweapons stat diff --git a/qcsrc/server/items/spawning.qc b/qcsrc/server/items/spawning.qc index 2f0668344..8307a70b9 100644 --- a/qcsrc/server/items/spawning.qc +++ b/qcsrc/server/items/spawning.qc @@ -121,6 +121,53 @@ bool Item_InitializeLoot(entity item, string class_name, vector position, return true; } +// An optimised and generic way to initialise items (loot or permanent) +// required field: itemdef (faster, preferred) OR classname +// optional fields: origin, velocity, lifetime, noalign +// lifetime < 0 means permanent (not loot), lifetime > 0 overrides the default +// permanent items only: noalign means the item is suspended (won't drop to floor) +bool Item_Initialise(entity item) +{ + if (item.lifetime >= 0) + { + Item_SetLoot(item, true); + item.pickup_anyway = true; // these are ALWAYS pickable + } + + if (item.itemdef) // no search required + { + if (item.itemdef.instanceOfWeapon) + weapon_defaultspawnfunc(item, item.itemdef); + else + StartItem(item, item.itemdef); + } + else // fall back to classname search + { + FOREACH(Weapons, it.m_canonical_spawnfunc == item.classname, + { + weapon_defaultspawnfunc(item, it); + goto classname_found; + }); + FOREACH(Items, it.m_canonical_spawnfunc == item.classname, + { + StartItem(item, it); + goto classname_found; + }); + LOG_FATALF("Item_Initialize: Invalid classname: %s", item.classname); + LABEL(classname_found) + } + + if (wasfreed(item)) + return false; + + // StartItem sets the default .wait expiry time which is respected by Item_Think() + if (item.lifetime > 0) + item.wait = time + item.lifetime; + + item.spawnfunc_checked = true; + return true; +} + bool Item_IsLoot(entity item) { return item.m_isloot || item.classname == "droppedweapon"; diff --git a/qcsrc/server/items/spawning.qh b/qcsrc/server/items/spawning.qh index f4bd32e7b..4915830ab 100644 --- a/qcsrc/server/items/spawning.qh +++ b/qcsrc/server/items/spawning.qh @@ -6,6 +6,9 @@ bool startitem_failed; +/// \brief lifetime < 0 means permanent (not loot), lifetime > 0 overrides the default +.float lifetime; + /// \brief Returns the item definition corresponding to the given class name. /// \param[in] class_name Class name to search for. /// \return Item definition corresponding to the given class name or NULL is not @@ -68,6 +71,15 @@ entity Item_CreateLoot(string class_name, vector position, vector vel, bool Item_InitializeLoot(entity item, string class_name, vector position, vector vel, float time_to_live); +/// \brief An optimised and generic way to initialise items (loot or permanent) +/// \param[in] item The item entity to initialise +/// \return True on success, false otherwise. +/// \nore required field: itemdef (faster, preferred) OR classname +/// optional fields: origin, velocity, lifetime, noalign +/// lifetime < 0 means permanent (not loot), lifetime > 0 overrides the default +/// permanent items only: noalign means the item is suspended (won't drop to floor) +bool Item_Initialise(entity item); + /// \brief Returns whether the item is loot. /// \param[in] item Item to check. /// \return True if the item is loot, false otherwise. -- 2.39.2