Browse Source

Fix dynamic_cast on MacOSX in CQuery.cpp

Vadim Markovtsev 10 years ago
parent
commit
68cc860133
3 changed files with 85 additions and 68 deletions
  1. 45 47
      server/CGameHandler.cpp
  2. 26 21
      server/CQuery.cpp
  3. 14 0
      server/StdInc.h

+ 45 - 47
server/CGameHandler.cpp

@@ -65,14 +65,14 @@ class ServerSpellCastEnvironment: public SpellCastEnvironment
 public:
 	ServerSpellCastEnvironment(CGameHandler * gh);
 	~ServerSpellCastEnvironment(){};
-	void sendAndApply(CPackForClient * info) const override;	
+	void sendAndApply(CPackForClient * info) const override;
 	CRandomGenerator & getRandomGenerator() const override;
 	void complain(const std::string & problem) const override;
 	const CMap * getMap() const override;
 	const CGameInfoCallback * getCb() const override;
-	bool moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, PlayerColor asker = PlayerColor::NEUTRAL) const override;	
+	bool moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, PlayerColor asker = PlayerColor::NEUTRAL) const override;
 private:
-	mutable CGameHandler * gh;	
+	mutable CGameHandler * gh;
 };
 
 CondSh<bool> battleMadeAction;
@@ -102,7 +102,7 @@ public:
 	}
 };
 
-template <> 
+template <>
 class CApplyOnGH<CPack> : public CBaseForGHApply
 {
 public:
@@ -799,15 +799,15 @@ void CGameHandler::prepareAttack(BattleAttack &bat, const CStack *att, const CSt
 
 	const Bonus * bonus = att->getBonusLocalFirst(Selector::type(Bonus::SPELL_LIKE_ATTACK));
 	if (bonus && (bat.shot())) //TODO: make it work in melee?
-	{	
+	{
 		//this is need for displaying hit animation
 		bat.flags |= BattleAttack::SPELL_LIKE;
 		bat.spellID = SpellID(bonus->subtype);
-		
+
 		//TODO: should spell override creature`s projectile?
-		
+
 		std::set<const CStack*> attackedCreatures = SpellID(bonus->subtype).toSpell()->getAffectedStacks(gs->curB, ECastingMode::SPELL_LIKE_ATTACK, att->owner, bonus->val, targetHex, att);
-	
+
 		//TODO: get exact attacked hex for defender
 
 		for(const CStack * stack : attackedCreatures)
@@ -817,7 +817,7 @@ void CGameHandler::prepareAttack(BattleAttack &bat, const CStack *att, const CSt
 				applyBattleEffects(bat, att, stack, distance, true);
 			}
 		}
-		
+
 		//now add effect info for all attacked stacks
 		for(BattleStackAttacked & bsa : bat.bsa)
 		{
@@ -828,7 +828,7 @@ void CGameHandler::prepareAttack(BattleAttack &bat, const CStack *att, const CSt
 				bsa.spellID = SpellID(bonus->subtype);
 			}
 		}
-		
+
 	}
 }
 void CGameHandler::applyBattleEffects(BattleAttack &bat, const CStack *att, const CStack *def, int distance, bool secondary) //helper function for prepareAttack
@@ -917,7 +917,7 @@ void CGameHandler::handleConnection(std::set<PlayerColor> players, CConnection &
 				c << &applied;
 			};
 
-			CBaseForGHApply *apply = applier->apps[packType]; //and appropriae applier object
+			CBaseForGHApply *apply = applier->apps[packType]; //and appropriate applier object
 			if(isBlockedByQueries(pack, player))
 			{
 				sendPackageResponse(false);
@@ -1026,7 +1026,7 @@ int CGameHandler::moveStack(int stack, BattleHex dest)
 		int v = path.first.size()-1;
 
 		bool stackIsMoving = true;
-		
+
 		while(stackIsMoving)
 		{
 			if(v<tilesToMove)
@@ -1079,10 +1079,10 @@ int CGameHandler::moveStack(int stack, BattleHex dest)
 						if(obs->stopsMovement() || !curStack->alive())
 							stackIsMoving = false;
 
-						obs.reset();						
+						obs.reset();
 					}
 				};
-				
+
 				processObstacle(obstacle);
 				if(curStack->alive())
 					processObstacle(obstacle2);
@@ -1105,14 +1105,14 @@ int CGameHandler::moveStack(int stack, BattleHex dest)
 	if(curStack->alive() && curStack->doubleWide())
 	{
 		BattleHex otherHex = curStack->occupiedHex(curStack->position);
-		
+
 		if(otherHex.isValid())
 			if(auto theLastObstacle = battleGetObstacleOnPos(otherHex, false))
 			{
 				//two hex creature hit obstacle by backside
 				handleDamageFromObstacle(*theLastObstacle, curStack);
 			}
-	}	
+	}
 	return ret;
 }
 
