1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
|
/*
* 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"
#include "../lib/mapObjects/CGHeroInstance.h"
#include "gui/CGuiHandler.h"
#include "gui/WindowHandler.h"
#include "widgets/CComponent.h"
#include "windows/CWindowWithArtifacts.h"
ArtifactsUIController::ArtifactsUIController()
{
numOfMovedArts = 0;
numOfArtsAskAssembleSession = 0;
}
bool ArtifactsUIController::askToAssemble(const ArtifactLocation & al, const bool onlyEquipped, const bool checkIgnored)
{
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;
}
return askToAssemble(hero, al.slot, onlyEquipped, checkIgnored);
}
return false;
}
bool ArtifactsUIController::askToAssemble(const CGHeroInstance * hero, const ArtifactPosition & slot,
const bool onlyEquipped, const bool checkIgnored)
{
assert(hero);
const auto art = hero->getArt(slot);
assert(art);
if(hero->tempOwner != LOCPLINT->playerID)
return false;
if(numOfArtsAskAssembleSession != 0)
numOfArtsAskAssembleSession--;
auto assemblyPossibilities = ArtifactUtils::assemblyPossibilities(hero, art->getTypeId(), onlyEquipped);
if(!assemblyPossibilities.empty())
{
auto askThread = new boost::thread([this, hero, art, slot, assemblyPossibilities, checkIgnored]() -> void
{
boost::mutex::scoped_lock askLock(askAssembleArtifactMutex);
for(const auto combinedArt : assemblyPossibilities)
{
boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
if(checkIgnored)
{
if(vstd::contains(ignoredArtifacts, combinedArt->getId()))
continue;
ignoredArtifacts.emplace(combinedArt->getId());
}
bool assembleConfirmed = false;
MetaString message = MetaString::createFromTextID(art->getType()->getDescriptionTextID());
message.appendEOL();
message.appendEOL();
if(combinedArt->isFused())
message.appendRawString(CGI->generaltexth->translate("vcmi.heroWindow.fusingArtifact.fusing"));
else
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->id, slot, true, combinedArt->getId());
}, 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->hasParts())
{
if(ArtifactUtils::isSlotBackpack(slot) && !ArtifactUtils::isBackpackFreeSlots(hero, art->getType()->getConstituents().size() - 1))
return false;
MetaString message = MetaString::createFromTextID(art->getType()->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->id, slot, false, ArtifactID());
}, nullptr);
return true;
}
return false;
}
void ArtifactsUIController::artifactRemoved()
{
for(const 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--;
if(numOfMovedArts == 0)
for(const auto & artWin : GH.windows().findWindows<CWindowWithArtifacts>())
{
artWin->update();
}
LOCPLINT->waitWhileDialog();
}
void ArtifactsUIController::bulkArtMovementStart(size_t totalNumOfArts, size_t possibleAssemblyNumOfArts)
{
assert(totalNumOfArts >= possibleAssemblyNumOfArts);
numOfMovedArts = totalNumOfArts;
if(numOfArtsAskAssembleSession == 0)
{
// Do not start the next session until the previous one is finished
numOfArtsAskAssembleSession = possibleAssemblyNumOfArts;
ignoredArtifacts.clear();
}
}
void ArtifactsUIController::artifactAssembled()
{
for(const auto & artWin : GH.windows().findWindows<CWindowWithArtifacts>())
artWin->update();
}
void ArtifactsUIController::artifactDisassembled()
{
for(const auto & artWin : GH.windows().findWindows<CWindowWithArtifacts>())
artWin->update();
}
|