Преглед на файлове

AI for neutral creatures and battles and player AIs can be different. StupidAI will handle neutrals by default.
Fixes for issues with deserialization and handling Tactics secondary skill.

Michał W. Urbańczyk преди 14 години
родител
ревизия
cab8f9e11d
променени са 13 файла, в които са добавени 64 реда и са изтрити 32 реда
  1. 5 0
      AI/GeniusAI/DLLMain.cpp
  2. 1 1
      CCallback.cpp
  3. 5 5
      CGameInterface.cpp
  4. 2 2
      CGameInterface.h
  5. 6 1
      client/CBattleInterface.cpp
  6. 2 1
      client/CConfigHandler.cpp
  7. 1 1
      client/CConfigHandler.h
  8. 22 10
      client/Client.cpp
  9. 2 1
      config/settings.txt
  10. 1 1
      global.h
  11. 1 1
      lib/CGameState.h
  12. 11 5
      lib/HeroBonus.cpp
  13. 5 3
      lib/HeroBonus.h

+ 5 - 0
AI/GeniusAI/DLLMain.cpp

@@ -32,4 +32,9 @@ extern "C" DLL_F_EXPORT CGlobalAI* GetNewAI()
 extern "C" DLL_F_EXPORT void ReleaseAI(CGlobalAI* i)
 {
 	delete (CGeniusAI*)i;
+}
+
+extern "C" DLL_F_EXPORT CBattleGameInterface* GetNewBattleAI()
+{
+	return new CGeniusAI();
 }

+ 1 - 1
CCallback.cpp

@@ -551,7 +551,7 @@ TStacks CBattleCallback::battleGetStacks(EStackOwnership whose /*= MINE_AND_ENEM
 
 	BOOST_FOREACH(const CStack *s, gs->curB->stacks)
 	{
-		bool ownerMatches = whose == MINE_AND_ENEMY || whose == ONLY_MINE && s->owner == player;
+		bool ownerMatches = whose == MINE_AND_ENEMY || whose == ONLY_MINE && s->owner == player || whose == ONLY_ENEMY && s->owner != player;
 		bool alivenessMatches = s->alive()  ||  !onlyAlive;
 		if(ownerMatches && alivenessMatches)
 			ret.push_back(s);

+ 5 - 5
CGameInterface.cpp

@@ -20,7 +20,7 @@
  */
 
 template<typename rett>
-rett * createAnyAI(CCallback * cb, std::string dllname, std::string methodName)
+rett * createAnyAI(std::string dllname, std::string methodName)
 {
 	char temp[50];
 	rett * ret=NULL;
@@ -62,14 +62,14 @@ rett * createAnyAI(CCallback * cb, std::string dllname, std::string methodName)
 	return ret;
 }
 
-CGlobalAI * CAIHandler::getNewAI(CCallback * cb, std::string dllname)
+CGlobalAI * CAIHandler::getNewAI(std::string dllname)
 {
-	return createAnyAI<CGlobalAI>(cb, dllname, "GetNewAI");
+	return createAnyAI<CGlobalAI>(dllname, "GetNewAI");
 }
 
-CBattleGameInterface * CAIHandler::getNewBattleAI( CCallback * cb, std::string dllname )
+CBattleGameInterface * CAIHandler::getNewBattleAI(std::string dllname )
 {
-	return createAnyAI<CBattleGameInterface>(cb, dllname, "GetNewBattleAI");
+	return createAnyAI<CBattleGameInterface>(dllname, "GetNewBattleAI");
 }
 
 BattleAction CGlobalAI::activeStack( const CStack * stack )

+ 2 - 2
CGameInterface.h

@@ -153,8 +153,8 @@ public:
 class CAIHandler
 {
 public:
-	static CGlobalAI * getNewAI(CCallback * cb, std::string dllname);
-	static CBattleGameInterface * getNewBattleAI(CCallback * cb, std::string dllname);
+	static CGlobalAI * getNewAI(std::string dllname);
+	static CBattleGameInterface * getNewBattleAI(std::string dllname);
 };
 class CGlobalAI : public CGameInterface // AI class (to derivate)
 {

+ 6 - 1
client/CBattleInterface.cpp

@@ -3334,6 +3334,9 @@ void CBattleInterface::endAction(const BattleAction* action)
 	}
 
 	queue->update();
+
+	if(tacticsMode) //we have activated next stack after sending request that has been just realized -> blockmap due to movement has changed
+		redrawBackgroundWithHexes(activeStack);
 }
 
 void CBattleInterface::hideQueue()
@@ -3461,9 +3464,11 @@ void CBattleInterface::waitForAnims()
 
 void CBattleInterface::bEndTacticPhase()
 {
+	btactEnd->block(true);
+	bDefence->block(false);
+	bWait->block(false);
 	BattleAction endt = BattleAction::makeEndOFTacticPhase(curInt->cb->battleGetMySide());
 	curInt->cb->battleMakeTacticAction(&endt);
-	btactEnd->block(true);
 }
 
 void CBattleInterface::bTacticNextStack()

