Procházet zdrojové kódy

[programming challenge, SSN] today's changes

mateuszb před 13 roky
rodič
revize
2f74224a34

+ 23 - 0
Odpalarka/Odpalarka.vcxproj

@@ -68,6 +68,7 @@
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <OutDir>$(SolutionDir)</OutDir>
     <IntDir>$(Configuration)\</IntDir>
+    <LibraryPath>$(SolutionDir);$(LibraryPath)</LibraryPath>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <OutDir>$(SolutionDir)</OutDir>
@@ -76,6 +77,7 @@
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RD|Win32'">
     <OutDir>$(SolutionDir)$(Configuration)\bin\</OutDir>
     <IntDir>$(Configuration)\</IntDir>
+    <LibraryPath>$(SolutionDir)$(SolutionDir)..\libs;\$(PlatformShortName);$(LibraryPath)</LibraryPath>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RD|x64'">
     <OutDir>$(SolutionDir)$(Configuration)\bin\</OutDir>
@@ -85,18 +87,24 @@
     <ClCompile>
       <WarningLevel>Level3</WarningLevel>
       <Optimization>Disabled</Optimization>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile>
     </ClCompile>
     <Link>
       <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>VCMI_lib.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <ClCompile>
       <WarningLevel>Level3</WarningLevel>
       <Optimization>Disabled</Optimization>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile>
     </ClCompile>
     <Link>
       <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>VCMI_lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='RD|Win32'">
@@ -105,11 +113,14 @@
       <Optimization>MaxSpeed</Optimization>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile>
     </ClCompile>
     <Link>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalDependencies>VCMI_lib.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='RD|x64'">
@@ -118,15 +129,27 @@
       <Optimization>MaxSpeed</Optimization>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile>
     </ClCompile>
     <Link>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalDependencies>VCMI_lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="main.cpp" />
+    <ClCompile Include="StdInc.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='RD|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='RD|x64'">Create</PrecompiledHeader>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="StdInc.h" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">

+ 93 - 23
Odpalarka/main.cpp

@@ -1,9 +1,14 @@
 //#include "../global.h"
-#include <boost/thread.hpp>
-#include <boost/bind.hpp>
-#include <boost/program_options.hpp>
+#include "StdInc.h"
+#include "../lib/VCMI_Lib.h"
 namespace po = boost::program_options;
 
