1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-12 02:28:11 +02:00
* crash on +5 growth week 
* crash on spawning wandering creatures on double growth months
(how come that has not been found in previous build?)

More logging for #729-like issues.
This commit is contained in:
Michał W. Urbańczyk 2011-05-28 01:02:28 +00:00
parent 4af4f0a707
commit 3ca95ef5ed
11 changed files with 82 additions and 38 deletions

View File

@ -106,7 +106,6 @@ public:
void setBlockVis(int objid, bool bv) OVERRIDE {};
void setOwner(int objid, ui8 owner) OVERRIDE {};
void setHoverName(int objid, MetaString * name) OVERRIDE {};
void setObjProperty(int objid, int prop, si64 val) OVERRIDE {};
void changePrimSkill(int ID, int which, si64 val, bool abs=false) OVERRIDE {};
void changeSecSkill(int ID, int which, int val, bool abs=false) OVERRIDE {};
void showBlockingDialog(BlockingDialog *iw, const CFunctionList<void(ui32)> &callback) OVERRIDE {};

View File

@ -509,7 +509,10 @@ void CStackInstance::giveStackExp(expType exp)
void CStackInstance::setType(int creID)
{
if(creID >= 0 && creID < VLC->creh->creatures.size())
setType(VLC->creh->creatures[creID]);
else
setType(NULL);
}
void CStackInstance::setType(const CCreature *c)

View File

@ -271,7 +271,17 @@ void MetaString::getLocalString(const std::pair<ui8,ui32> &txt, std::string &dst
case COLOR:
vec = &VLC->generaltexth->capColors;
break;
default:
tlog1 << "Failed string substitution because type is " << type << std::endl;
dst = "#@#";
return;
}
if(vec->size() <= ser)
{
tlog1 << "Failed string substitution with type " << type << " because index " << ser << " is out of bounds!\n";
dst = "#!#";
}
else
dst = (*vec)[ser];
}
}

View File

