mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-28 08:48:48 +02:00
Converted Component class to use VariantIdentifier instead of int
This commit is contained in:
parent
0376873cb3
commit
10e50548e7
@ -664,7 +664,7 @@ void AIGateway::showBlockingDialog(const std::string & text, const std::vector<C
|
||||
// TODO: Find better way to understand it is Chest of Treasures
|
||||
if(hero.validAndSet()
|
||||
&& components.size() == 2
|
||||
&& components.front().id == Component::EComponentType::RESOURCE
|
||||
&& components.front().type == ComponentType::RESOURCE
|
||||
&& (nullkiller->heroManager->getHeroRole(hero) != HeroRole::MAIN
|
||||
|| nullkiller->buildAnalyzer->getGoldPreasure() > MAX_GOLD_PEASURE))
|
||||
{
|
||||
|
@ -293,7 +293,7 @@ void CPlayerInterface::yourTurn(QueryID queryID)
|
||||
std::string msg = CGI->generaltexth->allTexts[13];
|
||||
boost::replace_first(msg, "%s", cb->getStartInfo()->playerInfos.find(playerID)->second.name);
|
||||
std::vector<std::shared_ptr<CComponent>> cmp;
|
||||
cmp.push_back(std::make_shared<CComponent>(CComponent::flag, playerID.getNum(), 0));
|
||||
cmp.push_back(std::make_shared<CComponent>(ComponentType::FLAG, playerID));
|
||||
showInfoDialog(msg, cmp);
|
||||
}
|
||||
else
|
||||
@ -326,7 +326,7 @@ void CPlayerInterface::acceptTurn(QueryID queryID)
|
||||
auto playerColor = *cb->getPlayerID();
|
||||
|
||||
std::vector<Component> components;
|
||||
components.emplace_back(Component::EComponentType::FLAG, playerColor.getNum(), 0, 0);
|
||||
components.emplace_back(ComponentType::FLAG, playerColor);
|
||||
MetaString text;
|
||||
|
||||
const auto & optDaysWithoutCastle = cb->getPlayerState(playerColor)->daysWithoutCastle;
|
||||
@ -1228,7 +1228,7 @@ void CPlayerInterface::showArtifactAssemblyDialog(const Artifact * artifact, con
|
||||
text += boost::str(boost::format(CGI->generaltexth->allTexts[732]) % assembledArtifact->getNameTranslated());
|
||||
|
||||
// Picture of assembled artifact at bottom.
|
||||
auto sc = std::make_shared<CComponent>(CComponent::artifact, assembledArtifact->getIndex(), 0);
|
||||
auto sc = std::make_shared<CComponent>(ComponentType::ARTIFACT, assembledArtifact->getId());
|
||||
scs.push_back(sc);
|
||||
}
|
||||
else
|
||||
@ -1441,7 +1441,7 @@ void CPlayerInterface::playerBlocked(int reason, bool start)
|
||||
std::string msg = CGI->generaltexth->translate("vcmi.adventureMap.playerAttacked");
|
||||
boost::replace_first(msg, "%s", cb->getStartInfo()->playerInfos.find(playerID)->second.name);
|
||||
std::vector<std::shared_ptr<CComponent>> cmp;
|
||||
cmp.push_back(std::make_shared<CComponent>(CComponent::flag, playerID.getNum(), 0));
|
||||
cmp.push_back(std::make_shared<CComponent>(ComponentType::FLAG, playerID));
|
||||
makingTurn = true; //workaround for stiff showInfoDialog implementation
|
||||
showInfoDialog(msg, cmp);
|
||||
makingTurn = false;
|
||||
|
@ -376,47 +376,51 @@ void CInfoBar::pushComponents(const std::vector<Component> & components, std::st
|
||||
std::array<std::pair<std::vector<Component>, int>, 10> reward_map;
|
||||
for(const auto & c : components)
|
||||
{
|
||||
switch(c.id)
|
||||
switch(c.type)
|
||||
{
|
||||
case Component::EComponentType::PRIM_SKILL:
|
||||
case Component::EComponentType::EXPERIENCE:
|
||||
case ComponentType::PRIM_SKILL:
|
||||
case ComponentType::EXPERIENCE:
|
||||
case ComponentType::LEVEL:
|
||||
case ComponentType::MANA:
|
||||
reward_map.at(0).first.push_back(c);
|
||||
reward_map.at(0).second = 8; //At most 8, cannot be more
|
||||
break;
|
||||
case Component::EComponentType::SEC_SKILL:
|
||||
case ComponentType::SEC_SKILL:
|
||||
reward_map.at(1).first.push_back(c);
|
||||
reward_map.at(1).second = 4; //At most 4
|
||||
break;
|
||||
case Component::EComponentType::SPELL:
|
||||
case ComponentType::SPELL:
|
||||
reward_map.at(2).first.push_back(c);
|
||||
reward_map.at(2).second = 4; //At most 4
|
||||
break;
|
||||
case Component::EComponentType::ARTIFACT:
|
||||
case ComponentType::ARTIFACT:
|
||||
case ComponentType::SPELL_SCROLL:
|
||||
reward_map.at(3).first.push_back(c);
|
||||
reward_map.at(3).second = 4; //At most 4, too long names
|
||||
break;
|
||||
case Component::EComponentType::CREATURE:
|
||||
case ComponentType::CREATURE:
|
||||
reward_map.at(4).first.push_back(c);
|
||||
reward_map.at(4).second = 4; //At most 4, too long names
|
||||
break;
|
||||
case Component::EComponentType::RESOURCE:
|
||||
case ComponentType::RESOURCE:
|
||||
case ComponentType::RESOURCE_PER_DAY:
|
||||
reward_map.at(5).first.push_back(c);
|
||||
reward_map.at(5).second = 7; //At most 7
|
||||
break;
|
||||
case Component::EComponentType::MORALE:
|
||||
case Component::EComponentType::LUCK:
|
||||
case ComponentType::MORALE:
|
||||
case ComponentType::LUCK:
|
||||
reward_map.at(6).first.push_back(c);
|
||||
reward_map.at(6).second = 2; //At most 2 - 1 for morale + 1 for luck
|
||||
break;
|
||||
case Component::EComponentType::BUILDING:
|
||||
case ComponentType::BUILDING:
|
||||
reward_map.at(7).first.push_back(c);
|
||||
reward_map.at(7).second = 1; //At most 1 - only large icons available AFAIK
|
||||
break;
|
||||
case Component::EComponentType::HERO_PORTRAIT:
|
||||
case ComponentType::HERO_PORTRAIT:
|
||||
reward_map.at(8).first.push_back(c);
|
||||
reward_map.at(8).second = 1; //I do not think than we even can get more than 1 hero
|
||||
break;
|
||||
case Component::EComponentType::FLAG:
|
||||
case ComponentType::FLAG:
|
||||
reward_map.at(9).first.push_back(c);
|
||||
reward_map.at(9).second = 1; //I do not think than we even can get more than 1 player in notification
|
||||
break;
|
||||
|
@ -571,7 +571,7 @@ void OptionsTab::CPlayerOptionTooltipBox::genTownWindow()
|
||||
for(auto & elem : town->creatures)
|
||||
{
|
||||
if(!elem.empty())
|
||||
components.push_back(std::make_shared<CComponent>(CComponent::creature, elem.front(), 0, CComponent::tiny));
|
||||
components.push_back(std::make_shared<CComponent>(ComponentType::CREATURE, elem.front(), 0, CComponent::tiny));
|
||||
}
|
||||
boxAssociatedCreatures = std::make_shared<CComponentBox>(components, Rect(10, 140, pos.w - 20, 140));
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ void CArtPlace::setInternals(const CArtifactInstance * artInst)
|
||||
if(settings["general"]["enableUiEnhancements"].Bool())
|
||||
{
|
||||
imageIndex = spellID.num;
|
||||
if(baseType != CComponent::spell)
|
||||
if(component.type != ComponentType::SPELL_SCROLL)
|
||||
{
|
||||
image->setScale(Point(pos.w, 34));
|
||||
image->setAnimationPath(AnimationPath::builtin("spellscr"), imageIndex);
|
||||
@ -57,21 +57,20 @@ void CArtPlace::setInternals(const CArtifactInstance * artInst)
|
||||
}
|
||||
}
|
||||
// Add spell component info (used to provide a pic in r-click popup)
|
||||
baseType = CComponent::spell;
|
||||
type = spellID;
|
||||
component.type = ComponentType::SPELL_SCROLL;
|
||||
component.subType = spellID;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(settings["general"]["enableUiEnhancements"].Bool() && baseType != CComponent::artifact)
|
||||
if(settings["general"]["enableUiEnhancements"].Bool() && component.type != ComponentType::ARTIFACT)
|
||||
{
|
||||
image->setScale(Point());
|
||||
image->setAnimationPath(AnimationPath::builtin("artifact"), imageIndex);
|
||||
image->moveTo(Point(pos.x, pos.y));
|
||||
}
|
||||
baseType = CComponent::artifact;
|
||||
type = artInst->getTypeId();
|
||||
component.type = ComponentType::ARTIFACT;
|
||||
component.subType = artInst->getTypeId();
|
||||
}
|
||||
bonusValue = 0;
|
||||
image->enable();
|
||||
text = artInst->getDescription();
|
||||
}
|
||||
|
@ -39,41 +39,35 @@
|
||||
#include "../../lib/CArtHandler.h"
|
||||
#include "../../lib/CArtifactInstance.h"
|
||||
|
||||
CComponent::CComponent(Etype Type, int Subtype, int Val, ESize imageSize, EFonts font):
|
||||
perDay(false)
|
||||
CComponent::CComponent(ComponentType Type, ComponentSubType Subtype, std::optional<int32_t> Val, ESize imageSize, EFonts font)
|
||||
{
|
||||
init(Type, Subtype, Val, imageSize, font, "");
|
||||
}
|
||||
|
||||
CComponent::CComponent(Etype Type, int Subtype, std::string Val, ESize imageSize, EFonts font):
|
||||
perDay(false)
|
||||
CComponent::CComponent(ComponentType Type, ComponentSubType Subtype, std::string Val, ESize imageSize, EFonts font)
|
||||
{
|
||||
init(Type, Subtype, 0, imageSize, font, Val);
|
||||
init(Type, Subtype, std::nullopt, imageSize, font, Val);
|
||||
}
|
||||
|
||||
CComponent::CComponent(const Component & c, ESize imageSize, EFonts font)
|
||||
: perDay(false)
|
||||
{
|
||||
if(c.id == Component::EComponentType::RESOURCE && c.when==-1)
|
||||
perDay = true;
|
||||
|
||||
init((Etype)c.id, c.subtype, c.val, imageSize, font);
|
||||
init(c.type, c.subType, c.value, imageSize, font);
|
||||
}
|
||||
|
||||
void CComponent::init(Etype Type, int Subtype, int Val, ESize imageSize, EFonts fnt, std::string ValText)
|
||||
void CComponent::init(ComponentType Type, ComponentSubType Subtype, std::optional<int32_t> Val, ESize imageSize, EFonts fnt, std::string ValText)
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
|
||||
|
||||
addUsedEvents(SHOW_POPUP);
|
||||
|
||||
compType = Type;
|
||||
subtype = Subtype;
|
||||
val = Val;
|
||||
valText = ValText;
|
||||
data.type = Type;
|
||||
data.subType = Subtype;
|
||||
data.value = Val;
|
||||
|
||||
customSubtitle = ValText;
|
||||
size = imageSize;
|
||||
font = fnt;
|
||||
|
||||
assert(compType < typeInvalid);
|
||||
assert(size < sizeInvalid);
|
||||
|
||||
setSurface(getFileName()[size], (int)getIndex());
|
||||
@ -94,7 +88,7 @@ void CComponent::init(Etype Type, int Subtype, int Val, ESize imageSize, EFonts
|
||||
if (size < small)
|
||||
max = 30;
|
||||
|
||||
if(Type == Etype::resource && !valText.empty())
|
||||
if(Type == ComponentType::RESOURCE && !ValText.empty())
|
||||
max = 80;
|
||||
|
||||
std::vector<std::string> textLines = CMessage::breakText(getSubtitle(), std::max<int>(max, pos.w), font);
|
||||
@ -115,151 +109,207 @@ void CComponent::init(Etype Type, int Subtype, int Val, ESize imageSize, EFonts
|
||||
|
||||
std::vector<AnimationPath> CComponent::getFileName()
|
||||
{
|
||||
static const std::string primSkillsArr [] = {"PSKIL32", "PSKIL32", "PSKIL42", "PSKILL"};
|
||||
static const std::string secSkillsArr [] = {"SECSK32", "SECSK32", "SECSKILL", "SECSK82"};
|
||||
static const std::string resourceArr [] = {"SMALRES", "RESOURCE", "RESOURCE", "RESOUR82"};
|
||||
static const std::string creatureArr [] = {"CPRSMALL", "CPRSMALL", "CPRSMALL", "TWCRPORT"};
|
||||
static const std::string artifactArr[] = {"Artifact", "Artifact", "Artifact", "Artifact"};
|
||||
static const std::string spellsArr [] = {"SpellInt", "SpellInt", "SpellInt", "SPELLSCR"};
|
||||
static const std::string moraleArr [] = {"IMRL22", "IMRL30", "IMRL42", "imrl82"};
|
||||
static const std::string luckArr [] = {"ILCK22", "ILCK30", "ILCK42", "ilck82"};
|
||||
static const std::string heroArr [] = {"PortraitsSmall", "PortraitsSmall", "PortraitsSmall", "PortraitsLarge"};
|
||||
static const std::string flagArr [] = {"CREST58", "CREST58", "CREST58", "CREST58"};
|
||||
static const std::array<std::string, 4> primSkillsArr = {"PSKIL32", "PSKIL32", "PSKIL42", "PSKILL"};
|
||||
static const std::array<std::string, 4> secSkillsArr = {"SECSK32", "SECSK32", "SECSKILL", "SECSK82"};
|
||||
static const std::array<std::string, 4> resourceArr = {"SMALRES", "RESOURCE", "RESOURCE", "RESOUR82"};
|
||||
static const std::array<std::string, 4> creatureArr = {"CPRSMALL", "CPRSMALL", "CPRSMALL", "TWCRPORT"};
|
||||
static const std::array<std::string, 4> artifactArr = {"Artifact", "Artifact", "Artifact", "Artifact"};
|
||||
static const std::array<std::string, 4> spellsArr = {"SpellInt", "SpellInt", "SpellInt", "SPELLSCR"};
|
||||
static const std::array<std::string, 4> moraleArr = {"IMRL22", "IMRL30", "IMRL42", "imrl82"};
|
||||
static const std::array<std::string, 4> luckArr = {"ILCK22", "ILCK30", "ILCK42", "ilck82"};
|
||||
static const std::array<std::string, 4> heroArr = {"PortraitsSmall", "PortraitsSmall", "PortraitsSmall", "PortraitsLarge"};
|
||||
static const std::array<std::string, 4> flagArr = {"CREST58", "CREST58", "CREST58", "CREST58"};
|
||||
|
||||
auto gen = [](const std::string * arr) -> std::vector<AnimationPath>
|
||||
auto gen = [](const std::array<std::string, 4> & arr) -> std::vector<AnimationPath>
|
||||
{
|
||||
return { AnimationPath::builtin(arr[0]), AnimationPath::builtin(arr[1]), AnimationPath::builtin(arr[2]), AnimationPath::builtin(arr[3]) };
|
||||
};
|
||||
|
||||
switch(compType)
|
||||
switch(data.type)
|
||||
{
|
||||
case primskill: return gen(primSkillsArr);
|
||||
case secskill: return gen(secSkillsArr);
|
||||
case resource: return gen(resourceArr);
|
||||
case creature: return gen(creatureArr);
|
||||
case artifact: return gen(artifactArr);
|
||||
case experience: return gen(primSkillsArr);
|
||||
case spell: return gen(spellsArr);
|
||||
case morale: return gen(moraleArr);
|
||||
case luck: return gen(luckArr);
|
||||
case building: return std::vector<AnimationPath>(4, (*CGI->townh)[subtype]->town->clientInfo.buildingsIcons);
|
||||
case hero: return gen(heroArr);
|
||||
case flag: return gen(flagArr);
|
||||
case ComponentType::PRIM_SKILL:
|
||||
case ComponentType::EXPERIENCE:
|
||||
case ComponentType::MANA:
|
||||
case ComponentType::LEVEL:
|
||||
return gen(primSkillsArr);
|
||||
case ComponentType::SEC_SKILL:
|
||||
return gen(secSkillsArr);
|
||||
case ComponentType::RESOURCE:
|
||||
case ComponentType::RESOURCE_PER_DAY:
|
||||
return gen(resourceArr);
|
||||
case ComponentType::CREATURE:
|
||||
return gen(creatureArr);
|
||||
case ComponentType::ARTIFACT:
|
||||
return gen(artifactArr);
|
||||
case ComponentType::SPELL_SCROLL:
|
||||
case ComponentType::SPELL:
|
||||
return gen(spellsArr);
|
||||
case ComponentType::MORALE:
|
||||
return gen(moraleArr);
|
||||
case ComponentType::LUCK:
|
||||
return gen(luckArr);
|
||||
case ComponentType::BUILDING:
|
||||
return std::vector<AnimationPath>(4, (*CGI->townh)[data.subType.as<BuildingTypeUniqueID>().getFaction()]->town->clientInfo.buildingsIcons);
|
||||
case ComponentType::HERO_PORTRAIT:
|
||||
return gen(heroArr);
|
||||
case ComponentType::FLAG:
|
||||
return gen(flagArr);
|
||||
default:
|
||||
assert(0);
|
||||
return {};
|
||||
}
|
||||
assert(0);
|
||||
return {};
|
||||
}
|
||||
|
||||
size_t CComponent::getIndex()
|
||||
{
|
||||
switch(compType)
|
||||
switch(data.type)
|
||||
{
|
||||
case primskill: return subtype;
|
||||
case secskill: return subtype*3 + 3 + val - 1;
|
||||
case resource: return subtype;
|
||||
case creature: return CGI->creatures()->getByIndex(subtype)->getIconIndex();
|
||||
case artifact: return CGI->artifacts()->getByIndex(subtype)->getIconIndex();
|
||||
case experience: return 4;
|
||||
case spell: return (size < large) ? subtype + 1 : subtype;
|
||||
case morale: return val+3;
|
||||
case luck: return val+3;
|
||||
case building: return val;
|
||||
case hero: return CGI->heroTypes()->getByIndex(subtype)->getIconIndex();
|
||||
case flag: return subtype;
|
||||
case ComponentType::PRIM_SKILL:
|
||||
return data.subType.getNum();
|
||||
case ComponentType::EXPERIENCE:
|
||||
case ComponentType::LEVEL:
|
||||
return 4; // for whatever reason, in H3 experience icon is located in primary skills icons
|
||||
case ComponentType::MANA:
|
||||
return 5; // for whatever reason, in H3 mana points icon is located in primary skills icons
|
||||
case ComponentType::SEC_SKILL:
|
||||
return data.subType.getNum() * 3 + 3 + data.value.value_or(0) - 1;
|
||||
case ComponentType::RESOURCE:
|
||||
case ComponentType::RESOURCE_PER_DAY:
|
||||
return data.subType.getNum();
|
||||
case ComponentType::CREATURE:
|
||||
return CGI->creatures()->getById(data.subType.as<CreatureID>())->getIconIndex();
|
||||
case ComponentType::ARTIFACT:
|
||||
return CGI->artifacts()->getById(data.subType.as<ArtifactID>())->getIconIndex();
|
||||
case ComponentType::SPELL_SCROLL:
|
||||
case ComponentType::SPELL:
|
||||
return (size < large) ? data.subType.getNum() + 1 : data.subType.getNum();
|
||||
case ComponentType::MORALE:
|
||||
return data.value.value_or(0) + 3;
|
||||
case ComponentType::LUCK:
|
||||
return data.value.value_or(0) + 3;
|
||||
case ComponentType::BUILDING:
|
||||
return data.subType.as<BuildingTypeUniqueID>().getBuilding();
|
||||
case ComponentType::HERO_PORTRAIT:
|
||||
return CGI->heroTypes()->getById(data.subType.as<HeroTypeID>())->getIconIndex();
|
||||
case ComponentType::FLAG:
|
||||
return data.subType.getNum();
|
||||
default:
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string CComponent::getDescription()
|
||||
{
|
||||
switch(compType)
|
||||
switch(data.type)
|
||||
{
|
||||
case primskill: return (subtype < 4)? CGI->generaltexth->arraytxt[2+subtype] //Primary skill
|
||||
: CGI->generaltexth->allTexts[149]; //mana
|
||||
case secskill: return CGI->skillh->getByIndex(subtype)->getDescriptionTranslated(val);
|
||||
case resource: return CGI->generaltexth->allTexts[242];
|
||||
case creature: return "";
|
||||
case artifact:
|
||||
{
|
||||
auto artID = ArtifactID(subtype);
|
||||
auto description = VLC->arth->objects[artID]->getDescriptionTranslated();
|
||||
if(artID == ArtifactID::SPELL_SCROLL)
|
||||
case ComponentType::PRIM_SKILL:
|
||||
return CGI->generaltexth->arraytxt[2+data.subType.getNum()];
|
||||
case ComponentType::EXPERIENCE:
|
||||
case ComponentType::LEVEL:
|
||||
return CGI->generaltexth->allTexts[241];
|
||||
case ComponentType::MANA:
|
||||
return CGI->generaltexth->allTexts[149];
|
||||
case ComponentType::SEC_SKILL:
|
||||
return CGI->skillh->getByIndex(data.subType.getNum())->getDescriptionTranslated(data.value.value_or(0));
|
||||
case ComponentType::RESOURCE:
|
||||
case ComponentType::RESOURCE_PER_DAY:
|
||||
return CGI->generaltexth->allTexts[242];
|
||||
case ComponentType::CREATURE:
|
||||
return "";
|
||||
case ComponentType::ARTIFACT:
|
||||
return VLC->artifacts()->getById(data.subType.as<ArtifactID>())->getDescriptionTranslated();
|
||||
case ComponentType::SPELL_SCROLL:
|
||||
{
|
||||
ArtifactUtils::insertScrrollSpellName(description, SpellID(val));
|
||||
auto description = VLC->arth->objects[ArtifactID::SPELL_SCROLL]->getDescriptionTranslated();
|
||||
ArtifactUtils::insertScrrollSpellName(description, data.subType.as<SpellID>());
|
||||
return description;
|
||||
}
|
||||
return description;
|
||||
case ComponentType::SPELL:
|
||||
return VLC->spells()->getById(data.subType.as<SpellID>())->getDescriptionTranslated(data.value.value_or(0));
|
||||
case ComponentType::MORALE:
|
||||
return CGI->generaltexth->heroscrn[ 4 - (data.value.value_or(0)>0) + (data.value.value_or(0)<0)];
|
||||
case ComponentType::LUCK:
|
||||
return CGI->generaltexth->heroscrn[ 7 - (data.value.value_or(0)>0) + (data.value.value_or(0)<0)];
|
||||
case ComponentType::BUILDING:
|
||||
{
|
||||
auto index = data.subType.as<BuildingTypeUniqueID>();
|
||||
return (*CGI->townh)[index.getFaction()]->town->buildings[index.getBuilding()]->getDescriptionTranslated();
|
||||
}
|
||||
case ComponentType::HERO_PORTRAIT:
|
||||
return "";
|
||||
case ComponentType::FLAG:
|
||||
return "";
|
||||
default:
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
case experience: return CGI->generaltexth->allTexts[241];
|
||||
case spell: return (*CGI->spellh)[subtype]->getDescriptionTranslated(val);
|
||||
case morale: return CGI->generaltexth->heroscrn[ 4 - (val>0) + (val<0)];
|
||||
case luck: return CGI->generaltexth->heroscrn[ 7 - (val>0) + (val<0)];
|
||||
case building: return (*CGI->townh)[subtype]->town->buildings[BuildingID(val)]->getDescriptionTranslated();
|
||||
case hero: return "";
|
||||
case flag: return "";
|
||||
}
|
||||
assert(0);
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string CComponent::getSubtitle()
|
||||
{
|
||||
if(!perDay)
|
||||
return getSubtitleInternal();
|
||||
if (!customSubtitle.empty())
|
||||
return customSubtitle;
|
||||
|
||||
std::string ret = CGI->generaltexth->allTexts[3];
|
||||
boost::replace_first(ret, "%d", getSubtitleInternal());
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string CComponent::getSubtitleInternal()
|
||||
{
|
||||
//FIXME: some of these are horrible (e.g creature)
|
||||
switch(compType)
|
||||
switch(data.type)
|
||||
{
|
||||
case primskill: return boost::str(boost::format("%+d %s") % val % (subtype < 4 ? CGI->generaltexth->primarySkillNames[subtype] : CGI->generaltexth->allTexts[387]));
|
||||
case secskill: return CGI->generaltexth->levels[val-1] + "\n" + CGI->skillh->getByIndex(subtype)->getNameTranslated();
|
||||
case resource: return valText.empty() ? std::to_string(val) : valText;
|
||||
case creature:
|
||||
{
|
||||
auto creature = CGI->creh->getByIndex(subtype);
|
||||
if ( val )
|
||||
return std::to_string(val) + " " + (val > 1 ? creature->getNamePluralTranslated() : creature->getNameSingularTranslated());
|
||||
case ComponentType::PRIM_SKILL:
|
||||
if (data.value)
|
||||
return boost::str(boost::format("%+d %s") % data.value.value_or(0) % CGI->generaltexth->primarySkillNames[data.subType.getNum()]);
|
||||
else
|
||||
return val > 1 ? creature->getNamePluralTranslated() : creature->getNameSingularTranslated();
|
||||
}
|
||||
case artifact: return CGI->artifacts()->getByIndex(subtype)->getNameTranslated();
|
||||
case experience:
|
||||
return CGI->generaltexth->primarySkillNames[data.subType.getNum()];
|
||||
case ComponentType::EXPERIENCE:
|
||||
return std::to_string(data.value.value_or(0));
|
||||
case ComponentType::LEVEL:
|
||||
{
|
||||
if(subtype == 1) //+1 level - tree of knowledge
|
||||
{
|
||||
std::string level = CGI->generaltexth->allTexts[442];
|
||||
boost::replace_first(level, "1", std::to_string(val));
|
||||
return level;
|
||||
}
|
||||
std::string level = CGI->generaltexth->allTexts[442];
|
||||
boost::replace_first(level, "1", std::to_string(data.value.value_or(0)));
|
||||
return level;
|
||||
}
|
||||
case ComponentType::MANA:
|
||||
return boost::str(boost::format("%+d %s") % data.value.value_or(0) % CGI->generaltexth->allTexts[387]);
|
||||
case ComponentType::SEC_SKILL:
|
||||
return CGI->generaltexth->levels[data.value.value_or(0)-1] + "\n" + CGI->skillh->getById(data.subType.as<SecondarySkill>())->getNameTranslated();
|
||||
case ComponentType::RESOURCE:
|
||||
return std::to_string(data.value.value_or(0));
|
||||
case ComponentType::RESOURCE_PER_DAY:
|
||||
return boost::str(boost::format(CGI->generaltexth->allTexts[387]) % data.value.value_or(0));
|
||||
case ComponentType::CREATURE:
|
||||
{
|
||||
auto creature = CGI->creh->getById(data.subType.as<CreatureID>());
|
||||
if ( data.value.value_or(0) )
|
||||
return std::to_string(data.value.value_or(0)) + " " + (data.value.value_or(0) > 1 ? creature->getNamePluralTranslated() : creature->getNameSingularTranslated());
|
||||
else
|
||||
{
|
||||
return std::to_string(val); //amount of experience OR level required for seer hut;
|
||||
}
|
||||
return data.value.value_or(0) > 1 ? creature->getNamePluralTranslated() : creature->getNameSingularTranslated();
|
||||
}
|
||||
case spell: return CGI->spells()->getByIndex(subtype)->getNameTranslated();
|
||||
case morale: return "";
|
||||
case luck: return "";
|
||||
case building:
|
||||
{
|
||||
auto building = (*CGI->townh)[subtype]->town->buildings[BuildingID(val)];
|
||||
if(!building)
|
||||
case ComponentType::ARTIFACT:
|
||||
return CGI->artifacts()->getById(data.subType.as<ArtifactID>())->getNameTranslated();
|
||||
case ComponentType::SPELL_SCROLL:
|
||||
case ComponentType::SPELL:
|
||||
return CGI->spells()->getById(data.subType.as<SpellID>())->getNameTranslated();
|
||||
case ComponentType::MORALE:
|
||||
return "";
|
||||
case ComponentType::LUCK:
|
||||
return "";
|
||||
case ComponentType::BUILDING:
|
||||
{
|
||||
logGlobal->error("Town of faction %s has no building #%d", (*CGI->townh)[subtype]->town->faction->getNameTranslated(), val);
|
||||
return (boost::format("Missing building #%d") % val).str();
|
||||
auto index = data.subType.as<BuildingTypeUniqueID>();
|
||||
auto building = (*CGI->townh)[index.getFaction()]->town->buildings[index.getBuilding()];
|
||||
if(!building)
|
||||
{
|
||||
logGlobal->error("Town of faction %s has no building #%d", (*CGI->townh)[index.getFaction()]->town->faction->getNameTranslated(), index.getBuilding().getNum());
|
||||
return (boost::format("Missing building #%d") % index.getBuilding().getNum()).str();
|
||||
}
|
||||
return building->getNameTranslated();
|
||||
}
|
||||
return building->getNameTranslated();
|
||||
}
|
||||
case hero: return "";
|
||||
case flag: return CGI->generaltexth->capColors[subtype];
|
||||
case ComponentType::HERO_PORTRAIT:
|
||||
return "";
|
||||
case ComponentType::FLAG:
|
||||
return CGI->generaltexth->capColors[data.subType.as<PlayerColor>().getNum()];
|
||||
default:
|
||||
assert(0);
|
||||
return "";
|
||||
}
|
||||
logGlobal->error("Invalid CComponent type: %d", (int)compType);
|
||||
return "";
|
||||
}
|
||||
|
||||
void CComponent::setSurface(const AnimationPath & defName, int imgPos)
|
||||
@ -299,7 +349,7 @@ CSelectableComponent::CSelectableComponent(const Component &c, std::function<voi
|
||||
init();
|
||||
}
|
||||
|
||||
CSelectableComponent::CSelectableComponent(Etype Type, int Sub, int Val, ESize imageSize, std::function<void()> OnSelect):
|
||||
CSelectableComponent::CSelectableComponent(ComponentType Type, ComponentSubType Sub, int Val, ESize imageSize, std::function<void()> OnSelect):
|
||||
CComponent(Type,Sub,Val, imageSize),onSelect(OnSelect)
|
||||
{
|
||||
setRedrawParent(true);
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "../gui/CIntObject.h"
|
||||
#include "../render/EFont.h"
|
||||
#include "../../lib/filesystem/ResourcePath.h"
|
||||
#include "../../lib/networkPacks/Component.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
@ -26,11 +27,6 @@ class CLabel;
|
||||
class CComponent : public virtual CIntObject
|
||||
{
|
||||
public:
|
||||
enum Etype
|
||||
{
|
||||
primskill, secskill, resource, creature, artifact, experience, spell, morale, luck, building, hero, flag, typeInvalid
|
||||
};
|
||||
|
||||
//NOTE: not all types have exact these sizes or have less than 4 of them. In such cases closest one will be used
|
||||
enum ESize
|
||||
{
|
||||
@ -47,26 +43,21 @@ private:
|
||||
size_t getIndex();
|
||||
std::vector<AnimationPath> getFileName();
|
||||
void setSurface(const AnimationPath & defName, int imgPos);
|
||||
std::string getSubtitleInternal();
|
||||
|
||||
void init(Etype Type, int Subtype, int Val, ESize imageSize, EFonts font = FONT_SMALL, std::string ValText="");
|
||||
void init(ComponentType Type, ComponentSubType Subtype, std::optional<int32_t> Val, ESize imageSize, EFonts font = FONT_SMALL, std::string ValText="");
|
||||
|
||||
public:
|
||||
std::shared_ptr<CAnimImage> image;
|
||||
|
||||
Etype compType; //component type
|
||||
Component data;
|
||||
std::string customSubtitle;
|
||||
ESize size; //component size.
|
||||
EFonts font; //Font size of label
|
||||
int subtype; //type-dependant subtype. See getSomething methods for details
|
||||
int val; // value \ strength \ amount of component. See getSomething methods for details
|
||||
std::string valText; // value instead of amount; currently only for resource
|
||||
bool perDay; // add "per day" text to subtitle
|
||||
|
||||
std::string getDescription();
|
||||
std::string getSubtitle();
|
||||
|
||||
CComponent(Etype Type, int Subtype, int Val = 0, ESize imageSize=large, EFonts font = FONT_SMALL);
|
||||
CComponent(Etype Type, int Subtype, std::string Val, ESize imageSize=large, EFonts font = FONT_SMALL);
|
||||
CComponent(ComponentType Type, ComponentSubType Subtype, std::optional<int32_t> Val = std::nullopt, ESize imageSize=large, EFonts font = FONT_SMALL);
|
||||
CComponent(ComponentType Type, ComponentSubType Subtype, std::string Val, ESize imageSize=large, EFonts font = FONT_SMALL);
|
||||
CComponent(const Component &c, ESize imageSize=large, EFonts font = FONT_SMALL);
|
||||
|
||||
void showPopupWindow(const Point & cursorPosition) override; //call-in
|
||||
@ -86,7 +77,7 @@ public:
|
||||
|
||||
void clickPressed(const Point & cursorPosition) override; //call-in
|
||||
void clickDouble(const Point & cursorPosition) override; //call-in
|
||||
CSelectableComponent(Etype Type, int Sub, int Val, ESize imageSize=large, std::function<void()> OnSelect = nullptr);
|
||||
CSelectableComponent(ComponentType Type, ComponentSubType Sub, int Val, ESize imageSize=large, std::function<void()> OnSelect = nullptr);
|
||||
CSelectableComponent(const Component & c, std::function<void()> OnSelect = nullptr);
|
||||
};
|
||||
|
||||
|
@ -95,7 +95,7 @@ void CWindowWithArtifacts::leftClickArtPlaceHero(CArtifactsOfHeroBase & artsInst
|
||||
if(artPlace.getArt()->getTypeId() == ArtifactID::CATAPULT)
|
||||
{
|
||||
// The Catapult must be equipped
|
||||
std::vector<std::shared_ptr<CComponent>> catapult(1, std::make_shared<CComponent>(CComponent::artifact, 3, 0));
|
||||
std::vector<std::shared_ptr<CComponent>> catapult(1, std::make_shared<CComponent>(ComponentType::ARTIFACT, ArtifactID(ArtifactID::CATAPULT)));
|
||||
LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[312], catapult);
|
||||
return false;
|
||||
}
|
||||
|
@ -95,16 +95,16 @@ void LRClickableAreaWTextComp::clickPressed(const Point & cursorPosition)
|
||||
LOCPLINT->showInfoDialog(text, comp);
|
||||
}
|
||||
|
||||
LRClickableAreaWTextComp::LRClickableAreaWTextComp(const Rect &Pos, int BaseType)
|
||||
: LRClickableAreaWText(Pos), baseType(BaseType), bonusValue(-1)
|
||||
LRClickableAreaWTextComp::LRClickableAreaWTextComp(const Rect &Pos, ComponentType BaseType)
|
||||
: LRClickableAreaWText(Pos)
|
||||
{
|
||||
type = -1;
|
||||
component.type = BaseType;
|
||||
}
|
||||
|
||||
std::shared_ptr<CComponent> LRClickableAreaWTextComp::createComponent() const
|
||||
{
|
||||
if(baseType >= 0)
|
||||
return std::make_shared<CComponent>(CComponent::Etype(baseType), type, bonusValue);
|
||||
if(component.type != ComponentType::NONE)
|
||||
return std::make_shared<CComponent>(component);
|
||||
else
|
||||
return std::shared_ptr<CComponent>();
|
||||
}
|
||||
@ -164,17 +164,11 @@ void CHeroArea::hover(bool on)
|
||||
void LRClickableAreaOpenTown::clickPressed(const Point & cursorPosition)
|
||||
{
|
||||
if(town)
|
||||
{
|
||||
LOCPLINT->openTownWindow(town);
|
||||
if ( type == 2 )
|
||||
LOCPLINT->castleInt->builds->buildingClicked(BuildingID::VILLAGE_HALL);
|
||||
else if ( type == 3 && town->fortLevel() )
|
||||
LOCPLINT->castleInt->builds->buildingClicked(BuildingID::FORT);
|
||||
}
|
||||
}
|
||||
|
||||
LRClickableAreaOpenTown::LRClickableAreaOpenTown(const Rect & Pos, const CGTownInstance * Town)
|
||||
: LRClickableAreaWTextComp(Pos, -1), town(Town)
|
||||
: LRClickableAreaWTextComp(Pos), town(Town)
|
||||
{
|
||||
}
|
||||
|
||||
@ -542,20 +536,21 @@ void MoraleLuckBox::set(const AFactionMember * node)
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
|
||||
|
||||
const int textId[] = {62, 88}; //eg %s \n\n\n {Current Luck Modifiers:}
|
||||
const std::array textId = {62, 88}; //eg %s \n\n\n {Current Luck Modifiers:}
|
||||
const int noneTxtId = 108; //Russian version uses same text for neutral morale\luck
|
||||
const int neutralDescr[] = {60, 86}; //eg {Neutral Morale} \n\n Neutral morale means your armies will neither be blessed with extra attacks or freeze in combat.
|
||||
const int componentType[] = {CComponent::luck, CComponent::morale};
|
||||
const int hoverTextBase[] = {7, 4};
|
||||
const std::array neutralDescr = {60, 86}; //eg {Neutral Morale} \n\n Neutral morale means your armies will neither be blessed with extra attacks or freeze in combat.
|
||||
const std::array componentType = {ComponentType::LUCK, ComponentType::MORALE};
|
||||
const std::array hoverTextBase = {7, 4};
|
||||
TConstBonusListPtr modifierList = std::make_shared<const BonusList>();
|
||||
bonusValue = 0;
|
||||
|
||||
component.value = 0;
|
||||
|
||||
if(node)
|
||||
bonusValue = morale ? node->moraleValAndBonusList(modifierList) : node->luckValAndBonusList(modifierList);
|
||||
component.value = morale ? node->moraleValAndBonusList(modifierList) : node->luckValAndBonusList(modifierList);
|
||||
|
||||
int mrlt = (bonusValue>0)-(bonusValue<0); //signum: -1 - bad luck / morale, 0 - neutral, 1 - good
|
||||
int mrlt = (component.value>0)-(component.value<0); //signum: -1 - bad luck / morale, 0 - neutral, 1 - good
|
||||
hoverText = CGI->generaltexth->heroscrn[hoverTextBase[morale] - mrlt];
|
||||
baseType = componentType[morale];
|
||||
component.type = componentType[morale];
|
||||
text = CGI->generaltexth->arraytxt[textId[morale]];
|
||||
boost::algorithm::replace_first(text,"%s",CGI->generaltexth->arraytxt[neutralDescr[morale]-mrlt]);
|
||||
|
||||
@ -563,19 +558,19 @@ void MoraleLuckBox::set(const AFactionMember * node)
|
||||
|| node->getBonusBearer()->hasBonusOfType(BonusType::NON_LIVING)))
|
||||
{
|
||||
text += CGI->generaltexth->arraytxt[113]; //unaffected by morale
|
||||
bonusValue = 0;
|
||||
component.value = 0;
|
||||
}
|
||||
else if(morale && node && node->getBonusBearer()->hasBonusOfType(BonusType::NO_MORALE))
|
||||
{
|
||||
auto noMorale = node->getBonusBearer()->getBonus(Selector::type()(BonusType::NO_MORALE));
|
||||
text += "\n" + noMorale->Description();
|
||||
bonusValue = 0;
|
||||
component.value = 0;
|
||||
}
|
||||
else if (!morale && node && node->getBonusBearer()->hasBonusOfType(BonusType::NO_LUCK))
|
||||
{
|
||||
auto noLuck = node->getBonusBearer()->getBonus(Selector::type()(BonusType::NO_LUCK));
|
||||
text += "\n" + noLuck->Description();
|
||||
bonusValue = 0;
|
||||
component.value = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -595,7 +590,7 @@ void MoraleLuckBox::set(const AFactionMember * node)
|
||||
else
|
||||
imageName = morale ? "IMRL42" : "ILCK42";
|
||||
|
||||
image = std::make_shared<CAnimImage>(AnimationPath::builtin(imageName), bonusValue + 3);
|
||||
image = std::make_shared<CAnimImage>(AnimationPath::builtin(imageName), *component.value + 3);
|
||||
image->moveBy(Point(pos.w/2 - image->pos.w/2, pos.h/2 - image->pos.h/2));//center icon
|
||||
}
|
||||
|
||||
@ -603,7 +598,6 @@ MoraleLuckBox::MoraleLuckBox(bool Morale, const Rect &r, bool Small)
|
||||
: morale(Morale),
|
||||
small(Small)
|
||||
{
|
||||
bonusValue = 0;
|
||||
pos = r + pos.topLeft();
|
||||
defActions = 255-DISPOSE;
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../gui/CIntObject.h"
|
||||
#include "../../lib/networkPacks/Component.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
@ -202,13 +203,12 @@ private:
|
||||
class LRClickableAreaWTextComp: public LRClickableAreaWText
|
||||
{
|
||||
public:
|
||||
int type;
|
||||
int baseType;
|
||||
int bonusValue;
|
||||
Component component;
|
||||
|
||||
void clickPressed(const Point & cursorPosition) override;
|
||||
void showPopupWindow(const Point & cursorPosition) override;
|
||||
|
||||
LRClickableAreaWTextComp(const Rect &Pos = Rect(0,0,0,0), int BaseType = -1);
|
||||
LRClickableAreaWTextComp(const Rect &Pos = Rect(0,0,0,0), ComponentType baseType = ComponentType::NONE);
|
||||
std::shared_ptr<CComponent> createComponent() const;
|
||||
};
|
||||
|
||||
@ -263,4 +263,4 @@ class SimpleLine : public CIntObject
|
||||
public:
|
||||
SimpleLine(Point pos1, Point pos2, ColorRGBA color);
|
||||
void showAll(Canvas & to) override;
|
||||
};
|
||||
};
|
||||
|
@ -157,7 +157,7 @@ void CBuildingRect::showPopupWindow(const Point & cursorPosition)
|
||||
if (bid < BuildingID::DWELL_FIRST)
|
||||
{
|
||||
CRClickPopup::createAndPush(CInfoWindow::genText(bld->getNameTranslated(), bld->getDescriptionTranslated()),
|
||||
std::make_shared<CComponent>(CComponent::building, bld->town->faction->getIndex(), bld->bid));
|
||||
std::make_shared<CComponent>(ComponentType::BUILDING, BuildingTypeUniqueID(bld->town->faction->getId(), bld->bid)));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -860,7 +860,7 @@ void CCastleBuildings::enterBlacksmith(ArtifactID artifactID)
|
||||
|
||||
void CCastleBuildings::enterBuilding(BuildingID building)
|
||||
{
|
||||
std::vector<std::shared_ptr<CComponent>> comps(1, std::make_shared<CComponent>(CComponent::building, town->subID, building));
|
||||
std::vector<std::shared_ptr<CComponent>> comps(1, std::make_shared<CComponent>(ComponentType::BUILDING, BuildingTypeUniqueID(town->getFaction(), building)));
|
||||
LOCPLINT->showInfoDialog( town->town->buildings.find(building)->second->getDescriptionTranslated(), comps);
|
||||
}
|
||||
|
||||
@ -920,7 +920,7 @@ void CCastleBuildings::enterToTheQuickRecruitmentWindow()
|
||||
|
||||
void CCastleBuildings::enterFountain(const BuildingID & building, BuildingSubID::EBuildingSubID subID, BuildingID upgrades)
|
||||
{
|
||||
std::vector<std::shared_ptr<CComponent>> comps(1, std::make_shared<CComponent>(CComponent::building,town->getFaction(),building));
|
||||
std::vector<std::shared_ptr<CComponent>> comps(1, std::make_shared<CComponent>(ComponentType::BUILDING, BuildingTypeUniqueID(town->getFaction(), building)));
|
||||
std::string descr = town->town->buildings.find(building)->second->getDescriptionTranslated();
|
||||
std::string hasNotProduced;
|
||||
std::string hasProduced;
|
||||
@ -986,7 +986,7 @@ void CCastleBuildings::enterMagesGuild()
|
||||
CFunctionList<void()> onYes = [this](){ openMagesGuild(); };
|
||||
CFunctionList<void()> onNo = onYes;
|
||||
onYes += [hero](){ LOCPLINT->cb->buyArtifact(hero, ArtifactID::SPELLBOOK); };
|
||||
std::vector<std::shared_ptr<CComponent>> components(1, std::make_shared<CComponent>(CComponent::artifact,ArtifactID::SPELLBOOK,0));
|
||||
std::vector<std::shared_ptr<CComponent>> components(1, std::make_shared<CComponent>(ComponentType::ARTIFACT, ArtifactID(ArtifactID::SPELLBOOK)));
|
||||
|
||||
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[214], onYes, onNo, components);
|
||||
}
|
||||
@ -1129,7 +1129,7 @@ void CCreaInfo::showPopupWindow(const Point & cursorPosition)
|
||||
if (showAvailable)
|
||||
GH.windows().createAndPushWindow<CDwellingInfoBox>(GH.screenDimensions().x / 2, GH.screenDimensions().y / 2, town, level);
|
||||
else
|
||||
CRClickPopup::createAndPush(genGrowthText(), std::make_shared<CComponent>(CComponent::creature, creature->getId()));
|
||||
CRClickPopup::createAndPush(genGrowthText(), std::make_shared<CComponent>(ComponentType::CREATURE, creature->getId()));
|
||||
}
|
||||
|
||||
bool CCreaInfo::getShowAvailable()
|
||||
@ -1180,7 +1180,7 @@ void CTownInfo::showPopupWindow(const Point & cursorPosition)
|
||||
{
|
||||
if(building)
|
||||
{
|
||||
auto c = std::make_shared<CComponent>(CComponent::building, building->town->faction->getIndex(), building->bid);
|
||||
auto c = std::make_shared<CComponent>(ComponentType::BUILDING, BuildingTypeUniqueID(building->town->faction->getId(), building->bid));
|
||||
CRClickPopup::createAndPush(CInfoWindow::genText(building->getNameTranslated(), building->getDescriptionTranslated()), c);
|
||||
}
|
||||
}
|
||||
@ -1526,15 +1526,22 @@ CBuildWindow::CBuildWindow(const CGTownInstance *Town, const CBuilding * Buildin
|
||||
//Create components for all required resources
|
||||
std::vector<std::shared_ptr<CComponent>> components;
|
||||
|
||||
for(int i = 0; i<GameConstants::RESOURCE_QUANTITY; i++)
|
||||
for(GameResID i : GameResID::ALL_RESOURCES())
|
||||
{
|
||||
if(building->resources[i])
|
||||
{
|
||||
std::string text = std::to_string(building->resources[i]);
|
||||
int resAfterBuy = LOCPLINT->cb->getResourceAmount(GameResID(i)) - building->resources[i];
|
||||
if(resAfterBuy < 0 && state != EBuildingState::ALREADY_PRESENT && settings["general"]["enableUiEnhancements"].Bool())
|
||||
text = "{H3Red|" + std::to_string(LOCPLINT->cb->getResourceAmount(GameResID(i))) + "}" + " / " + text;
|
||||
components.push_back(std::make_shared<CComponent>(CComponent::resource, i, text, CComponent::small));
|
||||
MetaString message;
|
||||
int resourceAmount = LOCPLINT->cb->getResourceAmount(i);
|
||||
bool canAfford = resourceAmount >= building->resources[i];
|
||||
|
||||
if(!canAfford && state != EBuildingState::ALREADY_PRESENT && settings["general"]["enableUiEnhancements"].Bool())
|
||||
message.appendRawString("{H3Red|%d}/%d");
|
||||
else
|
||||
message.appendRawString("%d");
|
||||
|
||||
message.replaceNumber(resourceAmount);
|
||||
message.replaceNumber(building->resources[i]);
|
||||
components.push_back(std::make_shared<CComponent>(ComponentType::RESOURCE, i, message.toString(), CComponent::small));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1889,12 +1896,12 @@ CMageGuildScreen::Scroll::Scroll(Point position, const CSpell *Spell)
|
||||
|
||||
void CMageGuildScreen::Scroll::clickPressed(const Point & cursorPosition)
|
||||
{
|
||||
LOCPLINT->showInfoDialog(spell->getDescriptionTranslated(0), std::make_shared<CComponent>(CComponent::spell, spell->id));
|
||||
LOCPLINT->showInfoDialog(spell->getDescriptionTranslated(0), std::make_shared<CComponent>(ComponentType::SPELL, spell->id));
|
||||
}
|
||||
|
||||
void CMageGuildScreen::Scroll::showPopupWindow(const Point & cursorPosition)
|
||||
{
|
||||
CRClickPopup::createAndPush(spell->getDescriptionTranslated(0), std::make_shared<CComponent>(CComponent::spell, spell->id));
|
||||
CRClickPopup::createAndPush(spell->getDescriptionTranslated(0), std::make_shared<CComponent>(ComponentType::SPELL, spell->id));
|
||||
}
|
||||
|
||||
void CMageGuildScreen::Scroll::hover(bool on)
|
||||
|
@ -325,7 +325,7 @@ CStackWindow::ButtonsSection::ButtonsSection(CStackWindow * owner, int yOffset)
|
||||
std::vector<std::shared_ptr<CComponent>> resComps;
|
||||
for(TResources::nziterator i(totalCost); i.valid(); i++)
|
||||
{
|
||||
resComps.push_back(std::make_shared<CComponent>(CComponent::resource, i->resType, (int)i->resVal));
|
||||
resComps.push_back(std::make_shared<CComponent>(ComponentType::RESOURCE, i->resType, i->resVal));
|
||||
}
|
||||
|
||||
if(LOCPLINT->cb->getResourceAmount().canAfford(totalCost))
|
||||
@ -582,10 +582,10 @@ CStackWindow::MainSection::MainSection(CStackWindow * owner, int yOffset, bool s
|
||||
const CCommanderInstance * commander = parent->info->commander;
|
||||
expRankIcon = std::make_shared<CAnimImage>(AnimationPath::builtin("PSKIL42"), 4, 0, pos.x, pos.y);
|
||||
|
||||
auto area = std::make_shared<LRClickableAreaWTextComp>(Rect(pos.x, pos.y, 44, 44), CComponent::experience);
|
||||
auto area = std::make_shared<LRClickableAreaWTextComp>(Rect(pos.x, pos.y, 44, 44), ComponentType::EXPERIENCE);
|
||||
expArea = area;
|
||||
area->text = CGI->generaltexth->allTexts[2];
|
||||
area->bonusValue = commander->getExpRank();
|
||||
area->component.value = commander->getExpRank();
|
||||
boost::replace_first(area->text, "%d", std::to_string(commander->getExpRank()));
|
||||
boost::replace_first(area->text, "%d", std::to_string(CGI->heroh->reqExp(commander->getExpRank() + 1)));
|
||||
boost::replace_first(area->text, "%d", std::to_string(commander->experience));
|
||||
@ -611,8 +611,8 @@ CStackWindow::MainSection::MainSection(CStackWindow * owner, int yOffset, bool s
|
||||
if(art)
|
||||
{
|
||||
parent->stackArtifactIcon = std::make_shared<CAnimImage>(AnimationPath::builtin("ARTIFACT"), art->artType->getIconIndex(), 0, pos.x, pos.y);
|
||||
parent->stackArtifactHelp = std::make_shared<LRClickableAreaWTextComp>(Rect(pos, Point(44, 44)), CComponent::artifact);
|
||||
parent->stackArtifactHelp->type = art->artType->getId();
|
||||
parent->stackArtifactHelp = std::make_shared<LRClickableAreaWTextComp>(Rect(pos, Point(44, 44)), ComponentType::ARTIFACT);
|
||||
parent->stackArtifactHelp->component.subType = art->artType->getId();
|
||||
|
||||
if(parent->info->owner)
|
||||
{
|
||||
|
@ -119,9 +119,9 @@ CHeroWindow::CHeroWindow(const CGHeroInstance * hero)
|
||||
|
||||
for(int v = 0; v < GameConstants::PRIMARY_SKILLS; ++v)
|
||||
{
|
||||
auto area = std::make_shared<LRClickableAreaWTextComp>(Rect(30 + 70 * v, 109, 42, 64), CComponent::primskill);
|
||||
auto area = std::make_shared<LRClickableAreaWTextComp>(Rect(30 + 70 * v, 109, 42, 64), ComponentType::PRIM_SKILL);
|
||||
area->text = CGI->generaltexth->arraytxt[2+v];
|
||||
area->type = v;
|
||||
area->component.subType = PrimarySkill(v);
|
||||
area->hoverText = boost::str(boost::format(CGI->generaltexth->heroscrn[1]) % CGI->generaltexth->primarySkillNames[v]);
|
||||
primSkillAreas.push_back(area);
|
||||
|
||||
@ -154,7 +154,7 @@ CHeroWindow::CHeroWindow(const CGHeroInstance * hero)
|
||||
for(int i = 0; i < std::min<size_t>(hero->secSkills.size(), 8u); ++i)
|
||||
{
|
||||
Rect r = Rect(i%2 == 0 ? 18 : 162, 276 + 48 * (i/2), 136, 42);
|
||||
secSkillAreas.push_back(std::make_shared<LRClickableAreaWTextComp>(r, CComponent::secskill));
|
||||
secSkillAreas.push_back(std::make_shared<LRClickableAreaWTextComp>(r, ComponentType::SEC_SKILL));
|
||||
secSkillImages.push_back(std::make_shared<CAnimImage>(secSkills, 0, 0, r.x, r.y));
|
||||
|
||||
int x = (i % 2) ? 212 : 68;
|
||||
@ -232,20 +232,21 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded)
|
||||
//primary skills support
|
||||
for(size_t g=0; g<primSkillAreas.size(); ++g)
|
||||
{
|
||||
primSkillAreas[g]->bonusValue = curHero->getPrimSkillLevel(static_cast<PrimarySkill>(g));
|
||||
primSkillValues[g]->setText(std::to_string(primSkillAreas[g]->bonusValue));
|
||||
int value = curHero->getPrimSkillLevel(static_cast<PrimarySkill>(g));
|
||||
primSkillAreas[g]->component.value = value;
|
||||
primSkillValues[g]->setText(std::to_string(value));
|
||||
}
|
||||
|
||||
//secondary skills support
|
||||
for(size_t g=0; g< secSkillAreas.size(); ++g)
|
||||
{
|
||||
int skill = curHero->secSkills[g].first;
|
||||
int level = curHero->getSecSkillLevel(SecondarySkill(curHero->secSkills[g].first));
|
||||
SecondarySkill skill = curHero->secSkills[g].first;
|
||||
int level = curHero->getSecSkillLevel(skill);
|
||||
std::string skillName = CGI->skillh->getByIndex(skill)->getNameTranslated();
|
||||
std::string skillValue = CGI->generaltexth->levels[level-1];
|
||||
|
||||
secSkillAreas[g]->type = skill;
|
||||
secSkillAreas[g]->bonusValue = level;
|
||||
secSkillAreas[g]->component.subType = skill;
|
||||
secSkillAreas[g]->component.value = level;
|
||||
secSkillAreas[g]->text = CGI->skillh->getByIndex(skill)->getDescriptionTranslated(level);
|
||||
secSkillAreas[g]->hoverText = boost::str(boost::format(heroscrn[21]) % skillValue % skillName);
|
||||
secSkillImages[g]->setFrame(skill*3 + level + 2);
|
||||
|
@ -256,7 +256,7 @@ void InfoBoxAbstractHeroData::prepareMessage(std::string & text, std::shared_ptr
|
||||
break;
|
||||
case HERO_PRIMARY_SKILL:
|
||||
text = CGI->generaltexth->arraytxt[2+getSubID()];
|
||||
comp = std::make_shared<CComponent>(CComponent::primskill, getSubID(), (int)getValue());
|
||||
comp = std::make_shared<CComponent>(ComponentType::PRIM_SKILL, PrimarySkill(getSubID()), getValue());
|
||||
break;
|
||||
case HERO_MANA:
|
||||
text = CGI->generaltexth->allTexts[149];
|
||||
@ -271,7 +271,7 @@ void InfoBoxAbstractHeroData::prepareMessage(std::string & text, std::shared_ptr
|
||||
if(value)
|
||||
{
|
||||
text = CGI->skillh->getByIndex(subID)->getDescriptionTranslated((int)value);
|
||||
comp = std::make_shared<CComponent>(CComponent::secskill, subID, (int)value);
|
||||
comp = std::make_shared<CComponent>(ComponentType::SEC_SKILL, SecondarySkill(subID), (int)value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -558,7 +558,7 @@ void CSpellWindow::SpellArea::clickPressed(const Point & cursorPosition)
|
||||
//battle spell on adv map or adventure map spell during combat => display infowindow, not cast
|
||||
if((combatSpell ^ inCombat) || inCastle)
|
||||
{
|
||||
std::vector<std::shared_ptr<CComponent>> hlp(1, std::make_shared<CComponent>(CComponent::spell, mySpell->id, 0));
|
||||
std::vector<std::shared_ptr<CComponent>> hlp(1, std::make_shared<CComponent>(ComponentType::SPELL, mySpell->id));
|
||||
LOCPLINT->showInfoDialog(mySpell->getDescriptionTranslated(schoolLevel), hlp);
|
||||
}
|
||||
else if(combatSpell)
|
||||
@ -614,7 +614,7 @@ void CSpellWindow::SpellArea::showPopupWindow(const Point & cursorPosition)
|
||||
boost::algorithm::replace_first(dmgInfo, "%d", std::to_string(causedDmg));
|
||||
}
|
||||
|
||||
CRClickPopup::createAndPush(mySpell->getDescriptionTranslated(schoolLevel) + dmgInfo, std::make_shared<CComponent>(CComponent::spell, mySpell->id));
|
||||
CRClickPopup::createAndPush(mySpell->getDescriptionTranslated(schoolLevel) + dmgInfo, std::make_shared<CComponent>(ComponentType::SPELL, mySpell->id));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -401,7 +401,7 @@ CLevelWindow::CLevelWindow(const CGHeroInstance * hero, PrimarySkill pskill, std
|
||||
std::vector<std::shared_ptr<CSelectableComponent>> comps;
|
||||
for(auto & skill : skills)
|
||||
{
|
||||
auto comp = std::make_shared<CSelectableComponent>(CComponent::secskill, skill, hero->getSecSkillLevel(SecondarySkill(skill))+1, CComponent::medium);
|
||||
auto comp = std::make_shared<CSelectableComponent>(ComponentType::SEC_SKILL, skill, hero->getSecSkillLevel(SecondarySkill(skill))+1, CComponent::medium);
|
||||
comp->onChoose = std::bind(&CLevelWindow::close, this);
|
||||
comps.push_back(comp);
|
||||
}
|
||||
@ -693,9 +693,7 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2,
|
||||
else
|
||||
primSkillAreas[g]->pos = Rect(Point(pos.x + 329, pos.y + 19 + 36 * g), Point(140, 32));
|
||||
primSkillAreas[g]->text = CGI->generaltexth->arraytxt[2+g];
|
||||
primSkillAreas[g]->type = g;
|
||||
primSkillAreas[g]->bonusValue = 0;
|
||||
primSkillAreas[g]->baseType = 0;
|
||||
primSkillAreas[g]->component = Component( ComponentType::PRIM_SKILL, PrimarySkill(g));
|
||||
primSkillAreas[g]->hoverText = CGI->generaltexth->heroscrn[1];
|
||||
boost::replace_first(primSkillAreas[g]->hoverText, "%s", CGI->generaltexth->primarySkillNames[g]);
|
||||
}
|
||||
@ -708,14 +706,11 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2,
|
||||
//secondary skill's clickable areas
|
||||
for(int g=0; g<hero->secSkills.size(); ++g)
|
||||
{
|
||||
int skill = hero->secSkills[g].first,
|
||||
level = hero->secSkills[g].second; // <1, 3>
|
||||
SecondarySkill skill = hero->secSkills[g].first;
|
||||
int level = hero->secSkills[g].second; // <1, 3>
|
||||
secSkillAreas[b].push_back(std::make_shared<LRClickableAreaWTextComp>());
|
||||
secSkillAreas[b][g]->pos = Rect(Point(pos.x + 32 + g * 36 + b * 454 , pos.y + (qeLayout ? 83 : 88)), Point(32, 32) );
|
||||
secSkillAreas[b][g]->baseType = 1;
|
||||
|
||||
secSkillAreas[b][g]->type = skill;
|
||||
secSkillAreas[b][g]->bonusValue = level;
|
||||
secSkillAreas[b][g]->component = Component(ComponentType::SEC_SKILL, skill, level);
|
||||
secSkillAreas[b][g]->text = CGI->skillh->getByIndex(skill)->getDescriptionTranslated(level);
|
||||
|
||||
secSkillAreas[b][g]->hoverText = CGI->generaltexth->heroscrn[21];
|
||||
@ -1082,7 +1077,7 @@ void CUniversityWindow::CItem::clickPressed(const Point & cursorPosition)
|
||||
|
||||
void CUniversityWindow::CItem::showPopupWindow(const Point & cursorPosition)
|
||||
{
|
||||
CRClickPopup::createAndPush(CGI->skillh->getByIndex(ID)->getDescriptionTranslated(1), std::make_shared<CComponent>(CComponent::secskill, ID, 1));
|
||||
CRClickPopup::createAndPush(CGI->skillh->getByIndex(ID)->getDescriptionTranslated(1), std::make_shared<CComponent>(ComponentType::SEC_SKILL, ID, 1));
|
||||
}
|
||||
|
||||
void CUniversityWindow::CItem::hover(bool on)
|
||||
|
@ -375,7 +375,7 @@ class CUniversityWindow : public CStatusbarWindow
|
||||
std::shared_ptr<CLabel> name;
|
||||
std::shared_ptr<CLabel> level;
|
||||
public:
|
||||
int ID;//id of selected skill
|
||||
SecondarySkill ID;//id of selected skill
|
||||
CUniversityWindow * parent;
|
||||
|
||||
void showAll(Canvas & to) override;
|
||||
|
@ -1017,6 +1017,11 @@ const Creature * CStackBasicDescriptor::getType() const
|
||||
return type;
|
||||
}
|
||||
|
||||
CreatureID CStackBasicDescriptor::getId() const
|
||||
{
|
||||
return type->getId();
|
||||
}
|
||||
|
||||
TQuantity CStackBasicDescriptor::getCount() const
|
||||
{
|
||||
return count;
|
||||
|
@ -39,6 +39,7 @@ public:
|
||||
virtual ~CStackBasicDescriptor() = default;
|
||||
|
||||
const Creature * getType() const;
|
||||
CreatureID getId() const;
|
||||
TQuantity getCount() const;
|
||||
|
||||
virtual void setType(const CCreature * c);
|
||||
|
@ -458,6 +458,21 @@ std::string GameResID::entityType()
|
||||
return "resource";
|
||||
}
|
||||
|
||||
const std::array<GameResID, 7> & GameResID::ALL_RESOURCES()
|
||||
{
|
||||
static const std::array allResources = {
|
||||
GameResID(WOOD),
|
||||
GameResID(MERCURY),
|
||||
GameResID(ORE),
|
||||
GameResID(SULFUR),
|
||||
GameResID(CRYSTAL),
|
||||
GameResID(GEMS),
|
||||
GameResID(GOLD)
|
||||
};
|
||||
|
||||
return allResources;
|
||||
}
|
||||
|
||||
std::string SecondarySkill::entityType()
|
||||
{
|
||||
return "secondarySkill";
|
||||
|
@ -960,9 +960,11 @@ public:
|
||||
static si32 decode(const std::string & identifier);
|
||||
static std::string encode(const si32 index);
|
||||
static std::string entityType();
|
||||
|
||||
static const std::array<GameResID, 7> & ALL_RESOURCES();
|
||||
};
|
||||
|
||||
class BuildingTypeUniqueID : public Identifier<BuildingTypeUniqueID>
|
||||
class DLL_LINKAGE BuildingTypeUniqueID : public Identifier<BuildingTypeUniqueID>
|
||||
{
|
||||
public:
|
||||
BuildingTypeUniqueID(FactionID faction, BuildingID building );
|
||||
|
@ -79,11 +79,7 @@ std::vector<Component> CBank::getPopupComponents(PlayerColor player) const
|
||||
|
||||
for (auto const & guard : guardsAmounts)
|
||||
{
|
||||
Component comp;
|
||||
comp.id = Component::EComponentType::CREATURE;
|
||||
comp.subtype = guard.first.getNum();
|
||||
comp.val = guard.second;
|
||||
|
||||
Component comp(ComponentType::CREATURE, guard.first, guard.second);
|
||||
result.push_back(comp);
|
||||
}
|
||||
return result;
|
||||
@ -236,7 +232,7 @@ void CBank::doVisit(const CGHeroInstance * hero) const
|
||||
break;
|
||||
}
|
||||
cb->giveHeroBonus(&gbonus);
|
||||
iw.components.emplace_back(Component::EComponentType::MORALE, 0, -1, 0);
|
||||
iw.components.emplace_back(ComponentType::MORALE, -1);
|
||||
iw.soundID = soundBase::GRAVEYARD;
|
||||
break;
|
||||
}
|
||||
@ -247,7 +243,7 @@ void CBank::doVisit(const CGHeroInstance * hero) const
|
||||
gb.id = hero->id.getNum();
|
||||
cb->giveHeroBonus(&gb);
|
||||
textID = 107;
|
||||
iw.components.emplace_back(Component::EComponentType::LUCK, 0, -2, 0);
|
||||
iw.components.emplace_back(ComponentType::LUCK, -2);
|
||||
break;
|
||||
}
|
||||
case Obj::CREATURE_BANK:
|
||||
@ -267,21 +263,21 @@ void CBank::doVisit(const CGHeroInstance * hero) const
|
||||
//grant resources
|
||||
if (bc)
|
||||
{
|
||||
for (int it = 0; it < bc->resources.size(); it++)
|
||||
for (GameResID it : GameResID::ALL_RESOURCES())
|
||||
{
|
||||
if (bc->resources[it] != 0)
|
||||
{
|
||||
iw.components.emplace_back(Component::EComponentType::RESOURCE, it, bc->resources[it], 0);
|
||||
iw.components.emplace_back(ComponentType::RESOURCE, it, bc->resources[it]);
|
||||
loot.appendRawString("%d %s");
|
||||
loot.replaceNumber(iw.components.back().val);
|
||||
loot.replaceLocalString(EMetaText::RES_NAMES, iw.components.back().subtype);
|
||||
loot.replaceNumber(bc->resources[it]);
|
||||
loot.replaceLocalString(EMetaText::RES_NAMES, it);
|
||||
cb->giveResource(hero->getOwner(), static_cast<EGameResID>(it), bc->resources[it]);
|
||||
}
|
||||
}
|
||||
//grant artifacts
|
||||
for (auto & elem : bc->artifacts)
|
||||
{
|
||||
iw.components.emplace_back(Component::EComponentType::ARTIFACT, elem, 0, 0);
|
||||
iw.components.emplace_back(ComponentType::ARTIFACT, elem);
|
||||
loot.appendRawString("%s");
|
||||
loot.replaceLocalString(EMetaText::ART_NAMES, elem);
|
||||
cb->giveHeroNewArtifact(hero, VLC->arth->objects[elem], ArtifactPosition::FIRST_AVAILABLE);
|
||||
@ -325,7 +321,7 @@ void CBank::doVisit(const CGHeroInstance * hero) const
|
||||
if(hero->canLearnSpell(spell))
|
||||
{
|
||||
spells.insert(spellId);
|
||||
iw.components.emplace_back(Component::EComponentType::SPELL, spellId, 0, 0);
|
||||
iw.components.emplace_back(ComponentType::SPELL, spellId);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -356,7 +352,7 @@ void CBank::doVisit(const CGHeroInstance * hero) const
|
||||
|
||||
for(const auto & elem : ourArmy.Slots())
|
||||
{
|
||||
iw.components.emplace_back(*elem.second);
|
||||
iw.components.emplace_back(ComponentType::CREATURE, elem.second->getId(), elem.second->getCount());
|
||||
loot.appendRawString("%s");
|
||||
loot.replaceCreatureName(*elem.second);
|
||||
}
|
||||
|
@ -563,17 +563,17 @@ void CGCreature::giveReward(const CGHeroInstance * h) const
|
||||
if(!resources.empty())
|
||||
{
|
||||
cb->giveResources(h->tempOwner, resources);
|
||||
for(int i = 0; i < resources.size(); i++)
|
||||
for(auto const & res : GameResID::ALL_RESOURCES())
|
||||
{
|
||||
if(resources[i] > 0)
|
||||
iw.components.emplace_back(Component::EComponentType::RESOURCE, i, resources[i], 0);
|
||||
if(resources[res] > 0)
|
||||
iw.components.emplace_back(ComponentType::RESOURCE, res, resources[res]);
|
||||
}
|
||||
}
|
||||
|
||||
if(gainedArtifact != ArtifactID::NONE)
|
||||
{
|
||||
cb->giveHeroNewArtifact(h, VLC->arth->objects[gainedArtifact], ArtifactPosition::FIRST_AVAILABLE);
|
||||
iw.components.emplace_back(Component::EComponentType::ARTIFACT, gainedArtifact, 0, 0);
|
||||
iw.components.emplace_back(ComponentType::ARTIFACT, gainedArtifact);
|
||||
}
|
||||
|
||||
if(!iw.components.empty())
|
||||
|
@ -944,7 +944,7 @@ void CGHeroInstance::showNecromancyDialog(const CStackBasicDescriptor &raisedSta
|
||||
iw.type = EInfoWindowMode::AUTO;
|
||||
iw.soundID = soundBase::pickup01 + rand.nextInt(6);
|
||||
iw.player = tempOwner;
|
||||
iw.components.emplace_back(raisedStack);
|
||||
iw.components.emplace_back(ComponentType::CREATURE, raisedStack.getId(), raisedStack.count);
|
||||
|
||||
if (raisedStack.count > 1) // Practicing the dark arts of necromancy, ... (plural)
|
||||
{
|
||||
|
@ -207,31 +207,31 @@ void CTownBonus::onHeroVisit (const CGHeroInstance * h) const
|
||||
case BuildingSubID::KNOWLEDGE_VISITING_BONUS: //wall of knowledge
|
||||
what = PrimarySkill::KNOWLEDGE;
|
||||
val = 1;
|
||||
iw.components.emplace_back(Component::EComponentType::PRIM_SKILL, 3, 1, 0);
|
||||
iw.components.emplace_back(ComponentType::PRIM_SKILL, PrimarySkill::KNOWLEDGE, 1);
|
||||
break;
|
||||
|
||||
case BuildingSubID::SPELL_POWER_VISITING_BONUS: //order of fire
|
||||
what = PrimarySkill::SPELL_POWER;
|
||||
val = 1;
|
||||
iw.components.emplace_back(Component::EComponentType::PRIM_SKILL, 2, 1, 0);
|
||||
iw.components.emplace_back(ComponentType::PRIM_SKILL, PrimarySkill::SPELL_POWER, 1);
|
||||
break;
|
||||
|
||||
case BuildingSubID::ATTACK_VISITING_BONUS: //hall of Valhalla
|
||||
what = PrimarySkill::ATTACK;
|
||||
val = 1;
|
||||
iw.components.emplace_back(Component::EComponentType::PRIM_SKILL, 0, 1, 0);
|
||||
iw.components.emplace_back(ComponentType::PRIM_SKILL, PrimarySkill::ATTACK, 1);
|
||||
break;
|
||||
|
||||
case BuildingSubID::EXPERIENCE_VISITING_BONUS: //academy of battle scholars
|
||||
what = PrimarySkill::EXPERIENCE;
|
||||
val = static_cast<int>(h->calculateXp(1000));
|
||||
iw.components.emplace_back(Component::EComponentType::EXPERIENCE, 0, val, 0);
|
||||
iw.components.emplace_back(ComponentType::EXPERIENCE, val);
|
||||
break;
|
||||
|
||||
case BuildingSubID::DEFENSE_VISITING_BONUS: //cage of warlords
|
||||
what = PrimarySkill::DEFENSE;
|
||||
val = 1;
|
||||
iw.components.emplace_back(Component::EComponentType::PRIM_SKILL, 1, 1, 0);
|
||||
iw.components.emplace_back(ComponentType::PRIM_SKILL, PrimarySkill::DEFENSE, 1);
|
||||
break;
|
||||
|
||||
case BuildingSubID::CUSTOM_VISITING_BONUS:
|
||||
|
@ -325,7 +325,7 @@ void CGTownInstance::onHeroVisit(const CGHeroInstance * h) const
|
||||
InfoWindow iw;
|
||||
iw.player = h->tempOwner;
|
||||
iw.text.appendRawString(h->commander->getName());
|
||||
iw.components.emplace_back(*h->commander);
|
||||
iw.components.emplace_back(ComponentType::CREATURE, h->commander->getId(), h->commander->getCount());
|
||||
cb->showInfoDialog(&iw);
|
||||
}
|
||||
}
|
||||
|
@ -204,13 +204,13 @@ void CQuest::addTextReplacements(MetaString & text, std::vector<Component> & com
|
||||
|
||||
if(killTarget != ObjectInstanceID::NONE && !heroName.empty())
|
||||
{
|
||||
components.emplace_back(Component::EComponentType::HERO_PORTRAIT, heroPortrait, 0, 0);
|
||||
components.emplace_back(ComponentType::HERO_PORTRAIT, heroPortrait);
|
||||
addKillTargetReplacements(text);
|
||||
}
|
||||
|
||||
if(killTarget != ObjectInstanceID::NONE && stackToKill.type)
|
||||
{
|
||||
components.emplace_back(stackToKill);
|
||||
components.emplace_back(ComponentType::CREATURE, stackToKill.getId(), stackToKill.getCount());
|
||||
addKillTargetReplacements(text);
|
||||
}
|
||||
|
||||
|
@ -169,7 +169,7 @@ void CGMine::flagMine(const PlayerColor & player) const
|
||||
iw.soundID = soundBase::FLAGMINE;
|
||||
iw.text.appendLocalString(EMetaText::MINE_EVNTS, producedResource); //not use subID, abandoned mines uses default mine texts
|
||||
iw.player = player;
|
||||
iw.components.emplace_back(Component::EComponentType::RESOURCE, producedResource, producedQuantity, -1);
|
||||
iw.components.emplace_back(ComponentType::RESOURCE_PER_DAY, producedResource, producedQuantity);
|
||||
cb->showInfoDialog(&iw);
|
||||
}
|
||||
|
||||
@ -324,7 +324,7 @@ void CGResource::collectRes(const PlayerColor & player) const
|
||||
sii.text.appendLocalString(EMetaText::ADVOB_TXT,113);
|
||||
sii.text.replaceLocalString(EMetaText::RES_NAMES, resourceID());
|
||||
}
|
||||
sii.components.emplace_back(Component::EComponentType::RESOURCE, resourceID(), amount, 0);
|
||||
sii.components.emplace_back(ComponentType::RESOURCE, resourceID(), amount);
|
||||
sii.soundID = soundBase::pickup01 + CRandomGenerator::getDefault().nextInt(6);
|
||||
cb->showInfoDialog(&sii);
|
||||
cb->removeObject(this, player);
|
||||
@ -666,7 +666,7 @@ void CGWhirlpool::onHeroVisit( const CGHeroInstance * h ) const
|
||||
iw.type = EInfoWindowMode::AUTO;
|
||||
iw.player = h->tempOwner;
|
||||
iw.text.appendLocalString(EMetaText::ADVOB_TXT, 168);
|
||||
iw.components.emplace_back(CStackBasicDescriptor(h->getCreature(targetstack), -countToTake));
|
||||
iw.components.emplace_back(ComponentType::CREATURE, h->getCreature(targetstack)->getId(), -countToTake);
|
||||
cb->showInfoDialog(&iw);
|
||||
cb->changeStackCount(StackLocation(h, targetstack), -countToTake);
|
||||
}
|
||||
@ -790,7 +790,7 @@ void CGArtifact::onHeroVisit(const CGHeroInstance * h) const
|
||||
{
|
||||
case Obj::ARTIFACT:
|
||||
{
|
||||
iw.components.emplace_back(Component::EComponentType::ARTIFACT, getArtifact(), 0, 0);
|
||||
iw.components.emplace_back(ComponentType::ARTIFACT, getArtifact());
|
||||
if(!message.empty())
|
||||
iw.text = message;
|
||||
else
|
||||
@ -800,7 +800,7 @@ void CGArtifact::onHeroVisit(const CGHeroInstance * h) const
|
||||
case Obj::SPELL_SCROLL:
|
||||
{
|
||||
int spellID = storedArtifact->getScrollSpellID();
|
||||
iw.components.emplace_back(Component::EComponentType::SPELL, spellID, 0, 0);
|
||||
iw.components.emplace_back(ComponentType::SPELL, spellID);
|
||||
if(!message.empty())
|
||||
iw.text = message;
|
||||
else
|
||||
|
@ -9,44 +9,67 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "../constants/VariantIdentifier.h"
|
||||
#include "../constants/EntityIdentifiers.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class CStackBasicDescriptor;
|
||||
enum class ComponentType : int8_t
|
||||
{
|
||||
NONE = -1,
|
||||
PRIM_SKILL,
|
||||
SEC_SKILL,
|
||||
RESOURCE,
|
||||
RESOURCE_PER_DAY,
|
||||
CREATURE,
|
||||
ARTIFACT,
|
||||
SPELL_SCROLL,
|
||||
MANA,
|
||||
EXPERIENCE,
|
||||
LEVEL,
|
||||
SPELL,
|
||||
MORALE,
|
||||
LUCK,
|
||||
BUILDING,
|
||||
HERO_PORTRAIT,
|
||||
FLAG
|
||||
};
|
||||
|
||||
using ComponentSubType = VariantIdentifier<PrimarySkill, SecondarySkill, GameResID, CreatureID, ArtifactID, SpellID, BuildingTypeUniqueID, HeroTypeID, PlayerColor>;
|
||||
|
||||
struct Component
|
||||
{
|
||||
enum class EComponentType : uint8_t
|
||||
{
|
||||
PRIM_SKILL,
|
||||
SEC_SKILL,
|
||||
RESOURCE,
|
||||
CREATURE,
|
||||
ARTIFACT,
|
||||
EXPERIENCE,
|
||||
SPELL,
|
||||
MORALE,
|
||||
LUCK,
|
||||
BUILDING,
|
||||
HERO_PORTRAIT,
|
||||
FLAG,
|
||||
INVALID //should be last
|
||||
};
|
||||
EComponentType id = EComponentType::INVALID;
|
||||
ui16 subtype = 0; //id==EXPPERIENCE subtype==0 means exp points and subtype==1 levels
|
||||
si32 val = 0; // + give; - take
|
||||
si16 when = 0; // 0 - now; +x - within x days; -x - per x days
|
||||
ComponentType type = ComponentType::NONE;
|
||||
ComponentSubType subType;
|
||||
std::optional<int32_t> value; // + give; - take
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & id;
|
||||
h & subtype;
|
||||
h & val;
|
||||
h & when;
|
||||
h & type;
|
||||
h & subType;
|
||||
h & value;
|
||||
}
|
||||
|
||||
Component() = default;
|
||||
DLL_LINKAGE explicit Component(const CStackBasicDescriptor &stack);
|
||||
Component(Component::EComponentType Type, ui16 Subtype, si32 Val, si16 When)
|
||||
:id(Type),subtype(Subtype),val(Val),when(When)
|
||||
|
||||
template<typename Numeric, std::enable_if_t<std::is_arithmetic_v<Numeric>, bool> = true>
|
||||
Component(ComponentType type, Numeric value)
|
||||
: type(type)
|
||||
, value(value)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename IdentifierType, std::enable_if_t<std::is_base_of_v<IdentifierBase, IdentifierType>, bool> = true>
|
||||
Component(ComponentType type, IdentifierType subType)
|
||||
: type(type)
|
||||
, subType(subType)
|
||||
{
|
||||
}
|
||||
|
||||
Component(ComponentType type, ComponentSubType subType, int32_t value)
|
||||
: type(type)
|
||||
, subType(subType)
|
||||
, value(value)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
@ -2522,13 +2522,6 @@ void TurnTimeUpdate::applyGs(CGameState *gs) const
|
||||
playerState.turnTimer = turnTimer;
|
||||
}
|
||||
|
||||
Component::Component(const CStackBasicDescriptor & stack)
|
||||
: id(EComponentType::CREATURE)
|
||||
, subtype(stack.type->getId())
|
||||
, val(stack.count)
|
||||
{
|
||||
}
|
||||
|
||||
void EntitiesChanged::applyGs(CGameState * gs)
|
||||
{
|
||||
for(const auto & change : changes)
|
||||
|
@ -201,7 +201,7 @@ void Rewardable::Info::configureReward(Rewardable::Configuration & object, CRand
|
||||
CreatureID from(VLC->identifiers()->getIdentifier(node.second.meta, "creature", node.first).value());
|
||||
CreatureID dest(VLC->identifiers()->getIdentifier(node.second.meta, "creature", node.second.String()).value());
|
||||
|
||||
reward.extraComponents.emplace_back(Component::EComponentType::CREATURE, dest.getNum(), 0, 0);
|
||||
reward.extraComponents.emplace_back(ComponentType::CREATURE, dest.getNum());
|
||||
|
||||
reward.creaturesChange[from] = dest;
|
||||
}
|
||||
|
@ -187,49 +187,45 @@ void Rewardable::Limiter::loadComponents(std::vector<Component> & comps,
|
||||
const CGHeroInstance * h) const
|
||||
{
|
||||
if (heroExperience)
|
||||
comps.emplace_back(Component::EComponentType::EXPERIENCE, 0, static_cast<si32>(h->calculateXp(heroExperience)), 0);
|
||||
comps.emplace_back(ComponentType::EXPERIENCE, static_cast<si32>(h->calculateXp(heroExperience)));
|
||||
|
||||
if (heroLevel > 0)
|
||||
comps.emplace_back(Component::EComponentType::EXPERIENCE, 1, heroLevel, 0);
|
||||
comps.emplace_back(ComponentType::EXPERIENCE, heroLevel);
|
||||
|
||||
if (manaPoints || manaPercentage > 0)
|
||||
{
|
||||
int absoluteMana = h->manaLimit() ? (manaPercentage * h->mana / h->manaLimit() / 100) : 0;
|
||||
comps.emplace_back(Component::EComponentType::PRIM_SKILL, 5, absoluteMana + manaPoints, 0);
|
||||
comps.emplace_back(ComponentType::MANA, absoluteMana + manaPoints);
|
||||
}
|
||||
|
||||
for (size_t i=0; i<primary.size(); i++)
|
||||
{
|
||||
if (primary[i] != 0)
|
||||
comps.emplace_back(Component::EComponentType::PRIM_SKILL, static_cast<ui16>(i), primary[i], 0);
|
||||
comps.emplace_back(ComponentType::PRIM_SKILL, PrimarySkill(i), primary[i]);
|
||||
}
|
||||
|
||||
for(const auto & entry : secondary)
|
||||
comps.emplace_back(Component::EComponentType::SEC_SKILL, entry.first, entry.second, 0);
|
||||
comps.emplace_back(ComponentType::SEC_SKILL, entry.first, entry.second);
|
||||
|
||||
for(const auto & entry : artifacts)
|
||||
comps.emplace_back(Component::EComponentType::ARTIFACT, entry, 1, 0);
|
||||
comps.emplace_back(ComponentType::ARTIFACT, entry);
|
||||
|
||||
for(const auto & entry : spells)
|
||||
comps.emplace_back(Component::EComponentType::SPELL, entry, 1, 0);
|
||||
comps.emplace_back(ComponentType::SPELL, entry);
|
||||
|
||||
for(const auto & entry : creatures)
|
||||
comps.emplace_back(Component::EComponentType::CREATURE, entry.type->getId(), entry.count, 0);
|
||||
comps.emplace_back(ComponentType::CREATURE, entry.type->getId(), entry.count);
|
||||
|
||||
for(const auto & entry : players)
|
||||
comps.emplace_back(Component::EComponentType::FLAG, entry, 0, 0);
|
||||
comps.emplace_back(ComponentType::FLAG, entry);
|
||||
|
||||
//FIXME: portrait may not match hero, if custom portrait was set in map editor
|
||||
for(const auto & entry : heroes)
|
||||
comps.emplace_back(Component::EComponentType::HERO_PORTRAIT, VLC->heroTypes()->getById(entry)->getIconIndex(), 0, 0);
|
||||
comps.emplace_back(ComponentType::HERO_PORTRAIT, entry);
|
||||
|
||||
for(const auto & entry : heroClasses)
|
||||
comps.emplace_back(Component::EComponentType::HERO_PORTRAIT, VLC->heroClasses()->getById(entry)->getIconIndex(), 0, 0);
|
||||
|
||||
for (size_t i=0; i<resources.size(); i++)
|
||||
{
|
||||
if (resources[i] !=0)
|
||||
comps.emplace_back(Component::EComponentType::RESOURCE, static_cast<ui16>(i), resources[i], 0);
|
||||
comps.emplace_back(ComponentType::RESOURCE, GameResID(i), resources[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,42 +74,42 @@ void Rewardable::Reward::loadComponents(std::vector<Component> & comps, const CG
|
||||
for (auto & bonus : bonuses)
|
||||
{
|
||||
if (bonus.type == BonusType::MORALE)
|
||||
comps.emplace_back(Component::EComponentType::MORALE, 0, bonus.val, 0);
|
||||
comps.emplace_back(ComponentType::MORALE, bonus.val);
|
||||
if (bonus.type == BonusType::LUCK)
|
||||
comps.emplace_back(Component::EComponentType::LUCK, 0, bonus.val, 0);
|
||||
comps.emplace_back(ComponentType::LUCK, bonus.val);
|
||||
}
|
||||
|
||||
if (heroExperience)
|
||||
comps.emplace_back(Component::EComponentType::EXPERIENCE, 0, static_cast<si32>(h ? h->calculateXp(heroExperience) : heroExperience), 0);
|
||||
comps.emplace_back(ComponentType::EXPERIENCE, static_cast<si32>(h ? h->calculateXp(heroExperience) : heroExperience));
|
||||
|
||||
if (heroLevel)
|
||||
comps.emplace_back(Component::EComponentType::EXPERIENCE, 1, heroLevel, 0);
|
||||
comps.emplace_back(ComponentType::LEVEL, heroLevel);
|
||||
|
||||
if (manaDiff || manaPercentage >= 0)
|
||||
comps.emplace_back(Component::EComponentType::PRIM_SKILL, 5, h ? (calculateManaPoints(h) - h->mana) : manaDiff, 0);
|
||||
comps.emplace_back(ComponentType::MANA, h ? (calculateManaPoints(h) - h->mana) : manaDiff);
|
||||
|
||||
for (size_t i=0; i<primary.size(); i++)
|
||||
{
|
||||
if (primary[i] != 0)
|
||||
comps.emplace_back(Component::EComponentType::PRIM_SKILL, static_cast<ui16>(i), primary[i], 0);
|
||||
comps.emplace_back(ComponentType::PRIM_SKILL, PrimarySkill(i), primary[i]);
|
||||
}
|
||||
|
||||
for(const auto & entry : secondary)
|
||||
comps.emplace_back(Component::EComponentType::SEC_SKILL, entry.first, entry.second, 0);
|
||||
comps.emplace_back(ComponentType::SEC_SKILL, entry.first, entry.second);
|
||||
|
||||
for(const auto & entry : artifacts)
|
||||
comps.emplace_back(Component::EComponentType::ARTIFACT, entry, 1, 0);
|
||||
comps.emplace_back(ComponentType::ARTIFACT, entry);
|
||||
|
||||
for(const auto & entry : spells)
|
||||
comps.emplace_back(Component::EComponentType::SPELL, entry, 1, 0);
|
||||
comps.emplace_back(ComponentType::SPELL, entry);
|
||||
|
||||
for(const auto & entry : creatures)
|
||||
comps.emplace_back(Component::EComponentType::CREATURE, entry.type->getId(), entry.count, 0);
|
||||
comps.emplace_back(ComponentType::CREATURE, entry.type->getId(), entry.count);
|
||||
|
||||
for (size_t i=0; i<resources.size(); i++)
|
||||
{
|
||||
if (resources[i] !=0)
|
||||
comps.emplace_back(Component::EComponentType::RESOURCE, static_cast<ui16>(i), resources[i], 0);
|
||||
comps.emplace_back(ComponentType::RESOURCE, GameResID(i), resources[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -528,8 +528,7 @@ ESpellCastResult TownPortalMechanics::beginCast(SpellCastEnvironment * env, cons
|
||||
request.player = parameters.caster->getCasterOwner();
|
||||
request.title.appendLocalString(EMetaText::JK_TXT, 40);
|
||||
request.description.appendLocalString(EMetaText::JK_TXT, 41);
|
||||
request.icon.id = Component::EComponentType::SPELL;
|
||||
request.icon.subtype = owner->id.toEnum();
|
||||
request.icon = Component(ComponentType::SPELL, owner->id);
|
||||
|
||||
env->genericQuery(&request, request.player, queryCallback);
|
||||
|
||||
|
@ -1571,11 +1571,12 @@ void CGameHandler::useScholarSkill(ObjectInstanceID fromHero, ObjectInstanceID t
|
||||
|
||||
if (!cs1.spells.empty() || !cs2.spells.empty())//create a message
|
||||
{
|
||||
int ScholarSkillLevel = std::max(h1->getSecSkillLevel(SecondarySkill::SCHOLAR),
|
||||
h2->getSecSkillLevel(SecondarySkill::SCHOLAR));
|
||||
SecondarySkill scholarSkill = SecondarySkill::SCHOLAR;
|
||||
|
||||
int scholarSkillLevel = std::max(h1->getSecSkillLevel(scholarSkill), h2->getSecSkillLevel(scholarSkill));
|
||||
InfoWindow iw;
|
||||
iw.player = h1->tempOwner;
|
||||
iw.components.emplace_back(Component::EComponentType::SEC_SKILL, 18, ScholarSkillLevel, 0);
|
||||
iw.components.emplace_back(ComponentType::SEC_SKILL, scholarSkill, scholarSkillLevel);
|
||||
|
||||
iw.text.appendLocalString(EMetaText::GENERAL_TXT, 139);//"%s, who has studied magic extensively,
|
||||
iw.text.replaceRawString(h1->getNameTranslated());
|
||||
@ -1586,7 +1587,7 @@ void CGameHandler::useScholarSkill(ObjectInstanceID fromHero, ObjectInstanceID t
|
||||
int size = static_cast<int>(cs2.spells.size());
|
||||
for (auto it : cs2.spells)
|
||||
{
|
||||
iw.components.emplace_back(Component::EComponentType::SPELL, it, 1, 0);
|
||||
iw.components.emplace_back(ComponentType::SPELL, it);
|
||||
iw.text.appendLocalString(EMetaText::SPELL_NAME, it.toEnum());
|
||||
switch (size--)
|
||||
{
|
||||
@ -1614,7 +1615,7 @@ void CGameHandler::useScholarSkill(ObjectInstanceID fromHero, ObjectInstanceID t
|
||||
int size = static_cast<int>(cs1.spells.size());
|
||||
for (auto it : cs1.spells)
|
||||
{
|
||||
iw.components.emplace_back(Component::EComponentType::SPELL, it, 1, 0);
|
||||
iw.components.emplace_back(ComponentType::SPELL, it);
|
||||
iw.text.appendLocalString(EMetaText::SPELL_NAME, it.toEnum());
|
||||
switch (size--)
|
||||
{
|
||||
@ -3216,10 +3217,10 @@ void CGameHandler::handleTimeEvents()
|
||||
iw.player = color;
|
||||
iw.text = ev.message;
|
||||
|
||||
for (int i=0; i<ev.resources.size(); i++)
|
||||
for (GameResID i : GameResID::ALL_RESOURCES())
|
||||
{
|
||||
if (ev.resources[i]) //if resource is changed, we add it to the dialog
|
||||
iw.components.emplace_back(Component::EComponentType::RESOURCE,i,ev.resources[i],0);
|
||||
iw.components.emplace_back(ComponentType::RESOURCE, i, ev.resources[i]);
|
||||
}
|
||||
|
||||
sendAndApply(&iw); //show dialog
|
||||
@ -3273,10 +3274,9 @@ void CGameHandler::handleTownEvents(CGTownInstance * town, NewTurn &n)
|
||||
n.res[player] += ev.resources;
|
||||
n.res[player].amax(0);
|
||||
|
||||
for (int i=0; i<ev.resources.size(); i++)
|
||||
for (GameResID i : GameResID::ALL_RESOURCES())
|
||||
if (ev.resources[i] && pinfo->resources[i] != n.res.at(player)[i]) //if resource had changed, we add it to the dialog
|
||||
iw.components.emplace_back(Component::EComponentType::RESOURCE,i,n.res.at(player)[i]-was[i],0);
|
||||
|
||||
iw.components.emplace_back(ComponentType::RESOURCE, i, n.res.at(player)[i] - was[i]);
|
||||
}
|
||||
|
||||
for (auto & i : ev.buildings)
|
||||
@ -3284,7 +3284,7 @@ void CGameHandler::handleTownEvents(CGTownInstance * town, NewTurn &n)
|
||||
if (!town->hasBuilt(i))
|
||||
{
|
||||
buildStructure(town->id, i, true);
|
||||
iw.components.emplace_back(Component::EComponentType::BUILDING, town->getFaction(), i, 0);
|
||||
iw.components.emplace_back(ComponentType::BUILDING, BuildingTypeUniqueID(town->getFaction(), i));
|
||||
}
|
||||
}
|
||||
|
||||
@ -3300,8 +3300,7 @@ void CGameHandler::handleTownEvents(CGTownInstance * town, NewTurn &n)
|
||||
if (!town->creatures.at(i).second.empty() && ev.creatures.at(i) > 0)//there is dwelling
|
||||
{
|
||||
sac.creatures[i].first += ev.creatures.at(i);
|
||||
iw.components.emplace_back(Component::EComponentType::CREATURE,
|
||||
town->creatures.at(i).second.back(), ev.creatures.at(i), 0);
|
||||
iw.components.emplace_back(ComponentType::CREATURE, town->creatures.at(i).second.back(), ev.creatures.at(i));
|
||||
}
|
||||
}
|
||||
sendAndApply(&iw); //show dialog
|
||||
@ -3641,7 +3640,7 @@ void CGameHandler::getVictoryLossMessage(PlayerColor player, const EVictoryLossC
|
||||
out.player = player;
|
||||
out.text = victoryLossCheckResult.messageToSelf;
|
||||
out.text.replaceLocalString(EMetaText::COLOR, player.getNum());
|
||||
out.components.emplace_back(Component::EComponentType::FLAG, player.getNum(), 0, 0);
|
||||
out.components.emplace_back(ComponentType::FLAG, player);
|
||||
}
|
||||
|
||||
bool CGameHandler::dig(const CGHeroInstance *h)
|
||||
@ -3669,7 +3668,7 @@ bool CGameHandler::dig(const CGHeroInstance *h)
|
||||
sendAndApply(&iw);
|
||||
|
||||
iw.soundID = soundBase::invalid;
|
||||
iw.components.emplace_back(Component::EComponentType::ARTIFACT, ArtifactID::GRAIL, 0, 0);
|
||||
iw.components.emplace_back(ComponentType::ARTIFACT, ArtifactID(ArtifactID::GRAIL));
|
||||
iw.text.clear();
|
||||
iw.text.appendLocalString(EMetaText::ART_DESCR, ArtifactID::GRAIL);
|
||||
sendAndApply(&iw);
|
||||
@ -4144,7 +4143,7 @@ const CGHeroInstance * CGameHandler::getVisitingHero(const CGObjectInstance *obj
|
||||
{
|
||||
assert(obj);
|
||||
|
||||
for (auto const & query : queries->allQueries())
|
||||
for(const auto & query : queries->allQueries())
|
||||
{
|
||||
auto visit = std::dynamic_pointer_cast<const CObjectVisitQuery>(query);
|
||||
if (visit && visit->visitedObject == obj)
|
||||
|
@ -419,9 +419,11 @@ void BattleResultProcessor::endBattleConfirm(const CBattleInfoCallback & battle)
|
||||
|
||||
for (auto art : arts) //TODO; separate function to display loot for various ojects?
|
||||
{
|
||||
iw.components.emplace_back(
|
||||
Component::EComponentType::ARTIFACT, art->artType->getId(),
|
||||
art->artType->getId() == ArtifactID::SPELL_SCROLL? art->getScrollSpellID() : SpellID(0), 0);
|
||||
if (art->artType->getId() == ArtifactID::SPELL_SCROLL)
|
||||
iw.components.emplace_back(ComponentType::SPELL_SCROLL, art->getScrollSpellID());
|
||||
else
|
||||
iw.components.emplace_back(ComponentType::ARTIFACT, art->artType->getId());
|
||||
|
||||
if (iw.components.size() >= 14)
|
||||
{
|
||||
gameHandler->sendAndApply(&iw);
|
||||
@ -463,7 +465,7 @@ void BattleResultProcessor::endBattleConfirm(const CBattleInfoCallback & battle)
|
||||
iw.text.replaceLocalString(EMetaText::SPELL_NAME, it->toEnum());
|
||||
if (i == cs.spells.size() - 2) //we just added pre-last name
|
||||
iw.text.replaceLocalString(EMetaText::GENERAL_TXT, 141); // " and "
|
||||
iw.components.emplace_back(Component::EComponentType::SPELL, *it, 0, 0);
|
||||
iw.components.emplace_back(ComponentType::SPELL, *it);
|
||||
}
|
||||
gameHandler->sendAndApply(&iw);
|
||||
gameHandler->sendAndApply(&cs);
|
||||
|
Loading…
Reference in New Issue
Block a user