mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-26 03:52:01 +02:00
Fixed #730:
* 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:
parent
4af4f0a707
commit
3ca95ef5ed
@ -106,7 +106,6 @@ public:
|
|||||||
void setBlockVis(int objid, bool bv) OVERRIDE {};
|
void setBlockVis(int objid, bool bv) OVERRIDE {};
|
||||||
void setOwner(int objid, ui8 owner) OVERRIDE {};
|
void setOwner(int objid, ui8 owner) OVERRIDE {};
|
||||||
void setHoverName(int objid, MetaString * name) 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 changePrimSkill(int ID, int which, si64 val, bool abs=false) OVERRIDE {};
|
||||||
void changeSecSkill(int ID, int which, int 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 {};
|
void showBlockingDialog(BlockingDialog *iw, const CFunctionList<void(ui32)> &callback) OVERRIDE {};
|
||||||
|
@ -509,7 +509,10 @@ void CStackInstance::giveStackExp(expType exp)
|
|||||||
|
|
||||||
void CStackInstance::setType(int creID)
|
void CStackInstance::setType(int creID)
|
||||||
{
|
{
|
||||||
|
if(creID >= 0 && creID < VLC->creh->creatures.size())
|
||||||
setType(VLC->creh->creatures[creID]);
|
setType(VLC->creh->creatures[creID]);
|
||||||
|
else
|
||||||
|
setType(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CStackInstance::setType(const CCreature *c)
|
void CStackInstance::setType(const CCreature *c)
|
||||||
|
@ -271,7 +271,17 @@ void MetaString::getLocalString(const std::pair<ui8,ui32> &txt, std::string &dst
|
|||||||
case COLOR:
|
case COLOR:
|
||||||
vec = &VLC->generaltexth->capColors;
|
vec = &VLC->generaltexth->capColors;
|
||||||
break;
|
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];
|
dst = (*vec)[ser];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3008,23 +3008,23 @@ void CGCreature::newTurn() const
|
|||||||
if (stacks.begin()->second->count < CREEP_SIZE && cb->getDate(1) == 1 && cb->getDate(0) > 1)
|
if (stacks.begin()->second->count < CREEP_SIZE && cb->getDate(1) == 1 && cb->getDate(0) > 1)
|
||||||
{
|
{
|
||||||
ui32 power = temppower * (100 + WEEKLY_GROWTH)/100;
|
ui32 power = temppower * (100 + WEEKLY_GROWTH)/100;
|
||||||
cb->setObjProperty(id, 10, std::min (power/1000 , (ui32)CREEP_SIZE)); //set new amount
|
cb->setObjProperty(id, ObjProperty::MONSTER_COUNT, std::min (power/1000 , (ui32)CREEP_SIZE)); //set new amount
|
||||||
cb->setObjProperty(id, 11, power); //increase temppower
|
cb->setObjProperty(id, ObjProperty::MONSTER_POWER, power); //increase temppower
|
||||||
}
|
}
|
||||||
if (STACK_EXP)
|
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)
|
void CGCreature::setPropertyDer(ui8 what, ui32 val)
|
||||||
{
|
{
|
||||||
switch (what)
|
switch (what)
|
||||||
{
|
{
|
||||||
case 10:
|
case ObjProperty::MONSTER_COUNT:
|
||||||
stacks[0]->count = val;
|
stacks[0]->count = val;
|
||||||
break;
|
break;
|
||||||
case 11:
|
case ObjProperty::MONSTER_POWER:
|
||||||
temppower = val;
|
temppower = val;
|
||||||
break;
|
break;
|
||||||
case 12:
|
case ObjProperty::MONSTER_EXP:
|
||||||
giveStackExp(val);
|
giveStackExp(val);
|
||||||
break;
|
break;
|
||||||
case 13:
|
case 13:
|
||||||
|
@ -1184,3 +1184,30 @@ void IGameEventRealizer::showInfoDialog( InfoWindow *iw )
|
|||||||
{
|
{
|
||||||
commitPackage(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);
|
||||||
|
}
|
||||||
|
@ -55,6 +55,8 @@ class CCreatureSet;
|
|||||||
class CCreature;
|
class CCreature;
|
||||||
class CStackBasicDescriptor;
|
class CStackBasicDescriptor;
|
||||||
class TeamState;
|
class TeamState;
|
||||||
|
class CGCreature;
|
||||||
|
|
||||||
|
|
||||||
typedef std::vector<const CStack*> TStacks;
|
typedef std::vector<const CStack*> TStacks;
|
||||||
|
|
||||||
@ -246,6 +248,7 @@ public:
|
|||||||
virtual void commitPackage(CPackForClient *pack) = 0;
|
virtual void commitPackage(CPackForClient *pack) = 0;
|
||||||
|
|
||||||
virtual void showInfoDialog(InfoWindow *iw);
|
virtual void showInfoDialog(InfoWindow *iw);
|
||||||
|
virtual void setObjProperty(int objid, int prop, si64 val);
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_EXPORT IGameEventCallback : public IGameEventRealizer
|
class DLL_EXPORT IGameEventCallback : public IGameEventRealizer
|
||||||
@ -256,7 +259,6 @@ public:
|
|||||||
virtual void setBlockVis(int objid, bool bv)=0;
|
virtual void setBlockVis(int objid, bool bv)=0;
|
||||||
virtual void setOwner(int objid, ui8 owner)=0;
|
virtual void setOwner(int objid, ui8 owner)=0;
|
||||||
virtual void setHoverName(int objid, MetaString * name)=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 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 changeSecSkill(int ID, int which, int val, bool abs=false)=0;
|
||||||
virtual void showBlockingDialog(BlockingDialog *iw, const CFunctionList<void(ui32)> &callback)=0;
|
virtual void showBlockingDialog(BlockingDialog *iw, const CFunctionList<void(ui32)> &callback)=0;
|
||||||
@ -306,7 +308,8 @@ public:
|
|||||||
virtual ~IGameCallback(){};
|
virtual ~IGameCallback(){};
|
||||||
|
|
||||||
//do sth
|
//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 CPack;
|
||||||
friend struct CPackForClient;
|
friend struct CPackForClient;
|
||||||
|
@ -677,14 +677,18 @@ struct OpenWindow : public CPackForClient //517
|
|||||||
|
|
||||||
struct NewObject : public CPackForClient //518
|
struct NewObject : public CPackForClient //518
|
||||||
{
|
{
|
||||||
NewObject(){type = 518;};
|
NewObject()
|
||||||
|
{
|
||||||
|
type = 518;
|
||||||
|
id = -1;
|
||||||
|
}
|
||||||
void applyCl(CClient *cl);
|
void applyCl(CClient *cl);
|
||||||
DLL_EXPORT void applyGs(CGameState *gs);
|
DLL_EXPORT void applyGs(CGameState *gs);
|
||||||
|
|
||||||
ui32 ID, subID;
|
ui32 ID, subID;
|
||||||
int3 pos;
|
int3 pos;
|
||||||
|
|
||||||
int id; //used internally
|
int id; //used locally, filled during applyGs
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
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
|
namespace ObjProperty
|
||||||
{
|
{
|
||||||
//TODO: move non general properties out to the appropriate objs classes
|
//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
|
struct SetObjectProperty : public CPackForClient//1001
|
||||||
|
@ -476,6 +476,8 @@ DLL_EXPORT void NewObject::applyGs( CGameState *gs )
|
|||||||
cre->notGrowingTeam = cre->neverFlees = 0;
|
cre->notGrowingTeam = cre->neverFlees = 0;
|
||||||
cre->character = 2;
|
cre->character = 2;
|
||||||
cre->gainedArtifact = -1;
|
cre->gainedArtifact = -1;
|
||||||
|
cre->identifier = -1;
|
||||||
|
cre->addToSlot(0, new CStackInstance(-1, -1)); //add placeholder stack
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -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)
|
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;
|
int monthType = rand()%100;
|
||||||
if(getDate(4) == 28) //new month
|
if(getDate(4) == 28) //new month
|
||||||
{
|
{
|
||||||
@ -843,7 +842,7 @@ void CGameHandler::newTurn()
|
|||||||
{
|
{
|
||||||
n.specialWeek = NewTurn::BONUS_GROWTH; //+5
|
n.specialWeek = NewTurn::BONUS_GROWTH; //+5
|
||||||
std::pair<int,int> newMonster (54, VLC->creh->pickRandomMonster(boost::ref(rand)));
|
std::pair<int,int> newMonster (54, VLC->creh->pickRandomMonster(boost::ref(rand)));
|
||||||
monsterid = newMonster.second;
|
n.creatureid = newMonster.second;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
n.specialWeek = NewTurn::NORMAL;
|
n.specialWeek = NewTurn::NORMAL;
|
||||||
@ -1006,11 +1005,7 @@ void CGameHandler::newTurn()
|
|||||||
for (int i = 0; i < amount; ++i)
|
for (int i = 0; i < amount; ++i)
|
||||||
{
|
{
|
||||||
tile = tiles.begin();
|
tile = tiles.begin();
|
||||||
NewObject no;
|
putNewMonster(n.creatureid, VLC->creh->creatures[n.creatureid]->getRandomAmount(std::rand), *tile);
|
||||||
no.ID = 54; //creature
|
|
||||||
no.subID= n.creatureid;
|
|
||||||
no.pos = *tile;
|
|
||||||
sendAndApply(&no);
|
|
||||||
tiles.erase(tile); //not use it again
|
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);
|
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 )
|
void CGameHandler::sendMessageTo( CConnection &c, const std::string &message )
|
||||||
{
|
{
|
||||||
SystemMessage sm;
|
SystemMessage sm;
|
||||||
|
@ -133,7 +133,6 @@ public:
|
|||||||
void setBlockVis(int objid, bool bv) OVERRIDE;
|
void setBlockVis(int objid, bool bv) OVERRIDE;
|
||||||
void setOwner(int objid, ui8 owner) OVERRIDE;
|
void setOwner(int objid, ui8 owner) OVERRIDE;
|
||||||
void setHoverName(int objid, MetaString * name) 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 changePrimSkill(int ID, int which, si64 val, bool abs=false) OVERRIDE;
|
||||||
void changeSecSkill(int ID, int which, int val, bool abs=false) OVERRIDE;
|
void changeSecSkill(int ID, int which, int val, bool abs=false) OVERRIDE;
|
||||||
//void showInfoDialog(InfoWindow *iw) OVERRIDE;
|
//void showInfoDialog(InfoWindow *iw) OVERRIDE;
|
||||||
|
@ -13,7 +13,14 @@
|
|||||||
#define ERROR_AND_RETURN do {if(c) *c << &SystemMessage("You are not allowed to perform this action!"); \
|
#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"; \
|
tlog1<<"Player is not allowed to perform this action!\n"; \
|
||||||
return false;} while(0)
|
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; }
|
#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 )
|
bool EndTurn::applyGh( CGameHandler *gh )
|
||||||
{
|
{
|
||||||
if(gh->getPlayerAt(c) != GS(gh)->currentPlayer)
|
ERROR_IF_NOT(GS(gh)->currentPlayer);
|
||||||
ERROR_AND_RETURN;
|
|
||||||
gh->states.setFlag(GS(gh)->currentPlayer,&PlayerStatus::makingTurn,false);
|
gh->states.setFlag(GS(gh)->currentPlayer,&PlayerStatus::makingTurn,false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -153,8 +159,7 @@ bool TradeOnMarketplace::applyGh( CGameHandler *gh )
|
|||||||
if(hero && (player != hero->tempOwner || hero->visitablePos() != market->visitablePos()))
|
if(hero && (player != hero->tempOwner || hero->visitablePos() != market->visitablePos()))
|
||||||
COMPLAIN_AND_RETURN("This hero can't use this marketplace!");
|
COMPLAIN_AND_RETURN("This hero can't use this marketplace!");
|
||||||
|
|
||||||
if(gh->getPlayerAt(c) != player)
|
ERROR_IF_NOT(player);
|
||||||
ERROR_AND_RETURN;
|
|
||||||
|
|
||||||
switch(mode)
|
switch(mode)
|
||||||
{
|
{
|
||||||
@ -255,6 +260,7 @@ bool CastAdvSpell::applyGh( CGameHandler *gh )
|
|||||||
|
|
||||||
bool PlayerMessage::applyGh( CGameHandler *gh )
|
bool PlayerMessage::applyGh( CGameHandler *gh )
|
||||||
{
|
{
|
||||||
|
ERROR_IF_NOT(player);
|
||||||
if(gh->getPlayerAt(c) != player) ERROR_AND_RETURN;
|
if(gh->getPlayerAt(c) != player) ERROR_AND_RETURN;
|
||||||
gh->playerMessage(player,text);
|
gh->playerMessage(player,text);
|
||||||
return true;
|
return true;
|
||||||
@ -262,8 +268,12 @@ bool PlayerMessage::applyGh( CGameHandler *gh )
|
|||||||
|
|
||||||
bool SetSelection::applyGh( CGameHandler *gh )
|
bool SetSelection::applyGh( CGameHandler *gh )
|
||||||
{
|
{
|
||||||
if(gh->getPlayerAt(c) != player) ERROR_AND_RETURN;
|
ERROR_IF_NOT(player);
|
||||||
if(!gh->getObj(id)) ERROR_AND_RETURN;
|
if(!gh->getObj(id))
|
||||||
|
{
|
||||||
|
tlog1 << "No such object...\n";
|
||||||
|
ERROR_AND_RETURN;
|
||||||
|
}
|
||||||
gh->sendAndApply(this);
|
gh->sendAndApply(this);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user