]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Add a more optimised and generic function to initialise items (loot or permanent)
authorbones_was_here <bones_was_here@xonotic.au>
Mon, 19 Jun 2023 01:04:31 +0000 (11:04 +1000)
committerbones_was_here <bones_was_here@xonotic.au>
Wed, 21 Jun 2023 10:58:59 +0000 (20:58 +1000)
It's faster when an itemdef is provided, which avoids a classname search.

qcsrc/server/items/items.qh
qcsrc/server/items/spawning.qc
qcsrc/server/items/spawning.qh

index bd26ce4b675e359e6df576d5befc5ce5acd4f9b5..a38765c276838037bb7844810476fe6b07d70224 100644 (file)
@@ -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
 
index 2f066834417387fb16769a8641cd677b0f4c4a19..8307a70b9bc7f467b0c6415f21dcfd262f45b68d 100644 (file)
@@ -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";
index f4bd32e7b87adda20e0c679c29430b719c87fa20..4915830ab02d83a83345ef68b1a660941a8342cc 100644 (file)
@@ -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.