@ -3008,23 +3008,23 @@ void CGCreature::newTurn() const
if (stacks.begin()->second->count < CREEP_SIZE && cb->getDate(1) == 1 && cb->getDate(0) > 1)
{
ui32 power = temppower * (100 + WEEKLY_GROWTH)/100;
cb->setObjProperty(id, 10, std::min (power/1000 , (ui32)CREEP_SIZE)); //set new amount
cb->setObjProperty(id, 11, power); //increase temppower
cb->setObjProperty(id, ObjProperty::MONSTER_COUNT, std::min (power/1000 , (ui32)CREEP_SIZE)); //set new amount
cb->setObjProperty(id, ObjProperty::MONSTER_POWER, power); //increase temppower
}
if (STACK_EXP)
cb->setObjProperty(id, 12, 10000); //for testing purpose
cb->setObjProperty(id, ObjProperty::MONSTER_EXP, 10000); //for testing purpose
}
void CGCreature::setPropertyDer(ui8 what, ui32 val)
{
switch (what)
{
case 10:
case ObjProperty::MONSTER_COUNT:
stacks[0]->count = val;
break;
case 11:
case ObjProperty::MONSTER_POWER:
temppower = val;
break;
case 12:
case ObjProperty::MONSTER_EXP:
giveStackExp(val);
break;
case 13:

View File

@ -1184,3 +1184,30 @@ void IGameEventRealizer::showInfoDialog( InfoWindow *iw )
{
commitPackage(iw);
}
void IGameEventRealizer::setObjProperty(int objid, int prop, si64 val)
{
SetObjectProperty sob;
sob.id = objid;
sob.what = prop;
sob.val = val;
commitPackage(&sob);
}
const CGObjectInstance * IGameCallback::putNewObject(int ID, int subID, int3 pos)
{
NewObject no;
no.ID = ID; //creature
no.subID= subID;
no.pos = pos;
commitPackage(&no);
return getObj(no.id); //id field will be filled during applaying on gs
}
const CGCreature * IGameCallback::putNewMonster(int creID, int count, int3 pos)
{
const CGObjectInstance *m = putNewObject(54, creID, pos);
setObjProperty(m->id, ObjProperty::MONSTER_COUNT, count);
setObjProperty(m->id, ObjProperty::MONSTER_POWER, (si64)1000*count);
return dynamic_cast<const CGCreature*>(m);
}

View File

@ -55,6 +55,8 @@ class CCreatureSet;
class CCreature;
class CStackBasicDescriptor;
class TeamState;
class CGCreature;
typedef std::vector<const CStack*> TStacks;
@ -246,6 +248,7 @@ public:
virtual void commitPackage(CPackForClient *pack) = 0;
virtual void showInfoDialog(InfoWindow *iw);
virtual void setObjProperty(int objid, int prop, si64 val);
};
class DLL_EXPORT IGameEventCallback : public IGameEventRealizer
@ -256,7 +259,6 @@ public:
virtual void setBlockVis(int objid, bool bv)=0;
virtual void setOwner(int objid, ui8 owner)=0;
virtual void setHoverName(int objid, MetaString * name)=0;
virtual void setObjProperty(int objid, int prop, si64 val)=0;
virtual void changePrimSkill(int ID, int which, si64 val, bool abs=false)=0;
virtual void changeSecSkill(int ID, int which, int val, bool abs=false)=0;
virtual void showBlockingDialog(BlockingDialog *iw, const CFunctionList<void(ui32)> &callback)=0;
@ -306,7 +308,8 @@ public:
virtual ~IGameCallback(){};
//do sth
const CGObjectInstance *putNewObject(int ID, int subID, int3 pos);
const CGCreature *putNewMonster(int creID, int count, int3 pos);
friend struct CPack;
friend struct CPackForClient;

View File

@ -677,14 +677,18 @@ struct OpenWindow : public CPackForClient //517
struct NewObject : public CPackForClient //518
{
NewObject(){type = 518;};
NewObject()
{
type = 518;
id = -1;
}
void applyCl(CClient *cl);
DLL_EXPORT void applyGs(CGameState *gs);
ui32 ID, subID;
int3 pos;
int id; //used internally
int id; //used locally, filled during applyGs
template <typename Handler> void serialize(Handler &h, const int version)
{
@ -1022,7 +1026,8 @@ struct InfoWindow : public CPackForClient //103 - displays simple info window
namespace ObjProperty
{
//TODO: move non general properties out to the appropriate objs classes
enum {OWNER = 1, BLOCKVIS = 2, PRIMARY_STACK_COUNT = 3, VISITORS = 4, VISITED = 5, ID = 6, AVAILABLE_CREATURE = 7, SUBID = 8};
enum {OWNER = 1, BLOCKVIS = 2, PRIMARY_STACK_COUNT = 3, VISITORS = 4, VISITED = 5, ID = 6, AVAILABLE_CREATURE = 7, SUBID = 8,
MONSTER_COUNT = 10, MONSTER_POWER = 11, MONSTER_EXP = 12};
}
struct SetObjectProperty : public CPackForClient//1001

View File

@ -476,6 +476,8 @@ DLL_EXPORT void NewObject::applyGs( CGameState *gs )
cre->notGrowingTeam = cre->neverFlees = 0;
cre->character = 2;
cre->gainedArtifact = -1;
cre->identifier = -1;
cre->addToSlot(0, new CStackInstance(-1, -1)); //add placeholder stack
}
break;
default:

View File

@ -811,7 +811,6 @@ void CGameHandler::newTurn()
if (getDate(1) == 7 && getDate(0)>1) //new week (day numbers are confusing, as day was not yet switched)
{
int monsterid;
int monthType = rand()%100;
if(getDate(4) == 28) //new month
{
@ -843,7 +842,7 @@ void CGameHandler::newTurn()
{
n.specialWeek = NewTurn::BONUS_GROWTH; //+5
std::pair<int,int> newMonster (54, VLC->creh->pickRandomMonster(boost::ref(rand)));
monsterid = newMonster.second;
n.creatureid = newMonster.second;
}
else
n.specialWeek = NewTurn::NORMAL;
@ -1006,11 +1005,7 @@ void CGameHandler::newTurn()
for (int i = 0; i < amount; ++i)
{
tile = tiles.begin();
NewObject no;
no.ID = 54; //creature
no.subID= n.creatureid;
no.pos = *tile;
sendAndApply(&no);
putNewMonster(n.creatureid, VLC->creh->creatures[n.creatureid]->getRandomAmount(std::rand), *tile);
tiles.erase(tile); //not use it again
}
}
@ -1704,15 +1699,6 @@ void CGameHandler::changeSpells( int hid, bool give, const std::set<ui32> &spell
sendAndApply(&cs);
}
void CGameHandler::setObjProperty( int objid, int prop, si64 val )
{
SetObjectProperty sob;
sob.id = objid;
sob.what = prop;
sob.val = val;
sendAndApply(&sob);
}
void CGameHandler::sendMessageTo( CConnection &c, const std::string &message )
{
SystemMessage sm;

View File

@ -133,7 +133,6 @@ public:
void setBlockVis(int objid, bool bv) OVERRIDE;
void setOwner(int objid, ui8 owner) OVERRIDE;
void setHoverName(int objid, MetaString * name) OVERRIDE;
void setObjProperty(int objid, int prop, si64 val) OVERRIDE;
void changePrimSkill(int ID, int which, si64 val, bool abs=false) OVERRIDE;
void changeSecSkill(int ID, int which, int val, bool abs=false) OVERRIDE;
//void showInfoDialog(InfoWindow *iw) OVERRIDE;

View File

@ -13,7 +13,14 @@
#define ERROR_AND_RETURN do {if(c) *c << &SystemMessage("You are not allowed to perform this action!"); \
tlog1<<"Player is not allowed to perform this action!\n"; \
return false;} while(0)
#define ERROR_IF_NOT_OWNS(id) if(!PLAYER_OWNS(id)) ERROR_AND_RETURN
#define WRONG_PLAYER_MSG(expectedplayer) do {std::ostringstream oss;\
oss << "You were identified as player " << (int)gh->getPlayerAt(c) << " while expecting " << (int)expectedplayer;\
tlog1 << oss.str() << std::endl; \
if(c) *c << &SystemMessage(oss.str());} while(0)
#define ERROR_IF_NOT_OWNS(id) do{if(!PLAYER_OWNS(id)){WRONG_PLAYER_MSG(gh->getOwner(id)); ERROR_AND_RETURN; }}while(0)
#define ERROR_IF_NOT(player) do{if(player != gh->getPlayerAt(c)){WRONG_PLAYER_MSG(player); ERROR_AND_RETURN; }}while(0)
#define COMPLAIN_AND_RETURN(txt) { gh->complain(txt); ERROR_AND_RETURN; }
/*
@ -54,8 +61,7 @@ bool CloseServer::applyGh( CGameHandler *gh )
bool EndTurn::applyGh( CGameHandler *gh )
{
if(gh->getPlayerAt(c) != GS(gh)->currentPlayer)
ERROR_AND_RETURN;
ERROR_IF_NOT(GS(gh)->currentPlayer);
gh->states.setFlag(GS(gh)->currentPlayer,&PlayerStatus::makingTurn,false);
return true;
}
@ -153,8 +159,7 @@ bool TradeOnMarketplace::applyGh( CGameHandler *gh )
if(hero && (player != hero->tempOwner || hero->visitablePos() != market->visitablePos()))
COMPLAIN_AND_RETURN("This hero can't use this marketplace!");
if(gh->getPlayerAt(c) != player)
ERROR_AND_RETURN;
ERROR_IF_NOT(player);
switch(mode)
{
@ -255,6 +260,7 @@ bool CastAdvSpell::applyGh( CGameHandler *gh )
bool PlayerMessage::applyGh( CGameHandler *gh )
{
ERROR_IF_NOT(player);
if(gh->getPlayerAt(c) != player) ERROR_AND_RETURN;
gh->playerMessage(player,text);
return true;
@ -262,8 +268,12 @@ bool PlayerMessage::applyGh( CGameHandler *gh )
bool SetSelection::applyGh( CGameHandler *gh )
{
if(gh->getPlayerAt(c) != player) ERROR_AND_RETURN;
if(!gh->getObj(id)) ERROR_AND_RETURN;
ERROR_IF_NOT(player);
if(!gh->getObj(id))
{
tlog1 << "No such object...\n";
ERROR_AND_RETURN;
}
gh->sendAndApply(this);
return true;
}