소스 검색

Adjusted player interface to new set of stack operations.
Const transitive ptr.

Michał W. Urbańczyk 15 년 전
부모
커밋
e301256f92
9개의 변경된 파일178개의 추가작업 그리고 77개의 파일을 삭제
  1. 16 1
      CGameInterface.h
  2. 34 0
      client/CPlayerInterface.cpp
  3. 64 58
      client/CPlayerInterface.h
  4. 10 10
      client/NetPacksClient.cpp
  5. 5 0
      global.h
  6. 0 6
      lib/CCreatureSet.h
  7. 36 0
      lib/ConstTransitivePtr.h
  8. 3 2
      lib/NetPacks.h
  9. 10 0
      lib/NetPacksLib.cpp

+ 16 - 1
CGameInterface.h

@@ -42,8 +42,12 @@ struct PackageApplied;
 struct SetObjectProperty;
 struct CatapultAttack;
 struct BattleStacksRemoved;
+struct StackLocation;
+class CStackInstance;
+class CCreature;
 class CLoadFile;
 class CSaveFile;
+typedef TQuantity;
 template <typename Serializer> class CISer;
 template <typename Serializer> class COSer;
 
@@ -56,8 +60,19 @@ public:
 
 	virtual ~CGameInterface() {};
 	virtual void buildChanged(const CGTownInstance *town, int buildingID, int what){}; //what: 1 - built, 2 - demolished
-	virtual void garrisonChanged(const CGObjectInstance * obj){};
+
+	//garrison operations
+	virtual void stackChagedCount(const StackLocation &location, const TQuantity &change, bool isAbsolute){}; //if absolute, change is the new count; otherwise count was modified by adding change
+	virtual void stackChangedType(const StackLocation &location, const CCreature &newType){}; //used eg. when upgrading creatures
+	virtual void stacksErased(const StackLocation &location){}; //stack removed from previously filled slot
+	virtual void stacksSwapped(const StackLocation &loc1, const StackLocation &loc2){};
+	virtual void newStackInserted(const StackLocation &location, const CStackInstance &stack){}; //new stack inserted at given (previously empty position)
+	virtual void stacksRebalanced(const StackLocation &src, const StackLocation &dst, TQuantity count){}; //moves creatures from src stack to dst slot, may be used for merging/splittint/moving stacks
+	//virtual void garrisonChanged(const CGObjectInstance * obj){};
+
+	//artifacts operations
 	virtual void heroArtifactSetChanged(const CGHeroInstance*hero){};
+
 	virtual void heroCreated(const CGHeroInstance*){};
 	virtual void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback)=0; //pskill is gained primary skill, interface has to choose one of given skills and call callback with selection id
 	virtual void heroInGarrisonChange(const CGTownInstance *town){};

+ 34 - 0
client/CPlayerInterface.cpp

@@ -2106,6 +2106,40 @@ void CPlayerInterface::sendCustomEvent( int code )
 	SDL_PushEvent(&event);
 }
 