@@ -1125,7 +1125,7 @@ CGameHandler::CGameHandler(void)
 	registerTypesServerPacks(*applier);
 	visitObjectAfterVictory = false;
 	queries.gh = this;
-	
+
 	spellEnv = new ServerSpellCastEnvironment(this);
 }
 
@@ -3907,8 +3907,8 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
 				complain("That stack can't cast spells!");
 			else
 			{
-				const CSpell * spell = SpellID(spellID).toSpell();				
-				BattleSpellCastParameters parameters(gs->curB, stack, spell);				
+				const CSpell * spell = SpellID(spellID).toSpell();
+				BattleSpellCastParameters parameters(gs->curB, stack, spell);
 				parameters.spellLvl = 0;
 				if (spellcaster)
 					vstd::amax(parameters.spellLvl, spellcaster->val);
@@ -3940,12 +3940,12 @@ void CGameHandler::playerMessage( PlayerColor player, const std::string &message
 	{
 		SetMana sm;
 		GiveBonus giveBonus(GiveBonus::HERO);
-		
+
 		CGHeroInstance *h = gs->getHero(currObj);
 		if(!h && complain("Cannot realize cheat, no hero selected!")) return;
 
 		sm.hid = h->id;
-		
+
 		giveBonus.id = h->id.getNum();
 
 		//give all spells with bonus (to allow banned spells)
@@ -4107,11 +4107,11 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
 			}
 
 			const CSpell * s = SpellID(ba.additionalInfo).toSpell();
-			
+
 			BattleSpellCastParameters parameters(gs->curB, h, s);
 			parameters.aimToHex(ba.destinationTile);//todo: allow multiple destinations
 			parameters.mode = ECastingMode::HERO_CASTING;
-			parameters.selectedStack = gs->curB->battleGetStackByID(ba.selectedStack, false);			
+			parameters.selectedStack = gs->curB->battleGetStackByID(ba.selectedStack, false);
 
 			ESpellCastProblem::ESpellCastProblem escp = gs->curB->battleCanCastThisSpell(h, s, ECastingMode::HERO_CASTING);//todo: should we check aimed cast(battleCanCastThisSpellHere)?
 			if(escp != ESpellCastProblem::OK)
@@ -4123,9 +4123,9 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
 
 			StartAction start_action(ba);
 			sendAndApply(&start_action); //start spell casting
-			
+
 			s->battleCast(spellEnv, parameters);
-			
+
 			sendAndApply(&end_action);
 			if( !gs->curB->battleGetStackByID(gs->curB->activeStack, true))
 			{
@@ -4255,8 +4255,8 @@ void CGameHandler::stackTurnTrigger(const CStack * st)
 				auto bonus = *RandomGeneratorUtil::nextItem(bl, gs->getRandomGenerator());
 				auto spellID = SpellID(bonus->subtype);
 				const CSpell * spell = SpellID(spellID).toSpell();
-				bl.remove_if([&bonus](Bonus * b){return b==bonus;});					
-				
+				bl.remove_if([&bonus](Bonus * b){return b==bonus;});
+
 				if (gs->curB->battleCanCastThisSpell(st, spell, ECastingMode::ENCHANTER_CASTING) == ESpellCastProblem::OK)
 				{
 					BattleSpellCastParameters parameters(gs->curB, st, spell);
@@ -4265,8 +4265,8 @@ void CGameHandler::stackTurnTrigger(const CStack * st)
 					parameters.aimToHex(BattleHex::INVALID);
 					parameters.mode = ECastingMode::ENCHANTER_CASTING;
 					parameters.selectedStack = nullptr;
-					
-					spell->battleCast(spellEnv, parameters);				
+
+					spell->battleCast(spellEnv, parameters);
 
 					//todo: move to mechanics
 					BattleSetStackProperty ssp;
@@ -4275,9 +4275,9 @@ void CGameHandler::stackTurnTrigger(const CStack * st)
 					ssp.val = bonus->additionalInfo; //increase cooldown counter
 					ssp.stackID = st->ID;
 					sendAndApply(&ssp);
-					
+
 					cast = true;
-				}				
+				}
 			};
 		}
 		bl = *(st->getBonuses(Selector::type(Bonus::ENCHANTED)));
