1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-24 08:32:34 +02:00

Add query for dwellings dialog

This commit is contained in:
Ivan Savenko 2023-10-04 17:24:19 +03:00
parent 3cb489e9bd
commit 39a92cdde3
13 changed files with 45 additions and 16 deletions

View File

@ -324,10 +324,13 @@ void AIGateway::heroPrimarySkillChanged(const CGHeroInstance * hero, PrimarySkil
NET_EVENT_HANDLER;
}
void AIGateway::showRecruitmentDialog(const CGDwelling * dwelling, const CArmedInstance * dst, int level)
void AIGateway::showRecruitmentDialog(const CGDwelling * dwelling, const CArmedInstance * dst, int level, QueryID queryID)
{
LOG_TRACE_PARAMS(logAi, "level '%i'", level);
NET_EVENT_HANDLER;
status.addQuery(queryID, "RecruitmentDialog");
requestActionASAP([=](){ answerQuery(queryID, 0); });
}
void AIGateway::heroMovePointsChanged(const CGHeroInstance * hero)

View File

@ -145,7 +145,7 @@ public:
void tileRevealed(const std::unordered_set<int3> & pos) override;
void heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID hero2, QueryID query) override;
void heroPrimarySkillChanged(const CGHeroInstance * hero, PrimarySkill which, si64 val) override;
void showRecruitmentDialog(const CGDwelling * dwelling, const CArmedInstance * dst, int level) override;
void showRecruitmentDialog(const CGDwelling * dwelling, const CArmedInstance * dst, int level, QueryID queryID) override;
void heroMovePointsChanged(const CGHeroInstance * hero) override;
void garrisonsChanged(ObjectInstanceID id1, ObjectInstanceID id2) override;
void newObject(const CGObjectInstance * obj) override;

View File

@ -360,10 +360,13 @@ void VCAI::heroPrimarySkillChanged(const CGHeroInstance * hero, PrimarySkill whi
NET_EVENT_HANDLER;
}
void VCAI::showRecruitmentDialog(const CGDwelling * dwelling, const CArmedInstance * dst, int level)
void VCAI::showRecruitmentDialog(const CGDwelling * dwelling, const CArmedInstance * dst, int level, QueryID queryID)
{
LOG_TRACE_PARAMS(logAi, "level '%i'", level);
NET_EVENT_HANDLER;
status.addQuery(queryID, "RecruitmentDialog");
requestActionASAP([=](){ answerQuery(queryID, 0); });
}
void VCAI::heroMovePointsChanged(const CGHeroInstance * hero)

View File

@ -178,7 +178,7 @@ public:
void tileRevealed(const std::unordered_set<int3> & pos) override;
void heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID hero2, QueryID query) override;
void heroPrimarySkillChanged(const CGHeroInstance * hero, PrimarySkill which, si64 val) override;
void showRecruitmentDialog(const CGDwelling * dwelling, const CArmedInstance * dst, int level) override;
void showRecruitmentDialog(const CGDwelling * dwelling, const CArmedInstance * dst, int level, QueryID queryID) override;
void heroMovePointsChanged(const CGHeroInstance * hero) override;
void garrisonsChanged(ObjectInstanceID id1, ObjectInstanceID id2) override;
void newObject(const CGObjectInstance * obj) override;

View File

@ -1318,15 +1318,19 @@ void CPlayerInterface::initializeHeroTownList()
adventureInt->onHeroChanged(nullptr);
}
void CPlayerInterface::showRecruitmentDialog(const CGDwelling *dwelling, const CArmedInstance *dst, int level)
void CPlayerInterface::showRecruitmentDialog(const CGDwelling *dwelling, const CArmedInstance *dst, int level, QueryID queryID)
{
EVENT_HANDLER_CALLED_BY_CLIENT;
waitWhileDialog();
auto recruitCb = [=](CreatureID id, int count)
{
LOCPLINT->cb->recruitCreatures(dwelling, dst, id, count, -1);
cb->recruitCreatures(dwelling, dst, id, count, -1);
};
GH.windows().createAndPushWindow<CRecruitmentWindow>(dwelling, level, dst, recruitCb);
auto closeCb = [=]()
{
cb->selectionMade(0, queryID);
};
GH.windows().createAndPushWindow<CRecruitmentWindow>(dwelling, level, dst, recruitCb, closeCb);
}
void CPlayerInterface::waitWhileDialog()

