mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Merge pull request #660 from ShubusCorporation/shc_rmg_issue
Mod system improvement: Patch 2
This commit is contained in:
commit
9ca9c809c6
@ -846,6 +846,23 @@ void CCastleBuildings::enterFountain(const BuildingID & building, BuildingSubID:
|
||||
{
|
||||
std::vector<std::shared_ptr<CComponent>> comps(1, std::make_shared<CComponent>(CComponent::building,town->subID, building));
|
||||
std::string descr = town->town->buildings.find(building)->second->Description();
|
||||
std::string hasNotProduced;
|
||||
std::string hasProduced;
|
||||
|
||||
if(this->town->town->faction->index == (TFaction)ETownType::RAMPART)
|
||||
{
|
||||
hasNotProduced = CGI->generaltexth->allTexts[677];
|
||||
hasProduced = CGI->generaltexth->allTexts[678];
|
||||
}
|
||||
else
|
||||
{
|
||||
auto buildingName = town->town->getSpecialBuilding(subID)->Name();
|
||||
|
||||
hasNotProduced = std::string(CGI->generaltexth->localizedTexts["townHall"]["hasNotProduced"].String());
|
||||
hasProduced = std::string(CGI->generaltexth->localizedTexts["townHall"]["hasProduced"].String());
|
||||
boost::algorithm::replace_first(hasNotProduced, "%s", buildingName);
|
||||
boost::algorithm::replace_first(hasProduced, "%s", buildingName);
|
||||
}
|
||||
|
||||
bool isMysticPondOrItsUpgrade = subID == BuildingSubID::MYSTIC_POND
|
||||
|| (upgrades != BuildingID::NONE
|
||||
@ -857,10 +874,10 @@ void CCastleBuildings::enterFountain(const BuildingID & building, BuildingSubID:
|
||||
if(isMysticPondOrItsUpgrade) //for vanila Rampart like towns
|
||||
{
|
||||
if(town->bonusValue.first == 0) //Mystic Pond produced nothing;
|
||||
descr += "\n\n" + CGI->generaltexth->allTexts[677];
|
||||
descr += "\n\n" + hasNotProduced;
|
||||
else //Mystic Pond produced something;
|
||||
{
|
||||
descr += "\n\n" + CGI->generaltexth->allTexts[678];
|
||||
descr += "\n\n" + hasProduced;
|
||||
boost::algorithm::replace_first(descr, "%s", CGI->generaltexth->restypes[town->bonusValue.first]);
|
||||
boost::algorithm::replace_first(descr, "%d", boost::lexical_cast<std::string>(town->bonusValue.second));
|
||||
}
|
||||
|
@ -1269,7 +1269,18 @@ CUniversityWindow::CUniversityWindow(const CGHeroInstance * _hero, const IMarket
|
||||
bars->preload();
|
||||
|
||||
if(market->o->ID == Obj::TOWN)
|
||||
titlePic = std::make_shared<CAnimImage>(CGI->townh->factions[ETownType::CONFLUX]->town->clientInfo.buildingsIcons, BuildingID::MAGIC_UNIVERSITY);
|
||||
{
|
||||
auto town = dynamic_cast<const CGTownInstance *>(_market);
|
||||
|
||||
if(town)
|
||||
{
|
||||
auto faction = town->town->faction->index;
|
||||
auto bid = town->town->getSpecialBuilding(BuildingSubID::MAGIC_UNIVERSITY)->bid;
|
||||
titlePic = std::make_shared<CAnimImage>(CGI->townh->factions[faction]->town->clientInfo.buildingsIcons, bid);
|
||||
}
|
||||
else
|
||||
titlePic = std::make_shared<CAnimImage>(CGI->townh->factions[ETownType::CONFLUX]->town->clientInfo.buildingsIcons, BuildingID::MAGIC_UNIVERSITY);
|
||||
}
|
||||
else
|
||||
titlePic = std::make_shared<CPicture>("UNIVBLDG");
|
||||
|
||||
|
@ -43,7 +43,15 @@
|
||||
},
|
||||
"townHall" :
|
||||
{
|
||||
"missingBase" : "Base building %s must be built first"
|
||||
"missingBase" : "Base building %s must be built first",
|
||||
"greetingManaVortex" : "As you near the %s your body is filled with new energy. You have doubled your normal spell points.",
|
||||
"greetingKnowledge" : "You study the glyphs on the %s and gain insight into the workings of various magics (+1 Knowledge).",
|
||||
"greetingSpellPower" : "The %s teaches you new ways to focus your magical powers (+1 Power).",
|
||||
"greetingExperience" : "A visit to the %s teaches you many new skills (+1000 Experience).",
|
||||
"greetingAttack" : "Some time spent at the %s allows you to learn more effective combat skills (+1 Attack Skill).",
|
||||
"greetingDefence" : "Spending time in the %s, the experienced warriors therein teach you additional defensive skills (+1 Defense).",
|
||||
"hasNotProduced" : "The %s has not produced anything yet.",
|
||||
"hasProduced" : "The %s produced %d %s this week."
|
||||
},
|
||||
"logicalExpressions" :
|
||||
{
|
||||
|
@ -217,6 +217,16 @@ BuildingID::EBuildingID CTown::getBuildingType(BuildingSubID::EBuildingSubID sub
|
||||
return building == nullptr ? BuildingID::NONE : building->bid.num;
|
||||
}
|
||||
|
||||
const std::string CTown::getGreeting(BuildingSubID::EBuildingSubID subID) const
|
||||
{
|
||||
return VLC->townh->getMappedValue<const std::string, BuildingSubID::EBuildingSubID>(subID, std::string(), specialMessages, false);
|
||||
}
|
||||
|
||||
void CTown::setGreeting(BuildingSubID::EBuildingSubID subID, const std::string message) const
|
||||
{
|
||||
specialMessages.insert(std::pair<BuildingSubID::EBuildingSubID, const std::string>(subID, message));
|
||||
}
|
||||
|
||||
CTownHandler::CTownHandler()
|
||||
{
|
||||
VLC->townh = this;
|
||||
|
@ -122,7 +122,7 @@ public:
|
||||
h & subId;
|
||||
h & height;
|
||||
}
|
||||
else if(!h.saving)
|
||||
if(!h.saving && version < 793)
|
||||
{
|
||||
update792(bid, subId, height);
|
||||
}
|
||||
@ -228,6 +228,8 @@ public:
|
||||
std::string getBuildingScope() const;
|
||||
std::set<si32> getAllBuildings() const;
|
||||
const CBuilding * getSpecialBuilding(BuildingSubID::EBuildingSubID subID) const;
|
||||
const std::string getGreeting(BuildingSubID::EBuildingSubID subID) const;
|
||||
void setGreeting(BuildingSubID::EBuildingSubID subID, const std::string message) const; //may affect only mutable field
|
||||
BuildingID::EBuildingID getBuildingType(BuildingSubID::EBuildingSubID subID) const;
|
||||
|
||||
CFaction * faction;
|
||||
@ -335,6 +337,10 @@ public:
|
||||
}
|
||||
h & defaultTavernChance;
|
||||
}
|
||||
|
||||
private:
|
||||
///generated bonusing buildings messages for all towns of this type.
|
||||
mutable std::map<BuildingSubID::EBuildingSubID, const std::string> specialMessages; //may be changed by CGTownBuilding::getVisitingBonusGreeting() const
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CTownHandler : public IHandlerBase
|
||||
|
@ -1644,11 +1644,11 @@ void CGTownInstance::serializeJsonOptions(JsonSerializeFormat & handler)
|
||||
}
|
||||
}
|
||||
|
||||
COPWBonus::COPWBonus (BuildingID bid, BuildingSubID::EBuildingSubID subId, CGTownInstance *TOWN)
|
||||
COPWBonus::COPWBonus(BuildingID bid, BuildingSubID::EBuildingSubID subId, CGTownInstance * cgTown)
|
||||
{
|
||||
bID = bid;
|
||||
bType = subId;
|
||||
town = TOWN;
|
||||
town = cgTown;
|
||||
indexOnTV = static_cast<si32>(town->bonusingBuildings.size());
|
||||
}
|
||||
|
||||
@ -1701,7 +1701,7 @@ void COPWBonus::onHeroVisit(const CGHeroInstance * h) const
|
||||
cb->setManaPoints(heroID, 2 * h->manaLimit());
|
||||
//TODO: investigate line below
|
||||
//cb->setObjProperty (town->id, ObjProperty::VISITED, true);
|
||||
iw.text << VLC->generaltexth->allTexts[579];
|
||||
iw.text << getVisitingBonusGreeting();
|
||||
cb->showInfoDialog(&iw);
|
||||
//extra visit penalty if hero alredy had double mana points (or even more?!)
|
||||
town->addHeroToStructureVisitors(h, indexOnTV);
|
||||
@ -1710,11 +1710,11 @@ void COPWBonus::onHeroVisit(const CGHeroInstance * h) const
|
||||
}
|
||||
}
|
||||
}
|
||||
CTownBonus::CTownBonus (BuildingID index, BuildingSubID::EBuildingSubID subId, CGTownInstance *TOWN)
|
||||
CTownBonus::CTownBonus(BuildingID index, BuildingSubID::EBuildingSubID subId, CGTownInstance * cgTown)
|
||||
{
|
||||
bID = index;
|
||||
bType = subId;
|
||||
town = TOWN;
|
||||
town = cgTown;
|
||||
indexOnTV = static_cast<si32>(town->bonusingBuildings.size());
|
||||
}
|
||||
|
||||
@ -1729,7 +1729,6 @@ void CTownBonus::onHeroVisit(const CGHeroInstance * h) const
|
||||
ObjectInstanceID heroID = h->id;
|
||||
if (town->hasBuilt(bID) && visitors.find(heroID) == visitors.end())
|
||||
{
|
||||
si32 mid = 0;
|
||||
si64 val = 0;
|
||||
InfoWindow iw;
|
||||
PrimarySkill::PrimarySkill what = PrimarySkill::ATTACK;
|
||||
@ -1739,41 +1738,35 @@ void CTownBonus::onHeroVisit(const CGHeroInstance * h) const
|
||||
case BuildingSubID::KNOWLEDGE_VISITING_BONUS: //wall of knowledge
|
||||
what = PrimarySkill::KNOWLEDGE;
|
||||
val = 1;
|
||||
mid = 581;
|
||||
iw.components.push_back(Component(Component::PRIM_SKILL, 3, 1, 0));
|
||||
break;
|
||||
|
||||
case BuildingSubID::SPELL_POWER_VISITING_BONUS: //order of fire
|
||||
what = PrimarySkill::SPELL_POWER;
|
||||
val = 1;
|
||||
mid = 582;
|
||||
iw.components.push_back(Component(Component::PRIM_SKILL, 2, 1, 0));
|
||||
break;
|
||||
|
||||
case BuildingSubID::ATTACK_VISITING_BONUS: //hall of Valhalla
|
||||
what = PrimarySkill::ATTACK;
|
||||
val = 1;
|
||||
mid = 584;
|
||||
iw.components.push_back(Component(Component::PRIM_SKILL, 0, 1, 0));
|
||||
break;
|
||||
|
||||
case BuildingSubID::EXPERIENCE_VISITING_BONUS: //academy of battle scholars
|
||||
what = PrimarySkill::EXPERIENCE;
|
||||
val = static_cast<int>(h->calculateXp(1000));
|
||||
mid = 583;
|
||||
iw.components.push_back(Component(Component::EXPERIENCE, 0, val, 0));
|
||||
break;
|
||||
|
||||
case BuildingSubID::DEFENSE_VISITING_BONUS: //cage of warlords
|
||||
what = PrimarySkill::DEFENSE;
|
||||
val = 1;
|
||||
mid = 585;
|
||||
iw.components.push_back(Component(Component::PRIM_SKILL, 1, 1, 0));
|
||||
break;
|
||||
}
|
||||
assert(mid);
|
||||
iw.player = cb->getOwner(heroID);
|
||||
iw.text << VLC->generaltexth->allTexts[mid];
|
||||
iw.text << getVisitingBonusGreeting();
|
||||
cb->showInfoDialog(&iw);
|
||||
cb->changePrimSkill(cb->getHero(heroID), what, val);
|
||||
town->addHeroToStructureVisitors(h, indexOnTV);
|
||||
@ -1811,3 +1804,39 @@ int GrowthInfo::totalGrowth() const
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const std::string CGTownBuilding::getVisitingBonusGreeting() const
|
||||
{
|
||||
auto bonusGreeting = town->town->getGreeting(bType);
|
||||
|
||||
if(!bonusGreeting.empty())
|
||||
return bonusGreeting;
|
||||
|
||||
switch(bType)
|
||||
{
|
||||
case BuildingSubID::MANA_VORTEX:
|
||||
bonusGreeting = std::string(VLC->generaltexth->localizedTexts["townHall"]["greetingManaVortex"].String());
|
||||
break;
|
||||
case BuildingSubID::KNOWLEDGE_VISITING_BONUS:
|
||||
bonusGreeting = std::string(VLC->generaltexth->localizedTexts["townHall"]["greetingKnowledge"].String());
|
||||
break;
|
||||
case BuildingSubID::SPELL_POWER_VISITING_BONUS:
|
||||
bonusGreeting = std::string(VLC->generaltexth->localizedTexts["townHall"]["greetingSpellPower"].String());
|
||||
break;
|
||||
case BuildingSubID::ATTACK_VISITING_BONUS:
|
||||
bonusGreeting = std::string(VLC->generaltexth->localizedTexts["townHall"]["greetingAttack"].String());
|
||||
break;
|
||||
case BuildingSubID::EXPERIENCE_VISITING_BONUS:
|
||||
bonusGreeting = std::string(VLC->generaltexth->localizedTexts["townHall"]["greetingExperience"].String());
|
||||
break;
|
||||
case BuildingSubID::DEFENSE_VISITING_BONUS:
|
||||
bonusGreeting = std::string(VLC->generaltexth->localizedTexts["townHall"]["greetingDefence"].String());
|
||||
break;
|
||||
}
|
||||
|
||||
assert(!bonusGreeting.empty());
|
||||
auto buildingName = town->town->getSpecialBuilding(bType)->Name();
|
||||
boost::algorithm::replace_first(bonusGreeting, "%s", buildingName);
|
||||
town->town->setGreeting(bType, bonusGreeting);
|
||||
return bonusGreeting;
|
||||
}
|
||||
|
@ -127,9 +127,12 @@ public:
|
||||
if(version >= 792)
|
||||
h & bType;
|
||||
}
|
||||
|
||||
protected:
|
||||
BuildingID bID; //from buildig list
|
||||
BuildingSubID::EBuildingSubID bType;
|
||||
|
||||
const std::string getVisitingBonusGreeting() const;
|
||||
};
|
||||
|
||||
class DLL_LINKAGE COPWBonus : public CGTownBuilding
|
||||
@ -251,7 +254,7 @@ public:
|
||||
return false;
|
||||
});
|
||||
|
||||
if(!h.saving && version < 792)
|
||||
if(!h.saving && version < 793)
|
||||
updateBonusingBuildings();
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
@ -196,11 +196,27 @@ void CObjectClassesHandler::loadObjectEntry(const std::string & identifier, cons
|
||||
|
||||
//some mods redefine content handlers in the decoration.json in such way:
|
||||
//"core:sign" : { "types" : { "forgeSign" : { ...
|
||||
if (!obj->subObjects.count(id)) // DO NOT override
|
||||
static const std::vector<std::string> knownProblemObjects
|
||||
{
|
||||
"hota.hota decorations:hotaPandoraBox"
|
||||
, "hota.hota decorations:hotaSubterreanGate"
|
||||
};
|
||||
bool overrideForce = !obj->subObjects.count(id) ||
|
||||
std::any_of(knownProblemObjects.begin(), knownProblemObjects.end(), [obj, id](const std::string & str)
|
||||
{
|
||||
return str.compare(obj->subObjects[id]->subTypeName) == 0;
|
||||
});
|
||||
|
||||
if (overrideForce) // DO NOT override mod handlers by default
|
||||
{
|
||||
obj->subObjects[id] = handler;
|
||||
obj->subIds[convertedId] = id;
|
||||
}
|
||||
else
|
||||
{
|
||||
logGlobal->warn("Don't override handler %s in object %s(%d)::%s(%d) subTypeName : %s"
|
||||
, obj->handlerName, obj->identifier, obj->id, convertedId, id, obj->subObjects[id]->subTypeName);
|
||||
}
|
||||
}
|
||||
|
||||
CObjectClassesHandler::ObjectContainter * CObjectClassesHandler::loadFromJson(const JsonNode & json, const std::string & name)
|
||||
|
@ -610,15 +610,16 @@ void CMapGenerator::createConnections2()
|
||||
|
||||
std::vector<int3> commonTiles;
|
||||
|
||||
//required for set_intersection
|
||||
boost::sort(tilesA);
|
||||
boost::sort(tilesB);
|
||||
|
||||
boost::set_intersection(tilesA, tilesB, std::back_inserter(commonTiles), [](const int3 &lhs, const int3 &rhs) -> bool
|
||||
auto lambda = [](const int3 & lhs, const int3 & rhs) -> bool
|
||||
{
|
||||
//ignore z coordinate
|
||||
return lhs.x < rhs.x || lhs.y < rhs.y;
|
||||
});
|
||||
//https://stackoverflow.com/questions/45966807/c-invalid-comparator-assert
|
||||
return std::tie(lhs.x, lhs.y) < std::tie(rhs.x, rhs.y); //ignore z coordinate
|
||||
};
|
||||
//required for set_intersection
|
||||
boost::sort(tilesA, lambda);
|
||||
boost::sort(tilesB, lambda);
|
||||
|
||||
boost::set_intersection(tilesA, tilesB, std::back_inserter(commonTiles), lambda);
|
||||
|
||||
vstd::erase_if(commonTiles, [](const int3 &tile) -> bool
|
||||
{
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include "../ConstTransitivePtr.h"
|
||||
#include "../GameConstants.h"
|
||||
|
||||
const ui32 SERIALIZATION_VERSION = 792;
|
||||
const ui32 SERIALIZATION_VERSION = 793;
|
||||
const ui32 MINIMAL_SERIALIZATION_VERSION = 753;
|
||||
const std::string SAVEGAME_MAGIC = "VCMISVG";
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user