1
0
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:
Ivan Savenko
2023-11-03 15:52:07 +02:00
committed by GitHub
38 changed files with 454 additions and 380 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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