mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Next set of fixes, mostly for deserialization.
This commit is contained in:
parent
1458cf64c2
commit
a46ad0b7ef
@ -1713,14 +1713,14 @@ void CBattleInterface::show(SDL_Surface * to)
|
||||
|
||||
if(tacticsMode)
|
||||
{
|
||||
btactNext->show(to);
|
||||
btactEnd->show(to);
|
||||
btactNext->showAll(to);
|
||||
btactEnd->showAll(to);
|
||||
}
|
||||
else
|
||||
{
|
||||
console->show(to);
|
||||
bConsoleUp->show(to);
|
||||
bConsoleDown->show(to);
|
||||
console->showAll(to);
|
||||
bConsoleUp->showAll(to);
|
||||
bConsoleDown->showAll(to);
|
||||
}
|
||||
|
||||
//showing buttons
|
||||
|
@ -475,7 +475,7 @@ void CClient::serialize( Handler &h, const int version )
|
||||
else
|
||||
nInt = new CPlayerInterface(pid);
|
||||
|
||||
playerint[pid] = nInt;
|
||||
battleints[pid] = playerint[pid] = nInt;
|
||||
nInt->init(callback);
|
||||
nInt->serialize(h, version);
|
||||
}
|
||||
|
2
global.h
2
global.h
@ -683,4 +683,6 @@ static inline ui32 read_unaligned_u32(const void *p)
|
||||
#define OVERRIDE //is there any working counterpart?
|
||||
#endif
|
||||
|
||||
#define BONUS_TREE_DESERIALIZATION_FIX if(!h.saving) deserializationFix();
|
||||
|
||||
#endif // __GLOBAL_H__
|
||||
|
@ -92,6 +92,7 @@ public:
|
||||
{
|
||||
h & static_cast<CBonusSystemNode&>(*this);
|
||||
h & artType & id;
|
||||
BONUS_TREE_DESERIALIZATION_FIX
|
||||
}
|
||||
|
||||
static CArtifactInstance *createScroll(const CSpell *s);
|
||||
@ -136,6 +137,7 @@ public:
|
||||
{
|
||||
h & static_cast<CArtifactInstance&>(*this);
|
||||
h & constituentsInfo;
|
||||
BONUS_TREE_DESERIALIZATION_FIX
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -487,15 +487,11 @@ void CCreatureHandler::loadCreatures()
|
||||
break;
|
||||
CCreature *c = creatures[id];
|
||||
c->level = lvl;
|
||||
if(isbetw(lvl, 0, ARRAY_COUNT(creaturesOfLevel)))
|
||||
c->attachTo(&creaturesOfLevel[lvl]);
|
||||
else
|
||||
c->attachTo(&creaturesOfLevel[0]);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_FOREACH(CBonusSystemNode &b, creaturesOfLevel)
|
||||
b.attachTo(&allCreatures);
|
||||
buildBonusTreeForTiers();
|
||||
|
||||
|
||||
ifs.close();
|
||||
ifs.clear();
|
||||
@ -1109,4 +1105,22 @@ void CCreatureHandler::addBonusForTier(int tier, Bonus *b)
|
||||
void CCreatureHandler::addBonusForAllCreatures(Bonus *b)
|
||||
{
|
||||
allCreatures.addNewBonus(b);
|
||||
}
|
||||
|
||||
void CCreatureHandler::buildBonusTreeForTiers()
|
||||
{
|
||||
BOOST_FOREACH(CCreature *c, creatures)
|
||||
{
|
||||
if(isbetw(c->level, 0, ARRAY_COUNT(creaturesOfLevel)))
|
||||
c->attachTo(&creaturesOfLevel[c->level]);
|
||||
else
|
||||
c->attachTo(&creaturesOfLevel[0]);
|
||||
}
|
||||
BOOST_FOREACH(CBonusSystemNode &b, creaturesOfLevel)
|
||||
b.attachTo(&allCreatures);
|
||||
}
|
||||
|
||||
void CCreatureHandler::deserializationFix()
|
||||
{
|
||||
buildBonusTreeForTiers();
|
||||
}
|
@ -117,7 +117,10 @@ public:
|
||||
std::vector<ui32> maxExpPerBattle; //%, tiers same as above
|
||||
si8 expAfterUpgrade;//multiplier in %
|
||||
|
||||
|
||||
void deserializationFix();
|
||||
void loadCreatures();
|
||||
void buildBonusTreeForTiers();
|
||||
void loadAnimationInfo();
|
||||
void loadUnitAnimInfo(CCreature & unit, std::string & src, int & i);
|
||||
void loadStackExp(Bonus & b, BonusList & bl, std::string & src, int & it);
|
||||
@ -138,8 +141,10 @@ public:
|
||||
{
|
||||
//TODO: should be optimized, not all these informations needs to be serialized (same for ccreature)
|
||||
h & notUsedMonsters & creatures & nameToID & idToProjectile & idToProjectileSpin & factionToTurretCreature;
|
||||
h & stackBonuses & expRanks & maxExpPerBattle & expAfterUpgrade;
|
||||
h & allCreatures;
|
||||
h & creaturesOfLevel;
|
||||
BONUS_TREE_DESERIALIZATION_FIX
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -650,8 +650,12 @@ std::string CStackInstance::nodeName() const
|
||||
|
||||
void CStackInstance::deserializationFix()
|
||||
{
|
||||
setType(type);
|
||||
setArmyObj(armyObj);
|
||||
const CCreature *backup = type;
|
||||
type = NULL;
|
||||
setType(backup);
|
||||
const CArmedInstance *armyBackup = _armyObj;
|
||||
_armyObj = NULL;
|
||||
setArmyObj(armyBackup);
|
||||
}
|
||||
|
||||
CStackBasicDescriptor::CStackBasicDescriptor()
|
||||
|
@ -41,6 +41,7 @@ public:
|
||||
h & static_cast<CBonusSystemNode&>(*this);
|
||||
h & static_cast<CStackBasicDescriptor&>(*this);
|
||||
h & _armyObj & experience;
|
||||
BONUS_TREE_DESERIALIZATION_FIX
|
||||
}
|
||||
|
||||
//overrides CBonusSystemNode
|
||||
|
@ -2851,6 +2851,25 @@ bmap<ui32, ConstTransitivePtr<CGHeroInstance> > CGameState::unusedHeroesFromPool
|
||||
}
|
||||
|
||||
void CGameState::buildBonusSystemTree()
|
||||
{
|
||||
buildGlobalTeamPlayerTree();
|
||||
attachArmedObjects();
|
||||
|
||||
BOOST_FOREACH(CGTownInstance *t, map->towns)
|
||||
{
|
||||
t->deserializationFix();
|
||||
}
|
||||
// CStackInstance <-> CCreature, CStackInstance <-> CArmedInstance, CArtifactInstance <-> CArtifact
|
||||
// are provided on initializing / deserializing
|
||||
}
|
||||
|
||||
void CGameState::deserializationFix()
|
||||
{
|
||||
buildGlobalTeamPlayerTree();
|
||||
attachArmedObjects();
|
||||
}
|
||||
|
||||
void CGameState::buildGlobalTeamPlayerTree()
|
||||
{
|
||||
for(std::map<ui8, TeamState>::iterator k=teams.begin(); k!=teams.end(); ++k)
|
||||
{
|
||||
@ -2863,33 +2882,16 @@ void CGameState::buildBonusSystemTree()
|
||||
assert(p);
|
||||
p->attachTo(t);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void CGameState::attachArmedObjects()
|
||||
{
|
||||
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);
|
||||
}
|
||||
armed->whatShouldBeAttached()->attachTo(armed->whereShouldBeAttached(this));
|
||||
}
|
||||
|
||||
BOOST_FOREACH(CGTownInstance *t, map->towns)
|
||||
{
|
||||
t->deserializationFix();
|
||||
}
|
||||
// CStackInstance <-> CCreature, CStackInstance <-> CArmedInstance, CArtifactInstance <-> CArtifact
|
||||
// are provided on initializing / deserializing
|
||||
}
|
||||
|
||||
int3 CPath::startPos() const
|
||||
|
@ -145,6 +145,7 @@ public:
|
||||
|
||||
PlayerState();
|
||||
std::string nodeName() const OVERRIDE;
|
||||
void deserializationFix();
|
||||
|
||||
//override
|
||||
//void getParents(TCNodes &out, const CBonusSystemNode *root = NULL) const;
|
||||
@ -350,6 +351,9 @@ public:
|
||||
BattleInfo * setupBattle(int3 tile, const CArmedInstance *armies[2], const CGHeroInstance * heroes[2], bool creatureBank, const CGTownInstance *town);
|
||||
|
||||
void buildBonusSystemTree();
|
||||
void attachArmedObjects();
|
||||
void buildGlobalTeamPlayerTree();
|
||||
void deserializationFix();
|
||||
|
||||
bool isVisible(int3 pos, int player);
|
||||
bool isVisible(const CGObjectInstance *obj, int player);
|
||||
@ -361,7 +365,7 @@ public:
|
||||
int getDate(int mode=0) const; //mode=0 - total days in game, mode=1 - day of week, mode=2 - current week, mode=3 - current month
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & scenarioOps & seed & currentPlayer & day & map & players & teams & hpool & globalEffects & campaign;
|
||||
h & scenarioOps & initialOpts & seed & currentPlayer & day & map & players & teams & hpool & globalEffects & campaign;
|
||||
h & villages & forts & capitols;
|
||||
if(!h.saving)
|
||||
{
|
||||
|
@ -26,6 +26,8 @@
|
||||
#include <SDL_stdinc.h>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/algorithm/string/trim.hpp>
|
||||
|
||||
using namespace boost::assign;
|
||||
|
||||
/*
|
||||
@ -1493,6 +1495,19 @@ void CGHeroInstance::deserializationFix()
|
||||
attachTo(&speciality);
|
||||
}
|
||||
|
||||
CBonusSystemNode * CGHeroInstance::whereShouldBeAttached(CGameState *gs)
|
||||
{
|
||||
if(visitedTown)
|
||||
{
|
||||
if(inTownGarrison)
|
||||
return visitedTown;
|
||||
else
|
||||
return &visitedTown->townAndVis;
|
||||
}
|
||||
else
|
||||
return CArmedInstance::whereShouldBeAttached(gs);
|
||||
}
|
||||
|
||||
void CGDwelling::initObj()
|
||||
{
|
||||
switch(ID)
|
||||
@ -2367,6 +2382,11 @@ bool CGTownInstance::armedGarrison() const
|
||||
return stacksCount() || garrisonHero;
|
||||
}
|
||||
|
||||
CBonusSystemNode * CGTownInstance::whatShouldBeAttached()
|
||||
{
|
||||
return &townAndVis;
|
||||
}
|
||||
|
||||
void CGVisitableOPH::onHeroVisit( const CGHeroInstance * h ) const
|
||||
{
|
||||
if(visitors.find(h->id)==visitors.end())
|
||||
@ -6586,6 +6606,7 @@ void CArmedInstance::updateMoraleBonusFromArmy()
|
||||
b->val = 2-factions.size();
|
||||
b->description = boost::str(boost::format(VLC->generaltexth->arraytxt[114]) % factions.size() % b->val); //Troops of %d alignments %d
|
||||
}
|
||||
boost::algorithm::trim(b->description);
|
||||
|
||||
//-1 modifier for any Necropolis unit in army
|
||||
const ui8 UNDEAD_MODIFIER_ID = -2;
|
||||
@ -6605,6 +6626,19 @@ void CArmedInstance::armyChanged()
|
||||
updateMoraleBonusFromArmy();
|
||||
}
|
||||
|
||||
CBonusSystemNode * CArmedInstance::whereShouldBeAttached(CGameState *gs)
|
||||
{
|
||||
if(tempOwner < PLAYER_LIMIT)
|
||||
return gs->getPlayer(tempOwner);
|
||||
else
|
||||
return &gs->globalEffects;
|
||||
}
|
||||
|
||||
CBonusSystemNode * CArmedInstance::whatShouldBeAttached()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
bool IMarket::getOffer(int id1, int id2, int &val1, int &val2, EMarketMode mode) const
|
||||
{
|
||||
switch(mode)
|
||||
|
@ -25,6 +25,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
class CGameState;
|
||||
class CArtifactInstance;
|
||||
struct MetaString;
|
||||
struct BattleInfo;
|
||||
@ -231,9 +232,9 @@ public:
|
||||
void armyChanged() OVERRIDE;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//void getParents(TCNodes &out, const CBonusSystemNode *root = NULL) const;
|
||||
//void getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root = NULL) const;
|
||||
int valOfGlobalBonuses(CSelector selector) const; //used only for castle interface ???
|
||||
virtual CBonusSystemNode *whereShouldBeAttached(CGameState *gs);
|
||||
virtual CBonusSystemNode *whatShouldBeAttached();
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CArmedInstance();
|
||||
@ -319,7 +320,7 @@ public:
|
||||
si32 movement; //remaining movement points
|
||||
ui8 sex;
|
||||
ui8 inTownGarrison; // if hero is in town garrison
|
||||
const CGTownInstance * visitedTown; //set if hero is visiting town or in the town garrison
|
||||
ConstTransitivePtr<CGTownInstance> visitedTown; //set if hero is visiting town or in the town garrison
|
||||
const CGBoat *boat; //set to CGBoat when sailing
|
||||
|
||||
|
||||
@ -361,6 +362,7 @@ public:
|
||||
& sex & inTownGarrison & /*artifacts & artifWorn & */spells & patrol & moveDir;
|
||||
|
||||
h & type & speciality;
|
||||
BONUS_TREE_DESERIALIZATION_FIX
|
||||
//visitied town pointer will be restored by map serialization method
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -433,7 +435,7 @@ public:
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
virtual CBonusSystemNode *whereShouldBeAttached(CGameState *gs) OVERRIDE;
|
||||
virtual std::string nodeName() const OVERRIDE;
|
||||
void deserializationFix();
|
||||
void setPropertyDer(ui8 what, ui32 val);//synchr
|
||||
@ -596,10 +598,12 @@ public:
|
||||
(*i)->town = this;
|
||||
|
||||
h & town & townAndVis;
|
||||
BONUS_TREE_DESERIALIZATION_FIX
|
||||
//garrison/visiting hero pointers will be restored in the map serialization
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual CBonusSystemNode *whatShouldBeAttached() OVERRIDE;
|
||||
std::string nodeName() const OVERRIDE;
|
||||
void deserializationFix();
|
||||
void recreateBuildingsBonuses();
|
||||
|
@ -944,6 +944,5 @@ public:
|
||||
|
||||
};
|
||||
|
||||
#define BONUS_TREE_DESERIALIZATION_FIX if(!h.saving) deserializationFix();
|
||||
|
||||
#endif // __CONNECTION_H__
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "CHeroHandler.h"
|
||||
#include "CGeneralTextHandler.h"
|
||||
#include "BattleState.h"
|
||||
#include "CArtHandler.h"
|
||||
|
||||
#define FOREACH_CONST_PARENT(pname) TCNodes lparents; getParents(lparents); BOOST_FOREACH(const CBonusSystemNode *pname, lparents)
|
||||
#define FOREACH_PARENT(pname) TNodes lparents; getParents(lparents); BOOST_FOREACH(CBonusSystemNode *pname, lparents)
|
||||
@ -606,20 +607,21 @@ std::string Bonus::Description() const
|
||||
return description;
|
||||
|
||||
std::ostringstream str;
|
||||
if(val < 0)
|
||||
str << '-';
|
||||
else if(val > 0)
|
||||
str << '+';
|
||||
|
||||
str << val << " ";
|
||||
str << std::showpos << val << " ";
|
||||
|
||||
switch(source)
|
||||
{
|
||||
case ARTIFACT:
|
||||
str << VLC->arth->artifacts[sid]->Name();
|
||||
break;;
|
||||
case SPELL_EFFECT:
|
||||
str << VLC->spellh->spells[sid]->name;
|
||||
break;
|
||||
case CREATURE_ABILITY:
|
||||
str << VLC->creh->creatures[sid]->namePl;
|
||||
break;
|
||||
case SECONDARY_SKILL:
|
||||
str << VLC->generaltexth->skillName[sid] << " secondary skill";
|
||||
str << VLC->generaltexth->skillName[sid]/* << " secondary skill"*/;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -824,6 +826,8 @@ bool ILimiter::limit(const Bonus *b, const CBonusSystemNode &node) const /*retur
|
||||
bool CCreatureTypeLimiter::limit(const Bonus *b, const CBonusSystemNode &node) const
|
||||
{
|
||||
const CCreature *c = retrieveCreature(&node);
|
||||
if(!c)
|
||||
return true;
|
||||
return c != creature && (!includeUpgrades || !creature->isMyUpgrade(c));
|
||||
//drop bonus if it's not our creature and (we dont check upgrades or its not our upgrade)
|
||||
}
|
||||
|
@ -246,15 +246,15 @@ DLL_EXPORT void RemoveObject::applyGs( CGameState *gs )
|
||||
PlayerState *p = gs->getPlayer(h->tempOwner);
|
||||
gs->map->heroes -= h;
|
||||
p->heroes -= h;
|
||||
h->detachFrom(p);
|
||||
h->detachFrom(h->whereShouldBeAttached(gs));
|
||||
h->tempOwner = 255; //no one owns beaten hero
|
||||
|
||||
if(CGTownInstance *t = const_cast<CGTownInstance *>(h->visitedTown))
|
||||
if(h->visitedTown)
|
||||
{
|
||||
if(h->inTownGarrison)
|
||||
t->garrisonHero = NULL;
|
||||
h->visitedTown->garrisonHero = NULL;
|
||||
else
|
||||
t->visitingHero = NULL;
|
||||
h->visitedTown->visitingHero = NULL;
|
||||
h->visitedTown = NULL;
|
||||
}
|
||||
|
||||
@ -800,36 +800,27 @@ DLL_EXPORT void SetObjectProperty::applyGs( CGameState *gs )
|
||||
|
||||
if(what == ObjProperty::OWNER)
|
||||
{
|
||||
CBonusSystemNode *nodeToMove = NULL;
|
||||
if(obj->ID == TOWNI_TYPE)
|
||||
{
|
||||
CGTownInstance *t = static_cast<CGTownInstance*>(obj);
|
||||
nodeToMove = &t->townAndVis;
|
||||
if(t->tempOwner < PLAYER_LIMIT)
|
||||
gs->getPlayer(t->tempOwner)->towns -= t;
|
||||
|
||||
if(val < PLAYER_LIMIT)
|
||||
gs->getPlayer(val)->towns.push_back(t);
|
||||
}
|
||||
if(CArmedInstance *cai = dynamic_cast<CArmedInstance *>(obj))
|
||||
{
|
||||
if(!nodeToMove)
|
||||
nodeToMove = cai;
|
||||
|
||||
if(obj->tempOwner < PLAYER_LIMIT)
|
||||
nodeToMove->detachFrom(gs->getPlayer(obj->tempOwner));
|
||||
else
|
||||
nodeToMove->detachFrom(&gs->globalEffects);
|
||||
|
||||
if(val < PLAYER_LIMIT)
|
||||
nodeToMove->attachTo(gs->getPlayer(val));
|
||||
else
|
||||
nodeToMove->attachTo(&gs->globalEffects);
|
||||
if(obj->ID == TOWNI_TYPE)
|
||||
{
|
||||
CGTownInstance *t = static_cast<CGTownInstance*>(obj);
|
||||
if(t->tempOwner < PLAYER_LIMIT)
|
||||
gs->getPlayer(t->tempOwner)->towns -= t;
|
||||
if(val < PLAYER_LIMIT)
|
||||
gs->getPlayer(val)->towns.push_back(t);
|
||||
}
|
||||
|
||||
CBonusSystemNode *nodeToMove = cai->whatShouldBeAttached();
|
||||
nodeToMove->detachFrom(cai->whereShouldBeAttached(gs));
|
||||
obj->setProperty(what,val);
|
||||
nodeToMove->attachTo(cai->whereShouldBeAttached(gs));
|
||||
}
|
||||
}
|
||||
|
||||
obj->setProperty(what,val);
|
||||
else
|
||||
{
|
||||
obj->setProperty(what,val);
|
||||
}
|
||||
}
|
||||
|
||||
DLL_EXPORT void SetHoverName::applyGs( CGameState *gs )
|
||||
|
@ -2777,7 +2777,7 @@ bool CGameHandler::assembleArtifacts (si32 heroID, ui16 artifactSlot, bool assem
|
||||
bool CGameHandler::buyArtifact( ui32 hid, si32 aid )
|
||||
{
|
||||
CGHeroInstance *hero = gs->getHero(hid);
|
||||
CGTownInstance *town = const_cast<CGTownInstance*>(hero->visitedTown);
|
||||
CGTownInstance *town = hero->visitedTown;
|
||||
if(aid==0) //spellbook
|
||||
{
|
||||
if(!vstd::contains(town->builtBuildings,si32(0)) && complain("Cannot buy a spellbook, no mage guild in the town!")
|
||||
|
Loading…
Reference in New Issue
Block a user