+std::string leftAI, rightAI, battle, results, logsDir;
+bool withVisualization = false;
+std::string servername;
+std::string runnername;
+extern DLL_EXPORT LibClasses * VLC;
+
 std::string addQuotesIfNeeded(const std::string &s)
 {
 	if(s.find_first_of(' ') != std::string::npos)
@@ -33,6 +38,84 @@ void runCommand(const std::string &command, const std::string &name, const std::
 	boost::thread tt(boost::bind(std::system, cmd.c_str()));
 }
 
+double playBattle(const DuelParameters &dp)
+{
+	{
+		CSaveFile out("pliczek.ssnb");
+		out << dp;
+	}
+
+
+	std::string serverCommand = servername + " " + addQuotesIfNeeded(battle) + " " + addQuotesIfNeeded(leftAI) + " " + addQuotesIfNeeded(rightAI) + " " + addQuotesIfNeeded(results) + " " + addQuotesIfNeeded(logsDir) + " " + (withVisualization ? " v" : "");
+	std::string runnerCommand = runnername + " " + addQuotesIfNeeded(logsDir);
+	std::cout <<"Server command: " << serverCommand << std::endl << "Runner command: " << runnerCommand << std::endl;
+
+	int code = 0;
+	boost::thread t([&]
+	{ 
+		code = std::system(serverCommand.c_str());
+	});
+
+	runCommand(runnerCommand, "first_runner", logsDir);
+	runCommand(runnerCommand, "second_runner", logsDir);
+	runCommand(runnerCommand, "third_runner", logsDir);
+	if(withVisualization)
+	{
+		//boost::this_thread::sleep(boost::posix_time::millisec(500)); //FIXME
+		boost::thread tttt(boost::bind(std::system, "VCMI_Client.exe -battle"));
+	}
+
+	//boost::this_thread::sleep(boost::posix_time::seconds(5));
+	t.join();
+	return code / 1000000.0;
+}
+
+void SSNRun()
+{
+	CArtifact *nowy = new CArtifact();
+	nowy->description = "Cudowny miecz Towa gwarantuje zwyciestwo";
+	nowy->name = "Cudowny miecz";
+	nowy->constituentOf = nowy->constituents = NULL;
+	nowy->possibleSlots.push_back(Arts::LEFT_HAND);
+
+	CArtifactInstance *artinst = new CArtifactInstance(nowy);
+	auto &arts = VLC->arth->artifacts;
+	CArtifactInstance *inny = new CArtifactInstance(VLC->arth->artifacts[15]);
+
+	artinst->addNewBonus(new Bonus(Bonus::PERMANENT, Bonus::PRIMARY_SKILL, Bonus::ARTIFACT_INSTANCE, +25, nowy->id, PrimarySkill::ATTACK));
+	artinst->addNewBonus(new Bonus(Bonus::PERMANENT, Bonus::PRIMARY_SKILL, Bonus::ARTIFACT_INSTANCE, +25, nowy->id, PrimarySkill::DEFENSE));
+
+	DuelParameters dp;
+	dp.bfieldType = 1;
+	dp.terType = 1;
+
+	for(int i = 0; i < 2 ; i++)
+	{
+		auto &side = dp.sides[i];
+		side.heroId = i;
+		side.heroPrimSkills.resize(4,0);
+		side.stacks[0] = DuelParameters::SideSettings::StackSettings(10+i, 40+i);
+	}
+
+	auto bonuses = artinst->getBonuses([](const Bonus *){ return true; });
+	BOOST_FOREACH(Bonus *b, *bonuses) 
+	{
+		std::cout << format("%s (%d) value:%d, description: %s\n") % bonusTypeToString(b->type) % b->subtype % b->val % b->Description();
+	}
+
+	
+
+
+	//lewa strona z art 0.9
+	//bez artefaktow -0.41
+	//prawa strona z art. -0.926
+
+	dp.sides[0].artifacts[Arts::LEFT_HAND] = artinst;
+
+	auto battleOutcome = playBattle(dp);
+	int g = 4;
+}
+
 int main(int argc, char **argv)
 {
 	std::cout << "VCMI Odpalarka\nMy path: " << argv[0] << std::endl;
@@ -42,13 +125,11 @@ int main(int argc, char **argv)
 		("help,h", "Display help and exit")
 		("aiLeft,l", po::value<std::string>()->default_value("StupidAI"), "Left AI path")
 		("aiRight,r", po::value<std::string>()->default_value("StupidAI"), "Right AI path")
-		("battle,b", po::value<std::string>()->default_value("b1.json"), "Duel file path")
+		("battle,b", po::value<std::string>()->default_value("pliczek.ssnb"), "Duel file path")
 		("resultsOut,o", po::value<std::string>()->default_value("./results.txt"), "Output file when results will be appended")
 		("logsDir,d", po::value<std::string>()->default_value("."), "Directory where log files will be created")
 		("visualization,v", "Runs a client to display a visualization of battle");
 
-	std::string leftAI, rightAI, battle, results, logsDir;
-	bool withVisualization = false;
 
 	try
 	{
@@ -86,14 +167,14 @@ int main(int argc, char **argv)
 
 
 
-	std::string runnername = 
+	runnername = 
 #ifdef _WIN32
 		"VCMI_BattleAiHost.exe"
 #else
 		"./vcmirunner"
 #endif
 	;
-	std::string servername = 
+	servername = 
 #ifdef _WIN32
 		"VCMI_server.exe"
 #else
@@ -101,22 +182,11 @@ int main(int argc, char **argv)
 #endif
 	;
 
-	std::string serverCommand = servername + " " + addQuotesIfNeeded(battle) + " " + addQuotesIfNeeded(leftAI) + " " + addQuotesIfNeeded(rightAI) + " " + addQuotesIfNeeded(results) + " " + addQuotesIfNeeded(logsDir) + " " + (withVisualization ? " v" : "");
-	std::string runnerCommand = runnername + " " + addQuotesIfNeeded(logsDir);
-	std::cout <<"Server command: " << serverCommand << std::endl << "Runner command: " << runnerCommand << std::endl;
+	
+	VLC = new LibClasses();
+	VLC->init();
 
-	boost::thread t(boost::bind(std::system, serverCommand.c_str()));
-	runCommand(runnerCommand, "first_runner", logsDir);
-	runCommand(runnerCommand, "second_runner", logsDir);
-	runCommand(runnerCommand, "third_runner", logsDir);
-	if(withVisualization)
-	{
-		//boost::this_thread::sleep(boost::posix_time::millisec(500)); //FIXME
-		boost::thread tttt(boost::bind(std::system, "VCMI_Client.exe -battle"));
-	}
+	SSNRun();
 
-	//boost::this_thread::sleep(boost::posix_time::seconds(5));
-
-	t.join();
 	return EXIT_SUCCESS;
 }

+ 1 - 1
VCMI_BattleAiHost/CheckTime.h

@@ -59,7 +59,7 @@ struct CheckTime
 //all ms
 const int PROCESS_INFO_TIME = 5; 
 const int MAKE_DECIDION_TIME = 150; 
-const int MEASURE_MARGIN = 3;
+const int MEASURE_MARGIN = 3000000;
 const int HANGUP_TIME = 250;
 const int CONSTRUCT_TIME = 50;
 const int STARTUP_TIME = 100;

+ 2 - 4
lib/CArtHandler.h

@@ -23,9 +23,8 @@ struct ArtifactLocation;
 
 class DLL_EXPORT CArtifact : public CBonusSystemNode //container for artifacts
 {
-protected:
-	std::string name, description; //set if custom
 public:
+	std::string name, description; //set if custom
 	enum EartClass {ART_SPECIAL=1, ART_TREASURE=2, ART_MINOR=4, ART_MAJOR=8, ART_RELIC=16}; //artifact classes
 	const std::string &Name() const; //getter
 	const std::string &Description() const; //getter
@@ -56,10 +55,9 @@ public:
 
 class DLL_EXPORT CArtifactInstance : public CBonusSystemNode
 {
-protected:
+public:
 	void init();
 	CArtifactInstance(CArtifact *Art);
-public:
 	CArtifactInstance();
 
 	ConstTransitivePtr<CArtifact> artType; 

+ 5 - 0
lib/CGameState.cpp

@@ -983,6 +983,11 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
 							h->spells.insert(spell);
 					}
 
+					BOOST_FOREACH(auto &parka, ss.artifacts)
+					{
+						h->putArtifact(parka.first, parka.second);
+					}
+
 					typedef const std::pair<si32, si8> &TSecSKill;
 					BOOST_FOREACH(TSecSKill secSkill, ss.heroSecSkills)
 						h->setSecSkillLevel((CGHeroInstance::SecondarySkill)secSkill.first, secSkill.second, 1);

+ 4 - 3
lib/CGameState.h

@@ -281,9 +281,9 @@ struct DLL_EXPORT CPathsInfo
 struct DLL_EXPORT DuelParameters
 {
 	si32 terType, bfieldType;
-	struct SideSettings
+	struct DLL_EXPORT SideSettings
 	{
-		struct StackSettings
+		struct DLL_EXPORT StackSettings
 		{
 			si32 type;
 			si32 count;
@@ -298,13 +298,14 @@ struct DLL_EXPORT DuelParameters
 
 		si32 heroId; //-1 if none
 		std::vector<si32> heroPrimSkills; //may be empty
+		std::map<int, CArtifactInstance*> artifacts;
 		std::vector<std::pair<si32, si8> > heroSecSkills; //may be empty; pairs <id, level>, level [0-3]
 		std::set<si32> spells;
 
 		SideSettings();
 		template <typename Handler> void serialize(Handler &h, const int version)
 		{
-			h & stacks & heroId & heroPrimSkills & spells;
+			h & stacks & heroId & heroPrimSkills & artifacts & heroSecSkills & spells;
 		}
 	} sides[2];
 

+ 11 - 0
lib/HeroBonus.cpp

@@ -28,6 +28,17 @@
 int CBonusSystemNode::treeChanged = 1;
 const bool CBonusSystemNode::cachingEnabled = false;
 
+DLL_EXPORT std::string bonusTypeToString(int type)
+{
+	BOOST_FOREACH(auto &p, bonusNameMap)
+	{
+		if(p.second == type)
+			return p.first;
+	}
+
+	return "UNKNOWN BONUS";
+}
+
 BonusList::BonusList(bool BelongsToTree /* =false */) : belongsToTree(BelongsToTree)
 {
 

+ 3 - 0
lib/HeroBonus.h

@@ -833,6 +833,7 @@ namespace Selector
 }
 
 extern DLL_EXPORT const std::map<std::string, int> bonusNameMap;
+DLL_EXPORT std::string bonusTypeToString(int type);
 
 // BonusList template that requires full interface of CBonusSystemNode
 template <class InputIterator>
@@ -859,3 +860,5 @@ namespace boost
 		typedef std::vector<Bonus*>::const_iterator type;
 	};
 }
+
+

+ 29 - 5
server/CGameHandler.cpp

@@ -332,7 +332,7 @@ void CGameHandler::startBattle( const CArmedInstance *armies[2], int3 tile, cons
 	runBattle();
 }
 
-void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2)
+int CGameHandler::endBattle( int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2 )
 {
 	bool duel = gs->initialOpts->mode == StartInfo::DUEL;
 	BattleResultsApplied resultsApplied;
@@ -381,8 +381,20 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
 		}
 	}
 
+	const CArmedInstance *armed = gs->curB->belligerents[battleResult.data->winner];
+
+	int winnerArmyAfterBattle = 0;
+	int winnerArmyBeforeBattle = 0;
+	BOOST_FOREACH(auto &slot, armed->Slots())
+	{
+		winnerArmyBeforeBattle += slot.second->type->AIValue * slot.second->count;
+		assert(winnerArmyBeforeBattle >= 0);
+	}
+
 	sendAndApply(battleResult.data);
 
+
+
 	//Eagle Eye secondary skill handling
 	if(cs.spells.size())
 	{
@@ -459,12 +471,12 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
 		addToSlot(StackLocation(winnerHero, necroSlot), raisedStack.type, raisedStack.count);
 	}
 
+	int casualtiesPoints = 0;
 	if(duel)
 	{
 		CSaveFile resultFile(LOGS_DIR + "/result.vdrst");
 		resultFile << *battleResult.data;
 
-		int casualtiesPoints = 0;
 		tlog0 << boost::format("Winner side %d\nWinner casualties:\n") % (int)battleResult.data->winner;
 		for(std::map<ui32,si32>::const_iterator i = battleResult.data->casualties[battleResult.data->winner].begin(); i != battleResult.data->casualties[battleResult.data->winner].end(); i++)
 		{
@@ -487,8 +499,18 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
 
 	sendAndApply(&resultsApplied);
 
+	winnerArmyAfterBattle = winnerArmyBeforeBattle - casualtiesPoints;
+
 	if(duel)
-		return;
+	{
+		double ratioKept = (double)winnerArmyAfterBattle / (double)winnerArmyBeforeBattle;
+
+		int ret = ratioKept * 1000000;
+		if(battleResult.data->winner)
+			ret *= -1;
+
+		return ret;
+	}
 
 	if(visitObjectAfterVictory && winnerHero == hero1)
 	{
@@ -517,6 +539,8 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
 
 		sendAndApply(&sah);
 	}
+
+	return 0;
 }
 
 void CGameHandler::afterBattleCallback() //object interaction after leveling up is done
@@ -4984,7 +5008,7 @@ bool CGameHandler::swapStacks(const StackLocation &sl1, const StackLocation &sl2
 	}
 }
 
-void CGameHandler::runBattle()
+int CGameHandler::runBattle()
 {
 	assert(gs->curB);
 	//TODO: pre-tactic stuff, call scripts etc.
@@ -5203,7 +5227,7 @@ void CGameHandler::runBattle()
 		}
 	}
 
