Переглянути джерело

Merge remote-tracking branch 'remotes/origin/develop' into SpellsRefactoring4

AlexVinS 11 роки тому
батько
коміт
f7ff61ce4f

+ 5 - 4
AI/CMakeLists.txt

@@ -3,13 +3,14 @@ cmake_minimum_required(VERSION 2.8)
 
 find_package(Fuzzylite)
 
+if(NOT MSVC)
+    add_definitions(-DFL_CPP11)
+    set(FL_CPP11 ON CACHE BOOL "")
+endif()
+
 if (NOT FL_FOUND)
     set(FL_BUILD_BINARY OFF CACHE BOOL "")
     set(FL_BUILD_SHARED OFF CACHE BOOL "")
-    if(NOT MSVC)
-        add_definitions(-DFL_CPP11)
-        set(FL_CPP11 ON CACHE BOOL "")
-    endif()
     add_subdirectory(FuzzyLite/fuzzylite)
 endif()
 add_subdirectory(BattleAI)

+ 9 - 1
Global.h

@@ -53,10 +53,18 @@ static_assert(sizeof(bool) == 1, "Bool needs to be 1 byte in size.");
 #  error "Windows CE isn't supported"
 #elif defined(__linux__) || defined(__gnu_linux__) || defined(linux) || defined(__linux)
 #  define VCMI_UNIX
-#  define VCMI_LINUX
+#  define VCMI_XDG
 #  ifdef __ANDROID__
 #    define VCMI_ANDROID 
 #  endif
+#elif defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
+#  define VCMI_UNIX
+#  define VCMI_XDG
+#  define VCMI_FREEBSD
+#elif defined(__GNU__) || defined(__gnu_hurd__) || (defined(__MACH__) && !defined(__APPLE))
+#  define VCMI_UNIX
+#  define VCMI_XDG
+#  define VCMI_HURD
 #elif defined(__APPLE__) && defined(__MACH__)
 #  define VCMI_UNIX
 #  define VCMI_APPLE

+ 2 - 4
client/CPlayerInterface.cpp

@@ -677,10 +677,8 @@ void CPlayerInterface::battleStacksHealedRes(const std::vector<std::pair<ui32, u
 			CCS->soundh->playSound(soundBase::DRAINLIF);
 
 			//print info about life drain
-			char textBuf[1000];
-			sprintf(textBuf, CGI->generaltexth->allTexts[361 + textOff].c_str(), attacker->getCreature()->nameSing.c_str(),
-				healedStacks[0].second, defender->getCreature()->namePl.c_str());
-			battleInt->console->addText(textBuf);
+			auto txt =  boost::format (CGI->generaltexth->allTexts[361 + textOff]) %  attacker->getCreature()->nameSing % healedStacks[0].second % defender->getCreature()->namePl;
+			battleInt->console->addText(boost::to_string(txt));
 		}
 	}
 	if (tentHeal)

+ 8 - 1
client/CPreGame.cpp

@@ -1586,7 +1586,14 @@ int SelectionTab::getLine()
 	Point clickPos(GH.current->button.x, GH.current->button.y);
 	clickPos = clickPos - pos.topLeft();
 
-	if (clickPos.y > 115  &&  clickPos.y < 564  &&  clickPos.x > 22  &&  clickPos.x < 371)
+	// Ignore clicks on save name area
+	int maxPosY;
+	if(tabType == CMenuScreen::saveGame)
+		maxPosY = 516;
+	else
+		maxPosY = 564;
+
+    	if(clickPos.y > 115  &&  clickPos.y < maxPosY  &&  clickPos.x > 22  &&  clickPos.x < 371)
 	{
 		line = (clickPos.y-115) / 25; //which line
 	}

+ 10 - 14
client/battle/CBattleInterface.cpp

@@ -831,11 +831,10 @@ void CBattleInterface::bFleef()
 			if(defendingHeroInstance->tempOwner == curInt->cb->getMyColor())
 				heroName = defendingHeroInstance->name;
 		//calculating text
