1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-13 19:54:17 +02:00

A few fixes for artifacts.

This commit is contained in:
Michał W. Urbańczyk
2011-01-18 18:56:14 +00:00
parent a9c98d2b8c
commit 898ad292ea
17 changed files with 312 additions and 205 deletions

View File

@@ -511,7 +511,7 @@ void CCastleInterface::buildingClicked(int building)
else //both heroes present, use the visiting one
h = town->visitingHero;
if(h && !vstd::contains(h->artifWorn,ui16(17))) //hero doesn't have spellbok
if(h && !h->hasSpellbook()) //hero doesn't have spellbok
{
if(LOCPLINT->cb->getResourceAmount(6) < 500) //not enough gold to buy spellbook
{

View File

@@ -162,7 +162,7 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded /*= fals
}
assert(hero == curHero);
assert(hero->tempOwner == LOCPLINT->playerID); //for now we won't show hero windows for non-our heroes
assert(hero->tempOwner == LOCPLINT->playerID || hero->tempOwner == NEUTRAL_PLAYER); //for now we won't show hero windows for non-our heroes
specArea->text = CGI->generaltexth->hTxts[hero->subID].longBonus;

View File

@@ -766,8 +766,8 @@ void CKingdomInterface::CHeroItem::setHero(const CGHeroInstance * newHero)
garr = NULL;
}
char bufor[4000];
artLeft->block(hero->artifacts.size() <= 8);
artRight->block(hero->artifacts.size() <= 8);
artLeft->block(hero->artifactsInBackpack.size() <= 8);
artRight->block(hero->artifactsInBackpack.size() <= 8);
garr = new CGarrisonInt(pos.x+6, pos.y+78, 4, Point(), parent->slots->ourImages[parent->PicCount].bitmap,
Point(6,78), hero, NULL, true, true, true);
@@ -833,10 +833,10 @@ void CKingdomInterface::CHeroItem::setHero(const CGHeroInstance * newHero)
void CKingdomInterface::CHeroItem::scrollArts(int move)
{
backpackPos = ( backpackPos + move + hero->artifacts.size()) % hero->artifacts.size();
backpackPos = ( backpackPos + move + hero->artifactsInBackpack.size()) % hero->artifactsInBackpack.size();
for (int i=0; i<backpack.size(); i++)
{
backpack[i]->type = hero->getArtTypeId(19+(backpackPos + i)%hero->artifacts.size());
backpack[i]->type = hero->getArtTypeId(19+(backpackPos + i)%hero->artifactsInBackpack.size());
if (backpack[i]->type<0)
backpack[i]->hoverText ="";
else
@@ -909,7 +909,7 @@ void CKingdomInterface::CHeroItem::showAll(SDL_Surface * to)
case 2:
artLeft->show(to);
artRight->show(to);
int max = hero->artifacts.size();
int max = hero->artifactsInBackpack.size();
iter = std::min(8, max);
/*for (size_t it = 0 ; it<iter;it++)
blitAt(graphics->artDefs->ourImages[hero->artifacts[(it+backpackPos)%max]->id].bitmap,pos.x+293+48*it,pos.y+66,to);

View File

@@ -3516,9 +3516,9 @@ CAltarWindow::CAltarWindow(const IMarket *Market, const CGHeroInstance *Hero /*=
printAtMiddle(CGI->generaltexth->allTexts[478], 302, 423, FONT_SMALL, tytulowy, *bg); //%s's Creatures
sacrificeAll = new AdventureMapButton(CGI->generaltexth->zelp[571],boost::bind(&CAltarWindow::SacrificeAll,this),393,520,"ALTFILL.DEF");
sacrificeAll->block(!hero->artifacts.size() && !hero->artifWorn.size());
sacrificeAll->block(!hero->artifactsInBackpack.size() && !hero->artifactsWorn.size());
sacrificeBackpack = new AdventureMapButton(CGI->generaltexth->zelp[570],boost::bind(&CAltarWindow::SacrificeBackpack,this),147,520,"ALTEMBK.DEF");
sacrificeBackpack->block(!hero->artifacts.size());
sacrificeBackpack->block(!hero->artifactsInBackpack.size());
slider = NULL;
max = NULL;
@@ -4189,9 +4189,9 @@ CTavernWindow::HeroPortrait::HeroPortrait(int &sel, int id, int x, int y, const
hoverName = CGI->generaltexth->tavernInfo[4];
boost::algorithm::replace_first(hoverName,"%s",H->name);
int artifs = h->artifWorn.size() + h->artifacts.size();
int artifs = h->artifactsWorn.size() + h->artifactsInBackpack.size();
for(int i=13; i<=17; i++) //war machines and spellbook don't count
if(vstd::contains(h->artifWorn,i))
if(vstd::contains(h->artifactsWorn,i))
artifs--;
sprintf_s(descr, sizeof(descr),CGI->generaltexth->allTexts[215].c_str(),
h->name.c_str(), h->level, h->type->heroClass->name.c_str(), artifs);
@@ -4997,8 +4997,8 @@ void CArtifactsOfHero::setHero(const CGHeroInstance * hero)
// }
curHero = hero;
if (curHero->artifacts.size() > 0)
backpackPos %= curHero->artifacts.size();
if (curHero->artifactsInBackpack.size() > 0)
backpackPos %= curHero->artifactsInBackpack.size();
else
backpackPos = 0;
@@ -5269,13 +5269,19 @@ void CArtifactsOfHero::artifactMoved(const ArtifactLocation &src, const Artifact
}
else
{
commonInfo->src.art = src.getArt();
commonInfo->src.slotID = src.slot;
commonInfo->src.art = dst.getArt();
commonInfo->src.slotID = dst.slot;
assert(commonInfo->src.AOH);
CCS->curh->dragAndDropCursor(graphics->artDefs->ourImages[src.getArt()->artType->id].bitmap);
CCS->curh->dragAndDropCursor(graphics->artDefs->ourImages[dst.getArt()->artType->id].bitmap);
markPossibleSlots(dst.getArt());
}
}
else if(src.slot >= Arts::BACKPACK_START && src.slot < commonInfo->src.slotID && src.hero == commonInfo->src.AOH->curHero) //artifact taken from before currently picked one
{
int fixedSlot = src.hero->getArtPos(commonInfo->src.art);
commonInfo->src.slotID--;
assert(commonInfo->src.valid());
}
else
{
tlog1 << "Unexpected artifact movement...\n";
@@ -6937,4 +6943,10 @@ bool CArtifactsOfHero::SCommonPart::Artpos::operator==(const ArtifactLocation &a
//assert(al.getArt() == art);
return ret;
}
bool CArtifactsOfHero::SCommonPart::Artpos::valid()
{
assert(AOH && art);
return art == AOH->curHero->getArt(slotID);
}

View File

@@ -965,6 +965,7 @@ public:
Artpos();
void clear();
void setTo(const CArtPlace *place, bool dontTakeBackpack);
bool valid();
bool operator==(const ArtifactLocation &al) const;
} src, dst;

View File

@@ -396,27 +396,27 @@ void SetHeroesInTown::applyCl( CClient *cl )
cl->playerint[t->tempOwner]->heroInGarrisonChange(t);
}
void SetHeroArtifacts::applyCl( CClient *cl )
{
tlog1 << "SetHeroArtifacts :(\n";
// void SetHeroArtifacts::applyCl( CClient *cl )
// {
// tlog1 << "SetHeroArtifacts :(\n";
// //
// // CGHeroInstance *h = GS(cl)->getHero(hid);
// // CGameInterface *player = (vstd::contains(cl->playerint,h->tempOwner) ? cl->playerint[h->tempOwner] : NULL);
// // if(!player)
// // return;
//
// CGHeroInstance *h = GS(cl)->getHero(hid);
// CGameInterface *player = (vstd::contains(cl->playerint,h->tempOwner) ? cl->playerint[h->tempOwner] : NULL);
// if(!player)
// return;
//h->recreateArtBonuses();
//player->heroArtifactSetChanged(h);
// BOOST_FOREACH(Bonus bonus, gained)
// {
// player->heroBonusChanged(h,bonus,true);
// }
// BOOST_FOREACH(Bonus bonus, lost)
// {
// player->heroBonusChanged(h,bonus,false);
// }
}
// //h->recreateArtBonuses();
// //player->heroArtifactSetChanged(h);
//
// // BOOST_FOREACH(Bonus bonus, gained)
// // {
// // player->heroBonusChanged(h,bonus,true);
// // }
// // BOOST_FOREACH(Bonus bonus, lost)
// // {
// // player->heroBonusChanged(h,bonus,false);
// // }
// }
void HeroRecruited::applyCl( CClient *cl )
{

View File

@@ -119,31 +119,31 @@ bool CArtifact::fitsAt (const std::map<ui16, const CArtifact*> &artifWorn, ui16
return true;
}
bool CArtifact::canBeAssembledTo (const std::map<ui16, const CArtifact*> &artifWorn, ui32 artifactID) const
{
if (constituentOf == NULL || !vstd::contains(*constituentOf, artifactID))
return false;
const CArtifact &artifact = *VLC->arth->artifacts[artifactID];
assert(artifact.constituents);
BOOST_FOREACH(ui32 constituentID, *artifact.constituents)
{
bool found = false;
for (std::map<ui16, const CArtifact*>::const_iterator it = artifWorn.begin(); it != artifWorn.end(); ++it)
{
if (it->second->id == constituentID)
{
found = true;
break;
}
}
if (!found)
return false;
}
return true;
}
// bool CArtifact::canBeAssembledTo (const std::map<ui16, const CArtifact*> &artifWorn, ui32 artifactID) const
// {
// if (constituentOf == NULL || !vstd::contains(*constituentOf, artifactID))
// return false;
//
// const CArtifact &artifact = *VLC->arth->artifacts[artifactID];
// assert(artifact.constituents);
//
// BOOST_FOREACH(ui32 constituentID, *artifact.constituents)
// {
// bool found = false;
// for (std::map<ui16, const CArtifact*>::const_iterator it = artifWorn.begin(); it != artifWorn.end(); ++it)
// {
// if (it->second->id == constituentID)
// {
// found = true;
// break;
// }
// }
// if (!found)
// return false;
// }
//
// return true;
// }
CArtifact::CArtifact()
{
@@ -875,11 +875,11 @@ CArtifactInstance::CArtifactInstance( CArtifact *Art)
}
CArtifactInstance::CArtifactInstance(int aid)
{
init();
setType(VLC->arth->artifacts[aid]);
}
// CArtifactInstance::CArtifactInstance(int aid)
// {
// init();
// setType(VLC->arth->artifacts[aid]);
// }
void CArtifactInstance::setType( CArtifact *Art )
{
@@ -909,7 +909,7 @@ int CArtifactInstance::firstAvailableSlot(const CGHeroInstance *h) const
{
BOOST_FOREACH(ui16 slot, artType->possibleSlots)
{
if(artType->fitsAt(h->artifWorn, slot))
if(canBePutAt(ArtifactLocation(h, slot))) //if(artType->fitsAt(h->artifWorn, slot))
{
//we've found a free suitable slot.
return slot;
@@ -987,15 +987,27 @@ bool CArtifactInstance::canBeDisassembled() const
std::vector<const CArtifact *> CArtifactInstance::assemblyPossibilities(const CGHeroInstance *h) const
{
std::vector<const CArtifact *> ret;
if(!artType->constituentOf)
if(!artType->constituentOf //not a part of combined artifact
|| artType->constituents) //combined artifact already: no combining of combined artifacts... for now.
return ret;
BOOST_FOREACH(ui32 combination, *artType->constituentOf)
BOOST_FOREACH(ui32 possibleCombinedArt, *artType->constituentOf)
{
if (artType->canBeAssembledTo(h->artifWorn, combination))
const CArtifact * const artifact = VLC->arth->artifacts[possibleCombinedArt];
assert(artifact->constituents);
bool possible = true;
BOOST_FOREACH(ui32 constituentID, *artifact->constituents) //check if all constituents are available
{
ret.push_back(VLC->arth->artifacts[combination]);
if(!h->hasArt(constituentID, true)) //constituent must be equipped
{
possible = false;
break;
}
}
if(possible)
ret.push_back(artifact);
}
return ret;
@@ -1007,6 +1019,19 @@ void CArtifactInstance::move(ArtifactLocation &src, ArtifactLocation &dst)
putAt(dst.hero, dst.slot);
}
CArtifactInstance * CArtifactInstance::createNewArtifactInstance(CArtifact *Art)
{
if(!Art->constituents)
return new CArtifactInstance(Art);
else
return new CCombinedArtifactInstance(Art);
}
CArtifactInstance * CArtifactInstance::createNewArtifactInstance(int aid)
{
return createNewArtifactInstance(VLC->arth->artifacts[aid]);
}
bool CCombinedArtifactInstance::canBePutAt(const ArtifactLocation &al, bool assumeDestRemoved /*= false*/) const
{
return CArtifactInstance::canBePutAt(al, assumeDestRemoved);
@@ -1016,4 +1041,32 @@ bool CCombinedArtifactInstance::canBePutAt(const ArtifactLocation &al, bool assu
bool CCombinedArtifactInstance::canBeDisassembled() const
{
return true;
}
CCombinedArtifactInstance::CCombinedArtifactInstance(CArtifact *Art)
: CArtifactInstance(Art)
{
}
CCombinedArtifactInstance::CCombinedArtifactInstance()
{
}
void CCombinedArtifactInstance::createConstituents()
{
assert(artType);
assert(artType->constituents);
BOOST_FOREACH(ui32 a, *artType->constituents)
{
constituentsInfo.push_back(ConstituentInfo(CArtifactInstance::createNewArtifactInstance(a)));
}
}
CCombinedArtifactInstance::ConstituentInfo::ConstituentInfo(CArtifactInstance *Art /*= NULL*/, ui16 Slot /*= -1*/)
{
art = Art;
slot = Slot;
}

View File

@@ -32,7 +32,7 @@ public:
bool isBig () const;
bool isModable () const;
bool fitsAt (const std::map<ui16, const CArtifact*> &artifWorn, ui16 slot) const;
bool canBeAssembledTo (const std::map<ui16, const CArtifact*> &artifWorn, ui32 artifactID) const;
//bool canBeAssembledTo (const std::map<ui16, const CArtifact*> &artifWorn, ui32 artifactID) const;
void addBonusesTo (BonusList *otherBonuses) const;
void removeBonusesFrom (BonusList *otherBonuses) const;
virtual void SetProperty (int mod){};
@@ -49,7 +49,7 @@ public:
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<CBonusSystemNode&>(*this);;
h & static_cast<CBonusSystemNode&>(*this);
h & name & description & price & possibleSlots & constituents & constituentOf & aClass & id;
}
@@ -62,14 +62,16 @@ public:
class DLL_EXPORT CArtifactInstance : public CBonusSystemNode
{
protected:
void init();
CArtifactInstance(CArtifact *Art);
public:
CArtifactInstance();
ConstTransitivePtr<CArtifact> artType;
si32 id; //id of the instance
CArtifactInstance();
CArtifactInstance(CArtifact *Art);
CArtifactInstance(int aid);
//CArtifactInstance(int aid);
std::string nodeName() const OVERRIDE;
void setType(CArtifact *Art);
@@ -79,7 +81,6 @@ public:
virtual bool canBePutAt(const ArtifactLocation &al, bool assumeDestRemoved = false) const;
virtual bool canBeDisassembled() const;
std::vector<const CArtifact *> assemblyPossibilities(const CGHeroInstance *h) const;
void putAt(CGHeroInstance *h, ui16 slot);
@@ -93,13 +94,40 @@ public:
}
static CArtifactInstance *createScroll(const CSpell *s);
static CArtifactInstance *createNewArtifactInstance(CArtifact *Art);
static CArtifactInstance *createNewArtifactInstance(int aid);
};
class DLL_EXPORT CCombinedArtifactInstance : public CArtifactInstance
{
CCombinedArtifactInstance(CArtifact *Art);
public:
struct ConstituentInfo
{
ConstTransitivePtr<CArtifactInstance> art;
si16 slot;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & art & slot;
}
ConstituentInfo(CArtifactInstance *art = NULL, ui16 slot = -1);
};
std::vector<ConstituentInfo> constituentsInfo;
bool canBePutAt(const ArtifactLocation &al, bool assumeDestRemoved = false) const OVERRIDE;
bool canBeDisassembled() const OVERRIDE;
CCombinedArtifactInstance();
void createConstituents();
friend class CArtifactInstance;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<CArtifactInstance&>(*this);
h & constituentsInfo;
}
};
class DLL_EXPORT IModableArt : public CArtifact //artifact which can have different properties, such as scroll or banner

