1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-16 10:19:47 +02:00
vcmi/client/ArtifactsUIController.cpp

167 lines
4.9 KiB
C++
Raw Normal View History

2024-06-22 18:29:39 +02:00
/*
* 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/texts/CGeneralTextHandler.h"
2024-06-22 18:29:39 +02:00
#include "../lib/mapObjects/CGHeroInstance.h"
#include "gui/CGuiHandler.h"
#include "gui/WindowHandler.h"
#include "widgets/CComponent.h"
#include "windows/CWindowWithArtifacts.h"
2024-07-15 23:03:06 +02:00
ArtifactsUIController::ArtifactsUIController()
{
numOfMovedArts = 0;
}
bool ArtifactsUIController::askToAssemble(const ArtifactLocation & al, const bool onlyEquipped, const bool checkIgnored)
2024-06-23 22:48:19 +02:00
{
if(auto hero = LOCPLINT->cb->getHero(al.artHolder))
{
if(hero->getArt(al.slot) == nullptr)
{
logGlobal->error("artifact location %d points to nothing", al.slot.num);
return false;
}
2024-07-15 23:03:06 +02:00
return askToAssemble(hero, al.slot, onlyEquipped, checkIgnored);
2024-06-23 22:48:19 +02:00
}
return false;
}
bool ArtifactsUIController::askToAssemble(const CGHeroInstance * hero, const ArtifactPosition & slot,
2024-07-15 23:03:06 +02:00
const bool onlyEquipped, const bool checkIgnored)
2024-06-22 18:29:39 +02:00
{
assert(hero);
const auto art = hero->getArt(slot);
assert(art);
if(hero->tempOwner != LOCPLINT->playerID)
return false;
2024-06-23 22:48:19 +02:00
if(numOfArtsAskAssembleSession != 0)
numOfArtsAskAssembleSession--;
auto assemblyPossibilities = ArtifactUtils::assemblyPossibilities(hero, art->getTypeId(), onlyEquipped);
2024-06-22 18:29:39 +02:00
if(!assemblyPossibilities.empty())
{
2024-07-15 23:03:06 +02:00
auto askThread = new boost::thread([this, hero, art, slot, assemblyPossibilities, checkIgnored]() -> void
2024-06-22 18:29:39 +02:00
{
2024-06-23 22:48:19 +02:00
boost::mutex::scoped_lock askLock(askAssembleArtifactMutex);
2024-06-22 18:29:39 +02:00
for(const auto combinedArt : assemblyPossibilities)
{
boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
2024-07-15 23:03:06 +02:00
if(checkIgnored)
2024-06-23 22:48:19 +02:00
{
2024-07-15 23:03:06 +02:00
if(vstd::contains(ignoredArtifacts, combinedArt->getId()))
2024-06-23 22:48:19 +02:00
continue;
2024-07-15 23:03:06 +02:00
ignoredArtifacts.emplace(combinedArt->getId());
2024-06-23 22:48:19 +02:00
}
2024-06-22 18:29:39 +02:00
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;
2024-06-23 22:48:19 +02:00
LOCPLINT->cb.get()->assembleArtifacts(hero->id, slot, true, combinedArt->getId());
2024-06-22 18:29:39 +02:00
}, nullptr, {std::make_shared<CComponent>(ComponentType::ARTIFACT, combinedArt->getId())});
LOCPLINT->waitWhileDialog();
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]()
{
2024-06-23 22:48:19 +02:00
LOCPLINT->cb->assembleArtifacts(hero->id, slot, false, ArtifactID());
2024-06-22 18:29:39 +02:00
}, nullptr);
return true;
}
return false;
}
void ArtifactsUIController::artifactRemoved()
{
2024-06-23 22:48:19 +02:00
for(const auto & artWin : GH.windows().findWindows<CWindowWithArtifacts>())
2024-06-22 18:29:39 +02:00
artWin->update();
LOCPLINT->waitWhileDialog();
}
void ArtifactsUIController::artifactMoved()
{
// If a bulk transfer has arrived, then redrawing only the last art movement.
if(numOfMovedArts != 0)
numOfMovedArts--;
2024-06-23 22:48:19 +02:00
if(numOfMovedArts == 0)
for(const auto & artWin : GH.windows().findWindows<CWindowWithArtifacts>())
2024-06-22 18:29:39 +02:00
{
artWin->update();
}
LOCPLINT->waitWhileDialog();
}
2024-06-23 22:48:19 +02:00
void ArtifactsUIController::bulkArtMovementStart(size_t totalNumOfArts, size_t possibleAssemblyNumOfArts)
2024-06-22 18:29:39 +02:00
{
2024-06-23 22:48:19 +02:00
assert(totalNumOfArts >= possibleAssemblyNumOfArts);
numOfMovedArts = totalNumOfArts;
2024-06-22 18:29:39 +02:00
if(numOfArtsAskAssembleSession == 0)
{
// Do not start the next session until the previous one is finished
2024-06-23 22:48:19 +02:00
numOfArtsAskAssembleSession = possibleAssemblyNumOfArts;
2024-06-22 18:29:39 +02:00
ignoredArtifacts.clear();
}
}
void ArtifactsUIController::artifactAssembled()
{
2024-06-23 22:48:19 +02:00
for(const auto & artWin : GH.windows().findWindows<CWindowWithArtifacts>())
2024-06-22 18:29:39 +02:00
artWin->update();
}
void ArtifactsUIController::artifactDisassembled()
{
2024-06-23 22:48:19 +02:00
for(const auto & artWin : GH.windows().findWindows<CWindowWithArtifacts>())
2024-06-22 18:29:39 +02:00
artWin->update();
}