-		char buffer[1000];
-		sprintf(buffer, CGI->generaltexth->allTexts[340].c_str(), heroName.c_str()); //The Shackles of War are present.  %s can not retreat!
+		auto txt = boost::format(CGI->generaltexth->allTexts[340]) % heroName; //The Shackles of War are present.  %s can not retreat!
 
 		//printing message
-		curInt->showInfoDialog(std::string(buffer), comps);
+		curInt->showInfoDialog(boost::to_string(txt), comps);
 	}
 }
 
@@ -1519,12 +1518,11 @@ void CBattleInterface::battleStacksEffectsSet(const SetStackEffect & sse)
 			if(stack->count != 1)
 				txtid++; //move to plural text
 
-			char txt[4000];
 			BonusList defenseBonuses = *(stack->getBonuses(Selector::typeSubtype(Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE)));
 			defenseBonuses.remove_if(Selector::durationType(Bonus::STACK_GETS_TURN)); //remove bonuses gained from defensive stance
 			int val = stack->Defense() - defenseBonuses.totalValue();
-			sprintf(txt, CGI->generaltexth->allTexts[txtid].c_str(),  (stack->count != 1) ? stack->getCreature()->namePl.c_str() : stack->getCreature()->nameSing.c_str(), val);
-			console->addText(txt);
+			auto txt = boost::format (CGI->generaltexth->allTexts[txtid]) % ((stack->count != 1) ? stack->getCreature()->namePl : stack->getCreature()->nameSing) % val;
+			console->addText(boost::to_string(txt));
 		}
 	}
 
@@ -1792,28 +1790,26 @@ void CBattleInterface::getPossibleActionsForStack(const CStack * stack)
 
 void CBattleInterface::printConsoleAttacked( const CStack * defender, int dmg, int killed, const CStack * attacker, bool multiple )
 {
-	char tabh[200] = {0};
+	boost::format txt;
 	int end = 0;
 	if (attacker) //ignore if stacks were killed by spell
 	{
-		end = sprintf(tabh, CGI->generaltexth->allTexts[attacker->count > 1 ? 377 : 376].c_str(),
-		(attacker->count > 1 ? attacker->getCreature()->namePl.c_str() : attacker->getCreature()->nameSing.c_str()), dmg);
+		txt = boost::format (CGI->generaltexth->allTexts[attacker->count > 1 ? 377 : 376]) %
+			(attacker->count > 1 ? attacker->getCreature()->namePl : attacker->getCreature()->nameSing) % dmg;
 	}
 	if(killed > 0)
 	{
 		if(killed > 1)
 		{
-			sprintf(tabh + end, CGI->generaltexth->allTexts[379].c_str(), killed,
-				multiple ? CGI->generaltexth->allTexts[43].c_str() : defender->getCreature()->namePl.c_str()); // creatures perish
+			txt = boost::format (CGI->generaltexth->allTexts[379]) % killed % (multiple ? CGI->generaltexth->allTexts[43] : defender->getCreature()->namePl); // creatures perish
 		}
 		else //killed == 1
 		{
-			sprintf(tabh + end, CGI->generaltexth->allTexts[378].c_str(),
-				multiple ? CGI->generaltexth->allTexts[42].c_str() : defender->getCreature()->nameSing.c_str()); // creature perishes
+			txt = boost::format (CGI->generaltexth->allTexts[378]) % (multiple ? CGI->generaltexth->allTexts[42] : defender->getCreature()->nameSing); // creature perishes
 		}
 	}
 
-	console->addText(std::string(tabh));
+	console->addText(boost::to_string (txt));
 }
 
 

+ 2 - 3
client/battle/CBattleInterfaceClasses.cpp