View File

@@ -522,7 +522,9 @@ void CCampaignScenario::prepareCrossoverHeroes( std::vector<CGHeroInstance *> he
{
BOOST_FOREACH(CGHeroInstance * cgh, crossoverHeroes)
{
cgh->artifacts -= VLC->arth->artifacts[g];
tlog1 << "TODO TODO TODO - take artifacts from hero\n";
//TODO how was that supposed to work with worn artifacts?
//cgh->artifactsInBackpack -= VLC->arth->artifacts[g];
}
}
}

View File

@@ -1379,11 +1379,7 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
toGive = VLC->arth->artifacts[VLC->arth->getRandomArt (CArtifact::ART_TREASURE)];
CGHeroInstance *hero = k->second.heroes[0];
std::vector<ui16>::iterator slot = vstd::findFirstNot (hero->artifWorn, toGive->possibleSlots);
if(slot != toGive->possibleSlots.end())
VLC->arth->equipArtifact(hero->artifWorn, *slot, toGive);
else
hero->giveArtifact(toGive->id);
hero->giveArtifact(toGive->id);
}
}
}
@@ -2675,7 +2671,7 @@ struct statsHLP
int ret = 0;
for(int g=0; g<ps->heroes.size(); ++g)
{
ret += ps->heroes[g]->artifacts.size() + ps->heroes[g]->artifWorn.size();
ret += ps->heroes[g]->artifactsInBackpack.size() + ps->heroes[g]->artifactsWorn.size();
}
return ret;
}

