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:
@@ -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
|
||||
{
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
}
|
@@ -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;
|
||||
|
||||
|
@@ -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 )
|
||||
{
|
||||
|
@@ -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;
|
||||
}
|
@@ -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
|
||||
|
@@ -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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@@ -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;
|
||||
|
@@ -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
|
||||
{
|
||||
|
@@ -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()
|
||||
|
@@ -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>();
|
||||
|
12
lib/map.cpp
12
lib/map.cpp
@@ -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();
|
||||
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user