From e4b60baa3b2ad89171c6e61f29950e0f7ad76c64 Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Fri, 12 Apr 2024 23:35:39 +0200 Subject: [PATCH] creature/town biography/description --- client/widgets/MiscWidgets.cpp | 3 +++ client/windows/CCastleInterface.cpp | 3 +++ client/windows/CCreatureWindow.cpp | 5 +++++ client/windows/CCreatureWindow.h | 2 ++ client/windows/CKingdomInterface.cpp | 3 +++ config/schemas/creature.json | 4 ++++ config/schemas/faction.json | 4 ++++ docs/modders/Entities_Format/Creature_Format.md | 4 ++++ docs/modders/Entities_Format/Faction_Format.md | 3 +++ lib/CCreatureHandler.cpp | 11 +++++++++++ lib/CCreatureHandler.h | 3 +++ lib/CTownHandler.cpp | 11 +++++++++++ lib/CTownHandler.h | 2 ++ 13 files changed, 58 insertions(+) diff --git a/client/widgets/MiscWidgets.cpp b/client/widgets/MiscWidgets.cpp index fc8f2b8ed..28503f72f 100644 --- a/client/widgets/MiscWidgets.cpp +++ b/client/widgets/MiscWidgets.cpp @@ -466,6 +466,9 @@ void CInteractableTownTooltip::init(const CGTownInstance * town) if(town->id == townId && town->builtBuildings.count(BuildingID::TAVERN)) LOCPLINT->showTavernWindow(town, nullptr, QueryID::NONE); } + }, [&]{ + if(!town->town->faction->getDescriptionTranslated().empty()) + CRClickPopup::createAndPush(town->town->faction->getDescriptionTranslated()); }); fastMarket = std::make_shared(Rect(143, 31, 30, 34), []() { diff --git a/client/windows/CCastleInterface.cpp b/client/windows/CCastleInterface.cpp index 9439ebf1e..654b56d76 100644 --- a/client/windows/CCastleInterface.cpp +++ b/client/windows/CCastleInterface.cpp @@ -1349,6 +1349,9 @@ void CCastleInterface::recreateIcons() { if(town->builtBuildings.count(BuildingID::TAVERN)) LOCPLINT->showTavernWindow(town, nullptr, QueryID::NONE); + }, [&]{ + if(!town->town->faction->getDescriptionTranslated().empty()) + CRClickPopup::createAndPush(town->town->faction->getDescriptionTranslated()); }); creainfo.clear(); diff --git a/client/windows/CCreatureWindow.cpp b/client/windows/CCreatureWindow.cpp index 65b457733..b16d40af0 100644 --- a/client/windows/CCreatureWindow.cpp +++ b/client/windows/CCreatureWindow.cpp @@ -22,6 +22,7 @@ #include "../widgets/Images.h" #include "../widgets/TextControls.h" #include "../widgets/ObjectLists.h" +#include "../windows/InfoWindows.h" #include "../gui/CGuiHandler.h" #include "../gui/Shortcut.h" @@ -517,6 +518,10 @@ CStackWindow::MainSection::MainSection(CStackWindow * owner, int yOffset, bool s }; animation = std::make_shared(5, 41, parent->info->creature); + animationArea = std::make_shared(Rect(5, 41, 100, 130), nullptr, [&]{ + if(!parent->info->creature->getBiographyTranslated().empty()) + CRClickPopup::createAndPush(parent->info->creature->getBiographyTranslated()); + }); if(parent->info->stackNode != nullptr && parent->info->commander == nullptr) { diff --git a/client/windows/CCreatureWindow.h b/client/windows/CCreatureWindow.h index de5997764..d4360462f 100644 --- a/client/windows/CCreatureWindow.h +++ b/client/windows/CCreatureWindow.h @@ -29,6 +29,7 @@ class CButton; class CMultiLineLabel; class CListBox; class CCommanderArtPlace; +class LRClickableArea; class CCommanderSkillIcon : public LRClickableAreaWText //TODO: maybe bring commander skill button initialization logic inside? { @@ -132,6 +133,7 @@ class CStackWindow : public CWindowObject }; std::shared_ptr animation; + std::shared_ptr animationArea; std::shared_ptr name; std::shared_ptr icons; std::shared_ptr morale; diff --git a/client/windows/CKingdomInterface.cpp b/client/windows/CKingdomInterface.cpp index caec81197..7252598f3 100644 --- a/client/windows/CKingdomInterface.cpp +++ b/client/windows/CKingdomInterface.cpp @@ -832,6 +832,9 @@ CTownItem::CTownItem(const CGTownInstance * Town) { if(town->builtBuildings.count(BuildingID::TAVERN)) LOCPLINT->showTavernWindow(town, nullptr, QueryID::NONE); + }, [&]{ + if(!town->town->faction->getDescriptionTranslated().empty()) + CRClickPopup::createAndPush(town->town->faction->getDescriptionTranslated()); }); fastMarket = std::make_shared(Rect(153, 6, 65, 64), []() { diff --git a/config/schemas/creature.json b/config/schemas/creature.json index c32fb8fcb..d9be33c45 100644 --- a/config/schemas/creature.json +++ b/config/schemas/creature.json @@ -41,6 +41,10 @@ } } }, + "biography" : { + "type" : "string", + "description" : "Creature biography" + }, "faction" : { "type" : "string", "description" : "Faction this creature belongs to. Examples: castle, rampart" diff --git a/config/schemas/faction.json b/config/schemas/faction.json index 705a88512..38f9f9e85 100644 --- a/config/schemas/faction.json +++ b/config/schemas/faction.json @@ -40,6 +40,10 @@ "type" : "string", "description" : "Localizable faction name, e.g. Rampart" }, + "description" : { + "type" : "string", + "description" : "Description about the faction" + }, "alignment" : { "type" : "string", "enum" : [ "good", "neutral", "evil" ], diff --git a/docs/modders/Entities_Format/Creature_Format.md b/docs/modders/Entities_Format/Creature_Format.md index 5bff93d9c..391b998d4 100644 --- a/docs/modders/Entities_Format/Creature_Format.md +++ b/docs/modders/Entities_Format/Creature_Format.md @@ -31,6 +31,10 @@ In order to make functional creature you also need: "singular" : "Creature", "plural" : "Creatures" }, + + // Biography and information about creature + "biography" : "", + "level" : 0, // Marks this object as special and not available by default diff --git a/docs/modders/Entities_Format/Faction_Format.md b/docs/modders/Entities_Format/Faction_Format.md index dd3438f51..a2906eb10 100644 --- a/docs/modders/Entities_Format/Faction_Format.md +++ b/docs/modders/Entities_Format/Faction_Format.md @@ -59,6 +59,9 @@ Each town requires a set of buildings (Around 30-45 buildings) // Localizable faction name, e.g. "Rampart" "name" : "", + // Description of town (e.g. history or story about town) + "description" : "", + // Faction alignment. Can be good, neutral (default) or evil. "alignment" : "", diff --git a/lib/CCreatureHandler.cpp b/lib/CCreatureHandler.cpp index 21fda1133..c0a487171 100644 --- a/lib/CCreatureHandler.cpp +++ b/lib/CCreatureHandler.cpp @@ -199,6 +199,11 @@ std::string CCreature::getNameTextID() const return getNameSingularTextID(); } +std::string CCreature::getBiographyTranslated() const +{ + return VLC->generaltexth->translate(getBiographyTextID()); +} + std::string CCreature::getNamePluralTextID() const { return TextIdentifier("creatures", modScope, identifier, "name", "plural" ).get(); @@ -209,6 +214,11 @@ std::string CCreature::getNameSingularTextID() const return TextIdentifier("creatures", modScope, identifier, "name", "singular" ).get(); } +std::string CCreature::getBiographyTextID() const +{ + return TextIdentifier("creatures", modScope, identifier, "biography").get(); +} + CCreature::CreatureQuantityId CCreature::getQuantityID(const int & quantity) { if (quantity<5) @@ -600,6 +610,7 @@ CCreature * CCreatureHandler::loadFromJson(const std::string & scope, const Json VLC->generaltexth->registerString(scope, cre->getNameSingularTextID(), node["name"]["singular"].String()); VLC->generaltexth->registerString(scope, cre->getNamePluralTextID(), node["name"]["plural"].String()); + VLC->generaltexth->registerString(scope, cre->getBiographyTextID(), node["biography"].String()); cre->addBonus(node["hitPoints"].Integer(), BonusType::STACK_HEALTH); cre->addBonus(node["speed"].Integer(), BonusType::STACKS_SPEED); diff --git a/lib/CCreatureHandler.h b/lib/CCreatureHandler.h index b38652ba4..8f75b7cd6 100644 --- a/lib/CCreatureHandler.h +++ b/lib/CCreatureHandler.h @@ -51,6 +51,9 @@ class DLL_LINKAGE CCreature : public Creature, public CBonusSystemNode TResources cost; //cost[res_id] - amount of that resource required to buy creature from dwelling public: + std::string getBiographyTranslated() const; + std::string getBiographyTextID() const; + ui32 ammMin; // initial size of stack of these creatures on adventure map (if not set in editor) ui32 ammMax; diff --git a/lib/CTownHandler.cpp b/lib/CTownHandler.cpp index b2dedcaa3..b65af0271 100644 --- a/lib/CTownHandler.cpp +++ b/lib/CTownHandler.cpp @@ -188,6 +188,16 @@ std::string CFaction::getNameTextID() const return TextIdentifier("faction", modScope, identifier, "name").get(); } +std::string CFaction::getDescriptionTranslated() const +{ + return VLC->generaltexth->translate(getDescriptionTextID()); +} + +std::string CFaction::getDescriptionTextID() const +{ + return TextIdentifier("faction", modScope, identifier, "description").get(); +} + FactionID CFaction::getId() const { return FactionID(index); @@ -1037,6 +1047,7 @@ CFaction * CTownHandler::loadFromJson(const std::string & scope, const JsonNode faction->identifier = identifier; VLC->generaltexth->registerString(scope, faction->getNameTextID(), source["name"].String()); + VLC->generaltexth->registerString(scope, faction->getDescriptionTranslated(), source["description"].String()); faction->creatureBg120 = ImagePath::fromJson(source["creatureBackground"]["120px"]); faction->creatureBg130 = ImagePath::fromJson(source["creatureBackground"]["130px"]); diff --git a/lib/CTownHandler.h b/lib/CTownHandler.h index e318903c3..f755d59e4 100644 --- a/lib/CTownHandler.h +++ b/lib/CTownHandler.h @@ -192,6 +192,8 @@ public: std::string getNameTranslated() const override; std::string getNameTextID() const override; + std::string getDescriptionTranslated() const; + std::string getDescriptionTextID() const; bool hasTown() const override; TerrainId getNativeTerrain() const override;