1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

It's now possible to assemble and disassemble artifacts.

There is some strange behavior when right-clicking on the artifact screen outside the slots though, all slots then get  right-click handling and display the assembly dialog for whatever it finds.
This commit is contained in:
OnionKnight 2010-02-27 01:05:39 +00:00
parent 4171a1959f
commit ad3371b4c0
5 changed files with 85 additions and 12 deletions

View File

@ -32,6 +32,7 @@
#include "../mapHandler.h" #include "../mapHandler.h"
#include "../timeHandler.h" #include "../timeHandler.h"
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <boost/format.hpp>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/replace.hpp> #include <boost/algorithm/string/replace.hpp>
#include <boost/assign/std/vector.hpp> #include <boost/assign/std/vector.hpp>
@ -1098,6 +1099,43 @@ void CPlayerInterface::showGarrisonDialog( const CArmedInstance *up, const CGHer
GH.pushInt(cgw); GH.pushInt(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.
* @param artifactID ID of a constituent artifact.
* @param assembleTo ID of artifact to assemble a constituent into, not used when assemble
* is false.
* @param assemble True if the artifact is to be assembled, false if it is to be disassembled.
*/
void CPlayerInterface::showArtifactAssemblyDialog (ui32 artifactID, ui32 assembleTo, bool assemble, CFunctionList<void()> onYes, CFunctionList<void()> onNo)
{
const CArtifact &artifact = CGI->arth->artifacts[artifactID];
std::string text = artifact.Description();
text += "\n\n";
std::vector<SComponent*> scs;
if (assemble) {
const CArtifact &assembledArtifact = CGI->arth->artifacts[assembleTo];
// You possess all of the components to...
text += boost::str(boost::format(CGI->generaltexth->allTexts[732]) % assembledArtifact.Name());
// Picture of assembled artifact at bottom.
SComponent* sc = new SComponent;
sc->type = SComponent::Etype::artifact;
sc->subtype = assembledArtifact.id;
sc->description = assembledArtifact.Description();
sc->subtitle = assembledArtifact.Name();
scs.push_back(sc);
} else {
// Do you wish to disassemble this artifact?
text += CGI->generaltexth->allTexts[733];
}
showYesNoDialog(text, scs, onYes, onNo, true);
}
void CPlayerInterface::requestRealized( PackageApplied *pa ) void CPlayerInterface::requestRealized( PackageApplied *pa )
{ {
if(stillMoveHero.get() == DURING_MOVE) if(stillMoveHero.get() == DURING_MOVE)

View File

@ -159,6 +159,7 @@ public:
void showShipyardDialog(const IShipyard *obj); //obj may be town or shipyard; void showShipyardDialog(const IShipyard *obj); //obj may be town or shipyard;
void showBlockingDialog(const std::string &text, const std::vector<Component> &components, ui32 askID, int soundID, bool selection, bool cancel); //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 showBlockingDialog(const std::string &text, const std::vector<Component> &components, ui32 askID, int soundID, bool selection, bool cancel); //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 showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, boost::function<void()> &onEnd); void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, boost::function<void()> &onEnd);
void showArtifactAssemblyDialog(ui32 artifactID, ui32 assembleTo, bool assemble, CFunctionList<void()> onYes, CFunctionList<void()> onNo);
void showPuzzleMap(); void showPuzzleMap();
void tileHidden(const std::set<int3> &pos); //called when given tiles become hidden under fog of war void tileHidden(const std::set<int3> &pos); //called when given tiles become hidden under fog of war
void tileRevealed(const std::set<int3> &pos); //called when fog of war disappears from given tiles void tileRevealed(const std::set<int3> &pos); //called when fog of war disappears from given tiles

View File

@ -3692,24 +3692,51 @@ void CArtPlace::clickLeft(tribool down, bool previousState)
void CArtPlace::clickRight(tribool down, bool previousState) void CArtPlace::clickRight(tribool down, bool previousState)
{ {
if(ourArt && !locked() && text.size()) { //if there is no description or it's a lock, do nothing ;] if(ourArt && !locked() && text.size()) { //if there is no description or it's a lock, do nothing ;]
LRClickableAreaWTextComp::clickRight(down, previousState); if (slotID < 19) {
selectedNo = false;
/*if (ourArt->constituentOf != NULL) { // If the artifact can be assembled, display dialog.
BOOST_FOREACH(ui32 combination, *ourArt->constituentOf) { if (ourArt->constituentOf != NULL) {
if (ourArt->canBeAssembledTo(ourOwner->curHero->artifWorn, combination)) { BOOST_FOREACH(ui32 combination, *ourArt->constituentOf) {
LOCPLINT->cb->assembleArtifacts(ourOwner->curHero, slotID, true, combination); if (ourArt->canBeAssembledTo(ourOwner->curHero->artifWorn, combination)) {
return; LOCPLINT->showArtifactAssemblyDialog(
ourArt->id,
combination,
true,
boost::bind(&CCallback::assembleArtifacts, LOCPLINT->cb, ourOwner->curHero, slotID, true, combination),
boost::bind(&CArtPlace::userSelectedNo, this));
if (!selectedNo)
return;
}
} }
} }
// Otherwise if the artifact can be diasassembled, display dialog.
if (ourArt->constituents != NULL) {
LOCPLINT->showArtifactAssemblyDialog(
ourArt->id,
0,
false,
boost::bind(&CCallback::assembleArtifacts, LOCPLINT->cb, ourOwner->curHero, slotID, false, 0),
boost::bind(&CArtPlace::userSelectedNo, this));
if (!selectedNo)
return;
}
} }
if (ourArt->constituents != NULL) { // Lastly just show the artifact description.
LOCPLINT->cb->assembleArtifacts(ourOwner->curHero, slotID, false, 0); LRClickableAreaWTextComp::clickRight(down, previousState);
return;
}*/
} }
} }
/**
* Helper function to catch when a user selects no in an artifact assembly dialog.
*/
void CArtPlace::userSelectedNo ()
{
selectedNo = true;
}
/** /**
* Selects artifact slot so that the containing artifact looks like it's picked up. * Selects artifact slot so that the containing artifact looks like it's picked up.
*/ */

View File

@ -749,6 +749,7 @@ public:
ui16 slotID; //0 head 1 shoulders 2 neck 3 right hand 4 left hand 5 torso 6 right ring 7 left ring 8 feet 9 misc. slot 1 10 misc. slot 2 11 misc. slot 3 12 misc. slot 4 13 ballista (war machine 1) 14 ammo cart (war machine 2) 15 first aid tent (war machine 3) 16 catapult 17 spell book 18 misc. slot 5 19+ backpack slots ui16 slotID; //0 head 1 shoulders 2 neck 3 right hand 4 left hand 5 torso 6 right ring 7 left ring 8 feet 9 misc. slot 1 10 misc. slot 2 11 misc. slot 3 12 misc. slot 4 13 ballista (war machine 1) 14 ammo cart (war machine 2) 15 first aid tent (war machine 3) 16 catapult 17 spell book 18 misc. slot 5 19+ backpack slots
bool marked; bool marked;
bool selectedNo;
CArtifactsOfHero * ourOwner; CArtifactsOfHero * ourOwner;
const CArtifact * ourArt; const CArtifact * ourArt;
CArtPlace(const CArtifact * Art); //c-tor CArtPlace(const CArtifact * Art); //c-tor
@ -761,6 +762,7 @@ public:
void show(SDL_Surface * to); void show(SDL_Surface * to);
bool fitsHere (const CArtifact * art); //returns true if given artifact can be placed here bool fitsHere (const CArtifact * art); //returns true if given artifact can be placed here
bool locked () const; bool locked () const;
void userSelectedNo ();
~CArtPlace(); //d-tor ~CArtPlace(); //d-tor
}; };

View File

@ -2680,7 +2680,7 @@ bool CGameHandler::assembleArtifacts (si32 heroID, ui16 artifactSlot, bool assem
sha.artifWorn = hero->artifWorn; sha.artifWorn = hero->artifWorn;
if (assemble) { if (assemble) {
if (VLC->arth->artifacts.size() >= assembleTo) { if (VLC->arth->artifacts.size() < assembleTo) {
complain("Illegal artifact to assemble to."); complain("Illegal artifact to assemble to.");
return false; return false;
} }
@ -2718,13 +2718,18 @@ bool CGameHandler::assembleArtifacts (si32 heroID, ui16 artifactSlot, bool assem
} }
} }
} else { } else {
bool destConsumed = false; // Determines which constituent that will be counted for together with the artifact.
BOOST_FOREACH(ui32 constituentID, *destArtifact->constituents) { BOOST_FOREACH(ui32 constituentID, *destArtifact->constituents) {
const CArtifact &constituent = VLC->arth->artifacts[constituentID]; const CArtifact &constituent = VLC->arth->artifacts[constituentID];
BOOST_REVERSE_FOREACH(ui16 slotID, constituent.possibleSlots) { BOOST_REVERSE_FOREACH(ui16 slotID, constituent.possibleSlots) {
if (sha.artifWorn.find(slotID) != sha.artifWorn.end()) { if (sha.artifWorn.find(slotID) != sha.artifWorn.end()) {
if (sha.artifWorn[slotID] == 145 || slotID == artifactSlot) if (sha.artifWorn[slotID] == 145 || (!destConsumed && slotID == artifactSlot)) {
if (slotID == artifactSlot)
destConsumed = true;
sha.artifWorn[slotID] = constituentID; sha.artifWorn[slotID] = constituentID;
break;
}
} }
} }
} }