mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-12 02:28:11 +02:00
* server sends confirmation (given later to player interface) after applying request (will be needed for AI)
* created new package for injuring multiple units - needed for area spells (not tested) * proper screen updating on garrison change * spell effects will be removed when they time out * Corpse (Skeleton) will be accessible from all directions * new objects supported: - Corpse - Lean To - Wagon - Warrior's Tomb * several minor improvements
This commit is contained in:
parent
f9ae91d88c
commit
d80afb1902
@ -35,6 +35,7 @@ struct BattleStackAttacked;
|
||||
struct SpellCasted;
|
||||
struct SetStackEffect;
|
||||
struct HeroBonus;
|
||||
struct PackageApplied;
|
||||
class CLoadFile;
|
||||
class CSaveFile;
|
||||
template <typename Serializer> class CISer;
|
||||
@ -88,6 +89,7 @@ public:
|
||||
virtual void yourTurn(){};
|
||||
virtual void availableCreaturesChanged(const CGTownInstance *town){};
|
||||
virtual void heroBonusChanged(const CGHeroInstance *hero, const HeroBonus &bonus, bool gain){};//if gain hero received bonus, else he lost it
|
||||
virtual void requestRealized(PackageApplied *pa){}
|
||||
virtual void serialize(COSer<CSaveFile> &h, const int version){}; //saving
|
||||
virtual void serialize(CISer<CLoadFile> &h, const int version){}; //loading
|
||||
|
||||
|
@ -2112,8 +2112,8 @@ void CPlayerInterface::garrisonChanged(const CGObjectInstance * obj)
|
||||
wasGarrison = true;
|
||||
}
|
||||
}
|
||||
if(wasGarrison)
|
||||
LOCPLINT->totalRedraw();
|
||||
|
||||
LOCPLINT->totalRedraw();
|
||||
}
|
||||
|
||||
void CPlayerInterface::buildChanged(const CGTownInstance *town, int buildingID, int what) //what: 1 - built, 2 - demolished
|
||||
@ -4761,14 +4761,14 @@ void CGarrisonWindow::deactivate()
|
||||
|
||||
void CGarrisonWindow::show(SDL_Surface * to)
|
||||
{
|
||||
blitAt(graphics->flags->ourImages[garr->odown->getOwner()].bitmap,pos.x+29,pos.y+125,to);
|
||||
blitAt(graphics->portraitLarge[static_cast<const CGHeroInstance*>(garr->odown)->portrait],pos.x+29,pos.y+222,to);
|
||||
printAtMiddle(CGI->generaltexth->allTexts[709],pos.x+275,pos.y+30,GEOR16,tytulowy,to);
|
||||
|
||||
blitAt(bg,pos,to);
|
||||
split->show(to);
|
||||
quit->show(to);
|
||||
garr->show(to);
|
||||
|
||||
blitAt(graphics->flags->ourImages[garr->odown->getOwner()].bitmap,pos.x+29,pos.y+125,to);
|
||||
blitAt(graphics->portraitLarge[static_cast<const CGHeroInstance*>(garr->odown)->portrait],pos.x+29,pos.y+222,to);
|
||||
printAtMiddle(CGI->generaltexth->allTexts[709],pos.x+275,pos.y+30,GEOR16,tytulowy,to);
|
||||
}
|
||||
|
||||
CGarrisonWindow::CGarrisonWindow( const CArmedInstance *up, const CGHeroInstance *down )
|
||||
|
@ -124,10 +124,16 @@ void CClient::run()
|
||||
CPack *pack;
|
||||
while(1)
|
||||
{
|
||||
tlog5 << "Listening... ";
|
||||
*serv >> pack;
|
||||
tlog5 << "\treceived server message of type " << typeid(*pack).name() << std::endl;
|
||||
CBaseForCLApply *apply = applier->apps[typeList.getTypeID(pack)];
|
||||
|
||||
//get the package from the server
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(*serv->rmx);
|
||||
tlog5 << "Listening... ";
|
||||
*serv >> pack;
|
||||
tlog5 << "\treceived server message of type " << typeid(*pack).name() << std::endl;
|
||||
}
|
||||
|
||||
CBaseForCLApply *apply = applier->apps[typeList.getTypeID(pack)]; //find the applier
|
||||
if(apply)
|
||||
{
|
||||
apply->applyOnClBefore(this,pack);
|
||||
@ -139,7 +145,7 @@ void CClient::run()
|
||||
}
|
||||
else
|
||||
{
|
||||
tlog5 << "Message cannot be applied, cannot find applier!\n";
|
||||
tlog1 << "Message cannot be applied, cannot find applier!\n";
|
||||
}
|
||||
delete pack;
|
||||
pack = NULL;
|
||||
|
@ -79,7 +79,7 @@ public:
|
||||
|
||||
//not working yet, will be implement somewhen later with support for local-sim-based gameplay
|
||||
void changeSpells(int hid, bool give, const std::set<ui32> &spells){};
|
||||
void removeObject(int objid){};
|
||||
bool removeObject(int objid){return false;};
|
||||
void setBlockVis(int objid, bool bv){};
|
||||
void setOwner(int objid, ui8 owner){};
|
||||
void setHoverName(int objid, MetaString * name){};
|
||||
@ -98,7 +98,7 @@ public:
|
||||
void startBattleI(const CCreatureSet * army1, const CCreatureSet * army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, boost::function<void(BattleResult*)> cb){}; //use hero=NULL for no hero
|
||||
void startBattleI(int heroID, CCreatureSet army, int3 tile, boost::function<void(BattleResult*)> cb){}; //for hero<=>neutral army
|
||||
void setAmount(int objid, ui32 val){};
|
||||
void moveHero(si32 hid, int3 dst, ui8 instant, ui8 asker = 255){};
|
||||
bool moveHero(si32 hid, int3 dst, ui8 instant, ui8 asker = 255){return false;};
|
||||
void giveHeroBonus(GiveBonus * bonus){};
|
||||
void setMovePoints(SetMovePoints * smp){};
|
||||
void setManaPoints(int hid, int val){};
|
||||
|
@ -404,6 +404,12 @@ void SetStackEffect::applyCl( CClient *cl )
|
||||
cl->playerint[GS(cl)->curB->side2]->battleStacksEffectsSet(*this);
|
||||
}
|
||||
|
||||
void StacksInjured::applyCl( CClient *cl )
|
||||
{
|
||||
INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->side1,battleStacksAttacked,stacks);
|
||||
INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->side2,battleStacksAttacked,stacks);
|
||||
}
|
||||
|
||||
CGameState* CPackForClient::GS( CClient *cl )
|
||||
{
|
||||
return cl->gs;
|
||||
@ -418,6 +424,11 @@ void EndAction::applyCl( CClient *cl )
|
||||
cl->curbaction = NULL;
|
||||
}
|
||||
|
||||
void PackageApplied::applyCl( CClient *cl )
|
||||
{
|
||||
INTERFACE_CALL_IF_PRESENT(GS(cl)->currentPlayer,requestRealized,this);
|
||||
}
|
||||
|
||||
void SystemMessage::applyCl( CClient *cl )
|
||||
{
|
||||
std::ostringstream str;
|
||||
|
1
global.h
1
global.h
@ -54,6 +54,7 @@ enum ElossCon {lossCastle, lossHero, timeExpires, lossStandard=255};
|
||||
enum EHeroClasses {HERO_KNIGHT, HERO_CLERIC, HERO_RANGER, HERO_DRUID, HERO_ALCHEMIST, HERO_WIZARD,
|
||||
HERO_DEMONIAC, HERO_HERETIC, HERO_DEATHKNIGHT, HERO_NECROMANCER, HERO_WARLOCK, HERO_OVERLORD,
|
||||
HERO_BARBARIAN, HERO_BATTLEMAGE, HERO_BEASTMASTER, HERO_WITCH, HERO_PLANESWALKER, HERO_ELEMENTALIST};
|
||||
enum EartClass {ART_SPECIAL=1, ART_TREASURE=2, ART_MINOR=4, ART_MAJOR=8, ART_RELIC=16}; //artifact classes
|
||||
enum EAbilities {DOUBLE_WIDE, FLYING, SHOOTER, TWO_HEX_ATTACK, SIEGE_ABILITY, SIEGE_WEAPON,
|
||||
KING1, KING2, KING3, MIND_IMMUNITY, NO_OBSTACLE_PENALTY, NO_CLOSE_COMBAT_PENALTY,
|
||||
JOUSTING, FIRE_IMMUNITY, TWICE_ATTACK, NO_ENEMY_RETALIATION, NO_MORAL_PENALTY,
|
||||
|
@ -43,7 +43,7 @@ void CArtHandler::loadArtifacts(bool onlyTxt)
|
||||
std::vector<ui16> slots;
|
||||
slots += 17, 16, 15,14,13, 18, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0;
|
||||
std::map<char,EartClass> classes =
|
||||
map_list_of('S',SartClass)('T',TartClass)('N',NartClass)('J',JartClass)('R',RartClass);
|
||||
map_list_of('S',ART_SPECIAL)('T',ART_TREASURE)('N',ART_MINOR)('J',ART_MAJOR)('R',ART_RELIC);
|
||||
std::string buf = bitmaph->getTextFile("ARTRAITS.TXT"), dump, pom;
|
||||
int it=0;
|
||||
for(int i=0; i<2; ++i)
|
||||
@ -112,16 +112,16 @@ void CArtHandler::sortArts()
|
||||
{
|
||||
switch (artifacts[i].aClass)
|
||||
{
|
||||
case TartClass:
|
||||
case ART_TREASURE:
|
||||
treasures.push_back(&(artifacts[i]));
|
||||
break;
|
||||
case NartClass:
|
||||
case ART_MINOR:
|
||||
minors.push_back(&(artifacts[i]));
|
||||
break;
|
||||
case JartClass:
|
||||
case ART_MAJOR:
|
||||
majors.push_back(&(artifacts[i]));
|
||||
break;
|
||||
case RartClass:
|
||||
case ART_RELIC:
|
||||
relics.push_back(&(artifacts[i]));
|
||||
break;
|
||||
}
|
||||
|
@ -6,17 +6,15 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/*
|
||||
* CArtHandler.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
/*
|
||||
* CArtHandler.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
|
||||
enum EartClass {SartClass=0, TartClass, NartClass, JartClass, RartClass}; //artifact class (relict, treasure, strong, weak etc.)
|
||||
class CDefHandler;
|
||||
|
||||
class DLL_EXPORT CArtifact //container for artifacts
|
||||
|
@ -89,7 +89,7 @@ void CDefObjInfoHandler::load()
|
||||
}
|
||||
else
|
||||
{
|
||||
static int visitableFromTop[] = {111,33,81,12,9,212,215}; //whirlpool, garrison, scholar, campfire, borderguard, bordergate, questguard
|
||||
static int visitableFromTop[] = {111,33,81,12,9,212,215,22}; //whirlpool, garrison, scholar, campfire, borderguard, bordergate, questguard, corpse
|
||||
for(int i=0; i < ARRAY_COUNT(visitableFromTop); i++)
|
||||
{
|
||||
if(visitableFromTop[i] == nobj->id)
|
||||
|
@ -778,7 +778,8 @@ double CGHeroInstance::getHeroStrength() const
|
||||
|
||||
int CGHeroInstance::getTotalStrength() const
|
||||
{
|
||||
return getHeroStrength() * getArmyStrength();
|
||||
double ret = getHeroStrength() * getArmyStrength();
|
||||
return (int) ret;
|
||||
}
|
||||
|
||||
ui8 CGHeroInstance::getSpellSchoolLevel(const CSpell * spell) const
|
||||
@ -1444,14 +1445,14 @@ int CGCreature::takenAction(const CGHeroInstance *h, bool allowJoin) const
|
||||
|
||||
//TODO: it's provisional formula, should be replaced with original one (or something closer to it)
|
||||
//TODO: should be deterministic (will be needed for Vision spell)
|
||||
int hlp2 = (hlp - 2)*1000;
|
||||
int hlp2 = (int) (hlp - 2)*1000;
|
||||
if(!neverFlees
|
||||
&& hlp2 >= 0
|
||||
&& rand()%2000 < hlp2
|
||||
)
|
||||
return -1;
|
||||
return -1; //flee
|
||||
else
|
||||
return -2;
|
||||
return -2; //fight
|
||||
|
||||
}
|
||||
|
||||
@ -2425,3 +2426,202 @@ void CGScholar::initObj()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGOnceVisitable::onHeroVisit( const CGHeroInstance * h ) const
|
||||
{
|
||||
int txtid = -1;
|
||||
switch(ID)
|
||||
{
|
||||
case 22: //Corpse
|
||||
txtid = 37;
|
||||
break;
|
||||
case 39: //Lean To
|
||||
txtid = 64;
|
||||
break;
|
||||
case 105://Wagon
|
||||
txtid = 154;
|
||||
break;
|
||||
case 108:
|
||||
break;
|
||||
default:
|
||||
tlog1 << "Error: Unknown object (" << ID <<") treated as CGOnceVisitable!\n";
|
||||
return;
|
||||
}
|
||||
|
||||
if(ID == 108)//Warrior's Tomb
|
||||
{
|
||||
//ask if player wants to search the Tomb
|
||||
BlockingDialog bd(true, false);
|
||||
bd.player = h->getOwner();
|
||||
bd.text.addTxt(MetaString::ADVOB_TXT,161);
|
||||
cb->showBlockingDialog(&bd,boost::bind(&CGOnceVisitable::searchTomb,this,h,_1));
|
||||
return;
|
||||
}
|
||||
|
||||
InfoWindow iw;
|
||||
iw.player = h->getOwner();
|
||||
|
||||
if(players.size()) //we have been already visited...
|
||||
{
|
||||
txtid++;
|
||||
if(ID == 105) //wagon has extra text (for finding art) we need to ommit
|
||||
txtid++;
|
||||
|
||||
iw.text.addTxt(MetaString::ADVOB_TXT, txtid);
|
||||
}
|
||||
else //first visit - give bonus!
|
||||
{
|
||||
if(ID == 105 && artOrRes == 1)
|
||||
{
|
||||
txtid++;
|
||||
iw.text.replacements.push_back(VLC->arth->artifacts[bonusType].Name());
|
||||
}
|
||||
|
||||
|
||||
switch(artOrRes)
|
||||
{
|
||||
case 0:
|
||||
txtid++;
|
||||
break;
|
||||
case 1: //art
|
||||
iw.components.push_back(Component(Component::ARTIFACT,bonusType,0,0));
|
||||
cb->giveHeroArtifact(bonusType,h->id,-2);
|
||||
break;
|
||||
case 2: //res
|
||||
iw.components.push_back(Component(Component::RESOURCE,bonusType,bonusVal,0));
|
||||
cb->giveResource(h->getOwner(),bonusType,bonusVal);
|
||||
break;
|
||||
}
|
||||
|
||||
iw.text.addTxt(MetaString::ADVOB_TXT, txtid);
|
||||
}
|
||||
|
||||
cb->showInfoDialog(&iw);
|
||||
cb->setObjProperty(id,10,h->getOwner());
|
||||
}
|
||||
|
||||
const std::string & CGOnceVisitable::getHoverText() const
|
||||
{
|
||||
hoverName = VLC->generaltexth->names[ID] + " ";
|
||||
|
||||
hoverName += (hasVisited(cb->getCurrentPlayer())
|
||||
? (VLC->generaltexth->allTexts[352]) //visited
|
||||
: ( VLC->generaltexth->allTexts[353])); //not visited
|
||||
|
||||
return hoverName;
|
||||
}
|
||||
|
||||
void CGOnceVisitable::initObj()
|
||||
{
|
||||
switch(ID)
|
||||
{
|
||||
case 22: //Corpse
|
||||
{
|
||||
blockVisit = true;
|
||||
int hlp = ran()%100;
|
||||
if(hlp < 20)
|
||||
{
|
||||
artOrRes = 1;
|
||||
std::vector<CArtifact*> arts;
|
||||
cb->getAllowed(arts, ART_TREASURE | ART_MINOR | ART_MAJOR);
|
||||
bonusType = arts[ran() % arts.size()]->id;
|
||||
}
|
||||
else
|
||||
{
|
||||
artOrRes = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 39: //Lean To
|
||||
{
|
||||
artOrRes = 2;
|
||||
bonusType = ran()%6; //any basic resource without gold
|
||||
bonusVal = ran()%4 + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
case 108://Warrior's Tomb
|
||||
{
|
||||
artOrRes = 1;
|
||||
|
||||
std::vector<CArtifact*> arts;
|
||||
|
||||
int hlp = ran()%100;
|
||||
if(hlp < 30)
|
||||
cb->getAllowed(arts,ART_TREASURE);
|
||||
else if(hlp < 80)
|
||||
cb->getAllowed(arts,ART_MINOR);
|
||||
else if(hlp < 95)
|
||||
cb->getAllowed(arts,ART_MAJOR);
|
||||
else
|
||||
cb->getAllowed(arts,ART_RELIC);
|
||||
|
||||
bonusType = arts[ran() % arts.size()]->id;
|
||||
}
|
||||
break;
|
||||
|
||||
case 105://Wagon
|
||||
{
|
||||
int hlp = ran()%100;
|
||||
|
||||
if(hlp < 10)
|
||||
{
|
||||
artOrRes = 0; // nothing... :(
|
||||
}
|
||||
else if(hlp < 50) //minor or treasure art
|
||||
{
|
||||
artOrRes = 1;
|
||||
std::vector<CArtifact*> arts;
|
||||
cb->getAllowed(arts, ART_TREASURE | ART_MINOR);
|
||||
bonusType = arts[ran() % arts.size()]->id;
|
||||
}
|
||||
else //2 - 5 of non-gold resource
|
||||
{
|
||||
artOrRes = 2;
|
||||
bonusType = ran()%6;
|
||||
bonusVal = ran()%4 + 2;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGOnceVisitable::searchTomb(const CGHeroInstance *h, ui32 accept) const
|
||||
{
|
||||
if(accept)
|
||||
{
|
||||
InfoWindow iw;
|
||||
iw.player = h->getOwner();
|
||||
iw.components.push_back(Component(Component::MORALE,0,-3,0));
|
||||
|
||||
if(players.size()) //we've been already visited, player found nothing
|
||||
{
|
||||
iw.text.addTxt(MetaString::ADVOB_TXT,163);
|
||||
}
|
||||
else //first visit - give artifact
|
||||
{
|
||||
iw.text.addTxt(MetaString::ADVOB_TXT,162);
|
||||
iw.components.push_back(Component(Component::ARTIFACT,bonusType,0,0));
|
||||
iw.text.replacements.push_back(VLC->arth->artifacts[bonusType].Name());
|
||||
|
||||
cb->giveHeroArtifact(bonusType,h->id,-2);
|
||||
}
|
||||
|
||||
if(!h->getBonus(HeroBonus::OBJECT,ID)) //we don't have modifier from this object yet
|
||||
{
|
||||
//ruin morale
|
||||
GiveBonus gb;
|
||||
gb.hid = h->id;
|
||||
gb.bonus = HeroBonus(HeroBonus::ONE_BATTLE,HeroBonus::MORALE,HeroBonus::OBJECT,-3,id,"");
|
||||
gb.bdescr.addTxt(MetaString::ARRAY_TXT,104); //Warrior Tomb Visited -3
|
||||
cb->giveHeroBonus(&gb);
|
||||
}
|
||||
|
||||
cb->showInfoDialog(&iw);
|
||||
|
||||
//add player to the visitors (for visited tooltop)
|
||||
cb->setObjProperty(id,10,h->getOwner());
|
||||
}
|
||||
}
|
@ -705,6 +705,25 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_EXPORT CGOnceVisitable : public CPlayersVisited //wagon, corpse, lean to, warriors tomb
|
||||
{
|
||||
public:
|
||||
ui8 artOrRes; //0 - nothing; 1 - artifact; 2 - resource
|
||||
ui32 bonusType, //id of res or artifact
|
||||
bonusVal; //resource amount (or not used)
|
||||
|
||||
void onHeroVisit(const CGHeroInstance * h) const;
|
||||
const std::string & getHoverText() const;
|
||||
void initObj();
|
||||
void searchTomb(const CGHeroInstance *h, ui32 accept) const;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & static_cast<CGObjectInstance&>(*this) & static_cast<CPlayersVisited&>(*this);;
|
||||
h & bonusType & bonusVal;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
class DLL_EXPORT CObjectHandler
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include "../map.h"
|
||||
#include "../hch/CObjectHandler.h"
|
||||
#include "../StartInfo.h"
|
||||
#include "../hch/CArtHandler.h"
|
||||
#include "../lib/VCMI_Lib.h"
|
||||
|
||||
/*
|
||||
* IGameCallback.cpp, part of VCMI engine
|
||||
@ -112,8 +114,34 @@ bool IGameCallback::isAllowed( int type, int id )
|
||||
{
|
||||
case 0:
|
||||
return gs->map->allowedSpell[id];
|
||||
case 1:
|
||||
return gs->map->allowedArtifact[id];
|
||||
default:
|
||||
tlog1 << "Wrong call to IGameCallback::isAllowed!\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void IGameCallback::getAllowedArts(std::vector<CArtifact*> &out, std::vector<CArtifact*> CArtHandler::*arts)
|
||||
{
|
||||
for(int i = 0; i < (VLC->arth->*arts).size(); i++)
|
||||
{
|
||||
CArtifact *art = (VLC->arth->*arts)[i];
|
||||
if(isAllowed(1,art->id))
|
||||
{
|
||||
out.push_back(art);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IGameCallback::getAllowed(std::vector<CArtifact*> &out, int flags)
|
||||
{
|
||||
if(flags & ART_TREASURE)
|
||||
getAllowedArts(out,&CArtHandler::treasures);
|
||||
if(flags & ART_MINOR)
|
||||
getAllowedArts(out,&CArtHandler::minors);
|
||||
if(flags & ART_MAJOR)
|
||||
getAllowedArts(out,&CArtHandler::majors);
|
||||
if(flags & ART_RELIC)
|
||||
getAllowedArts(out,&CArtHandler::relics);
|
||||
}
|
@ -29,6 +29,8 @@ struct BattleResult;
|
||||
class CGameState;
|
||||
struct PlayerSettings;
|
||||
struct CPackForClient;
|
||||
class CArtHandler;
|
||||
class CArtifact;
|
||||
|
||||
class DLL_EXPORT IGameCallback
|
||||
{
|
||||
@ -49,11 +51,13 @@ public:
|
||||
virtual const PlayerSettings * getPlayerSettings(int color);
|
||||
virtual int getHeroCount(int player, bool includeGarrisoned);
|
||||
virtual void getTilesInRange(std::set<int3> &tiles, int3 pos, int radious, int player=-1, int mode=0); //mode 1 - only unrevealed tiles; mode 0 - all, mode -1 - only unrevealed
|
||||
virtual bool isAllowed(int type, int id); //type: 0 - spell
|
||||
virtual bool isAllowed(int type, int id); //type: 0 - spell; 1- artifact
|
||||
virtual void getAllowedArts(std::vector<CArtifact*> &out, std::vector<CArtifact*> CArtHandler::*arts);
|
||||
virtual void getAllowed(std::vector<CArtifact*> &out, int flags); //flags: bitfield uses EartClass
|
||||
|
||||
//do sth
|
||||
virtual void changeSpells(int hid, bool give, const std::set<ui32> &spells)=0;
|
||||
virtual void removeObject(int objid)=0;
|
||||
virtual bool removeObject(int objid)=0;
|
||||
virtual void setBlockVis(int objid, bool bv)=0;
|
||||
virtual void setOwner(int objid, ui8 owner)=0;
|
||||
virtual void setHoverName(int objid, MetaString * name)=0;
|
||||
@ -72,7 +76,7 @@ public:
|
||||
virtual void startBattleI(const CCreatureSet * army1, const CCreatureSet * army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, boost::function<void(BattleResult*)> cb)=0; //use hero=NULL for no hero
|
||||
virtual void startBattleI(int heroID, CCreatureSet army, int3 tile, boost::function<void(BattleResult*)> cb)=0; //for hero<=>neutral army
|
||||
virtual void setAmount(int objid, ui32 val)=0;
|
||||
virtual void moveHero(si32 hid, int3 dst, ui8 instant, ui8 asker = 255)=0;
|
||||
virtual bool moveHero(si32 hid, int3 dst, ui8 instant, ui8 asker = 255)=0;
|
||||
virtual void giveHeroBonus(GiveBonus * bonus)=0;
|
||||
virtual void setMovePoints(SetMovePoints * smp)=0;
|
||||
virtual void setManaPoints(int hid, int val)=0;
|
||||
|
@ -57,7 +57,7 @@ struct CPackForServer : public CPack
|
||||
c = NULL;
|
||||
};
|
||||
|
||||
void applyGh(CGameHandler *gh)//called after applying to gs
|
||||
bool applyGh(CGameHandler *gh)//called after applying to gs
|
||||
{};
|
||||
};
|
||||
|
||||
@ -108,6 +108,21 @@ struct MetaString : public CPack //2001 helper for object scrips
|
||||
|
||||
/***********************************************************************************************************/
|
||||
|
||||
struct PackageApplied : public CPackForClient //94
|
||||
{
|
||||
PackageApplied() {type = 94;}
|
||||
PackageApplied(ui8 Result) : result(Result) {type = 94;}
|
||||
void applyCl(CClient *cl);
|
||||
|
||||
ui8 result; //0 - something went wrong, request hasn't been realized; 1 - OK
|
||||
ui32 packType; //type id of applied package
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & result;
|
||||
}
|
||||
};
|
||||
|
||||
struct SystemMessage : public CPackForClient //95
|
||||
{
|
||||
SystemMessage(const std::string Text) : text(Text){type = 95;};
|
||||
@ -490,7 +505,7 @@ struct NewTurn : public CPackForClient //101
|
||||
|
||||
struct Component : public CPack //2002 helper for object scrips informations
|
||||
{
|
||||
enum {PRIM_SKILL,SEC_SKILL,RESOURCE,CREATURE,ARTIFACT,EXPERIENCE,SPELL};
|
||||
enum {PRIM_SKILL,SEC_SKILL,RESOURCE,CREATURE,ARTIFACT,EXPERIENCE,SPELL, MORALE=8, LUCK};
|
||||
ui16 id, subtype; //id uses ^^^ enums, when id==EXPPERIENCE subtype==0 means exp points and subtype==1 levels)
|
||||
si32 val; // + give; - take
|
||||
si16 when; // 0 - now; +x - within x days; -x - per x days
|
||||
@ -814,6 +829,19 @@ struct SetStackEffect : public CPackForClient //3010
|
||||
}
|
||||
};
|
||||
|
||||
struct StacksInjured : public CPackForClient //3011
|
||||
{
|
||||
StacksInjured(){type = 3011;}
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
void applyCl(CClient *cl);
|
||||
|
||||
std::set<BattleStackAttacked> stacks;
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & stacks;
|
||||
}
|
||||
};
|
||||
|
||||
struct ShowInInfobox : public CPackForClient //107
|
||||
{
|
||||
ShowInInfobox(){type = 107;};
|
||||
@ -832,14 +860,14 @@ struct ShowInInfobox : public CPackForClient //107
|
||||
|
||||
struct CloseServer : public CPackForServer
|
||||
{
|
||||
void applyGh(CGameHandler *gh);
|
||||
bool applyGh(CGameHandler *gh);
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{}
|
||||
};
|
||||
|
||||
struct EndTurn : public CPackForServer
|
||||
{
|
||||
void applyGh(CGameHandler *gh);
|
||||
bool applyGh(CGameHandler *gh);
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{}
|
||||
};
|
||||
@ -850,7 +878,7 @@ struct DismissHero : public CPackForServer
|
||||
DismissHero(si32 HID) : hid(HID) {};
|
||||
si32 hid;
|
||||
|
||||
void applyGh(CGameHandler *gh);
|
||||
bool applyGh(CGameHandler *gh);
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & hid;
|
||||
@ -864,7 +892,7 @@ struct MoveHero : public CPackForServer
|
||||
int3 dest;
|
||||
si32 hid;
|
||||
|
||||
void applyGh(CGameHandler *gh);
|
||||
bool applyGh(CGameHandler *gh);
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & dest & hid;
|
||||
@ -881,7 +909,7 @@ struct ArrangeStacks : public CPackForServer
|
||||
ui8 p1, p2; //positions of first and second stack
|
||||
si32 id1, id2; //ids of objects with garrison
|
||||
si32 val;
|
||||
void applyGh(CGameHandler *gh);
|
||||
bool applyGh(CGameHandler *gh);
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & what & p1 & p2 & id1 & id2 & val;
|
||||
@ -895,7 +923,7 @@ struct DisbandCreature : public CPackForServer
|
||||
ui8 pos; //stack pos
|
||||
si32 id; //object id
|
||||
|
||||
void applyGh(CGameHandler *gh);
|
||||
bool applyGh(CGameHandler *gh);
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & pos & id;
|
||||
@ -908,7 +936,7 @@ struct BuildStructure : public CPackForServer
|
||||
BuildStructure(si32 TID, si32 BID):bid(BID),tid(TID){};
|
||||
si32 bid, tid; //structure and town ids
|
||||
|
||||
void applyGh(CGameHandler *gh);
|
||||
bool applyGh(CGameHandler *gh);
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & tid & bid;
|
||||
@ -922,7 +950,7 @@ struct RecruitCreatures : public CPackForServer
|
||||
si32 tid; //town id
|
||||
ui32 crid, amount;//creature ID and amount
|
||||
|
||||
void applyGh(CGameHandler *gh);
|
||||
bool applyGh(CGameHandler *gh);
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & tid & crid & amount;
|
||||
@ -937,7 +965,7 @@ struct UpgradeCreature : public CPackForServer
|
||||
si32 id; //object id
|
||||
si32 cid; //id of type to which we want make upgrade
|
||||
|
||||
void applyGh(CGameHandler *gh);
|
||||
bool applyGh(CGameHandler *gh);
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & pos & id & cid;
|
||||
@ -950,7 +978,7 @@ struct GarrisonHeroSwap : public CPackForServer
|
||||
GarrisonHeroSwap(si32 TID):tid(TID){};
|
||||
si32 tid;
|
||||
|
||||
void applyGh(CGameHandler *gh);
|
||||
bool applyGh(CGameHandler *gh);
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & tid;
|
||||
@ -965,7 +993,7 @@ struct ExchangeArtifacts : public CPackForServer
|
||||
si32 hid1, hid2;
|
||||
ui16 slot1, slot2;
|
||||
|
||||
void applyGh(CGameHandler *gh);
|
||||
bool applyGh(CGameHandler *gh);
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & hid1 & hid2 & slot1 & slot2;
|
||||
@ -978,7 +1006,7 @@ struct BuyArtifact : public CPackForServer
|
||||
BuyArtifact(si32 HID, si32 AID):hid(HID),aid(AID){};
|
||||
si32 hid, aid; //hero and artifact id
|
||||
|
||||
void applyGh(CGameHandler *gh);
|
||||
bool applyGh(CGameHandler *gh);
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & hid & aid;
|
||||
@ -996,7 +1024,7 @@ struct TradeOnMarketplace : public CPackForServer
|
||||
ui32 r1, r2; //mode 0: r1 - sold resource, r2 - bought res
|
||||
ui32 val; //units of sold resource
|
||||
|
||||
void applyGh(CGameHandler *gh);
|
||||
bool applyGh(CGameHandler *gh);
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & player & mode & /*id & */r1 & r2 & val;
|
||||
@ -1010,7 +1038,7 @@ struct SetFormation : public CPackForServer
|
||||
si32 hid;
|
||||
ui8 formation;
|
||||
|
||||
void applyGh(CGameHandler *gh);
|
||||
bool applyGh(CGameHandler *gh);
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & hid & formation;
|
||||
@ -1023,7 +1051,7 @@ struct HireHero : public CPackForServer
|
||||
HireHero(si32 HID, si32 TID):hid(HID),tid(TID){};
|
||||
si32 hid, tid; //available hero serial and town id
|
||||
|
||||
void applyGh(CGameHandler *gh);
|
||||
bool applyGh(CGameHandler *gh);
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & hid & tid;
|
||||
@ -1036,7 +1064,7 @@ struct QueryReply : public CPackForServer
|
||||
QueryReply(ui32 QID, ui32 Answer):qid(QID),answer(Answer){};
|
||||
ui32 qid, answer; //hero and artifact id
|
||||
|
||||
void applyGh(CGameHandler *gh);
|
||||
bool applyGh(CGameHandler *gh);
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & qid & answer;
|
||||
@ -1049,7 +1077,7 @@ struct MakeAction : public CPackForServer
|
||||
MakeAction(const BattleAction &BA):ba(BA){};
|
||||
BattleAction ba;
|
||||
|
||||
void applyGh(CGameHandler *gh);
|
||||
bool applyGh(CGameHandler *gh);
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & ba;
|
||||
@ -1062,7 +1090,7 @@ struct MakeCustomAction : public CPackForServer
|
||||
MakeCustomAction(const BattleAction &BA):ba(BA){};
|
||||
BattleAction ba;
|
||||
|
||||
void applyGh(CGameHandler *gh);
|
||||
bool applyGh(CGameHandler *gh);
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & ba;
|
||||
@ -1079,7 +1107,7 @@ struct SaveGame : public CPackForClient, public CPackForServer
|
||||
|
||||
void applyCl(CClient *cl);
|
||||
void applyGs(CGameState *gs){};
|
||||
void applyGh(CGameHandler *gh);
|
||||
bool applyGh(CGameHandler *gh);
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & fname;
|
||||
@ -1094,7 +1122,7 @@ struct PlayerMessage : public CPackForClient, public CPackForServer //513
|
||||
{CPackForClient::type = 513;};
|
||||
void applyCl(CClient *cl);
|
||||
void applyGs(CGameState *gs){};
|
||||
void applyGh(CGameHandler *gh);
|
||||
bool applyGh(CGameHandler *gh);
|
||||
|
||||
ui8 player;
|
||||
std::string text;
|
||||
@ -1110,7 +1138,7 @@ struct SetSelection : public CPackForClient, public CPackForServer //514
|
||||
{
|
||||
SetSelection(){CPackForClient::type = 514;};
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
void applyGh(CGameHandler *gh);
|
||||
bool applyGh(CGameHandler *gh);
|
||||
|
||||
ui8 player;
|
||||
ui32 id;
|
||||
|
@ -448,6 +448,16 @@ DLL_EXPORT void BattleNextRound::applyGs( CGameState *gs )
|
||||
s->state -= MOVED;
|
||||
s->state -= HAD_MORALE;
|
||||
s->counterAttacks = 1;
|
||||
|
||||
//remove effects and restore only those with remaining turns in duration
|
||||
std::vector<CStack::StackEffect> tmpEffects = s->effects;
|
||||
s->effects.clear();
|
||||
for(int i=0; i < tmpEffects.size(); i++)
|
||||
{
|
||||
tmpEffects[i].turnsRemain--;
|
||||
if(tmpEffects[i].turnsRemain > 0)
|
||||
s->effects.push_back(tmpEffects[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -545,6 +555,12 @@ DLL_EXPORT void SetStackEffect::applyGs( CGameState *gs )
|
||||
}
|
||||
}
|
||||
|
||||
DLL_EXPORT void StacksInjured::applyGs( CGameState *gs )
|
||||
{
|
||||
BOOST_FOREACH(BattleStackAttacked stackAttacked, stacks)
|
||||
stackAttacked.applyGs(gs);
|
||||
}
|
||||
|
||||
DLL_EXPORT void YourTurn::applyGs( CGameState *gs )
|
||||
{
|
||||
gs->currentPlayer = player;
|
||||
|
@ -42,12 +42,14 @@ void registerTypes1(Serializer &s)
|
||||
s.template registerType<CGBonusingObject>();
|
||||
s.template registerType<CGMagicWell>();
|
||||
s.template registerType<CGObservatory>();
|
||||
s.template registerType<CGOnceVisitable>();
|
||||
s.template registerType<CGObjectInstance>();
|
||||
}
|
||||
|
||||
template<typename Serializer> DLL_EXPORT
|
||||
void registerTypes2(Serializer &s)
|
||||
{
|
||||
s.template registerType<PackageApplied>();
|
||||
s.template registerType<SystemMessage>();
|
||||
s.template registerType<YourTurn>();
|
||||
s.template registerType<SetResource>();
|
||||
@ -89,6 +91,7 @@ void registerTypes2(Serializer &s)
|
||||
s.template registerType<EndAction>();
|
||||
s.template registerType<SpellCasted>();
|
||||
s.template registerType<SetStackEffect>();
|
||||
s.template registerType<StacksInjured>();
|
||||
s.template registerType<ShowInInfobox>();
|
||||
|
||||
s.template registerType<SaveGame>();
|
||||
|
8
map.cpp
8
map.cpp
@ -1802,6 +1802,14 @@ void Mapa::readObjects( unsigned char * bufor, int &i)
|
||||
nobj = new CGObservatory();
|
||||
break;
|
||||
}
|
||||
case 22: //Corpse
|
||||
case 39: //Lean To
|
||||
case 105://Wagon
|
||||
case 108://Warrior's Tomb
|
||||
{
|
||||
nobj = new CGOnceVisitable();
|
||||
break;
|
||||
}
|
||||
case 214: //hero placeholder
|
||||
{
|
||||
i+=3; //TODO: handle it more properly
|
||||
|
@ -55,16 +55,16 @@ CondSh<BattleResult *> battleResult(NULL);
|
||||
class CBaseForGHApply
|
||||
{
|
||||
public:
|
||||
virtual void applyOnGH(CGameHandler *gh, CConnection *c, void *pack) const =0;
|
||||
virtual bool applyOnGH(CGameHandler *gh, CConnection *c, void *pack) const =0;
|
||||
};
|
||||
template <typename T> class CApplyOnGH : public CBaseForGHApply
|
||||
{
|
||||
public:
|
||||
void applyOnGH(CGameHandler *gh, CConnection *c, void *pack) const
|
||||
bool applyOnGH(CGameHandler *gh, CConnection *c, void *pack) const
|
||||
{
|
||||
T *ptr = static_cast<T*>(pack);
|
||||
ptr->c = c;
|
||||
ptr->applyGh(gh);
|
||||
return ptr->applyGh(gh);
|
||||
}
|
||||
};
|
||||
|
||||
@ -484,17 +484,32 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
|
||||
{
|
||||
while(!end2)
|
||||
{
|
||||
c >> pack;
|
||||
tlog5 << "Received client message of type " << typeid(*pack).name() << std::endl;
|
||||
CBaseForGHApply *apply = applier->apps[typeList.getTypeID(pack)];
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(*c.rmx);
|
||||
c >> pack; //get the package
|
||||
tlog5 << "Received client message of type " << typeid(*pack).name() << std::endl;
|
||||
}
|
||||
|
||||
int packType = typeList.getTypeID(pack); //get the id of type
|
||||
CBaseForGHApply *apply = applier->apps[packType]; //and appropriae applier object
|
||||
|
||||
if(apply)
|
||||
{
|
||||
apply->applyOnGH(this,&c,pack);
|
||||
tlog5 << "Message successfully applied!\n";
|
||||
bool result = apply->applyOnGH(this,&c,pack);
|
||||
tlog5 << "Message successfully applied (result=" << result << ")!\n";
|
||||
|
||||
//send confirmation that we've applied the package
|
||||
PackageApplied applied;
|
||||
applied.result = result;
|
||||
applied.packType = packType;
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(*c.wmx);
|
||||
c << &applied;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tlog5 << "Message cannot be applied, cannot find applier!\n";
|
||||
tlog1 << "Message cannot be applied, cannot find applier (unregistered type)!\n";
|
||||
}
|
||||
delete pack;
|
||||
pack = NULL;
|
||||
@ -759,6 +774,7 @@ void CGameHandler::run(bool resume)
|
||||
{
|
||||
YourTurn yt;
|
||||
yt.player = i->first;
|
||||
boost::unique_lock<boost::mutex> lock(*connections[i->first]->wmx);
|
||||
*connections[i->first] << &yt;
|
||||
}
|
||||
|
||||
@ -1063,11 +1079,19 @@ void CGameHandler::setBlockVis(int objid, bool bv)
|
||||
SetObjectProperty sop(objid,2,bv);
|
||||
sendAndApply(&sop);
|
||||
}
|
||||
void CGameHandler::removeObject(int objid)
|
||||
|
||||
bool CGameHandler::removeObject( int objid )
|
||||
{
|
||||
if(!getObj(objid))
|
||||
{
|
||||
tlog1 << "Something wrong, that object already has been removed or hasn't existed!\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
RemoveObject ro;
|
||||
ro.id = objid;
|
||||
sendAndApply(&ro);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CGameHandler::setAmount(int objid, ui32 val)
|
||||
@ -1076,7 +1100,7 @@ void CGameHandler::setAmount(int objid, ui32 val)
|
||||
sendAndApply(&sop);
|
||||
}
|
||||
|
||||
void CGameHandler::moveHero(si32 hid, int3 dst, ui8 instant, ui8 asker)
|
||||
bool CGameHandler::moveHero( si32 hid, int3 dst, ui8 instant, ui8 asker /*= 255*/ )
|
||||
{
|
||||
bool blockvis = false;
|
||||
const CGHeroInstance *h = getHero(hid);
|
||||
@ -1085,7 +1109,7 @@ void CGameHandler::moveHero(si32 hid, int3 dst, ui8 instant, ui8 asker)
|
||||
)
|
||||
{
|
||||
tlog1 << "Illegal call to move hero!\n";
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
tlog5 << "Player " <<int(asker) << " wants to move hero "<< hid << " from "<< h->pos << " to " << dst << std::endl;
|
||||
@ -1109,7 +1133,7 @@ void CGameHandler::moveHero(si32 hid, int3 dst, ui8 instant, ui8 asker)
|
||||
{
|
||||
tlog2 << "Cannot move hero, destination tile is blocked!\n";
|
||||
sendAndApply(&tmh);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
//checks for standard movement
|
||||
@ -1121,7 +1145,7 @@ void CGameHandler::moveHero(si32 hid, int3 dst, ui8 instant, ui8 asker)
|
||||
{
|
||||
tlog2 << "Cannot move hero, not enough move points or tiles are not neighbouring!\n";
|
||||
sendAndApply(&tmh);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
//check if there is blocking visitable object
|
||||
@ -1148,7 +1172,7 @@ void CGameHandler::moveHero(si32 hid, int3 dst, ui8 instant, ui8 asker)
|
||||
}
|
||||
}
|
||||
tlog5 << "Blocking visit at " << hmpos << std::endl;
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
else //normal move
|
||||
{
|
||||
@ -1169,6 +1193,7 @@ void CGameHandler::moveHero(si32 hid, int3 dst, ui8 instant, ui8 asker)
|
||||
}
|
||||
}
|
||||
tlog5 << "Movement end!\n";
|
||||
return true;
|
||||
}
|
||||
else //instant move - teleportation
|
||||
{
|
||||
@ -1177,16 +1202,17 @@ void CGameHandler::moveHero(si32 hid, int3 dst, ui8 instant, ui8 asker)
|
||||
if(obj->ID==HEROI_TYPE)
|
||||
{
|
||||
if(obj->tempOwner==h->tempOwner)
|
||||
return;//TODO: exchange
|
||||
return true;//TODO: exchange
|
||||
//TODO: check for ally
|
||||
CGHeroInstance *dh = static_cast<CGHeroInstance *>(obj);
|
||||
startBattleI(&h->army,&dh->army,dst,h,dh,0);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
tmh.result = instant+1;
|
||||
getTilesInRange(tmh.fowRevealed,h->getSightCenter()+(tmh.end-tmh.start),h->getSightRadious(),h->tempOwner,1);
|
||||
sendAndApply(&tmh);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
void CGameHandler::setOwner(int objid, ui8 owner)
|
||||
@ -1452,7 +1478,7 @@ void CGameHandler::close()
|
||||
//exit(0);
|
||||
}
|
||||
|
||||
void CGameHandler::arrangeStacks(si32 id1, si32 id2, ui8 what, ui8 p1, ui8 p2, si32 val)
|
||||
bool CGameHandler::arrangeStacks( si32 id1, si32 id2, ui8 what, ui8 p1, ui8 p2, si32 val )
|
||||
{
|
||||
CArmedInstance *s1 = static_cast<CArmedInstance*>(gs->map->objects[id1]),
|
||||
*s2 = static_cast<CArmedInstance*>(gs->map->objects[id2]);
|
||||
@ -1462,7 +1488,7 @@ void CGameHandler::arrangeStacks(si32 id1, si32 id2, ui8 what, ui8 p1, ui8 p2, s
|
||||
if(!isAllowedExchange(id1,id2))
|
||||
{
|
||||
complain("Cannot exchange stacks between these two objects!\n");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(what==1) //swap
|
||||
@ -1480,7 +1506,7 @@ void CGameHandler::arrangeStacks(si32 id1, si32 id2, ui8 what, ui8 p1, ui8 p2, s
|
||||
if(S1.slots[p1].first != S2.slots[p2].first) //not same creature
|
||||
{
|
||||
complain("Cannot merge different creatures stacks!");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
S2.slots[p2].second += S1.slots[p1].second;
|
||||
@ -1492,7 +1518,7 @@ void CGameHandler::arrangeStacks(si32 id1, si32 id2, ui8 what, ui8 p1, ui8 p2, s
|
||||
if((!vstd::contains(S1.slots,p1) && complain("no creatures to split"))
|
||||
|| (val<1 && complain("no creatures to split")) )
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -1503,7 +1529,7 @@ void CGameHandler::arrangeStacks(si32 id1, si32 id2, ui8 what, ui8 p1, ui8 p2, s
|
||||
|| (S2.slots[p2].first != S1.slots[p1].first && complain("Cannot rebalance different creatures stacks!"))
|
||||
)
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
S2.slots[p2].second = val;
|
||||
@ -1514,7 +1540,7 @@ void CGameHandler::arrangeStacks(si32 id1, si32 id2, ui8 what, ui8 p1, ui8 p2, s
|
||||
if(S1.slots[p1].second < val)//not enough creatures
|
||||
{
|
||||
complain("Cannot split that stack, not enough creatures!");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
S2.slots[p2].first = S1.slots[p1].first;
|
||||
S2.slots[p2].second = val;
|
||||
@ -1529,7 +1555,7 @@ void CGameHandler::arrangeStacks(si32 id1, si32 id2, ui8 what, ui8 p1, ui8 p2, s
|
||||
)
|
||||
{
|
||||
complain("Cannot take the last stack!");
|
||||
return; //leave without applying changes to garrison
|
||||
return false; //leave without applying changes to garrison
|
||||
}
|
||||
|
||||
//apply changes
|
||||
@ -1538,6 +1564,7 @@ void CGameHandler::arrangeStacks(si32 id1, si32 id2, ui8 what, ui8 p1, ui8 p2, s
|
||||
if(s1 != s2)
|
||||
sg.garrs[id2] = S2;
|
||||
sendAndApply(&sg);
|
||||
return true;
|
||||
}
|
||||
|
||||
int CGameHandler::getPlayerAt( CConnection *c ) const
|
||||
@ -1564,21 +1591,22 @@ int CGameHandler::getPlayerAt( CConnection *c ) const
|
||||
}
|
||||
}
|
||||
|
||||
void CGameHandler::disbandCreature(si32 id, ui8 pos)
|
||||
bool CGameHandler::disbandCreature( si32 id, ui8 pos )
|
||||
{
|
||||
CArmedInstance *s1 = static_cast<CArmedInstance*>(gs->map->objects[id]);
|
||||
if(!vstd::contains(s1->army.slots,pos))
|
||||
{
|
||||
complain("Illegal call to disbandCreature - no such stack in army!");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
s1->army.slots.erase(pos);
|
||||
SetGarrisons sg;
|
||||
sg.garrs[id] = s1->army;
|
||||
sendAndApply(&sg);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CGameHandler::buildStructure(si32 tid, si32 bid)
|
||||
bool CGameHandler::buildStructure( si32 tid, si32 bid )
|
||||
{
|
||||
CGTownInstance * t = static_cast<CGTownInstance*>(gs->map->objects[tid]);
|
||||
CBuilding * b = VLC->buildh->buildings[t->subID][bid];
|
||||
@ -1586,7 +1614,7 @@ void CGameHandler::buildStructure(si32 tid, si32 bid)
|
||||
if(gs->canBuildStructure(t,bid) != 7)
|
||||
{
|
||||
complain("Cannot build that building!");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
NewStructures ns;
|
||||
@ -1625,6 +1653,8 @@ void CGameHandler::buildStructure(si32 tid, si32 bid)
|
||||
if(t->garrisonHero)
|
||||
giveSpells(t,t->garrisonHero);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CGameHandler::sendMessageToAll( const std::string &message )
|
||||
@ -1634,7 +1664,7 @@ void CGameHandler::sendMessageToAll( const std::string &message )
|
||||
sendToAllClients(&sm);
|
||||
}
|
||||
|
||||
void CGameHandler::recruitCreatures( si32 objid, ui32 crid, ui32 cram )
|
||||
bool CGameHandler::recruitCreatures( si32 objid, ui32 crid, ui32 cram )
|
||||
{
|
||||
si32 ser = -1;
|
||||
CGTownInstance * t = static_cast<CGTownInstance*>(gs->map->objects[objid]);
|
||||
@ -1654,11 +1684,13 @@ void CGameHandler::recruitCreatures( si32 objid, ui32 crid, ui32 cram )
|
||||
}
|
||||
int slot = t->army.getSlotFor(crid);
|
||||
|
||||
if(!found || //no such creature
|
||||
cram > VLC->creh->creatures[crid].maxAmount(gs->getPlayer(t->tempOwner)->resources) || //lack of resources
|
||||
cram<=0 ||
|
||||
slot<0 )
|
||||
return;
|
||||
if(!found && complain("Cannot recruit: no such creatures!")
|
||||
|| cram > VLC->creh->creatures[crid].maxAmount(gs->getPlayer(t->tempOwner)->resources) && complain("Cannot recruit: lack of resources!")
|
||||
|| cram<=0 && complain("Cannot recruit: cram <= 0!")
|
||||
|| slot<0 && complain("Cannot recruit: no available slot!"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//recruit
|
||||
SetResources sr;
|
||||
@ -1684,9 +1716,10 @@ void CGameHandler::recruitCreatures( si32 objid, ui32 crid, ui32 cram )
|
||||
sendAndApply(&sr);
|
||||
sendAndApply(&sac);
|
||||
sendAndApply(&sg);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CGameHandler::upgradeCreature( ui32 objid, ui8 pos, ui32 upgID )
|
||||
bool CGameHandler::upgradeCreature( ui32 objid, ui8 pos, ui32 upgID )
|
||||
{
|
||||
CArmedInstance *obj = static_cast<CArmedInstance*>(gs->map->objects[objid]);
|
||||
UpgradeInfo ui = gs->getUpgradeInfo(obj,pos);
|
||||
@ -1694,8 +1727,10 @@ void CGameHandler::upgradeCreature( ui32 objid, ui8 pos, ui32 upgID )
|
||||
int crQuantity = obj->army.slots[pos].second;
|
||||
|
||||
//check if upgrade is possible
|
||||
if(ui.oldID<0 || !vstd::contains(ui.newID,upgID))
|
||||
return;
|
||||
if((ui.oldID<0 || !vstd::contains(ui.newID,upgID)) && complain("That upgrade is not possible!"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//check if player has enough resources
|
||||
for(int i=0;i<ui.cost.size();i++)
|
||||
@ -1703,7 +1738,10 @@ void CGameHandler::upgradeCreature( ui32 objid, ui8 pos, ui32 upgID )
|
||||
for (std::set<std::pair<int,int> >::iterator j=ui.cost[i].begin(); j!=ui.cost[i].end(); j++)
|
||||
{
|
||||
if(gs->getPlayer(player)->resources[j->first] < j->second*crQuantity)
|
||||
return;
|
||||
{
|
||||
complain("Cannot upgrade, not enough resources!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1725,9 +1763,10 @@ void CGameHandler::upgradeCreature( ui32 objid, ui8 pos, ui32 upgID )
|
||||
sg.garrs[objid] = obj->army;
|
||||
sg.garrs[objid].slots[pos].first = upgID;
|
||||
sendAndApply(&sg);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CGameHandler::garrisonSwap(si32 tid)
|
||||
bool CGameHandler::garrisonSwap( si32 tid )
|
||||
{
|
||||
CGTownInstance *town = gs->getTown(tid);
|
||||
if(!town->garrisonHero && town->visitingHero) //visiting => garrison, merge armies
|
||||
@ -1737,7 +1776,10 @@ void CGameHandler::garrisonSwap(si32 tid)
|
||||
{
|
||||
int pos = csn.getSlotFor(cso.slots.begin()->second.first);
|
||||
if(pos<0)
|
||||
return;
|
||||
{
|
||||
complain("Cannot make garrison swap, not enough free slots!");
|
||||
return false;
|
||||
}
|
||||
if(csn.slots.find(pos)!=csn.slots.end()) //add creatures to the existing stack
|
||||
{
|
||||
csn.slots[pos].second += cso.slots.begin()->second.second;
|
||||
@ -1759,6 +1801,7 @@ void CGameHandler::garrisonSwap(si32 tid)
|
||||
intown.visiting = -1;
|
||||
intown.garrison = town->visitingHero->id;
|
||||
sendAndApply(&intown);
|
||||
return true;
|
||||
}
|
||||
else if (town->garrisonHero && !town->visitingHero) //move hero out of the garrison
|
||||
{
|
||||
@ -1766,7 +1809,7 @@ void CGameHandler::garrisonSwap(si32 tid)
|
||||
if(getHeroCount(town->garrisonHero->tempOwner,true) >= 8)
|
||||
{
|
||||
complain("Cannot move hero out of the garrison, there are already 8 wandering heroes!");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
SetHeroesInTown intown;
|
||||
@ -1779,6 +1822,7 @@ void CGameHandler::garrisonSwap(si32 tid)
|
||||
SetGarrisons sg;
|
||||
sg.garrs[tid] = CCreatureSet();
|
||||
sendAndApply(&sg);
|
||||
return true;
|
||||
}
|
||||
else if (town->garrisonHero && town->visitingHero) //swap visiting and garrison hero
|
||||
{
|
||||
@ -1792,18 +1836,21 @@ void CGameHandler::garrisonSwap(si32 tid)
|
||||
intown.visiting = town->garrisonHero->id;
|
||||
sendAndApply(&intown);
|
||||
sendAndApply(&sg);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
complain("Cannot swap garrison hero!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void CGameHandler::swapArtifacts( si32 hid1, si32 hid2, ui16 slot1, ui16 slot2 )
|
||||
bool CGameHandler::swapArtifacts( si32 hid1, si32 hid2, ui16 slot1, ui16 slot2 )
|
||||
{
|
||||
CGHeroInstance *h1 = gs->getHero(hid1), *h2 = gs->getHero(hid2);
|
||||
if((distance(h1->pos,h2->pos) > 1.0) || (h1->tempOwner != h2->tempOwner))
|
||||
return;
|
||||
return false;
|
||||
|
||||
const CArtifact *a1 = h1->getArt(slot1),
|
||||
*a2=h2->getArt(slot2);
|
||||
|
||||
@ -1813,7 +1860,7 @@ void CGameHandler::swapArtifacts( si32 hid1, si32 hid2, ui16 slot1, ui16 slot2 )
|
||||
{
|
||||
//artifact doesn't fit dst slot
|
||||
complain("Cannot swap artifacts!");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -1832,9 +1879,11 @@ void CGameHandler::swapArtifacts( si32 hid1, si32 hid2, ui16 slot1, ui16 slot2 )
|
||||
sha.setArtAtPos(slot2,h1->getArtAtPos(slot1));
|
||||
sendAndApply(&sha);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CGameHandler::buyArtifact( ui32 hid, si32 aid )
|
||||
bool CGameHandler::buyArtifact( ui32 hid, si32 aid )
|
||||
{
|
||||
CGHeroInstance *hero = gs->getHero(hid);
|
||||
CGTownInstance *town = hero->visitedTown;
|
||||
@ -1844,29 +1893,32 @@ void CGameHandler::buyArtifact( ui32 hid, si32 aid )
|
||||
|| getResource(hero->getOwner(),6)<500 && complain("Cannot buy a spellbook, not enough gold!")
|
||||
|| hero->getArt(17) && complain("Cannot buy a spellbook, hero already has a one!")
|
||||
)
|
||||
return;
|
||||
return false;
|
||||
|
||||
giveResource(hero->getOwner(),6,-500);
|
||||
giveHeroArtifact(0,hid,17);
|
||||
giveSpells(town,hero);
|
||||
return true;
|
||||
}
|
||||
else if(aid < 7 && aid > 3) //war machine
|
||||
{
|
||||
int price = VLC->arth->artifacts[aid].price;
|
||||
if(vstd::contains(hero->artifWorn,ui16(9+aid)) //hero already has this machine
|
||||
|| !vstd::contains(town->builtBuildings,si32(16)) //no blackismith
|
||||
|| gs->getPlayer(hero->getOwner())->resources[6] < price //no gold
|
||||
|| town->town->warMachine!= aid ) //this machine is not available here (//TODO: support ballista yard in stronghold)
|
||||
if(vstd::contains(hero->artifWorn,ui16(9+aid)) && complain("Hero already has this machine!")
|
||||
|| !vstd::contains(town->builtBuildings,si32(16)) && complain("No blackismith!")
|
||||
|| gs->getPlayer(hero->getOwner())->resources[6] < price && complain("Not enough gold!") //no gold
|
||||
|| town->town->warMachine!= aid && complain("This machine is unavailale here!") ) //TODO: ballista yard in Stronghold
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
giveResource(hero->getOwner(),6,-price);
|
||||
giveHeroArtifact(aid,hid,9+aid);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CGameHandler::tradeResources( ui32 val, ui8 player, ui32 id1, ui32 id2 )
|
||||
bool CGameHandler::tradeResources( ui32 val, ui8 player, ui32 id1, ui32 id2 )
|
||||
{
|
||||
val = std::min(si32(val),gs->getPlayer(player)->resources[id1]);
|
||||
double uzysk = (double)gs->resVals[id1] * val * gs->getMarketEfficiency(player);
|
||||
@ -1880,22 +1932,25 @@ void CGameHandler::tradeResources( ui32 val, ui8 player, ui32 id1, ui32 id2 )
|
||||
sr.resid = id2;
|
||||
sr.val = gs->getPlayer(player)->resources[id2] + (int)uzysk;
|
||||
sendAndApply(&sr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CGameHandler::setFormation( si32 hid, ui8 formation )
|
||||
bool CGameHandler::setFormation( si32 hid, ui8 formation )
|
||||
{
|
||||
gs->getHero(hid)->army.formation = formation;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CGameHandler::hireHero( ui32 tid, ui8 hid )
|
||||
bool CGameHandler::hireHero( ui32 tid, ui8 hid )
|
||||
{
|
||||
CGTownInstance *t = gs->getTown(tid);
|
||||
if(!vstd::contains(t->builtBuildings,5) //no tavern in the town
|
||||
|| gs->getPlayer(t->tempOwner)->resources[6]<2500 //not enough gold
|
||||
|| t->visitingHero //there is visiting hero - no place
|
||||
if(!vstd::contains(t->builtBuildings,5) && complain("No tavern!")
|
||||
|| gs->getPlayer(t->tempOwner)->resources[6]<2500 && complain("Not enough gold for buying hero!")
|
||||
|| t->visitingHero && complain("There is visiting hero - no place!")
|
||||
|| getHeroCount(t->tempOwner,false) >= 8 && complain("Cannot hire hero, only 8 wandering heroes are allowed!")
|
||||
)
|
||||
return;
|
||||
return false;
|
||||
CGHeroInstance *nh = gs->getPlayer(t->tempOwner)->availableHeroes[hid];
|
||||
|
||||
HeroRecruited hr;
|
||||
@ -1919,9 +1974,10 @@ void CGameHandler::hireHero( ui32 tid, ui8 hid )
|
||||
sendAndApply(&sr);
|
||||
|
||||
giveSpells(t,nh);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CGameHandler::queryReply( ui32 qid, ui32 answer )
|
||||
bool CGameHandler::queryReply( ui32 qid, ui32 answer )
|
||||
{
|
||||
boost::unique_lock<boost::recursive_mutex> lock(gsm);
|
||||
if(vstd::contains(callbacks,qid))
|
||||
@ -1941,11 +1997,14 @@ void CGameHandler::queryReply( ui32 qid, ui32 answer )
|
||||
else
|
||||
{
|
||||
tlog1 << "Unknown query reply...\n";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CGameHandler::makeBattleAction( BattleAction &ba )
|
||||
bool CGameHandler::makeBattleAction( BattleAction &ba )
|
||||
{
|
||||
bool ok = true;
|
||||
switch(ba.actionType)
|
||||
{
|
||||
case 2: //walk
|
||||
@ -1985,11 +2044,13 @@ void CGameHandler::makeBattleAction( BattleAction &ba )
|
||||
if(curStack->position != ba.destinationTile) //we wasn't able to reach destination tile
|
||||
{
|
||||
tlog3<<"We cannot move this stack to its destination "<<curStack->creature->namePl<<std::endl;
|
||||
ok = false;
|
||||
}
|
||||
|
||||
if(!stackAtEnd)
|
||||
{
|
||||
tlog3 << "There is no stack on " << ba.additionalInfo << " tile (no attack)!";
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2010,7 +2071,7 @@ void CGameHandler::makeBattleAction( BattleAction &ba )
|
||||
{
|
||||
tlog3 << "Attack cannot be performed!";
|
||||
sendAndApply(&EndAction());
|
||||
break;
|
||||
ok = false;
|
||||
}
|
||||
|
||||
//attack
|
||||
@ -2080,6 +2141,7 @@ void CGameHandler::makeBattleAction( BattleAction &ba )
|
||||
}
|
||||
}
|
||||
battleMadeAction.setn(true);
|
||||
return ok;
|
||||
}
|
||||
|
||||
void CGameHandler::playerMessage( ui8 player, const std::string &message )
|
||||
@ -2182,7 +2244,7 @@ void CGameHandler::playerMessage( ui8 player, const std::string &message )
|
||||
}
|
||||
}
|
||||
|
||||
void CGameHandler::makeCustomAction( BattleAction &ba )
|
||||
bool CGameHandler::makeCustomAction( BattleAction &ba )
|
||||
{
|
||||
switch(ba.actionType)
|
||||
{
|
||||
@ -2192,12 +2254,12 @@ void CGameHandler::makeCustomAction( BattleAction &ba )
|
||||
if(!h)
|
||||
{
|
||||
tlog2 << "Wrong caster!\n";
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
if(ba.additionalInfo >= VLC->spellh->spells.size())
|
||||
{
|
||||
tlog2 << "Wrong spell id (" << ba.additionalInfo << ")!\n";
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
CSpell *s = &VLC->spellh->spells[ba.additionalInfo];
|
||||
@ -2210,7 +2272,7 @@ void CGameHandler::makeCustomAction( BattleAction &ba )
|
||||
)
|
||||
{
|
||||
tlog2 << "Spell cannot be casted!\n";
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
sendAndApply(&StartAction(ba)); //start spell casting
|
||||
@ -2343,8 +2405,10 @@ void CGameHandler::makeCustomAction( BattleAction &ba )
|
||||
}
|
||||
}
|
||||
sendAndApply(&EndAction());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CGameHandler::handleTimeEvents()
|
||||
|
@ -103,7 +103,7 @@ public:
|
||||
|
||||
//do sth
|
||||
void changeSpells(int hid, bool give, const std::set<ui32> &spells);
|
||||
void removeObject(int objid);
|
||||
bool removeObject(int objid);
|
||||
void setBlockVis(int objid, bool bv);
|
||||
void setOwner(int objid, ui8 owner);
|
||||
void setHoverName(int objid, MetaString * name);
|
||||
@ -124,7 +124,7 @@ public:
|
||||
void startBattleI(const CCreatureSet * army1, const CCreatureSet * army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, boost::function<void(BattleResult*)> cb); //use hero=NULL for no hero
|
||||
void startBattleI(int heroID, CCreatureSet army, int3 tile, boost::function<void(BattleResult*)> cb); //for hero<=>neutral army
|
||||
void setAmount(int objid, ui32 val);
|
||||
void moveHero(si32 hid, int3 dst, ui8 instant, ui8 asker = 255);
|
||||
bool moveHero(si32 hid, int3 dst, ui8 instant, ui8 asker = 255);
|
||||
void giveHeroBonus(GiveBonus * bonus);
|
||||
void setMovePoints(SetMovePoints * smp);
|
||||
void setManaPoints(int hid, int val);
|
||||
@ -137,20 +137,20 @@ public:
|
||||
int getPlayerAt(CConnection *c) const;
|
||||
|
||||
void playerMessage( ui8 player, const std::string &message);
|
||||
void makeBattleAction(BattleAction &ba);
|
||||
void makeCustomAction(BattleAction &ba);
|
||||
void queryReply( ui32 qid, ui32 answer );
|
||||
void hireHero( ui32 tid, ui8 hid );
|
||||
void setFormation( si32 hid, ui8 formation );
|
||||
void tradeResources( ui32 val, ui8 player, ui32 id1, ui32 id2 );
|
||||
void buyArtifact( ui32 hid, si32 aid );
|
||||
void swapArtifacts( si32 hid1, si32 hid2, ui16 slot1, ui16 slot2 );
|
||||
void garrisonSwap(si32 tid);
|
||||
void upgradeCreature( ui32 objid, ui8 pos, ui32 upgID );
|
||||
void recruitCreatures(si32 objid, ui32 crid, ui32 cram);
|
||||
void buildStructure(si32 tid, si32 bid);
|
||||
void disbandCreature( si32 id, ui8 pos );
|
||||
void arrangeStacks( si32 id1, si32 id2, ui8 what, ui8 p1, ui8 p2, si32 val );
|
||||
bool makeBattleAction(BattleAction &ba);
|
||||
bool makeCustomAction(BattleAction &ba);
|
||||
bool queryReply( ui32 qid, ui32 answer );
|
||||
bool hireHero( ui32 tid, ui8 hid );
|
||||
bool setFormation( si32 hid, ui8 formation );
|
||||
bool tradeResources( ui32 val, ui8 player, ui32 id1, ui32 id2 );
|
||||
bool buyArtifact( ui32 hid, si32 aid );
|
||||
bool swapArtifacts( si32 hid1, si32 hid2, ui16 slot1, ui16 slot2 );
|
||||
bool garrisonSwap(si32 tid);
|
||||
bool upgradeCreature( ui32 objid, ui8 pos, ui32 upgID );
|
||||
bool recruitCreatures(si32 objid, ui32 crid, ui32 cram);
|
||||
bool buildStructure(si32 tid, si32 bid);
|
||||
bool disbandCreature( si32 id, ui8 pos );
|
||||
bool arrangeStacks( si32 id1, si32 id2, ui8 what, ui8 p1, ui8 p2, si32 val );
|
||||
void save(const std::string &fname);
|
||||
void close();
|
||||
void handleTimeEvents();
|
||||
|
@ -5,7 +5,7 @@
|
||||
#define PLAYER_OWNS(id) (gh->getPlayerAt(c)==gh->getOwner(id))
|
||||
#define ERROR_AND_RETURN {if(c) *c << &SystemMessage("You are not allowed to perform this action!"); \
|
||||
tlog1<<"Player is not allowed to perform this action!\n"; \
|
||||
return;}
|
||||
return false;}
|
||||
#define ERROR_IF_NOT_OWNS(id) if(!PLAYER_OWNS(id)) ERROR_AND_RETURN
|
||||
|
||||
/*
|
||||
@ -23,128 +23,136 @@ CGameState* CPackForServer::GS(CGameHandler *gh)
|
||||
return gh->gs;
|
||||
}
|
||||
|
||||
void SaveGame::applyGh( CGameHandler *gh )
|
||||
bool SaveGame::applyGh( CGameHandler *gh )
|
||||
{
|
||||
gh->sendMessageTo(*c,"Saving...");
|
||||
gh->save(fname);
|
||||
gh->sendMessageTo(*c,"Game has been succesfully saved!");
|
||||
return true;
|
||||
}
|
||||
|
||||
void CloseServer::applyGh( CGameHandler *gh )
|
||||
bool CloseServer::applyGh( CGameHandler *gh )
|
||||
{
|
||||
gh->close();
|
||||
return true;
|
||||
}
|
||||
|
||||
void EndTurn::applyGh( CGameHandler *gh )
|
||||
bool EndTurn::applyGh( CGameHandler *gh )
|
||||
{
|
||||
gh->states.setFlag(GS(gh)->currentPlayer,&PlayerStatus::makingTurn,false);
|
||||
return true;
|
||||
}
|
||||
|
||||
void DismissHero::applyGh( CGameHandler *gh )
|
||||
bool DismissHero::applyGh( CGameHandler *gh )
|
||||
{
|
||||
ERROR_IF_NOT_OWNS(hid);
|
||||
gh->removeObject(hid);
|
||||
return gh->removeObject(hid);
|
||||
}
|
||||
|
||||
void MoveHero::applyGh( CGameHandler *gh )
|
||||
bool MoveHero::applyGh( CGameHandler *gh )
|
||||
{
|
||||
ERROR_IF_NOT_OWNS(hid);
|
||||
gh->moveHero(hid,dest,0,gh->getPlayerAt(c));
|
||||
return gh->moveHero(hid,dest,0,gh->getPlayerAt(c));
|
||||
}
|
||||
|
||||
void ArrangeStacks::applyGh( CGameHandler *gh )
|
||||
bool ArrangeStacks::applyGh( CGameHandler *gh )
|
||||
{
|
||||
//ERROR_IF_NOT_OWNS(id1);
|
||||
//ERROR_IF_NOT_OWNS(id2);
|
||||
gh->arrangeStacks(id1,id2,what,p1,p2,val);
|
||||
//checks for owning in the gh func
|
||||
return gh->arrangeStacks(id1,id2,what,p1,p2,val);
|
||||
}
|
||||
|
||||
void DisbandCreature::applyGh( CGameHandler *gh )
|
||||
bool DisbandCreature::applyGh( CGameHandler *gh )
|
||||
{
|
||||
ERROR_IF_NOT_OWNS(id);
|
||||
gh->disbandCreature(id,pos);
|
||||
return gh->disbandCreature(id,pos);
|
||||
}
|
||||
|
||||
void BuildStructure::applyGh( CGameHandler *gh )
|
||||
bool BuildStructure::applyGh( CGameHandler *gh )
|
||||
{
|
||||
ERROR_IF_NOT_OWNS(tid);
|
||||
gh->buildStructure(tid,bid);
|
||||
return gh->buildStructure(tid,bid);
|
||||
}
|
||||
|
||||
void RecruitCreatures::applyGh( CGameHandler *gh )
|
||||
bool RecruitCreatures::applyGh( CGameHandler *gh )
|
||||
{
|
||||
ERROR_IF_NOT_OWNS(tid);
|
||||
gh->recruitCreatures(tid,crid,amount);
|
||||
return gh->recruitCreatures(tid,crid,amount);
|
||||
}
|
||||
|
||||
void UpgradeCreature::applyGh( CGameHandler *gh )
|
||||
bool UpgradeCreature::applyGh( CGameHandler *gh )
|
||||
{
|
||||
ERROR_IF_NOT_OWNS(id);
|
||||
gh->upgradeCreature(id,pos,cid);
|
||||
return gh->upgradeCreature(id,pos,cid);
|
||||
}
|
||||
|
||||
void GarrisonHeroSwap::applyGh( CGameHandler *gh )
|
||||
bool GarrisonHeroSwap::applyGh( CGameHandler *gh )
|
||||
{
|
||||
ERROR_IF_NOT_OWNS(tid);
|
||||
gh->garrisonSwap(tid);
|
||||
return gh->garrisonSwap(tid);
|
||||
}
|
||||
|
||||
void ExchangeArtifacts::applyGh( CGameHandler *gh )
|
||||
bool ExchangeArtifacts::applyGh( CGameHandler *gh )
|
||||
{
|
||||
ERROR_IF_NOT_OWNS(hid1);
|
||||
ERROR_IF_NOT_OWNS(hid2);
|
||||
gh->swapArtifacts(hid1,hid2,slot1,slot2);
|
||||
return gh->swapArtifacts(hid1,hid2,slot1,slot2);
|
||||
}
|
||||
|
||||
void BuyArtifact::applyGh( CGameHandler *gh )
|
||||
bool BuyArtifact::applyGh( CGameHandler *gh )
|
||||
{
|
||||
ERROR_IF_NOT_OWNS(hid);
|
||||
gh->buyArtifact(hid,aid);
|
||||
return gh->buyArtifact(hid,aid);
|
||||
}
|
||||
|
||||
void TradeOnMarketplace::applyGh( CGameHandler *gh )
|
||||
bool TradeOnMarketplace::applyGh( CGameHandler *gh )
|
||||
{
|
||||
if(gh->getPlayerAt(c) != player) ERROR_AND_RETURN;
|
||||
gh->tradeResources(val,player,r1,r2);
|
||||
return gh->tradeResources(val,player,r1,r2);
|
||||
}
|
||||
|
||||
void SetFormation::applyGh( CGameHandler *gh )
|
||||
bool SetFormation::applyGh( CGameHandler *gh )
|
||||
{
|
||||
ERROR_IF_NOT_OWNS(hid);
|
||||
gh->setFormation(hid,formation);
|
||||
return gh->setFormation(hid,formation);
|
||||
}
|
||||
|
||||
void HireHero::applyGh( CGameHandler *gh )
|
||||
bool HireHero::applyGh( CGameHandler *gh )
|
||||
{
|
||||
ERROR_IF_NOT_OWNS(tid);
|
||||
gh->hireHero(tid,hid);
|
||||
return gh->hireHero(tid,hid);
|
||||
}
|
||||
|
||||
void QueryReply::applyGh( CGameHandler *gh )
|
||||
bool QueryReply::applyGh( CGameHandler *gh )
|
||||
{
|
||||
gh->queryReply(qid,answer);
|
||||
//TODO - check if player matches the query
|
||||
return gh->queryReply(qid,answer);
|
||||
}
|
||||
|
||||
void MakeAction::applyGh( CGameHandler *gh )
|
||||
bool MakeAction::applyGh( CGameHandler *gh )
|
||||
{
|
||||
if(!GS(gh)->curB) ERROR_AND_RETURN;
|
||||
if(gh->connections[GS(gh)->curB->getStack(GS(gh)->curB->activeStack)->owner] != c) ERROR_AND_RETURN;
|
||||
gh->makeBattleAction(ba);
|
||||
return gh->makeBattleAction(ba);
|
||||
}
|
||||
|
||||
void MakeCustomAction::applyGh( CGameHandler *gh )
|
||||
bool MakeCustomAction::applyGh( CGameHandler *gh )
|
||||
{
|
||||
if(!GS(gh)->curB) ERROR_AND_RETURN;
|
||||
if(gh->connections[GS(gh)->curB->getStack(GS(gh)->curB->activeStack)->owner] != c) ERROR_AND_RETURN;
|
||||
gh->makeCustomAction(ba);
|
||||
return gh->makeCustomAction(ba);
|
||||
}
|
||||
|
||||
void PlayerMessage::applyGh( CGameHandler *gh )
|
||||
bool PlayerMessage::applyGh( CGameHandler *gh )
|
||||
{
|
||||
if(gh->getPlayerAt(c) != player) ERROR_AND_RETURN;
|
||||
gh->playerMessage(player,text);
|
||||
return true;
|
||||
}
|
||||
|
||||
void SetSelection::applyGh( CGameHandler *gh )
|
||||
bool SetSelection::applyGh( CGameHandler *gh )
|
||||
{
|
||||
if(gh->getPlayerAt(c) != player) ERROR_AND_RETURN;
|
||||
if(!gh->getObj(id)) ERROR_AND_RETURN;
|
||||
gh->sendAndApply(this);
|
||||
return true;
|
||||
}
|
Loading…
Reference in New Issue
Block a user