1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

* a bit better stack reversing

* FoWChange uses unordered_set instead of set
This commit is contained in:
mateuszb 2011-01-20 17:25:15 +00:00
parent 898ad292ea
commit 2451c0dea6
16 changed files with 106 additions and 64 deletions

View File

@ -128,8 +128,8 @@ public:
virtual void showHillFortWindow(const CGObjectInstance *object, const CGHeroInstance *visitor){};
virtual void showTavernWindow(const CGObjectInstance *townOrTavern){};
virtual void advmapSpellCast(const CGHeroInstance * caster, int spellID){}; //called when a hero casts a spell
virtual void tileHidden(const std::set<int3> &pos){};
virtual void tileRevealed(const std::set<int3> &pos){};
virtual void tileHidden(const boost::unordered_set<int3, ShashInt3> &pos){};
virtual void tileRevealed(const boost::unordered_set<int3, ShashInt3> &pos){};
virtual void newObject(const CGObjectInstance * obj){}; //eg. ship built in shipyard
virtual void availableArtifactsChanged(const CGBlackMarket *bm = NULL){}; //bm may be NULL, then artifacts are changed in the global pool (used by merchants in towns)
virtual void yourTurn(){};

View File

@ -3245,9 +3245,9 @@ void CBattleInterface::endAction(const BattleAction* action)
}
//check if we should reverse stacks
std::vector<const CStack *> stacks;
stacks.push_back(LOCPLINT->cb->battleGetStackByID(action->stackNumber));
stacks.push_back(LOCPLINT->cb->battleGetStackByPos(action->destinationTile));
std::set<const CStack *> stacks;
stacks.insert(LOCPLINT->cb->battleGetStackByID(action->stackNumber));
stacks.insert(LOCPLINT->cb->battleGetStackByPos(action->destinationTile));
BOOST_FOREACH(const CStack *s, stacks)
{

View File

@ -933,19 +933,19 @@ void CPlayerInterface::showBlockingDialog( const std::string &text, const std::v
}
void CPlayerInterface::tileRevealed(const std::set<int3> &pos)
void CPlayerInterface::tileRevealed(const boost::unordered_set<int3, ShashInt3> &pos)
{
boost::unique_lock<boost::recursive_mutex> un(*pim);
for(std::set<int3>::const_iterator i=pos.begin(); i!=pos.end();i++)
for(boost::unordered_set<int3, ShashInt3>::const_iterator i=pos.begin(); i!=pos.end();i++)
adventureInt->minimap.showTile(*i);
if(pos.size())
GH.totalRedraw();
}
void CPlayerInterface::tileHidden(const std::set<int3> &pos)
void CPlayerInterface::tileHidden(const boost::unordered_set<int3, ShashInt3> &pos)
{
boost::unique_lock<boost::recursive_mutex> un(*pim);
for(std::set<int3>::const_iterator i=pos.begin(); i!=pos.end();i++)
for(boost::unordered_set<int3, ShashInt3>::const_iterator i=pos.begin(); i!=pos.end();i++)
adventureInt->minimap.hideTile(*i);
if(pos.size())
GH.totalRedraw();

View File

@ -192,8 +192,8 @@ public:
void showHillFortWindow(const CGObjectInstance *object, const CGHeroInstance *visitor) OVERRIDE;
void showTavernWindow(const CGObjectInstance *townOrTavern) OVERRIDE;
void advmapSpellCast(const CGHeroInstance * caster, int spellID) OVERRIDE; //called when a hero casts a spell
void tileHidden(const std::set<int3> &pos) OVERRIDE; //called when given tiles become hidden under fog of war
void tileRevealed(const std::set<int3> &pos) OVERRIDE; //called when fog of war disappears from given tiles
void tileHidden(const boost::unordered_set<int3, ShashInt3> &pos) OVERRIDE; //called when given tiles become hidden under fog of war
void tileRevealed(const boost::unordered_set<int3, ShashInt3> &pos) OVERRIDE; //called when fog of war disappears from given tiles
void newObject(const CGObjectInstance * obj) OVERRIDE;
void availableArtifactsChanged(const CGBlackMarket *bm = NULL) OVERRIDE; //bm may be NULL, then artifacts are changed in the global pool (used by merchants in towns)
void yourTurn() OVERRIDE;

View File

@ -98,32 +98,31 @@ public:
int getSelectedHero();
//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){};
bool removeObject(int objid){return false;};
void setBlockVis(int objid, bool bv){};
void setOwner(int objid, ui8 owner){};
void setHoverName(int objid, MetaString * name){};
void setObjProperty(int objid, int prop, si64 val){};
void changePrimSkill(int ID, int which, si64 val, bool abs=false){};
void changeSecSkill(int ID, int which, int val, bool abs=false){};
void showInfoDialog(InfoWindow *iw){};
void showBlockingDialog(BlockingDialog *iw, const CFunctionList<void(ui32)> &callback){};
ui32 showBlockingDialog(BlockingDialog *iw){return 0;}; //synchronous version of above
void showGarrisonDialog(int upobj, int hid, bool removableUnits, const boost::function<void()> &cb){};
void showThievesGuildWindow(int requestingObjId){};
void giveResource(int player, int which, int val){};
void changeSpells(int hid, bool give, const std::set<ui32> &spells) OVERRIDE {};
bool removeObject(int objid) OVERRIDE {return false;};
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 {};
void showBlockingDialog(BlockingDialog *iw, const CFunctionList<void(ui32)> &callback) OVERRIDE {};
ui32 showBlockingDialog(BlockingDialog *iw) OVERRIDE {return 0;}; //synchronous version of above
void showGarrisonDialog(int upobj, int hid, bool removableUnits, const boost::function<void()> &cb) OVERRIDE {};
void showThievesGuildWindow(int requestingObjId) OVERRIDE {};
void giveResource(int player, int which, int val) OVERRIDE {};
void giveCreatures (const CArmedInstance * objid, const CGHeroInstance * h, const CCreatureSet &creatures, bool remove) {};
void takeCreatures (int objid, TSlots creatures){};
void takeCreatures (int objid, std::vector<CStackBasicDescriptor> creatures){};
bool changeStackType(const StackLocation &sl, CCreature *c){return false;};
bool changeStackCount(const StackLocation &sl, TQuantity count, bool absoluteValue = false){return false;};
bool insertNewStack(const StackLocation &sl, const CCreature *c, TQuantity count){return false;};
void giveCreatures (const CArmedInstance * objid, const CGHeroInstance * h, const CCreatureSet &creatures, bool remove) OVERRIDE {};
void takeCreatures (int objid, std::vector<CStackBasicDescriptor> creatures) OVERRIDE {};
bool changeStackType(const StackLocation &sl, CCreature *c) OVERRIDE {return false;};
bool changeStackCount(const StackLocation &sl, TQuantity count, bool absoluteValue = false) OVERRIDE {return false;};
bool insertNewStack(const StackLocation &sl, const CCreature *c, TQuantity count) OVERRIDE {return false;};
bool eraseStack(const StackLocation &sl, bool forceRemoval = false){return false;};
bool swapStacks(const StackLocation &sl1, const StackLocation &sl2){return false;}
bool addToSlot(const StackLocation &sl, const CCreature *c, TQuantity count){return false;}
void tryJoiningArmy(const CArmedInstance *src, const CArmedInstance *dst, bool removeObjWhenFinished, bool allowMerging){}
bool moveStack(const StackLocation &src, const StackLocation &dst, TQuantity count = -1){return false;}
bool swapStacks(const StackLocation &sl1, const StackLocation &sl2) OVERRIDE {return false;}
bool addToSlot(const StackLocation &sl, const CCreature *c, TQuantity count) OVERRIDE {return false;}
void tryJoiningArmy(const CArmedInstance *src, const CArmedInstance *dst, bool removeObjWhenFinished, bool allowMerging) OVERRIDE {}
bool moveStack(const StackLocation &src, const StackLocation &dst, TQuantity count = -1) OVERRIDE {return false;}
void giveHeroNewArtifact(const CGHeroInstance *h, const CArtifact *artType, int pos) OVERRIDE {};
void giveHeroArtifact(const CGHeroInstance *h, const CArtifactInstance *a, int pos) OVERRIDE {};
@ -131,24 +130,23 @@ public:
void removeArtifact(const ArtifactLocation &al) OVERRIDE {};
void moveArtifact(const ArtifactLocation &al1, const ArtifactLocation &al2) OVERRIDE {};
void showCompInfo(ShowInInfobox * comp){};
void heroVisitCastle(int obj, int heroID){};
void stopHeroVisitCastle(int obj, int heroID){};
void showCompInfo(ShowInInfobox * comp) OVERRIDE {};
void heroVisitCastle(int obj, int heroID) OVERRIDE {};
void stopHeroVisitCastle(int obj, int heroID) OVERRIDE {};
//void giveHeroArtifact(int artid, int hid, int position){};
//void giveNewArtifact(int hid, int position){};
bool removeArtifact(const CArtifact* art, int hid){return false;};
void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool creatureBank = false, boost::function<void(BattleResult*)> cb = 0, const CGTownInstance *town = NULL){}; //use hero=NULL for no hero
void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, boost::function<void(BattleResult*)> cb = 0, bool creatureBank = false){}; //if any of armies is hero, hero will be used
void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, boost::function<void(BattleResult*)> cb = 0, bool creatureBank = false){}; //if any of armies is hero, hero will be used, visitable tile of second obj is place of battle
void setAmount(int objid, ui32 val){};
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){};
void giveHero(int id, int player){};
void changeObjPos(int objid, int3 newPos, ui8 flags){};
void sendAndApply(CPackForClient * info){};
void heroExchange(si32 hero1, si32 hero2){};
void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool creatureBank = false, boost::function<void(BattleResult*)> cb = 0, const CGTownInstance *town = NULL) OVERRIDE {}; //use hero=NULL for no hero
void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, boost::function<void(BattleResult*)> cb = 0, bool creatureBank = false) OVERRIDE {}; //if any of armies is hero, hero will be used
void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, boost::function<void(BattleResult*)> cb = 0, bool creatureBank = false) OVERRIDE {}; //if any of armies is hero, hero will be used, visitable tile of second obj is place of battle
void setAmount(int objid, ui32 val) OVERRIDE {};
bool moveHero(si32 hid, int3 dst, ui8 instant, ui8 asker = 255) OVERRIDE {return false;};
void giveHeroBonus(GiveBonus * bonus) OVERRIDE {};
void setMovePoints(SetMovePoints * smp) OVERRIDE {};
void setManaPoints(int hid, int val) OVERRIDE {};
void giveHero(int id, int player) OVERRIDE {};
void changeObjPos(int objid, int3 newPos, ui8 flags) OVERRIDE {};
void sendAndApply(CPackForClient * info) OVERRIDE {};
void heroExchange(si32 hero1, si32 hero2) OVERRIDE {};
//////////////////////////////////////////////////////////////////////////
friend class CCallback; //handling players actions

