1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-31 22:05:10 +02:00
Bonuses from artifacts are now inherited. Some work on artifacts set GUI. CArtifactsOfHero now operates on its own hero copy when picking artifact. Still more fixes are needed though.
This commit is contained in:
Michał W. Urbańczyk 2010-07-20 18:34:32 +00:00
parent 5dc444cd2b
commit 7ae02b7c5a
15 changed files with 180 additions and 334 deletions

View File

@ -171,10 +171,6 @@ CHeroWindow::~CHeroWindow()
delete garr; delete garr;
delete ourBar; delete ourBar;
artifs->rollback();
delete artifs->commonInfo;
artifs->commonInfo = NULL; //to prevent heap corruption
delete artifs; delete artifs;
delete portraitArea; delete portraitArea;
@ -532,7 +528,6 @@ void CHeroWindow::dispose()
curBack = NULL; curBack = NULL;
curHero = NULL; curHero = NULL;
artifs->rollback();
artifs->dispose(); artifs->dispose();
} }

View File

@ -945,10 +945,10 @@ void CPlayerInterface::openHeroWindow(const CGHeroInstance *hero)
void CPlayerInterface::heroArtifactSetChanged(const CGHeroInstance*hero) void CPlayerInterface::heroArtifactSetChanged(const CGHeroInstance*hero)
{ {
boost::unique_lock<boost::recursive_mutex> un(*pim); boost::unique_lock<boost::recursive_mutex> un(*pim);
if(adventureInt->heroWindow->curHero) //hero window is opened if(adventureInt->heroWindow->curHero && adventureInt->heroWindow->curHero->id == hero->id) //hero window is opened
{ {
adventureInt->heroWindow->deactivate(); adventureInt->heroWindow->deactivate();
adventureInt->heroWindow->setHero(adventureInt->heroWindow->curHero); adventureInt->heroWindow->setHero(hero);
adventureInt->heroWindow->activate(); adventureInt->heroWindow->activate();
return; return;
} }
@ -957,8 +957,9 @@ void CPlayerInterface::heroArtifactSetChanged(const CGHeroInstance*hero)
cew->deactivate(); cew->deactivate();
for(int g=0; g<ARRAY_COUNT(cew->heroInst); ++g) for(int g=0; g<ARRAY_COUNT(cew->heroInst); ++g)
{ {
if(cew->heroInst[g] == hero) if(cew->heroInst[g]->id == hero->id)
{ {
cew->heroInst[g] = hero;
cew->artifs[g]->updateState = true; cew->artifs[g]->updateState = true;
cew->artifs[g]->setHero(hero); cew->artifs[g]->setHero(hero);
cew->artifs[g]->updateState = false; cew->artifs[g]->updateState = false;

View File

@ -4367,10 +4367,12 @@ void CArtPlace::clickLeft(tribool down, bool previousState)
GH.pushInt(spellWindow); GH.pushInt(spellWindow);
} }
} }
if (!down && previousState) if (!down && previousState)
{ {
if(ourArt && ourArt->id == 0) if(ourArt && ourArt->id == 0)
return; //this is handled separately return; //this is handled separately
if(!ourOwner->commonInfo->srcAOH) //nothing has been clicked if(!ourOwner->commonInfo->srcAOH) //nothing has been clicked
{ {
if(ourArt) //to prevent selecting empty slots (bugfix to what GrayFace reported) if(ourArt) //to prevent selecting empty slots (bugfix to what GrayFace reported)
@ -4431,10 +4433,11 @@ void CArtPlace::clickLeft(tribool down, bool previousState)
ourOwner->commonInfo->destArtifact = ourArt; ourOwner->commonInfo->destArtifact = ourArt;
// Special case when the dest artifact can't be fit into the src slot. // Special case when the dest artifact can't be fit into the src slot.
//CGI->arth->unequipArtifact(ourOwner->curHero->artifWorn, slotID); CGI->arth->unequipArtifact(ourOwner->curHero->artifWorn, slotID);
const CArtifactsOfHero* srcAOH = ourOwner->commonInfo->srcAOH; const CArtifactsOfHero* srcAOH = ourOwner->commonInfo->srcAOH;
ui16 srcSlotID = ourOwner->commonInfo->srcSlotID; ui16 srcSlotID = ourOwner->commonInfo->srcSlotID;
if (ourArt && srcSlotID < 19 && !ourArt->fitsAt(srcAOH->curHero->artifWorn, srcSlotID)) { if (ourArt && srcSlotID < 19 && !ourArt->fitsAt(srcAOH->curHero->artifWorn, srcSlotID))
{
// Put dest artifact into owner's backpack. // Put dest artifact into owner's backpack.
ourOwner->commonInfo->srcAOH = ourOwner; ourOwner->commonInfo->srcAOH = ourOwner;
ourOwner->commonInfo->srcSlotID = ourOwner->curHero->artifacts.size() + 19; ourOwner->commonInfo->srcSlotID = ourOwner->curHero->artifacts.size() + 19;
@ -4448,19 +4451,14 @@ void CArtPlace::clickLeft(tribool down, bool previousState)
} }
} }
} }
/*else if(!down && clicked)
{
if(ourArt && ourArt->id == 0)
return; //this is handled separately
deselect();
}*/
//ClickableL::clickLeft(down);
} }
void CArtPlace::clickRight(tribool down, bool previousState) void CArtPlace::clickRight(tribool down, bool previousState)
{ {
if(down && ourArt && !locked() && text.size()) { //if there is no description or it's a lock, do nothing ;] if(down && ourArt && !locked() && text.size()) //if there is no description or it's a lock, do nothing ;]
if (slotID < 19) { {
if (slotID < 19)
{
selectedNo = false; selectedNo = false;
// If the artifact can be assembled, display dialog. // If the artifact can be assembled, display dialog.
@ -4480,7 +4478,8 @@ void CArtPlace::clickRight(tribool down, bool previousState)
} }
// Otherwise if the artifact can be diasassembled, display dialog. // Otherwise if the artifact can be diasassembled, display dialog.
if (ourArt->constituents != NULL) { if (ourArt->constituents != NULL)
{
LOCPLINT->showArtifactAssemblyDialog( LOCPLINT->showArtifactAssemblyDialog(
ourArt->id, ourArt->id,
0, 0,
@ -4522,11 +4521,11 @@ void CArtPlace::select ()
ourOwner->commonInfo->srcAOH = ourOwner; ourOwner->commonInfo->srcAOH = ourOwner;
// Temporarily remove artifact from hero. // Temporarily remove artifact from hero.
//if (slotID < 19) if (slotID < 19)
// CGI->arth->unequipArtifact(ourOwner->curHero->artifWorn, slotID); CGI->arth->unequipArtifact(ourOwner->curHero->artifWorn, slotID);
//else else
// ourOwner->curHero->artifacts.erase(ourOwner->curHero->artifacts.begin() + (slotID - 19)); ourOwner->curHero->artifacts.erase(ourOwner->curHero->artifacts.begin() + (slotID - 19));
//ourOwner->markPossibleSlots(ourArt); ourOwner->markPossibleSlots(ourArt);
//ourOwner->curHero->recreateArtBonuses(); //ourOwner->curHero->recreateArtBonuses();
// Update the hero bonuses. // Update the hero bonuses.
@ -4548,6 +4547,13 @@ void CArtPlace::select ()
cew->artifs[g]->setHero(ourOwner->curHero); cew->artifs[g]->setHero(ourOwner->curHero);
} }
} }
//use our copy of hero to draw window
if(cew->heroInst[0]->id == ourOwner->curHero->id)
cew->heroInst[0] = ourOwner->curHero;
else
cew->heroInst[1] = ourOwner->curHero;
cew->prepareBackground(); cew->prepareBackground();
cew->activate(); cew->activate();
} }
@ -4694,61 +4700,23 @@ void LRClickableAreaOpenTown::clickRight(tribool down, bool previousState)
LOCPLINT->openTownWindow(town);//TODO: popup? LOCPLINT->openTownWindow(town);//TODO: popup?
} }
void CArtifactsOfHero::activate() void CArtifactsOfHero::SCommonPart::reset()
{ {
for(size_t f=0; f<artWorn.size(); ++f) destAOH = srcAOH = NULL;
{ destArtifact = srcArtifact = NULL;
if(artWorn[f]) destSlotID = srcSlotID = -1;
artWorn[f]->activate();
}
for(size_t f=0; f<backpack.size(); ++f)
{
if(backpack[f])
backpack[f]->activate();
}
leftArtRoll->activate();
rightArtRoll->activate();
}
void CArtifactsOfHero::deactivate()
{
for(size_t f=0; f<artWorn.size(); ++f)
{
if(artWorn[f])
artWorn[f]->deactivate();
}
for(size_t f=0; f<backpack.size(); ++f)
{
if(backpack[f])
backpack[f]->deactivate();
}
leftArtRoll->deactivate();
rightArtRoll->deactivate();
}
void CArtifactsOfHero::show(SDL_Surface * to)
{
for(size_t d=0; d<artWorn.size(); ++d)
{
artWorn[d]->show(to);
}
for(size_t d=0; d<backpack.size(); ++d)
{
backpack[d]->show(to);
}
leftArtRoll->show(to);
rightArtRoll->show(to);
} }
void CArtifactsOfHero::setHero(const CGHeroInstance * hero) void CArtifactsOfHero::setHero(const CGHeroInstance * hero)
{ {
// An update is made, rather than initialization. // An update is made, rather than initialization.
if (curHero == hero) if (curHero && curHero->id == hero->id)
{ {
curHero = hero; if(curHero != hero)
{
delete curHero;
curHero = new CGHeroInstance(*hero);
}
// Compensate backpack pos if an artifact was insertad before it. // Compensate backpack pos if an artifact was insertad before it.
if (commonInfo->destSlotID >= 19 && commonInfo->destAOH == this if (commonInfo->destSlotID >= 19 && commonInfo->destAOH == this
@ -4757,14 +4725,16 @@ void CArtifactsOfHero::setHero(const CGHeroInstance * hero)
backpackPos++; backpackPos++;
} }
if (updateState && commonInfo->srcAOH == this) { if (updateState && commonInfo->srcAOH == this)
{
// A swap was made, make the replaced artifact the current selected. // A swap was made, make the replaced artifact the current selected.
if (commonInfo->destSlotID < 19 && commonInfo->destArtifact) { if (commonInfo->destSlotID < 19 && commonInfo->destArtifact)
{
// Temporarily remove artifact from hero. // Temporarily remove artifact from hero.
//if (commonInfo->srcSlotID < 19) if (commonInfo->srcSlotID < 19)
// CGI->arth->unequipArtifact(curHero->artifWorn, commonInfo->srcSlotID); CGI->arth->unequipArtifact(curHero->artifWorn, commonInfo->srcSlotID);
//else else
// curHero->artifacts.erase(curHero->artifacts.begin() + (commonInfo->srcSlotID - 19)); curHero->artifacts.erase(curHero->artifacts.begin() + (commonInfo->srcSlotID - 19));
//curHero->recreateArtBonuses(); //curHero->recreateArtBonuses();
// Source <- Dest // Source <- Dest
@ -4775,20 +4745,13 @@ void CArtifactsOfHero::setHero(const CGHeroInstance * hero)
commonInfo->destArtifact = NULL; commonInfo->destArtifact = NULL;
commonInfo->destSlotID = -1; commonInfo->destSlotID = -1;
CGI->curh->dragAndDropCursor( CGI->curh->dragAndDropCursor(graphics->artDefs->ourImages[commonInfo->srcArtifact->id].bitmap);
graphics->artDefs->ourImages[commonInfo->srcArtifact->id].bitmap);
markPossibleSlots(commonInfo->srcArtifact); markPossibleSlots(commonInfo->srcArtifact);
} }
else if (commonInfo->destAOH != NULL) else if (commonInfo->destAOH != NULL)
{ {
// Reset all parameters. // Reset all parameters.
commonInfo->srcAOH = NULL; commonInfo->reset();
commonInfo->srcArtifact = NULL;
commonInfo->srcSlotID = -1;
commonInfo->destAOH = NULL;
commonInfo->destArtifact = NULL;
commonInfo->destSlotID = -1;
CGI->curh->dragAndDropCursor(NULL); CGI->curh->dragAndDropCursor(NULL);
unmarkSlots(); unmarkSlots();
} }
@ -4796,10 +4759,14 @@ void CArtifactsOfHero::setHero(const CGHeroInstance * hero)
} }
else else
{ {
rollback(); commonInfo->reset();
} }
curHero = const_cast<CGHeroInstance *>(hero); if(hero != curHero)
{
delete curHero;
curHero = new CGHeroInstance(*hero);
}
if (curHero->artifacts.size() > 0) if (curHero->artifacts.size() > 0)
backpackPos %= curHero->artifacts.size(); backpackPos %= curHero->artifacts.size();
@ -4816,67 +4783,16 @@ void CArtifactsOfHero::setHero(const CGHeroInstance * hero)
rightArtRoll->block(curHero->artifacts.size() <= backpack.size()); rightArtRoll->block(curHero->artifacts.size() <= backpack.size());
} }
/**
* Any held artifacts, marked slots etc. will be restored to it's original way.
*/
void CArtifactsOfHero::rollback()
{
if (curHero != NULL)
{
// Restore any held artifact to it's original position.
if (commonInfo->srcArtifact && commonInfo->srcAOH == this)
{
if (commonInfo->srcSlotID != -1) {
// Put a held artifact back to it's spot.
//if (commonInfo->srcSlotID < 19)
// CGI->arth->equipArtifact(curHero->artifWorn, commonInfo->srcSlotID, commonInfo->srcArtifact->id);
//else
// curHero->artifacts.insert(curHero->artifacts.begin() + (commonInfo->srcSlotID - 19), commonInfo->srcArtifact->id);
}
else // Held swapped artifact.
{
// Wear the artifact in a suitable spot.
ui16 i = 0;
for (; i < 19; i++)
{
if (artWorn[i]->fitsHere(commonInfo->srcArtifact) && !vstd::contains(curHero->artifWorn, i))
{
//CGI->arth->equipArtifact(curHero->artifWorn, i, commonInfo->srcArtifact->id);
break;
}
}
// If it can't be worn, put it in the backpack.
if (i == 19)
;//curHero->artifacts.push_back(commonInfo->srcArtifact->id);
}
//curHero->recreateArtBonuses();
}
}
unmarkSlots();
backpackPos = 0;
commonInfo->srcAOH = NULL;
commonInfo->srcArtifact = NULL;
commonInfo->srcSlotID = -1;
commonInfo->destAOH = NULL;
commonInfo->destArtifact = NULL;
commonInfo->destSlotID = -1;
CGI->curh->dragAndDropCursor(NULL);
}
void CArtifactsOfHero::dispose() void CArtifactsOfHero::dispose()
{ {
curHero = NULL; delNull(curHero);
} }
void CArtifactsOfHero::scrollBackpack(int dir) void CArtifactsOfHero::scrollBackpack(int dir)
{ {
backpackPos += dir; backpackPos += dir;
if (curHero->artifacts.size() > 0) { if (curHero->artifacts.size() > 0)
{
if (backpackPos < 0) { // No guarantee of modulus behavior with negative operands. if (backpackPos < 0) { // No guarantee of modulus behavior with negative operands.
do { do {
backpackPos += curHero->artifacts.size(); backpackPos += curHero->artifacts.size();
@ -4887,7 +4803,8 @@ void CArtifactsOfHero::scrollBackpack(int dir)
} }
//set new data //set new data
for (size_t s = 0; s < backpack.size(); ++s) { for (size_t s = 0; s < backpack.size(); ++s)
{
if (s < curHero->artifacts.size()) if (s < curHero->artifacts.size())
setSlotData(backpack[s], 19 + (s + backpackPos)%curHero->artifacts.size()); setSlotData(backpack[s], 19 + (s + backpackPos)%curHero->artifacts.size());
else else
@ -4906,7 +4823,8 @@ void CArtifactsOfHero::markPossibleSlots (const CArtifact* art)
it != commonInfo->participants.end(); it != commonInfo->participants.end();
++it) ++it)
{ {
for (int i = 0; i < (*it)->artWorn.size(); i++) { for (int i = 0; i < (*it)->artWorn.size(); i++)
{
if ((*it)->artWorn[i]->fitsHere(art)) if ((*it)->artWorn[i]->fitsHere(art))
(*it)->artWorn[i]->marked = true; (*it)->artWorn[i]->marked = true;
else else
@ -4924,7 +4842,8 @@ void CArtifactsOfHero::unmarkSlots ()
it != commonInfo->participants.end(); it != commonInfo->participants.end();
++it) ++it)
{ {
for (int i = 0; i < (*it)->artWorn.size(); i++) { for (int i = 0; i < (*it)->artWorn.size(); i++)
{
(*it)->artWorn[i]->marked = false; (*it)->artWorn[i]->marked = false;
} }
} }
@ -4938,13 +4857,16 @@ void CArtifactsOfHero::setSlotData (CArtPlace* artPlace, int slotID)
artPlace->slotID = slotID; artPlace->slotID = slotID;
artPlace->ourArt = curHero->getArt(slotID); artPlace->ourArt = curHero->getArt(slotID);
if (artPlace->ourArt) { if (artPlace->ourArt)
{
artPlace->text = artPlace->ourArt->Description(); artPlace->text = artPlace->ourArt->Description();
if (artPlace->locked()) // Locks should appear as empty. if (artPlace->locked()) // Locks should appear as empty.
artPlace->hoverText = CGI->generaltexth->allTexts[507]; artPlace->hoverText = CGI->generaltexth->allTexts[507];
else else
artPlace->hoverText = boost::str(boost::format(CGI->generaltexth->heroscrn[1].c_str()) % artPlace->ourArt->Name().c_str()); artPlace->hoverText = boost::str(boost::format(CGI->generaltexth->heroscrn[1].c_str()) % artPlace->ourArt->Name().c_str());
} else { }
else
{
eraseSlotData(artPlace, slotID); eraseSlotData(artPlace, slotID);
} }
} }
@ -4961,25 +4883,26 @@ void CArtifactsOfHero::eraseSlotData (CArtPlace* artPlace, int slotID)
} }
CArtifactsOfHero::CArtifactsOfHero(const Point &position) : CArtifactsOfHero::CArtifactsOfHero(const Point &position) :
backpackPos(0), updateState(false), commonInfo(NULL) backpackPos(0), updateState(false), commonInfo(NULL), curHero(NULL)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL;
pos += position; pos += position;
artWorn.resize(19); artWorn.resize(19);
std::vector<SDL_Rect> slotPos; std::vector<Rect> slotPos;
slotPos += genRect(44,44,pos.x+509,pos.y+30), genRect(44,44,pos.x+567,pos.y+240), genRect(44,44,pos.x+509,pos.y+80), slotPos += genRect(44,44,509,30), genRect(44,44,567,240), genRect(44,44,509,80),
genRect(44,44,pos.x+383,pos.y+68), genRect(44,44,pos.x+564,pos.y+183), genRect(44,44,pos.x+509,pos.y+130), genRect(44,44,383,68), genRect(44,44,564,183), genRect(44,44,509,130),
genRect(44,44,pos.x+431,pos.y+68), genRect(44,44,pos.x+610,pos.y+183), genRect(44,44,pos.x+515,pos.y+295), genRect(44,44,431,68), genRect(44,44,610,183), genRect(44,44,515,295),
genRect(44,44,pos.x+383,pos.y+143), genRect(44,44,pos.x+399,pos.y+194), genRect(44,44,pos.x+415,pos.y+245), genRect(44,44,383,143), genRect(44,44,399,194), genRect(44,44,415,245),
genRect(44,44,pos.x+431,pos.y+296), genRect(44,44,pos.x+564,pos.y+30), genRect(44,44,pos.x+610,pos.y+30), genRect(44,44,431,296), genRect(44,44,564,30), genRect(44,44,610,30),
genRect(44,44,pos.x+610,pos.y+76), genRect(44,44,pos.x+610,pos.y+122), genRect(44,44,pos.x+610,pos.y+310), genRect(44,44,610,76), genRect(44,44,610,122), genRect(44,44,610,310),
genRect(44,44,pos.x+381,pos.y+296); genRect(44,44,381,296);
// Create slots for worn artifacts. // Create slots for worn artifacts.
for (int g = 0; g < 19 ; g++) for (int g = 0; g < 19 ; g++)
{ {
artWorn[g] = new CArtPlace(NULL); artWorn[g] = new CArtPlace(NULL);
artWorn[g]->pos = slotPos[g]; artWorn[g]->pos = slotPos[g] + pos;
artWorn[g]->ourOwner = this; artWorn[g]->ourOwner = this;
eraseSlotData(artWorn[g], g); eraseSlotData(artWorn[g], g);
} }
@ -4998,28 +4921,14 @@ CArtifactsOfHero::CArtifactsOfHero(const Point &position) :
backpack.push_back(add); backpack.push_back(add);
} }
leftArtRoll = new AdventureMapButton(std::string(), std::string(), boost::bind(&CArtifactsOfHero::scrollBackpack,this,-1), pos.x+379, pos.y+364, "hsbtns3.def", SDLK_LEFT); leftArtRoll = new AdventureMapButton(std::string(), std::string(), boost::bind(&CArtifactsOfHero::scrollBackpack,this,-1), 379, 364, "hsbtns3.def", SDLK_LEFT);
rightArtRoll = new AdventureMapButton(std::string(), std::string(), boost::bind(&CArtifactsOfHero::scrollBackpack,this,+1), pos.x+632, pos.y+364, "hsbtns5.def", SDLK_RIGHT); rightArtRoll = new AdventureMapButton(std::string(), std::string(), boost::bind(&CArtifactsOfHero::scrollBackpack,this,+1), 632, 364, "hsbtns5.def", SDLK_RIGHT);
} }
CArtifactsOfHero::~CArtifactsOfHero() CArtifactsOfHero::~CArtifactsOfHero()
{ {
dispose(); dispose();
for(size_t g=0; g<artWorn.size(); ++g) CGI->curh->dragAndDropCursor(NULL);
{
delete artWorn[g];
artWorn[g] = NULL;
}
for(size_t g=0; g<backpack.size(); ++g)
{
delete backpack[g];
backpack[g] = NULL;
}
backpack.clear();
artWorn.clear();
delete leftArtRoll;
delete rightArtRoll;
} }
void CExchangeWindow::close() void CExchangeWindow::close()
@ -5324,8 +5233,6 @@ CExchangeWindow::~CExchangeWindow() //d-tor
delete quit; delete quit;
//warning: don't experiment with these =NULL lines, they prevent heap corruption! //warning: don't experiment with these =NULL lines, they prevent heap corruption!
artifs[0]->rollback();
artifs[1]->rollback();
delete artifs[0]->commonInfo; delete artifs[0]->commonInfo;
artifs[0]->commonInfo = NULL; artifs[0]->commonInfo = NULL;
delete artifs[0]; delete artifs[0];

View File

@ -909,7 +909,7 @@ inline bool CArtPlace::locked () const
class CArtifactsOfHero : public CIntObject class CArtifactsOfHero : public CIntObject
{ {
const CGHeroInstance * curHero; CGHeroInstance * curHero; //local copy of hero on which we operate
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 *> 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!) std::vector<CArtPlace *> backpack; //hero's visible backpack (only 5 elements!)
@ -925,19 +925,16 @@ public:
const CArtifactsOfHero * destAOH; // For swapping. (i.e. changing what is held) const CArtifactsOfHero * destAOH; // For swapping. (i.e. changing what is held)
int destSlotID; // Needed to determine what kind of action was last taken in setHero int destSlotID; // Needed to determine what kind of action was last taken in setHero
const CArtifact * destArtifact; // For swapping. const CArtifact * destArtifact; // For swapping.
void reset();
} * 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 } * 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. bool updateState; // Whether the commonInfo should be updated on setHero or not.
AdventureMapButton * leftArtRoll, * rightArtRoll; AdventureMapButton * leftArtRoll, * rightArtRoll;
void activate();
void deactivate();
void show(SDL_Surface * to);
void setHero(const CGHeroInstance * hero); void setHero(const CGHeroInstance * hero);
void dispose(); //free resources not needed after closing windows and reset state void dispose(); //free resources not needed after closing windows and reset state
void rollback();
void scrollBackpack(int dir); //dir==-1 => to left; dir==1 => to right void scrollBackpack(int dir); //dir==-1 => to left; dir==1 => to right
void markPossibleSlots (const CArtifact* art); void markPossibleSlots (const CArtifact* art);
void unmarkSlots (); void unmarkSlots ();

