From ebb9c84da9e2cda52f875c530ca6f6eb44637740 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20W=2E=20Urba=C5=84czyk?= Date: Thu, 30 Dec 2010 14:41:46 +0000 Subject: [PATCH] Artifacts, updated map loading. --- global.h | 2 +- lib/CArtHandler.cpp | 8 ++- lib/CArtHandler.h | 1 + lib/CObjectHandler.cpp | 41 ++++++++--- lib/CObjectHandler.h | 3 + lib/NetPacksLib.cpp | 3 +- lib/map.cpp | 154 ++++++++++++++++------------------------ lib/map.h | 4 ++ server/CGameHandler.cpp | 2 +- 9 files changed, 110 insertions(+), 108 deletions(-) diff --git a/global.h b/global.h index 5ff634454..152b96a55 100644 --- a/global.h +++ b/global.h @@ -151,7 +151,7 @@ namespace Arts AFTER_LAST }; const ui16 BACKPACK_START = 19; - const int LOCK_ID = 145; + const int ID_CATAPULT = 3, ID_LOCK = 145; } enum EAlignment diff --git a/lib/CArtHandler.cpp b/lib/CArtHandler.cpp index 7112087c3..9ee6d249a 100644 --- a/lib/CArtHandler.cpp +++ b/lib/CArtHandler.cpp @@ -875,6 +875,12 @@ CArtifactInstance::CArtifactInstance( CArtifact *Art) } +CArtifactInstance::CArtifactInstance(int aid) +{ + init(); + setType(VLC->arth->artifacts[aid]); +} + void CArtifactInstance::setType( CArtifact *Art ) { artType = Art; @@ -947,7 +953,7 @@ void CArtifactInstance::putAt(CGHeroInstance *h, ui16 slot) ArtSlotInfo &asi = slot < Arts::BACKPACK_START ? h->artifactsWorn[slot] - : *h->artifactsInBackpack.insert(h->artifactsInBackpack.begin() + slot - Arts::BACKPACK_START, ArtSlotInfo()); + : *h->artifactsInBackpack.insert(h->artifactsInBackpack.begin() + (slot - Arts::BACKPACK_START), ArtSlotInfo()); asi.artifact = this; asi.locked = false; diff --git a/lib/CArtHandler.h b/lib/CArtHandler.h index 0e98717c7..eb8c96a87 100644 --- a/lib/CArtHandler.h +++ b/lib/CArtHandler.h @@ -69,6 +69,7 @@ public: CArtifactInstance(); CArtifactInstance(CArtifact *Art); + CArtifactInstance(int aid); std::string nodeName() const OVERRIDE; void setType(CArtifact *Art); diff --git a/lib/CObjectHandler.cpp b/lib/CObjectHandler.cpp index 2a8c32759..e26102a29 100644 --- a/lib/CObjectHandler.cpp +++ b/lib/CObjectHandler.cpp @@ -790,12 +790,12 @@ void CGHeroInstance::initHero() else //remove placeholder spells -= 0xffffffff; - if(!vstd::contains(artifWorn, 16) && type->startingSpell >= 0) //no catapult means we haven't read pre-existant set - { - VLC->arth->equipArtifact(artifWorn, 17, VLC->arth->artifacts[0]); //give spellbook - } - VLC->arth->equipArtifact(artifWorn, 16, VLC->arth->artifacts[3]); //everyone has a catapult + 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)); + if(!getArt(Arts::MACH4)) + putArtifact(Arts::MACH4, new CArtifactInstance(3)); //everyone has a catapult + if(portrait < 0 || portrait == 255) portrait = subID; if(!hasBonus(Selector::sourceType(Bonus::HERO_BASE_SKILL))) @@ -861,18 +861,26 @@ void CGHeroInstance::initArmy(CCreatureSet *dst /*= NULL*/) if(creID>=145 && creID<=149) //war machine { warMachinesGiven++; + if(dst != this) + continue; + + int slot = -1, aid = -1; switch (creID) { case 145: //catapult - VLC->arth->equipArtifact(artifWorn, 16, VLC->arth->artifacts[3]); + slot = Arts::MACH4; + aid = 3; break; default: - VLC->arth->equipArtifact( - artifWorn, - 9+CArtHandler::convertMachineID(creID,true), - VLC->arth->artifacts[CArtHandler::convertMachineID(creID,true)]); + aid = CArtHandler::convertMachineID(creID,true); + slot = 9 + aid; break; } + + if(!getArt(slot)) + putArtifact(slot, new CArtifactInstance(aid)); + else + tlog3 << "Hero " << name << " already has artifact at " << slot << ", ommiting giving " << aid << std::endl; } else dst->putStack(stackNo-warMachinesGiven, new CStackInstance(creID, count)); @@ -1542,6 +1550,17 @@ std::string CGHeroInstance::nodeName() const return "Hero " + name; } +void CGHeroInstance::putArtifact(ui16 pos, CArtifactInstance *art) +{ + assert(!getArt(pos)); + art->putAt(this, pos); +} + +void CGHeroInstance::putInBackpack(CArtifactInstance *art) +{ + putArtifact(art->firstBackpackSlot(this), art); +} + void CGDwelling::initObj() { switch(ID) @@ -6982,4 +7001,4 @@ si32 CArtifactSet::getArtTypeId(ui16 pos) const CArtifactSet::~CArtifactSet() { -} \ No newline at end of file +} diff --git a/lib/CObjectHandler.h b/lib/CObjectHandler.h index 8073a0d27..a95533f46 100644 --- a/lib/CObjectHandler.h +++ b/lib/CObjectHandler.h @@ -272,6 +272,7 @@ public: bool isPositionFree(ui16 pos) const; si32 getArtTypeId(ui16 pos) const; + virtual ~CArtifactSet(); template void serialize(Handler &h, const int version) @@ -407,6 +408,8 @@ public: void initHero(); void initHero(int SUBID); + void putArtifact(ui16 pos, CArtifactInstance *art); + void putInBackpack(CArtifactInstance *art); void initExp(); void initArmy(CCreatureSet *dst = NULL); void giveArtifact (ui32 aid); diff --git a/lib/NetPacksLib.cpp b/lib/NetPacksLib.cpp index 92295ad4f..7e55b51fc 100644 --- a/lib/NetPacksLib.cpp +++ b/lib/NetPacksLib.cpp @@ -699,7 +699,8 @@ DLL_EXPORT void RebalanceStacks::applyGs( CGameState *gs ) DLL_EXPORT void PutArtifact::applyGs( CGameState *gs ) { assert(art->canBePutAt(al)); - art->putAt(al.hero, al.slot); + al.hero->putArtifact(al.slot, art); + //art->putAt(al.hero, al.slot); } DLL_EXPORT void EraseArtifact::applyGs( CGameState *gs ) diff --git a/lib/map.cpp b/lib/map.cpp index 9aeaabf5e..b1a1c7984 100644 --- a/lib/map.cpp +++ b/lib/map.cpp @@ -848,52 +848,7 @@ CGObjectInstance * Mapa::loadHero(const unsigned char * bufor, int &i) readCreatureSet(nhi, bufor, i, 7, version > RoE); nhi->formation =bufor[i]; ++i; //formation - bool artSet = bufor[i]; ++i; //true if artifact set is not default (hero has some artifacts) - int artmask = version == RoE ? 0xff : 0xffff; - int artidlen = version == RoE ? 1 : 2; - if(artSet) - { - for(int pom=0;pom<16;pom++) - { - int id = readNormalNr(bufor,i, artidlen); i+=artidlen; - if(id != artmask) - VLC->arth->equipArtifact(nhi->artifWorn, pom, VLC->arth->artifacts[id]); - } - //misc5 art //17 - if(version>=SoD) - { - int id = readNormalNr(bufor,i, artidlen); i+=artidlen; - if(id!=artmask) - VLC->arth->equipArtifact(nhi->artifWorn, 16, VLC->arth->artifacts[id]); - else - VLC->arth->equipArtifact(nhi->artifWorn, 16, VLC->arth->artifacts[3]); //catapult by default - } - //spellbook - int id = readNormalNr(bufor,i, artidlen); i+=artidlen; - if(id!=artmask) - VLC->arth->equipArtifact(nhi->artifWorn, 17, VLC->arth->artifacts[id]); - //19 //???what is that? gap in file or what? - it's probably fifth slot.. - if(version>RoE) - { - id = readNormalNr(bufor,i, artidlen); i+=artidlen; - if(id!=artmask) - VLC->arth->equipArtifact(nhi->artifWorn, 18, VLC->arth->artifacts[id]); - } - else - i+=1; - //bag artifacts //20 - int amount = readNormalNr(bufor,i, 2); i+=2; //number of artifacts in hero's bag - if(amount > 0) - { - for(int ss = 0; ss < amount; ++ss) - { - id = readNormalNr(bufor,i, artidlen); i+=artidlen; - if(id != artmask) - nhi->giveArtifact(id); - } - } - } //artifacts - + loadArtifactsOfHero(bufor, i, nhi); nhi->patrol.patrolRadious = readNormalNr(bufor,i, 1); ++i; if(nhi->patrol.patrolRadious == 0xff) nhi->patrol.patrolling = false; @@ -1089,50 +1044,9 @@ void Mapa::readPredefinedHeroes( const unsigned char * bufor, int &i) cgh->secSkills[yy].second = readNormalNr(bufor,i, 1); ++i; } } - bool artSet = bufor[i]; ++i; //true if artifact set is not default (hero has some artifacts) - int artmask = version == RoE ? 0xff : 0xffff; - int artidlen = version == RoE ? 1 : 2; - if(artSet) - { - for(int pom=0;pom<16;pom++) - { - int id = readNormalNr(bufor,i, artidlen); i+=artidlen; - if(id!=artmask) - VLC->arth->equipArtifact(cgh->artifWorn, pom, VLC->arth->artifacts[id]); - } - //misc5 art //17 - if(version>=SoD) - { - i+=2; - //int id = readNormalNr(bufor,i, artidlen); i+=artidlen; - //if(id!=artmask) - // spec->artifWorn[16] = id; - } - //spellbook - int id = readNormalNr(bufor,i, artidlen); i+=artidlen; - if(id!=artmask) - VLC->arth->equipArtifact(cgh->artifWorn, 17, VLC->arth->artifacts[id]); - //19 //???what is that? gap in file or what? - it's probably fifth slot.. - if(version>RoE) - { - id = readNormalNr(bufor,i, artidlen); i+=artidlen; - if(id!=artmask) - VLC->arth->equipArtifact(cgh->artifWorn, 18, VLC->arth->artifacts[id]); - } - else - i+=1; - //bag artifacts //20 - int amount = readNormalNr(bufor,i, 2); i+=2; //number of artifacts in hero's bag - if(amount>0) - { - for(int ss=0; ssgiveArtifact(id); - } - } - } //artifacts + + loadArtifactsOfHero(bufor, i, cgh); + if(readChar(bufor,i))//customBio cgh->biography = readString(bufor,i); int sex = bufor[i++]; // 0xFF is default, 00 male, 01 female //FIXME:unused? @@ -1578,14 +1492,13 @@ void Mapa::readObjects( const unsigned char * bufor, int &i) } else if(art->ID == 5) //specific artifact { - innerArt = new CArtifactInstance(VLC->arth->artifacts[art->subID]); + innerArt = createArt(art->subID); } else { - innerArt = new CArtifactInstance(); + innerArt = createArt(-1); } art->storedArtifact = innerArt; - addNewArtifactInstance(innerArt); break; } case 76: case 79: //random resource; resource @@ -2116,6 +2029,61 @@ void Mapa::addNewArtifactInstance( CArtifactInstance *art ) artInstances.push_back(art); } +bool Mapa::loadArtifactToSlot(CGHeroInstance *h, int slot, const unsigned char * bufor, int &i) +{ + const int artmask = version == RoE ? 0xff : 0xffff; + const int artidlen = version == RoE ? 1 : 2; + + int aid = readNormalNr(bufor,i, artidlen); i+=artidlen; + bool isArt = aid != artmask; + if(isArt) + h->putArtifact(slot, createArt(aid)); + + return isArt; +} + +void Mapa::loadArtifactsOfHero(const unsigned char * bufor, int & i, CGHeroInstance * nhi) +{ + bool artSet = bufor[i]; ++i; //true if artifact set is not default (hero has some artifacts) + if(artSet) + { + for(int pom=0;pom<16;pom++) + loadArtifactToSlot(nhi, pom, bufor, i); + + //misc5 art //17 + if(version >= SoD) + { + if(!loadArtifactToSlot(nhi, Arts::MACH4, bufor, i)) + nhi->putArtifact(Arts::MACH4, createArt(Arts::ID_CATAPULT)); //catapult by default + } + + loadArtifactToSlot(nhi, Arts::SPELLBOOK, bufor, i); + + //19 //???what is that? gap in file or what? - it's probably fifth slot.. + if(version > RoE) + loadArtifactToSlot(nhi, Arts::MISC5, bufor, i); + else + i+=1; + + //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); + } //artifacts +} + +CArtifactInstance * Mapa::createArt(int aid) +{ + CArtifactInstance *a = NULL; + if(aid >= 0) + a = new CArtifactInstance(aid); + else + a = new CArtifactInstance(); + + this->addNewArtifactInstance(a); + return a; +} + LossCondition::LossCondition() { obj = NULL; diff --git a/lib/map.h b/lib/map.h index c891bb8b8..af5381573 100644 --- a/lib/map.h +++ b/lib/map.h @@ -297,9 +297,13 @@ struct DLL_EXPORT Mapa : public CMapHeader void readHeader( const unsigned char * bufor, int &i); void readRumors( const unsigned char * bufor, int &i); CGObjectInstance *loadHero(const unsigned char * bufor, int &i); + void loadArtifactsOfHero(const unsigned char * bufor, int & i, CGHeroInstance * nhi); + bool loadArtifactToSlot(CGHeroInstance *h, int slot, const unsigned char * bufor, int &i); void loadTown( CGObjectInstance * &nobj, const unsigned char * bufor, int &i, int subid); int loadSeerHut( const unsigned char * bufor, int i, CGObjectInstance *& nobj); + CArtifactInstance *createArt(int aid); + void checkForObjectives(); void addNewArtifactInstance(CArtifactInstance *art); void addBlockVisTiles(CGObjectInstance * obj); diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 960d10332..997464ee5 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -2489,7 +2489,7 @@ bool CGameHandler::moveArtifact(si32 srcHeroID, si32 destHeroID, ui16 srcSlot, u && srcArtifact && !srcArtifact->canBePutAt(dst)) COMPLAIN_RET("Cannot swap artifacts!"); - if ((srcArtifact && srcArtifact->artType->id == Arts::LOCK_ID) || (destArtifact && destArtifact->artType->id == Arts::LOCK_ID)) + if ((srcArtifact && srcArtifact->artType->id == Arts::ID_LOCK) || (destArtifact && destArtifact->artType->id == Arts::ID_LOCK)) COMPLAIN_RET("Cannot move artifact locks."); if (destSlot >= Arts::BACKPACK_START && srcArtifact->artType->isBig())