mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-28 08:48:48 +02:00
Locks for combination artifacts largely implemented, only one or two bugs when moving them around in a certain way. Artifact assembly still remaining.
To make sure these artifacts get (un)equipped properly the functions CArtHandler::equipArtifact and CArtHandler::unequipArtifact should be used instead of modifying artifWorn manually.
This commit is contained in:
parent
28f8ef3b0f
commit
790a77c280
@ -257,7 +257,9 @@ void CHeroWindow::setHero(const CGHeroInstance *hero)
|
||||
sprintf(bufor, CGI->generaltexth->allTexts[205].c_str(), hero->name.c_str(), hero->mana, hero->manaLimit());
|
||||
spellPointsArea->text = std::string(bufor);
|
||||
|
||||
artifs->updateState = true;
|
||||
artifs->setHero(hero);
|
||||
artifs->updateState = false;
|
||||
|
||||
//if we have exchange window with this hero open
|
||||
bool noDismiss=false;
|
||||
|
@ -853,7 +853,9 @@ void CPlayerInterface::heroArtifactSetChanged(const CGHeroInstance*hero)
|
||||
{
|
||||
if(cew->heroInst[g] == hero)
|
||||
{
|
||||
cew->artifs[g]->updateState = true;
|
||||
cew->artifs[g]->setHero(hero);
|
||||
cew->artifs[g]->updateState = false;
|
||||
}
|
||||
}
|
||||
cew->prepareBackground();
|
||||
|
@ -3657,9 +3657,20 @@ void CArtPlace::clickLeft(tribool down, bool previousState)
|
||||
ourOwner->commonInfo->destSlotID = slotID;
|
||||
ourOwner->commonInfo->destArtifact = ourArt;
|
||||
|
||||
// Special case when the dest artifact can't be fit into the src slot.
|
||||
CGHeroInstance *destHero = const_cast<CGHeroInstance *>(ourOwner->curHero);
|
||||
CGI->arth->unequipArtifact(destHero->artifWorn, slotID);
|
||||
const CArtifactsOfHero* srcAOH = ourOwner->commonInfo->srcAOH;
|
||||
ui16 srcSlotID = ourOwner->commonInfo->srcSlotID;
|
||||
if (ourArt && srcSlotID < 19 && !ourArt->fitsAt(srcAOH->curHero->artifWorn, srcSlotID)) {
|
||||
// Put dest artifact into owner's backpack.
|
||||
ourOwner->commonInfo->srcAOH = ourOwner;
|
||||
ourOwner->commonInfo->srcSlotID = ourOwner->curHero->artifacts.size() + 19;
|
||||
}
|
||||
|
||||
LOCPLINT->cb->swapArtifacts(
|
||||
ourOwner->commonInfo->srcAOH->curHero,
|
||||
ourOwner->commonInfo->srcSlotID,
|
||||
srcAOH->curHero,
|
||||
srcSlotID,
|
||||
ourOwner->curHero,
|
||||
slotID);
|
||||
}
|
||||
@ -3676,7 +3687,7 @@ void CArtPlace::clickLeft(tribool down, bool previousState)
|
||||
|
||||
void CArtPlace::clickRight(tribool down, bool previousState)
|
||||
{
|
||||
if(text.size()) //if there is no description, do nothing ;]
|
||||
if(!locked() && text.size()) //if there is no description or it's a lock, do nothing ;]
|
||||
LRClickableAreaWTextComp::clickRight(down, previousState);
|
||||
}
|
||||
|
||||
@ -3685,8 +3696,10 @@ void CArtPlace::clickRight(tribool down, bool previousState)
|
||||
*/
|
||||
void CArtPlace::select ()
|
||||
{
|
||||
if (locked())
|
||||
return;
|
||||
|
||||
CGI->curh->dragAndDropCursor(graphics->artDefs->ourImages[ourArt->id].bitmap);
|
||||
ourOwner->markPossibleSlots(ourArt);
|
||||
|
||||
ourOwner->commonInfo->srcArtifact = ourArt;
|
||||
ourOwner->commonInfo->srcSlotID = slotID;
|
||||
@ -3695,9 +3708,10 @@ void CArtPlace::select ()
|
||||
// Temporarily remove artifact from hero.
|
||||
CGHeroInstance* hero = const_cast<CGHeroInstance*>(ourOwner->curHero);
|
||||
if (slotID < 19)
|
||||
hero->artifWorn.erase(slotID);
|
||||
CGI->arth->unequipArtifact(hero->artifWorn, slotID);
|
||||
else
|
||||
hero->artifacts.erase(hero->artifacts.begin() + (slotID - 19));
|
||||
ourOwner->markPossibleSlots(ourArt);
|
||||
hero->recreateArtBonuses();
|
||||
|
||||
// Update the hero bonuses.
|
||||
@ -3776,14 +3790,10 @@ bool CArtPlace::fitsHere(const CArtifact * art)
|
||||
return true;
|
||||
|
||||
// Anything can but War Machines can be placed in backpack.
|
||||
if (slotID >= 19) {
|
||||
if (slotID >= 19)
|
||||
return !CGI->arth->isBigArtifact(art->id);
|
||||
} else if (vstd::contains(art->possibleSlots, slotID)) {
|
||||
// TODO: Deal with combinational at dest and as src.
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return art->fitsAt(ourOwner->curHero->artifWorn, slotID);
|
||||
}
|
||||
|
||||
CArtPlace::~CArtPlace()
|
||||
@ -3988,21 +3998,20 @@ void CArtifactsOfHero::setHero(const CGHeroInstance * hero)
|
||||
backpackPos++;
|
||||
}
|
||||
|
||||
if (commonInfo->srcAOH == this) {
|
||||
if (updateState && commonInfo->srcAOH == this) {
|
||||
curHero = hero;
|
||||
// A swap was made, make the replaced artifact the current selected.
|
||||
if (commonInfo->destSlotID < 19 && commonInfo->destArtifact) {
|
||||
// Temporarily remove artifact from hero.
|
||||
CGHeroInstance * hero = const_cast<CGHeroInstance *>(curHero);
|
||||
CGHeroInstance * nonconstCurHero = const_cast<CGHeroInstance *>(curHero);
|
||||
if (commonInfo->srcSlotID < 19)
|
||||
hero->artifWorn.erase(commonInfo->srcSlotID);
|
||||
CGI->arth->unequipArtifact(nonconstCurHero->artifWorn, commonInfo->srcSlotID);
|
||||
else
|
||||
hero->artifacts.erase(hero->artifacts.begin() + (commonInfo->srcSlotID - 19));
|
||||
hero->recreateArtBonuses();
|
||||
nonconstCurHero->artifacts.erase(nonconstCurHero->artifacts.begin() + (commonInfo->srcSlotID - 19));
|
||||
nonconstCurHero->recreateArtBonuses();
|
||||
|
||||
// Source <- Dest
|
||||
//commonInfo->srcAOH = commonInfo->destAOH;
|
||||
commonInfo->srcArtifact = commonInfo->destArtifact;
|
||||
//commonInfo->srcSlotID = commonInfo->destSlotID;
|
||||
|
||||
// Reset destination parameters.
|
||||
commonInfo->destAOH = NULL;
|
||||
@ -4059,7 +4068,7 @@ void CArtifactsOfHero::rollback()
|
||||
if (commonInfo->srcSlotID != -1) {
|
||||
// Put a held artifact back to it's spot.
|
||||
if (commonInfo->srcSlotID < 19)
|
||||
hero->artifWorn[commonInfo->srcSlotID] = commonInfo->srcArtifact->id;
|
||||
CGI->arth->equipArtifact(hero->artifWorn, commonInfo->srcSlotID, commonInfo->srcArtifact->id);
|
||||
else
|
||||
hero->artifacts.insert(hero->artifacts.begin() + (commonInfo->srcSlotID - 19), commonInfo->srcArtifact->id);
|
||||
} else { // Held swapped artifact.
|
||||
@ -4069,7 +4078,7 @@ void CArtifactsOfHero::rollback()
|
||||
if (artWorn[i]->fitsHere(commonInfo->srcArtifact)
|
||||
&& curHero->artifWorn.find(i) == curHero->artifWorn.end())
|
||||
{
|
||||
hero->artifWorn[i] = commonInfo->srcArtifact->id;
|
||||
CGI->arth->equipArtifact(hero->artifWorn, i, commonInfo->srcArtifact->id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -4137,6 +4146,8 @@ void CArtifactsOfHero::markPossibleSlots (const CArtifact* art)
|
||||
for (int i = 0; i < (*it)->artWorn.size(); i++) {
|
||||
if ((*it)->artWorn[i]->fitsHere(art))
|
||||
(*it)->artWorn[i]->marked = true;
|
||||
else
|
||||
(*it)->artWorn[i]->marked = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4166,7 +4177,10 @@ void CArtifactsOfHero::setSlotData (CArtPlace* artPlace, int slotID)
|
||||
|
||||
if (artPlace->ourArt) {
|
||||
artPlace->text = artPlace->ourArt->Description();
|
||||
artPlace->hoverText = boost::str(boost::format(CGI->generaltexth->heroscrn[1].c_str()) % artPlace->ourArt->Name().c_str());
|
||||
if (artPlace->locked()) // Locks should appear as empty.
|
||||
artPlace->hoverText = CGI->generaltexth->allTexts[507];
|
||||
else
|
||||
artPlace->hoverText = boost::str(boost::format(CGI->generaltexth->heroscrn[1].c_str()) % artPlace->ourArt->Name().c_str());
|
||||
} else {
|
||||
eraseSlotData(artPlace, slotID);
|
||||
}
|
||||
@ -4184,7 +4198,7 @@ void CArtifactsOfHero::eraseSlotData (CArtPlace* artPlace, int slotID)
|
||||
}
|
||||
|
||||
CArtifactsOfHero::CArtifactsOfHero(const SDL_Rect & position) :
|
||||
backpackPos(0)
|
||||
backpackPos(0), updateState(false)
|
||||
{
|
||||
pos = position;
|
||||
artWorn.resize(19);
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define __GUICLASSES_H__
|
||||
|
||||
#include "../global.h"
|
||||
#include "../hch/CArtHandler.h"
|
||||
#include "SDL_framerate.h"
|
||||
#include "GUIBase.h"
|
||||
#include "FunctionList.h"
|
||||
@ -691,10 +692,15 @@ public:
|
||||
void activate();
|
||||
void deactivate();
|
||||
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;
|
||||
~CArtPlace(); //d-tor
|
||||
};
|
||||
|
||||
inline bool CArtPlace::locked () const
|
||||
{
|
||||
return ourArt && ourArt->id == 145;
|
||||
}
|
||||
|
||||
class CArtifactsOfHero : public CIntObject
|
||||
{
|
||||
@ -702,7 +708,7 @@ class CArtifactsOfHero : public CIntObject
|
||||
|
||||
std::vector<CArtPlace *> artWorn; // 0 - head; 1 - shoulders; 2 - neck; 3 - right hand; 4 - left hand; 5 - torso; 6 - right ring; 7 - left ring; 8 - feet; 9 - misc1; 10 - misc2; 11 - misc3; 12 - misc4; 13 - mach1; 14 - mach2; 15 - mach3; 16 - mach4; 17 - spellbook; 18 - misc5
|
||||
std::vector<CArtPlace *> backpack; //hero's visible backpack (only 5 elements!)
|
||||
int backpackPos; //unmber of first art visible in backpack (in hero's vector)
|
||||
int backpackPos; //number of first art visible in backpack (in hero's vector)
|
||||
|
||||
public:
|
||||
struct SCommonPart
|
||||
@ -716,6 +722,8 @@ public:
|
||||
const CArtifact * destArtifact; // For swapping.
|
||||
} * commonInfo; //when we have more than one CArtifactsOfHero in one window with exchange possibility, we use this (eg. in exchange window); to be provided externally
|
||||
|
||||
bool updateState; // Whether the commonInfo should be updated on setHero or not.
|
||||
|
||||
AdventureMapButton * leftArtRoll, * rightArtRoll;
|
||||
|
||||
void activate();
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <boost/assign/std/vector.hpp>
|
||||
#include <boost/assign/list_of.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include "../lib/VCMI_Lib.h"
|
||||
extern CLodHandler *bitmaph;
|
||||
using namespace boost::assign;
|
||||
@ -36,11 +37,69 @@ const std::string & CArtifact::Description() const
|
||||
return VLC->generaltexth->artifDescriptions[id];
|
||||
}
|
||||
|
||||
bool CArtifact::isBig () const
|
||||
inline bool CArtifact::isBig () const
|
||||
{
|
||||
return VLC->arth->isBigArtifact(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the artifact fits at a given slot.
|
||||
* @param artifWorn A hero's set of worn artifacts.
|
||||
*/
|
||||
bool CArtifact::fitsAt (const std::map<ui16, ui32> &artifWorn, ui16 slotID) const
|
||||
{
|
||||
if (!vstd::contains(possibleSlots, slotID))
|
||||
return false;
|
||||
|
||||
// Can't put an artifact in a locked slot.
|
||||
std::map<ui16, ui32>::const_iterator it = artifWorn.find(slotID);
|
||||
if (it != artifWorn.end() && it->second == 145)
|
||||
return false;
|
||||
|
||||
// Check if a combination artifact fits.
|
||||
// TODO: Might want a more general algorithm?
|
||||
// Assumes that misc & rings fits only in their slots, and others in only one slot and no duplicates.
|
||||
if (constituents != NULL) {
|
||||
std::map<ui16, ui32> tempArtifWorn = artifWorn;
|
||||
const ui16 ringSlots[] = {6, 7};
|
||||
const ui16 miscSlots[] = {9, 10, 11, 12, 18};
|
||||
int rings = 0;
|
||||
int misc = 0;
|
||||
|
||||
VLC->arth->unequipArtifact(tempArtifWorn, slotID);
|
||||
|
||||
BOOST_FOREACH(ui32 constituentID, *constituents) {
|
||||
const CArtifact& constituent = VLC->arth->artifacts[constituentID];
|
||||
const int slot = constituent.possibleSlots[0];
|
||||
|
||||
if (slot == 6 || slot == 7)
|
||||
rings++;
|
||||
else if (slot >= 9 && slot <= 12 || slot == 18)
|
||||
misc++;
|
||||
else if (tempArtifWorn.find(slot) != tempArtifWorn.end())
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ensure enough ring slots are free
|
||||
for (int i = 0; i < sizeof(ringSlots)/sizeof(*ringSlots); i++) {
|
||||
if (tempArtifWorn.find(ringSlots[i]) == tempArtifWorn.end() || ringSlots[i] == slotID)
|
||||
rings--;
|
||||
}
|
||||
if (rings > 0)
|
||||
return false;
|
||||
|
||||
// Ensure enough misc slots are free.
|
||||
for (int i = 0; i < sizeof(miscSlots)/sizeof(*miscSlots); i++) {
|
||||
if (tempArtifWorn.find(miscSlots[i]) == tempArtifWorn.end() || miscSlots[i] == slotID)
|
||||
misc--;
|
||||
}
|
||||
if (misc > 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CArtHandler::CArtHandler()
|
||||
{
|
||||
VLC->arth = this;
|
||||
@ -52,7 +111,7 @@ CArtHandler::CArtHandler()
|
||||
void CArtHandler::loadArtifacts(bool onlyTxt)
|
||||
{
|
||||
std::vector<ui16> slots;
|
||||
slots += 17, 16, 15,14,13, 18, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0;
|
||||
slots += 17, 16, 15, 14, 13, 18, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0;
|
||||
static std::map<char, CArtifact::EartClass> classes =
|
||||
map_list_of('S',CArtifact::ART_SPECIAL)('T',CArtifact::ART_TREASURE)('N',CArtifact::ART_MINOR)('J',CArtifact::ART_MAJOR)('R',CArtifact::ART_RELIC);
|
||||
std::string buf = bitmaph->getTextFile("ARTRAITS.TXT"), dump, pom;
|
||||
@ -85,65 +144,65 @@ void CArtHandler::loadArtifacts(bool onlyTxt)
|
||||
if(desc[0] == '\"' && desc[desc.size()-1] == '\"')
|
||||
desc = desc.substr(1,desc.size()-2);
|
||||
|
||||
// Fill in information about combined artifacts.
|
||||
// Fill in information about combined artifacts. Should perhaps be moved to a config file?
|
||||
switch (nart.id) {
|
||||
case 129: // Angelic Alliance
|
||||
nart.constituents = new std::vector<ui32>(6);
|
||||
nart.constituents = new std::vector<ui32>();
|
||||
*nart.constituents += 31, 32, 33, 34, 35, 36;
|
||||
break;
|
||||
|
||||
case 130: // Cloak of the Undead King
|
||||
nart.constituents = new std::vector<ui32>(3);
|
||||
nart.constituents = new std::vector<ui32>();
|
||||
*nart.constituents += 54, 55, 56;
|
||||
break;
|
||||
|
||||
case 131: // Elixir of Life
|
||||
nart.constituents = new std::vector<ui32>(3);
|
||||
nart.constituents = new std::vector<ui32>();
|
||||
*nart.constituents += 94, 95, 96;
|
||||
break;
|
||||
|
||||
case 132: // Armor of the Damned
|
||||
nart.constituents = new std::vector<ui32>(4);
|
||||
nart.constituents = new std::vector<ui32>();
|
||||
*nart.constituents += 8, 14, 20, 26;
|
||||
break;
|
||||
|
||||
case 133: // Statue of Legion
|
||||
nart.constituents = new std::vector<ui32>(5);
|
||||
nart.constituents = new std::vector<ui32>();
|
||||
*nart.constituents += 118, 119, 120, 121, 122;
|
||||
break;
|
||||
|
||||
case 134: // Power of the Dragon Father
|
||||
nart.constituents = new std::vector<ui32>(9);
|
||||
nart.constituents = new std::vector<ui32>();
|
||||
*nart.constituents += 37, 38, 39, 40, 41, 42, 43, 44, 45;
|
||||
break;
|
||||
|
||||
case 135: // Titan's Thunder
|
||||
nart.constituents = new std::vector<ui32>(4);
|
||||
nart.constituents = new std::vector<ui32>();
|
||||
*nart.constituents += 12, 18, 24, 30;
|
||||
break;
|
||||
|
||||
case 136: // Admiral's Hat
|
||||
nart.constituents = new std::vector<ui32>(2);
|
||||
nart.constituents = new std::vector<ui32>();
|
||||
*nart.constituents += 71, 123;
|
||||
break;
|
||||
|
||||
case 137: // Bow of the Sharpshooter
|
||||
nart.constituents = new std::vector<ui32>(3);
|
||||
nart.constituents = new std::vector<ui32>();
|
||||
*nart.constituents += 60, 61, 62;
|
||||
break;
|
||||
|
||||
case 138: // Wizards' Well
|
||||
nart.constituents = new std::vector<ui32>(3);
|
||||
nart.constituents = new std::vector<ui32>();
|
||||
*nart.constituents += 73, 74, 75;
|
||||
break;
|
||||
|
||||
case 139: // Ring of the Magi
|
||||
nart.constituents = new std::vector<ui32>(3);
|
||||
nart.constituents = new std::vector<ui32>();
|
||||
*nart.constituents += 76, 77, 78;
|
||||
break;
|
||||
|
||||
case 140: // Cornucopia
|
||||
nart.constituents = new std::vector<ui32>(4);
|
||||
nart.constituents = new std::vector<ui32>();
|
||||
*nart.constituents += 109, 110, 111, 113;
|
||||
break;
|
||||
|
||||
@ -484,4 +543,76 @@ void CArtHandler::clear()
|
||||
minors.clear();
|
||||
majors.clear();
|
||||
relics.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Locally equips an artifact to a hero's worn slots. Unequips an already present artifact.
|
||||
* Does not test if the operation is legal.
|
||||
* @param artifWorn A hero's set of worn artifacts.
|
||||
*/
|
||||
void CArtHandler::equipArtifact (std::map<ui16, ui32> &artifWorn, ui16 slotID, ui32 artifactID)
|
||||
{
|
||||
unequipArtifact(artifWorn, slotID);
|
||||
|
||||
const CArtifact &artifact = artifacts[artifactID];
|
||||
|
||||
// Add artifact.
|
||||
artifWorn[slotID] = artifactID;
|
||||
|
||||
// Add locks, in reverse order of being removed.
|
||||
if (artifact.constituents != NULL) {
|
||||
bool destConsumed = false; // Determines which constituent that will be counted for together with the artifact.
|
||||
|
||||
BOOST_FOREACH(ui32 constituentID, *artifact.constituents) {
|
||||
const CArtifact &constituent = artifacts[constituentID];
|
||||
|
||||
if (!destConsumed && vstd::contains(constituent.possibleSlots, slotID)) {
|
||||
destConsumed = true;
|
||||
} else {
|
||||
BOOST_FOREACH(ui16 slot, constituent.possibleSlots) {
|
||||
if (artifWorn.find(slot) == artifWorn.end()) {
|
||||
artifWorn[slot] = 145;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Locally unequips an artifact from a hero's worn slots.
|
||||
* Does not test if the operation is legal.
|
||||
* @param artifWorn A hero's set of worn artifacts.
|
||||
*/
|
||||
void CArtHandler::unequipArtifact (std::map<ui16, ui32> &artifWorn, ui16 slotID)
|
||||
{
|
||||
if (artifWorn.find(slotID) == artifWorn.end())
|
||||
return;
|
||||
|
||||
const CArtifact &artifact = artifacts[artifWorn[slotID]];
|
||||
|
||||
// Remove artifact, if it's not already removed.
|
||||
artifWorn.erase(slotID);
|
||||
|
||||
// Remove locks, in reverse order of being added.
|
||||
if (artifact.constituents != NULL) {
|
||||
bool destConsumed = false;
|
||||
|
||||
BOOST_FOREACH(ui32 constituentID, *artifact.constituents) {
|
||||
const CArtifact &constituent = artifacts[constituentID];
|
||||
|
||||
if (!destConsumed && vstd::contains(constituent.possibleSlots, slotID)) {
|
||||
destConsumed = true;
|
||||
} else {
|
||||
BOOST_REVERSE_FOREACH(ui16 slot, constituent.possibleSlots) {
|
||||
if (artifWorn.find(slot) != artifWorn.end() && artifWorn[slot] == 145) {
|
||||
artifWorn.erase(slot);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -26,6 +26,7 @@ public:
|
||||
const std::string &Name() const; //getter
|
||||
const std::string &Description() const; //getter
|
||||
bool isBig () const;
|
||||
bool fitsAt (const std::map<ui16, ui32> &artifWorn, ui16 slot) const;
|
||||
|
||||
ui32 price;
|
||||
std::vector<ui16> possibleSlots; //ids of slots where artifact can be placed
|
||||
@ -53,6 +54,8 @@ public:
|
||||
void addBonuses();
|
||||
void clear();
|
||||
bool isBigArtifact (ui32 artID) {return bigArtifacts.find(artID) != bigArtifacts.end();}
|
||||
void equipArtifact (std::map<ui16, ui32> &artifWorn, ui16 slotID, ui32 artifactID);
|
||||
void unequipArtifact (std::map<ui16, ui32> &artifWorn, ui16 slotID);
|
||||
static int convertMachineID(int id, bool creToArt);
|
||||
CArtHandler();
|
||||
|
||||
|
@ -704,9 +704,9 @@ void CGHeroInstance::initHero()
|
||||
|
||||
if(!vstd::contains(artifWorn, 16) && type->startingSpell >= 0) //no catapult means we haven't read pre-existant set
|
||||
{
|
||||
artifWorn[17] = 0; //give spellbook
|
||||
VLC->arth->equipArtifact(artifWorn, 17, 0); //give spellbook
|
||||
}
|
||||
artifWorn[16] = 3; //everyone has a catapult
|
||||
VLC->arth->equipArtifact(artifWorn, 16, 3); //everyone has a catapult
|
||||
|
||||
if(portrait < 0 || portrait == 255)
|
||||
portrait = subID;
|
||||
@ -754,10 +754,10 @@ void CGHeroInstance::initHero()
|
||||
switch (pom)
|
||||
{
|
||||
case 145: //catapult
|
||||
artifWorn[16] = 3;
|
||||
VLC->arth->equipArtifact(artifWorn, 16, 3);
|
||||
break;
|
||||
default:
|
||||
artifWorn[9+CArtHandler::convertMachineID(pom,true)] = CArtHandler::convertMachineID(pom,true);
|
||||
VLC->arth->equipArtifact(artifWorn, 9+CArtHandler::convertMachineID(pom,true), CArtHandler::convertMachineID(pom,true));
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
@ -1220,7 +1220,7 @@ void CGHeroInstance::giveArtifact (ui32 aid)
|
||||
if (artifact.isBig()) {
|
||||
for (std::vector<ui16>::const_iterator it = artifact.possibleSlots.begin(); it != artifact.possibleSlots.end(); ++it) {
|
||||
if (artifWorn.find(*it) == artifWorn.end()) {
|
||||
artifWorn[*it] = aid;
|
||||
VLC->arth->equipArtifact(artifWorn, *it, aid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1490,7 +1490,7 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed)
|
||||
std::vector<ui16>::iterator slot = vstd::findFirstNot(hero->artifWorn,toGive->possibleSlots);
|
||||
if(slot!=toGive->possibleSlots.end())
|
||||
{
|
||||
hero->artifWorn[*slot] = toGive->id;
|
||||
VLC->arth->equipArtifact(hero->artifWorn, *slot, toGive->id);
|
||||
hero->recreateArtBonuses();
|
||||
}
|
||||
else
|
||||
|
@ -31,7 +31,7 @@ struct DLL_EXPORT HeroBonus
|
||||
NONEVIL_ALIGNMENT_MIX, //good and neutral creatures can be mixed without morale penalty
|
||||
HP_REGENERATION, //regenerates a certain amount of hp for the top of each stack every turn, val - hp regained
|
||||
LEVEL_SPELL_IMMUNITY, //val - spell level creatures become immune to and below
|
||||
//not handled yet:
|
||||
//might not be handled yet:
|
||||
MAGIC_RESISTANCE, // %
|
||||
SECONDARY_SKILL_PREMY, //%
|
||||
SURRENDER_DISCOUNT, //%
|
||||
|
@ -464,14 +464,14 @@ DLL_EXPORT void SetHeroArtifacts::setArtAtPos(ui16 pos, int art)
|
||||
if(art<0)
|
||||
{
|
||||
if(pos<19)
|
||||
artifWorn.erase(pos);
|
||||
VLC->arth->unequipArtifact(artifWorn, pos);
|
||||
else
|
||||
artifacts.erase(artifacts.begin() + (pos - 19));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pos < 19) {
|
||||
artifWorn[pos] = art;
|
||||
VLC->arth->equipArtifact(artifWorn, pos, (ui32) art);
|
||||
} else { // Goes into the backpack.
|
||||
if(pos - 19 < artifacts.size())
|
||||
artifacts.insert(artifacts.begin() + (pos - 19), art);
|
||||
|
16
lib/map.cpp
16
lib/map.cpp
@ -964,27 +964,27 @@ void Mapa::loadHero( CGObjectInstance * &nobj, const unsigned char * bufor, int
|
||||
{
|
||||
int id = readNormalNr(bufor,i, artidlen); i+=artidlen;
|
||||
if(id!=artmask)
|
||||
nhi->artifWorn[pom] = id;
|
||||
VLC->arth->equipArtifact(nhi->artifWorn, pom, id);
|
||||
}
|
||||
//misc5 art //17
|
||||
if(version>=SoD)
|
||||
{
|
||||
int id = readNormalNr(bufor,i, artidlen); i+=artidlen;
|
||||
if(id!=artmask)
|
||||
nhi->artifWorn[16] = id;
|
||||
VLC->arth->equipArtifact(nhi->artifWorn, 16, id);
|
||||
else
|
||||
nhi->artifWorn[16] = 3; //catapult by default
|
||||
VLC->arth->equipArtifact(nhi->artifWorn, 16, 3); //catapult by default
|
||||
}
|
||||
//spellbook
|
||||
int id = readNormalNr(bufor,i, artidlen); i+=artidlen;
|
||||
if(id!=artmask)
|
||||
nhi->artifWorn[17] = id;
|
||||
VLC->arth->equipArtifact(nhi->artifWorn, 17, id);
|
||||
//19 //???what is that? gap in file or what? - it's probably fifth slot..
|
||||
if(version>RoE)
|
||||
{
|
||||
id = readNormalNr(bufor,i, artidlen); i+=artidlen;
|
||||
if(id!=artmask)
|
||||
nhi->artifWorn[18] = id;
|
||||
VLC->arth->equipArtifact(nhi->artifWorn, 18, id);
|
||||
}
|
||||
else
|
||||
i+=1;
|
||||
@ -1204,7 +1204,7 @@ void Mapa::readPredefinedHeroes( const unsigned char * bufor, int &i)
|
||||
{
|
||||
int id = readNormalNr(bufor,i, artidlen); i+=artidlen;
|
||||
if(id!=artmask)
|
||||
cgh->artifWorn[pom] = id;
|
||||
VLC->arth->equipArtifact(cgh->artifWorn, pom, id);
|
||||
}
|
||||
//misc5 art //17
|
||||
if(version>=SoD)
|
||||
@ -1217,13 +1217,13 @@ void Mapa::readPredefinedHeroes( const unsigned char * bufor, int &i)
|
||||
//spellbook
|
||||
int id = readNormalNr(bufor,i, artidlen); i+=artidlen;
|
||||
if(id!=artmask)
|
||||
cgh->artifWorn[17] = id;
|
||||
VLC->arth->equipArtifact(cgh->artifWorn, 17, id);
|
||||
//19 //???what is that? gap in file or what? - it's probably fifth slot..
|
||||
if(version>RoE)
|
||||
{
|
||||
id = readNormalNr(bufor,i, artidlen); i+=artidlen;
|
||||
if(id!=artmask)
|
||||
cgh->artifWorn[18] = id;
|
||||
VLC->arth->equipArtifact(cgh->artifWorn, 18, id);
|
||||
}
|
||||
else
|
||||
i+=1;
|
||||
|
@ -1806,7 +1806,7 @@ void CGameHandler::giveHeroArtifact(int artid, int hid, int position) //pos==-1
|
||||
if( !vstd::contains(sha.artifWorn,art.possibleSlots[i]) )
|
||||
{
|
||||
//we've found a free suitable slot
|
||||
sha.artifWorn[art.possibleSlots[i]] = artid;
|
||||
VLC->arth->equipArtifact(sha.artifWorn, art.possibleSlots[i], artid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1822,7 +1822,7 @@ void CGameHandler::giveHeroArtifact(int artid, int hid, int position) //pos==-1
|
||||
{
|
||||
if(!vstd::contains(sha.artifWorn,ui16(position)))
|
||||
{
|
||||
sha.artifWorn[position] = artid;
|
||||
VLC->arth->equipArtifact(sha.artifWorn, position, artid);
|
||||
}
|
||||
else if (!art.isBig())
|
||||
{
|
||||
@ -1850,7 +1850,7 @@ void CGameHandler::removeArtifact(int artid, int hid)
|
||||
{
|
||||
if (itr->second == artid)
|
||||
{
|
||||
sha.artifWorn.erase(itr);
|
||||
VLC->arth->unequipArtifact(sha.artifWorn, itr->first);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2536,6 +2536,7 @@ bool CGameHandler::garrisonSwap( si32 tid )
|
||||
}
|
||||
}
|
||||
|
||||
// With the amount of changes done to the function, it's more like transferArtifacts.
|
||||
bool CGameHandler::swapArtifacts(si32 srcHeroID, si32 destHeroID, ui16 srcSlot, ui16 destSlot)
|
||||
{
|
||||
CGHeroInstance *srcHero = gs->getHero(srcHeroID);
|
||||
@ -2545,19 +2546,35 @@ bool CGameHandler::swapArtifacts(si32 srcHeroID, si32 destHeroID, ui16 srcSlot,
|
||||
if ((distance(srcHero->pos,destHero->pos) > 1.5 )|| (srcHero->tempOwner != destHero->tempOwner))
|
||||
return false;
|
||||
|
||||
const CArtifact *srcArtifact = srcHero->getArt(srcSlot);
|
||||
const CArtifact *srcArtifact = srcHero->getArt(srcSlot);
|
||||
const CArtifact *destArtifact = destHero->getArt(destSlot);
|
||||
|
||||
SetHeroArtifacts sha;
|
||||
sha.hid = srcHeroID;
|
||||
sha.artifacts = srcHero->artifacts;
|
||||
sha.artifWorn = srcHero->artifWorn;
|
||||
|
||||
// Combinational artifacts needs to be removed first so they don't get denied movement because of their own locks.
|
||||
if (srcHeroID == destHeroID && srcSlot < 19) {
|
||||
VLC->arth->unequipArtifact(sha.artifWorn, srcSlot);
|
||||
if (sha.artifWorn.find(destSlot) == sha.artifWorn.end())
|
||||
destArtifact = NULL;
|
||||
}
|
||||
|
||||
// Check if src/dest slots are appropriate for the artifacts exchanged.
|
||||
// Moving to the backpack is always allowed.
|
||||
if ((!srcArtifact || destSlot < 19)
|
||||
&& (((srcArtifact && !vstd::contains(srcArtifact->possibleSlots, destSlot))
|
||||
|| (destArtifact && srcSlot < 19 && !vstd::contains(destArtifact->possibleSlots, srcSlot)))))
|
||||
&& (srcArtifact && !srcArtifact->fitsAt(srcHeroID == destHeroID ? sha.artifWorn : destHero->artifWorn, destSlot)))
|
||||
{
|
||||
complain("Cannot swap artifacts!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((srcArtifact && srcArtifact->id == 145) || (destArtifact && destArtifact->id == 145)) {
|
||||
complain("Cannot move artifact locks.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (destSlot >= 19 && srcArtifact->isBig()) {
|
||||
complain("Cannot put big artifacts in backpack!");
|
||||
return false;
|
||||
@ -2568,14 +2585,11 @@ bool CGameHandler::swapArtifacts(si32 srcHeroID, si32 destHeroID, ui16 srcSlot,
|
||||
return false;
|
||||
}
|
||||
|
||||
// Perform the exchange.
|
||||
SetHeroArtifacts sha;
|
||||
sha.hid = srcHeroID;
|
||||
sha.artifacts = srcHero->artifacts;
|
||||
sha.artifWorn = srcHero->artifWorn;
|
||||
// If dest does not fit in src, put it in dest's backpack instead.
|
||||
bool destFits = !destArtifact || srcSlot >= 19 || destArtifact->fitsAt(sha.artifWorn, srcSlot);
|
||||
|
||||
sha.setArtAtPos(srcSlot, -1);
|
||||
if (destSlot < 19 && (destArtifact || srcSlot < 19))
|
||||
if (destSlot < 19 && (destArtifact || srcSlot < 19) && destFits)
|
||||
sha.setArtAtPos(srcSlot, destHero->getArtAtPos(destSlot));
|
||||
|
||||
// Internal hero artifact arrangement.
|
||||
@ -2593,6 +2607,8 @@ bool CGameHandler::swapArtifacts(si32 srcHeroID, si32 destHeroID, ui16 srcSlot,
|
||||
sha.artifacts = destHero->artifacts;
|
||||
sha.artifWorn = destHero->artifWorn;
|
||||
sha.setArtAtPos(destSlot, srcArtifact ? srcArtifact->id : -1);
|
||||
if (!destFits)
|
||||
sha.setArtAtPos(sha.artifacts.size() + 19, destHero->getArtAtPos(destSlot));
|
||||
sendAndApply(&sha);
|
||||
}
|
||||
|
||||
@ -3026,7 +3042,7 @@ void CGameHandler::playerMessage( ui8 player, const std::string &message )
|
||||
sha.hid = h->id;
|
||||
sha.artifacts = h->artifacts;
|
||||
sha.artifWorn = h->artifWorn;
|
||||
sha.artifWorn[17] = 0;
|
||||
VLC->arth->equipArtifact(sha.artifWorn, 17, 0);
|
||||
sendAndApply(&sha);
|
||||
}
|
||||
|
||||
@ -3063,9 +3079,9 @@ void CGameHandler::playerMessage( ui8 player, const std::string &message )
|
||||
sha.hid = hero->id;
|
||||
sha.artifacts = hero->artifacts;
|
||||
sha.artifWorn = hero->artifWorn;
|
||||
sha.artifWorn[13] = 4;
|
||||
sha.artifWorn[14] = 5;
|
||||
sha.artifWorn[15] = 6;
|
||||
VLC->arth->equipArtifact(sha.artifWorn, 13, 4);
|
||||
VLC->arth->equipArtifact(sha.artifWorn, 14, 5);
|
||||
VLC->arth->equipArtifact(sha.artifWorn, 15, 6);
|
||||
sendAndApply(&sha);
|
||||
}
|
||||
else if(message == "vcminahar") //1000000 movement points
|
||||
|
Loading…
Reference in New Issue
Block a user