View File

@ -326,17 +326,17 @@ void SetHeroArtifacts::applyCl( CClient *cl )
if(!player) if(!player)
return; return;
h->recreateArtBonuses(); //h->recreateArtBonuses();
player->heroArtifactSetChanged(h); player->heroArtifactSetChanged(h);
BOOST_FOREACH(Bonus bonus, gained) // BOOST_FOREACH(Bonus bonus, gained)
{ // {
player->heroBonusChanged(h,bonus,true); // player->heroBonusChanged(h,bonus,true);
} // }
BOOST_FOREACH(Bonus bonus, lost) // BOOST_FOREACH(Bonus bonus, lost)
{ // {
player->heroBonusChanged(h,bonus,false); // player->heroBonusChanged(h,bonus,false);
} // }
} }
void HeroRecruited::applyCl( CClient *cl ) void HeroRecruited::applyCl( CClient *cl )

View File

@ -87,7 +87,8 @@ bool CArtifact::fitsAt (const std::map<ui16, ui32> &artifWorn, ui16 slotID) cons
} }
// Ensure enough ring slots are free // Ensure enough ring slots are free
for (int i = 0; i < sizeof(ringSlots)/sizeof(*ringSlots); i++) { for (int i = 0; i < sizeof(ringSlots)/sizeof(*ringSlots); i++)
{
if (tempArtifWorn.find(ringSlots[i]) == tempArtifWorn.end() || ringSlots[i] == slotID) if (tempArtifWorn.find(ringSlots[i]) == tempArtifWorn.end() || ringSlots[i] == slotID)
rings--; rings--;
} }
@ -95,7 +96,8 @@ bool CArtifact::fitsAt (const std::map<ui16, ui32> &artifWorn, ui16 slotID) cons
return false; return false;
// Ensure enough misc slots are free. // Ensure enough misc slots are free.
for (int i = 0; i < sizeof(miscSlots)/sizeof(*miscSlots); i++) { for (int i = 0; i < sizeof(miscSlots)/sizeof(*miscSlots); i++)
{
if (tempArtifWorn.find(miscSlots[i]) == tempArtifWorn.end() || miscSlots[i] == slotID) if (tempArtifWorn.find(miscSlots[i]) == tempArtifWorn.end() || miscSlots[i] == slotID)
misc--; misc--;
} }
@ -114,10 +116,13 @@ bool CArtifact::canBeAssembledTo (const std::map<ui16, ui32> &artifWorn, ui32 ar
const CArtifact &artifact = *VLC->arth->artifacts[artifactID]; const CArtifact &artifact = *VLC->arth->artifacts[artifactID];
assert(artifact.constituents); assert(artifact.constituents);
BOOST_FOREACH(ui32 constituentID, *artifact.constituents) { BOOST_FOREACH(ui32 constituentID, *artifact.constituents)
{
bool found = false; bool found = false;
for (std::map<ui16, ui32>::const_iterator it = artifWorn.begin(); it != artifWorn.end(); ++it) { for (std::map<ui16, ui32>::const_iterator it = artifWorn.begin(); it != artifWorn.end(); ++it)
if (it->second == constituentID) { {
if (it->second == constituentID)
{
found = true; found = true;
break; break;
} }
@ -129,43 +134,13 @@ bool CArtifact::canBeAssembledTo (const std::map<ui16, ui32> &artifWorn, ui32 ar
return true; return true;
} }
/** CArtifact::CArtifact()
* Adds all the bonuses of this artifact, including possible constituents, to
* a bonus list.
*/
void CArtifact::addBonusesTo (BonusList *otherBonuses) const
{ {
for(std::list<Bonus>::const_iterator i = bonuses.begin(); i != bonuses.end(); i++) nodeType = ARTIFACT;
otherBonuses->push_back(*i);
if (constituents != NULL) {
BOOST_FOREACH(ui32 artifactID, *constituents)
{
VLC->arth->artifacts[artifactID]->addBonusesTo(otherBonuses);
}
}
} }
/** CArtifact::~CArtifact()
* Removes all the bonuses of this artifact, including possible constituents, from
* a bonus list.
*/
void CArtifact::removeBonusesFrom (BonusList *otherBonuses) const
{ {
if (constituents != NULL) {
BOOST_FOREACH(ui32 artifactID, *constituents) {
VLC->arth->artifacts[artifactID]->removeBonusesFrom(otherBonuses);
}
}
while (1) {
std::list<Bonus>::iterator it = std::find_if(otherBonuses->begin(), otherBonuses->end(),boost::bind(Bonus::IsFrom,_1,Bonus::ARTIFACT,id));
if (it != otherBonuses->end())
otherBonuses->erase(it);
else
break;
}
} }
CArtHandler::CArtHandler() CArtHandler::CArtHandler()
@ -709,10 +684,9 @@ void CArtHandler::clear()
* @param artifWorn A hero's set of worn artifacts. * @param artifWorn A hero's set of worn artifacts.
* @param bonuses Optional list of bonuses to update. * @param bonuses Optional list of bonuses to update.
*/ */
void CArtHandler::equipArtifact void CArtHandler::equipArtifact(std::map<ui16, ui32> &artifWorn, ui16 slotID, ui32 artifactID)
(std::map<ui16, ui32> &artifWorn, ui16 slotID, ui32 artifactID, BonusList *bonuses)
{ {
unequipArtifact(artifWorn, slotID, bonuses); unequipArtifact(artifWorn, slotID);
const CArtifact &artifact = *artifacts[artifactID]; const CArtifact &artifact = *artifacts[artifactID];
@ -745,9 +719,6 @@ void CArtHandler::equipArtifact
} }
} }
} }
if (bonuses != NULL)
artifact.addBonusesTo(bonuses);
} }
/** /**
@ -756,8 +727,7 @@ void CArtHandler::equipArtifact
* @param artifWorn A hero's set of worn artifacts. * @param artifWorn A hero's set of worn artifacts.
* @param bonuses Optional list of bonuses to update. * @param bonuses Optional list of bonuses to update.
*/ */
void CArtHandler::unequipArtifact void CArtHandler::unequipArtifact(std::map<ui16, ui32> &artifWorn, ui16 slotID)
(std::map<ui16, ui32> &artifWorn, ui16 slotID, BonusList *bonuses)
{ {
if (!vstd::contains(artifWorn, slotID)) if (!vstd::contains(artifWorn, slotID))
return; return;
@ -793,7 +763,4 @@ void CArtHandler::unequipArtifact
} }
} }
} }
if (bonuses != NULL)
artifact.removeBonusesFrom(bonuses);
} }

