mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-12 02:28:11 +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 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 {};
|
||||
|
@ -509,7 +509,10 @@ void CStackInstance::giveStackExp(expType exp)
|
||||
|
||||
void CStackInstance::setType(int creID)
|
||||
{
|
||||
setType(VLC->creh->creatures[creID]);
|
||||
if(creID >= 0 && creID < VLC->creh->creatures.size())
|
||||
setType(VLC->creh->creatures[creID]);
|
||||
else
|
||||
setType(NULL);
|
||||
}
|
||||
|
||||
void CStackInstance::setType(const CCreature *c)
|
||||
|
@ -271,8 +271,18 @@ 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;
|
||||
}
|
||||
dst = (*vec)[ser];
|
||||
if(vec->size() <= ser)
|
||||
{
|
||||
tlog1 << "Failed string substitution with type " << type << " because index " << ser << " is out of bounds!\n";
|
||||
dst = "#!#";
|
||||
}
|
||||
else
|
||||
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)
|
||||
{
|
||||
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:
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user