+void CPlayerInterface::stackChagedCount(const StackLocation &location, const TQuantity &change, bool isAbsolute)
+{
+	garrisonChanged(location.army);
+}
+
+void CPlayerInterface::stackChangedType(const StackLocation &location, const CCreature &newType)
+{
+	garrisonChanged(location.army);
+}
+
+void CPlayerInterface::stacksErased(const StackLocation &location)
+{
+	garrisonChanged(location.army);
+}
+
+void CPlayerInterface::stacksSwapped(const StackLocation &loc1, const StackLocation &loc2)
+{
+	garrisonChanged(loc1.army);
+	if(loc2.army != loc1.army)
+		garrisonChanged(loc2.army);
+}
+
+void CPlayerInterface::newStackInserted(const StackLocation &location, const CStackInstance &stack)
+{
+	garrisonChanged(location.army);
+}
+
+void CPlayerInterface::stacksRebalanced(const StackLocation &src, const StackLocation &dst, TQuantity count)
+{
+	garrisonChanged(src.army);
+	if(dst.army != src.army)
+		garrisonChanged(dst.army);
+}
+
 CPlayerInterface::SpellbookLastSetting::SpellbookLastSetting()
 {
 	spellbookLastPageBattle = spellbokLastPageAdvmap = 0;

+ 64 - 58
client/CPlayerInterface.h

@@ -157,69 +157,75 @@ public:
 	int getLastIndex(std::string namePrefix);
 
 	//overloaded funcs from CGameInterface
-	void buildChanged(const CGTownInstance *town, int buildingID, int what); //what: 1 - built, 2 - demolished
-	void garrisonChanged(const CGObjectInstance * obj);
-	void heroArtifactSetChanged(const CGHeroInstance* hero);
-	void heroCreated(const CGHeroInstance* hero);
-	void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback);
-	void heroInGarrisonChange(const CGTownInstance *town);
-	void heroMoved(const TryMoveHero & details);
-	void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, si64 val);
-	void heroSecondarySkillChanged(const CGHeroInstance * hero, int which, int val);
-	void heroManaPointsChanged(const CGHeroInstance * hero);
-	void heroMovePointsChanged(const CGHeroInstance * hero);
-	void heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town);
-	void receivedResource(int type, int val);
-	void showInfoDialog(const std::string &text, const std::vector<Component*> &components, int soundID);
-	void showRecruitmentDialog(const CGDwelling *dwelling, const CArmedInstance *dst, int level);
-	void showShipyardDialog(const IShipyard *obj); //obj may be town or shipyard; 
-	void showBlockingDialog(const std::string &text, const std::vector<Component> &components, ui32 askID, int soundID, bool selection, bool cancel); //Show a dialog, player must take decision. If selection then he has to choose between one of given components, if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called with number of selected component (1 - n) or 0 for cancel (if allowed) and askID.
-	void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, boost::function<void()> &onEnd);
-	void showArtifactAssemblyDialog(ui32 artifactID, ui32 assembleTo, bool assemble, CFunctionList<void()> onYes, CFunctionList<void()> onNo);
-	void showPuzzleMap();
-	void showMarketWindow(const IMarket *market, const CGHeroInstance *visitor);
-	void showUniversityWindow(const IMarket *market, const CGHeroInstance *visitor);
-	void showHillFortWindow(const CGObjectInstance *object, const CGHeroInstance *visitor);
-	void showTavernWindow(const CGObjectInstance *townOrTavern);
-	void advmapSpellCast(const CGHeroInstance * caster, int spellID); //called when a hero casts a spell
-	void tileHidden(const std::set<int3> &pos); //called when given tiles become hidden under fog of war
-	void tileRevealed(const std::set<int3> &pos); //called when fog of war disappears from given tiles
-	void newObject(const CGObjectInstance * obj);
-	void availableArtifactsChanged(const CGBlackMarket *bm = NULL); //bm may be NULL, then artifacts are changed in the global pool (used by merchants in towns)
-	void yourTurn();
-	void availableCreaturesChanged(const CGDwelling *town);
-	void heroBonusChanged(const CGHeroInstance *hero, const Bonus &bonus, bool gain);//if gain hero received bonus, else he lost it
-	void playerBonusChanged(const Bonus &bonus, bool gain);
-	void requestRealized(PackageApplied *pa);
-	void heroExchangeStarted(si32 hero1, si32 hero2);
-	void centerView (int3 pos, int focusTime);
-	void objectPropertyChanged(const SetObjectProperty * sop);
-	void objectRemoved(const CGObjectInstance *obj);
-	void gameOver(ui8 player, bool victory);
-	void serialize(COSer<CSaveFile> &h, const int version); //saving
-	void serialize(CISer<CLoadFile> &h, const int version); //loading
+	void buildChanged(const CGTownInstance *town, int buildingID, int what) OVERRIDE; //what: 1 - built, 2 - demolished
+	void stackChagedCount(const StackLocation &location, const TQuantity &change, bool isAbsolute) OVERRIDE; //if absolute, change is the new count; otherwise count was modified by adding change
+	void stackChangedType(const StackLocation &location, const CCreature &newType) OVERRIDE; //used eg. when upgrading creatures
+	void stacksErased(const StackLocation &location) OVERRIDE; //stack removed from previously filled slot
+	void stacksSwapped(const StackLocation &loc1, const StackLocation &loc2) OVERRIDE;
+	void newStackInserted(const StackLocation &location, const CStackInstance &stack) OVERRIDE; //new stack inserted at given (previously empty position)
+	void stacksRebalanced(const StackLocation &src, const StackLocation &dst, TQuantity count) OVERRIDE; //moves creatures from src stack to dst slot, may be used for merging/splittint/moving stacks
+	void heroArtifactSetChanged(const CGHeroInstance* hero) OVERRIDE;
+	void heroCreated(const CGHeroInstance* hero) OVERRIDE;
+	void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback) OVERRIDE;
+	void heroInGarrisonChange(const CGTownInstance *town) OVERRIDE;
+	void heroMoved(const TryMoveHero & details) OVERRIDE;
+	void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, si64 val) OVERRIDE;
+	void heroSecondarySkillChanged(const CGHeroInstance * hero, int which, int val) OVERRIDE;
+	void heroManaPointsChanged(const CGHeroInstance * hero) OVERRIDE;
+	void heroMovePointsChanged(const CGHeroInstance * hero) OVERRIDE;
+	void heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town) OVERRIDE;
+	void receivedResource(int type, int val) OVERRIDE;
+	void showInfoDialog(const std::string &text, const std::vector<Component*> &components, int soundID) OVERRIDE;
+	void showRecruitmentDialog(const CGDwelling *dwelling, const CArmedInstance *dst, int level) OVERRIDE;
+	void showShipyardDialog(const IShipyard *obj) OVERRIDE; //obj may be town or shipyard; 
+	void showBlockingDialog(const std::string &text, const std::vector<Component> &components, ui32 askID, int soundID, bool selection, bool cancel) OVERRIDE; //Show a dialog, player must take decision. If selection then he has to choose between one of given components, if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called with number of selected component (1 - n) or 0 for cancel (if allowed) and askID.
+	void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, boost::function<void()> &onEnd) OVERRIDE;
+	void showPuzzleMap() OVERRIDE;
+	void showMarketWindow(const IMarket *market, const CGHeroInstance *visitor) OVERRIDE;
+	void showUniversityWindow(const IMarket *market, const CGHeroInstance *visitor) OVERRIDE;
+	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 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;
+	void availableCreaturesChanged(const CGDwelling *town) OVERRIDE;
+	void heroBonusChanged(const CGHeroInstance *hero, const Bonus &bonus, bool gain) OVERRIDE;//if gain hero received bonus, else he lost it
+	void playerBonusChanged(const Bonus &bonus, bool gain) OVERRIDE;
+	void requestRealized(PackageApplied *pa) OVERRIDE;
+	void heroExchangeStarted(si32 hero1, si32 hero2) OVERRIDE;
+	void centerView (int3 pos, int focusTime) OVERRIDE;
+	void objectPropertyChanged(const SetObjectProperty * sop) OVERRIDE;
+	void objectRemoved(const CGObjectInstance *obj) OVERRIDE;
+	void gameOver(ui8 player, bool victory) OVERRIDE;
+	void serialize(COSer<CSaveFile> &h, const int version) OVERRIDE; //saving
+	void serialize(CISer<CLoadFile> &h, const int version) OVERRIDE; //loading
 
 	//for battles