View File

@@ -791,10 +791,10 @@ void CGHeroInstance::initHero()
spells -= 0xffffffff;
if(!getArt(Arts::MACH4) && type->startingSpell >= 0) //no catapult means we haven't read pre-existant set -> use default rules for spellbook
putArtifact(Arts::SPELLBOOK, new CArtifactInstance(0));
putArtifact(Arts::SPELLBOOK, CArtifactInstance::createNewArtifactInstance(0));
if(!getArt(Arts::MACH4))
putArtifact(Arts::MACH4, new CArtifactInstance(3)); //everyone has a catapult
putArtifact(Arts::MACH4, CArtifactInstance::createNewArtifactInstance(3)); //everyone has a catapult
if(portrait < 0 || portrait == 255)
portrait = subID;
@@ -878,7 +878,7 @@ void CGHeroInstance::initArmy(CCreatureSet *dst /*= NULL*/)
}
if(!getArt(slot))
putArtifact(slot, new CArtifactInstance(aid));
putArtifact(slot, CArtifactInstance::createNewArtifactInstance(aid));
else
tlog3 << "Hero " << name << " already has artifact at " << slot << ", ommiting giving " << aid << std::endl;
}
@@ -1429,22 +1429,24 @@ si32 CGHeroInstance::manaRegain() const
void CGHeroInstance::giveArtifact (ui32 aid) //use only for fixed artifacts
{
CArtifact * const artifact = VLC->arth->artifacts[aid]; //pointer to constant object
if (artifact->isBig())
{
for (std::vector<ui16>::const_iterator it = artifact->possibleSlots.begin(); it != artifact->possibleSlots.end(); ++it)
{
if (!vstd::contains(artifWorn, *it))
{
VLC->arth->equipArtifact(artifWorn, *it, artifact);
break;
}
}
}
else
{
artifacts.push_back(artifact);
}
CArtifactInstance *ai = CArtifactInstance::createNewArtifactInstance(artifact);
ai->putAt(this, ai->firstAvailableSlot(this));
//
// if (artifact->isBig())
// {
// for (std::vector<ui16>::const_iterator it = artifact->possibleSlots.begin(); it != artifact->possibleSlots.end(); ++it)
// {
// if (!vstd::contains(artifWorn, *it))
// {
// VLC->arth->equipArtifact(artifWorn, *it, artifact);
// break;
// }
// }
// }
// else
// {
// artifacts.push_back(artifact);
// }
}
int CGHeroInstance::getBoatType() const
@@ -1576,6 +1578,11 @@ void CGHeroInstance::putInBackpack(CArtifactInstance *art)
putArtifact(art->firstBackpackSlot(this), art);
}
bool CGHeroInstance::hasSpellbook() const
{
return getArt(Arts::SPELLBOOK);
}
void CGDwelling::initObj()
{
switch(ID)
@@ -7016,4 +7023,4 @@ si32 CArtifactSet::getArtTypeId(ui16 pos) const
CArtifactSet::~CArtifactSet()
{
}
}