@@ -4383,7 +4383,7 @@ void CGameHandler::handleTimeEvents()
 	while(gs->map->events.size() && gs->map->events.front().firstOccurence+1 == gs->day)
 	{
 		CMapEvent ev = gs->map->events.front();
-		
+
 		for (int player = 0; player < PlayerColor::PLAYER_LIMIT_I; player++)
 		{
 			auto color = PlayerColor(player);
@@ -4973,7 +4973,7 @@ void CGameHandler::attackCasting(const BattleAttack & bat, Bonus::BonusType atta
 				parameters.mode = ECastingMode::AFTER_ATTACK_CASTING;
 				parameters.selectedStack = nullptr;
 
-				spell->battleCast(spellEnv, parameters);			
+				spell->battleCast(spellEnv, parameters);
 			}
 		}
 	}
@@ -4990,7 +4990,7 @@ void CGameHandler::handleAfterAttackCasting( const BattleAttack & bat )
 	const CStack * attacker = gs->curB->battleGetStackByID(bat.stackAttacking);
 	if (!attacker) //could be already dead
 		return;
-	
+
 	auto cast = [=](SpellID spellID, int power)
 	{
 		const CSpell * spell = SpellID(spellID).toSpell();
@@ -4999,13 +4999,13 @@ void CGameHandler::handleAfterAttackCasting( const BattleAttack & bat )
 		parameters.spellLvl = 0;
 		parameters.effectLevel = 0;
 		parameters.aimToStack(gs->curB->battleGetStackByID(bat.bsa.at(0).stackAttacked));
-		parameters.effectPower = power;	
+		parameters.effectPower = power;
 		parameters.mode = ECastingMode::AFTER_ATTACK_CASTING;
 		parameters.selectedStack = nullptr;
 
-		spell->battleCast(this->spellEnv, parameters);		
-	};	
-	
+		spell->battleCast(this->spellEnv, parameters);
+	};
+
 	attackCasting(bat, Bonus::SPELL_AFTER_ATTACK, attacker);
 
 	if(bat.bsa.at(0).newAmount <= 0)
@@ -5056,11 +5056,11 @@ void CGameHandler::handleAfterAttackCasting( const BattleAttack & bat )
 bool CGameHandler::castSpell(const CGHeroInstance *h, SpellID spellID, const int3 &pos)
 {
 	const CSpell *s = spellID.toSpell();
-	
+
 	AdventureSpellCastParameters p;
 	p.caster = h;
 	p.pos = pos;
-	
+
 	return s->adventureCast(spellEnv, p);
 }
 