-	void actionFinished(const BattleAction* action);//occurs AFTER action taken by active stack or by the hero
-	void actionStarted(const BattleAction* action);//occurs BEFORE action taken by active stack or by the hero
-	BattleAction activeStack(int stackID); //called when it's turn of that stack
-	void battleAttack(const BattleAttack *ba); //stack performs attack
-	void battleEnd(const BattleResult *br); //end of battle
+	void actionFinished(const BattleAction* action) OVERRIDE;//occurs AFTER action taken by active stack or by the hero
+	void actionStarted(const BattleAction* action) OVERRIDE;//occurs BEFORE action taken by active stack or by the hero
+	BattleAction activeStack(int stackID) OVERRIDE; //called when it's turn of that stack
+	void battleAttack(const BattleAttack *ba) OVERRIDE; //stack performs attack
+	void battleEnd(const BattleResult *br) OVERRIDE; //end of battle
 	//void battleResultQuited();
-	void battleNewRoundFirst(int round); //called at the beginning of each turn before changes are applied; used for HP regen handling
-	void battleNewRound(int round); //called at the beggining of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn
-	void battleStackMoved(int ID, int dest, int distance, bool end);
-	void battleSpellCast(const BattleSpellCast *sc);
-	void battleStacksEffectsSet(const SetStackEffect & sse); //called when a specific effect is set to stacks
-	void battleStacksAttacked(const std::vector<BattleStackAttacked> & bsa);
-	void battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side); //called by engine when battle starts; side=0 - left, side=1 - right
-	void battleStacksHealedRes(const std::vector<std::pair<ui32, ui32> > & healedStacks, bool lifeDrain, si32 lifeDrainFrom); //called when stacks are healed / resurrected
-	void battleNewStackAppeared(int stackID); //not called at the beginning of a battle or by resurrection; called eg. when elemental is summoned
-	void battleObstaclesRemoved(const std::set<si32> & removedObstacles); //called when a certain set  of obstacles is removed from batlefield; IDs of them are given
-	void battleCatapultAttacked(const CatapultAttack & ca); //called when catapult makes an attack
-	void battleStacksRemoved(const BattleStacksRemoved & bsr); //called when certain stack is completely removed from battlefield
+	void battleNewRoundFirst(int round) OVERRIDE; //called at the beginning of each turn before changes are applied; used for HP regen handling
+	void battleNewRound(int round) OVERRIDE; //called at the beggining of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn
+	void battleStackMoved(int ID, int dest, int distance, bool end) OVERRIDE;
+	void battleSpellCast(const BattleSpellCast *sc) OVERRIDE;
+	void battleStacksEffectsSet(const SetStackEffect & sse) OVERRIDE; //called when a specific effect is set to stacks
+	void battleStacksAttacked(const std::vector<BattleStackAttacked> & bsa) OVERRIDE;
+	void battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side) OVERRIDE; //called by engine when battle starts; side=0 - left, side=1 - right
+	void battleStacksHealedRes(const std::vector<std::pair<ui32, ui32> > & healedStacks, bool lifeDrain, si32 lifeDrainFrom) OVERRIDE; //called when stacks are healed / resurrected
+	void battleNewStackAppeared(int stackID) OVERRIDE; //not called at the beginning of a battle or by resurrection; called eg. when elemental is summoned
+	void battleObstaclesRemoved(const std::set<si32> & removedObstacles) OVERRIDE; //called when a certain set  of obstacles is removed from batlefield; IDs of them are given
+	void battleCatapultAttacked(const CatapultAttack & ca) OVERRIDE; //called when catapult makes an attack
+	void battleStacksRemoved(const BattleStacksRemoved & bsr) OVERRIDE; //called when certain stack is completely removed from battlefield
 
 	//-------------//