-	endBattle(gs->curB->tile, gs->curB->heroes[0], gs->curB->heroes[1]);
+	return endBattle(gs->curB->tile, gs->curB->heroes[0], gs->curB->heroes[1]);
 }
 
 void CGameHandler::giveHeroArtifact(const CGHeroInstance *h, const CArtifactInstance *a, int pos)

+ 2 - 2
server/CGameHandler.h

@@ -113,7 +113,7 @@ public:
 	void giveSpells(const CGTownInstance *t, const CGHeroInstance *h);
 	int moveStack(int stack, THex dest); //returned value - travelled distance
 	void startBattle(const CArmedInstance *armies[2], int3 tile, const CGHeroInstance *heroes[2], bool creatureBank, boost::function<void(BattleResult*)> cb, const CGTownInstance *town = NULL); //use hero=NULL for no hero
-	void runBattle();
+	int runBattle();
 	void checkLossVictory(ui8 player);
 	void winLoseHandle(ui8 players=255); //players: bit field - colours of players to be checked; default: all
 	void getLossVicMessage(ui8 player, ui8 standard, bool victory, InfoWindow &out) const;
@@ -125,7 +125,7 @@ public:
 	//
 
 	void disqualifyPlayer(int side);
-	void endBattle(int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2); //ends battle
+	int endBattle(int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2); //ends battle
 	void prepareAttack(BattleAttack &bat, const CStack *att, const CStack *def, int distance, int targetHex); //distance - number of hexes travelled before attacking
 	void applyBattleEffects(BattleAttack &bat, const CStack *att, const CStack *def, int distance, bool secondary); //damage, drain life & fire shield
 	void checkForBattleEnd( std::vector<CStack*> &stacks );

