diff --git a/client/widgets/CComponent.cpp b/client/widgets/CComponent.cpp index 5b9d84f63..ccd19ce91 100644 --- a/client/widgets/CComponent.cpp +++ b/client/widgets/CComponent.cpp @@ -119,7 +119,7 @@ std::vector CComponent::getFileName() const static const std::array primSkillsArr = {"PSKIL32", "PSKIL32", "PSKIL42", "PSKILL"}; static const std::array secSkillsArr = {"SECSK32", "SECSK32", "SECSKILL", "SECSK82"}; static const std::array resourceArr = {"SMALRES", "RESOURCE", "RESOURCE", "RESOUR82"}; - static const std::array creatureArr = {"CPRSMALL", "CPRSMALL", "CPRSMALL", "TWCRPORT"}; + static const std::array creatureArr = {"CPRSMALL", "CPRSMALL", "TWCRPORT", "TWCRPORT"}; static const std::array artifactArr = {"Artifact", "Artifact", "Artifact", "Artifact"}; static const std::array spellsArr = {"SpellInt", "SpellInt", "SpellInt", "SPELLSCR"}; static const std::array moraleArr = {"IMRL22", "IMRL30", "IMRL42", "imrl82"}; diff --git a/client/windows/GUIClasses.cpp b/client/windows/GUIClasses.cpp index e61ba68ee..6a54229f4 100644 --- a/client/windows/GUIClasses.cpp +++ b/client/windows/GUIClasses.cpp @@ -51,6 +51,7 @@ #include "../lib/mapObjects/CGHeroInstance.h" #include "../lib/mapObjects/CGMarket.h" #include "../lib/mapObjects/CGTownInstance.h" +#include "../lib/mapObjects/ObjectTemplate.h" #include "../lib/gameState/CGameState.h" #include "../lib/gameState/SThievesGuildInfo.h" #include "../lib/gameState/TavernHeroesPool.h" diff --git a/client/windows/InfoWindows.cpp b/client/windows/InfoWindows.cpp index 07b88cb47..98997550e 100644 --- a/client/windows/InfoWindows.cpp +++ b/client/windows/InfoWindows.cpp @@ -233,7 +233,7 @@ void CRClickPopup::createAndPush(const CGObjectInstance * obj, const Point & p, std::vector> guiComponents; for(auto & component : components) - guiComponents.push_back(std::make_shared(component)); + guiComponents.push_back(std::make_shared(component, CComponent::medium)); if(GAME->interface()->localState->getCurrentHero()) CRClickPopup::createAndPush(obj->getPopupText(GAME->interface()->localState->getCurrentHero()), guiComponents); diff --git a/config/objects/markets.json b/config/objects/markets.json index ea5c517b9..9a1357277 100644 --- a/config/objects/markets.json +++ b/config/objects/markets.json @@ -124,6 +124,7 @@ "rarity" : 20 }, "modes" : ["resource-skill"], + "description" : "@core.xtrainfo.24", "speech" : "@core.genrltxt.603", "offer": [ @@ -135,4 +136,4 @@ } } } -} \ No newline at end of file +} diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index bdeee78f6..8f074adce 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -140,6 +140,7 @@ set(lib_MAIN_SRCS mapObjectConstructors/DwellingInstanceConstructor.cpp mapObjectConstructors/FlaggableInstanceConstructor.cpp mapObjectConstructors/HillFortInstanceConstructor.cpp + mapObjectConstructors/MarketInstanceConstructor.cpp mapObjectConstructors/ShipyardInstanceConstructor.cpp mapObjects/CGCreature.cpp @@ -565,6 +566,7 @@ set(lib_MAIN_HEADERS mapObjectConstructors/HillFortInstanceConstructor.h mapObjectConstructors/FlaggableInstanceConstructor.h mapObjectConstructors/IObjectInfo.h + mapObjectConstructors/MarketInstanceConstructor.h mapObjectConstructors/RandomMapInfo.h mapObjectConstructors/ShipyardInstanceConstructor.h mapObjectConstructors/SObjectSounds.h diff --git a/lib/mapObjectConstructors/CObjectClassesHandler.cpp b/lib/mapObjectConstructors/CObjectClassesHandler.cpp index bd199a1d0..dc5dc6407 100644 --- a/lib/mapObjectConstructors/CObjectClassesHandler.cpp +++ b/lib/mapObjectConstructors/CObjectClassesHandler.cpp @@ -25,6 +25,7 @@ #include "../mapObjectConstructors/DwellingInstanceConstructor.h" #include "../mapObjectConstructors/FlaggableInstanceConstructor.h" #include "../mapObjectConstructors/HillFortInstanceConstructor.h" +#include "../mapObjectConstructors/MarketInstanceConstructor.h" #include "../mapObjectConstructors/ShipyardInstanceConstructor.h" #include "../mapObjects/CGCreature.h" diff --git a/lib/mapObjectConstructors/CommonConstructors.cpp b/lib/mapObjectConstructors/CommonConstructors.cpp index f055f654a..3019e0e28 100644 --- a/lib/mapObjectConstructors/CommonConstructors.cpp +++ b/lib/mapObjectConstructors/CommonConstructors.cpp @@ -10,24 +10,20 @@ #include "StdInc.h" #include "CommonConstructors.h" -#include "../texts/CGeneralTextHandler.h" #include "../json/JsonRandom.h" #include "../constants/StringConstants.h" -#include "../TerrainHandler.h" #include "../GameLibrary.h" -#include "../CConfigHandler.h" #include "../callback/IGameInfoCallback.h" #include "../entities/faction/CTownHandler.h" #include "../entities/hero/CHeroClass.h" -#include "../json/JsonUtils.h" #include "../mapObjects/CGHeroInstance.h" -#include "../mapObjects/CGMarket.h" #include "../mapObjects/CGTownInstance.h" #include "../mapObjects/MiscObjects.h" #include "../mapObjects/ObjectTemplate.h" #include "../mapping/TerrainTile.h" #include "../modding/IdentifierStorage.h" +#include "../texts/TextIdentifier.h" VCMI_LIB_NAMESPACE_BEGIN @@ -277,90 +273,4 @@ AnimationPath BoatInstanceConstructor::getBoatAnimationName() const return actualAnimation; } -void MarketInstanceConstructor::initTypeData(const JsonNode & input) -{ - if (settings["mods"]["validation"].String() != "off") - JsonUtils::validate(input, "vcmi:market", getJsonKey()); - - if (!input["description"].isNull()) - { - std::string description = input["description"].String(); - descriptionTextID = TextIdentifier(getBaseTextID(), "description").get(); - LIBRARY->generaltexth->registerString( input.getModScope(), descriptionTextID, input["description"]); - } - - if (!input["speech"].isNull()) - { - std::string speech = input["speech"].String(); - if (!speech.empty() && speech.at(0) == '@') - { - speechTextID = speech.substr(1); - } - else - { - speechTextID = TextIdentifier(getBaseTextID(), "speech").get(); - LIBRARY->generaltexth->registerString( input.getModScope(), speechTextID, input["speech"]); - } - } - - for(auto & element : input["modes"].Vector()) - { - if(MappedKeys::MARKET_NAMES_TO_TYPES.count(element.String())) - marketModes.insert(MappedKeys::MARKET_NAMES_TO_TYPES.at(element.String())); - } - - marketEfficiency = input["efficiency"].isNull() ? 5 : input["efficiency"].Integer(); - predefinedOffer = input["offer"]; -} - -bool MarketInstanceConstructor::hasDescription() const -{ - return !descriptionTextID.empty(); -} - -std::shared_ptr MarketInstanceConstructor::createObject(IGameInfoCallback * cb) const -{ - if(marketModes.size() == 1) - { - switch(*marketModes.begin()) - { - case EMarketMode::ARTIFACT_RESOURCE: - case EMarketMode::RESOURCE_ARTIFACT: - return std::make_shared(cb); - - case EMarketMode::RESOURCE_SKILL: - return std::make_shared(cb); - } - } - return std::make_shared(cb); -} - -const std::set & MarketInstanceConstructor::availableModes() const -{ - return marketModes; -} - -void MarketInstanceConstructor::randomizeObject(CGMarket * object, IGameRandomizer & gameRandomizer) const -{ - JsonRandom randomizer(object->cb, gameRandomizer); - JsonRandom::Variables emptyVariables; - - if(auto * university = dynamic_cast(object)) - { - for(auto skill : randomizer.loadSecondaries(predefinedOffer, emptyVariables)) - university->skills.push_back(skill.first); - } -} - -std::string MarketInstanceConstructor::getSpeechTranslated() const -{ - assert(marketModes.count(EMarketMode::RESOURCE_SKILL)); - return LIBRARY->generaltexth->translate(speechTextID); -} - -int MarketInstanceConstructor::getMarketEfficiency() const -{ - return marketEfficiency; -} - VCMI_LIB_NAMESPACE_END diff --git a/lib/mapObjectConstructors/CommonConstructors.h b/lib/mapObjectConstructors/CommonConstructors.h index a941d3143..4b75c1bc8 100644 --- a/lib/mapObjectConstructors/CommonConstructors.h +++ b/lib/mapObjectConstructors/CommonConstructors.h @@ -15,10 +15,8 @@ #include "../mapObjects/MiscObjects.h" #include "../mapObjects/CGCreature.h" #include "../mapObjects/CGHeroInstance.h" -#include "../mapObjects/CGMarket.h" #include "../mapObjects/CGResource.h" #include "../mapObjects/CGTownInstance.h" -#include "../mapObjects/ObstacleSetHandler.h" VCMI_LIB_NAMESPACE_BEGIN @@ -126,25 +124,4 @@ public: AnimationPath getBoatAnimationName() const; }; -class MarketInstanceConstructor : public CDefaultObjectTypeHandler -{ - std::string descriptionTextID; - std::string speechTextID; - - std::set marketModes; - JsonNode predefinedOffer; - int marketEfficiency; - - void initTypeData(const JsonNode & config) override; -public: - std::shared_ptr createObject(IGameInfoCallback * cb) const override; - void randomizeObject(CGMarket * object, IGameRandomizer & gameRandomizer) const override; - - const std::set & availableModes() const; - bool hasDescription() const; - - std::string getSpeechTranslated() const; - int getMarketEfficiency() const; -}; - VCMI_LIB_NAMESPACE_END diff --git a/lib/mapObjectConstructors/MarketInstanceConstructor.cpp b/lib/mapObjectConstructors/MarketInstanceConstructor.cpp new file mode 100644 index 000000000..a008c0108 --- /dev/null +++ b/lib/mapObjectConstructors/MarketInstanceConstructor.cpp @@ -0,0 +1,121 @@ +/* +* MarketInstanceConstructor.cpp, part of VCMI engine +* +* Authors: listed in file AUTHORS in main folder +* +* License: GNU General Public License v2.0 or later +* Full text of license available in license.txt file, in main folder +* +*/ +#include "StdInc.h" +#include "MarketInstanceConstructor.h" + +#include "../CConfigHandler.h" +#include "../GameLibrary.h" +#include "../constants/StringConstants.h" +#include "../json/JsonRandom.h" +#include "../json/JsonUtils.h" +#include "../texts/CGeneralTextHandler.h" +#include "../texts/TextIdentifier.h" + +VCMI_LIB_NAMESPACE_BEGIN + +void MarketInstanceConstructor::initTypeData(const JsonNode & input) +{ + if (settings["mods"]["validation"].String() != "off") + JsonUtils::validate(input, "vcmi:market", getJsonKey()); + + if (!input["description"].isNull()) + { + std::string description = input["description"].String(); + if (!description.empty() && description.at(0) == '@') + { + descriptionTextID = description.substr(1); + } + else + { + descriptionTextID = TextIdentifier(getBaseTextID(), "description").get(); + LIBRARY->generaltexth->registerString( input.getModScope(), descriptionTextID, input["description"]); + } + } + + if (!input["speech"].isNull()) + { + std::string speech = input["speech"].String(); + if (!speech.empty() && speech.at(0) == '@') + { + speechTextID = speech.substr(1); + } + else + { + speechTextID = TextIdentifier(getBaseTextID(), "speech").get(); + LIBRARY->generaltexth->registerString( input.getModScope(), speechTextID, input["speech"]); + } + } + + for(auto & element : input["modes"].Vector()) + { + if(MappedKeys::MARKET_NAMES_TO_TYPES.count(element.String())) + marketModes.insert(MappedKeys::MARKET_NAMES_TO_TYPES.at(element.String())); + } + + marketEfficiency = input["efficiency"].isNull() ? 5 : input["efficiency"].Integer(); + predefinedOffer = input["offer"]; +} + +bool MarketInstanceConstructor::hasDescription() const +{ + return !descriptionTextID.empty(); +} + +std::string MarketInstanceConstructor::getDescriptionTextID() const +{ + return descriptionTextID; +} + +std::shared_ptr MarketInstanceConstructor::createObject(IGameInfoCallback * cb) const +{ + if(marketModes.size() == 1) + { + switch(*marketModes.begin()) + { + case EMarketMode::ARTIFACT_RESOURCE: + case EMarketMode::RESOURCE_ARTIFACT: + return std::make_shared(cb); + + case EMarketMode::RESOURCE_SKILL: + return std::make_shared(cb); + } + } + return std::make_shared(cb); +} + +const std::set & MarketInstanceConstructor::availableModes() const +{ + return marketModes; +} + +void MarketInstanceConstructor::randomizeObject(CGMarket * object, IGameRandomizer & gameRandomizer) const +{ + JsonRandom randomizer(object->cb, gameRandomizer); + JsonRandom::Variables emptyVariables; + + if(auto * university = dynamic_cast(object)) + { + for(auto skill : randomizer.loadSecondaries(predefinedOffer, emptyVariables)) + university->skills.push_back(skill.first); + } +} + +std::string MarketInstanceConstructor::getSpeechTranslated() const +{ + assert(marketModes.count(EMarketMode::RESOURCE_SKILL)); + return LIBRARY->generaltexth->translate(speechTextID); +} + +int MarketInstanceConstructor::getMarketEfficiency() const +{ + return marketEfficiency; +} + +VCMI_LIB_NAMESPACE_END diff --git a/lib/mapObjectConstructors/MarketInstanceConstructor.h b/lib/mapObjectConstructors/MarketInstanceConstructor.h new file mode 100644 index 000000000..5d6741791 --- /dev/null +++ b/lib/mapObjectConstructors/MarketInstanceConstructor.h @@ -0,0 +1,40 @@ +/* +* MarketInstanceConstructor.h, part of VCMI engine +* +* Authors: listed in file AUTHORS in main folder +* +* License: GNU General Public License v2.0 or later +* Full text of license available in license.txt file, in main folder +* +*/ +#pragma once + +#include "CDefaultObjectTypeHandler.h" +#include "../mapObjects/CGMarket.h" +#include "../json/JsonNode.h" + +VCMI_LIB_NAMESPACE_BEGIN + +class MarketInstanceConstructor : public CDefaultObjectTypeHandler +{ + std::string descriptionTextID; + std::string speechTextID; + + std::set marketModes; + JsonNode predefinedOffer; + int marketEfficiency; + + void initTypeData(const JsonNode & config) override; +public: + std::shared_ptr createObject(IGameInfoCallback * cb) const override; + void randomizeObject(CGMarket * object, IGameRandomizer & gameRandomizer) const override; + + const std::set & availableModes() const; + bool hasDescription() const; + std::string getDescriptionTextID() const; + + std::string getSpeechTranslated() const; + int getMarketEfficiency() const; +}; + +VCMI_LIB_NAMESPACE_END diff --git a/lib/mapObjects/CGMarket.cpp b/lib/mapObjects/CGMarket.cpp index c66d9271f..6bcb47c1f 100644 --- a/lib/mapObjects/CGMarket.cpp +++ b/lib/mapObjects/CGMarket.cpp @@ -11,18 +11,21 @@ #include "StdInc.h" #include "CGMarket.h" -#include "../callback/IGameInfoCallback.h" -#include "../callback/IGameEventCallback.h" -#include "../callback/IGameRandomizer.h" -#include "../texts/CGeneralTextHandler.h" -#include "../CCreatureHandler.h" +#include "CGHeroInstance.h" #include "CGTownInstance.h" + +//#include "../CCreatureHandler.h" +#include "../CPlayerState.h" +//#include "../CSkillHandler.h" #include "../IGameSettings.h" -#include "../CSkillHandler.h" +#include "../callback/IGameEventCallback.h" +#include "../callback/IGameInfoCallback.h" +#include "../callback/IGameRandomizer.h" #include "../mapObjectConstructors/AObjectTypeHandler.h" #include "../mapObjectConstructors/CObjectClassesHandler.h" -#include "../mapObjectConstructors/CommonConstructors.h" +#include "../mapObjectConstructors/MarketInstanceConstructor.h" #include "../networkPacks/PacksForClient.h" +#include "../texts/TextIdentifier.h" VCMI_LIB_NAMESPACE_BEGIN @@ -48,7 +51,7 @@ std::string CGMarket::getPopupText(PlayerColor player) const MetaString message = MetaString::createFromRawString("{%s}\r\n\r\n%s"); message.replaceName(ID, subID); - message.replaceTextID(TextIdentifier(getObjectHandler()->getBaseTextID(), "description").get()); + message.replaceTextID(getMarketHandler()->getDescriptionTextID()); return message.toString(); } @@ -135,7 +138,31 @@ std::string CGUniversity::getSpeechTranslated() const void CGUniversity::onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const { + ChangeObjectVisitors cow; + cow.object = id; + cow.mode = ChangeObjectVisitors::VISITOR_ADD_PLAYER; + cow.hero = h->id; + gameEvents.sendAndApply(cow); + gameEvents.showObjectWindow(this, EOpenWindowMode::UNIVERSITY_WINDOW, h, true); } +bool CGUniversity::wasVisited (PlayerColor player) const +{ + return cb->getPlayerState(player)->visitedObjects.count(id) != 0; +} + +std::vector CGUniversity::getPopupComponents(PlayerColor player) const +{ + std::vector result; + + if (!wasVisited(player)) + return result; + + for (auto const & skill : skills) + result.emplace_back(ComponentType::SEC_SKILL, skill.as()); + + return result; +} + VCMI_LIB_NAMESPACE_END diff --git a/lib/mapObjects/CGMarket.h b/lib/mapObjects/CGMarket.h index f52cecb08..2ddd551f4 100644 --- a/lib/mapObjects/CGMarket.h +++ b/lib/mapObjects/CGMarket.h @@ -65,6 +65,8 @@ public: std::vector availableItemsIds(EMarketMode mode) const override; void onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const override; //open window + std::vector getPopupComponents(PlayerColor player) const override; + bool wasVisited (PlayerColor player) const override; template void serialize(Handler &h) {