+	void showArtifactAssemblyDialog(ui32 artifactID, ui32 assembleTo, bool assemble, CFunctionList<void()> onYes, CFunctionList<void()> onNo);
+	void garrisonChanged(const CGObjectInstance * obj);
 	void heroKilled(const CGHeroInstance* hero);
 	void waitWhileDialog();
 	bool shiftPressed() const; //determines if shift key is pressed (left or right or both)

+ 10 - 10
client/NetPacksClient.cpp

@@ -124,36 +124,36 @@ void SetAvailableHeroes::applyCl( CClient *cl )
 
 void ChangeStackCount::applyCl( CClient *cl )
 {
-	INTERFACE_CALL_IF_PRESENT(sl.army->tempOwner,garrisonChanged,sl.army);
+	INTERFACE_CALL_IF_PRESENT(sl.army->tempOwner,stackChagedCount, sl, count, absoluteValue);
 }
 
 void SetStackType::applyCl( CClient *cl )
 {
-	INTERFACE_CALL_IF_PRESENT(sl.army->tempOwner,garrisonChanged,sl.army);
+	INTERFACE_CALL_IF_PRESENT(sl.army->tempOwner,stackChangedType,sl, *type);
 }
 
 void EraseStack::applyCl( CClient *cl )
 {
-	INTERFACE_CALL_IF_PRESENT(sl.army->tempOwner,garrisonChanged,sl.army);
+	INTERFACE_CALL_IF_PRESENT(sl.army->tempOwner,stacksErased,sl);
 }
 
 void SwapStacks::applyCl( CClient *cl )
 {
-	INTERFACE_CALL_IF_PRESENT(sl1.army->tempOwner,garrisonChanged,sl1.army);
-	if(sl1.army != sl2.army)
-		INTERFACE_CALL_IF_PRESENT(sl2.army->tempOwner,garrisonChanged,sl2.army);
+	INTERFACE_CALL_IF_PRESENT(sl1.army->tempOwner,stacksSwapped, sl1, sl2);
+	if(sl1.army->tempOwner != sl2.army->tempOwner)
+		INTERFACE_CALL_IF_PRESENT(sl2.army->tempOwner,stacksSwapped, sl1, sl2);
 }
 
 void InsertNewStack::applyCl( CClient *cl )
 {
-	INTERFACE_CALL_IF_PRESENT(sl.army->tempOwner,garrisonChanged,sl.army);
+	INTERFACE_CALL_IF_PRESENT(sl.army->tempOwner,newStackInserted,sl, *sl.getStack());
 }
 
 void RebalanceStacks::applyCl( CClient *cl )
 {
-	INTERFACE_CALL_IF_PRESENT(src.army->tempOwner,garrisonChanged,src.army);
-	if(src.army != dst.army)
-		INTERFACE_CALL_IF_PRESENT(dst.army->tempOwner,garrisonChanged,dst.army);
+	INTERFACE_CALL_IF_PRESENT(src.army->tempOwner, stacksRebalanced, src, dst, count);
+	if(src.army->tempOwner != dst.army->tempOwner)
+		INTERFACE_CALL_IF_PRESENT(dst.army->tempOwner,stacksRebalanced, src, dst, count);
 }
 
 void GiveBonus::applyCl( CClient *cl )