View File

@ -18,7 +18,7 @@
*/ */
class CDefHandler; class CDefHandler;
class DLL_EXPORT CArtifact //container for artifacts class DLL_EXPORT CArtifact : public CBonusSystemNode //container for artifacts
{ {
std::string name, description; //set if custom std::string name, description; //set if custom
public: public:
@ -37,12 +37,15 @@ public:
std::vector<ui32> * constituentOf; // Reverse map of constituents. std::vector<ui32> * constituentOf; // Reverse map of constituents.
EartClass aClass; EartClass aClass;
si32 id; si32 id;
std::list<Bonus> bonuses; //bonuses given by artifact
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & name & description & price & possibleSlots & constituents & constituentOf & aClass & id & bonuses; h & static_cast<CBonusSystemNode&>(*this);;
h & name & description & price & possibleSlots & constituents & constituentOf & aClass & id;
} }
CArtifact();
~CArtifact();
}; };
class DLL_EXPORT CArtHandler //handles artifacts class DLL_EXPORT CArtHandler //handles artifacts
@ -64,8 +67,8 @@ public:
void getAllowed(std::vector<CArtifact*> &out, int flags); void getAllowed(std::vector<CArtifact*> &out, int flags);
void erasePickedArt (si32 id); void erasePickedArt (si32 id);
bool isBigArtifact (ui32 artID) {return bigArtifacts.find(artID) != bigArtifacts.end();} bool isBigArtifact (ui32 artID) {return bigArtifacts.find(artID) != bigArtifacts.end();}
void equipArtifact (std::map<ui16, ui32> &artifWorn, ui16 slotID, ui32 artifactID, BonusList *bonuses = NULL); void equipArtifact (std::map<ui16, ui32> &artifWorn, ui16 slotID, ui32 artifactID);
void unequipArtifact (std::map<ui16, ui32> &artifWorn, ui16 slotID, BonusList *bonuses = NULL); void unequipArtifact (std::map<ui16, ui32> &artifWorn, ui16 slotID);
static int convertMachineID(int id, bool creToArt); static int convertMachineID(int id, bool creToArt);
CArtHandler(); CArtHandler();
~CArtHandler(); ~CArtHandler();

