From 84fe2dfd4cd8c3134963f90ed693c2562fc71306 Mon Sep 17 00:00:00 2001 From: WasabiRaptor Date: Fri, 8 Mar 2024 18:14:40 -0500 Subject: [PATCH] Perfectly Generic Item improvements spawnitem won't create generic items unless you intend to generic items will retain the data for what item they were if a mod is uninstalled, and will attempt to restore themselves if re-installed --- source/game/StarCommandProcessor.cpp | 4 ++-- source/game/StarItemDatabase.cpp | 30 ++++++++++++++++++++++------ source/game/StarItemDatabase.hpp | 4 ++-- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/source/game/StarCommandProcessor.cpp b/source/game/StarCommandProcessor.cpp index 02a8ec0..0d9d4e9 100644 --- a/source/game/StarCommandProcessor.cpp +++ b/source/game/StarCommandProcessor.cpp @@ -183,7 +183,7 @@ String CommandProcessor::warpRandom(ConnectionId connectionId, String const& typ } } } - + if (size.magnitude() > 1024) return "could not find a matching world"; size *= 2; @@ -296,7 +296,7 @@ String CommandProcessor::spawnItem(ConnectionId connectionId, String const& argu bool done = m_universe->executeForClient(connectionId, [&](WorldServer* world, PlayerPtr const& player) { auto itemDatabase = Root::singleton().itemDatabase(); - world->addEntity(ItemDrop::createRandomizedDrop(itemDatabase->item(ItemDescriptor(kind, amount, parameters), level, seed), player->aimPosition())); + world->addEntity(ItemDrop::createRandomizedDrop(itemDatabase->item(ItemDescriptor(kind, amount, parameters), level, seed, true), player->aimPosition())); }); return done ? "" : "Invalid client state"; diff --git a/source/game/StarItemDatabase.cpp b/source/game/StarItemDatabase.cpp index 0eccb2e..50d044c 100644 --- a/source/game/StarItemDatabase.cpp +++ b/source/game/StarItemDatabase.cpp @@ -232,11 +232,11 @@ ItemPtr ItemDatabase::itemShared(ItemDescriptor descriptor, Maybe level, } } -ItemPtr ItemDatabase::item(ItemDescriptor descriptor, Maybe level, Maybe seed) const { +ItemPtr ItemDatabase::item(ItemDescriptor descriptor, Maybe level, Maybe seed, bool ignoreInvalid) const { if (!descriptor) return {}; else - return tryCreateItem(descriptor, level, seed); + return tryCreateItem(descriptor, level, seed, ignoreInvalid); } bool ItemDatabase::hasRecipeToMake(ItemDescriptor const& item) const { @@ -499,14 +499,32 @@ ItemPtr ItemDatabase::createItem(ItemType type, ItemConfig const& config) { } } -ItemPtr ItemDatabase::tryCreateItem(ItemDescriptor const& descriptor, Maybe level, Maybe seed) const { +ItemPtr ItemDatabase::tryCreateItem(ItemDescriptor const& descriptor, Maybe level, Maybe seed, bool ignoreInvalid) const { ItemPtr result; + String name = descriptor.name(); + Json parameters = descriptor.parameters(); + try { - result = createItem(m_items.get(descriptor.name()).type, itemConfig(descriptor.name(), descriptor.parameters(), level, seed)); + if ((name == "perfectlygenericitem") && parameters.contains("genericItemStorage")) { + Json storage = parameters.get("genericItemStorage"); + name = storage.getString("name"); + parameters = storage.get("parameters"); + } + result = createItem(m_items.get(name).type, itemConfig(name, parameters, level, seed)); } catch (std::exception const& e) { - Logger::error("Could not instantiate item '{}'. {}", descriptor, outputException(e, false)); - result = createItem(m_items.get("perfectlygenericitem").type, itemConfig("perfectlygenericitem", JsonObject(), {}, {})); + if (descriptor.name() == "perfectlygenericitem") { + Logger::error("Could not re-instantiate item '{}'. {}", descriptor, outputException(e, false)); + result = createItem(m_items.get("perfectlygenericitem").type, itemConfig("perfectlygenericitem", descriptor.parameters(), level, seed)); + } else if (!ignoreInvalid) { + Logger::error("Could not instantiate item '{}'. {}", descriptor, outputException(e, false)); + result = createItem(m_items.get("perfectlygenericitem").type, itemConfig("perfectlygenericitem", JsonObject({ + {"genericItemStorage", descriptor.toJson()}, + {"shortdescription", descriptor.name()}, + {"description", "Reinstall the parent mod to return this item to normal\n^red;(to retain data, do not place as object)"} + }), {}, {})); + } else + throw e; } result->setCount(descriptor.count()); diff --git a/source/game/StarItemDatabase.hpp b/source/game/StarItemDatabase.hpp index c45f4ca..50a8e35 100644 --- a/source/game/StarItemDatabase.hpp +++ b/source/game/StarItemDatabase.hpp @@ -117,7 +117,7 @@ public: // The returned item pointer will be shared. Either call ->clone() or use item() instead for a copy. ItemPtr itemShared(ItemDescriptor descriptor, Maybe level = {}, Maybe seed = {}) const; // Same as itemShared, but makes a copy instead. Does not cache. - ItemPtr item(ItemDescriptor descriptor, Maybe level = {}, Maybe seed = {}) const; + ItemPtr item(ItemDescriptor descriptor, Maybe level = {}, Maybe seed = {}, bool ignoreInvalid = false) const; bool hasRecipeToMake(ItemDescriptor const& item) const; @@ -159,7 +159,7 @@ private: }; static ItemPtr createItem(ItemType type, ItemConfig const& config); - ItemPtr tryCreateItem(ItemDescriptor const& descriptor, Maybe level = {}, Maybe seed = {}) const; + ItemPtr tryCreateItem(ItemDescriptor const& descriptor, Maybe level = {}, Maybe seed = {}, bool ignoreInvalid = false) const; ItemData const& itemData(String const& name) const; ItemRecipe makeRecipe(List inputs, ItemDescriptor output, float duration, StringSet groups) const;