View File

@ -117,7 +117,7 @@ protected: // Call-ins from server, should not be called directly, but only via
void heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town) override;
void receivedResource() override;
void showInfoDialog(EInfoWindowMode type, const std::string & text, const std::vector<Component> & components, int soundID) override;
void showRecruitmentDialog(const CGDwelling *dwelling, const CArmedInstance *dst, int level) override;
void showRecruitmentDialog(const CGDwelling *dwelling, const CArmedInstance *dst, int level, QueryID queryID) override;
void showBlockingDialog(const std::string &text, const std::vector<Component> &components, QueryID askID, const int soundID, bool selection, bool cancel) override; //Show a dialog, player must take decision. If selection then he has to choose between one of given components, if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called with number of selected component (1 - n) or 0 for cancel (if allowed) and askID.
void showTeleportDialog(const CGHeroInstance * hero, TeleportChannelID channel, TTeleportExitsList exits, bool impassable, QueryID askID) override;
void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, QueryID queryID) override;

View File

@ -936,10 +936,9 @@ void ApplyClientNetPackVisitor::visitOpenWindow(OpenWindow & pack)
case EOpenWindowMode::RECRUITMENT_FIRST:
case EOpenWindowMode::RECRUITMENT_ALL:
{
assert(pack.queryID == QueryID::NONE);
const CGDwelling *dw = dynamic_cast<const CGDwelling*>(cl.getObj(ObjectInstanceID(pack.object)));
const CArmedInstance *dst = dynamic_cast<const CArmedInstance*>(cl.getObj(ObjectInstanceID(pack.visitor)));
callInterfaceIfPresent(cl, dst->tempOwner, &IGameEventsReceiver::showRecruitmentDialog, dw, dst, pack.window == EOpenWindowMode::RECRUITMENT_FIRST ? 0 : -1);
callInterfaceIfPresent(cl, dst->tempOwner, &IGameEventsReceiver::showRecruitmentDialog, dw, dst, pack.window == EOpenWindowMode::RECRUITMENT_FIRST ? 0 : -1, pack.queryID);
}
break;
case EOpenWindowMode::SHIPYARD_WINDOW:

View File

@ -864,7 +864,7 @@ void CCastleBuildings::enterDwelling(int level)
{
LOCPLINT->cb->recruitCreatures(town, town->getUpperArmy(), id, count, level);
};
GH.windows().createAndPushWindow<CRecruitmentWindow>(town, level, town, recruitCb, -87);
GH.windows().createAndPushWindow<CRecruitmentWindow>(town, level, town, recruitCb, nullptr, -87);
}
void CCastleBuildings::enterToTheQuickRecruitmentWindow()
@ -1073,7 +1073,7 @@ void CCreaInfo::clickPressed(const Point & cursorPosition)
{
LOCPLINT->cb->recruitCreatures(town, town->getUpperArmy(), id, count, level);
};
GH.windows().createAndPushWindow<CRecruitmentWindow>(town, level, town, recruitCb, offset);
GH.windows().createAndPushWindow<CRecruitmentWindow>(town, level, town, recruitCb, nullptr, offset);
}
std::string CCreaInfo::genGrowthText()

View File