View File

@ -363,6 +363,7 @@ enum EAlignment
#define DLL_EXPORT DLL_F_IMPORT
#endif
template<typename T, size_t N> char (&_ArrayCountObj(const T (&)[N]))[N];
#define ARRAY_COUNT(arr) (sizeof(_ArrayCountObj(arr)))

12
int3.h
View File

@ -82,6 +82,7 @@ public:
{
h & x & y & z;
}
};
inline std::istream & operator>>(std::istream & str, int3 & dest)
{
@ -93,4 +94,15 @@ inline std::ostream & operator<<(std::ostream & str, const int3 & sth)
return str<<sth.x<<' '<<sth.y<<' '<<sth.z;
}
struct ShashInt3
{
size_t operator()(int3 const& pos) const
{
size_t ret = ::boost::hash<int>()(pos.x);
boost::hash_combine(ret, pos.y);
boost::hash_combine(ret, pos.z);
return ret;
}
};
#endif // __INT3_H__

View File

@ -1335,7 +1335,7 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
{
if( !vstd::contains(k->second.players, obj->tempOwner)) continue; //not a flagged object
std::set<int3> tiles;
boost::unordered_set<int3, ShashInt3> tiles;
obj->getSightTiles(tiles);
BOOST_FOREACH(int3 tile, tiles)
{

View File

@ -435,7 +435,7 @@ int CGObjectInstance::getSightRadious() const
{
return 3;
}
void CGObjectInstance::getSightTiles(std::set<int3> &tiles) const //returns reference to the set
void CGObjectInstance::getSightTiles(boost::unordered_set<int3, ShashInt3> &tiles) const //returns reference to the set
{
cb->getTilesInRange(tiles, getSightCenter(), getSightRadious(), tempOwner, 1);
}

View File

@ -13,6 +13,7 @@
#endif
#include "../lib/CCreatureSet.h"
#include "../lib/ConstTransitivePtr.h"
#include <boost/unordered_set.hpp>
/*
* CObjectHandler.h, part of VCMI engine
@ -157,7 +158,7 @@ public:
virtual ui8 getPassableness() const; //bitmap - if the bit is set the corresponding player can pass through the visitable tiles of object, even if it's blockvis; if not set - default properties from definfo are used
virtual int3 getSightCenter() const; //"center" tile from which the sight distance is calculated
virtual int getSightRadious() const; //sight distance (should be used if player-owned structure)
void getSightTiles(std::set<int3> &tiles) const; //returns reference to the set
void getSightTiles(boost::unordered_set<int3, ShashInt3> &tiles) const; //returns reference to the set
int getOwner() const;
void setOwner(int ow);
int getWidth() const; //returns width of object graphic in tiles

View File

@ -16,6 +16,7 @@
#include <boost/type_traits/is_array.hpp>
#include <boost/type_traits/remove_pointer.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/unordered_set.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/equal_to.hpp>
@ -520,6 +521,15 @@ public:
for(typename std::set<T>::iterator i=d.begin();i!=d.end();i++)
*this << *i;
}
template <typename T, typename U>
void saveSerializable(const boost::unordered_set<T, U> &data)
{
boost::unordered_set<T, U> &d = const_cast<boost::unordered_set<T, U> &>(data);
boost::uint32_t length = d.size();
*this << length;
for(typename boost::unordered_set<T, U>::iterator i=d.begin();i!=d.end();i++)
*this << *i;
}
template <typename T>
void saveSerializable(const std::list<T> &data)
{
@ -780,6 +790,17 @@ public:
data.insert(ins);
}
}
template <typename T, typename U>
void loadSerializable(boost::unordered_set<T, U> &data)
{
READ_CHECK_U32(length);
T ins;
for(ui32 i=0;i<length;i++)
{
*this >> ins;
data.insert(ins);
}
}
template <typename T>
void loadSerializable(std::list<T> &data)
{

View File

@ -96,7 +96,7 @@ int IGameCallback::getHeroCount( int player, bool includeGarrisoned )
return ret;
}
void IGameCallback::getTilesInRange( std::set<int3> &tiles, int3 pos, int radious, int player/*=-1*/, int mode/*=0*/ )
void IGameCallback::getTilesInRange( boost::unordered_set<int3, ShashInt3> &tiles, int3 pos, int radious, int player/*=-1*/, int mode/*=0*/ )
{
if(player >= PLAYER_LIMIT)
{
@ -126,7 +126,7 @@ void IGameCallback::getTilesInRange( std::set<int3> &tiles, int3 pos, int radiou
}
}
void IGameCallback::getAllTiles (std::set<int3> &tiles, int player/*=-1*/, int level, int surface )
void IGameCallback::getAllTiles (boost::unordered_set<int3, ShashInt3> &tiles, int player/*=-1*/, int level, int surface )
{
if(player >= PLAYER_LIMIT)
{

View File

@ -60,8 +60,8 @@ public:
virtual int getSelectedHero()=0;
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 void getAllTiles (std::set<int3> &tiles, int player=-1, int level=-1, int surface=0); //returns all tiles on given level (-1 - both levels, otherwise number of level); surface: 0 - land and water, 1 - only land, 2 - only water
virtual void getTilesInRange(boost::unordered_set<int3, ShashInt3> &tiles, int3 pos, int radious, int player=-1, int mode=0); //mode 1 - only unrevealed tiles; mode 0 - all, mode -1 - only unrevealed
virtual void getAllTiles (boost::unordered_set<int3, ShashInt3> &tiles, int player=-1, int level=-1, int surface=0); //returns all tiles on given level (-1 - both levels, otherwise number of level); surface: 0 - land and water, 1 - only land, 2 - only water
virtual void getFreeTiles (std::vector<int3> &tiles); //used for random spawns
virtual bool isAllowed(int type, int id); //type: 0 - spell; 1- artifact; 2 - secondary skill
virtual ui16 getRandomArt (int flags);

View File

@ -1,5 +1,6 @@
#ifndef __NETPACKS_H__
#define __NETPACKS_H__
#include <boost/unordered_set.hpp>
#include "../global.h"
#include "BattleAction.h"
#include "HeroBonus.h"
@ -8,6 +9,7 @@
#include "CMapInfo.h"
#include "../StartInfo.h"
#include "ConstTransitivePtr.h"
#include "../int3.h"
/*
* NetPacks.h, part of VCMI engine
@ -330,7 +332,8 @@ struct SetMana : public CPackForClient //110
{
h & val & hid;
}
};
};
struct SetMovePoints : public CPackForClient //111
{
SetMovePoints(){type = 111;};
@ -343,14 +346,15 @@ struct SetMovePoints : public CPackForClient //111
{
h & val & hid;
}
};
};
struct FoWChange : public CPackForClient //112
{
FoWChange(){type = 112;};
void applyCl(CClient *cl);
DLL_EXPORT void applyGs(CGameState *gs);
std::set<int3> tiles;
boost::unordered_set<int3, struct ShashInt3 > tiles;
ui8 player, mode; //mode==0 - hide, mode==1 - reveal
template <typename Handler> void serialize(Handler &h, const int version)
{
@ -521,7 +525,7 @@ struct TryMoveHero : public CPackForClient //501
ui32 id, movePoints;
ui8 result; //uses EResult
int3 start, end; //h3m format
std::set<int3> fowRevealed; //revealed tiles
boost::unordered_set<int3, ShashInt3> fowRevealed; //revealed tiles
int3 attackedFrom; // Set when stepping into endangered tile.
bool humanKnows; //used locally during applying to client

View File

@ -150,7 +150,7 @@ DLL_EXPORT void FoWChange::applyGs( CGameState *gs )
team->fogOfWarMap[t.x][t.y][t.z] = mode;
if (mode == 0) //do not hide too much
{
std::set<int3> tilesRevealed;
boost::unordered_set<int3, ShashInt3> tilesRevealed;
for (size_t i = 0; i < gs->map->objects.size(); i++)
{
if (gs->map->objects[i])

View File

@ -1,4 +1,5 @@
#include "stdafx.h"
#include "../int3.h"
#include "../lib/CCampaignHandler.h"
#include "../StartInfo.h"
#include "../lib/CArtHandler.h"
@ -3405,11 +3406,15 @@ void CGameHandler::playerMessage( ui8 player, const std::string &message )
FoWChange fc;
fc.mode = 1;
fc.player = player;
int3 * hlp_tab = new int3[gs->map->width * gs->map->height * (gs->map->twoLevel + 1)];
int lastUnc = 0;
for(int i=0;i<gs->map->width;i++)
for(int j=0;j<gs->map->height;j++)
for(int k=0;k<gs->map->twoLevel+1;k++)
if(!gs->getPlayerTeam(fc.player)->fogOfWarMap[i][j][k])
fc.tiles.insert(int3(i,j,k));
hlp_tab[lastUnc++] = int3(i,j,k);
fc.tiles.insert(hlp_tab, hlp_tab + lastUnc);
delete [] hlp_tab;
sendAndApply(&fc);
}
else if(message == "vcmiglorfindel") //selected hero gains a new level