1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Mod system improvement: Patch 2

This commit is contained in:
Dmitry Orlov 2020-10-25 01:04:34 +03:00
parent 3cb0dfb143
commit d6a4767865
8 changed files with 104 additions and 20 deletions

View File

@ -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));
}

View File

@ -1269,7 +1269,18 @@ CUniversityWindow::CUniversityWindow(const CGHeroInstance * _hero, const IMarket
bars->preload();
if(market->o->ID == Obj::TOWN)
{
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");

View File

@ -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" :
{

View File

@ -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;

View File

@ -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

View File

@ -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;
}

View File

@ -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();
}
//////////////////////////////////////////////////////////////////////////

View File

@ -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";