+ 2 - 1
client/CConfigHandler.cpp

@@ -210,7 +210,8 @@ struct SettingsGrammar : public grammar<SettingsGrammar>
 				| str_p("localInformation=") >> (uint_p[assign_a(conf.cc.localInformation)] | eps_p[lerror("Wrong localInformation!")])
 				| str_p("fullscreen=") >> (uint_p[assign_a(conf.cc.fullscreen)] | eps_p[lerror("Wrong fullscreen!")])
 				| str_p("server=") >> ( ( +digit_p >> *('.' >> +digit_p) )[assign_a(conf.cc.server)]   | eps_p[lerror("Wrong server!")])
-				| str_p("defaultAI=") >> ((+(anychar_p - ';'))[assign_a(conf.cc.defaultAI)] | eps_p[lerror("Wrong defaultAI!")])
+				| str_p("defaultPlayerAI=") >> ((+(anychar_p - ';'))[assign_a(conf.cc.defaultPlayerAI)] | eps_p[lerror("Wrong defaultAI!")])
+				| str_p("neutralBattleAI=") >> ((+(anychar_p - ';'))[assign_a(conf.cc.defaultBattleAI)] | eps_p[lerror("Wrong defaultAI!")])
 				| (+(anychar_p - '}'))[lerror2("Unrecognized client option: ")]
 				;
 			clientOptionsSequence = *(clientOption >> (';' | eps_p[lerror("Semicolon lacking after client option!")]));

+ 1 - 1
client/CConfigHandler.h

@@ -23,7 +23,7 @@ namespace config
 		int pregameResx, pregameResy; //real screen resolution of preGame
 		int port, localInformation;
 		std::string server, //server address (e.g. 127.0.0.1)
-			defaultAI; //dll name
+			defaultPlayerAI, defaultBattleAI; //dll names
 	};
 	
 	struct ButtonInfo

+ 22 - 10
client/Client.cpp

@@ -398,7 +398,7 @@ void CClient::newGame( CConnection *con, StartInfo *si )
 			CCallback *cb = new CCallback(gs,color,this);
 			if(!it->second.human) 
 			{
-				playerint[color] = static_cast<CGameInterface*>(CAIHandler::getNewAI(cb,conf.cc.defaultAI));
+				playerint[color] = static_cast<CGameInterface*>(CAIHandler::getNewAI(conf.cc.defaultPlayerAI));
 			}
 			else 
 			{
@@ -412,7 +412,7 @@ void CClient::newGame( CConnection *con, StartInfo *si )
 		else
 		{
 			CBattleCallback * cbc = new CBattleCallback(gs, color, this);
-			battleints[color] = CAIHandler::getNewBattleAI(cb,"StupidAI");
+			battleints[color] = CAIHandler::getNewBattleAI("StupidAI");
 			battleints[color]->init(cbc);
 		}
 	}
@@ -428,9 +428,10 @@ void CClient::newGame( CConnection *con, StartInfo *si )
 	}
 	else
 	{
-		playerint[255] =  CAIHandler::getNewAI(cb,conf.cc.defaultAI);
-		playerint[255]->init(new CCallback(gs,255,this));
-		battleints[255] = playerint[255];
+		battleints[255] = CAIHandler::getNewBattleAI(conf.cc.defaultBattleAI);
+		battleints[255]->init(new CBattleCallback(gs, 255, this));
+// 		playerint[255]->init(new CCallback(gs,255,this));
+// 		battleints[255] = playerint[255];
 	}
 
 	serv->addStdVecItems(const_cast<CGameInfo*>(CGI)->state);
@@ -465,16 +466,27 @@ void CClient::serialize( Handler &h, const int version )
 			ui8 pid;
 			h & pid & dllname;
 
-			CCallback *callback = new CCallback(gs,pid,this);
-			callbacks.insert(callback);
-			CGameInterface *nInt = NULL;
-
 
+			CGameInterface *nInt = NULL;
 			if(dllname.length())
-				nInt = CAIHandler::getNewAI(callback,dllname);
+			{
+				if(pid == 255)
+				{
+					CBattleCallback * cbc = new CBattleCallback(gs, pid, this);
+					CBattleGameInterface *cbgi = CAIHandler::getNewBattleAI(dllname);
+					battleints[pid] = cbgi;
+					cbgi->init(cb);
+					//TODO? consider serialization 
+					continue;
+				}
+				else
+					nInt = CAIHandler::getNewAI(dllname);
+			}
 			else
 				nInt = new CPlayerInterface(pid);
 
+			CCallback *callback = new CCallback(gs,pid,this);
+			callbacks.insert(callback);
 			battleints[pid] = playerint[pid] = nInt;
 			nInt->init(callback);
 			nInt->serialize(h, version);