+ 5 - 0
global.h

@@ -80,6 +80,11 @@ enum ECombatInfo{ALIVE = 180, SUMMONED, CLONED, HAD_MORALE, WAITING, MOVED, DEFE
 class CGameInfo;
 extern CGameInfo* CGI; //game info for general use
 
+//a few typedefs for CCreatureSet
+typedef si32 TSlot;
+typedef si32 TQuantity; 
+typedef ui32 TCreature; //creature id
+const int ARMY_SIZE = 7;
 
 const int HEROI_TYPE = 34, 
 	TOWNI_TYPE = 98,

+ 0 - 6
lib/CCreatureSet.h

@@ -9,12 +9,6 @@ class CCreature;
 class CGHeroInstance;
 class CArmedInstance;
 
-//a few typedefs for CCreatureSet
-typedef si32 TSlot;
-typedef si32 TQuantity; 
-typedef ui32 TCreature; //creature id
-
-const int ARMY_SIZE = 7;
 
 class DLL_EXPORT CStackBasicDescriptor
 {

+ 36 - 0
lib/ConstTransitivePtr.h

@@ -0,0 +1,36 @@
+#pragma once
+
+template <typename T>
+class ConstTransitivePtr
+{
+	T *ptr;
+public:
+	ConstTransitivePtr() 
+		: ptr(NULL)
+	{}
+	ConstTransitivePtr(T *Ptr)
+		: ptr(Ptr) 
+	{}
+
+	operator const T*() const
+	{
+		return ptr;
+	}
+	operator T*() 
+	{
+		return ptr;
+	}
+	T *operator->() 
+	{
+		return ptr;
+	}
+	const T *operator->() const 
+	{
+		return ptr;
+	}
+
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & ptr;
+	}
+};

+ 3 - 2
lib/NetPacks.h

@@ -8,6 +8,7 @@
 #include "CCreatureSet.h"
 #include "CMapInfo.h"
 #include "../StartInfo.h"
+#include "ConstTransitivePtr.h"
 
 /*
  * NetPacks.h, part of VCMI engine
@@ -717,7 +718,7 @@ struct NewArtifact : public CPackForClient
 
 struct StackLocation
 {
-	CArmedInstance *army;
+	ConstTransitivePtr<CArmedInstance> army;
 	TSlot slot;
 
 	StackLocation()
@@ -730,7 +731,7 @@ struct StackLocation
 		army = const_cast<CArmedInstance*>(Army); //we are allowed here to const cast -> change will go through one of our packages... do not abuse!
 		slot = Slot;
 	}
-
+	DLL_EXPORT const CStackInstance *getStack();
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
 		h & army & slot;

+ 10 - 0
lib/NetPacksLib.cpp

@@ -605,6 +605,16 @@ DLL_EXPORT void NewArtifact::applyGs( CGameState *gs )
 	gs->map->artInstances.push_back(art);
 }
 
+DLL_EXPORT const CStackInstance * StackLocation::getStack()
+{
+	if(!army->hasStackAtSlot(slot))
+	{
+		tlog2 << "Warning: " << army->nodeName() << " dont have a stack at slot " << slot << std::endl;
+		return NULL;
+	}
+	return &army->getStack(slot);
+}
+
 DLL_EXPORT void ChangeStackCount::applyGs( CGameState *gs )
 {
 	if(absoluteValue)