View File

@ -762,9 +762,9 @@ void CGHeroInstance::initHero()
if(!vstd::contains(artifWorn, 16) && type->startingSpell >= 0) //no catapult means we haven't read pre-existant set if(!vstd::contains(artifWorn, 16) && type->startingSpell >= 0) //no catapult means we haven't read pre-existant set
{ {
VLC->arth->equipArtifact(artifWorn, 17, 0, &bonuses); //give spellbook VLC->arth->equipArtifact(artifWorn, 17, 0); //give spellbook
} }
VLC->arth->equipArtifact(artifWorn, 16, 3, &bonuses); //everyone has a catapult VLC->arth->equipArtifact(artifWorn, 16, 3); //everyone has a catapult
if(portrait < 0 || portrait == 255) if(portrait < 0 || portrait == 255)
portrait = subID; portrait = subID;
@ -800,7 +800,6 @@ void CGHeroInstance::initHero()
boost::algorithm::replace_first(hoverName,"%s",name); boost::algorithm::replace_first(hoverName,"%s",name);
boost::algorithm::replace_first(hoverName,"%s", type->heroClass->name); boost::algorithm::replace_first(hoverName,"%s", type->heroClass->name);
recreateArtBonuses();
if(mana < 0) if(mana < 0)
mana = manaLimit(); //after all bonuses are taken into account mana = manaLimit(); //after all bonuses are taken into account
} }
@ -833,14 +832,13 @@ void CGHeroInstance::initArmy(CCreatureSet *dst /*= NULL*/)
switch (creID) switch (creID)
{ {
case 145: //catapult case 145: //catapult
VLC->arth->equipArtifact(artifWorn, 16, 3, &bonuses); VLC->arth->equipArtifact(artifWorn, 16, 3);
break; break;
default: default:
VLC->arth->equipArtifact( VLC->arth->equipArtifact(
artifWorn, artifWorn,
9+CArtHandler::convertMachineID(creID,true), 9+CArtHandler::convertMachineID(creID,true),
CArtHandler::convertMachineID(creID,true), CArtHandler::convertMachineID(creID,true));
&bonuses);
break; break;
} }
} }
@ -937,7 +935,7 @@ void CGHeroInstance::initObj()
if(!type) if(!type)
return; //TODO support prison return; //TODO support prison
for (std::vector<specialInfo>::iterator it = type->spec.begin(); it != type->spec.end(); it++) for (std::vector<specialInfo>::const_iterator it = type->spec.begin(); it != type->spec.end(); it++)
{ {
bonus.val = it->val; bonus.val = it->val;
bonus.id = id; //from the hero, speciality has no unique id bonus.id = id; //from the hero, speciality has no unique id
@ -1386,7 +1384,7 @@ void CGHeroInstance::giveArtifact (ui32 aid)
{ {
if (!vstd::contains(artifWorn, *it)) if (!vstd::contains(artifWorn, *it))
{ {
VLC->arth->equipArtifact(artifWorn, *it, aid, &bonuses); VLC->arth->equipArtifact(artifWorn, *it, aid);
break; break;
} }
} }
@ -1397,17 +1395,6 @@ void CGHeroInstance::giveArtifact (ui32 aid)
} }
} }
void CGHeroInstance::recreateArtBonuses()
{
//clear all bonuses from artifacts (if present) and give them again
bonuses.remove_if(boost::bind(Bonus::IsFrom,_1,Bonus::ARTIFACT,0xffffff));
for (std::map<ui16,ui32>::iterator ari = artifWorn.begin(); ari != artifWorn.end(); ari++)
{
CArtifact &art = *VLC->arth->artifacts[ari->second];
art.addBonusesTo(&bonuses);
}
}
bool CGHeroInstance::hasArt( ui32 aid ) const bool CGHeroInstance::hasArt( ui32 aid ) const
{ {
if(vstd::contains(artifacts, aid)) if(vstd::contains(artifacts, aid))
@ -1455,7 +1442,10 @@ void CGHeroInstance::getParents(TCNodes &out, const CBonusSystemNode *root /*= N
if((root == this || contains(static_cast<const CStackInstance *>(root))) && visitedTown) if((root == this || contains(static_cast<const CStackInstance *>(root))) && visitedTown)
out.insert(visitedTown); out.insert(visitedTown);
out.insert (&speciality); for (std::map<ui16,ui32>::const_iterator i = artifWorn.begin(); i != artifWorn.end(); i++)
out.insert(VLC->arth->artifacts[i->second]);
out.insert(&speciality);
} }
void CGHeroInstance::pushPrimSkill(int which, int val) void CGHeroInstance::pushPrimSkill(int which, int val)

View File

@ -275,7 +275,7 @@ public:
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
CHero * type; const CHero * type;
ui64 exp; //experience points ui64 exp; //experience points
si32 level; //current level of hero si32 level; //current level of hero
std::string name; //may be custom std::string name; //may be custom
@ -286,8 +286,8 @@ public:
si32 movement; //remaining movement points si32 movement; //remaining movement points
ui8 sex; ui8 sex;
ui8 inTownGarrison; // if hero is in town garrison ui8 inTownGarrison; // if hero is in town garrison
CGTownInstance * visitedTown; //set if hero is visiting town or in the town garrison const CGTownInstance * visitedTown; //set if hero is visiting town or in the town garrison
CGBoat *boat; //set to CGBoat when sailing const CGBoat *boat; //set to CGBoat when sailing
std::vector<ui32> artifacts; //hero's artifacts from bag std::vector<ui32> artifacts; //hero's artifacts from bag
std::map<ui16,ui32> artifWorn; //map<position,artifact_id>; positions: 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::map<ui16,ui32> artifWorn; //map<position,artifact_id>; positions: 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::set<ui32> spells; //known spells (spell IDs) std::set<ui32> spells; //known spells (spell IDs)
@ -376,7 +376,6 @@ public:
void initHero(); void initHero();
void initHero(int SUBID); void initHero(int SUBID);
void initArmy(CCreatureSet *dst = NULL); void initArmy(CCreatureSet *dst = NULL);
void recreateArtBonuses();
void giveArtifact (ui32 aid); void giveArtifact (ui32 aid);
void initHeroDefInfo(); void initHeroDefInfo();
void pushPrimSkill(int which, int val); void pushPrimSkill(int which, int val);

View File

@ -1484,10 +1484,8 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
CGHeroInstance *hero = k->second.heroes[0]; CGHeroInstance *hero = k->second.heroes[0];
std::vector<ui16>::iterator slot = vstd::findFirstNot (hero->artifWorn, toGive->possibleSlots); std::vector<ui16>::iterator slot = vstd::findFirstNot (hero->artifWorn, toGive->possibleSlots);
if(slot!=toGive->possibleSlots.end()) if(slot != toGive->possibleSlots.end())
{ VLC->arth->equipArtifact(hero->artifWorn, *slot, toGive->id);
VLC->arth->equipArtifact(hero->artifWorn, *slot, toGive->id, &hero->bonuses);
}
else else
hero->giveArtifact(toGive->id); hero->giveArtifact(toGive->id);
} }

View File

@ -377,7 +377,7 @@ public:
enum ENodeTypes enum ENodeTypes
{ {
UNKNOWN, STACK, SPECIALITY UNKNOWN, STACK, SPECIALITY, ARTIFACT
}; };
}; };

View File

@ -588,6 +588,7 @@ struct SetHeroArtifacts : public CPackForClient //509
h & hid & artifacts & artifWorn; h & hid & artifacts & artifWorn;
} }
std::vector<ui32> equiped, unequiped; //used locally
BonusList gained, lost; //used locally as hlp when applying BonusList gained, lost; //used locally as hlp when applying
}; };

View File

@ -301,12 +301,12 @@ DLL_EXPORT void RemoveObject::applyGs( CGameState *gs )
gs->getPlayer(player)->heroes.erase(nitr); gs->getPlayer(player)->heroes.erase(nitr);
h->tempOwner = 255; //no one owns beaten hero h->tempOwner = 255; //no one owns beaten hero
if(h->visitedTown) if(CGTownInstance *t = const_cast<CGTownInstance *>(h->visitedTown))
{ {
if(h->inTownGarrison) if(h->inTownGarrison)
h->visitedTown->garrisonHero = NULL; t->garrisonHero = NULL;
else else
h->visitedTown->visitingHero = NULL; t->visitingHero = NULL;
h->visitedTown = NULL; h->visitedTown = NULL;
} }
@ -382,10 +382,11 @@ void TryMoveHero::applyGs( CGameState *gs )
} }
else if(result == DISEMBARK) //hero leaves boat to dest tile else if(result == DISEMBARK) //hero leaves boat to dest tile
{ {
h->boat->direction = h->moveDir; CGBoat *b = const_cast<CGBoat *>(h->boat);
h->boat->pos = start; b->direction = h->moveDir;
h->boat->hero = NULL; b->pos = start;
gs->map->addBlockVisTiles(h->boat); b->hero = NULL;
gs->map->addBlockVisTiles(b);
h->boat = NULL; h->boat = NULL;
} }
@ -393,8 +394,8 @@ void TryMoveHero::applyGs( CGameState *gs )
{ {
gs->map->removeBlockVisTiles(h); gs->map->removeBlockVisTiles(h);
h->pos = end; h->pos = end;
if(h->boat) if(CGBoat *b = const_cast<CGBoat *>(h->boat))
h->boat->pos = end; b->pos = end;
gs->map->addBlockVisTiles(h); gs->map->addBlockVisTiles(h);
} }
@ -413,8 +414,9 @@ DLL_EXPORT void SetGarrisons::applyGs( CGameState *gs )
else if(ai->ID==HEROI_TYPE) else if(ai->ID==HEROI_TYPE)
{ {
CGHeroInstance *h = static_cast<CGHeroInstance*>(ai); CGHeroInstance *h = static_cast<CGHeroInstance*>(ai);
if(h->visitedTown && h->inTownGarrison) CGTownInstance *t = const_cast<CGTownInstance *>(h->visitedTown);
h->visitedTown->setArmy(i->second); if(t && h->inTownGarrison)
t->setArmy(i->second);
} }
} }
} }
@ -470,7 +472,6 @@ DLL_EXPORT void SetHeroesInTown::applyGs( CGameState *gs )
DLL_EXPORT void SetHeroArtifacts::applyGs( CGameState *gs ) DLL_EXPORT void SetHeroArtifacts::applyGs( CGameState *gs )
{ {
CGHeroInstance *h = gs->getHero(hid); CGHeroInstance *h = gs->getHero(hid);
std::vector<ui32> equiped, unequiped;
for(std::map<ui16,ui32>::const_iterator i = h->artifWorn.begin(); i != h->artifWorn.end(); i++) for(std::map<ui16,ui32>::const_iterator i = h->artifWorn.begin(); i != h->artifWorn.end(); i++)
if(!vstd::contains(artifWorn,i->first) || artifWorn[i->first] != i->second) if(!vstd::contains(artifWorn,i->first) || artifWorn[i->first] != i->second)
unequiped.push_back(i->second); unequiped.push_back(i->second);
@ -479,37 +480,14 @@ DLL_EXPORT void SetHeroArtifacts::applyGs( CGameState *gs )
if(!vstd::contains(h->artifWorn,i->first) || h->artifWorn[i->first] != i->second) if(!vstd::contains(h->artifWorn,i->first) || h->artifWorn[i->first] != i->second)
equiped.push_back(i->second); equiped.push_back(i->second);
BOOST_FOREACH(ui32 id, equiped)
{
//if hero already had equipped at least one artifact of that type, don't give any new bonuses
if(h->getArtPos(id) >= 0)
continue;
CArtifact &art = *VLC->arth->artifacts[id];
art.addBonusesTo(&h->bonuses);
art.addBonusesTo(&gained);
}
//update hero data //update hero data
h->artifacts = artifacts; h->artifacts = artifacts;
h->artifWorn = artifWorn; h->artifWorn = artifWorn;
//remove bonus from unequipped artifact
BOOST_FOREACH(ui32 id, unequiped)
{
//if hero still has equipped at least one artifact of that type, don't remove bonuses
if(h->getArtPos(id) >= 0)
continue;
CArtifact &art = *VLC->arth->artifacts[id];
art.removeBonusesFrom(&h->bonuses);
art.addBonusesTo(&lost);
}
} }
DLL_EXPORT void SetHeroArtifacts::setArtAtPos(ui16 pos, int art) DLL_EXPORT void SetHeroArtifacts::setArtAtPos(ui16 pos, int art)
{ {
if(art<0) if(art < 0)
{ {
if(pos<19) if(pos<19)
VLC->arth->unequipArtifact(artifWorn, pos); VLC->arth->unequipArtifact(artifWorn, pos);
@ -518,9 +496,12 @@ DLL_EXPORT void SetHeroArtifacts::setArtAtPos(ui16 pos, int art)
} }
else else
{ {
if (pos < 19) { if (pos < 19)
{
VLC->arth->equipArtifact(artifWorn, pos, (ui32) art); VLC->arth->equipArtifact(artifWorn, pos, (ui32) art);
} else { // Goes into the backpack. }
else // Goes into the backpack.
{
if(pos - 19 < artifacts.size()) if(pos - 19 < artifacts.size())
artifacts.insert(artifacts.begin() + (pos - 19), art); artifacts.insert(artifacts.begin() + (pos - 19), art);
else else

View File

@ -920,39 +920,39 @@ void Mapa::loadHero( CGObjectInstance * &nobj, const unsigned char * bufor, int
for(int pom=0;pom<16;pom++) for(int pom=0;pom<16;pom++)
{ {
int id = readNormalNr(bufor,i, artidlen); i+=artidlen; int id = readNormalNr(bufor,i, artidlen); i+=artidlen;
if(id!=artmask) if(id != artmask)
VLC->arth->equipArtifact(nhi->artifWorn, pom, id, &nhi->bonuses); VLC->arth->equipArtifact(nhi->artifWorn, pom, id);
} }
//misc5 art //17 //misc5 art //17
if(version>=SoD) if(version>=SoD)
{ {
int id = readNormalNr(bufor,i, artidlen); i+=artidlen; int id = readNormalNr(bufor,i, artidlen); i+=artidlen;
if(id!=artmask) if(id!=artmask)
VLC->arth->equipArtifact(nhi->artifWorn, 16, id, &nhi->bonuses); VLC->arth->equipArtifact(nhi->artifWorn, 16, id);
else else
VLC->arth->equipArtifact(nhi->artifWorn, 16, 3, &nhi->bonuses); //catapult by default VLC->arth->equipArtifact(nhi->artifWorn, 16, 3); //catapult by default
} }
//spellbook //spellbook
int id = readNormalNr(bufor,i, artidlen); i+=artidlen; int id = readNormalNr(bufor,i, artidlen); i+=artidlen;
if(id!=artmask) if(id!=artmask)
VLC->arth->equipArtifact(nhi->artifWorn, 17, id, &nhi->bonuses); VLC->arth->equipArtifact(nhi->artifWorn, 17, id);
//19 //???what is that? gap in file or what? - it's probably fifth slot.. //19 //???what is that? gap in file or what? - it's probably fifth slot..
if(version>RoE) if(version>RoE)
{ {
id = readNormalNr(bufor,i, artidlen); i+=artidlen; id = readNormalNr(bufor,i, artidlen); i+=artidlen;
if(id!=artmask) if(id!=artmask)
VLC->arth->equipArtifact(nhi->artifWorn, 18, id, &nhi->bonuses); VLC->arth->equipArtifact(nhi->artifWorn, 18, id);
} }
else else
i+=1; i+=1;
//bag artifacts //20 //bag artifacts //20
int amount = readNormalNr(bufor,i, 2); i+=2; //number of artifacts in hero's bag int amount = readNormalNr(bufor,i, 2); i+=2; //number of artifacts in hero's bag
if(amount>0) if(amount > 0)
{ {
for(int ss=0; ss<amount; ++ss) for(int ss = 0; ss < amount; ++ss)
{ {
id = readNormalNr(bufor,i, artidlen); i+=artidlen; id = readNormalNr(bufor,i, artidlen); i+=artidlen;
if(id!=artmask) if(id != artmask)
nhi->giveArtifact(id); nhi->giveArtifact(id);
} }
} }
@ -1160,7 +1160,7 @@ void Mapa::readPredefinedHeroes( const unsigned char * bufor, int &i)
{ {
int id = readNormalNr(bufor,i, artidlen); i+=artidlen; int id = readNormalNr(bufor,i, artidlen); i+=artidlen;
if(id!=artmask) if(id!=artmask)
VLC->arth->equipArtifact(cgh->artifWorn, pom, id, &cgh->bonuses); VLC->arth->equipArtifact(cgh->artifWorn, pom, id);
} }
//misc5 art //17 //misc5 art //17
if(version>=SoD) if(version>=SoD)
@ -1173,13 +1173,13 @@ void Mapa::readPredefinedHeroes( const unsigned char * bufor, int &i)
//spellbook //spellbook
int id = readNormalNr(bufor,i, artidlen); i+=artidlen; int id = readNormalNr(bufor,i, artidlen); i+=artidlen;
if(id!=artmask) if(id!=artmask)
VLC->arth->equipArtifact(cgh->artifWorn, 17, id, &cgh->bonuses); VLC->arth->equipArtifact(cgh->artifWorn, 17, id);
//19 //???what is that? gap in file or what? - it's probably fifth slot.. //19 //???what is that? gap in file or what? - it's probably fifth slot..
if(version>RoE) if(version>RoE)
{ {
id = readNormalNr(bufor,i, artidlen); i+=artidlen; id = readNormalNr(bufor,i, artidlen); i+=artidlen;
if(id!=artmask) if(id!=artmask)
VLC->arth->equipArtifact(cgh->artifWorn, 18, id, &cgh->bonuses); VLC->arth->equipArtifact(cgh->artifWorn, 18, id);
} }
else else
i+=1; i+=1;

View File

@ -2926,7 +2926,8 @@ bool CGameHandler::swapArtifacts(si32 srcHeroID, si32 destHeroID, ui16 srcSlot,
const CArtifact *srcArtifact = srcHero->getArt(srcSlot); const CArtifact *srcArtifact = srcHero->getArt(srcSlot);
const CArtifact *destArtifact = destHero->getArt(destSlot); const CArtifact *destArtifact = destHero->getArt(destSlot);
if (srcArtifact == NULL) { if (srcArtifact == NULL)
{
complain("No artifact to swap!"); complain("No artifact to swap!");
return false; return false;
} }
@ -2937,7 +2938,8 @@ bool CGameHandler::swapArtifacts(si32 srcHeroID, si32 destHeroID, ui16 srcSlot,
sha.artifWorn = srcHero->artifWorn; sha.artifWorn = srcHero->artifWorn;
// Combinational artifacts needs to be removed first so they don't get denied movement because of their own locks. // Combinational artifacts needs to be removed first so they don't get denied movement because of their own locks.
if (srcHeroID == destHeroID && srcSlot < 19 && destSlot < 19) { if (srcHeroID == destHeroID && srcSlot < 19 && destSlot < 19)
{
sha.setArtAtPos(srcSlot, -1); sha.setArtAtPos(srcSlot, -1);
if (!vstd::contains(sha.artifWorn, destSlot)) if (!vstd::contains(sha.artifWorn, destSlot))
destArtifact = NULL; destArtifact = NULL;
@ -2952,17 +2954,20 @@ bool CGameHandler::swapArtifacts(si32 srcHeroID, si32 destHeroID, ui16 srcSlot,
return false; return false;
} }
if ((srcArtifact && srcArtifact->id == 145) || (destArtifact && destArtifact->id == 145)) { if ((srcArtifact && srcArtifact->id == 145) || (destArtifact && destArtifact->id == 145))
{
complain("Cannot move artifact locks."); complain("Cannot move artifact locks.");
return false; return false;
} }
if (destSlot >= 19 && srcArtifact->isBig()) { if (destSlot >= 19 && srcArtifact->isBig())
{
complain("Cannot put big artifacts in backpack!"); complain("Cannot put big artifacts in backpack!");
return false; return false;
} }
if (srcSlot == 16 || destSlot == 16) { if (srcSlot == 16 || destSlot == 16)
{
complain("Cannot move catapult!"); complain("Cannot move catapult!");
return false; return false;
} }
@ -2979,7 +2984,8 @@ bool CGameHandler::swapArtifacts(si32 srcHeroID, si32 destHeroID, ui16 srcSlot,
sha.setArtAtPos(srcSlot, destArtifact ? destArtifact->id : -1); sha.setArtAtPos(srcSlot, destArtifact ? destArtifact->id : -1);
// Internal hero artifact arrangement. // Internal hero artifact arrangement.
if(srcHero == destHero) { if(srcHero == destHero)
{
// Correction for destination from removing source artifact in backpack. // Correction for destination from removing source artifact in backpack.
if (srcSlot >= 19 && destSlot >= 19 && srcSlot < destSlot) if (srcSlot >= 19 && destSlot >= 19 && srcSlot < destSlot)
destSlot--; destSlot--;
@ -2987,7 +2993,8 @@ bool CGameHandler::swapArtifacts(si32 srcHeroID, si32 destHeroID, ui16 srcSlot,
sha.setArtAtPos(destSlot, srcHero->getArtAtPos(srcSlot)); sha.setArtAtPos(destSlot, srcHero->getArtAtPos(srcSlot));
} }
sendAndApply(&sha); sendAndApply(&sha);
if (srcHeroID != destHeroID) { if (srcHeroID != destHeroID)
{
// Exchange between two different heroes. // Exchange between two different heroes.
sha.hid = destHeroID; sha.hid = destHeroID;
sha.artifacts = destHero->artifacts; sha.artifacts = destHero->artifacts;
@ -3112,7 +3119,7 @@ bool CGameHandler::assembleArtifacts (si32 heroID, ui16 artifactSlot, bool assem
bool CGameHandler::buyArtifact( ui32 hid, si32 aid ) bool CGameHandler::buyArtifact( ui32 hid, si32 aid )
{ {
CGHeroInstance *hero = gs->getHero(hid); CGHeroInstance *hero = gs->getHero(hid);
CGTownInstance *town = hero->visitedTown; CGTownInstance *town = const_cast<CGTownInstance*>(hero->visitedTown);
if(aid==0) //spellbook if(aid==0) //spellbook
{ {
if(!vstd::contains(town->builtBuildings,si32(0)) && complain("Cannot buy a spellbook, no mage guild in the town!") if(!vstd::contains(town->builtBuildings,si32(0)) && complain("Cannot buy a spellbook, no mage guild in the town!")