@ -135,6 +135,13 @@ void CRecruitmentWindow::select(std::shared_ptr<CCreatureCard> card)
}
}
void CRecruitmentWindow::close()
{
if (onClose)
onClose();
CStatusbarWindow::close();
}
void CRecruitmentWindow::buy()
{
CreatureID crid = selected->creature->getId();
@ -192,9 +199,10 @@ void CRecruitmentWindow::showAll(Canvas & to)
to.drawBorder(Rect(289, 312, 66, 34) + pos.topLeft(), Colors::METALLIC_GOLD);
}
CRecruitmentWindow::CRecruitmentWindow(const CGDwelling * Dwelling, int Level, const CArmedInstance * Dst, const std::function<void(CreatureID,int)> & Recruit, int y_offset):
CRecruitmentWindow::CRecruitmentWindow(const CGDwelling * Dwelling, int Level, const CArmedInstance * Dst, const std::function<void(CreatureID,int)> & Recruit, const std::function<void()> & onClose, int y_offset):
CStatusbarWindow(PLAYER_COLORED, ImagePath::builtin("TPRCRT")),
onRecruit(Recruit),
onClose(onClose),
level(Level),
dst(Dst),
selected(nullptr),

View File

@ -61,6 +61,7 @@ class CRecruitmentWindow : public CStatusbarWindow
};
std::function<void(CreatureID,int)> onRecruit; //void (int ID, int amount) <-- call to recruit creatures
std::function<void()> onClose;
int level;
const CArmedInstance * dst;
@ -87,8 +88,9 @@ class CRecruitmentWindow : public CStatusbarWindow
void showAll(Canvas & to) override;
public:
const CGDwelling * const dwelling;
CRecruitmentWindow(const CGDwelling * Dwelling, int Level, const CArmedInstance * Dst, const std::function<void(CreatureID,int)> & Recruit, int y_offset = 0);
CRecruitmentWindow(const CGDwelling * Dwelling, int Level, const CArmedInstance * Dst, const std::function<void(CreatureID,int)> & Recruit, const std::function<void()> & onClose, int y_offset = 0);
void availableCreaturesChanged();
void close();
};
/// Split window where creatures can be split up into two single unit stacks

View File

@ -105,7 +105,7 @@ public:
virtual void heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town){};
virtual void receivedResource(){};
virtual void showInfoDialog(EInfoWindowMode type, const std::string & text, const std::vector<Component> & components, int soundID){};
virtual void showRecruitmentDialog(const CGDwelling *dwelling, const CArmedInstance *dst, int level){}
virtual void showRecruitmentDialog(const CGDwelling *dwelling, const CArmedInstance *dst, int level, QueryID queryID){}
virtual void showShipyardDialog(const IShipyard *obj){} //obj may be town or shipyard; state: 0 - can buid, 1 - lack of resources, 2 - dest tile is blocked, 3 - no water
virtual void showPuzzleMap(){};

View File

@ -394,7 +394,7 @@ void CGDwelling::heroAcceptsCreatures( const CGHeroInstance *h) const
}
auto windowMode = (ID == Obj::CREATURE_GENERATOR1 || ID == Obj::REFUGEE_CAMP) ? EOpenWindowMode::RECRUITMENT_FIRST : EOpenWindowMode::RECRUITMENT_ALL;
cb->showObjectWindow(this, windowMode, h, false);
cb->showObjectWindow(this, windowMode, h, true);
}
}

View File

@ -171,6 +171,16 @@ void OpenWindowQuery::onExposure(QueryPtr topQuery)
bool OpenWindowQuery::blocksPack(const CPack *pack) const
{
if (mode == EOpenWindowMode::RECRUITMENT_FIRST || mode == EOpenWindowMode::RECRUITMENT_ALL)
{
if(dynamic_ptr_cast<RecruitCreatures>(pack) != nullptr)
return false;
// If hero has no free slots, he might get some stacks merged automatically
if(dynamic_ptr_cast<ArrangeStacks>(pack) != nullptr)
return false;
}
if (mode == EOpenWindowMode::TAVERN_WINDOW)
{
if(dynamic_ptr_cast<HireHero>(pack) != nullptr)