View File

@@ -315,8 +315,8 @@ public:
const CGBoat *boat; //set to CGBoat when sailing
std::vector<const CArtifact*> artifacts; //hero's artifacts from bag
std::map<ui16, const CArtifact*> 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::vector<const CArtifact*> artifacts; //hero's artifacts from bag
//std::map<ui16, const CArtifact*> 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)
@@ -350,7 +350,7 @@ public:
h & static_cast<CArmedInstance&>(*this);
h & static_cast<CArtifactSet&>(*this);
h & exp & level & name & biography & portrait & mana & secSkills & movement
& sex & inTownGarrison & artifacts & artifWorn & spells & patrol & moveDir;
& sex & inTownGarrison & /*artifacts & artifWorn & */spells & patrol & moveDir;
h & type & speciality;
//visitied town pointer will be restored by map serialization method
@@ -368,6 +368,7 @@ public:
//////////////////////////////////////////////////////////////////////////
bool hasSpellbook() const;
EAlignment getAlignment() const;
const std::string &getBiography() const;
bool needsLastStack()const;

View File

@@ -604,25 +604,25 @@ struct SetHeroesInTown : public CPackForClient //508
}
};
struct SetHeroArtifacts : public CPackForClient //509
{
SetHeroArtifacts(){type = 509;};
void applyCl(CClient *cl);
DLL_EXPORT void applyGs(CGameState *gs);
DLL_EXPORT void setArtAtPos(ui16 pos, const CArtifact* art);
si32 hid;
std::vector<const CArtifact*> artifacts; //hero's artifacts from bag
std::map<ui16, const CArtifact*> 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
template <typename Handler> void serialize(Handler &h, const int version)
{
h & hid & artifacts & artifWorn;
}
std::vector<const CArtifact*> equiped, unequiped; //used locally
BonusList gained, lost; //used locally as hlp when applying
};
// struct SetHeroArtifacts : public CPackForClient //509
// {
// SetHeroArtifacts(){type = 509;};
// void applyCl(CClient *cl);
// DLL_EXPORT void applyGs(CGameState *gs);
// DLL_EXPORT void setArtAtPos(ui16 pos, const CArtifact* art);
//
// si32 hid;
// std::vector<const CArtifact*> artifacts; //hero's artifacts from bag
// std::map<ui16, const CArtifact*> 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
//
// template <typename Handler> void serialize(Handler &h, const int version)
// {
// h & hid & artifacts & artifWorn;
// }
//
// std::vector<const CArtifact*> equiped, unequiped; //used locally
// BonusList gained, lost; //used locally as hlp when applying
// };
struct HeroRecruited : public CPackForClient //515
{

View File

@@ -288,6 +288,8 @@ DLL_EXPORT void RemoveObject::applyGs( CGameState *gs )
gs->hpool.heroesPool[h->subID] = h;
if(!vstd::contains(gs->hpool.pavailable, h->subID))
gs->hpool.pavailable[h->subID] = 0xff;
return;
}
else if (obj->ID==CREI_TYPE && gs->map->version > CMapHeader::RoE) //only fixed monsters can be a part of quest
{
@@ -443,48 +445,48 @@ DLL_EXPORT void SetHeroesInTown::applyGs( CGameState *gs )
}
}
DLL_EXPORT void SetHeroArtifacts::applyGs( CGameState *gs )
{
CGHeroInstance *h = gs->getHero(hid);
for(std::map<ui16, const CArtifact*>::const_iterator i = h->artifWorn.begin(); i != h->artifWorn.end(); i++)
if(!vstd::contains(artifWorn,i->first) || artifWorn[i->first] != i->second)
unequiped.push_back(i->second);
for(std::map<ui16, const CArtifact*>::iterator i = artifWorn.begin(); i != artifWorn.end(); i++)
if(!vstd::contains(h->artifWorn,i->first) || h->artifWorn[i->first] != i->second)
{
equiped.push_back(i->second);
}
//update hero data
h->artifacts = artifacts;
h->artifWorn = artifWorn;
}
DLL_EXPORT void SetHeroArtifacts::setArtAtPos(ui16 pos, const CArtifact* art)
{
if(!art)
{
if(pos<19)
VLC->arth->unequipArtifact(artifWorn, pos);
else if (pos - 19 < artifacts.size())
artifacts.erase(artifacts.begin() + (pos - 19));
}
else
{
if (pos < 19)
{
VLC->arth->equipArtifact(artifWorn, pos, art);
}
else // Goes into the backpack.
{
if(pos - 19 < artifacts.size())
artifacts.insert(artifacts.begin() + (pos - 19), art);
else
artifacts.push_back(art);
}
}
}
// DLL_EXPORT void SetHeroArtifacts::applyGs( CGameState *gs )
// {
// CGHeroInstance *h = gs->getHero(hid);
// for(std::map<ui16, const CArtifact*>::const_iterator i = h->artifWorn.begin(); i != h->artifWorn.end(); i++)
// if(!vstd::contains(artifWorn,i->first) || artifWorn[i->first] != i->second)
// unequiped.push_back(i->second);
//
// for(std::map<ui16, const CArtifact*>::iterator i = artifWorn.begin(); i != artifWorn.end(); i++)
// if(!vstd::contains(h->artifWorn,i->first) || h->artifWorn[i->first] != i->second)
// {
// equiped.push_back(i->second);
// }
//
// //update hero data
// h->artifacts = artifacts;
// h->artifWorn = artifWorn;
// }
//
// DLL_EXPORT void SetHeroArtifacts::setArtAtPos(ui16 pos, const CArtifact* art)
// {
// if(!art)
// {
// if(pos<19)
// VLC->arth->unequipArtifact(artifWorn, pos);
// else if (pos - 19 < artifacts.size())
// artifacts.erase(artifacts.begin() + (pos - 19));
// }
// else
// {
// if (pos < 19)
// {
// VLC->arth->equipArtifact(artifWorn, pos, art);
// }
// else // Goes into the backpack.
// {
// if(pos - 19 < artifacts.size())
// artifacts.insert(artifacts.begin() + (pos - 19), art);
// else
// artifacts.push_back(art);
// }
// }
// }
DLL_EXPORT void HeroRecruited::applyGs( CGameState *gs )
@@ -588,7 +590,7 @@ DLL_EXPORT void NewArtifact::applyGs( CGameState *gs )
gs->map->artInstances.push_back(art);
assert(!art->parents.size());
art->attachTo(art->artType);
art->setType(art->artType);
}
DLL_EXPORT const CStackInstance * StackLocation::getStack()

