1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-24 08:32:34 +02:00
vcmi/lib/mapping/CMapHeader.cpp
2023-10-01 18:00:36 +02:00

216 lines
6.2 KiB
C++

/*
* CMapHeader.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 "CMapHeader.h"
#include "MapFormat.h"
#include "../VCMI_Lib.h"
#include "../CTownHandler.h"
#include "../CGeneralTextHandler.h"
#include "../modding/CModHandler.h"
#include "../CHeroHandler.h"
#include "../Languages.h"
VCMI_LIB_NAMESPACE_BEGIN
SHeroName::SHeroName() : heroId(-1)
{
}
PlayerInfo::PlayerInfo(): canHumanPlay(false), canComputerPlay(false),
aiTactic(EAiTactic::RANDOM), isFactionRandom(false), hasRandomHero(false), mainCustomHeroPortrait(-1), mainCustomHeroId(-1), hasMainTown(false),
generateHeroAtMainTown(false), posOfMainTown(-1), team(TeamID::NO_TEAM)
{
allowedFactions = VLC->townh->getAllowedFactions();
}
si8 PlayerInfo::defaultCastle() const
{
//if random allowed set it as default
if(isFactionRandom)
return -1;
if(!allowedFactions.empty())
return *allowedFactions.begin();
// fall back to random
return -1;
}
si8 PlayerInfo::defaultHero() const
{
// we will generate hero in front of main town
if((generateHeroAtMainTown && hasMainTown) || hasRandomHero)
{
//random hero
return -1;
}
return -2;
}
bool PlayerInfo::canAnyonePlay() const
{
return canHumanPlay || canComputerPlay;
}
bool PlayerInfo::hasCustomMainHero() const
{
return !mainCustomHeroNameTextId.empty() && mainCustomHeroPortrait != -1;
}
EventCondition::EventCondition(EWinLoseType condition):
object(nullptr),
metaType(EMetaclass::INVALID),
value(-1),
objectType(-1),
objectSubtype(-1),
position(-1, -1, -1),
condition(condition)
{
}
EventCondition::EventCondition(EWinLoseType condition, si32 value, si32 objectType, const int3 & position):
object(nullptr),
metaType(EMetaclass::INVALID),
value(value),
objectType(objectType),
objectSubtype(-1),
position(position),
condition(condition)
{}
void CMapHeader::setupEvents()
{
EventCondition victoryCondition(EventCondition::STANDARD_WIN);
EventCondition defeatCondition(EventCondition::DAYS_WITHOUT_TOWN);
defeatCondition.value = 7;
//Victory condition - defeat all
TriggeredEvent standardVictory;
standardVictory.effect.type = EventEffect::VICTORY;
standardVictory.effect.toOtherMessage.appendTextID("core.genrltxt.5");
standardVictory.identifier = "standardVictory";
standardVictory.description.clear(); // TODO: display in quest window
standardVictory.onFulfill.appendTextID("core.genrltxt.659");
standardVictory.trigger = EventExpression(victoryCondition);
//Loss condition - 7 days without town
TriggeredEvent standardDefeat;
standardDefeat.effect.type = EventEffect::DEFEAT;
standardDefeat.effect.toOtherMessage.appendTextID("core.genrltxt.8");
standardDefeat.identifier = "standardDefeat";
standardDefeat.description.clear(); // TODO: display in quest window
standardDefeat.onFulfill.appendTextID("core.genrltxt.7");
standardDefeat.trigger = EventExpression(defeatCondition);
triggeredEvents.push_back(standardVictory);
triggeredEvents.push_back(standardDefeat);
victoryIconIndex = 11;
victoryMessage.appendTextID("core.vcdesc.0");
defeatIconIndex = 3;
defeatMessage.appendTextID("core.lcdesc.0");
}
CMapHeader::CMapHeader() : version(EMapFormat::VCMI), height(72), width(72),
twoLevel(true), difficulty(1), levelLimit(0), howManyTeams(0), areAnyPlayers(false)
{
setupEvents();
allowedHeroes = VLC->heroh->getDefaultAllowed();
players.resize(PlayerColor::PLAYER_LIMIT_I);
VLC->generaltexth->addSubContainer(*this);
}
CMapHeader::~CMapHeader()
{
VLC->generaltexth->removeSubContainer(*this);
}
ui8 CMapHeader::levels() const
{
return (twoLevel ? 2 : 1);
}
void CMapHeader::registerMapStrings()
{
//get supported languages. Assuming that translation containing most strings is the base language
std::set<std::string> mapLanguages, mapBaseLanguages;
int maxStrings = 0;
for(auto & translation : translations.Struct())
{
if(translation.first.empty() || !translation.second.isStruct() || translation.second.Struct().empty())
continue;
if(translation.second.Struct().size() > maxStrings)
maxStrings = translation.second.Struct().size();
mapLanguages.insert(translation.first);
}
if(maxStrings == 0 || mapBaseLanguages.empty())
{
logGlobal->info("Map %s doesn't have any supported translation", name.toString());
return;
}
//identifying base languages
for(auto & translation : translations.Struct())
{
if(translation.second.isStruct() && translation.second.Struct().size() == maxStrings)
mapBaseLanguages.insert(translation.first);
}
std::string baseLanguage, language;
//english is preferrable as base language
if(mapBaseLanguages.count(Languages::getLanguageOptions(Languages::ELanguages::ENGLISH).identifier))
baseLanguage = Languages::getLanguageOptions(Languages::ELanguages::ENGLISH).identifier;
else
baseLanguage = *mapBaseLanguages.begin();
if(mapBaseLanguages.count(CGeneralTextHandler::getPreferredLanguage()))
{
language = CGeneralTextHandler::getPreferredLanguage(); //preferred language is base language - use it
baseLanguage = language;
}
else
{
if(mapLanguages.count(CGeneralTextHandler::getPreferredLanguage()))
language = CGeneralTextHandler::getPreferredLanguage();
else
language = baseLanguage; //preferred language is not supported, use base language
}
assert(!language.empty());
JsonNode data = translations[baseLanguage];
if(language != baseLanguage)
JsonUtils::mergeCopy(data, translations[language]);
for(auto & s : data.Struct())
registerString("map", TextIdentifier(s.first), s.second.String(), language);
}
std::string mapRegisterLocalizedString(const std::string & modContext, CMapHeader & mapHeader, const TextIdentifier & UID, const std::string & localized)
{
return mapRegisterLocalizedString(modContext, mapHeader, UID, localized, VLC->modh->getModLanguage(modContext));
}
std::string mapRegisterLocalizedString(const std::string & modContext, CMapHeader & mapHeader, const TextIdentifier & UID, const std::string & localized, const std::string & language)
{
mapHeader.registerString(modContext, UID, localized, language);
mapHeader.translations.Struct()[language].Struct()[UID.get()].String() = localized;
return UID.get();
}
VCMI_LIB_NAMESPACE_END