+ 13 - 9
server/CVCMIServer.cpp

@@ -668,7 +668,7 @@ void CVCMIServer::startDuel(const std::string &battle, const std::string &leftAI
 	*gh->gameLog << battle << leftAI << rightAI << ui8('$');
 	
 	tlog0 << "Starting battle!\n";
-	gh->runBattle();
+	auto battleOut = gh->runBattle();
 	tlog0 << "Battle over!\n";
 	tlog0 << "Waiting for connections to close\n";
 	
@@ -687,7 +687,8 @@ void CVCMIServer::startDuel(const std::string &battle, const std::string &leftAI
 	tlog0 << "Removed gh!\n";
 
 	tlog0 << "Dying...\n";
-	exit(0);
+
+	exit(battleOut);
 }
 
 #ifndef __GNUC__
@@ -711,15 +712,18 @@ int main(int argc, char** argv)
 	{
 		io_service io_service;
 		CVCMIServer server;
-		if(argc == 6 || argc == 7)
+		if(argc != 2)
 		{
-			RESULTS_PATH = argv[4];
-			tlog1 << "Results path: " << RESULTS_PATH << std::endl;
-			tlog1 << "Logs path: " << RESULTS_PATH << std::endl;
-			server.startDuel(argv[1], argv[2], argv[3], argc-3);
+			if(argc == 6 || argc == 7)
+			{
+				RESULTS_PATH = argv[4];
+				tlog1 << "Results path: " << RESULTS_PATH << std::endl;
+				tlog1 << "Logs path: " << RESULTS_PATH << std::endl;
+				server.startDuel(argv[1], argv[2], argv[3], argc-3);
+			}
+			else
+				server.startDuel("b1.json", "StupidAI", "StupidAI", 2);
 		}
-		else
-			server.startDuel("b1.json", "StupidAI", "StupidAI", 2);
 
 		while(!end2)
 		{

+ 2 - 2
server/NetPacksServer.cpp

@@ -243,8 +243,8 @@ bool MakeAction::applyGh( CGameHandler *gh )
 		if(gh->connections[b->sides[b->tacticsSide]] != c) 
 			ERROR_AND_RETURN;
 	}
-	else if(gh->connections[b->getStack(b->activeStack)->owner] != c) 
-		ERROR_AND_RETURN;
+// 	else if(gh->connections[b->getStack(b->activeStack)->owner] != c) 
+// 		ERROR_AND_RETURN;
 
 	return gh->makeBattleAction(ba);
 }