@@ -577,10 +577,9 @@ void CClickableHex::mouseMoved(const SDL_MouseMotionEvent &sEvent)
 			attackedStack->owner != myInterface->getCurrentPlayerInterface()->playerID &&
 			attackedStack->alive())
 		{
-			char tabh[160];
 			const std::string & attackedName = attackedStack->count == 1 ? attackedStack->getCreature()->nameSing : attackedStack->getCreature()->namePl;
-			sprintf(tabh, CGI->generaltexth->allTexts[220].c_str(), attackedName.c_str());
-			myInterface->console->alterTxt = std::string(tabh);
+			auto txt = boost::format (CGI->generaltexth->allTexts[220]) % attackedName;
+			myInterface->console->alterTxt = boost::to_string(txt);
 			setAlterText = true;
 		}
 	}

+ 1 - 1
client/widgets/MiscWidgets.cpp

@@ -383,7 +383,7 @@ void MoraleLuckBox::set(const IBonusBearer *node)
 	else
 	{
 		//it's a creature window
-		if ((morale && node->hasBonusOfType(Bonus::UNDEAD)) ||
+		if ((morale && node && node->hasBonusOfType(Bonus::UNDEAD)) ||
 			node->hasBonusOfType(Bonus::BLOCK_MORALE) || node->hasBonusOfType(Bonus::NON_LIVING))
 		{
 			text += CGI->generaltexth->arraytxt[113]; //unaffected by morale

+ 6 - 1
client/windows/CCreatureWindow.cpp

@@ -749,11 +749,12 @@ void CStackWindow::initBonusesList()
 	for(Bonus* b : output)
 	{
 		bonusInfo.name = info->stackNode->bonusToString(b, false);
+		bonusInfo.description = info->stackNode->bonusToString(b, true);
 		bonusInfo.imagePath = info->stackNode->bonusToGraphics(b);
 
 		//if it's possible to give any description or image for this kind of bonus
 		//TODO: figure out why half of bonuses don't have proper description
-		if (!bonusInfo.name.empty() || !bonusInfo.imagePath.empty())
+		if ((!bonusInfo.name.empty() || !bonusInfo.imagePath.empty())&& b->type != Bonus::MAGIC_RESISTANCE)
 			activeBonuses.push_back(bonusInfo);
 	}
 
@@ -823,6 +824,7 @@ CStackWindow::CStackWindow(const CStackInstance * stack, bool popup):
 	info->creature = stack->type;
 	info->creatureCount = stack->count;
 	info->popupWindow = popup;
+	info->owner = dynamic_cast<const CGHeroInstance *> (stack->armyObj);	
 	init();
 }
 
@@ -839,6 +841,7 @@ CStackWindow::CStackWindow(const CStackInstance * stack, std::function<void()> d
 	info->upgradeInfo->info = upgradeInfo;
 	info->upgradeInfo->callback = callback;
 	info->dismissInfo->callback = dismiss;
+	info->owner = dynamic_cast<const CGHeroInstance *> (stack->armyObj);
 	init();
 }
 
@@ -851,6 +854,7 @@ CStackWindow::CStackWindow(const CCommanderInstance * commander, bool popup):
 	info->commander = commander;
 	info->creatureCount = 1;
 	info->popupWindow = popup;
+	info->owner = dynamic_cast<const CGHeroInstance *> (commander->armyObj);	
 	init();
 }
 
@@ -865,6 +869,7 @@ CStackWindow::CStackWindow(const CCommanderInstance * commander, std::vector<ui3
 	info->levelupInfo = StackWindowInfo::CommanderLevelInfo();
 	info->levelupInfo->skills = skills;
 	info->levelupInfo->callback = callback;
+	info->owner = dynamic_cast<const CGHeroInstance *> (commander->armyObj);		
 	init();
 }
 

+ 2 - 3
lib/CBattleCallback.cpp

@@ -1378,11 +1378,11 @@ AttackableTiles CBattleInfoCallback::getPotentiallyAttackableHexes (const CStack
 		case -WN: //-17 //left-up or right-up
 		case WN + 1: //18 //right-down
 		case -WN + 1: //-16 //right-up
-			BattleHex::checkAndPush (destinationTile.hex + pseudoVector + ((hex/WN)%2 ? 1 : -1 ), hexes);
+			BattleHex::checkAndPush (destinationTile.hex + pseudoVector + (((hex/WN)%2) ? 1 : -1 ), hexes);
 			break;
 		case WN-1: //16 //left-down
 		case -WN-1: //-18 //left-up
-			BattleHex::checkAndPush (destinationTile.hex + pseudoVector + ((hex/WN)%2 ? 1 : 0), hexes);
+			BattleHex::checkAndPush (destinationTile.hex + pseudoVector + (((hex/WN)%2) ? 1 : 0), hexes);
 			break;
 		}
 		for (BattleHex tile : hexes)
@@ -1734,7 +1734,6 @@ ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleCanCastThisSpell
 					case CSpell::NEUTRAL:
 							targetExists = true;
 							break;
-						break;
 					case CSpell::NEGATIVE:
 						if(!casterStack || !ti.smart)
 						{

+ 1 - 1
lib/CThreadHelper.cpp

@@ -3,7 +3,7 @@
 
 #ifdef VCMI_WINDOWS
 	#include <windows.h>
-#elif !defined(VCMI_APPLE)
+#elif !defined(VCMI_APPLE) && !defined(VCMI_FREEBSD) && !defined(VCMI_HURD)
 	#include <sys/prctl.h>
 #endif
 /*

+ 2 - 2
lib/GameConstants.h

@@ -333,8 +333,8 @@ public:
 		BROTHERHOOD = SPECIAL_3,
 
 		MYSTIC_POND         = SPECIAL_1,
-		FOUNTAIN_OF_FORTUNE = SPECIAL_3, //Rampart
-		TREASURY            = SPECIAL_4,
+		FOUNTAIN_OF_FORTUNE = SPECIAL_2, //Rampart
+		TREASURY            = SPECIAL_3,
 
 		ARTIFACT_MERCHANT = SPECIAL_1,
 		LOOKOUT_TOWER     = SPECIAL_2, //Tower

+ 13 - 13
lib/VCMIDirs.cpp

@@ -449,8 +449,8 @@ bfs::path VCMIDirsOSX::libraryPath() const { return "."; }
 bfs::path VCMIDirsOSX::binaryPath() const { return "."; }
 
 std::string VCMIDirsOSX::libraryName(const std::string& basename) const { return "lib" + basename + ".dylib"; }
-#elif defined(VCMI_LINUX)
-class VCMIDirsLinux : public IVCMIDirsUNIX
+#elif defined(VCMI_XDG)
+class VCMIDirsXDG : public IVCMIDirsUNIX
 {
 public:
 	boost::filesystem::path userDataPath() const override;
@@ -465,7 +465,7 @@ public:
 	std::string libraryName(const std::string& basename) const override;
 };
 
-bfs::path VCMIDirsLinux::userDataPath() const
+bfs::path VCMIDirsXDG::userDataPath() const
 {
 	// $XDG_DATA_HOME, default: $HOME/.local/share
 	const char* homeDir;
@@ -476,7 +476,7 @@ bfs::path VCMIDirsLinux::userDataPath() const
 	else
 		return ".";
 }
-bfs::path VCMIDirsLinux::userCachePath() const
+bfs::path VCMIDirsXDG::userCachePath() const
 {
 	// $XDG_CACHE_HOME, default: $HOME/.cache
 	const char* tempResult;
@@ -487,7 +487,7 @@ bfs::path VCMIDirsLinux::userCachePath() const
 	else
 		return ".";
 }
-bfs::path VCMIDirsLinux::userConfigPath() const
+bfs::path VCMIDirsXDG::userConfigPath() const
 {
 	// $XDG_CONFIG_HOME, default: $HOME/.config
 	const char* tempResult;
@@ -499,7 +499,7 @@ bfs::path VCMIDirsLinux::userConfigPath() const
 		return ".";
 }
 
-std::vector<bfs::path> VCMIDirsLinux::dataPaths() const
+std::vector<bfs::path> VCMIDirsXDG::dataPaths() const
 {
 	// $XDG_DATA_DIRS, default: /usr/local/share/:/usr/share/
 
@@ -528,12 +528,12 @@ std::vector<bfs::path> VCMIDirsLinux::dataPaths() const
 	return ret;
 }
 
-bfs::path VCMIDirsLinux::libraryPath() const { return M_LIB_DIR; }
-bfs::path VCMIDirsLinux::binaryPath() const { return M_BIN_DIR; }
+bfs::path VCMIDirsXDG::libraryPath() const { return M_LIB_DIR; }
+bfs::path VCMIDirsXDG::binaryPath() const { return M_BIN_DIR; }
 
-std::string VCMIDirsLinux::libraryName(const std::string& basename) const { return "lib" + basename + ".so"; }
+std::string VCMIDirsXDG::libraryName(const std::string& basename) const { return "lib" + basename + ".so"; }
 #ifdef VCMI_ANDROID
-class VCMIDirsAndroid : public VCMIDirsLinux
+class VCMIDirsAndroid : public VCMIDirsXDG
 {
 public:
 	boost::filesystem::path userDataPath() const override;
@@ -553,7 +553,7 @@ std::vector<bfs::path> VCMIDirsAndroid::dataPaths() const
 	return std::vector<bfs::path>(1, userDataPath());
 }
 #endif // VCMI_ANDROID
-#endif // VCMI_APPLE, VCMI_LINUX
+#endif // VCMI_APPLE, VCMI_XDG
 #endif // VCMI_WINDOWS, VCMI_UNIX
 
 // Getters for interfaces are separated for clarity.
@@ -565,8 +565,8 @@ namespace VCMIDirs
 			static VCMIDirsWIN32 singleton;
 		#elif defined(VCMI_ANDROID)
 			static VCMIDirsAndroid singleton;
-		#elif defined(VCMI_LINUX)
-			static VCMIDirsLinux singleton;
+		#elif defined(VCMI_XDG)
+			static VCMIDirsXDG singleton;
 		#elif defined(VCMI_APPLE)
 			static VCMIDirsOSX singleton;
 		#endif

+ 1 - 1
lib/mapObjects/CRewardableObject.cpp

@@ -677,7 +677,7 @@ void CGBonusingObject::initObj()
 		for (int i=0; i<6; i++)
 		{
 			info[i].limiter.dayOfWeek = i+1;
-			configureBonus(info[i], i%2 ? Bonus::MORALE : Bonus::LUCK, 1, 68);
+			configureBonus(info[i], (i%2) ? Bonus::MORALE : Bonus::LUCK, 1, 68);
 			info[i].message.addTxt(MetaString::ADVOB_TXT, 62);
 			soundID = soundBase::experience;
 		}

+ 11 - 2
lib/rmg/CRmgTemplateZone.cpp

@@ -787,7 +787,12 @@ bool CRmgTemplateZone::createTreasurePile (CMapGenerator* gen, int3 &pos, float
 
 			//randomize next position from among possible ones
 			std::vector<int3> boundaryCopy (boundary.begin(), boundary.end());
-			RandomGeneratorUtil::randomShuffle(boundaryCopy, gen->rand);
+			//RandomGeneratorUtil::randomShuffle(boundaryCopy, gen->rand);
+			auto chooseTopTile = [](const int3 & lhs, const int3 & rhs) -> bool
+			{
+				return lhs.y < rhs.y;
+			};
+			boost::sort(boundaryCopy, chooseTopTile); //start from top tiles to allow objects accessible from bottom
 
 			for (auto tile : boundaryCopy)
 			{
@@ -2000,7 +2005,7 @@ void CRmgTemplateZone::addAllPossibleObjects (CMapGenerator* gen)
 			{
 				creaturesAmount = boost::math::round(creaturesAmount / 5) * 5;
 			}
-			else if (creaturesAmount <= 12)
+			else
 			{
 				creaturesAmount = boost::math::round(creaturesAmount / 10) * 10;
 			}
@@ -2070,12 +2075,16 @@ void CRmgTemplateZone::addAllPossibleObjects (CMapGenerator* gen)
 					{
 						case 1:
 							school = spell->air;
+							break;
 						case 2:
 							school = spell->earth;
+							break;
 						case 3:
 							school = spell->fire;
+							break;
 						case 4:
 							school = spell->water;
+							break;
 					}
 					if (school)
 						spells.push_back(spell);

+ 2 - 2
scripting/erm/ERM.cbp

@@ -6,7 +6,7 @@
 		<Option pch_mode="2" />
 		<Option compiler="gcc" />
 		<Build>
-			<Target title="Debug">
+			<Target title="Debug-win32-SDL2">
 				<Option output="../ERM" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="1" extension_auto="1" />
 				<Option object_output="obj/Debug/" />
 				<Option type="3" />
@@ -16,7 +16,7 @@
 					<Add option="-ggdb" />
 				</Compiler>
 			</Target>
-			<Target title="Release">
+			<Target title="Release-win32-SDL2">
 				<Option output="../ERM" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="1" extension_auto="1" />
 				<Option object_output="obj/Release/" />
 				<Option type="3" />

+ 11 - 9
scripting/erm/ERMInterpreter.cpp

@@ -23,9 +23,9 @@
 
 namespace spirit = boost::spirit;
 using namespace VERMInterpreter;
-using namespace boost::assign;
+
 typedef int TUnusedType;
-using namespace boost::assign;
+
 
 ERMInterpreter *erm;
 Environment *topDyn;
@@ -1339,10 +1339,10 @@ struct ERMExpDispatch : boost::static_visitor<>
 					std::vector<int> params(FunctionLocalVars::NUM_PARAMETERS, 0);
 					params.back() = it;
 					//owner->getFuncVars(funNum)->getParam(16) = it;
-					ERMInterpreter::TIDPattern tip;
+					
 					std::vector<int> v1;
-					v1 += funNum;
-					insert(tip) (v1.size(), v1);
+					v1.push_back(funNum);
+					ERMInterpreter::TIDPattern tip = {{v1.size(), v1}};
 					erm->executeTriggerType(TriggerType("FU"), true, tip, params);
 					it = erm->getFuncVars(funNum)->getParam(16);
 				}
@@ -1394,7 +1394,7 @@ struct ERMExpDispatch : boost::static_visitor<>
 					{
 						int heroNum = erm->getIexp(tid[0]).getInt();
 						if(heroNum == -1)
-							hero = icb->getSelectedHero();
+							assert(false); //FIXME: use new hero selection mechanics
 						else
 							hero = icb->getHeroWithSubid(heroNum);
 
@@ -2509,9 +2509,11 @@ struct VNodeEvaluator : boost::static_visitor<VOption>
 	}
 	VOption operator()(VSymbol const& opt) const
 	{
-		std::map<std::string, VFunc::Eopt> symToFunc = boost::assign::map_list_of
-			("<", VFunc::LT)("<=", VFunc::LE)(">", VFunc::GT)(">=", VFunc::GE)("=", VFunc::EQ)("+", VFunc::ADD)("-", VFunc::SUB)
-			("*", VFunc::MULT)("/", VFunc::DIV)("%", VFunc::MOD);
+		std::map<std::string, VFunc::Eopt> symToFunc =
+		{
+			{"<", VFunc::LT},{"<=", VFunc::LE},{">", VFunc::GT},{">=", VFunc::GE},{"=", VFunc::EQ},{"+", VFunc::ADD},{"-", VFunc::SUB},
+			{"*", VFunc::MULT},{"/", VFunc::DIV},{"%", VFunc::MOD}
+		};
 
 		//check keywords
 		if(opt.text == "quote")

+ 0 - 2
scripting/erm/StdInc.h

@@ -5,6 +5,4 @@
 // This header should be treated as a pre compiled header file(PCH) in the compiler building settings.
 
 // Here you can add specific libraries and macros which are specific to this project.
-#include <boost/variant.hpp>
-#include <boost/optional.hpp>
 

+ 1 - 1
server/CGameHandler.cpp

@@ -3390,7 +3390,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
 				break;
 			}
 
-			if(destinationStack && stack->ID == destinationStack->ID) //we should just move, it will be handled by following check
+			if(destinationStack && stack && stack->ID == destinationStack->ID) //we should just move, it will be handled by following check
 			{
 				destinationStack = nullptr;
 			}

+ 6 - 3
vcmi.workspace

@@ -6,8 +6,8 @@
 			<Depends filename="lib/minizip/minizip.cbp" />
 		</Project>
 		<Project filename="client/VCMI_client.cbp">
-			<Depends filename="lib/VCMI_lib.cbp" />
 			<Depends filename="server/VCMI_server.cbp" />
+			<Depends filename="lib/VCMI_lib.cbp" />
 		</Project>
 		<Project filename="server/VCMI_server.cbp">
 			<Depends filename="lib/VCMI_lib.cbp" />
@@ -17,8 +17,8 @@
 			<Depends filename="lib/VCMI_lib.cbp" />
 		</Project>
 		<Project filename="AI/VCAI/VCAI.cbp">
-			<Depends filename="lib/VCMI_lib.cbp" />
 			<Depends filename="AI/FuzzyLite/FuzzyLite.cbp" />
+			<Depends filename="lib/VCMI_lib.cbp" />
 		</Project>
 		<Project filename="AI/StupidAI/StupidAI.cbp">
 			<Depends filename="lib/VCMI_lib.cbp" />
@@ -27,13 +27,16 @@
 			<Depends filename="lib/VCMI_lib.cbp" />
 		</Project>
 		<Project filename="test/Test.cbp">
-			<Depends filename="lib/VCMI_lib.cbp" />
 			<Depends filename="client/VCMI_client.cbp" />
 			<Depends filename="server/VCMI_server.cbp" />
 			<Depends filename="AI/EmptyAI/EmptyAI.cbp" />
 			<Depends filename="AI/VCAI/VCAI.cbp" />
 			<Depends filename="AI/StupidAI/StupidAI.cbp" />
 			<Depends filename="AI/BattleAI/BattleAI.cbp" />
+			<Depends filename="lib/VCMI_lib.cbp" />
+		</Project>
+		<Project filename="scripting/erm/ERM.cbp">
+			<Depends filename="lib/VCMI_lib.cbp" />
 		</Project>
 	</Workspace>
 </CodeBlocks_workspace_file>

+ 4 - 1
vcmibuilder

@@ -56,7 +56,7 @@ then
 #	echo " --download       " "Automatically download optional package using wget"
 #	echo "                  " "Requires wget and Internet connection"
 #	echo
-	echo " --dest DIRECTORY " "Path where resulting data will be placed. Default is ~/.vcmi"
+	echo " --dest DIRECTORY " "Path where resulting data will be placed. Default is ~/.local/share/vcmi"
 	echo
 	echo " --validate       " "Run basic validness checks"
 	exit 0
@@ -181,6 +181,9 @@ then
 	elif [ -d "$data_dir""/Program_Files" ] 
 	then
 		mv "$data_dir"/Program_Files/* "$data_dir" 
+	elif [ -d "$data_dir""/LangInde_Program_Files" ]
+	then
+		mv "$data_dir"/LangInde_Program_Files/* "$data_dir"
 	else
 		echo "Error: failed to find extracted game files!"
 		echo "Extracted directories are: "