mirror of
https://github.com/vcmi/vcmi.git
synced 2025-03-19 21:10:12 +02:00
* Fixed the artifact screen completely, hopefully. Structural overhaul of the CArtPlace and CArtifactsOfHero classes, and I had to add a new server message SetArtifact to deal with things properly. The only thing that differs from H3 now is that you can't have gaps of empty slots in the backpack.
* Preliminary work on bug #112, a bigArtifacts set is added to CArtHandler.
This commit is contained in:
parent
df3ef1c330
commit
0a96decf87
@ -416,6 +416,16 @@ bool CCallback::swapArtifacts(const CGHeroInstance * hero1, ui16 pos1, const CGH
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCallback::setArtifact(const CGHeroInstance * hero, ui16 pos, int artID)
|
||||
{
|
||||
if(player != hero->tempOwner)
|
||||
return false;
|
||||
|
||||
SetArtifact sa(hero->id, pos, artID);
|
||||
sendRequest(&sa);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCallback::buildBuilding(const CGTownInstance *town, si32 buildingID)
|
||||
{
|
||||
CGTownInstance * t = const_cast<CGTownInstance *>(town);
|
||||
|
@ -224,6 +224,7 @@ public:
|
||||
int splitStack(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2, int val);
|
||||
bool dismissHero(const CGHeroInstance * hero);
|
||||
bool swapArtifacts(const CGHeroInstance * hero1, ui16 pos1, const CGHeroInstance * hero2, ui16 pos2);
|
||||
bool setArtifact(const CGHeroInstance * hero, ui16 pos, int artID);
|
||||
bool buildBuilding(const CGTownInstance *town, si32 buildingID);
|
||||
void recruitCreatures(const CGObjectInstance *obj, ui32 ID, ui32 amount);
|
||||
bool dismissCreature(const CArmedInstance *obj, int stackPos);
|
||||
|
@ -55,7 +55,6 @@ CHeroWindow::CHeroWindow(int playerColor):
|
||||
artifs = new CArtifactsOfHero(pos);
|
||||
artifs->commonInfo = new CArtifactsOfHero::SCommonPart;
|
||||
artifs->commonInfo->participants.insert(artifs);
|
||||
artifs->commonInfo->activeArtPlace = NULL;
|
||||
|
||||
garr = NULL;
|
||||
ourBar = new CStatusBar(pos.x+72, pos.y+567, "ADROLLVR.bmp", 660);
|
||||
@ -146,6 +145,7 @@ CHeroWindow::~CHeroWindow()
|
||||
delete garr;
|
||||
delete ourBar;
|
||||
|
||||
artifs->rollback();
|
||||
delete artifs->commonInfo;
|
||||
artifs->commonInfo = NULL; //to prevent heap corruption
|
||||
delete artifs;
|
||||
@ -506,6 +506,7 @@ void CHeroWindow::dispose()
|
||||
curBack = NULL;
|
||||
curHero = NULL;
|
||||
|
||||
artifs->rollback();
|
||||
artifs->dispose();
|
||||
}
|
||||
|
||||
|
@ -3497,7 +3497,7 @@ CRClickPopupInt::~CRClickPopupInt()
|
||||
CGI->curh->show();
|
||||
}
|
||||
|
||||
CArtPlace::CArtPlace(const CArtifact* Art): active(false), clicked(false), marked(false), ourArt(Art)/*,
|
||||
CArtPlace::CArtPlace(const CArtifact* Art): active(false), marked(false), ourArt(Art)/*,
|
||||
spellBook(false), warMachine1(false), warMachine2(false), warMachine3(false),
|
||||
warMachine4(false),misc1(false), misc2(false), misc3(false), misc4(false),
|
||||
misc5(false), feet(false), lRing(false), rRing(false), torso(false),
|
||||
@ -3520,7 +3520,7 @@ void CArtPlace::clickLeft(tribool down, bool previousState)
|
||||
//LRClickableAreaWTextComp::clickLeft(down);
|
||||
|
||||
// If clicked on spellbook, open it only if no artifact is held at the moment.
|
||||
if(ourArt && !down && previousState && !ourOwner->commonInfo->activeArtPlace)
|
||||
if(ourArt && !down && previousState && !ourOwner->commonInfo->srcAOH)
|
||||
{
|
||||
if(ourArt->id == 0)
|
||||
{
|
||||
@ -3528,11 +3528,11 @@ void CArtPlace::clickLeft(tribool down, bool previousState)
|
||||
GH.pushInt(spellWindow);
|
||||
}
|
||||
}
|
||||
if(!down && (!clicked || ourOwner->commonInfo->srcSlotID >= 19) && previousState) //not clicked before
|
||||
if (!down && previousState)
|
||||
{
|
||||
if(ourArt && ourArt->id == 0)
|
||||
return; //this is handled separately
|
||||
if(!ourOwner->commonInfo->activeArtPlace) //nothing has been clicked
|
||||
if(!ourOwner->commonInfo->srcAOH) //nothing has been clicked
|
||||
{
|
||||
if(ourArt) //to prevent selecting empty slots (bugfix to what GrayFace reported)
|
||||
{
|
||||
@ -3567,39 +3567,36 @@ void CArtPlace::clickLeft(tribool down, bool previousState)
|
||||
default:
|
||||
ourOwner->commonInfo->destAOH = ourOwner;
|
||||
ourOwner->commonInfo->destSlotID = slotID;
|
||||
ourOwner->commonInfo->destArtifact = NULL;
|
||||
|
||||
LOCPLINT->cb->swapArtifacts(
|
||||
ourOwner->commonInfo->activeArtPlace->ourOwner->curHero,
|
||||
ourOwner->commonInfo->srcSlotID,
|
||||
LOCPLINT->cb->setArtifact(
|
||||
ourOwner->curHero,
|
||||
slotID);
|
||||
slotID,
|
||||
ourOwner->commonInfo->srcArtifact->id);
|
||||
|
||||
ourOwner->commonInfo->activeArtPlace->deselect();
|
||||
break;
|
||||
}
|
||||
}
|
||||
//check if swap is possible
|
||||
else if(this->fitsHere(ourOwner->commonInfo->srcArtifact) && ourOwner->commonInfo->activeArtPlace->fitsHere(this->ourArt))
|
||||
else if (this->fitsHere(ourOwner->commonInfo->srcArtifact))
|
||||
{
|
||||
ourOwner->commonInfo->destAOH = ourOwner;
|
||||
ourOwner->commonInfo->destSlotID = slotID;
|
||||
ourOwner->commonInfo->destArtifact = ourArt;
|
||||
|
||||
LOCPLINT->cb->swapArtifacts(
|
||||
ourOwner->commonInfo->activeArtPlace->ourOwner->curHero,
|
||||
ourOwner->commonInfo->srcSlotID,
|
||||
LOCPLINT->cb->setArtifact(
|
||||
ourOwner->curHero,
|
||||
slotID);
|
||||
|
||||
ourOwner->commonInfo->activeArtPlace->deselect();
|
||||
slotID,
|
||||
ourOwner->commonInfo->srcArtifact->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(!down && clicked)
|
||||
/*else if(!down && clicked)
|
||||
{
|
||||
if(ourArt && ourArt->id == 0)
|
||||
return; //this is handled separately
|
||||
deselect();
|
||||
}
|
||||
}*/
|
||||
//ClickableL::clickLeft(down);
|
||||
}
|
||||
|
||||
@ -3615,20 +3612,19 @@ void CArtPlace::clickRight(tribool down, bool previousState)
|
||||
void CArtPlace::select ()
|
||||
{
|
||||
CGI->curh->dragAndDropCursor(graphics->artDefs->ourImages[ourArt->id].bitmap);
|
||||
clicked = true;
|
||||
ourOwner->markPossibleSlots(ourArt);
|
||||
|
||||
ourOwner->commonInfo->activeArtPlace = this;
|
||||
ourOwner->commonInfo->srcArtifact = ourArt;
|
||||
ourOwner->commonInfo->srcSlotID = slotID;
|
||||
ourOwner->commonInfo->srcAOH = ourOwner;
|
||||
|
||||
if (slotID >= 19) {
|
||||
// Updates backpack, possibly correcting the position.
|
||||
// Correcting position in backpack.
|
||||
ourOwner->scrollBackpack(-(slotID - 19 < ourOwner->backpackPos));
|
||||
} else {
|
||||
ourOwner->eraseSlotData(this, slotID);
|
||||
}
|
||||
LOCPLINT->cb->setArtifact(ourOwner->curHero, slotID, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3636,14 +3632,8 @@ void CArtPlace::select ()
|
||||
*/
|
||||
void CArtPlace::deselect ()
|
||||
{
|
||||
clicked = false;
|
||||
CGI->curh->dragAndDropCursor(NULL);
|
||||
ourOwner->unmarkSlots();
|
||||
ourOwner->commonInfo->activeArtPlace = NULL;
|
||||
|
||||
// If a worn artifact is deselected, restore it's picture.
|
||||
if (slotID < 19 && !ourOwner->commonInfo->destAOH)
|
||||
ourOwner->setSlotData(this, slotID);
|
||||
}
|
||||
|
||||
void CArtPlace::deactivate()
|
||||
@ -3658,10 +3648,9 @@ void CArtPlace::deactivate()
|
||||
|
||||
void CArtPlace::show(SDL_Surface *to)
|
||||
{
|
||||
if(ourArt && (!clicked || slotID >= 19))
|
||||
{
|
||||
if (ourArt)
|
||||
blitAt(graphics->artDefs->ourImages[ourArt->id].bitmap, pos.x, pos.y, to);
|
||||
}
|
||||
|
||||
if(marked && active)
|
||||
{
|
||||
// Draw vertical bars.
|
||||
@ -3685,8 +3674,8 @@ bool CArtPlace::fitsHere(const CArtifact * art)
|
||||
return true;
|
||||
|
||||
// Anything can be placed in the backpack, except War Machines.
|
||||
if(slotID > 18 && !(art->id >= 3 && art->id <= 6)
|
||||
|| vstd::contains(art->possibleSlots,slotID))
|
||||
if (slotID >= 19 && !CGI->arth->isBigArtifact(art->id)
|
||||
|| vstd::contains(art->possibleSlots, slotID))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -3697,10 +3686,6 @@ bool CArtPlace::fitsHere(const CArtifact * art)
|
||||
CArtPlace::~CArtPlace()
|
||||
{
|
||||
deactivate();
|
||||
|
||||
// Make sure a currently held artifact does not affect the outside.
|
||||
if (clicked)
|
||||
CGI->curh->dragAndDropCursor(NULL);
|
||||
}
|
||||
|
||||
void LClickableArea::activate()
|
||||
@ -3867,124 +3852,141 @@ void CArtifactsOfHero::setHero(const CGHeroInstance * hero)
|
||||
{
|
||||
// An update is made, rather than initialization.
|
||||
if (curHero == hero) {
|
||||
// Compensate backpack pos if an artifact is insertad before it.
|
||||
// Compensate backpack pos if an artifact was insertad before it.
|
||||
if (commonInfo->destSlotID >= 19 && commonInfo->destAOH == this
|
||||
&& commonInfo->destSlotID - 19 < backpackPos)
|
||||
{
|
||||
backpackPos++;
|
||||
}
|
||||
|
||||
// A swap was made, make the replaced artifact into current selected.
|
||||
if (commonInfo->destSlotID < 19 && commonInfo->destArtifact) {
|
||||
// Source <- Dest
|
||||
commonInfo->srcAOH = commonInfo->destAOH;
|
||||
commonInfo->srcArtifact = commonInfo->destArtifact;
|
||||
commonInfo->srcSlotID = -1; // The artifact's original place is taken now.
|
||||
|
||||
// Reset destination parameters.
|
||||
commonInfo->destAOH = NULL;
|
||||
commonInfo->destArtifact = NULL;
|
||||
commonInfo->destSlotID = -1;
|
||||
|
||||
CGI->curh->dragAndDropCursor(
|
||||
graphics->artDefs->ourImages[commonInfo->srcArtifact->id].bitmap);
|
||||
markPossibleSlots(commonInfo->srcArtifact);
|
||||
} else if (commonInfo->destAOH != NULL) {
|
||||
// Reset all parameters.
|
||||
commonInfo->srcAOH = NULL;
|
||||
commonInfo->srcArtifact = NULL;
|
||||
commonInfo->srcSlotID = -1;
|
||||
commonInfo->destAOH = NULL;
|
||||
commonInfo->destArtifact = NULL;
|
||||
commonInfo->destSlotID = -1;
|
||||
|
||||
CGI->curh->dragAndDropCursor(NULL);
|
||||
unmarkSlots();
|
||||
}
|
||||
} else {
|
||||
rollback();
|
||||
}
|
||||
|
||||
commonInfo->srcAOH = NULL;
|
||||
commonInfo->srcArtifact = NULL;
|
||||
commonInfo->srcSlotID = 0; // Can be anything that's not in backpack range.
|
||||
commonInfo->destAOH = NULL;
|
||||
commonInfo->destSlotID = 0;
|
||||
|
||||
curHero = hero;
|
||||
backpackSize = curHero->artifacts.size();
|
||||
|
||||
// Remove any previously allocated slots.
|
||||
for(size_t g=0; g<artWorn.size(); ++g)
|
||||
delete artWorn[g];
|
||||
for(size_t g=0; g<backpack.size(); ++g)
|
||||
delete backpack[g];
|
||||
backpack.clear();
|
||||
|
||||
std::vector<SDL_Rect> slotPos;
|
||||
if (curHero->artifacts.size() > 0)
|
||||
backpackPos %= curHero->artifacts.size();
|
||||
else
|
||||
backpackPos = 0;
|
||||
|
||||
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),
|
||||
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,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,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,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,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,pos.x+381,pos.y+296);
|
||||
|
||||
// Fill the slots for worn artifacts.
|
||||
// Fill the slots for worn artifacts and backpack.
|
||||
for (int g = 0; g < 19 ; g++)
|
||||
{
|
||||
artWorn[g] = new CArtPlace(hero->getArt(g));
|
||||
artWorn[g]->pos = slotPos[g];
|
||||
artWorn[g]->ourOwner = this;
|
||||
setSlotData(artWorn[g], g);
|
||||
}
|
||||
|
||||
// Fill the slots for the backpack.
|
||||
for(size_t s=0; s<5; ++s)
|
||||
{
|
||||
CArtPlace * add = new CArtPlace(NULL);
|
||||
|
||||
add->ourOwner = this;
|
||||
add->pos.x = pos.x + 403 + 46*s;
|
||||
add->pos.y = pos.y + 365;
|
||||
add->pos.h = add->pos.w = 44;
|
||||
|
||||
if (s < curHero->artifacts.size())
|
||||
setSlotData(add, 19 + (s + backpackPos)%curHero->artifacts.size());
|
||||
else
|
||||
setSlotData(add, 19 + s);
|
||||
backpack.push_back(add);
|
||||
}
|
||||
commonInfo->activeArtPlace = NULL;
|
||||
scrollBackpack(0);
|
||||
|
||||
//blocking scrolling if there is not enough artifacts to scroll
|
||||
leftArtRoll->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->destArtifact && commonInfo->destAOH == this) {
|
||||
// For an unlikely race condition scenario, put swapped artifact into backpack.
|
||||
LOCPLINT->cb->setArtifact(
|
||||
curHero,
|
||||
19 + curHero->artifacts.size(),
|
||||
commonInfo->destArtifact->id);
|
||||
}
|
||||
else if (commonInfo->srcArtifact && commonInfo->srcAOH == this) {
|
||||
if (commonInfo->srcSlotID != -1) { // Held artifact, just put it back to it's spot.
|
||||
LOCPLINT->cb->setArtifact(
|
||||
curHero,
|
||||
commonInfo->srcSlotID,
|
||||
commonInfo->srcArtifact->id);
|
||||
} else { // Swapped artifact.
|
||||
// Wear the artifact in a suitable spot.
|
||||
ui16 i = 0;
|
||||
for (; i < 19; i++) {
|
||||
if (artWorn[i]->fitsHere(commonInfo->srcArtifact)
|
||||
&& curHero->artifWorn.find(i) == curHero->artifWorn.end())
|
||||
{
|
||||
LOCPLINT->cb->setArtifact(
|
||||
curHero, i, commonInfo->srcArtifact->id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If it can't be worn, put it in the backpack.
|
||||
if (i == 19)
|
||||
LOCPLINT->cb->setArtifact(
|
||||
curHero,
|
||||
19 + curHero->artifacts.size(),
|
||||
commonInfo->srcArtifact->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
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()
|
||||
{
|
||||
curHero = NULL;
|
||||
for(size_t g=0; g<artWorn.size(); ++g)
|
||||
{
|
||||
delete artWorn[g];
|
||||
artWorn[g] = NULL;
|
||||
}
|
||||
for(size_t g=0; g<backpack.size(); ++g)
|
||||
{
|
||||
delete backpack[g];
|
||||
backpack[g] = NULL;
|
||||
}
|
||||
backpack.clear();
|
||||
if(commonInfo)
|
||||
commonInfo->activeArtPlace = NULL;
|
||||
}
|
||||
|
||||
void CArtifactsOfHero::scrollBackpack(int dir)
|
||||
{
|
||||
backpackPos += dir;
|
||||
if (backpackPos < 0) { // No guarantee of modulus behavior with negative operands.
|
||||
do {
|
||||
backpackPos += curHero->artifacts.size();
|
||||
} while (backpackPos < 0);
|
||||
} else {
|
||||
backpackPos %= curHero->artifacts.size();
|
||||
if (curHero->artifacts.size() > 0) {
|
||||
if (backpackPos < 0) { // No guarantee of modulus behavior with negative operands.
|
||||
do {
|
||||
backpackPos += curHero->artifacts.size();
|
||||
} while (backpackPos < 0);
|
||||
} else {
|
||||
backpackPos %= curHero->artifacts.size();
|
||||
}
|
||||
}
|
||||
|
||||
const int tempBackpackSize = curHero->artifacts.size() - (commonInfo->srcSlotID >= 19);
|
||||
|
||||
//set new data
|
||||
for (size_t s = 0; s < backpack.size(); ++s) {
|
||||
int slotID = 19 + (s + backpackPos)%tempBackpackSize;
|
||||
|
||||
// Don't show the held artifact, skip it.
|
||||
if (commonInfo->srcAOH == this && commonInfo->srcSlotID >= 19 && slotID >= commonInfo->srcSlotID)
|
||||
slotID++;
|
||||
|
||||
if (s < tempBackpackSize)
|
||||
setSlotData(backpack[s], slotID);
|
||||
if (s < curHero->artifacts.size())
|
||||
setSlotData(backpack[s], 19 + (s + backpackPos)%curHero->artifacts.size());
|
||||
else
|
||||
eraseSlotData(backpack[s], slotID);
|
||||
eraseSlotData(backpack[s], 19 + s);
|
||||
}
|
||||
|
||||
// Activate/deactivate sliders.
|
||||
leftArtRoll->block(tempBackpackSize <= backpack.size());
|
||||
rightArtRoll->block(tempBackpackSize <= backpack.size());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -4053,6 +4055,38 @@ CArtifactsOfHero::CArtifactsOfHero(const SDL_Rect & position) :
|
||||
pos = position;
|
||||
artWorn.resize(19);
|
||||
|
||||
std::vector<SDL_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),
|
||||
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,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,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,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,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,pos.x+381,pos.y+296);
|
||||
|
||||
// Create slots for worn artifacts.
|
||||
for (int g = 0; g < 19 ; g++)
|
||||
{
|
||||
artWorn[g] = new CArtPlace(NULL);
|
||||
artWorn[g]->pos = slotPos[g];
|
||||
artWorn[g]->ourOwner = this;
|
||||
eraseSlotData(artWorn[g], g);
|
||||
}
|
||||
|
||||
// Create slots for the backpack.
|
||||
for(size_t s=0; s<5; ++s)
|
||||
{
|
||||
CArtPlace * add = new CArtPlace(NULL);
|
||||
|
||||
add->ourOwner = this;
|
||||
add->pos.x = pos.x + 403 + 46*s;
|
||||
add->pos.y = pos.y + 365;
|
||||
add->pos.h = add->pos.w = 44;
|
||||
eraseSlotData(add, 19 + s);
|
||||
|
||||
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);
|
||||
rightArtRoll = new AdventureMapButton(std::string(), std::string(), boost::bind(&CArtifactsOfHero::scrollBackpack,this,+1), pos.x+632, pos.y+364, "hsbtns5.def", SDLK_RIGHT);
|
||||
}
|
||||
@ -4060,6 +4094,17 @@ CArtifactsOfHero::CArtifactsOfHero(const SDL_Rect & position) :
|
||||
CArtifactsOfHero::~CArtifactsOfHero()
|
||||
{
|
||||
dispose();
|
||||
for(size_t g=0; g<artWorn.size(); ++g)
|
||||
{
|
||||
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;
|
||||
@ -4261,7 +4306,6 @@ CExchangeWindow::CExchangeWindow(si32 hero1, si32 hero2) : bg(NULL)
|
||||
artifs[0] = new CArtifactsOfHero(genRect(600, 800, pos.x + -334, pos.y + 150));
|
||||
artifs[0]->commonInfo = new CArtifactsOfHero::SCommonPart;
|
||||
artifs[0]->commonInfo->participants.insert(artifs[0]);
|
||||
artifs[0]->commonInfo->activeArtPlace = NULL;
|
||||
artifs[0]->setHero(heroInst[0]);
|
||||
artifs[1] = new CArtifactsOfHero(genRect(600, 800, pos.x + 96, pos.y + 150));
|
||||
artifs[1]->commonInfo = artifs[0]->commonInfo;
|
||||
@ -4353,6 +4397,8 @@ CExchangeWindow::~CExchangeWindow() //d-tor
|
||||
delete quit;
|
||||
|
||||
//warning: don't experiment with these =NULL lines, they prevent heap corruption!
|
||||
artifs[0]->rollback();
|
||||
artifs[1]->rollback();
|
||||
delete artifs[0]->commonInfo;
|
||||
artifs[0]->commonInfo = NULL;
|
||||
delete artifs[0];
|
||||
|
@ -645,7 +645,6 @@ public:
|
||||
// lHand, rHand, neck, shoulders, head; //my types
|
||||
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 clicked;
|
||||
bool marked;
|
||||
CArtifactsOfHero * ourOwner;
|
||||
const CArtifact * ourArt;
|
||||
@ -666,7 +665,6 @@ class CArtifactsOfHero : public CIntObject
|
||||
{
|
||||
const CGHeroInstance * curHero;
|
||||
|
||||
size_t backpackSize; // Used to check differences in backpack sizes.
|
||||
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)
|
||||
@ -675,12 +673,12 @@ public:
|
||||
struct SCommonPart
|
||||
{
|
||||
std::set<CArtifactsOfHero *> participants; // Needed to mark slots.
|
||||
CArtPlace * activeArtPlace;
|
||||
const CArtifact * srcArtifact; // Held artifact., technically superfluous right now.
|
||||
const CArtifact * srcArtifact; // Held artifact.
|
||||
const CArtifactsOfHero * srcAOH; // Following two needed to uniquely identify the source.
|
||||
int srcSlotID; //
|
||||
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
|
||||
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
|
||||
|
||||
AdventureMapButton * leftArtRoll, * rightArtRoll;
|
||||
@ -691,6 +689,7 @@ public:
|
||||
|
||||
void setHero(const CGHeroInstance * hero);
|
||||
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 markPossibleSlots (const CArtifact* art);
|
||||
void unmarkSlots ();
|
||||
|
@ -38,6 +38,10 @@ const std::string & CArtifact::Description() const
|
||||
CArtHandler::CArtHandler()
|
||||
{
|
||||
VLC->arth = this;
|
||||
|
||||
// War machines are the default big artifacts.
|
||||
for (ui32 i = 3; i <= 6; i++)
|
||||
bigArtifacts.insert(i);
|
||||
}
|
||||
void CArtHandler::loadArtifacts(bool onlyTxt)
|
||||
{
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define __CARTHANDLER_H__
|
||||
#include "../global.h"
|
||||
#include "../lib/HeroBonus.h"
|
||||
#include <set>
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@ -43,11 +44,13 @@ class DLL_EXPORT CArtHandler //handles artifacts
|
||||
public:
|
||||
std::vector<CArtifact*> treasures, minors, majors, relics;
|
||||
std::vector<CArtifact> artifacts;
|
||||
std::set<ui32> bigArtifacts; // Artifacts that cannot be moved to backpack, e.g. war machines.
|
||||
|
||||
void loadArtifacts(bool onlyTxt);
|
||||
void sortArts();
|
||||
void addBonuses();
|
||||
void clear();
|
||||
bool isBigArtifact (ui32 artID) {return bigArtifacts.find(artID) != bigArtifacts.end();}
|
||||
static int convertMachineID(int id, bool creToArt);
|
||||
CArtHandler();
|
||||
|
||||
|
@ -1307,7 +1307,7 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed)
|
||||
players.insert(ins);
|
||||
}
|
||||
/******************RESOURCES****************************************************/
|
||||
//TODO: computer player should receive other amount of resource than computer (depending on difficulty)
|
||||
//TODO: computer player should receive other amount of resource than player (depending on difficulty)
|
||||
std::vector<int> startres;
|
||||
std::ifstream tis(DATA_DIR "/config/startres.txt");
|
||||
int k;
|
||||
|
@ -1226,6 +1226,22 @@ struct ExchangeArtifacts : public CPackForServer
|
||||
}
|
||||
};
|
||||
|
||||
struct SetArtifact : public CPackForServer
|
||||
{
|
||||
SetArtifact () {};
|
||||
SetArtifact (si32 hid, ui16 slot, int artID)
|
||||
:hid(hid), slot(slot), artID(artID) {};
|
||||
si32 hid;
|
||||
ui16 slot;
|
||||
int artID;
|
||||
|
||||
bool applyGh(CGameHandler *gh);
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & hid & slot & artID;
|
||||
}
|
||||
};
|
||||
|
||||
struct BuyArtifact : public CPackForServer
|
||||
{
|
||||
BuyArtifact(){};
|
||||
|
@ -137,6 +137,7 @@ void registerTypes3(Serializer &s)
|
||||
s.template registerType<UpgradeCreature>();
|
||||
s.template registerType<GarrisonHeroSwap>();
|
||||
s.template registerType<ExchangeArtifacts>();
|
||||
s.template registerType<SetArtifact>();
|
||||
s.template registerType<BuyArtifact>();
|
||||
s.template registerType<TradeOnMarketplace>();
|
||||
s.template registerType<SetFormation>();
|
||||
|
@ -2326,6 +2326,7 @@ bool CGameHandler::swapArtifacts(si32 srcHeroID, si32 destHeroID, ui16 srcSlot,
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: This relates to bug #112, fix later.
|
||||
// Make sure the artifacts are not war machines.
|
||||
if ((srcSlot>=13 && srcSlot<=16) || (destSlot>=13 && destSlot<=16)) {
|
||||
complain("Cannot move war machine!");
|
||||
@ -2363,6 +2364,28 @@ bool CGameHandler::swapArtifacts(si32 srcHeroID, si32 destHeroID, ui16 srcSlot,
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a hero artifact slot to contain a specific artifact.
|
||||
*
|
||||
* @param artID ID of an artifact or -1 for no artifact.
|
||||
*/
|
||||
bool CGameHandler::setArtifact(si32 heroID, ui16 slot, int artID)
|
||||
{
|
||||
CGHeroInstance *hero = gs->getHero(heroID);
|
||||
|
||||
// TODO: Deal with war machine placement.
|
||||
|
||||
// Perform the exchange.
|
||||
SetHeroArtifacts sha;
|
||||
sha.hid = heroID;
|
||||
sha.artifacts = hero->artifacts;
|
||||
sha.artifWorn = hero->artifWorn;
|
||||
sha.setArtAtPos(slot, artID);
|
||||
sendAndApply(&sha);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGameHandler::buyArtifact( ui32 hid, si32 aid )
|
||||
{
|
||||
CGHeroInstance *hero = gs->getHero(hid);
|
||||
|
@ -155,6 +155,7 @@ public:
|
||||
bool tradeResources( ui32 val, ui8 player, ui32 id1, ui32 id2 );
|
||||
bool buyArtifact( ui32 hid, si32 aid );
|
||||
bool swapArtifacts(si32 srcHeroID, si32 destHeroID, ui16 srcSlot, ui16 destSlot);
|
||||
bool setArtifact(si32 heroID, ui16 slot, int artID);
|
||||
bool garrisonSwap(si32 tid);
|
||||
bool upgradeCreature( ui32 objid, ui8 pos, ui32 upgID );
|
||||
bool recruitCreatures(si32 objid, ui32 crid, ui32 cram);
|
||||
|
@ -98,6 +98,12 @@ bool ExchangeArtifacts::applyGh( CGameHandler *gh )
|
||||
return gh->swapArtifacts(hid1,hid2,slot1,slot2);
|
||||
}
|
||||
|
||||
bool SetArtifact::applyGh( CGameHandler *gh )
|
||||
{
|
||||
ERROR_IF_NOT_OWNS(hid);
|
||||
return gh->setArtifact(hid, slot, artID);
|
||||
}
|
||||
|
||||
bool BuyArtifact::applyGh( CGameHandler *gh )
|
||||
{
|
||||
ERROR_IF_NOT_OWNS(hid);
|
||||
|
Loading…
x
Reference in New Issue
Block a user