mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-06 09:09:40 +02:00
Merge pull request #3139 from IvanSavenko/component_variant_identifier
Refactoring of Component class
This commit is contained in:
@@ -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, const 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, const 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);
|
||||
@@ -113,153 +107,209 @@ void CComponent::init(Etype Type, int Subtype, int Val, ESize imageSize, EFonts
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<AnimationPath> CComponent::getFileName()
|
||||
std::vector<AnimationPath> CComponent::getFileName() const
|
||||
{
|
||||
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()
|
||||
size_t CComponent::getIndex() const
|
||||
{
|
||||
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()
|
||||
std::string CComponent::getDescription() const
|
||||
{
|
||||
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 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();
|
||||
|
||||
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)
|
||||
{
|
||||
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:
|
||||
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 creature = CGI->creh->getByIndex(subtype);
|
||||
if ( val )
|
||||
return std::to_string(val) + " " + (val > 1 ? creature->getNamePluralTranslated() : creature->getNameSingularTranslated());
|
||||
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 "";
|
||||
}
|
||||
}
|
||||
|
||||
std::string CComponent::getSubtitle() const
|
||||
{
|
||||
if (!customSubtitle.empty())
|
||||
return customSubtitle;
|
||||
|
||||
switch(data.type)
|
||||
{
|
||||
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[3]) % data.value.value_or(0));
|
||||
case ComponentType::CREATURE:
|
||||
{
|
||||
auto creature = CGI->creh->getById(data.subType.as<CreatureID>());
|
||||
if(data.value)
|
||||
return std::to_string(*data.value) + " " + (*data.value > 1 ? creature->getNamePluralTranslated() : creature->getNameSingularTranslated());
|
||||
else
|
||||
{
|
||||
return std::to_string(val); //amount of experience OR level required for seer hut;
|
||||
}
|
||||
return creature->getNamePluralTranslated();
|
||||
}
|
||||
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
|
||||
{
|
||||
@@ -44,29 +40,24 @@ public:
|
||||
private:
|
||||
std::vector<std::shared_ptr<CLabel>> lines;
|
||||
|
||||
size_t getIndex();
|
||||
std::vector<AnimationPath> getFileName();
|
||||
size_t getIndex() const;
|
||||
std::vector<AnimationPath> getFileName() const;
|
||||
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, const 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();
|
||||
std::string getDescription() const;
|
||||
std::string getSubtitle() const;
|
||||
|
||||
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, const 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,24 @@ 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");
|
||||
message.replaceNumber(resourceAmount);
|
||||
}
|
||||
else
|
||||
message.appendRawString("%d");
|
||||
|
||||
message.replaceNumber(building->resources[i]);
|
||||
components.push_back(std::make_shared<CComponent>(ComponentType::RESOURCE, i, message.toString(), CComponent::small));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1889,12 +1898,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;
|
||||
|
||||
Reference in New Issue
Block a user