mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-28 08:48:48 +02:00
ArtifactsUIController class
This commit is contained in:
parent
f87762bc96
commit
ef1fbffad4
142
client/ArtifactsUIController.cpp
Normal file
142
client/ArtifactsUIController.cpp
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
/*
|
||||||
|
* ArtifactsUIController.cpp, part of VCMI engine
|
||||||
|
*
|
||||||
|
* Authors: listed in file AUTHORS in main folder
|
||||||
|
*
|
||||||
|
* License: GNU General Public License v2.0 or later
|
||||||
|
* Full text of license available in license.txt file, in main folder
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "StdInc.h"
|
||||||
|
#include "ArtifactsUIController.h"
|
||||||
|
#include "CGameInfo.h"
|
||||||
|
#include "CPlayerInterface.h"
|
||||||
|
|
||||||
|
#include "../CCallback.h"
|
||||||
|
#include "../lib/ArtifactUtils.h"
|
||||||
|
#include "../lib/CGeneralTextHandler.h"
|
||||||
|
#include "../lib/mapObjects/CGHeroInstance.h"
|
||||||
|
|
||||||
|
#include "gui/CGuiHandler.h"
|
||||||
|
#include "gui/WindowHandler.h"
|
||||||
|
#include "widgets/CComponent.h"
|
||||||
|
#include "windows/CWindowWithArtifacts.h"
|
||||||
|
|
||||||
|
bool ArtifactsUIController::askToAssemble(const CGHeroInstance * hero, const ArtifactPosition & slot, std::set<ArtifactID> * ignoredArtifacts)
|
||||||
|
{
|
||||||
|
assert(hero);
|
||||||
|
const auto art = hero->getArt(slot);
|
||||||
|
assert(art);
|
||||||
|
|
||||||
|
if(hero->tempOwner != LOCPLINT->playerID)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto assemblyPossibilities = ArtifactUtils::assemblyPossibilities(hero, art->getTypeId(), true);
|
||||||
|
if(!assemblyPossibilities.empty())
|
||||||
|
{
|
||||||
|
auto askThread = new boost::thread([this, hero, art, slot, assemblyPossibilities, ignoredArtifacts]() -> void
|
||||||
|
{
|
||||||
|
boost::mutex::scoped_lock askLock(askAssembleArtifactsMutex);
|
||||||
|
for(const auto combinedArt : assemblyPossibilities)
|
||||||
|
{
|
||||||
|
boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
|
||||||
|
if(ignoredArtifacts && vstd::contains(*ignoredArtifacts, combinedArt->getId()))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bool assembleConfirmed = false;
|
||||||
|
MetaString message = MetaString::createFromTextID(art->artType->getDescriptionTextID());
|
||||||
|
message.appendEOL();
|
||||||
|
message.appendEOL();
|
||||||
|
message.appendRawString(CGI->generaltexth->allTexts[732]); // You possess all of the components needed to assemble the
|
||||||
|
message.replaceName(ArtifactID(combinedArt->getId()));
|
||||||
|
LOCPLINT->showYesNoDialog(message.toString(), [&assembleConfirmed, hero, slot, combinedArt]()
|
||||||
|
{
|
||||||
|
assembleConfirmed = true;
|
||||||
|
LOCPLINT->cb.get()->assembleArtifacts(hero, slot, true, combinedArt->getId());
|
||||||
|
}, nullptr, {std::make_shared<CComponent>(ComponentType::ARTIFACT, combinedArt->getId())});
|
||||||
|
|
||||||
|
LOCPLINT->waitWhileDialog();
|
||||||
|
if(ignoredArtifacts)
|
||||||
|
ignoredArtifacts->emplace(combinedArt->getId());
|
||||||
|
if(assembleConfirmed)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
askThread->detach();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ArtifactsUIController::askToDisassemble(const CGHeroInstance * hero, const ArtifactPosition & slot)
|
||||||
|
{
|
||||||
|
assert(hero);
|
||||||
|
const auto art = hero->getArt(slot);
|
||||||
|
assert(art);
|
||||||
|
|
||||||
|
if(hero->tempOwner != LOCPLINT->playerID)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(art->isCombined())
|
||||||
|
{
|
||||||
|
if(ArtifactUtils::isSlotBackpack(slot) && !ArtifactUtils::isBackpackFreeSlots(hero, art->artType->getConstituents().size() - 1))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
MetaString message = MetaString::createFromTextID(art->artType->getDescriptionTextID());
|
||||||
|
message.appendEOL();
|
||||||
|
message.appendEOL();
|
||||||
|
message.appendRawString(CGI->generaltexth->allTexts[733]); // Do you wish to disassemble this artifact?
|
||||||
|
LOCPLINT->showYesNoDialog(message.toString(), [hero, slot]()
|
||||||
|
{
|
||||||
|
LOCPLINT->cb->assembleArtifacts(hero, slot, false, ArtifactID());
|
||||||
|
}, nullptr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ArtifactsUIController::artifactRemoved()
|
||||||
|
{
|
||||||
|
for(auto & artWin : GH.windows().findWindows<CWindowWithArtifacts>())
|
||||||
|
artWin->update();
|
||||||
|
LOCPLINT->waitWhileDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ArtifactsUIController::artifactMoved()
|
||||||
|
{
|
||||||
|
// If a bulk transfer has arrived, then redrawing only the last art movement.
|
||||||
|
if(numOfMovedArts != 0)
|
||||||
|
numOfMovedArts--;
|
||||||
|
|
||||||
|
for(auto & artWin : GH.windows().findWindows<CWindowWithArtifacts>())
|
||||||
|
if(numOfMovedArts == 0)
|
||||||
|
{
|
||||||
|
artWin->update();
|
||||||
|
artWin->redraw();
|
||||||
|
}
|
||||||
|
LOCPLINT->waitWhileDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ArtifactsUIController::bulkArtMovementStart(size_t numOfArts)
|
||||||
|
{
|
||||||
|
numOfMovedArts = numOfArts;
|
||||||
|
if(numOfArtsAskAssembleSession == 0)
|
||||||
|
{
|
||||||
|
// Do not start the next session until the previous one is finished
|
||||||
|
numOfArtsAskAssembleSession = numOfArts; // TODO this is wrong
|
||||||
|
ignoredArtifacts.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ArtifactsUIController::artifactAssembled()
|
||||||
|
{
|
||||||
|
for(auto & artWin : GH.windows().findWindows<CWindowWithArtifacts>())
|
||||||
|
artWin->update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ArtifactsUIController::artifactDisassembled()
|
||||||
|
{
|
||||||
|
for(auto & artWin : GH.windows().findWindows<CWindowWithArtifacts>())
|
||||||
|
artWin->update();
|
||||||
|
}
|
38
client/ArtifactsUIController.h
Normal file
38
client/ArtifactsUIController.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* ArtifactsUIController.h, part of VCMI engine
|
||||||
|
*
|
||||||
|
* Authors: listed in file AUTHORS in main folder
|
||||||
|
*
|
||||||
|
* License: GNU General Public License v2.0 or later
|
||||||
|
* Full text of license available in license.txt file, in main folder
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../lib/constants/EntityIdentifiers.h"
|
||||||
|
|
||||||
|
VCMI_LIB_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
class CGHeroInstance;
|
||||||
|
|
||||||
|
VCMI_LIB_NAMESPACE_END
|
||||||
|
|
||||||
|
class ArtifactsUIController
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
size_t numOfMovedArts;
|
||||||
|
size_t numOfArtsAskAssembleSession;
|
||||||
|
std::set<ArtifactID> ignoredArtifacts;
|
||||||
|
|
||||||
|
boost::mutex askAssembleArtifactsMutex;
|
||||||
|
|
||||||
|
bool askToAssemble(const CGHeroInstance * hero, const ArtifactPosition & slot, std::set<ArtifactID> * ignoredArtifacts = nullptr);
|
||||||
|
bool askToDisassemble(const CGHeroInstance * hero, const ArtifactPosition & slot);
|
||||||
|
|
||||||
|
void artifactRemoved();
|
||||||
|
void artifactMoved();
|
||||||
|
void bulkArtMovementStart(size_t numOfArts);
|
||||||
|
void artifactAssembled();
|
||||||
|
void artifactDisassembled();
|
||||||
|
};
|
||||||
|
|
@ -168,6 +168,7 @@ set(client_SRCS
|
|||||||
windows/settings/BattleOptionsTab.cpp
|
windows/settings/BattleOptionsTab.cpp
|
||||||
windows/settings/AdventureOptionsTab.cpp
|
windows/settings/AdventureOptionsTab.cpp
|
||||||
|
|
||||||
|
ArtifactsUIController.cpp
|
||||||
CGameInfo.cpp
|
CGameInfo.cpp
|
||||||
CMT.cpp
|
CMT.cpp
|
||||||
CPlayerInterface.cpp
|
CPlayerInterface.cpp
|
||||||
@ -371,6 +372,7 @@ set(client_HEADERS
|
|||||||
windows/settings/BattleOptionsTab.h
|
windows/settings/BattleOptionsTab.h
|
||||||
windows/settings/AdventureOptionsTab.h
|
windows/settings/AdventureOptionsTab.h
|
||||||
|
|
||||||
|
ArtifactsUIController.h
|
||||||
CGameInfo.h
|
CGameInfo.h
|
||||||
CMT.h
|
CMT.h
|
||||||
CPlayerInterface.h
|
CPlayerInterface.h
|
||||||
|
@ -1251,35 +1251,6 @@ void CPlayerInterface::showGarrisonDialog( const CArmedInstance *up, const CGHer
|
|||||||
GH.windows().pushWindow(cgw);
|
GH.windows().pushWindow(cgw);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Shows the dialog that appears when right-clicking an artifact that can be assembled
|
|
||||||
* into a combinational one on an artifact screen. Does not require the combination of
|
|
||||||
* artifacts to be legal.
|
|
||||||
*/
|
|
||||||
void CPlayerInterface::showArtifactAssemblyDialog(const Artifact * artifact, const Artifact * assembledArtifact, CFunctionList<void()> onYes)
|
|
||||||
{
|
|
||||||
std::string text = artifact->getDescriptionTranslated();
|
|
||||||
text += "\n\n";
|
|
||||||
std::vector<std::shared_ptr<CComponent>> scs;
|
|
||||||
|
|
||||||
if(assembledArtifact)
|
|
||||||
{
|
|
||||||
// You possess all of the components to...
|
|
||||||
text += boost::str(boost::format(CGI->generaltexth->allTexts[732]) % assembledArtifact->getNameTranslated());
|
|
||||||
|
|
||||||
// Picture of assembled artifact at bottom.
|
|
||||||
auto sc = std::make_shared<CComponent>(ComponentType::ARTIFACT, assembledArtifact->getId());
|
|
||||||
scs.push_back(sc);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Do you wish to disassemble this artifact?
|
|
||||||
text += CGI->generaltexth->allTexts[733];
|
|
||||||
}
|
|
||||||
|
|
||||||
showYesNoDialog(text, onYes, nullptr, scs);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CPlayerInterface::requestRealized( PackageApplied *pa )
|
void CPlayerInterface::requestRealized( PackageApplied *pa )
|
||||||
{
|
{
|
||||||
if(pa->packType == CTypeList::getInstance().getTypeID<MoveHero>(nullptr))
|
if(pa->packType == CTypeList::getInstance().getTypeID<MoveHero>(nullptr))
|
||||||
@ -1739,14 +1710,14 @@ void CPlayerInterface::askToAssembleArtifact(const ArtifactLocation &al)
|
|||||||
{
|
{
|
||||||
if(auto hero = cb->getHero(al.artHolder))
|
if(auto hero = cb->getHero(al.artHolder))
|
||||||
{
|
{
|
||||||
auto art = hero->getArt(al.slot);
|
if(hero->getArt(al.slot) == nullptr)
|
||||||
if(art == nullptr)
|
|
||||||
{
|
{
|
||||||
logGlobal->error("artifact location %d points to nothing",
|
logGlobal->error("artifact location %d points to nothing", al.slot.num);
|
||||||
al.slot.num);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ArtifactUtilsClient::askToAssemble(hero, al.slot);
|
askToAssemble(hero, al.slot, &ignoredArtifacts);
|
||||||
|
if(numOfArtsAskAssembleSession != 0)
|
||||||
|
numOfArtsAskAssembleSession--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1760,55 +1731,33 @@ void CPlayerInterface::artifactRemoved(const ArtifactLocation &al)
|
|||||||
{
|
{
|
||||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||||
adventureInt->onHeroChanged(cb->getHero(al.artHolder));
|
adventureInt->onHeroChanged(cb->getHero(al.artHolder));
|
||||||
|
ArtifactsUIController::artifactRemoved();
|
||||||
for(auto artWin : GH.windows().findWindows<CWindowWithArtifacts>())
|
|
||||||
artWin->artifactRemoved(al);
|
|
||||||
|
|
||||||
waitWhileDialog();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayerInterface::artifactMoved(const ArtifactLocation &src, const ArtifactLocation &dst)
|
void CPlayerInterface::artifactMoved(const ArtifactLocation &src, const ArtifactLocation &dst)
|
||||||
{
|
{
|
||||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||||
adventureInt->onHeroChanged(cb->getHero(dst.artHolder));
|
adventureInt->onHeroChanged(cb->getHero(dst.artHolder));
|
||||||
|
ArtifactsUIController::artifactMoved();
|
||||||
// If a bulk transfer has arrived, then redrawing only the last art movement.
|
|
||||||
if(numOfMovedArts != 0)
|
|
||||||
numOfMovedArts--;
|
|
||||||
|
|
||||||
for(auto artWin : GH.windows().findWindows<CWindowWithArtifacts>())
|
|
||||||
{
|
|
||||||
artWin->artifactMoved(src, dst);
|
|
||||||
if(numOfMovedArts == 0)
|
|
||||||
{
|
|
||||||
artWin->update();
|
|
||||||
artWin->redraw();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
waitWhileDialog();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayerInterface::bulkArtMovementStart(size_t numOfArts)
|
void CPlayerInterface::bulkArtMovementStart(size_t numOfArts)
|
||||||
{
|
{
|
||||||
numOfMovedArts = numOfArts;
|
ArtifactsUIController::bulkArtMovementStart(numOfArts);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayerInterface::artifactAssembled(const ArtifactLocation &al)
|
void CPlayerInterface::artifactAssembled(const ArtifactLocation &al)
|
||||||
{
|
{
|
||||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||||
adventureInt->onHeroChanged(cb->getHero(al.artHolder));
|
adventureInt->onHeroChanged(cb->getHero(al.artHolder));
|
||||||
|
ArtifactsUIController::artifactAssembled();
|
||||||
for(auto artWin : GH.windows().findWindows<CWindowWithArtifacts>())
|
|
||||||
artWin->artifactAssembled(al);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayerInterface::artifactDisassembled(const ArtifactLocation &al)
|
void CPlayerInterface::artifactDisassembled(const ArtifactLocation &al)
|
||||||
{
|
{
|
||||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||||
adventureInt->onHeroChanged(cb->getHero(al.artHolder));
|
adventureInt->onHeroChanged(cb->getHero(al.artHolder));
|
||||||
|
ArtifactsUIController::artifactDisassembled();
|
||||||
for(auto artWin : GH.windows().findWindows<CWindowWithArtifacts>())
|
|
||||||
artWin->artifactDisassembled(al);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayerInterface::waitForAllDialogs()
|
void CPlayerInterface::waitForAllDialogs()
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "../lib/FunctionList.h"
|
#include "../lib/FunctionList.h"
|
||||||
#include "../lib/CGameInterface.h"
|
#include "../lib/CGameInterface.h"
|
||||||
#include "gui/CIntObject.h"
|
#include "gui/CIntObject.h"
|
||||||
|
#include "ArtifactsUIController.h"
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_BEGIN
|
VCMI_LIB_NAMESPACE_BEGIN
|
||||||
|
|
||||||
@ -56,11 +57,9 @@ namespace boost
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Central class for managing user interface logic
|
/// Central class for managing user interface logic
|
||||||
class CPlayerInterface : public CGameInterface, public IUpdateable
|
class CPlayerInterface : public CGameInterface, public IUpdateable, public ArtifactsUIController
|
||||||
{
|
{
|
||||||
bool ignoreEvents;
|
bool ignoreEvents;
|
||||||
size_t numOfMovedArts;
|
|
||||||
|
|
||||||
int autosaveCount;
|
int autosaveCount;
|
||||||
|
|
||||||
std::list<std::shared_ptr<CInfoWindow>> dialogs; //queue of dialogs awaiting to be shown (not currently shown!)
|
std::list<std::shared_ptr<CInfoWindow>> dialogs; //queue of dialogs awaiting to be shown (not currently shown!)
|
||||||
@ -180,7 +179,6 @@ public: // public interface for use by client via LOCPLINT access
|
|||||||
void showShipyardDialog(const IShipyard *obj) override; //obj may be town or shipyard;
|
void showShipyardDialog(const IShipyard *obj) override; //obj may be town or shipyard;
|
||||||
|
|
||||||
void showHeroExchange(ObjectInstanceID hero1, ObjectInstanceID hero2);
|
void showHeroExchange(ObjectInstanceID hero1, ObjectInstanceID hero2);
|
||||||
void showArtifactAssemblyDialog(const Artifact * artifact, const Artifact * assembledArtifact, CFunctionList<void()> onYes);
|
|
||||||
void waitWhileDialog();
|
void waitWhileDialog();
|
||||||
void waitForAllDialogs();
|
void waitForAllDialogs();
|
||||||
void openTownWindow(const CGTownInstance * town); //shows townscreen
|
void openTownWindow(const CGTownInstance * town); //shows townscreen
|
||||||
|
@ -307,7 +307,7 @@ void ApplyClientNetPackVisitor::visitBulkMoveArtifacts(BulkMoveArtifacts & pack)
|
|||||||
const auto dstLoc = ArtifactLocation(pack.dstArtHolder, slotToMove.dstPos);
|
const auto dstLoc = ArtifactLocation(pack.dstArtHolder, slotToMove.dstPos);
|
||||||
|
|
||||||
callInterfaceIfPresent(cl, pack.interfaceOwner, &IGameEventsReceiver::artifactMoved, srcLoc, dstLoc);
|
callInterfaceIfPresent(cl, pack.interfaceOwner, &IGameEventsReceiver::artifactMoved, srcLoc, dstLoc);
|
||||||
if(pack.askAssemble)
|
if(slotToMove.askAssemble)
|
||||||
callInterfaceIfPresent(cl, pack.interfaceOwner, &IGameEventsReceiver::askToAssembleArtifact, dstLoc);
|
callInterfaceIfPresent(cl, pack.interfaceOwner, &IGameEventsReceiver::askToAssembleArtifact, dstLoc);
|
||||||
if(pack.interfaceOwner != dstOwner)
|
if(pack.interfaceOwner != dstOwner)
|
||||||
callInterfaceIfPresent(cl, dstOwner, &IGameEventsReceiver::artifactMoved, srcLoc, dstLoc);
|
callInterfaceIfPresent(cl, dstOwner, &IGameEventsReceiver::artifactMoved, srcLoc, dstLoc);
|
||||||
|
@ -245,59 +245,3 @@ void CArtPlace::addCombinedArtInfo(const std::map<const ArtifactID, std::vector<
|
|||||||
text += info.toString();
|
text += info.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ArtifactUtilsClient::askToAssemble(const CGHeroInstance * hero, const ArtifactPosition & slot)
|
|
||||||
{
|
|
||||||
assert(hero);
|
|
||||||
const auto art = hero->getArt(slot);
|
|
||||||
assert(art);
|
|
||||||
|
|
||||||
if(hero->tempOwner != LOCPLINT->playerID)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
auto assemblyPossibilities = ArtifactUtils::assemblyPossibilities(hero, art->getTypeId());
|
|
||||||
if(!assemblyPossibilities.empty())
|
|
||||||
{
|
|
||||||
auto askThread = new boost::thread([hero, art, slot, assemblyPossibilities]() -> void
|
|
||||||
{
|
|
||||||
boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
|
|
||||||
for(const auto combinedArt : assemblyPossibilities)
|
|
||||||
{
|
|
||||||
LOCPLINT->waitWhileDialog();
|
|
||||||
bool assembleConfirmed = false;
|
|
||||||
CFunctionList<void()> onYesHandlers([&assembleConfirmed]() -> void {assembleConfirmed = true; });
|
|
||||||
onYesHandlers += std::bind(&CCallback::assembleArtifacts, LOCPLINT->cb.get(), hero, slot, true, combinedArt->getId());
|
|
||||||
|
|
||||||
LOCPLINT->showArtifactAssemblyDialog(art->artType, combinedArt, onYesHandlers);
|
|
||||||
if(assembleConfirmed)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
askThread->detach();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ArtifactUtilsClient::askToDisassemble(const CGHeroInstance * hero, const ArtifactPosition & slot)
|
|
||||||
{
|
|
||||||
assert(hero);
|
|
||||||
const auto art = hero->getArt(slot);
|
|
||||||
assert(art);
|
|
||||||
|
|
||||||
if(hero->tempOwner != LOCPLINT->playerID)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if(art->isCombined())
|
|
||||||
{
|
|
||||||
if(ArtifactUtils::isSlotBackpack(slot) && !ArtifactUtils::isBackpackFreeSlots(hero, art->artType->getConstituents().size() - 1))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
LOCPLINT->showArtifactAssemblyDialog(
|
|
||||||
art->artType,
|
|
||||||
nullptr,
|
|
||||||
std::bind(&CCallback::assembleArtifacts, LOCPLINT->cb.get(), hero, slot, false, ArtifactID()));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
@ -59,9 +59,3 @@ public:
|
|||||||
void clickPressed(const Point & cursorPosition) override;
|
void clickPressed(const Point & cursorPosition) override;
|
||||||
void showPopupWindow(const Point & cursorPosition) override;
|
void showPopupWindow(const Point & cursorPosition) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace ArtifactUtilsClient
|
|
||||||
{
|
|
||||||
bool askToAssemble(const CGHeroInstance * hero, const ArtifactPosition & slot);
|
|
||||||
bool askToDisassemble(const CGHeroInstance * hero, const ArtifactPosition & slot);
|
|
||||||
}
|
|
||||||
|
@ -117,9 +117,9 @@ void CWindowWithArtifacts::showArtifactAssembling(const CArtifactsOfHeroBase & a
|
|||||||
{
|
{
|
||||||
if(artsInst.getArt(artPlace.slot))
|
if(artsInst.getArt(artPlace.slot))
|
||||||
{
|
{
|
||||||
if(ArtifactUtilsClient::askToDisassemble(artsInst.getHero(), artPlace.slot))
|
if(LOCPLINT->askToDisassemble(artsInst.getHero(), artPlace.slot))
|
||||||
return;
|
return;
|
||||||
if(ArtifactUtilsClient::askToAssemble(artsInst.getHero(), artPlace.slot))
|
if(LOCPLINT->askToAssemble(artsInst.getHero(), artPlace.slot))
|
||||||
return;
|
return;
|
||||||
if(artPlace.text.size())
|
if(artPlace.text.size())
|
||||||
artPlace.LRClickableAreaWTextComp::showPopupWindow(cursorPosition);
|
artPlace.LRClickableAreaWTextComp::showPopupWindow(cursorPosition);
|
||||||
@ -166,14 +166,13 @@ void CWindowWithArtifacts::enableKeyboardShortcuts() const
|
|||||||
artSet->enableKeyboardShortcuts();
|
artSet->enableKeyboardShortcuts();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWindowWithArtifacts::artifactRemoved(const ArtifactLocation & artLoc)
|
void CWindowWithArtifacts::update()
|
||||||
{
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CWindowWithArtifacts::artifactMoved(const ArtifactLocation & srcLoc, const ArtifactLocation & destLoc)
|
|
||||||
{
|
{
|
||||||
for(const auto & artSet : artSets)
|
for(const auto & artSet : artSets)
|
||||||
|
{
|
||||||
|
artSet->updateWornSlots();
|
||||||
|
artSet->updateBackpackSlots();
|
||||||
|
|
||||||
if(const auto pickedArtInst = getPickedArtifact())
|
if(const auto pickedArtInst = getPickedArtifact())
|
||||||
{
|
{
|
||||||
markPossibleSlots();
|
markPossibleSlots();
|
||||||
@ -184,25 +183,6 @@ void CWindowWithArtifacts::artifactMoved(const ArtifactLocation & srcLoc, const
|
|||||||
artSet->unmarkSlots();
|
artSet->unmarkSlots();
|
||||||
CCS->curh->dragAndDropCursor(nullptr);
|
CCS->curh->dragAndDropCursor(nullptr);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void CWindowWithArtifacts::artifactDisassembled(const ArtifactLocation & artLoc)
|
|
||||||
{
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CWindowWithArtifacts::artifactAssembled(const ArtifactLocation & artLoc)
|
|
||||||
{
|
|
||||||
markPossibleSlots();
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CWindowWithArtifacts::update()
|
|
||||||
{
|
|
||||||
for(const auto & artSet : artSets)
|
|
||||||
{
|
|
||||||
artSet->updateWornSlots();
|
|
||||||
artSet->updateBackpackSlots();
|
|
||||||
|
|
||||||
// Make sure the status bar is updated so it does not display old text
|
// Make sure the status bar is updated so it does not display old text
|
||||||
if(auto artPlace = artSet->getArtPlace(GH.getCursorPosition()))
|
if(auto artPlace = artSet->getArtPlace(GH.getCursorPosition()))
|
||||||
|
@ -37,10 +37,6 @@ public:
|
|||||||
void deactivate() override;
|
void deactivate() override;
|
||||||
void enableKeyboardShortcuts() const;
|
void enableKeyboardShortcuts() const;
|
||||||
|
|
||||||
virtual void artifactRemoved(const ArtifactLocation & artLoc);
|
|
||||||
virtual void artifactMoved(const ArtifactLocation & srcLoc, const ArtifactLocation & destLoc);
|
|
||||||
virtual void artifactDisassembled(const ArtifactLocation & artLoc);
|
|
||||||
virtual void artifactAssembled(const ArtifactLocation & artLoc);
|
|
||||||
virtual void update();
|
virtual void update();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -196,7 +196,7 @@ DLL_LINKAGE bool ArtifactUtils::isBackpackFreeSlots(const CArtifactSet * target,
|
|||||||
}
|
}
|
||||||
|
|
||||||
DLL_LINKAGE std::vector<const CArtifact*> ArtifactUtils::assemblyPossibilities(
|
DLL_LINKAGE std::vector<const CArtifact*> ArtifactUtils::assemblyPossibilities(
|
||||||
const CArtifactSet * artSet, const ArtifactID & aid)
|
const CArtifactSet * artSet, const ArtifactID & aid, const bool onlyEquiped)
|
||||||
{
|
{
|
||||||
std::vector<const CArtifact*> arts;
|
std::vector<const CArtifact*> arts;
|
||||||
const auto * art = aid.toArtifact();
|
const auto * art = aid.toArtifact();
|
||||||
@ -210,7 +210,7 @@ DLL_LINKAGE std::vector<const CArtifact*> ArtifactUtils::assemblyPossibilities(
|
|||||||
|
|
||||||
for(const auto constituent : artifact->getConstituents()) //check if all constituents are available
|
for(const auto constituent : artifact->getConstituents()) //check if all constituents are available
|
||||||
{
|
{
|
||||||
if(!artSet->hasArt(constituent->getId(), false, false, false))
|
if(!artSet->hasArt(constituent->getId(), onlyEquiped, false, false))
|
||||||
{
|
{
|
||||||
possible = false;
|
possible = false;
|
||||||
break;
|
break;
|
||||||
|
@ -39,7 +39,7 @@ namespace ArtifactUtils
|
|||||||
DLL_LINKAGE bool isSlotBackpack(const ArtifactPosition & slot);
|
DLL_LINKAGE bool isSlotBackpack(const ArtifactPosition & slot);
|
||||||
DLL_LINKAGE bool isSlotEquipment(const ArtifactPosition & slot);
|
DLL_LINKAGE bool isSlotEquipment(const ArtifactPosition & slot);
|
||||||
DLL_LINKAGE bool isBackpackFreeSlots(const CArtifactSet * target, const size_t reqSlots = 1);
|
DLL_LINKAGE bool isBackpackFreeSlots(const CArtifactSet * target, const size_t reqSlots = 1);
|
||||||
DLL_LINKAGE std::vector<const CArtifact*> assemblyPossibilities(const CArtifactSet * artSet, const ArtifactID & aid);
|
DLL_LINKAGE std::vector<const CArtifact*> assemblyPossibilities(const CArtifactSet * artSet, const ArtifactID & aid, const bool onlyEquiped = false);
|
||||||
DLL_LINKAGE CArtifactInstance * createScroll(const SpellID & sid);
|
DLL_LINKAGE CArtifactInstance * createScroll(const SpellID & sid);
|
||||||
DLL_LINKAGE CArtifactInstance * createNewArtifactInstance(const CArtifact * art);
|
DLL_LINKAGE CArtifactInstance * createNewArtifactInstance(const CArtifact * art);
|
||||||
DLL_LINKAGE CArtifactInstance * createNewArtifactInstance(const ArtifactID & aid);
|
DLL_LINKAGE CArtifactInstance * createNewArtifactInstance(const ArtifactID & aid);
|
||||||
|
@ -1031,17 +1031,20 @@ struct DLL_LINKAGE BulkMoveArtifacts : CArtifactOperationPack
|
|||||||
{
|
{
|
||||||
ArtifactPosition srcPos;
|
ArtifactPosition srcPos;
|
||||||
ArtifactPosition dstPos;
|
ArtifactPosition dstPos;
|
||||||
|
bool askAssemble;
|
||||||
|
|
||||||
LinkedSlots() = default;
|
LinkedSlots() = default;
|
||||||
LinkedSlots(const ArtifactPosition & srcPos, const ArtifactPosition & dstPos)
|
LinkedSlots(const ArtifactPosition & srcPos, const ArtifactPosition & dstPos, bool askAssemble = false)
|
||||||
: srcPos(srcPos)
|
: srcPos(srcPos)
|
||||||
, dstPos(dstPos)
|
, dstPos(dstPos)
|
||||||
|
, askAssemble(askAssemble)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
template <typename Handler> void serialize(Handler & h)
|
template <typename Handler> void serialize(Handler & h)
|
||||||
{
|
{
|
||||||
h & srcPos;
|
h & srcPos;
|
||||||
h & dstPos;
|
h & dstPos;
|
||||||
|
h & askAssemble;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1056,7 +1059,6 @@ struct DLL_LINKAGE BulkMoveArtifacts : CArtifactOperationPack
|
|||||||
, srcArtHolder(ObjectInstanceID::NONE)
|
, srcArtHolder(ObjectInstanceID::NONE)
|
||||||
, dstArtHolder(ObjectInstanceID::NONE)
|
, dstArtHolder(ObjectInstanceID::NONE)
|
||||||
, swap(false)
|
, swap(false)
|
||||||
, askAssemble(false)
|
|
||||||
, srcCreature(std::nullopt)
|
, srcCreature(std::nullopt)
|
||||||
, dstCreature(std::nullopt)
|
, dstCreature(std::nullopt)
|
||||||
{
|
{
|
||||||
@ -1066,7 +1068,6 @@ struct DLL_LINKAGE BulkMoveArtifacts : CArtifactOperationPack
|
|||||||
, srcArtHolder(srcArtHolder)
|
, srcArtHolder(srcArtHolder)
|
||||||
, dstArtHolder(dstArtHolder)
|
, dstArtHolder(dstArtHolder)
|
||||||
, swap(swap)
|
, swap(swap)
|
||||||
, askAssemble(false)
|
|
||||||
, srcCreature(std::nullopt)
|
, srcCreature(std::nullopt)
|
||||||
, dstCreature(std::nullopt)
|
, dstCreature(std::nullopt)
|
||||||
{
|
{
|
||||||
@ -1077,7 +1078,6 @@ struct DLL_LINKAGE BulkMoveArtifacts : CArtifactOperationPack
|
|||||||
std::vector<LinkedSlots> artsPack0;
|
std::vector<LinkedSlots> artsPack0;
|
||||||
std::vector<LinkedSlots> artsPack1;
|
std::vector<LinkedSlots> artsPack1;
|
||||||
bool swap;
|
bool swap;
|
||||||
bool askAssemble;
|
|
||||||
|
|
||||||
void visitTyped(ICPackVisitor & visitor) override;
|
void visitTyped(ICPackVisitor & visitor) override;
|
||||||
|
|
||||||
@ -1091,7 +1091,6 @@ struct DLL_LINKAGE BulkMoveArtifacts : CArtifactOperationPack
|
|||||||
h & srcCreature;
|
h & srcCreature;
|
||||||
h & dstCreature;
|
h & dstCreature;
|
||||||
h & swap;
|
h & swap;
|
||||||
h & askAssemble;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2783,7 +2783,7 @@ bool CGameHandler::moveArtifact(const PlayerColor & player, const ArtifactLocati
|
|||||||
|
|
||||||
ma.artsPack0.push_back(BulkMoveArtifacts::LinkedSlots(src.slot, dstSlot));
|
ma.artsPack0.push_back(BulkMoveArtifacts::LinkedSlots(src.slot, dstSlot));
|
||||||
if(src.artHolder != dst.artHolder)
|
if(src.artHolder != dst.artHolder)
|
||||||
ma.askAssemble = true;
|
ma.artsPack0.back().askAssemble = true;
|
||||||
sendAndApply(&ma);
|
sendAndApply(&ma);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -407,6 +407,8 @@ void BattleResultProcessor::endBattleConfirm(const CBattleInfoCallback & battle)
|
|||||||
if(dstSlot != ArtifactPosition::PRE_FIRST)
|
if(dstSlot != ArtifactPosition::PRE_FIRST)
|
||||||
{
|
{
|
||||||
pack.artsPack0.emplace_back(BulkMoveArtifacts::LinkedSlots(srcSlot, dstSlot));
|
pack.artsPack0.emplace_back(BulkMoveArtifacts::LinkedSlots(srcSlot, dstSlot));
|
||||||
|
if(ArtifactUtils::isSlotEquipment(dstSlot))
|
||||||
|
pack.artsPack0.back().askAssemble = true;
|
||||||
arts.emplace_back(art);
|
arts.emplace_back(art);
|
||||||
artFittingSet.putArtifact(dstSlot, const_cast<CArtifactInstance*>(art));
|
artFittingSet.putArtifact(dstSlot, const_cast<CArtifactInstance*>(art));
|
||||||
}
|
}
|
||||||
@ -421,7 +423,6 @@ void BattleResultProcessor::endBattleConfirm(const CBattleInfoCallback & battle)
|
|||||||
if(finishingBattle->loserHero)
|
if(finishingBattle->loserHero)
|
||||||
{
|
{
|
||||||
packHero.srcArtHolder = finishingBattle->loserHero->id;
|
packHero.srcArtHolder = finishingBattle->loserHero->id;
|
||||||
packHero.askAssemble = true;
|
|
||||||
for(const auto & artSlot : finishingBattle->loserHero->artifactsWorn)
|
for(const auto & artSlot : finishingBattle->loserHero->artifactsWorn)
|
||||||
{
|
{
|
||||||
if(ArtifactUtils::isArtRemovable(artSlot))
|
if(ArtifactUtils::isArtRemovable(artSlot))
|
||||||
|
Loading…
Reference in New Issue
Block a user