mirror of
https://github.com/vcmi/vcmi.git
synced 2025-06-23 00:28:08 +02:00
More development around bonus system: building hierarchy, managing morale bonuses. Fully functional Spell Scroll and Angelic Alliance artifacts. Fixed recruiting hero and moving hero to garrison.
This commit is contained in:
@ -1319,7 +1319,7 @@ void CCastleInterface::keyPressed( const SDL_KeyboardEvent & key )
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SDLK_SPACE:
|
case SDLK_SPACE:
|
||||||
if(town->visitingHero && town->garrisonHero)
|
if(!!town->visitingHero && town->garrisonHero)
|
||||||
{
|
{
|
||||||
LOCPLINT->cb->swapGarrisonHero(town);
|
LOCPLINT->cb->swapGarrisonHero(town);
|
||||||
}
|
}
|
||||||
@ -1331,7 +1331,7 @@ void CCastleInterface::keyPressed( const SDL_KeyboardEvent & key )
|
|||||||
|
|
||||||
void CCastleInterface::splitClicked()
|
void CCastleInterface::splitClicked()
|
||||||
{
|
{
|
||||||
if(town->visitingHero && town->garrisonHero && (hslotdown.highlight || hslotup.highlight))
|
if(!!town->visitingHero && town->garrisonHero && (hslotdown.highlight || hslotup.highlight))
|
||||||
{
|
{
|
||||||
LOCPLINT->heroExchangeStarted(town->visitingHero->id, town->garrisonHero->id);
|
LOCPLINT->heroExchangeStarted(town->visitingHero->id, town->garrisonHero->id);
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ void SetSecSkill::applyCl( CClient *cl )
|
|||||||
|
|
||||||
void HeroVisitCastle::applyCl( CClient *cl )
|
void HeroVisitCastle::applyCl( CClient *cl )
|
||||||
{
|
{
|
||||||
if(start() && !garrison() && vstd::contains(cl->playerint,GS(cl)->getHero(hid)->tempOwner))
|
if(start() && vstd::contains(cl->playerint,GS(cl)->getHero(hid)->tempOwner))
|
||||||
{
|
{
|
||||||
cl->playerint[GS(cl)->getHero(hid)->tempOwner]->heroVisitsTown(GS(cl)->getHero(hid),GS(cl)->getTown(tid));
|
cl->playerint[GS(cl)->getHero(hid)->tempOwner]->heroVisitsTown(GS(cl)->getHero(hid),GS(cl)->getTown(tid));
|
||||||
}
|
}
|
||||||
|
@ -699,7 +699,7 @@ void CArtHandler::addBonuses()
|
|||||||
|
|
||||||
//Angelic Alliance
|
//Angelic Alliance
|
||||||
giveArtBonus(129, Bonus::NONEVIL_ALIGNMENT_MIX, 0);
|
giveArtBonus(129, Bonus::NONEVIL_ALIGNMENT_MIX, 0);
|
||||||
giveArtBonus(129, Bonus::OPENING_BATTLE_SPELL, 10, 29); // Prayer
|
giveArtBonus(129, Bonus::OPENING_BATTLE_SPELL, 10, 48); // Prayer
|
||||||
|
|
||||||
//Cloak of the Undead King
|
//Cloak of the Undead King
|
||||||
giveArtBonus(130, Bonus::IMPROVED_NECROMANCY, 0);
|
giveArtBonus(130, Bonus::IMPROVED_NECROMANCY, 0);
|
||||||
@ -894,8 +894,8 @@ std::string CArtifactInstance::nodeName() const
|
|||||||
|
|
||||||
CArtifactInstance * CArtifactInstance::createScroll( const CSpell *s)
|
CArtifactInstance * CArtifactInstance::createScroll( const CSpell *s)
|
||||||
{
|
{
|
||||||
CArtifactInstance *ret = new CArtifactInstance(VLC->arth->artifacts[93]);
|
CArtifactInstance *ret = new CArtifactInstance(VLC->arth->artifacts[1]);
|
||||||
Bonus *b = new Bonus(Bonus::PERMANENT, Bonus::SPELL, Bonus::ARTIFACT_INSTANCE, -1, s->id );
|
Bonus *b = new Bonus(Bonus::PERMANENT, Bonus::SPELL, Bonus::ARTIFACT_INSTANCE, -1, 1, s->id);
|
||||||
ret->addNewBonus(b);
|
ret->addNewBonus(b);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1021,6 +1021,11 @@ CArtifactInstance * CArtifactInstance::createNewArtifactInstance(int aid)
|
|||||||
return createNewArtifactInstance(VLC->arth->artifacts[aid]);
|
return createNewArtifactInstance(VLC->arth->artifacts[aid]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CArtifactInstance::deserializationFix()
|
||||||
|
{
|
||||||
|
setType(artType);
|
||||||
|
}
|
||||||
|
|
||||||
bool CCombinedArtifactInstance::canBePutAt(const ArtifactLocation &al, bool assumeDestRemoved /*= false*/) const
|
bool CCombinedArtifactInstance::canBePutAt(const ArtifactLocation &al, bool assumeDestRemoved /*= false*/) const
|
||||||
{
|
{
|
||||||
bool canMainArtifactBePlaced = CArtifactInstance::canBePutAt(al, assumeDestRemoved);
|
bool canMainArtifactBePlaced = CArtifactInstance::canBePutAt(al, assumeDestRemoved);
|
||||||
@ -1162,6 +1167,12 @@ CArtifactInstance * CCombinedArtifactInstance::figureMainConstituent(ui16 slot)
|
|||||||
return mainConstituent;
|
return mainConstituent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CCombinedArtifactInstance::deserializationFix()
|
||||||
|
{
|
||||||
|
BOOST_FOREACH(ConstituentInfo &ci, constituentsInfo)
|
||||||
|
attachTo(ci.art);
|
||||||
|
}
|
||||||
|
|
||||||
CCombinedArtifactInstance::ConstituentInfo::ConstituentInfo(CArtifactInstance *Art /*= NULL*/, ui16 Slot /*= -1*/)
|
CCombinedArtifactInstance::ConstituentInfo::ConstituentInfo(CArtifactInstance *Art /*= NULL*/, ui16 Slot /*= -1*/)
|
||||||
{
|
{
|
||||||
art = Art;
|
art = Art;
|
||||||
|
@ -74,6 +74,7 @@ public:
|
|||||||
//CArtifactInstance(int aid);
|
//CArtifactInstance(int aid);
|
||||||
|
|
||||||
std::string nodeName() const OVERRIDE;
|
std::string nodeName() const OVERRIDE;
|
||||||
|
void deserializationFix();
|
||||||
void setType(CArtifact *Art);
|
void setType(CArtifact *Art);
|
||||||
|
|
||||||
int firstAvailableSlot(const CGHeroInstance *h) const;
|
int firstAvailableSlot(const CGHeroInstance *h) const;
|
||||||
@ -127,6 +128,8 @@ public:
|
|||||||
|
|
||||||
CCombinedArtifactInstance();
|
CCombinedArtifactInstance();
|
||||||
|
|
||||||
|
void deserializationFix();
|
||||||
|
|
||||||
friend class CArtifactInstance;
|
friend class CArtifactInstance;
|
||||||
friend class AssembledArtifact;
|
friend class AssembledArtifact;
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
|
@ -41,7 +41,7 @@ bool CCreatureSet::setCreature(TSlot slot, TCreature type, TQuantity quantity) /
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(vstd::contains(stacks, slot)) //remove old creature
|
if(hasStackAtSlot(slot)) //remove old creature
|
||||||
eraseStack(slot);
|
eraseStack(slot);
|
||||||
|
|
||||||
putStack(slot, new CStackInstance(type, quantity));
|
putStack(slot, new CStackInstance(type, quantity));
|
||||||
@ -132,7 +132,7 @@ void CCreatureSet::addToSlot(TSlot slot, TCreature cre, TQuantity count, bool al
|
|||||||
{
|
{
|
||||||
const CCreature *c = VLC->creh->creatures[cre];
|
const CCreature *c = VLC->creh->creatures[cre];
|
||||||
|
|
||||||
if(!vstd::contains(stacks, slot))
|
if(!hasStackAtSlot(slot))
|
||||||
{
|
{
|
||||||
setCreature(slot, cre, count);
|
setCreature(slot, cre, count);
|
||||||
}
|
}
|
||||||
@ -150,7 +150,7 @@ void CCreatureSet::addToSlot(TSlot slot, CStackInstance *stack, bool allowMergin
|
|||||||
{
|
{
|
||||||
assert(stack->valid(true));
|
assert(stack->valid(true));
|
||||||
|
|
||||||
if(!vstd::contains(stacks, slot))
|
if(!hasStackAtSlot(slot))
|
||||||
{
|
{
|
||||||
putStack(slot, stack);
|
putStack(slot, stack);
|
||||||
}
|
}
|
||||||
@ -176,7 +176,7 @@ bool CCreatureSet::validTypes(bool allowUnrandomized /*= false*/) const
|
|||||||
|
|
||||||
bool CCreatureSet::slotEmpty(TSlot slot) const
|
bool CCreatureSet::slotEmpty(TSlot slot) const
|
||||||
{
|
{
|
||||||
return !vstd::contains(stacks, slot);
|
return !hasStackAtSlot(slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CCreatureSet::needsLastStack() const
|
bool CCreatureSet::needsLastStack() const
|
||||||
@ -213,9 +213,10 @@ void CCreatureSet::setFormation(bool tight)
|
|||||||
|
|
||||||
void CCreatureSet::setStackCount(TSlot slot, TQuantity count)
|
void CCreatureSet::setStackCount(TSlot slot, TQuantity count)
|
||||||
{
|
{
|
||||||
assert(vstd::contains(stacks, slot));
|
assert(hasStackAtSlot(slot));
|
||||||
assert(count > 0);
|
assert(count > 0);
|
||||||
stacks[slot]->count = count;
|
stacks[slot]->count = count;
|
||||||
|
armyChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCreatureSet::clear()
|
void CCreatureSet::clear()
|
||||||
@ -228,15 +229,15 @@ void CCreatureSet::clear()
|
|||||||
|
|
||||||
const CStackInstance& CCreatureSet::getStack(TSlot slot) const
|
const CStackInstance& CCreatureSet::getStack(TSlot slot) const
|
||||||
{
|
{
|
||||||
assert(vstd::contains(stacks, slot));
|
assert(hasStackAtSlot(slot));
|
||||||
return *stacks.find(slot)->second;
|
return *stacks.find(slot)->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCreatureSet::eraseStack(TSlot slot)
|
void CCreatureSet::eraseStack(TSlot slot)
|
||||||
{
|
{
|
||||||
assert(vstd::contains(stacks, slot));
|
assert(hasStackAtSlot(slot));
|
||||||
delNull(stacks[slot]);
|
CStackInstance *toErase = detachStack(slot);
|
||||||
stacks.erase(slot);
|
delNull(toErase);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CCreatureSet::contains(const CStackInstance *stack) const
|
bool CCreatureSet::contains(const CStackInstance *stack) const
|
||||||
@ -270,9 +271,10 @@ CArmedInstance * CCreatureSet::castToArmyObj()
|
|||||||
|
|
||||||
void CCreatureSet::putStack(TSlot slot, CStackInstance *stack)
|
void CCreatureSet::putStack(TSlot slot, CStackInstance *stack)
|
||||||
{
|
{
|
||||||
assert(!vstd::contains(stacks, slot));
|
assert(!hasStackAtSlot(slot));
|
||||||
stacks[slot] = stack;
|
stacks[slot] = stack;
|
||||||
stack->setArmyObj(castToArmyObj());
|
stack->setArmyObj(castToArmyObj());
|
||||||
|
armyChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCreatureSet::joinStack(TSlot slot, CStackInstance * stack)
|
void CCreatureSet::joinStack(TSlot slot, CStackInstance * stack)
|
||||||
@ -323,7 +325,7 @@ void CCreatureSet::setToArmy(CSimpleArmy &src)
|
|||||||
|
|
||||||
CStackInstance * CCreatureSet::detachStack(TSlot slot)
|
CStackInstance * CCreatureSet::detachStack(TSlot slot)
|
||||||
{
|
{
|
||||||
assert(vstd::contains(stacks, slot));
|
assert(hasStackAtSlot(slot));
|
||||||
CStackInstance *ret = stacks[slot];
|
CStackInstance *ret = stacks[slot];
|
||||||
|
|
||||||
if(CArmedInstance *armedObj = castToArmyObj())
|
if(CArmedInstance *armedObj = castToArmyObj())
|
||||||
@ -332,16 +334,17 @@ CStackInstance * CCreatureSet::detachStack(TSlot slot)
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert(!ret->armyObj); //we failed detaching?
|
assert(!ret->armyObj); //we failed detaching?
|
||||||
|
|
||||||
stacks.erase(slot);
|
stacks.erase(slot);
|
||||||
|
armyChanged();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCreatureSet::setStackType(TSlot slot, const CCreature *type)
|
void CCreatureSet::setStackType(TSlot slot, const CCreature *type)
|
||||||
{
|
{
|
||||||
assert(vstd::contains(stacks, slot));
|
assert(hasStackAtSlot(slot));
|
||||||
CStackInstance *s = stacks[slot];
|
CStackInstance *s = stacks[slot];
|
||||||
s->setType(type->idNumber);
|
s->setType(type->idNumber);
|
||||||
|
armyChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CCreatureSet::canBeMergedWith(const CCreatureSet &cs, bool allowMergingStacks) const
|
bool CCreatureSet::canBeMergedWith(const CCreatureSet &cs, bool allowMergingStacks) const
|
||||||
@ -383,6 +386,10 @@ CCreatureSet & CCreatureSet::operator=(const CCreatureSet&cs)
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CCreatureSet::armyChanged()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
CStackInstance::CStackInstance()
|
CStackInstance::CStackInstance()
|
||||||
: armyObj(_armyObj)
|
: armyObj(_armyObj)
|
||||||
{
|
{
|
||||||
@ -494,6 +501,12 @@ std::string CStackInstance::nodeName() const
|
|||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CStackInstance::deserializationFix()
|
||||||
|
{
|
||||||
|
setType(type);
|
||||||
|
setArmyObj(armyObj);
|
||||||
|
}
|
||||||
|
|
||||||
CStackBasicDescriptor::CStackBasicDescriptor()
|
CStackBasicDescriptor::CStackBasicDescriptor()
|
||||||
{
|
{
|
||||||
type = NULL;
|
type = NULL;
|
||||||
|
@ -59,6 +59,7 @@ public:
|
|||||||
void setArmyObj(const CArmedInstance *ArmyObj);
|
void setArmyObj(const CArmedInstance *ArmyObj);
|
||||||
bool valid(bool allowUnrandomized) const;
|
bool valid(bool allowUnrandomized) const;
|
||||||
virtual std::string nodeName() const OVERRIDE;
|
virtual std::string nodeName() const OVERRIDE;
|
||||||
|
void deserializationFix();
|
||||||
};
|
};
|
||||||
|
|
||||||
DLL_EXPORT std::ostream & operator<<(std::ostream & str, const CStackInstance & sth);
|
DLL_EXPORT std::ostream & operator<<(std::ostream & str, const CStackInstance & sth);
|
||||||
@ -98,6 +99,7 @@ public:
|
|||||||
|
|
||||||
CCreatureSet();
|
CCreatureSet();
|
||||||
virtual ~CCreatureSet();
|
virtual ~CCreatureSet();
|
||||||
|
virtual void armyChanged();
|
||||||
|
|
||||||
const CStackInstance &operator[](TSlot slot) const;
|
const CStackInstance &operator[](TSlot slot) const;
|
||||||
|
|
||||||
@ -110,14 +112,14 @@ public:
|
|||||||
CArmedInstance *castToArmyObj();
|
CArmedInstance *castToArmyObj();
|
||||||
|
|
||||||
//basic operations
|
//basic operations
|
||||||
void eraseStack(TSlot slot); //slot must be occupied
|
|
||||||
void putStack(TSlot slot, CStackInstance *stack); //adds new stack to the army, slot must be empty
|
void putStack(TSlot slot, CStackInstance *stack); //adds new stack to the army, slot must be empty
|
||||||
void joinStack(TSlot slot, CStackInstance * stack); //adds new stack to the existing stack of the same type
|
|
||||||
void setStackCount(TSlot slot, TQuantity count); //stack must exist!
|
void setStackCount(TSlot slot, TQuantity count); //stack must exist!
|
||||||
CStackInstance *detachStack(TSlot slot); //removes stack from army but doesn't destroy it (so it can be moved somewhere else)
|
CStackInstance *detachStack(TSlot slot); //removes stack from army but doesn't destroy it (so it can be moved somewhere else or safely deleted)
|
||||||
void setStackType(TSlot slot, const CCreature *type);
|
void setStackType(TSlot slot, const CCreature *type);
|
||||||
|
|
||||||
//derivative
|
//derivative
|
||||||
|
void eraseStack(TSlot slot); //slot must be occupied
|
||||||
|
void joinStack(TSlot slot, CStackInstance * stack); //adds new stack to the existing stack of the same type
|
||||||
void changeStackCount(TSlot slot, TQuantity toAdd); //stack must exist!
|
void changeStackCount(TSlot slot, TQuantity toAdd); //stack must exist!
|
||||||
bool setCreature (TSlot slot, TCreature type, TQuantity quantity) OVERRIDE; //replaces creature in stack; slots 0 to 6, if quantity=0 erases stack
|
bool setCreature (TSlot slot, TCreature type, TQuantity quantity) OVERRIDE; //replaces creature in stack; slots 0 to 6, if quantity=0 erases stack
|
||||||
void setToArmy(CSimpleArmy &src); //erases all our army and moves stacks from src to us; src MUST NOT be an armed object! WARNING: use it wisely. Or better do not use at all.
|
void setToArmy(CSimpleArmy &src); //erases all our army and moves stacks from src to us; src MUST NOT be an armed object! WARNING: use it wisely. Or better do not use at all.
|
||||||
|
@ -941,19 +941,6 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// h->setCreature(0, 110, 1);
|
|
||||||
// h->setCreature(1, 69, 1);
|
|
||||||
//
|
|
||||||
// CGHeroInstance *h = new CGHeroInstance();
|
|
||||||
//
|
|
||||||
// CGCreature *c = new CGCreature();
|
|
||||||
// c->setOwner(1);
|
|
||||||
// c->putStack(0, new CStackInstance(69, 6));
|
|
||||||
// c->putStack(1, new CStackInstance(11, 3));
|
|
||||||
// c->subID = 34;
|
|
||||||
// c->initObj();
|
|
||||||
|
|
||||||
curB = BattleInfo::setupBattle(int3(), dp.bfieldType, dp.terType, armies, heroes, false, town);
|
curB = BattleInfo::setupBattle(int3(), dp.bfieldType, dp.terType, armies, heroes, false, town);
|
||||||
curB->localInit();
|
curB->localInit();
|
||||||
return;
|
return;
|
||||||
@ -1069,32 +1056,19 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
|
|||||||
/*********give starting hero****************************************/
|
/*********give starting hero****************************************/
|
||||||
for(int i=0;i<PLAYER_LIMIT;i++)
|
for(int i=0;i<PLAYER_LIMIT;i++)
|
||||||
{
|
{
|
||||||
if((map->players[i].generateHeroAtMainTown && map->players[i].hasMainTown) || (map->players[i].hasMainTown && map->version==CMapHeader::RoE))
|
const PlayerInfo &p = map->players[i];
|
||||||
|
bool generateHero = (p.generateHeroAtMainTown && p.hasMainTown) || (p.hasMainTown && map->version==CMapHeader::RoE);
|
||||||
|
if(generateHero && vstd::contains(scenarioOps->playerInfos, i))
|
||||||
{
|
{
|
||||||
int3 hpos = map->players[i].posOfMainTown;
|
int3 hpos = p.posOfMainTown;
|
||||||
hpos.x+=1;// hpos.y+=1;
|
hpos.x+=1;
|
||||||
if (scenarioOps->playerInfos.find(i) == scenarioOps->playerInfos.end())
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int h=pickHero(i);
|
int h = pickHero(i);
|
||||||
if(scenarioOps->playerInfos[i].hero == -1)
|
if(scenarioOps->playerInfos[i].hero == -1)
|
||||||
scenarioOps->playerInfos[i].hero = h;
|
scenarioOps->playerInfos[i].hero = h;
|
||||||
|
|
||||||
CGHeroInstance * nnn = static_cast<CGHeroInstance*>(createObject(HEROI_TYPE,h,hpos,i));
|
CGHeroInstance * nnn = static_cast<CGHeroInstance*>(createObject(HEROI_TYPE,h,hpos,i));
|
||||||
nnn->id = map->objects.size();
|
nnn->id = map->objects.size();
|
||||||
hpos = map->players[i].posOfMainTown;hpos.x+=2;
|
|
||||||
for(unsigned int o=0;o<map->towns.size();o++) //find main town
|
|
||||||
{
|
|
||||||
if(map->towns[o]->pos == hpos)
|
|
||||||
{
|
|
||||||
map->towns[o]->visitingHero = nnn;
|
|
||||||
nnn->visitedTown = map->towns[o];
|
|
||||||
nnn->inTownGarrison = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nnn->initHero();
|
nnn->initHero();
|
||||||
map->heroes.push_back(nnn);
|
map->heroes.push_back(nnn);
|
||||||
map->objects.push_back(nnn);
|
map->objects.push_back(nnn);
|
||||||
@ -1533,24 +1507,31 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
objCaller->preInit();
|
||||||
|
BOOST_FOREACH(CGObjectInstance *obj, map->objects)
|
||||||
|
{
|
||||||
|
obj->initObj();
|
||||||
|
if(obj->ID == 62) //prison also needs to initialize hero
|
||||||
|
static_cast<CGHeroInstance*>(obj)->initHero();
|
||||||
|
}
|
||||||
|
CGTeleport::postInit(); //pairing subterranean gates
|
||||||
|
|
||||||
|
buildBonusSystemTree();
|
||||||
|
|
||||||
for(std::map<ui8, PlayerState>::iterator k=players.begin(); k!=players.end(); ++k)
|
for(std::map<ui8, PlayerState>::iterator k=players.begin(); k!=players.end(); ++k)
|
||||||
{
|
{
|
||||||
if(k->first==-1 || k->first==255)
|
if(k->first==-1 || k->first==255)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
//init visiting and garrisoned heroes
|
//init visiting and garrisoned heroes
|
||||||
for(unsigned int l=0; l<k->second.heroes.size();l++)
|
BOOST_FOREACH(CGHeroInstance *h, k->second.heroes)
|
||||||
{
|
{
|
||||||
CGHeroInstance *h = k->second.heroes[l];
|
BOOST_FOREACH(CGTownInstance *t, k->second.towns)
|
||||||
for(unsigned int m=0; m<k->second.towns.size();m++)
|
|
||||||
{
|
{
|
||||||
CGTownInstance *t = k->second.towns[m];
|
|
||||||
int3 vistile = t->pos; vistile.x--; //tile next to the entrance
|
int3 vistile = t->pos; vistile.x--; //tile next to the entrance
|
||||||
if(vistile == h->pos || h->pos==t->pos)
|
if(vistile == h->pos || h->pos==t->pos)
|
||||||
{
|
{
|
||||||
t->visitingHero = h;
|
t->setVisitingHero(h);
|
||||||
h->visitedTown = t;
|
|
||||||
h->inTownGarrison = false;
|
|
||||||
if(h->pos == t->pos) //visiting hero placed in the editor has same pos as the town - we need to correct it
|
if(h->pos == t->pos) //visiting hero placed in the editor has same pos as the town - we need to correct it
|
||||||
{
|
{
|
||||||
map->removeBlockVisTiles(h);
|
map->removeBlockVisTiles(h);
|
||||||
@ -1562,15 +1543,6 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
objCaller->preInit();
|
|
||||||
for(unsigned int i=0; i<map->objects.size(); i++)
|
|
||||||
{
|
|
||||||
map->objects[i]->initObj();
|
|
||||||
if(map->objects[i]->ID == 62) //prison also needs to initialize hero
|
|
||||||
static_cast<CGHeroInstance*>(map->objects[i].get())->initHero();
|
|
||||||
}
|
|
||||||
CGTeleport::postInit(); //pairing subterranean gates
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int CGameState::battleGetBattlefieldType(int3 tile)
|
int CGameState::battleGetBattlefieldType(int3 tile)
|
||||||
@ -2882,8 +2854,46 @@ bmap<ui32, ConstTransitivePtr<CGHeroInstance> > CGameState::unusedHeroesFromPool
|
|||||||
return pool;
|
return pool;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameState::buildGameLogicTree()
|
void CGameState::buildBonusSystemTree()
|
||||||
{
|
{
|
||||||
|
for(std::map<ui8, TeamState>::iterator k=teams.begin(); k!=teams.end(); ++k)
|
||||||
|
{
|
||||||
|
TeamState *t = &k->second;
|
||||||
|
t->attachTo(&globalEffects);
|
||||||
|
|
||||||
|
BOOST_FOREACH(ui8 teamMember, k->second.players)
|
||||||
|
{
|
||||||
|
PlayerState *p = getPlayer(teamMember);
|
||||||
|
assert(p);
|
||||||
|
p->attachTo(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_FOREACH(CGObjectInstance *obj, map->objects)
|
||||||
|
{
|
||||||
|
if(CArmedInstance *armed = dynamic_cast<CArmedInstance*>(obj))
|
||||||
|
{
|
||||||
|
CBonusSystemNode *whereToAttach = armed->tempOwner < PLAYER_LIMIT
|
||||||
|
? getPlayer(armed->tempOwner)
|
||||||
|
: &globalEffects;
|
||||||
|
|
||||||
|
if(armed->ID == TOWNI_TYPE)
|
||||||
|
{
|
||||||
|
CGTownInstance *town = static_cast<CGTownInstance*>(armed);
|
||||||
|
town->townAndVis.attachTo(whereToAttach);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
armed->attachTo(whereToAttach);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_FOREACH(CGTownInstance *t, map->towns)
|
||||||
|
{
|
||||||
|
t->deserializationFix();
|
||||||
|
}
|
||||||
|
// CStackInstance <-> CCreature, CStackInstance <-> CArmedInstance, CArtifactInstance <-> CArtifact
|
||||||
|
// are provided on initializing / deserializing
|
||||||
}
|
}
|
||||||
|
|
||||||
int3 CPath::startPos() const
|
int3 CPath::startPos() const
|
||||||
|
@ -321,7 +321,6 @@ public:
|
|||||||
const TeamState *getTeam(ui8 teamID) const;
|
const TeamState *getTeam(ui8 teamID) const;
|
||||||
const TeamState *getPlayerTeam(ui8 color) const;
|
const TeamState *getPlayerTeam(ui8 color) const;
|
||||||
void init(StartInfo * si, ui32 checksum, int Seed);
|
void init(StartInfo * si, ui32 checksum, int Seed);
|
||||||
void buildGameLogicTree();
|
|
||||||
void loadTownDInfos();
|
void loadTownDInfos();
|
||||||
void randomizeObject(CGObjectInstance *cur);
|
void randomizeObject(CGObjectInstance *cur);
|
||||||
std::pair<int,int> pickObject(CGObjectInstance *obj); //chooses type of object to be randomized, returns <type, subtype>
|
std::pair<int,int> pickObject(CGObjectInstance *obj); //chooses type of object to be randomized, returns <type, subtype>
|
||||||
@ -350,6 +349,7 @@ public:
|
|||||||
bmap<ui32, ConstTransitivePtr<CGHeroInstance> > unusedHeroesFromPool(); //heroes pool without heroes that are available in taverns
|
bmap<ui32, ConstTransitivePtr<CGHeroInstance> > unusedHeroesFromPool(); //heroes pool without heroes that are available in taverns
|
||||||
BattleInfo * setupBattle(int3 tile, const CArmedInstance *armies[2], const CGHeroInstance * heroes[2], bool creatureBank, const CGTownInstance *town);
|
BattleInfo * setupBattle(int3 tile, const CArmedInstance *armies[2], const CGHeroInstance * heroes[2], bool creatureBank, const CGTownInstance *town);
|
||||||
|
|
||||||
|
void buildBonusSystemTree();
|
||||||
|
|
||||||
bool isVisible(int3 pos, int player);
|
bool isVisible(int3 pos, int player);
|
||||||
bool isVisible(const CGObjectInstance *obj, int player);
|
bool isVisible(const CGObjectInstance *obj, int player);
|
||||||
|
@ -271,34 +271,6 @@ CGObjectInstance::~CGObjectInstance()
|
|||||||
// delete state;
|
// delete state;
|
||||||
//state=NULL;
|
//state=NULL;
|
||||||
}
|
}
|
||||||
//CGObjectInstance::CGObjectInstance(const CGObjectInstance & right)
|
|
||||||
//{
|
|
||||||
// pos = right.pos;
|
|
||||||
// ID = right.ID;
|
|
||||||
// subID = right.subID;
|
|
||||||
// id = right.id;
|
|
||||||
// defInfo = right.defInfo;
|
|
||||||
// info = right.info;
|
|
||||||
// blockVisit = right.blockVisit;
|
|
||||||
// //state = new CLuaObjectScript(right.state->);
|
|
||||||
// //*state = *right.state;
|
|
||||||
// //state = right.state;
|
|
||||||
// tempOwner = right.tempOwner;
|
|
||||||
//}
|
|
||||||
//CGObjectInstance& CGObjectInstance::operator=(const CGObjectInstance & right)
|
|
||||||
//{
|
|
||||||
// pos = right.pos;
|
|
||||||
// ID = right.ID;
|
|
||||||
// subID = right.subID;
|
|
||||||
// id = right.id;
|
|
||||||
// defInfo = right.defInfo;
|
|
||||||
// info = right.info;
|
|
||||||
// blockVisit = right.blockVisit;
|
|
||||||
// //state = new CLuaObjectScript();
|
|
||||||
// //*state = *right.state;
|
|
||||||
// tempOwner = right.tempOwner;
|
|
||||||
// return *this;
|
|
||||||
//}
|
|
||||||
|
|
||||||
const std::string & CGObjectInstance::getHoverText() const
|
const std::string & CGObjectInstance::getHoverText() const
|
||||||
{
|
{
|
||||||
@ -1431,22 +1403,6 @@ void CGHeroInstance::giveArtifact (ui32 aid) //use only for fixed artifacts
|
|||||||
CArtifact * const artifact = VLC->arth->artifacts[aid]; //pointer to constant object
|
CArtifact * const artifact = VLC->arth->artifacts[aid]; //pointer to constant object
|
||||||
CArtifactInstance *ai = CArtifactInstance::createNewArtifactInstance(artifact);
|
CArtifactInstance *ai = CArtifactInstance::createNewArtifactInstance(artifact);
|
||||||
ai->putAt(this, ai->firstAvailableSlot(this));
|
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
|
int CGHeroInstance::getBoatType() const
|
||||||
@ -1477,21 +1433,6 @@ int CGHeroInstance::getSpellCost(const CSpell *sp) const
|
|||||||
return sp->costs[getSpellSchoolLevel(sp)];
|
return sp->costs[getSpellSchoolLevel(sp)];
|
||||||
}
|
}
|
||||||
|
|
||||||
// void CGHeroInstance::getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/) const
|
|
||||||
// {
|
|
||||||
// CArmedInstance::getParents(out, root);
|
|
||||||
//
|
|
||||||
// if((root == this || contains(static_cast<const CStackInstance *>(root))) && visitedTown && !dynamic_cast<const PlayerState*>(root))
|
|
||||||
// {
|
|
||||||
// out.insert(visitedTown);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// for (std::map<ui16,CArtifact*>::const_iterator i = artifWorn.begin(); i != artifWorn.end(); i++)
|
|
||||||
// out.insert(i->second);
|
|
||||||
//
|
|
||||||
// out.insert(&speciality);
|
|
||||||
// }
|
|
||||||
|
|
||||||
void CGHeroInstance::pushPrimSkill(int which, int val)
|
void CGHeroInstance::pushPrimSkill(int which, int val)
|
||||||
{
|
{
|
||||||
addNewBonus(new Bonus(Bonus::PERMANENT, Bonus::PRIMARY_SKILL, Bonus::HERO_BASE_SKILL, val, id, which));
|
addNewBonus(new Bonus(Bonus::PERMANENT, Bonus::PRIMARY_SKILL, Bonus::HERO_BASE_SKILL, val, id, which));
|
||||||
@ -1583,6 +1524,15 @@ bool CGHeroInstance::hasSpellbook() const
|
|||||||
return getArt(Arts::SPELLBOOK);
|
return getArt(Arts::SPELLBOOK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CGHeroInstance::deserializationFix()
|
||||||
|
{
|
||||||
|
for(bmap<ui16, ArtSlotInfo>::iterator i = artifactsWorn.begin(); i != artifactsWorn.end(); i++)
|
||||||
|
if(i->second.artifact && !i->second.locked)
|
||||||
|
attachTo(i->second.artifact);
|
||||||
|
|
||||||
|
attachTo(&speciality);
|
||||||
|
}
|
||||||
|
|
||||||
void CGDwelling::initObj()
|
void CGDwelling::initObj()
|
||||||
{
|
{
|
||||||
switch(ID)
|
switch(ID)
|
||||||
@ -2008,9 +1958,7 @@ CGTownInstance::CGTownInstance()
|
|||||||
{
|
{
|
||||||
builded=-1;
|
builded=-1;
|
||||||
destroyed=-1;
|
destroyed=-1;
|
||||||
garrisonHero=NULL;
|
|
||||||
town=NULL;
|
town=NULL;
|
||||||
visitingHero = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CGTownInstance::~CGTownInstance()
|
CGTownInstance::~CGTownInstance()
|
||||||
@ -2137,10 +2085,8 @@ void CGTownInstance::initObj()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//add special bonuses from buildings
|
//add special bonuses from buildings
|
||||||
if(subID == 4 && vstd::contains(builtBuildings, 17))
|
|
||||||
{
|
recreateBuildingsBonuses();
|
||||||
addNewBonus(new Bonus(Bonus::PERMANENT, Bonus::DARKNESS, Bonus::TOWN_STRUCTURE, 20, 17) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGTownInstance::newTurn() const
|
void CGTownInstance::newTurn() const
|
||||||
@ -2241,27 +2187,6 @@ void CGTownInstance::fightOver( const CGHeroInstance *h, BattleResult *result )
|
|||||||
{
|
{
|
||||||
if(result->winner == 0)
|
if(result->winner == 0)
|
||||||
{
|
{
|
||||||
if (hasBonusOfType(Bonus::DARKNESS))
|
|
||||||
{
|
|
||||||
//TODO: Make some 'change owner' function for bonus, or bonuses independent of player
|
|
||||||
/*
|
|
||||||
RemoveBonus rb(RemoveBonus::PLAYER);
|
|
||||||
rb.whoID = getOwner();
|
|
||||||
rb.source = Bonus::TOWN_STRUCTURE;
|
|
||||||
rb.id = id;
|
|
||||||
cb->sendAndApply(&rb);
|
|
||||||
|
|
||||||
GiveBonus gb(GiveBonus::PLAYER);
|
|
||||||
gb.bonus.type = Bonus::DARKNESS;
|
|
||||||
gb.bonus.val = 20;
|
|
||||||
gb.id = h->tempOwner;
|
|
||||||
gb.bonus.duration = Bonus::PERMANENT;
|
|
||||||
gb.bonus.source = Bonus::TOWN_STRUCTURE;
|
|
||||||
gb.bonus.id = id;
|
|
||||||
cb->sendAndApply(&gb);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
removeCapitols (h->getOwner());
|
removeCapitols (h->getOwner());
|
||||||
cb->setOwner (id, h->tempOwner); //give control after checkout is done
|
cb->setOwner (id, h->tempOwner); //give control after checkout is done
|
||||||
FoWChange fw;
|
FoWChange fw;
|
||||||
@ -2269,8 +2194,6 @@ void CGTownInstance::fightOver( const CGHeroInstance *h, BattleResult *result )
|
|||||||
fw.mode = 1;
|
fw.mode = 1;
|
||||||
getSightTiles (fw.tiles); //update visibility for castle structures
|
getSightTiles (fw.tiles); //update visibility for castle structures
|
||||||
cb->sendAndApply (&fw);
|
cb->sendAndApply (&fw);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2305,33 +2228,6 @@ int CGTownInstance::getBoatType() const
|
|||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// void CGTownInstance::getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/) const
|
|
||||||
// {
|
|
||||||
// CArmedInstance::getParents(out, root);
|
|
||||||
// if(root == this && visitingHero && visitingHero != root)
|
|
||||||
// out.insert(visitingHero);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// void CGTownInstance::getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root /*= NULL*/) const
|
|
||||||
// {
|
|
||||||
// CArmedInstance::getBonuses(out, selector, root);
|
|
||||||
// //TODO eliminate by moving structures effects to bonus system
|
|
||||||
//
|
|
||||||
// if(Selector::matchesType(selector, Bonus::LUCK))
|
|
||||||
// {
|
|
||||||
// if(subID == 1 && vstd::contains(builtBuildings,21)) //rampart, fountain of fortune
|
|
||||||
// out.push_back(Bonus(Bonus::PERMANENT, Bonus::LUCK, Bonus::TOWN_STRUCTURE, +2, 21, VLC->generaltexth->buildings[1][21].first + " +2"));
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if(Selector::matchesType(selector, Bonus::MORALE))
|
|
||||||
// {
|
|
||||||
// if(subID == 0 && vstd::contains(builtBuildings,22)) //castle, brotherhood of sword built
|
|
||||||
// out.push_back(Bonus(Bonus::PERMANENT, Bonus::MORALE, Bonus::TOWN_STRUCTURE, +2, 22, VLC->generaltexth->buildings[0][22].first + " +2"));
|
|
||||||
// else if(vstd::contains(builtBuildings,5)) //tavern is built
|
|
||||||
// out.push_back(Bonus(Bonus::PERMANENT, Bonus::MORALE, Bonus::TOWN_STRUCTURE, +1, 5, VLC->generaltexth->buildings[0][5].first + " +1"));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
int CGTownInstance::getMarketEfficiency() const
|
int CGTownInstance::getMarketEfficiency() const
|
||||||
{
|
{
|
||||||
if(!vstd::contains(builtBuildings, 14))
|
if(!vstd::contains(builtBuildings, 14))
|
||||||
@ -2390,6 +2286,83 @@ std::vector<int> CGTownInstance::availableItemsIds(EMarketMode mode) const
|
|||||||
return IMarket::availableItemsIds(mode);
|
return IMarket::availableItemsIds(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string CGTownInstance::nodeName() const
|
||||||
|
{
|
||||||
|
return "Town (" + (town ? town->Name() : "unknown") + ") of " + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGTownInstance::deserializationFix()
|
||||||
|
{
|
||||||
|
attachTo(&townAndVis);
|
||||||
|
if(visitingHero)
|
||||||
|
visitingHero->attachTo(&townAndVis);
|
||||||
|
if(garrisonHero)
|
||||||
|
garrisonHero->attachTo(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGTownInstance::recreateBuildingsBonuses()
|
||||||
|
{
|
||||||
|
bonuses.remove_if(Selector::sourceType(Bonus::TOWN_STRUCTURE)); //TODO memory leak
|
||||||
|
|
||||||
|
if(subID == 4 && vstd::contains(builtBuildings, 17))
|
||||||
|
addNewBonus(new Bonus(Bonus::PERMANENT, Bonus::DARKNESS, Bonus::TOWN_STRUCTURE, 20, 17));
|
||||||
|
|
||||||
|
if(subID == 1 && vstd::contains(builtBuildings,21)) //rampart, fountain of fortune
|
||||||
|
addNewBonus(new Bonus(Bonus::PERMANENT, Bonus::LUCK, Bonus::TOWN_STRUCTURE, +2, 21, VLC->generaltexth->buildings[1][21].first + " +2"));
|
||||||
|
|
||||||
|
if(subID == 0 && vstd::contains(builtBuildings,22)) //castle, brotherhood of sword built
|
||||||
|
addNewBonus(new Bonus(Bonus::PERMANENT, Bonus::MORALE, Bonus::TOWN_STRUCTURE, +2, 22, VLC->generaltexth->buildings[0][22].first + " +2"));
|
||||||
|
else if(vstd::contains(builtBuildings,5)) //tavern is built
|
||||||
|
addNewBonus(new Bonus(Bonus::PERMANENT, Bonus::MORALE, Bonus::TOWN_STRUCTURE, +1, 5, VLC->generaltexth->buildings[0][5].first + " +1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGTownInstance::setVisitingHero(CGHeroInstance *h)
|
||||||
|
{
|
||||||
|
assert(!!visitingHero == !h);
|
||||||
|
if(h)
|
||||||
|
{
|
||||||
|
PlayerState *p = cb->gameState()->getPlayer(h->tempOwner);
|
||||||
|
assert(p);
|
||||||
|
h->detachFrom(p);
|
||||||
|
h->attachTo(&townAndVis);
|
||||||
|
visitingHero = h;
|
||||||
|
h->visitedTown = this;
|
||||||
|
h->inTownGarrison = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PlayerState *p = cb->gameState()->getPlayer(visitingHero->tempOwner);
|
||||||
|
visitingHero->visitedTown = NULL;
|
||||||
|
visitingHero->detachFrom(&townAndVis);
|
||||||
|
visitingHero->attachTo(p);
|
||||||
|
visitingHero = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGTownInstance::setGarrisonedHero(CGHeroInstance *h)
|
||||||
|
{
|
||||||
|
assert(!!garrisonHero == !h);
|
||||||
|
if(h)
|
||||||
|
{
|
||||||
|
PlayerState *p = cb->gameState()->getPlayer(h->tempOwner);
|
||||||
|
assert(p);
|
||||||
|
h->detachFrom(p);
|
||||||
|
h->attachTo(this);
|
||||||
|
garrisonHero = h;
|
||||||
|
h->visitedTown = this;
|
||||||
|
h->inTownGarrison = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PlayerState *p = cb->gameState()->getPlayer(garrisonHero->tempOwner);
|
||||||
|
garrisonHero->visitedTown = NULL;
|
||||||
|
garrisonHero->inTownGarrison = false;
|
||||||
|
garrisonHero->detachFrom(this);
|
||||||
|
garrisonHero->attachTo(p);
|
||||||
|
garrisonHero = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CGVisitableOPH::onHeroVisit( const CGHeroInstance * h ) const
|
void CGVisitableOPH::onHeroVisit( const CGHeroInstance * h ) const
|
||||||
{
|
{
|
||||||
if(visitors.find(h->id)==visitors.end())
|
if(visitors.find(h->id)==visitors.end())
|
||||||
@ -6584,44 +6557,7 @@ CArmedInstance::CArmedInstance()
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// if(Selector::matchesType(selector, Bonus::MORALE))
|
|
||||||
// {
|
|
||||||
// //number of alignments and presence of undead
|
|
||||||
// if(contains(dynamic_cast<const CStackInstance*>(root)))
|
|
||||||
// {
|
|
||||||
// bool archangelInArmy = false;
|
|
||||||
// bool canMix = hasBonusOfType(Bonus::NONEVIL_ALIGNMENT_MIX);
|
|
||||||
// std::set<si8> factions;
|
|
||||||
// for(TSlots::const_iterator i=Slots().begin(); i!=Slots().end(); i++)
|
|
||||||
// {
|
|
||||||
// // Take Angelic Alliance troop-mixing freedom of non-evil, non-Conflux units into account.
|
|
||||||
// const si8 faction = i->second.type->faction;
|
|
||||||
// if (canMix
|
|
||||||
// && ((faction >= 0 && faction <= 2) || faction == 6 || faction == 7))
|
|
||||||
// {
|
|
||||||
// factions.insert(0); // Insert a single faction of the affected group, Castle will do.
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// factions.insert(faction);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if(i->second.type->idNumber == 13)
|
|
||||||
// archangelInArmy = true;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if(factions.size() == 1)
|
|
||||||
// out.push_back(Bonus(Bonus::PERMANENT, Bonus::MORALE, Bonus::ARMY, +1, id, VLC->generaltexth->arraytxt[115]));//All troops of one alignment +1
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// int fcountModifier = 2-factions.size();
|
|
||||||
// out.push_back(Bonus(Bonus::PERMANENT, Bonus::MORALE, Bonus::ARMY, fcountModifier, id, boost::str(boost::format(VLC->generaltexth->arraytxt[114]) % factions.size() % fcountModifier)));//Troops of %d alignments %d
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if(vstd::contains(factions,4))
|
|
||||||
// out.push_back(Bonus(Bonus::PERMANENT, Bonus::MORALE, Bonus::ARMY, -1, id, VLC->generaltexth->arraytxt[116]));//Undead in group -1
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
int CArmedInstance::valOfGlobalBonuses(CSelector selector) const
|
int CArmedInstance::valOfGlobalBonuses(CSelector selector) const
|
||||||
@ -6630,6 +6566,56 @@ int CArmedInstance::valOfGlobalBonuses(CSelector selector) const
|
|||||||
return cb->gameState()->players[tempOwner].valOfBonuses(selector);
|
return cb->gameState()->players[tempOwner].valOfBonuses(selector);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CArmedInstance::updateMoraleBonusFromArmy()
|
||||||
|
{
|
||||||
|
if(!validTypes(false)) //object not randomized, don't bother
|
||||||
|
return;
|
||||||
|
|
||||||
|
Bonus *b = bonuses.getFirst(Selector::sourceType(Bonus::ARMY) && Selector::type(Bonus::MORALE));
|
||||||
|
if(!b)
|
||||||
|
{
|
||||||
|
b = new Bonus(Bonus::PERMANENT, Bonus::MORALE, Bonus::ARMY, 0, -1);
|
||||||
|
addNewBonus(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
//number of alignments and presence of undead
|
||||||
|
bool canMix = hasBonusOfType(Bonus::NONEVIL_ALIGNMENT_MIX);
|
||||||
|
std::set<si8> factions;
|
||||||
|
for(TSlots::const_iterator i=Slots().begin(); i!=Slots().end(); i++)
|
||||||
|
{
|
||||||
|
// Take Angelic Alliance troop-mixing freedom of non-evil, non-Conflux units into account.
|
||||||
|
const si8 faction = i->second->type->faction;
|
||||||
|
if (canMix
|
||||||
|
&& ((faction >= 0 && faction <= 2) || faction == 6 || faction == 7))
|
||||||
|
{
|
||||||
|
factions.insert(0); // Insert a single faction of the affected group, Castle will do.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
factions.insert(faction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(factions.size() == 1)
|
||||||
|
{
|
||||||
|
b->val = +1;
|
||||||
|
b->description = VLC->generaltexth->arraytxt[115]; //All troops of one alignment +1
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
b->val = 2-factions.size();
|
||||||
|
b->description = boost::str(boost::format(VLC->generaltexth->arraytxt[114]) % factions.size() % b->val); //Troops of %d alignments %d
|
||||||
|
}
|
||||||
|
|
||||||
|
// if(vstd::contains(factions,4))
|
||||||
|
// out.push_back(Bonus(Bonus::PERMANENT, Bonus::MORALE, Bonus::ARMY, -1, id, VLC->generaltexth->arraytxt[116]));//Undead in group -1
|
||||||
|
}
|
||||||
|
|
||||||
|
void CArmedInstance::armyChanged()
|
||||||
|
{
|
||||||
|
updateMoraleBonusFromArmy();
|
||||||
|
}
|
||||||
|
|
||||||
bool IMarket::getOffer(int id1, int id2, int &val1, int &val2, EMarketMode mode) const
|
bool IMarket::getOffer(int id1, int id2, int &val1, int &val2, EMarketMode mode) const
|
||||||
{
|
{
|
||||||
switch(mode)
|
switch(mode)
|
||||||
|
@ -227,6 +227,9 @@ public:
|
|||||||
|
|
||||||
CCreatureSet& getArmy() const;
|
CCreatureSet& getArmy() const;
|
||||||
void randomizeArmy(int type);
|
void randomizeArmy(int type);
|
||||||
|
void updateMoraleBonusFromArmy();
|
||||||
|
|
||||||
|
void armyChanged() OVERRIDE;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
//void getParents(TCNodes &out, const CBonusSystemNode *root = NULL) const;
|
//void getParents(TCNodes &out, const CBonusSystemNode *root = NULL) const;
|
||||||
@ -432,6 +435,7 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
virtual std::string nodeName() const OVERRIDE;
|
virtual std::string nodeName() const OVERRIDE;
|
||||||
|
void deserializationFix();
|
||||||
void setPropertyDer(ui8 what, ui32 val);//synchr
|
void setPropertyDer(ui8 what, ui32 val);//synchr
|
||||||
void initObj();
|
void initObj();
|
||||||
void onHeroVisit(const CGHeroInstance * h) const;
|
void onHeroVisit(const CGHeroInstance * h) const;
|
||||||
@ -556,14 +560,19 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class DLL_EXPORT CTownAndVisitingHero : public CBonusSystemNode
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
class DLL_EXPORT CGTownInstance : public CGDwelling, public IShipyard, public IMarket
|
class DLL_EXPORT CGTownInstance : public CGDwelling, public IShipyard, public IMarket
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
CTownAndVisitingHero townAndVis;
|
||||||
CTown * town;
|
CTown * town;
|
||||||
std::string name; // name of town
|
std::string name; // name of town
|
||||||
si32 builded; //how many buildings has been built this turn
|
si32 builded; //how many buildings has been built this turn
|
||||||
si32 destroyed; //how many buildings has been destroyed this turn
|
si32 destroyed; //how many buildings has been destroyed this turn
|
||||||
const CGHeroInstance * garrisonHero, *visitingHero;
|
ConstTransitivePtr<CGHeroInstance> garrisonHero, visitingHero;
|
||||||
ui32 identifier; //special identifier from h3m (only > RoE maps)
|
ui32 identifier; //special identifier from h3m (only > RoE maps)
|
||||||
si32 alignment;
|
si32 alignment;
|
||||||
std::set<si32> forbiddenBuildings, builtBuildings;
|
std::set<si32> forbiddenBuildings, builtBuildings;
|
||||||
@ -586,10 +595,16 @@ public:
|
|||||||
for (std::vector<CGTownBuilding*>::iterator i = bonusingBuildings.begin(); i!=bonusingBuildings.end(); i++)
|
for (std::vector<CGTownBuilding*>::iterator i = bonusingBuildings.begin(); i!=bonusingBuildings.end(); i++)
|
||||||
(*i)->town = this;
|
(*i)->town = this;
|
||||||
|
|
||||||
h & town;
|
h & town & townAndVis;
|
||||||
//garrison/visiting hero pointers will be restored in the map serialization
|
//garrison/visiting hero pointers will be restored in the map serialization
|
||||||
}
|
}
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
std::string nodeName() const OVERRIDE;
|
||||||
|
void deserializationFix();
|
||||||
|
void recreateBuildingsBonuses();
|
||||||
|
void setVisitingHero(CGHeroInstance *h);
|
||||||
|
void setGarrisonedHero(CGHeroInstance *h);
|
||||||
// void getParents(TCNodes &out, const CBonusSystemNode *root = NULL) const;
|
// void getParents(TCNodes &out, const CBonusSystemNode *root = NULL) const;
|
||||||
// void getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root = NULL) const;
|
// void getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root = NULL) const;
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -944,4 +944,6 @@ public:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define BONUS_TREE_DESERIALIZATION_FIX if(!h.saving) deserializationFix();
|
||||||
|
|
||||||
#endif // __CONNECTION_H__
|
#endif // __CONNECTION_H__
|
||||||
|
@ -46,6 +46,10 @@ public:
|
|||||||
{
|
{
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
const T*operator=(T *t)
|
||||||
|
{
|
||||||
|
return ptr = t;
|
||||||
|
}
|
||||||
|
|
||||||
void dellNull()
|
void dellNull()
|
||||||
{
|
{
|
||||||
|
@ -315,6 +315,8 @@ CBonusSystemNode::~CBonusSystemNode()
|
|||||||
if(children.size())
|
if(children.size())
|
||||||
{
|
{
|
||||||
tlog2 << "Warning: an orphaned child!\n";
|
tlog2 << "Warning: an orphaned child!\n";
|
||||||
|
while(children.size())
|
||||||
|
children.front()->detachFrom(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -440,6 +442,11 @@ std::string CBonusSystemNode::nodeName() const
|
|||||||
return std::string("Bonus system node of type ") + typeid(*this).name();
|
return std::string("Bonus system node of type ") + typeid(*this).name();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CBonusSystemNode::deserializationFix()
|
||||||
|
{
|
||||||
|
tlog2 << "Deserialization fix called on bare CBSN? Shouldn't be...\n";
|
||||||
|
}
|
||||||
|
|
||||||
int NBonus::valOf(const CBonusSystemNode *obj, Bonus::BonusType type, int subtype /*= -1*/)
|
int NBonus::valOf(const CBonusSystemNode *obj, Bonus::BonusType type, int subtype /*= -1*/)
|
||||||
{
|
{
|
||||||
if(obj)
|
if(obj)
|
||||||
|
@ -434,6 +434,7 @@ public:
|
|||||||
|
|
||||||
void popBonuses(const CSelector &s);
|
void popBonuses(const CSelector &s);
|
||||||
virtual std::string nodeName() const;
|
virtual std::string nodeName() const;
|
||||||
|
void deserializationFix();
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
|
@ -287,17 +287,17 @@ struct HeroVisitCastle : public CPackForClient //108
|
|||||||
void applyCl(CClient *cl);
|
void applyCl(CClient *cl);
|
||||||
DLL_EXPORT void applyGs(CGameState *gs);
|
DLL_EXPORT void applyGs(CGameState *gs);
|
||||||
|
|
||||||
ui8 flags; //1 - start, 2 - garrison
|
ui8 flags; //1 - start
|
||||||
ui32 tid, hid;
|
ui32 tid, hid;
|
||||||
|
|
||||||
bool start() //if hero is entering castle (if false - leaving)
|
bool start() //if hero is entering castle (if false - leaving)
|
||||||
{
|
{
|
||||||
return flags & 1;
|
return flags & 1;
|
||||||
}
|
}
|
||||||
bool garrison() //if hero is entering/leaving garrison (if false - it's only visiting hero)
|
// bool garrison() //if hero is entering/leaving garrison (if false - it's only visiting hero)
|
||||||
{
|
// {
|
||||||
return flags & 2;
|
// return flags & 2;
|
||||||
}
|
// }
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & flags & tid & hid;
|
h & flags & tid & hid;
|
||||||
|
@ -86,36 +86,11 @@ DLL_EXPORT void HeroVisitCastle::applyGs( CGameState *gs )
|
|||||||
{
|
{
|
||||||
CGHeroInstance *h = gs->getHero(hid);
|
CGHeroInstance *h = gs->getHero(hid);
|
||||||
CGTownInstance *t = gs->getTown(tid);
|
CGTownInstance *t = gs->getTown(tid);
|
||||||
|
|
||||||
if(start())
|
if(start())
|
||||||
{
|
t->setVisitingHero(h);
|
||||||
if(garrison())
|
|
||||||
{
|
|
||||||
t->garrisonHero = h;
|
|
||||||
h->visitedTown = t;
|
|
||||||
h->inTownGarrison = true;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
t->setVisitingHero(NULL);
|
||||||
t->visitingHero = h;
|
|
||||||
h->visitedTown = t;
|
|
||||||
h->inTownGarrison = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(garrison())
|
|
||||||
{
|
|
||||||
t->garrisonHero = NULL;
|
|
||||||
h->visitedTown = NULL;
|
|
||||||
h->inTownGarrison = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
t->visitingHero = NULL;
|
|
||||||
h->visitedTown = NULL;
|
|
||||||
h->inTownGarrison = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DLL_EXPORT void ChangeSpells::applyGs( CGameState *gs )
|
DLL_EXPORT void ChangeSpells::applyGs( CGameState *gs )
|
||||||
@ -379,24 +354,6 @@ void TryMoveHero::applyGs( CGameState *gs )
|
|||||||
gs->getPlayerTeam(h->getOwner())->fogOfWarMap[t.x][t.y][t.z] = 1;
|
gs->getPlayerTeam(h->getOwner())->fogOfWarMap[t.x][t.y][t.z] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// DLL_EXPORT void SetGarrisons::applyGs( CGameState *gs )
|
|
||||||
// {
|
|
||||||
// for(std::map<ui32,CCreatureSet>::iterator i = garrs.begin(); i!=garrs.end(); i++)
|
|
||||||
// {
|
|
||||||
// CArmedInstance *ai = static_cast<CArmedInstance*>(gs->map->objects[i->first]);
|
|
||||||
// ai->setToArmy(i->second);
|
|
||||||
// if(ai->ID==TOWNI_TYPE && (static_cast<CGTownInstance*>(ai))->garrisonHero) //if there is a hero in garrison then we must update also his army
|
|
||||||
// const_cast<CGHeroInstance*>((static_cast<CGTownInstance*>(ai))->garrisonHero)->setToArmy(i->second);
|
|
||||||
// else if(ai->ID==HEROI_TYPE)
|
|
||||||
// {
|
|
||||||
// CGHeroInstance *h = static_cast<CGHeroInstance*>(ai);
|
|
||||||
// CGTownInstance *t = const_cast<CGTownInstance *>(h->visitedTown);
|
|
||||||
// if(t && h->inTownGarrison)
|
|
||||||
// t->setToArmy(i->second);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
DLL_EXPORT void NewStructures::applyGs( CGameState *gs )
|
DLL_EXPORT void NewStructures::applyGs( CGameState *gs )
|
||||||
{
|
{
|
||||||
CGTownInstance *t = gs->getTown(tid);
|
CGTownInstance *t = gs->getTown(tid);
|
||||||
@ -405,6 +362,7 @@ DLL_EXPORT void NewStructures::applyGs( CGameState *gs )
|
|||||||
t->builtBuildings.insert(id);
|
t->builtBuildings.insert(id);
|
||||||
}
|
}
|
||||||
t->builded = builded;
|
t->builded = builded;
|
||||||
|
t->recreateBuildingsBonuses();
|
||||||
}
|
}
|
||||||
DLL_EXPORT void RazeStructures::applyGs( CGameState *gs )
|
DLL_EXPORT void RazeStructures::applyGs( CGameState *gs )
|
||||||
{
|
{
|
||||||
@ -414,7 +372,9 @@ DLL_EXPORT void RazeStructures::applyGs( CGameState *gs )
|
|||||||
t->builtBuildings.erase(id);
|
t->builtBuildings.erase(id);
|
||||||
}
|
}
|
||||||
t->destroyed = destroyed; //yeaha
|
t->destroyed = destroyed; //yeaha
|
||||||
|
t->recreateBuildingsBonuses();
|
||||||
}
|
}
|
||||||
|
|
||||||
DLL_EXPORT void SetAvailableCreatures::applyGs( CGameState *gs )
|
DLL_EXPORT void SetAvailableCreatures::applyGs( CGameState *gs )
|
||||||
{
|
{
|
||||||
CGDwelling *dw = dynamic_cast<CGDwelling*>(gs->map->objects[tid].get());
|
CGDwelling *dw = dynamic_cast<CGDwelling*>(gs->map->objects[tid].get());
|
||||||
@ -429,71 +389,34 @@ DLL_EXPORT void SetHeroesInTown::applyGs( CGameState *gs )
|
|||||||
CGHeroInstance *v = gs->getHero(visiting),
|
CGHeroInstance *v = gs->getHero(visiting),
|
||||||
*g = gs->getHero(garrison);
|
*g = gs->getHero(garrison);
|
||||||
|
|
||||||
t->visitingHero = v;
|
bool newVisitorComesFromGarrison = v && v == t->garrisonHero;
|
||||||
t->garrisonHero = g;
|
bool newGarrisonComesFromVisiting = g && g == t->visitingHero;
|
||||||
|
|
||||||
|
if(newVisitorComesFromGarrison)
|
||||||
|
t->setGarrisonedHero(NULL);
|
||||||
|
if(newGarrisonComesFromVisiting)
|
||||||
|
t->setVisitingHero(NULL);
|
||||||
|
if(!newGarrisonComesFromVisiting || v)
|
||||||
|
t->setVisitingHero(v);
|
||||||
|
if(!newVisitorComesFromGarrison || g)
|
||||||
|
t->setGarrisonedHero(g);
|
||||||
|
|
||||||
if(v)
|
if(v)
|
||||||
{
|
{
|
||||||
v->visitedTown = t;
|
|
||||||
v->inTownGarrison = false;
|
|
||||||
gs->map->addBlockVisTiles(v);
|
gs->map->addBlockVisTiles(v);
|
||||||
}
|
}
|
||||||
if(g)
|
if(g)
|
||||||
{
|
{
|
||||||
g->visitedTown = t;
|
|
||||||
g->inTownGarrison = true;
|
|
||||||
gs->map->removeBlockVisTiles(g);
|
gs->map->removeBlockVisTiles(g);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 )
|
DLL_EXPORT void HeroRecruited::applyGs( CGameState *gs )
|
||||||
{
|
{
|
||||||
assert(vstd::contains(gs->hpool.heroesPool, hid));
|
assert(vstd::contains(gs->hpool.heroesPool, hid));
|
||||||
CGHeroInstance *h = gs->hpool.heroesPool[hid];
|
CGHeroInstance *h = gs->hpool.heroesPool[hid];
|
||||||
CGTownInstance *t = gs->getTown(tid);
|
CGTownInstance *t = gs->getTown(tid);
|
||||||
|
PlayerState *p = gs->getPlayer(player);
|
||||||
h->setOwner(player);
|
h->setOwner(player);
|
||||||
h->pos = tile;
|
h->pos = tile;
|
||||||
h->movement = h->maxMovePoints(true);
|
h->movement = h->maxMovePoints(true);
|
||||||
@ -509,16 +432,15 @@ DLL_EXPORT void HeroRecruited::applyGs( CGameState *gs )
|
|||||||
|
|
||||||
h->initHeroDefInfo();
|
h->initHeroDefInfo();
|
||||||
gs->map->heroes.push_back(h);
|
gs->map->heroes.push_back(h);
|
||||||
gs->getPlayer(h->getOwner())->heroes.push_back(h);
|
p->heroes.push_back(h);
|
||||||
|
h->attachTo(p);
|
||||||
h->initObj();
|
h->initObj();
|
||||||
gs->map->addBlockVisTiles(h);
|
gs->map->addBlockVisTiles(h);
|
||||||
|
|
||||||
if(t)
|
if(t)
|
||||||
{
|
{
|
||||||
t->visitingHero = h;
|
t->setVisitingHero(h);
|
||||||
h->visitedTown = t;
|
|
||||||
}
|
}
|
||||||
h->inTownGarrison = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DLL_EXPORT void GiveHero::applyGs( CGameState *gs )
|
DLL_EXPORT void GiveHero::applyGs( CGameState *gs )
|
||||||
@ -702,7 +624,6 @@ DLL_EXPORT void PutArtifact::applyGs( CGameState *gs )
|
|||||||
{
|
{
|
||||||
assert(art->canBePutAt(al));
|
assert(art->canBePutAt(al));
|
||||||
al.hero->putArtifact(al.slot, art);
|
al.hero->putArtifact(al.slot, art);
|
||||||
//art->putAt(al.hero, al.slot);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DLL_EXPORT void EraseArtifact::applyGs( CGameState *gs )
|
DLL_EXPORT void EraseArtifact::applyGs( CGameState *gs )
|
||||||
|
@ -2142,14 +2142,15 @@ bool CGameHandler::buildStructure( si32 tid, si32 bid, bool force /*=false*/ )
|
|||||||
ns.bid.insert(29);
|
ns.bid.insert(29);
|
||||||
else if (t->subID == 4 && bid == 17) //veil of darkness
|
else if (t->subID == 4 && bid == 17) //veil of darkness
|
||||||
{
|
{
|
||||||
GiveBonus gb(GiveBonus::TOWN);
|
//handled via town->reacreateBonuses in apply
|
||||||
gb.bonus.type = Bonus::DARKNESS;
|
// GiveBonus gb(GiveBonus::TOWN);
|
||||||
gb.bonus.val = 20;
|
// gb.bonus.type = Bonus::DARKNESS;
|
||||||
gb.id = t->id;
|
// gb.bonus.val = 20;
|
||||||
gb.bonus.duration = Bonus::PERMANENT;
|
// gb.id = t->id;
|
||||||
gb.bonus.source = Bonus::TOWN_STRUCTURE;
|
// gb.bonus.duration = Bonus::PERMANENT;
|
||||||
gb.bonus.id = 17;
|
// gb.bonus.source = Bonus::TOWN_STRUCTURE;
|
||||||
sendAndApply(&gb);
|
// gb.bonus.id = 17;
|
||||||
|
// sendAndApply(&gb);
|
||||||
}
|
}
|
||||||
else if ( t->subID == 5 && bid == 22 )
|
else if ( t->subID == 5 && bid == 22 )
|
||||||
{
|
{
|
||||||
@ -2204,14 +2205,14 @@ bool CGameHandler::razeStructure (si32 tid, si32 bid)
|
|||||||
rs.destroyed = t->destroyed + 1;
|
rs.destroyed = t->destroyed + 1;
|
||||||
sendAndApply(&rs);
|
sendAndApply(&rs);
|
||||||
//TODO: Remove dwellers
|
//TODO: Remove dwellers
|
||||||
if (t->subID == 4 && bid == 17) //Veil of Darkness
|
// if (t->subID == 4 && bid == 17) //Veil of Darkness
|
||||||
{
|
// {
|
||||||
RemoveBonus rb(RemoveBonus::TOWN);
|
// RemoveBonus rb(RemoveBonus::TOWN);
|
||||||
rb.whoID = t->id;
|
// rb.whoID = t->id;
|
||||||
rb.source = Bonus::TOWN_STRUCTURE;
|
// rb.source = Bonus::TOWN_STRUCTURE;
|
||||||
rb.id = 17;
|
// rb.id = 17;
|
||||||
sendAndApply(&rb);
|
// sendAndApply(&rb);
|
||||||
}
|
// }
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2371,7 +2372,7 @@ bool CGameHandler::changeStackType(const StackLocation &sl, CCreature *c)
|
|||||||
void CGameHandler::moveArmy(const CArmedInstance *src, const CArmedInstance *dst, bool allowMerging)
|
void CGameHandler::moveArmy(const CArmedInstance *src, const CArmedInstance *dst, bool allowMerging)
|
||||||
{
|
{
|
||||||
assert(src->canBeMergedWith(*dst, allowMerging));
|
assert(src->canBeMergedWith(*dst, allowMerging));
|
||||||
while(!src->stacksCount())//while there are unmoved creatures
|
while(src->stacksCount())//while there are unmoved creatures
|
||||||
{
|
{
|
||||||
TSlots::const_iterator i = src->Slots().begin(); //iterator to stack to move
|
TSlots::const_iterator i = src->Slots().begin(); //iterator to stack to move
|
||||||
StackLocation sl(src, i->first); //location of stack to move
|
StackLocation sl(src, i->first); //location of stack to move
|
||||||
@ -2437,7 +2438,7 @@ bool CGameHandler::garrisonSwap( si32 tid )
|
|||||||
sendAndApply(&intown);
|
sendAndApply(&intown);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (town->garrisonHero && town->visitingHero) //swap visiting and garrison hero
|
else if(!!town->garrisonHero && town->visitingHero) //swap visiting and garrison hero
|
||||||
{
|
{
|
||||||
SetHeroesInTown intown;
|
SetHeroesInTown intown;
|
||||||
intown.tid = tid;
|
intown.tid = tid;
|
||||||
@ -3480,7 +3481,7 @@ void CGameHandler::playerMessage( ui8 player, const std::string &message )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<ui32> calculateResistedStacks(const CSpell * sp, const CGHeroInstance * caster, const CGHeroInstance * hero2, const std::set<CStack*> affectedCreatures)
|
static std::vector<ui32> calculateResistedStacks(const CSpell * sp, const CGHeroInstance * caster, const CGHeroInstance * hero2, const std::set<CStack*> affectedCreatures, int casterSideOwner)
|
||||||
{
|
{
|
||||||
std::vector<ui32> ret;
|
std::vector<ui32> ret;
|
||||||
for(std::set<CStack*>::const_iterator it = affectedCreatures.begin(); it != affectedCreatures.end(); ++it)
|
for(std::set<CStack*>::const_iterator it = affectedCreatures.begin(); it != affectedCreatures.end(); ++it)
|
||||||
@ -3518,11 +3519,11 @@ static std::vector<ui32> calculateResistedStacks(const CSpell * sp, const CGHero
|
|||||||
|
|
||||||
|
|
||||||
//non-negative spells on friendly stacks should always succeed, unless immune
|
//non-negative spells on friendly stacks should always succeed, unless immune
|
||||||
if(sp->positiveness >= 0 && (*it)->owner == caster->tempOwner)
|
if(sp->positiveness >= 0 && (*it)->owner == casterSideOwner)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const CGHeroInstance * bonusHero; //hero we should take bonuses from
|
const CGHeroInstance * bonusHero; //hero we should take bonuses from
|
||||||
if(caster && (*it)->owner == caster->tempOwner)
|
if((*it)->owner == casterSideOwner)
|
||||||
bonusHero = caster;
|
bonusHero = caster;
|
||||||
else
|
else
|
||||||
bonusHero = hero2;
|
bonusHero = hero2;
|
||||||
@ -3582,7 +3583,7 @@ void CGameHandler::handleSpellCasting( int spellID, int spellLvl, int destinatio
|
|||||||
}
|
}
|
||||||
|
|
||||||
//checking if creatures resist
|
//checking if creatures resist
|
||||||
sc.resisted = calculateResistedStacks(spell, caster, secHero, attackedCres);
|
sc.resisted = calculateResistedStacks(spell, caster, secHero, attackedCres, casterColor);
|
||||||
|
|
||||||
//calculating dmg to display
|
//calculating dmg to display
|
||||||
for(std::set<CStack*>::iterator it = attackedCres.begin(); it != attackedCres.end(); ++it)
|
for(std::set<CStack*>::iterator it = attackedCres.begin(); it != attackedCres.end(); ++it)
|
||||||
|
Reference in New Issue
Block a user