+ 2 - 1
config/settings.txt

@@ -10,7 +10,8 @@ clientSettings
 	fullscreen=0; //0 - windowed mode, 1 - fullscreen
 	server=127.0.0.1; //use 127.0.0.1 for localhost
 	localInformation=2; //0 - *all* information sent from server (safest and slowest); 1 - map information sent from server; 2 - all information local-storaged
-	defaultAI=GeniusAI; 
+	defaultPlayerAI=GeniusAI; 
+	neutralBattleAI=StupidAI;
 }
 GUISettings
 {

+ 1 - 1
global.h

@@ -685,6 +685,6 @@ static inline ui32 read_unaligned_u32(const void *p)
 	#define OVERRIDE 	//is there any working counterpart?
 #endif
 
-#define BONUS_TREE_DESERIALIZATION_FIX if(!h.saving) deserializationFix();
+#define BONUS_TREE_DESERIALIZATION_FIX if(!h.saving && h.smartPointerSerialization) deserializationFix();
 
 #endif // __GLOBAL_H__

+ 1 - 1
lib/CGameState.h

@@ -145,7 +145,6 @@ public:
 
 	PlayerState();
 	std::string nodeName() const OVERRIDE;
-	void deserializationFix();
 
 	//override
 	//void getParents(TCNodes &out, const CBonusSystemNode *root = NULL) const; 
@@ -371,6 +370,7 @@ public:
 		{
 			loadTownDInfos();
 		}
+		BONUS_TREE_DESERIALIZATION_FIX
 	}
 
 	friend class CCallback;

+ 11 - 5
lib/HeroBonus.cpp

@@ -386,10 +386,7 @@ void CBonusSystemNode::addNewBonus(Bonus *b)
 {
 	assert(!vstd::contains(exportedBonuses,b));
 	exportedBonuses.push_back(b);
-	if(b->propagator)
-		propagateBonus(b);
-	else
-		bonuses.push_back(b);
+	exportBonus(b);
 }
 
 void CBonusSystemNode::removeBonus(Bonus *b)
@@ -478,7 +475,8 @@ std::string CBonusSystemNode::nodeName() const
 
 void CBonusSystemNode::deserializationFix()
 {
-	tlog2 << "Deserialization fix called on bare CBSN? Shouldn't be...\n";
+	BOOST_FOREACH(Bonus *b, exportedBonuses)
+		exportBonus(b);
 }
 
 void CBonusSystemNode::getRedParents(TNodes &out)
@@ -567,6 +565,14 @@ void CBonusSystemNode::battleTurnPassed()
 	}
 }
 
+void CBonusSystemNode::exportBonus(Bonus * b)
+{
+	if(b->propagator)
+		propagateBonus(b);
+	else
+		bonuses.push_back(b);
+}
+
 int NBonus::valOf(const CBonusSystemNode *obj, Bonus::BonusType type, int subtype /*= -1*/)
 {
 	if(obj)

+ 5 - 3
lib/HeroBonus.h

@@ -55,6 +55,7 @@ namespace PrimarySkill
 	BONUS_NAME(EARTH_SPELL_DMG_PREMY) \
 	BONUS_NAME(FIRE_SPELL_DMG_PREMY) \
 	BONUS_NAME(WATER_SPELL_DMG_PREMY) \
+	BONUS_NAME(BLOCK_SPELLS_ABOVE_LEVEL) \
 	BONUS_NAME(WATER_WALKING) /*subtype 1 - without penalty, 2 - with penalty*/ \
 	BONUS_NAME(NO_SHOTING_PENALTY) /* duplicates NO_DISTANCE_PENALTY or FREE_SHOOTHING?*/\
 	BONUS_NAME(NEGATE_ALL_NATURAL_IMMUNITIES) \
@@ -253,7 +254,7 @@ struct DLL_EXPORT Bonus
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
-		h & duration & type & subtype & source & val & sid & description & additionalInfo & turnsRemain & valType & effectRange & limiter;
+		h & duration & type & subtype & source & val & sid & description & additionalInfo & turnsRemain & valType & effectRange & limiter & propagator;
 	}
 
 	static bool OneDay(const Bonus *hb)
@@ -448,15 +449,16 @@ public:
 	void popBonuses(const CSelector &s);
 	virtual std::string nodeName() const;
 	void deserializationFix();
+	void exportBonus(Bonus * b);
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
-		h & bonuses & nodeType;
+		h & /*bonuses & */nodeType;
 		h & exportedBonuses;
 		h & description;
+		BONUS_TREE_DESERIALIZATION_FIX
 		//h & parents & children;
 	}
-
 	enum ENodeTypes
 	{
 		UNKNOWN, STACK_INSTANCE, STACK_BATTLE, SPECIALITY, ARTIFACT, CREATURE, ARTIFACT_INSTANCE, HERO, PLAYER, TEAM