mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-25 22:42:04 +02:00
Merge pull request #4348 from MichalZr6/hill_fort_changes
Hill Fort unavailable upgrade and status bar new messages
This commit is contained in:
@@ -553,6 +553,8 @@
|
|||||||
"core.seerhut.quest.reachDate.visit.4" : "Closed till %s.",
|
"core.seerhut.quest.reachDate.visit.4" : "Closed till %s.",
|
||||||
"core.seerhut.quest.reachDate.visit.5" : "Closed till %s.",
|
"core.seerhut.quest.reachDate.visit.5" : "Closed till %s.",
|
||||||
|
|
||||||
|
"mapObject.core.hillFort.object.description" : "Upgrades creatures. Levels 1 - 4 are less expensive than in associated town.",
|
||||||
|
|
||||||
"core.bonus.ADDITIONAL_ATTACK.name": "Double Strike",
|
"core.bonus.ADDITIONAL_ATTACK.name": "Double Strike",
|
||||||
"core.bonus.ADDITIONAL_ATTACK.description": "Attacks twice",
|
"core.bonus.ADDITIONAL_ATTACK.description": "Attacks twice",
|
||||||
"core.bonus.ADDITIONAL_RETALIATION.name": "Additional retaliations",
|
"core.bonus.ADDITIONAL_RETALIATION.name": "Additional retaliations",
|
||||||
|
|||||||
@@ -533,6 +533,8 @@
|
|||||||
"core.seerhut.quest.reachDate.visit.4" : "Zamknięte do %s.",
|
"core.seerhut.quest.reachDate.visit.4" : "Zamknięte do %s.",
|
||||||
"core.seerhut.quest.reachDate.visit.5" : "Zamknięte do %s.",
|
"core.seerhut.quest.reachDate.visit.5" : "Zamknięte do %s.",
|
||||||
|
|
||||||
|
"mapObject.core.hillFort.object.description" : "Ulepsza jednostki. Koszt ulepszenia dla poziomów 1 - 4 jest bardziej korzystny niż w mieście.",
|
||||||
|
|
||||||
"core.bonus.ADDITIONAL_ATTACK.name": "Podwójne Uderzenie",
|
"core.bonus.ADDITIONAL_ATTACK.name": "Podwójne Uderzenie",
|
||||||
"core.bonus.ADDITIONAL_ATTACK.description": "Atakuje dwa razy",
|
"core.bonus.ADDITIONAL_ATTACK.description": "Atakuje dwa razy",
|
||||||
"core.bonus.ADDITIONAL_RETALIATION.name": "Dodatkowy odwet",
|
"core.bonus.ADDITIONAL_RETALIATION.name": "Dodatkowy odwet",
|
||||||
|
|||||||
@@ -1113,6 +1113,9 @@ CHillFortWindow::CHillFortWindow(const CGHeroInstance * visitor, const CGObjectI
|
|||||||
statusbar = CGStatusBar::create(std::make_shared<CPicture>(background->getSurface(), Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
|
statusbar = CGStatusBar::create(std::make_shared<CPicture>(background->getSurface(), Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
|
||||||
|
|
||||||
garr = std::make_shared<CGarrisonInt>(Point(108, 60), 18, Point(), hero, nullptr);
|
garr = std::make_shared<CGarrisonInt>(Point(108, 60), 18, Point(), hero, nullptr);
|
||||||
|
|
||||||
|
statusbar->write(VLC->generaltexth->translate(dynamic_cast<const HillFort *>(fort)->getDescriptionToolTip()));
|
||||||
|
|
||||||
updateGarrisons();
|
updateGarrisons();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1130,45 +1133,59 @@ void CHillFortWindow::updateGarrisons()
|
|||||||
|
|
||||||
TResources totalSum; // totalSum[resource ID] = value
|
TResources totalSum; // totalSum[resource ID] = value
|
||||||
|
|
||||||
|
auto getImgIdx = [](CHillFortWindow::State st) -> std::size_t
|
||||||
|
{
|
||||||
|
switch (st)
|
||||||
|
{
|
||||||
|
case State::EMPTY:
|
||||||
|
return 0;
|
||||||
|
case State::UNAVAILABLE:
|
||||||
|
case State::ALREADY_UPGRADED:
|
||||||
|
return 1;
|
||||||
|
default:
|
||||||
|
return static_cast<std::size_t>(st);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
for(int i=0; i<slotsCount; i++)
|
for(int i=0; i<slotsCount; i++)
|
||||||
{
|
{
|
||||||
std::fill(costs[i].begin(), costs[i].end(), 0);
|
std::fill(costs[i].begin(), costs[i].end(), 0);
|
||||||
int newState = getState(SlotID(i));
|
State newState = getState(SlotID(i));
|
||||||
if(newState != -1)
|
if(newState != State::EMPTY)
|
||||||
{
|
{
|
||||||
UpgradeInfo info;
|
UpgradeInfo info;
|
||||||
LOCPLINT->cb->fillUpgradeInfo(hero, SlotID(i), info);
|
LOCPLINT->cb->fillUpgradeInfo(hero, SlotID(i), info);
|
||||||
if(info.newID.size())//we have upgrades here - update costs
|
if(info.newID.size())//we have upgrades here - update costs
|
||||||
{
|
{
|
||||||
costs[i] = info.cost[0] * hero->getStackCount(SlotID(i));
|
costs[i] = info.cost.back() * hero->getStackCount(SlotID(i));
|
||||||
totalSum += costs[i];
|
totalSum += costs[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
currState[i] = newState;
|
currState[i] = newState;
|
||||||
upgrade[i]->setImage(AnimationPath::builtin(currState[i] == -1 ? slotImages[0] : slotImages[currState[i]]));
|
upgrade[i]->setImage(AnimationPath::builtin(slotImages[getImgIdx(currState[i])]));
|
||||||
upgrade[i]->block(currState[i] == -1);
|
upgrade[i]->block(currState[i] == State::EMPTY);
|
||||||
upgrade[i]->addHoverText(EButtonState::NORMAL, getTextForSlot(SlotID(i)));
|
upgrade[i]->addHoverText(EButtonState::NORMAL, getTextForSlot(SlotID(i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
//"Upgrade all" slot
|
//"Upgrade all" slot
|
||||||
int newState = 2;
|
State newState = State::MAKE_UPGRADE;
|
||||||
{
|
{
|
||||||
TResources myRes = LOCPLINT->cb->getResourceAmount();
|
TResources myRes = LOCPLINT->cb->getResourceAmount();
|
||||||
|
|
||||||
bool allUpgraded = true;//All creatures are upgraded?
|
bool allUpgraded = true;//All creatures are upgraded?
|
||||||
for(int i=0; i<slotsCount; i++)
|
for(int i=0; i<slotsCount; i++)
|
||||||
allUpgraded &= currState[i] == 1 || currState[i] == -1;
|
allUpgraded &= currState[i] == State::ALREADY_UPGRADED || currState[i] == State::EMPTY || currState[i] == State::UNAVAILABLE;
|
||||||
|
|
||||||
if(allUpgraded)
|
if (allUpgraded)
|
||||||
newState = 1;
|
newState = State::ALREADY_UPGRADED;
|
||||||
|
|
||||||
if(!totalSum.canBeAfforded(myRes))
|
if(!totalSum.canBeAfforded(myRes))
|
||||||
newState = 0;
|
newState = State::UNAFFORDABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
currState[slotsCount] = newState;
|
currState[slotsCount] = newState;
|
||||||
upgradeAll->setImage(AnimationPath::builtin(allImages[newState]));
|
upgradeAll->setImage(AnimationPath::builtin(allImages[static_cast<std::size_t>(newState)]));
|
||||||
|
|
||||||
garr->recreateSlots();
|
garr->recreateSlots();
|
||||||
|
|
||||||
@@ -1181,7 +1198,7 @@ void CHillFortWindow::updateGarrisons()
|
|||||||
slotLabels[i][j]->setText("");
|
slotLabels[i][j]->setText("");
|
||||||
}
|
}
|
||||||
//if can upgrade or can not afford, draw cost
|
//if can upgrade or can not afford, draw cost
|
||||||
if(currState[i] == 0 || currState[i] == 2)
|
if(currState[i] == State::UNAFFORDABLE || currState[i] == State::MAKE_UPGRADE)
|
||||||
{
|
{
|
||||||
if(costs[i].nonZero())
|
if(costs[i].nonZero())
|
||||||
{
|
{
|
||||||
@@ -1226,24 +1243,30 @@ void CHillFortWindow::updateGarrisons()
|
|||||||
|
|
||||||
void CHillFortWindow::makeDeal(SlotID slot)
|
void CHillFortWindow::makeDeal(SlotID slot)
|
||||||
{
|
{
|
||||||
assert(slot.getNum()>=0);
|
assert(slot.getNum() >= 0);
|
||||||
int offset = (slot.getNum() == slotsCount)?2:0;
|
int offset = (slot.getNum() == slotsCount) ? 2 : 0;
|
||||||
switch(currState[slot.getNum()])
|
switch(currState[slot.getNum()])
|
||||||
{
|
{
|
||||||
case 0:
|
case State::ALREADY_UPGRADED:
|
||||||
LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[314 + offset], std::vector<std::shared_ptr<CComponent>>(), soundBase::sound_todo);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[313 + offset], std::vector<std::shared_ptr<CComponent>>(), soundBase::sound_todo);
|
LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[313 + offset], std::vector<std::shared_ptr<CComponent>>(), soundBase::sound_todo);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case State::UNAFFORDABLE:
|
||||||
for(int i=0; i<slotsCount; i++)
|
LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[314 + offset], std::vector<std::shared_ptr<CComponent>>(), soundBase::sound_todo);
|
||||||
|
break;
|
||||||
|
case State::UNAVAILABLE:
|
||||||
|
{
|
||||||
|
std::string message = VLC->generaltexth->translate(dynamic_cast<const HillFort *>(fort)->getUnavailableUpgradeMessage());
|
||||||
|
LOCPLINT->showInfoDialog(message, std::vector<std::shared_ptr<CComponent>>(), soundBase::sound_todo);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case State::MAKE_UPGRADE:
|
||||||
|
for(int i = 0; i < slotsCount; i++)
|
||||||
{
|
{
|
||||||
if(slot.getNum() ==i || ( slot.getNum() == slotsCount && currState[i] == 2 ))//this is activated slot or "upgrade all"
|
if(slot.getNum() == i || ( slot.getNum() == slotsCount && currState[i] == State::MAKE_UPGRADE ))//this is activated slot or "upgrade all"
|
||||||
{
|
{
|
||||||
UpgradeInfo info;
|
UpgradeInfo info;
|
||||||
LOCPLINT->cb->fillUpgradeInfo(hero, SlotID(i), info);
|
LOCPLINT->cb->fillUpgradeInfo(hero, SlotID(i), info);
|
||||||
LOCPLINT->cb->upgradeCreature(hero, SlotID(i), info.newID[0]);
|
LOCPLINT->cb->upgradeCreature(hero, SlotID(i), info.newID.back());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -1265,22 +1288,28 @@ std::string CHillFortWindow::getTextForSlot(SlotID slot)
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CHillFortWindow::getState(SlotID slot)
|
CHillFortWindow::State CHillFortWindow::getState(SlotID slot)
|
||||||
{
|
{
|
||||||
TResources myRes = LOCPLINT->cb->getResourceAmount();
|
TResources myRes = LOCPLINT->cb->getResourceAmount();
|
||||||
|
|
||||||
if(hero->slotEmpty(slot))//no creature here
|
if(hero->slotEmpty(slot))
|
||||||
return -1;
|
return State::EMPTY;
|
||||||
|
|
||||||
UpgradeInfo info;
|
UpgradeInfo info;
|
||||||
LOCPLINT->cb->fillUpgradeInfo(hero, slot, info);
|
LOCPLINT->cb->fillUpgradeInfo(hero, slot, info);
|
||||||
if(!info.newID.size())//already upgraded
|
if (info.newID.empty())
|
||||||
return 1;
|
{
|
||||||
|
// Hill Fort may limit level of upgradeable creatures, e.g. mini Hill Fort from HOTA
|
||||||
|
if (hero->getCreature(slot)->hasUpgrades())
|
||||||
|
return State::UNAVAILABLE;
|
||||||
|
|
||||||
if(!(info.cost[0] * hero->getStackCount(slot)).canBeAfforded(myRes))
|
return State::ALREADY_UPGRADED;
|
||||||
return 0;
|
}
|
||||||
|
|
||||||
return 2;//can upgrade
|
if(!(info.cost.back() * hero->getStackCount(slot)).canBeAfforded(myRes))
|
||||||
|
return State::UNAFFORDABLE;
|
||||||
|
|
||||||
|
return State::MAKE_UPGRADE;
|
||||||
}
|
}
|
||||||
|
|
||||||
CThievesGuildWindow::CThievesGuildWindow(const CGObjectInstance * _owner):
|
CThievesGuildWindow::CThievesGuildWindow(const CGObjectInstance * _owner):
|
||||||
|
|||||||
@@ -449,9 +449,11 @@ public:
|
|||||||
class CHillFortWindow : public CStatusbarWindow, public IGarrisonHolder
|
class CHillFortWindow : public CStatusbarWindow, public IGarrisonHolder
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
static const int slotsCount = 7;
|
|
||||||
|
enum class State { UNAFFORDABLE, ALREADY_UPGRADED, MAKE_UPGRADE, EMPTY, UNAVAILABLE };
|
||||||
|
static constexpr std::size_t slotsCount = 7;
|
||||||
//todo: mithril support
|
//todo: mithril support
|
||||||
static const int resCount = 7;
|
static constexpr std::size_t resCount = 7;
|
||||||
|
|
||||||
const CGObjectInstance * fort;
|
const CGObjectInstance * fort;
|
||||||
const CGHeroInstance * hero;
|
const CGHeroInstance * hero;
|
||||||
@@ -463,7 +465,7 @@ private:
|
|||||||
std::array<std::shared_ptr<CLabel>, resCount> totalLabels;
|
std::array<std::shared_ptr<CLabel>, resCount> totalLabels;
|
||||||
|
|
||||||
std::array<std::shared_ptr<CButton>, slotsCount> upgrade;//upgrade single creature
|
std::array<std::shared_ptr<CButton>, slotsCount> upgrade;//upgrade single creature
|
||||||
std::array<int, slotsCount + 1> currState;//current state of slot - to avoid calls to getState or updating buttons
|
std::array<State, slotsCount + 1> currState;//current state of slot - to avoid calls to getState or updating buttons
|
||||||
|
|
||||||
//there is a place for only 2 resources per slot
|
//there is a place for only 2 resources per slot
|
||||||
std::array< std::array<std::shared_ptr<CAnimImage>, 2>, slotsCount> slotIcons;
|
std::array< std::array<std::shared_ptr<CAnimImage>, 2>, slotsCount> slotIcons;
|
||||||
@@ -478,7 +480,7 @@ private:
|
|||||||
std::string getTextForSlot(SlotID slot);
|
std::string getTextForSlot(SlotID slot);
|
||||||
|
|
||||||
void makeDeal(SlotID slot);//-1 for upgrading all creatures
|
void makeDeal(SlotID slot);//-1 for upgrading all creatures
|
||||||
int getState(SlotID slot); //-1 = no creature 0=can't upgrade, 1=upgraded, 2=can upgrade
|
State getState(SlotID slot);
|
||||||
public:
|
public:
|
||||||
CHillFortWindow(const CGHeroInstance * visitor, const CGObjectInstance * object);
|
CHillFortWindow(const CGHeroInstance * visitor, const CGObjectInstance * object);
|
||||||
void updateGarrisons() override;//update buttons after garrison changes
|
void updateGarrisons() override;//update buttons after garrison changes
|
||||||
|
|||||||
@@ -666,6 +666,7 @@
|
|||||||
"object" : {
|
"object" : {
|
||||||
"index" : 0,
|
"index" : 0,
|
||||||
"aiValue" : 7000,
|
"aiValue" : 7000,
|
||||||
|
"description" : "",
|
||||||
"rmg" : {
|
"rmg" : {
|
||||||
"zoneLimit" : 1,
|
"zoneLimit" : 1,
|
||||||
"value" : 7000,
|
"value" : 7000,
|
||||||
|
|||||||
@@ -11,12 +11,15 @@
|
|||||||
#include "HillFortInstanceConstructor.h"
|
#include "HillFortInstanceConstructor.h"
|
||||||
|
|
||||||
#include "../mapObjects/MiscObjects.h"
|
#include "../mapObjects/MiscObjects.h"
|
||||||
|
#include "../texts/CGeneralTextHandler.h"
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_BEGIN
|
VCMI_LIB_NAMESPACE_BEGIN
|
||||||
|
|
||||||
void HillFortInstanceConstructor::initTypeData(const JsonNode & config)
|
void HillFortInstanceConstructor::initTypeData(const JsonNode & config)
|
||||||
{
|
{
|
||||||
parameters = config;
|
parameters = config;
|
||||||
|
VLC->generaltexth->registerString(parameters.getModScope(), TextIdentifier(getBaseTextID(), "unavailableUpgradeMessage"), parameters["unavailableUpgradeMessage"].String());
|
||||||
|
VLC->generaltexth->registerString(parameters.getModScope(), TextIdentifier(getBaseTextID(), "description"), parameters["description"].String());
|
||||||
}
|
}
|
||||||
|
|
||||||
void HillFortInstanceConstructor::initializeObject(HillFort * fort) const
|
void HillFortInstanceConstructor::initializeObject(HillFort * fort) const
|
||||||
|
|||||||
@@ -1333,4 +1333,14 @@ void HillFort::fillUpgradeInfo(UpgradeInfo & info, const CStackInstance &stack)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string HillFort::getDescriptionToolTip() const
|
||||||
|
{
|
||||||
|
return TextIdentifier(getObjectHandler()->getBaseTextID(), "description").get();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string HillFort::getUnavailableUpgradeMessage() const
|
||||||
|
{
|
||||||
|
return TextIdentifier(getObjectHandler()->getBaseTextID(), "unavailableUpgradeMessage").get();
|
||||||
|
}
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_END
|
VCMI_LIB_NAMESPACE_END
|
||||||
|
|||||||
@@ -437,6 +437,9 @@ protected:
|
|||||||
public:
|
public:
|
||||||
using CGObjectInstance::CGObjectInstance;
|
using CGObjectInstance::CGObjectInstance;
|
||||||
|
|
||||||
|
std::string getDescriptionToolTip() const;
|
||||||
|
std::string getUnavailableUpgradeMessage() const;
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h)
|
template <typename Handler> void serialize(Handler &h)
|
||||||
{
|
{
|
||||||
h & static_cast<CGObjectInstance&>(*this);
|
h & static_cast<CGObjectInstance&>(*this);
|
||||||
|
|||||||
Reference in New Issue
Block a user