View File

@@ -79,6 +79,9 @@ void registerTypes1(Serializer &s)
s.template registerType<CreatureNativeTerrainLimiter>();
s.template registerType<CreatureFactionLimiter>();
s.template registerType<CreatureAlignmentLimiter>();
s.template registerType<CArtifactInstance>();
s.template registerType<CCombinedArtifactInstance>();
}
template<typename Serializer> DLL_EXPORT
@@ -110,7 +113,7 @@ void registerTypes2(Serializer &s)
s.template registerType<RazeStructures>();
s.template registerType<SetAvailableCreatures>();
s.template registerType<SetHeroesInTown>();
s.template registerType<SetHeroArtifacts>();
//s.template registerType<SetHeroArtifacts>();
s.template registerType<HeroRecruited>();
s.template registerType<GiveHero>();
s.template registerType<NewTurn>();

View File

@@ -2037,8 +2037,12 @@ bool Mapa::loadArtifactToSlot(CGHeroInstance *h, int slot, const unsigned char *
int aid = readNormalNr(bufor,i, artidlen); i+=artidlen;
bool isArt = aid != artmask;
if(isArt)
h->putArtifact(slot, createArt(aid));
{
if(vstd::contains(VLC->arth->bigArtifacts, aid) && slot >= Arts::BACKPACK_START)
tlog3 << "Warning: A big artifact (war machine) in hero's backpack, ignoring...\n";
else
h->putArtifact(slot, createArt(aid));
}
return isArt;
}
@@ -2068,7 +2072,7 @@ void Mapa::loadArtifactsOfHero(const unsigned char * bufor, int & i, CGHeroInsta
//bag artifacts //20
int amount = readNormalNr(bufor,i, 2); i+=2; //number of artifacts in hero's bag
for(int ss = 0; ss < amount; ++ss)
loadArtifactToSlot(nhi, Arts::BACKPACK_START + ss, bufor, i);
loadArtifactToSlot(nhi, Arts::BACKPACK_START + nhi->artifactsInBackpack.size(), bufor, i);
} //artifacts
}
@@ -2076,7 +2080,7 @@ CArtifactInstance * Mapa::createArt(int aid)
{
CArtifactInstance *a = NULL;
if(aid >= 0)
a = new CArtifactInstance(aid);
a = CArtifactInstance::createNewArtifactInstance(aid);
else
a = new CArtifactInstance();

View File

@@ -1190,7 +1190,7 @@ void CGameHandler::checkForBattleEnd( std::vector<CStack*> &stacks )
void CGameHandler::giveSpells( const CGTownInstance *t, const CGHeroInstance *h )
{
if(!vstd::contains(h->artifWorn,17))
if(!h->hasSpellbook())
return; //hero hasn't spellbok
ChangeSpells cs;
cs.hid = h->id;
@@ -1759,7 +1759,7 @@ void CGameHandler::useScholarSkill(si32 fromHero, si32 toHero)
}
int ScholarLevel = h1->getSecSkillLevel(CGHeroInstance::SCHOLAR);//heroes can trade up to this level
if (!ScholarLevel || !vstd::contains(h1->artifWorn,17) || !vstd::contains(h2->artifWorn,17) )
if (!ScholarLevel || !h1->hasSpellbook() || !h2->hasSpellbook() )
return;//no scholar skill or no spellbook
int h1Lvl = std::min(ScholarLevel+1, h1->getSecSkillLevel(CGHeroInstance::WISDOM)+2),
@@ -2707,7 +2707,7 @@ bool CGameHandler::buyArtifact( ui32 hid, si32 aid )
else if(aid < 7 && aid > 3) //war machine
{
int price = VLC->arth->artifacts[aid]->price;
if(vstd::contains(hero->artifWorn,ui16(9+aid)) && complain("Hero already has this machine!")
if(hero->getArt(9+aid) && complain("Hero already has this machine!")
|| !vstd::contains(town->builtBuildings,si32(16)) && complain("No blackismith!")
|| gs->getPlayer(hero->getOwner())->resources[Res::GOLD] < price && complain("Not enough gold!") //no gold
|| (!(town->subID == 6 && vstd::contains(town->builtBuildings,si32(22) ) )
@@ -3326,7 +3326,6 @@ void CGameHandler::playerMessage( ui8 player, const std::string &message )
{
SetMana sm;
ChangeSpells cs;
SetHeroArtifacts sha;
CGHeroInstance *h = gs->getHero(gs->getPlayer(player)->currentSelection);
if(!h && complain("Cannot realize cheat, no hero selected!")) return;
@@ -3344,15 +3343,8 @@ void CGameHandler::playerMessage( ui8 player, const std::string &message )
//give mana
sm.val = 999;
if(!h->getArt(17)) //hero doesn't have spellbook
{
//give spellbook
sha.hid = h->id;
sha.artifacts = h->artifacts;
sha.artifWorn = h->artifWorn;
VLC->arth->equipArtifact(sha.artifWorn, 17, 0);
sendAndApply(&sha);
}
if(!h->hasSpellbook()) //hero doesn't have spellbook
giveHeroNewArtifact(h, VLC->arth->artifacts[0], Arts::SPELLBOOK); //give spellbook
sendAndApply(&cs);
sendAndApply(&sm);
@@ -3381,14 +3373,13 @@ void CGameHandler::playerMessage( ui8 player, const std::string &message )
{
CGHeroInstance *hero = gs->getHero(gs->getPlayer(player)->currentSelection);
if(!hero) return;
SetHeroArtifacts sha;
sha.hid = hero->id;
sha.artifacts = hero->artifacts;
sha.artifWorn = hero->artifWorn;
VLC->arth->equipArtifact(sha.artifWorn, 13, VLC->arth->artifacts[4]);
VLC->arth->equipArtifact(sha.artifWorn, 14, VLC->arth->artifacts[5]);
VLC->arth->equipArtifact(sha.artifWorn, 15, VLC->arth->artifacts[6]);
sendAndApply(&sha);
if(!hero->getArt(Arts::MACH1))
giveHeroNewArtifact(hero, VLC->arth->artifacts[4], Arts::MACH1);
if(!hero->getArt(Arts::MACH2))
giveHeroNewArtifact(hero, VLC->arth->artifacts[5], Arts::MACH2);
if(!hero->getArt(Arts::MACH3))
giveHeroNewArtifact(hero, VLC->arth->artifacts[6], Arts::MACH3);
}
else if(message == "vcminahar") //1000000 movement points
{
@@ -3440,16 +3431,19 @@ void CGameHandler::playerMessage( ui8 player, const std::string &message )
{
CGHeroInstance *hero = gs->getHero(gs->getPlayer(player)->currentSelection);
if(!hero) return;
SetHeroArtifacts sha;
sha.hid = hero->id;
sha.artifacts = hero->artifacts;
sha.artifWorn = hero->artifWorn;
sha.artifacts.push_back(VLC->arth->artifacts[2]); //grail
for (int g=7; g<=140; ++g)
{
sha.artifacts.push_back(VLC->arth->artifacts[g]);
}
sendAndApply(&sha);
giveHeroNewArtifact(hero, VLC->arth->artifacts[g], -1);
// SetHeroArtifacts sha;
// sha.hid = hero->id;
// sha.artifacts = hero->artifacts;
// sha.artifWorn = hero->artifWorn;
// sha.artifacts.push_back(VLC->arth->artifacts[2]); //grail
// for (int g=7; g<=140; ++g)
// {
// sha.artifacts.push_back(VLC->arth->artifacts[g]);
// }
// sendAndApply(&sha);
}
else
cheated = false;
@@ -5037,7 +5031,11 @@ void CGameHandler::moveArtifact(const ArtifactLocation &al1, const ArtifactLocat
void CGameHandler::giveHeroNewArtifact(const CGHeroInstance *h, const CArtifact *artType, int pos)
{
CArtifactInstance *a = new CArtifactInstance();
CArtifactInstance *a = NULL;
if(artType->constituents)
a = new CArtifactInstance();
else
a = new CCombinedArtifactInstance();
a->artType = artType; //*NOT* via settype -> all bonus-related stuff must be done by NewArtifact apply
NewArtifact na;