@@ -5298,8 +5298,8 @@ void CGameHandler::runBattle()
 		auto h = gs->curB->battleGetFightingHero(i);
 		if(h && h->hasBonusOfType(Bonus::OPENING_BATTLE_SPELL))
 		{
-			TBonusListPtr bl = h->getBonuses(Selector::type(Bonus::OPENING_BATTLE_SPELL));		
-			
+			TBonusListPtr bl = h->getBonuses(Selector::type(Bonus::OPENING_BATTLE_SPELL));
+
 			for (Bonus *b : *bl)
 			{
 				const CSpell * spell = SpellID(b->subtype).toSpell();
@@ -5308,7 +5308,7 @@ void CGameHandler::runBattle()
 				parameters.effectLevel = 3;
 				parameters.aimToHex(BattleHex::INVALID);
 				parameters.mode = ECastingMode::PASSIVE_CASTING;
-				parameters.selectedStack = nullptr;					
+				parameters.selectedStack = nullptr;
 				parameters.enchantPower = b->val;
 				spell->battleCast(spellEnv, parameters);
 			}
@@ -5347,7 +5347,6 @@ void CGameHandler::runBattle()
 		const CStack *next;
 		while(!battleResult.get() && (next = curB.getNextStack()) && next->willMove())
 		{
-
 			//check for bad morale => freeze
 			int nextStackMorale = next->MoraleVal();
 			if( nextStackMorale < 0 &&
@@ -5483,7 +5482,7 @@ void CGameHandler::runBattle()
 					{
                         logGlobal->traceStream() << "Activating " << next->nodeName();
                         auto nextId = next->ID;
-						BattleSetActiveStack sas;						
+						BattleSetActiveStack sas;
 						sas.stack = nextId;
 						sendAndApply(&sas);
 
@@ -5900,7 +5899,7 @@ CGameHandler::FinishingBattleHelper::FinishingBattleHelper()
 ///ServerSpellCastEnvironment
 ServerSpellCastEnvironment::ServerSpellCastEnvironment(CGameHandler * gh): gh(gh)
 {
-	
+
 }
 
 void ServerSpellCastEnvironment::sendAndApply(CPackForClient * info) const
@@ -5933,4 +5932,3 @@ bool ServerSpellCastEnvironment::moveHero(ObjectInstanceID hid, int3 dst, ui8 te
 {
 	return gh->moveHero(hid, dst, teleporting, false, asker);
 }
-

+ 26 - 21
server/CQuery.cpp

@@ -97,11 +97,11 @@ CObjectVisitQuery::CObjectVisitQuery(const CGObjectInstance *Obj, const CGHeroIn
 	addPlayer(Hero->tempOwner);
 }
 
-bool CObjectVisitQuery::blocksPack(const CPack *pack) const 
+bool CObjectVisitQuery::blocksPack(const CPack *pack) const
 {
 	//During the visit itself ALL actions are blocked.
 	//(However, the visit may trigger a query above that'll pass some.)
-	return true; 
+	return true;
 }
 
 void CObjectVisitQuery::onRemoval(CGameHandler *gh, PlayerColor color)
@@ -220,7 +220,7 @@ std::vector<shared_ptr<CQuery>> Queries::allQueries()
 	return ret;
 }
 
-void CBattleQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const 
+void CBattleQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const
 {
 	assert(result);
 	objectVisit.visitedObject->battleFinished(objectVisit.visitingHero, *result);
@@ -242,9 +242,14 @@ CBattleQuery::CBattleQuery()
 
 }
 
-bool CBattleQuery::blocksPack(const CPack *pack) const 
+bool CBattleQuery::blocksPack(const CPack *pack) const
 {
-	return !dynamic_cast<const MakeAction*>(pack) && !dynamic_cast<const MakeCustomAction*>(pack);
+	#ifndef __APPLE__
+	bool dynamic_success = !dynamic_cast<const MakeAction*>(pack) && !dynamic_cast<const MakeCustomAction*>(pack);
+	#else
+	const char * name = typeid(*pack).name();
+	return strcmp(name, typeid(MakeAction).name()) && strcmp(name, typeid(MakeCustomAction).name());
+	#endif
 }
 
 void CBattleQuery::onRemoval(CGameHandler *gh, PlayerColor color)
@@ -252,7 +257,7 @@ void CBattleQuery::onRemoval(CGameHandler *gh, PlayerColor color)
 	gh->battleAfterLevelUp(*result);
 }
 
-void CGarrisonDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const 
+void CGarrisonDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const
 {
 	objectVisit.visitedObject->garrisonDialogClosed(objectVisit.visitingHero);
 }
@@ -266,18 +271,18 @@ CGarrisonDialogQuery::CGarrisonDialogQuery(const CArmedInstance *up, const CArme
 	addPlayer(down->tempOwner);
 }
 
-bool CGarrisonDialogQuery::blocksPack(const CPack *pack) const 
+bool CGarrisonDialogQuery::blocksPack(const CPack *pack) const
 {
 	std::set<ObjectInstanceID> ourIds;
 	ourIds.insert(this->exchangingArmies[0]->id);
 	ourIds.insert(this->exchangingArmies[1]->id);
 
-
-	if (auto stacks = dynamic_cast<const ArrangeStacks*>(pack))
+	if (auto stacks = dynamic_ptr_cast<ArrangeStacks>(pack))
 	{
 		return !vstd::contains(ourIds, stacks->id1) || !vstd::contains(ourIds, stacks->id2);
 	}
-	if (auto arts = dynamic_cast<const ExchangeArtifacts*>(pack))
+
+	if (auto arts = dynamic_ptr_cast<ExchangeArtifacts>(pack))
 	{
 		if(auto id1 = boost::apply_visitor(GetEngagedHeroIds(), arts->src.artHolder))
 			if(!vstd::contains(ourIds, *id1))
@@ -288,24 +293,24 @@ bool CGarrisonDialogQuery::blocksPack(const CPack *pack) const
 				return true;
 		return false;
 	}
-	if (auto dismiss = dynamic_cast<const DisbandCreature*>(pack))
+	if (auto dismiss = dynamic_ptr_cast<DisbandCreature>(pack))
 	{
 		return !vstd::contains(ourIds, dismiss->id);
 	}
 
-	if (auto dismiss = dynamic_cast<const AssembleArtifacts*>(pack))
+	if (auto dismiss = dynamic_ptr_cast<AssembleArtifacts>(pack))
 	{
 		return !vstd::contains(ourIds, dismiss->heroID);
 	}
-	
-	if(auto upgrade = dynamic_cast<const UpgradeCreature*>(pack))
+
+	if(auto upgrade = dynamic_ptr_cast<UpgradeCreature>(pack))
 	{
 		return !vstd::contains(ourIds, upgrade->id);
 	}
 	return CDialogQuery::blocksPack(pack);
 }
 
-void CBlockingDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const 
+void CBlockingDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const
 {
 	assert(answer);
 	objectVisit.visitedObject->blockingDialogAnswered(objectVisit.visitingHero, *answer);
@@ -319,7 +324,7 @@ CBlockingDialogQuery::CBlockingDialogQuery(const BlockingDialog &bd)
 
 void CTeleportDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const
 {
-	auto obj = dynamic_cast<const CGTeleport *>(objectVisit.visitedObject);
+	auto obj = dynamic_ptr_cast<CGTeleport>(objectVisit.visitedObject);
 	obj->teleportDialogAnswered(objectVisit.visitingHero, *answer, td.exits);
 }
 
@@ -342,7 +347,7 @@ void CHeroLevelUpDialogQuery::onRemoval(CGameHandler *gh, PlayerColor color)
 	gh->levelUpHero(hlu.hero, hlu.skills[*answer]);
 }
 
-void CHeroLevelUpDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const 
+void CHeroLevelUpDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const
 {
 	objectVisit.visitedObject->heroLevelUpDone(objectVisit.visitingHero);
 }
@@ -360,20 +365,20 @@ void CCommanderLevelUpDialogQuery::onRemoval(CGameHandler *gh, PlayerColor color
 	gh->levelUpCommander(clu.hero->commander, clu.skills[*answer]);
 }
 
-void CCommanderLevelUpDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const 
+void CCommanderLevelUpDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const
 {
 	objectVisit.visitedObject->heroLevelUpDone(objectVisit.visitingHero);
 }
 
-bool CDialogQuery::endsByPlayerAnswer() const 
+bool CDialogQuery::endsByPlayerAnswer() const
 {
 	return true;
 }
 
-bool CDialogQuery::blocksPack(const CPack *pack) const 
+bool CDialogQuery::blocksPack(const CPack *pack) const
 {
 	//We accept only query replies from correct player
-	if(auto reply = dynamic_cast<const QueryReply *>(pack))
+	if(auto reply = dynamic_ptr_cast<QueryReply>(pack))
 	{
 		return !vstd::contains(players, reply->player);
 	}

+ 14 - 0
server/StdInc.h

@@ -8,3 +8,17 @@
 #include <boost/random/mersenne_twister.hpp>
 #include <boost/random/variate_generator.hpp>
 #include <boost/system/system_error.hpp>
+
+template<class T, class F>
+inline const T * dynamic_ptr_cast(const F * ptr)
+{
+	#ifndef __APPLE__
+  return dynamic_cast<const T*>(ptr);
+	#else
+	if (!strcmp(typeid(*ptr).name(), typeid(T).name()))
+	{
+		return static_cast<const T*>(ptr);
+	}
+	return nullptr;
+	#endif
+}