[spring] 03/06: Imported Upstream version 103.0+dfsg

Markus Koschany apo at moszumanska.debian.org
Sat Jul 23 21:58:52 UTC 2016


This is an automated email from the git hooks/post-receive script.

apo pushed a commit to branch master
in repository spring.

commit c254b140fbc1a6037b82143125cd075e3d75ee8a
Author: Markus Koschany <apo at debian.org>
Date:   Sat Jul 23 22:21:42 2016 +0200

    Imported Upstream version 103.0+dfsg
---
 AI/Skirmish/HughAI/README                        |   4 +-
 AI/Skirmish/HughAI/data/AIInfo.lua               |   2 +-
 AI/Skirmish/KAIK/data/AIInfo.lua                 |   2 +-
 VERSION                                          |   2 +-
 buildbot/slave/win/make_installer.sh             |   2 +-
 doc/changelog.txt                                |  18 +++
 doc/releasechecklist.txt                         |   9 +-
 rts/Game/Game.cpp                                |   7 ++
 rts/Game/GameHelper.cpp                          |  10 +-
 rts/Game/GameHelper.h                            |   1 +
 rts/Game/PreGame.cpp                             |   2 +-
 rts/Game/SyncedGameCommands.cpp                  |   5 +-
 rts/Game/UnsyncedGameCommands.cpp                |   5 +-
 rts/Lua/LuaArchive.cpp                           |   4 +-
 rts/Lua/LuaSyncedCtrl.cpp                        |  23 ++++
 rts/Lua/LuaSyncedCtrl.h                          |   2 +
 rts/Rendering/Env/Particles/ProjectileDrawer.cpp |  10 +-
 rts/Rendering/FeatureDrawer.cpp                  |  10 +-
 rts/Rendering/Textures/S3OTextureHandler.cpp     |   2 +-
 rts/Rendering/UnitDrawer.cpp                     | 142 +++++++++++++----------
 rts/Rendering/UnitDrawer.h                       |   6 +-
 rts/Sim/CMakeLists.txt                           |   1 +
 rts/Sim/Misc/BuildingMaskMap.cpp                 |  33 ++++++
 rts/Sim/Misc/BuildingMaskMap.h                   |  37 ++++++
 rts/Sim/Misc/ModInfo.cpp                         |   3 +
 rts/Sim/Misc/ModInfo.h                           |   2 +
 rts/Sim/MoveTypes/GroundMoveType.cpp             |   5 +-
 rts/Sim/MoveTypes/MoveDefHandler.cpp             |  11 +-
 rts/Sim/MoveTypes/MoveMath/MoveMath.cpp          |  34 +++++-
 rts/Sim/MoveTypes/MoveMath/MoveMath.h            |   1 +
 rts/Sim/Units/UnitDef.cpp                        |   1 +
 rts/Sim/Units/UnitDef.h                          |   3 +
 rts/System/TimeProfiler.cpp                      |   4 +
 33 files changed, 304 insertions(+), 99 deletions(-)

diff --git a/AI/Skirmish/HughAI/README b/AI/Skirmish/HughAI/README
index 18a8ac2..b7df31c 100644
--- a/AI/Skirmish/HughAI/README
+++ b/AI/Skirmish/HughAI/README
@@ -1,8 +1,8 @@
 Java AI for Spring, HughAI
 
-Spring can be found at http://springrts.com
+Spring can be found at https://springrts.com
 
 More details on HughAI:
 
-http://springrts.com/wiki/AI:HughAI
+https://springrts.com/wiki/AI:HughAI
 
diff --git a/AI/Skirmish/HughAI/data/AIInfo.lua b/AI/Skirmish/HughAI/data/AIInfo.lua
index 3f62bc3..b6715e1 100644
--- a/AI/Skirmish/HughAI/data/AIInfo.lua
+++ b/AI/Skirmish/HughAI/data/AIInfo.lua
@@ -26,7 +26,7 @@ local infos = {
 	},
 	{
 		key    = 'url',
-		value  = 'http://springrts.com/wiki/AI:HughAI',
+		value  = 'https://springrts.com/wiki/AI:HughAI',
 		desc   = 'URL with more detailed info about the AI',
 	},
 	{
diff --git a/AI/Skirmish/KAIK/data/AIInfo.lua b/AI/Skirmish/KAIK/data/AIInfo.lua
index 56283ad..afaafe2 100644
--- a/AI/Skirmish/KAIK/data/AIInfo.lua
+++ b/AI/Skirmish/KAIK/data/AIInfo.lua
@@ -46,7 +46,7 @@ recommended: use only for *A mods
 
 	{
 		key    = 'url',
-		value  = 'http://springrts.com/wiki/AI:KAIK',
+		value  = 'https://springrts.com/wiki/AI:KAIK',
 		desc   = 'URL with more detailed info about the AI',
 	},
 	{
diff --git a/VERSION b/VERSION
index c27460a..23d9d3a 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-102.0
+103.0
diff --git a/buildbot/slave/win/make_installer.sh b/buildbot/slave/win/make_installer.sh
index 8711f00..9d4f387 100755
--- a/buildbot/slave/win/make_installer.sh
+++ b/buildbot/slave/win/make_installer.sh
@@ -74,7 +74,7 @@ ${SEVENZIP} ${MIN_PORTABLE_ARCHIVE} ${INSTALLDIR}/* -xr!*.dbg &
 # Update 2016/07/06 ZK is yet to support, so only stable releases will have a zipped archive,
 # and that's because we're feeling nice.
 if [ "$OUTPUTDIR" == "win32" ] && [ x${BRANCH} = xmaster ]; then
-	(cd ${INSTALLDIR} && ${ZIP} ${MIN_PORTABLE_ZIP} * -x spring-headless.exe spring-dedicated.exe \*.dbg) &
+	(cd ${INSTALLDIR} && ${ZIP} ${MIN_PORTABLE_ZIP} * -x spring-headless.exe \*.dbg) &
 fi
 
 # compress UnitTests
diff --git a/doc/changelog.txt b/doc/changelog.txt
index 57de76e..cc10832 100644
--- a/doc/changelog.txt
+++ b/doc/changelog.txt
@@ -2,6 +2,24 @@ Spring changelog
 (since 85.0: "!" prefix indicate backward compatibility broke)
 (numbers in brackets normally mean the mantis ticket ID)
 
+-- 103.0 --------------------------------------------------------
+General:
+ - Fix & Improve performace
+ - Add 'allowTake' modoption (default: true) to enable/disable /take (by lamer)
+
+Sim:
+ - Add new UnitDef tag "buildingMask" and LuaSyncedCtrl function "SetSquareBuildingMask". (by ivand)
+   Both used in conjunction to allow/disallow construction of certain unit types (via setting buildingMask)
+   on certain tiles (via SetSquareBuildingMask). By default all tiles and buildings have mask of 1
+
+Rendering:
+ - Ghosted buildings are now consistent when changing specTeam/specFullView
+
+
+Bugfixes:
+ - Fix #5301 Units with restricted firearcs do not turn to aim
+ - Fix #5302 extreme slowdown
+
 -- 102.0 --------------------------------------------------------
 General:
  - Fix & Improve LoS performance
diff --git a/doc/releasechecklist.txt b/doc/releasechecklist.txt
index cfd3a13..d4e63aa 100644
--- a/doc/releasechecklist.txt
+++ b/doc/releasechecklist.txt
@@ -30,14 +30,14 @@ Release Time
 		git reset --hard origin/master
 		git merge develop --no-ff
 2) Tag the release:
-		export REL_VERS=99.0
+		export REL_VERS=102.0
 		git tag -a -m "${REL_VERS} release [changed APIs: Lua, unitsync, AI]" ${REL_VERS}
 3) switch back your local branch to develop so you don't commit into the master branch by accident:
 		git checkout develop
 4) Tag the develop branch:
 		git tag -a -m "dev version after the ${REL_VERS} release" ${REL_VERS}.1
 5) Make sure it looks correct:
-		gitk master develop &
+		gitk master develop
 6) POINT OF NO RETURN: Push to the main repo:
 		git push --tags origin develop master
 7) The Buildbot should automaticly start build the release on the buildslaves, wait for it until all builds are done,
@@ -45,8 +45,9 @@ Release Time
 8) Write the news post for the springrts.com frontpage, while waiting for the
    buildbot to compile the master branch.
 9) Check if everything went fine on http://buildbot.springrts.com/waterfall and fetch these archives:
-		wget https://springrts.com/dl/buildbot/default/master/${REL_VERS}/win32/spring_${REL_VERS}.exe
-		wget https://springrts.com/dl/buildbot/default/master/${REL_VERS}/win32/spring_${REL_VERS}_portable.7z
+		wget https://springrts.com/dl/buildbot/default/master/${REL_VERS}/win32/spring_${REL_VERS}_win32.exe
+		wget https://springrts.com/dl/buildbot/default/master/${REL_VERS}/win32/spring_${REL_VERS}_win32-minimal-portable.7z
+		wget https://springrts.com/dl/buildbot/default/master/${REL_VERS}/win64/spring_${REL_VERS}_win64-minimal-portable.7z
 		wget https://springrts.com/dl/buildbot/default/master/${REL_VERS}/osx64/spring_${REL_VERS}_MacOSX-10.6-SnowLeopard.zip
 		wget https://springrts.com/dl/buildbot/default/master/${REL_VERS}/linux32/spring_${REL_VERS}_minimal-portable-linux32-static.7z
 		wget https://springrts.com/dl/buildbot/default/master/${REL_VERS}/linux64/spring_${REL_VERS}_minimal-portable-linux64-static.7z
diff --git a/rts/Game/Game.cpp b/rts/Game/Game.cpp
index d93d3e4..04c6f2b 100644
--- a/rts/Game/Game.cpp
+++ b/rts/Game/Game.cpp
@@ -69,6 +69,7 @@
 #include "Sim/Misc/DamageArrayHandler.h"
 #include "Sim/Misc/GeometricObjects.h"
 #include "Sim/Misc/GroundBlockingObjectMap.h"
+#include "Sim/Misc/BuildingMaskMap.h"
 #include "Sim/Misc/LosHandler.h"
 #include "Sim/Misc/ModInfo.h"
 #include "Sim/Misc/InterceptHandler.h"
@@ -418,6 +419,7 @@ void CGame::LoadMap(const std::string& mapName)
 
 		readMap = CReadMap::LoadMap(mapName);
 		groundBlockingObjectMap = new CGroundBlockingObjectMap(mapDims.mapSquares);
+		buildingMaskMap = new BuildingMaskMap();
 	}
 
 	LEAVE_SYNCED_CODE();
@@ -826,6 +828,7 @@ void CGame::KillSimulation()
 	SafeDelete(readMap);
 	SafeDelete(smoothGround);
 	SafeDelete(groundBlockingObjectMap);
+	SafeDelete(buildingMaskMap);
 	SafeDelete(losHandler);
 	SafeDelete(mapDamage);
 	SafeDelete(quadField);
@@ -1465,6 +1468,10 @@ void CGame::SimFrame() {
 		unitScriptEngine->Tick(33);
 		wind.Update();
 		losHandler->Update();
+		// dead ghosts have to be updated in sim, after los,
+		// to make sure they represent the current knowledge correctly.
+		// should probably be split from drawer
+		unitDrawer->UpdateGhostedBuildings();
 		interceptHandler.Update(false);
 
 		teamHandler->GameFrame(gs->frameNum);
diff --git a/rts/Game/GameHelper.cpp b/rts/Game/GameHelper.cpp
index e55561e..c839ff2 100644
--- a/rts/Game/GameHelper.cpp
+++ b/rts/Game/GameHelper.cpp
@@ -12,6 +12,7 @@
 #include "Rendering/Models/3DModel.h"
 #include "Sim/Features/Feature.h"
 #include "Sim/Features/FeatureDef.h"
+#include "Sim/Misc/BuildingMaskMap.h"
 #include "Sim/Misc/CollisionHandler.h"
 #include "Sim/Misc/CollisionVolume.h"
 #include "Sim/Misc/DamageArray.h"
@@ -1088,7 +1089,7 @@ CGameHelper::BuildSquareStatus CGameHelper::TestUnitBuildSquare(
 		for (int z = z1; z < z2; z++) {
 			for (int x = x1; x < x2; x++) {
 				const float3 bpos(x * SQUARE_SIZE, buildHeight, z * SQUARE_SIZE);
-				BuildSquareStatus tbs = (bpos.IsInBounds()) ? TestBuildSquare(bpos, xrange, zrange, buildInfo.def, moveDef, feature, gu->myAllyTeam, synced) : BUILDSQUARE_BLOCKED;
+				BuildSquareStatus tbs = (bpos.IsInBounds()) ? TestBuildSquare(bpos, xrange, zrange, buildInfo.def, moveDef, feature, gu->myAllyTeam, buildInfo.def->buildingMask, synced) : BUILDSQUARE_BLOCKED;
 
 				if (tbs != BUILDSQUARE_BLOCKED) {
 					// test if build-position overlaps a queued command
@@ -1126,7 +1127,7 @@ CGameHelper::BuildSquareStatus CGameHelper::TestUnitBuildSquare(
 		// this can be called in either context
 		for (int z = z1; z < z2; z++) {
 			for (int x = x1; x < x2; x++) {
-				canBuild = std::min(canBuild, TestBuildSquare(float3(x * SQUARE_SIZE, buildHeight, z * SQUARE_SIZE), xrange, zrange, buildInfo.def, moveDef, feature, allyteam, synced));
+				canBuild = std::min(canBuild, TestBuildSquare(float3(x * SQUARE_SIZE, buildHeight, z * SQUARE_SIZE), xrange, zrange, buildInfo.def, moveDef, feature, allyteam, buildInfo.def->buildingMask, synced));
 
 				if (canBuild == BUILDSQUARE_BLOCKED) {
 					return BUILDSQUARE_BLOCKED;
@@ -1146,6 +1147,7 @@ CGameHelper::BuildSquareStatus CGameHelper::TestBuildSquare(
 	const MoveDef* moveDef,
 	CFeature*& feature,
 	int allyteam,
+	boost::uint16_t mask,
 	bool synced
 ) {
 	assert(pos.IsInBounds());
@@ -1157,6 +1159,10 @@ CGameHelper::BuildSquareStatus CGameHelper::TestBuildSquare(
 	if (!unitDef->CheckTerrainConstraints(moveDef, groundHeight))
 		return BUILDSQUARE_BLOCKED;
 
+	if (!buildingMaskMap->TestTileMaskUnsafe(sqx >> 1, sqz >> 1, mask))
+		return BUILDSQUARE_BLOCKED;
+	
+
 	// check maxHeightDif constraint (structures only)
 	//
 	// if we are capable of floating, only test local
diff --git a/rts/Game/GameHelper.h b/rts/Game/GameHelper.h
index ecb57e4..d6c3726 100644
--- a/rts/Game/GameHelper.h
+++ b/rts/Game/GameHelper.h
@@ -91,6 +91,7 @@ public:
 		const MoveDef* moveDef,
 		CFeature *&feature,
 		int allyteam,
+		boost::uint16_t mask,
 		bool synced
 	);
 
diff --git a/rts/Game/PreGame.cpp b/rts/Game/PreGame.cpp
index 1b04966..8bb3628 100644
--- a/rts/Game/PreGame.cpp
+++ b/rts/Game/PreGame.cpp
@@ -157,7 +157,7 @@ bool CPreGame::Draw()
 	font->glFormat(0.5f,0.25f,0.8f,FONT_CENTER | FONT_SCALE | FONT_NORM, "Press SHIFT + ESC to quit");
 	// credits
 	font->glFormat(0.5f,0.06f,1.0f,FONT_CENTER | FONT_SCALE | FONT_NORM, "Spring %s", SpringVersion::GetFull().c_str());
-	font->glPrint(0.5f,0.02f,0.6f,FONT_CENTER | FONT_SCALE | FONT_NORM, "This program is distributed under the GNU General Public License, see license.html for more info");
+	font->glPrint(0.5f,0.02f,0.6f,FONT_CENTER | FONT_SCALE | FONT_NORM, "This program is distributed under the GNU General Public License, see doc/LICENSE for more info");
 
 	font->End();
 
diff --git a/rts/Game/SyncedGameCommands.cpp b/rts/Game/SyncedGameCommands.cpp
index b749afe..4aeceeb 100644
--- a/rts/Game/SyncedGameCommands.cpp
+++ b/rts/Game/SyncedGameCommands.cpp
@@ -20,6 +20,7 @@
 #include "Sim/Misc/GlobalSynced.h"
 #include "Sim/Misc/LosHandler.h"
 #include "Sim/Misc/TeamHandler.h"
+#include "Sim/Misc/ModInfo.h"
 #include "Sim/Projectiles/ExplosionGenerator.h"
 #include "Sim/Units/UnitDefHandler.h"
 #include "Sim/Units/UnitHandler.h"
@@ -490,7 +491,9 @@ void SyncedGameCommands::AddDefaultActionExecutors() {
 	AddActionExecutor(new DesyncActionExecutor());
 #endif // defined DEBUG
 	AddActionExecutor(new AtmActionExecutor());
-	AddActionExecutor(new TakeActionExecutor());
+	if (modInfo.allowTake) {
+		AddActionExecutor(new TakeActionExecutor());
+	}
 	AddActionExecutor(new SkipActionExecutor());
 }
 
diff --git a/rts/Game/UnsyncedGameCommands.cpp b/rts/Game/UnsyncedGameCommands.cpp
index d6a4a61..b1869a1 100644
--- a/rts/Game/UnsyncedGameCommands.cpp
+++ b/rts/Game/UnsyncedGameCommands.cpp
@@ -56,6 +56,7 @@
 #include "Lua/LuaUI.h"
 #include "Sim/MoveTypes/MoveDefHandler.h"
 #include "Sim/Misc/TeamHandler.h"
+#include "Sim/Misc/ModInfo.h"
 #include "Sim/Units/UnitDef.h"
 #include "Sim/Units/UnitDefHandler.h"
 #include "Sim/Units/Scripts/UnitScript.h"
@@ -3212,7 +3213,9 @@ void UnsyncedGameCommands::AddDefaultActionExecutors() {
 	AddActionExecutor(new RedirectToSyncedActionExecutor("Desync"));
 #endif
 	AddActionExecutor(new RedirectToSyncedActionExecutor("Resync"));
-	AddActionExecutor(new RedirectToSyncedActionExecutor("Take"));
+	if (modInfo.allowTake) {
+		AddActionExecutor(new RedirectToSyncedActionExecutor("Take"));
+	}
 	AddActionExecutor(new RedirectToSyncedActionExecutor("LuaRules"));
 	AddActionExecutor(new RedirectToSyncedActionExecutor("LuaGaia"));
 	AddActionExecutor(new CommandListActionExecutor());
diff --git a/rts/Lua/LuaArchive.cpp b/rts/Lua/LuaArchive.cpp
index 4b09814..4c02662 100644
--- a/rts/Lua/LuaArchive.cpp
+++ b/rts/Lua/LuaArchive.cpp
@@ -220,10 +220,10 @@ int LuaArchive::GetAvailableAIs(lua_State* L)
 
 	// load selected archives to get lua ais
 	if (!gameArchivePath.empty()) {
-		vfsHandler->AddArchive(gameArchivePath, true);
+		vfsHandler->AddArchive(gameArchivePath, false);
 	}
 	if (!mapArchivePath.empty()) {
-		vfsHandler->AddArchive(mapArchivePath, true);
+		vfsHandler->AddArchive(mapArchivePath, false);
 	}
 
 	const IAILibraryManager::T_skirmishAIKeys& skirmishAIKeys = aiLibManager->GetSkirmishAIKeys();
diff --git a/rts/Lua/LuaSyncedCtrl.cpp b/rts/Lua/LuaSyncedCtrl.cpp
index 17d580f..e4fdaf6 100644
--- a/rts/Lua/LuaSyncedCtrl.cpp
+++ b/rts/Lua/LuaSyncedCtrl.cpp
@@ -45,6 +45,7 @@
 #include "Sim/Misc/Team.h"
 #include "Sim/Misc/TeamHandler.h"
 #include "Sim/Misc/QuadField.h"
+#include "Sim/Misc/BuildingMaskMap.h"
 #include "Sim/MoveTypes/AAirMoveType.h"
 #include "Sim/Path/IPathManager.h"
 #include "Sim/Projectiles/ExplosionGenerator.h"
@@ -297,6 +298,8 @@ bool LuaSyncedCtrl::PushEntries(lua_State* L)
 	REGISTER_LUA_CFUNC(SetMapSquareTerrainType);
 	REGISTER_LUA_CFUNC(SetTerrainTypeData);
 
+	REGISTER_LUA_CFUNC(SetSquareBuildingMask);
+
 	REGISTER_LUA_CFUNC(UnitWeaponFire);
 	REGISTER_LUA_CFUNC(UnitWeaponHoldFire);
 
@@ -3949,6 +3952,26 @@ int LuaSyncedCtrl::SetTerrainTypeData(lua_State* L)
 /******************************************************************************/
 /******************************************************************************/
 
+int LuaSyncedCtrl::SetSquareBuildingMask(lua_State* L)
+{
+	const int x = luaL_checkint(L, 1);
+	const int z = luaL_checkint(L, 2);
+	const int mask = luaL_checkint(L, 3);	
+	if (mask < 0 || mask > USHRT_MAX) {
+		luaL_error(L, "Incorrect value of mask: %s(%d, %d, %d)", __FUNCTION__, x, z, mask);
+		return 0;
+	}	
+	const bool result = buildingMaskMap->SetTileMask(x, z, (boost::uint16_t)mask);
+	if (!result) {
+		luaL_error(L, "Invalid values supplied: %s(%d, %d, %d)", __FUNCTION__, x, z, mask);
+		return 0;
+	}
+	return 0; //no error = success
+}
+
+/******************************************************************************/
+/******************************************************************************/
+
 int LuaSyncedCtrl::UnitWeaponFire(lua_State* L)
 {
 	CUnit* unit = ParseUnit(L, __FUNCTION__, 1);
diff --git a/rts/Lua/LuaSyncedCtrl.h b/rts/Lua/LuaSyncedCtrl.h
index 475d00b..c49375b 100644
--- a/rts/Lua/LuaSyncedCtrl.h
+++ b/rts/Lua/LuaSyncedCtrl.h
@@ -171,6 +171,8 @@ class LuaSyncedCtrl
 		static int SetMapSquareTerrainType(lua_State* L);
 		static int SetTerrainTypeData(lua_State* L);
 
+		static int SetSquareBuildingMask(lua_State* L);
+
 		static int UnitWeaponFire(lua_State* L);
 		static int UnitWeaponHoldFire(lua_State* L);
 
diff --git a/rts/Rendering/Env/Particles/ProjectileDrawer.cpp b/rts/Rendering/Env/Particles/ProjectileDrawer.cpp
index 6c2d9e2..e8e8422 100644
--- a/rts/Rendering/Env/Particles/ProjectileDrawer.cpp
+++ b/rts/Rendering/Env/Particles/ProjectileDrawer.cpp
@@ -419,18 +419,20 @@ void CProjectileDrawer::DrawProjectileNow(CProjectile* pro, bool drawReflection,
 	if (!CanDrawProjectile(pro, pro->owner()))
 		return;
 
+
 	if (drawRefraction && (pro->drawPos.y > pro->GetDrawRadius()) /*!pro->IsInWater()*/)
 		return;
 	if (drawReflection && !CUnitDrawer::ObjectVisibleReflection(pro->drawPos, camera->GetPos(), pro->GetDrawRadius()))
 		return;
 
-	if (!camera->InView(pro->drawPos, pro->GetDrawRadius()))
+	const CCamera* cam = CCamera::GetActiveCamera();
+	if (!cam->InView(pro->drawPos, pro->GetDrawRadius()))
 		return;
 
 	DrawProjectileModel(pro);
 
 	if (pro->drawSorted) {
-		pro->SetSortDist(camera->ProjectedDistance(pro->pos));
+		pro->SetSortDist(cam->ProjectedDistance(pro->pos));
 		zSortedProjectiles.insert(pro);
 	} else {
 		unsortedProjectiles.push_back(pro);
@@ -460,6 +462,10 @@ void CProjectileDrawer::DrawProjectilesSetShadow(const std::vector<CProjectile*>
 void CProjectileDrawer::DrawProjectileShadow(CProjectile* p)
 {
 	if (CanDrawProjectile(p, p->owner())) {
+		const CCamera* cam = CCamera::GetActiveCamera();
+		if (!cam->InView(p->drawPos, p->GetDrawRadius()))
+			return;
+
 		// if this returns false, then projectile is
 		// neither weapon nor piece, or has no model
 		if (DrawProjectileModel(p))
diff --git a/rts/Rendering/FeatureDrawer.cpp b/rts/Rendering/FeatureDrawer.cpp
index ddb5edf..3073a6f 100644
--- a/rts/Rendering/FeatureDrawer.cpp
+++ b/rts/Rendering/FeatureDrawer.cpp
@@ -248,8 +248,6 @@ inline void CFeatureDrawer::UpdateDrawPos(CFeature* f)
 {
 	f->drawPos    = f->GetDrawPos(globalRendering->timeOffset);
 	f->drawMidPos = f->GetMdlDrawMidPos();
-
-	f->UpdateTransform(f->drawPos, false);
 }
 
 
@@ -643,8 +641,11 @@ void CFeatureDrawer::FlagVisibleFeatures(
 
 
 					if (drawShadowPass) {
-						// no shadows for fully alpha-faded features from player's POV
-						f->drawFlag = CFeature::FD_SHADOW_FLAG * SetFeatureDrawAlpha(f, playerCam, sqFadeDistBegin, sqFadeDistEnd);
+						if (SetFeatureDrawAlpha(f, playerCam, sqFadeDistBegin, sqFadeDistEnd)) {
+							// no shadows for fully alpha-faded features from player's POV
+							f->UpdateTransform(f->drawPos, false);
+							f->drawFlag = CFeature::FD_SHADOW_FLAG;
+						}
 						continue;
 					}
 
@@ -656,6 +657,7 @@ void CFeatureDrawer::FlagVisibleFeatures(
 
 
 					if (SetFeatureDrawAlpha(f, cam, sqFadeDistBegin, sqFadeDistEnd)) {
+						f->UpdateTransform(f->drawPos, false);
 						f->drawFlag += (CFeature::FD_OPAQUE_FLAG * (f->drawAlpha == 1.0f));
 						f->drawFlag += (CFeature::FD_ALPHAF_FLAG * (f->drawAlpha <  1.0f));
 						continue;
diff --git a/rts/Rendering/Textures/S3OTextureHandler.cpp b/rts/Rendering/Textures/S3OTextureHandler.cpp
index 1448a8e..8814ca4 100644
--- a/rts/Rendering/Textures/S3OTextureHandler.cpp
+++ b/rts/Rendering/Textures/S3OTextureHandler.cpp
@@ -140,7 +140,7 @@ unsigned int CS3OTextureHandler::LoadAndCacheTexture(
 	if (preloadCall)
 		return 0;
 
-	const unsigned int texID = bitmap->CreateTexture(true);
+	const unsigned int texID = bitmap->CreateMipMapTexture();
 
 	textureCache[textureName] = {
 		texID,
diff --git a/rts/Rendering/UnitDrawer.cpp b/rts/Rendering/UnitDrawer.cpp
index 536b970..f162f4a 100644
--- a/rts/Rendering/UnitDrawer.cpp
+++ b/rts/Rendering/UnitDrawer.cpp
@@ -237,6 +237,9 @@ CUnitDrawer::CUnitDrawer(): CEventClient("[CUnitDrawer]", 271828, false)
 		alphaModelRenderers[modelType] = IModelRenderContainer::GetInstance(modelType);
 	}
 
+	deadGhostBuildings.resize(teamHandler->ActiveAllyTeams());
+	liveGhostBuildings.resize(teamHandler->ActiveAllyTeams());
+
 	// LH must be initialized before drawer-state is initialized
 	lightHandler.Init(2U, configHandler->GetInt("MaxDynamicModelLights"));
 
@@ -280,16 +283,20 @@ CUnitDrawer::~CUnitDrawer()
 		groundDecals->ForceRemoveSolidObject(u);
 	}
 
-	for (int modelType = MODELTYPE_3DO; modelType < MODELTYPE_OTHER; modelType++) {
-		for (GhostSolidObject* ghost: deadGhostBuildings[modelType]) {
-			// <ghost> might be the gbOwner of a decal; groundDecals is deleted after us
-			groundDecals->GhostDestroyed(ghost);
-			delete ghost;
-		}
+	for (int allyTeam = 0; allyTeam < deadGhostBuildings.size(); ++allyTeam) {
+		for (int modelType = MODELTYPE_3DO; modelType < MODELTYPE_OTHER; modelType++) {
+			for (GhostSolidObject* ghost: deadGhostBuildings[allyTeam][modelType]) {
+				// <ghost> might be the gbOwner of a decal; groundDecals is deleted after us
+				groundDecals->GhostDestroyed(ghost);
+				delete ghost;
+			}
 
-		deadGhostBuildings[modelType].clear();
-		liveGhostBuildings[modelType].clear();
+			deadGhostBuildings[allyTeam][modelType].clear();
+			liveGhostBuildings[allyTeam][modelType].clear();
+		}
 	}
+	deadGhostBuildings.clear();
+	liveGhostBuildings.clear();
 
 
 	for (int modelType = MODELTYPE_3DO; modelType < MODELTYPE_OTHER; modelType++) {
@@ -749,7 +756,8 @@ void CUnitDrawer::DrawAlphaUnits(int modelType)
 	}
 
 	// living and dead ghosted buildings
-	DrawGhostedBuildings(modelType);
+	if (!gu->spectatingFullView)
+		DrawGhostedBuildings(modelType);
 }
 
 inline void CUnitDrawer::DrawAlphaUnit(CUnit* unit, int modelType, bool drawGhostBuildingsPass) {
@@ -870,47 +878,53 @@ void CUnitDrawer::DrawAlphaAIUnitBorder(const TempDrawUnit& unit)
 	glEnable(GL_TEXTURE_2D);
 }
 
-
+void CUnitDrawer::UpdateGhostedBuildings()
+{
+	for (int allyTeam = 0; allyTeam < deadGhostBuildings.size(); ++allyTeam) {
+		for (int modelType = MODELTYPE_3DO; modelType < MODELTYPE_OTHER; modelType++) {
+			auto& dgb = deadGhostBuildings[allyTeam][modelType];
+
+			for (auto it = dgb.begin(); it != dgb.end(); ) {
+				if (losHandler->InLos((*it)->pos, allyTeam)) {
+					// obtained LOS on the ghost of a dead building
+					groundDecals->GhostDestroyed(*it);
+
+					delete *it;
+					*it = dgb.back();
+					dgb.pop_back();
+				} else {
+					++it;
+				}
+			}
+		}
+	}
+}
 
 void CUnitDrawer::DrawGhostedBuildings(int modelType)
 {
-	std::vector<GhostSolidObject*>& deadGhostedBuildings = deadGhostBuildings[modelType];
-	std::vector<CUnit*>& liveGhostedBuildings = liveGhostBuildings[modelType];
+	assert((unsigned) gu->myAllyTeam < deadGhostBuildings.size());
+	std::vector<GhostSolidObject*>& deadGhostedBuildings = deadGhostBuildings[gu->myAllyTeam][modelType];
+	std::vector<CUnit*>& liveGhostedBuildings = liveGhostBuildings[gu->myAllyTeam][modelType];
 
 	glColor4f(0.6f, 0.6f, 0.6f, alphaValues.y);
 
 	// buildings that died while ghosted
-	for (auto it = deadGhostedBuildings.begin(); it != deadGhostedBuildings.end(); ) {
-		if (losHandler->InLos((*it)->pos, gu->myAllyTeam) || gu->spectatingFullView) {
-			// obtained LOS on the ghost of a dead building
-			groundDecals->GhostDestroyed(*it);
-
-			delete *it;
-			*it = deadGhostedBuildings.back();
-			deadGhostedBuildings.pop_back();
-		} else {
-			if (camera->InView((*it)->pos, (*it)->model->GetDrawRadius())) {
-				glPushMatrix();
-				glTranslatef3((*it)->pos);
-				glRotatef((*it)->facing * 90.0f, 0, 1, 0);
-
-				BindModelTypeTexture(modelType, (*it)->model->textureType);
-				SetTeamColour((*it)->team, float2(alphaValues.y, 1.0f));
+	for (auto it = deadGhostedBuildings.begin(); it != deadGhostedBuildings.end(); ++it) {
+		if (camera->InView((*it)->pos, (*it)->model->GetDrawRadius())) {
+			glPushMatrix();
+			glTranslatef3((*it)->pos);
+			glRotatef((*it)->facing * 90.0f, 0, 1, 0);
 
-				(*it)->model->DrawStatic();
-				glPopMatrix();
-			}
+			BindModelTypeTexture(modelType, (*it)->model->textureType);
+			SetTeamColour((*it)->team, float2(alphaValues.y, 1.0f));
 
-			++it;
+			(*it)->model->DrawStatic();
+			glPopMatrix();
 		}
 	}
 
-	if (!gu->spectatingFullView) {
-		for (CUnit* u: liveGhostedBuildings) {
-			// because of team switching via cheat, ghost buildings can exist for units in LOS
-			if (!(u->losStatus[gu->myAllyTeam] & LOS_INLOS))
-				DrawAlphaUnit(u, modelType, true);
-		}
+	for (CUnit* u: liveGhostedBuildings) {
+		DrawAlphaUnit(u, modelType, true);
 	}
 }
 
@@ -1744,24 +1758,27 @@ void CUnitDrawer::RenderUnitDestroyed(const CUnit* unit) {
 
 	// TODO - make ghosted buildings per allyTeam - so they are correctly dealt with
 	// when spectating
-	if (unitDef->IsBuildingUnit() && gameSetup->ghostedBuildings &&
-		!(u->losStatus[gu->myAllyTeam] & (LOS_INLOS | LOS_CONTRADAR)) &&
-		(u->losStatus[gu->myAllyTeam] & (LOS_PREVLOS)) && !gu->spectatingFullView
-	) {
-		// FIXME -- adjust decals for decoys? gets weird?
-		S3DModel* gbModel = (decoyDef == nullptr)? u->model: decoyDef->LoadModel();
-
-		GhostSolidObject* gb = new GhostSolidObject();
-		gb->pos    = u->pos;
-		gb->model  = gbModel;
-		gb->decal  = nullptr;
-		gb->facing = u->buildFacing;
-		gb->dir    = u->frontdir;
-		gb->team   = u->team;
-
-		deadGhostBuildings[gbModel->type].push_back(gb);
-
-		groundDecals->GhostCreated(u, gb);
+	for (int allyTeam = 0; allyTeam < deadGhostBuildings.size(); ++allyTeam) {
+		if (unitDef->IsBuildingUnit() && gameSetup->ghostedBuildings &&
+			!(u->losStatus[allyTeam] & (LOS_INLOS | LOS_CONTRADAR)) &&
+			(u->losStatus[allyTeam] & (LOS_PREVLOS))
+		) {
+			// FIXME -- adjust decals for decoys? gets weird?
+			S3DModel* gbModel = (decoyDef == nullptr)? u->model: decoyDef->LoadModel();
+
+			GhostSolidObject* gb = new GhostSolidObject();
+			gb->pos    = u->pos;
+			gb->model  = gbModel;
+			gb->decal  = nullptr;
+			gb->facing = u->buildFacing;
+			gb->dir    = u->frontdir;
+			gb->team   = u->team;
+
+			deadGhostBuildings[allyTeam][gbModel->type].push_back(gb);
+
+			groundDecals->GhostCreated(u, gb);
+		}
+		VectorErase(liveGhostBuildings[allyTeam][MDL_TYPE(u)], u);
 	}
 
 	if (u->model != nullptr) {
@@ -1771,7 +1788,6 @@ void CUnitDrawer::RenderUnitDestroyed(const CUnit* unit) {
 	}
 
 	VectorErase(unsortedUnits, u);
-	VectorErase(liveGhostBuildings[MDL_TYPE(u)], u);
 
 	UpdateUnitMiniMapIcon(unit, false, true);
 	LuaObjectDrawer::SetObjectLOD(u, LUAOBJ_UNIT, 0);
@@ -1799,24 +1815,24 @@ void CUnitDrawer::UnitDecloaked(const CUnit* unit) {
 void CUnitDrawer::UnitEnteredLos(const CUnit* unit, int allyTeam) {
 	CUnit* u = const_cast<CUnit*>(unit); //cleanup
 
+	if (gameSetup->ghostedBuildings && unit->unitDef->IsImmobileUnit())
+		VectorErase(liveGhostBuildings[allyTeam][MDL_TYPE(unit)], u);
+
 	if (allyTeam != gu->myAllyTeam)
 		return;
 
-	if (gameSetup->ghostedBuildings && unit->unitDef->IsImmobileUnit())
-		VectorErase(liveGhostBuildings[MDL_TYPE(unit)], u);
-
 	UpdateUnitMiniMapIcon(unit, false, false);
 }
 
 void CUnitDrawer::UnitLeftLos(const CUnit* unit, int allyTeam) {
 	CUnit* u = const_cast<CUnit*>(unit); //cleanup
 
+	if (gameSetup->ghostedBuildings && unit->unitDef->IsImmobileUnit())
+		VectorInsertUnique(liveGhostBuildings[allyTeam][MDL_TYPE(unit)], u, true);
+
 	if (allyTeam != gu->myAllyTeam)
 		return;
 
-	if (gameSetup->ghostedBuildings && unit->unitDef->IsImmobileUnit())
-		VectorInsertUnique(liveGhostBuildings[MDL_TYPE(unit)], u, true);
-
 	UpdateUnitMiniMapIcon(unit, false, false);
 }
 
diff --git a/rts/Rendering/UnitDrawer.h b/rts/Rendering/UnitDrawer.h
index f5424dc..03dc93f 100644
--- a/rts/Rendering/UnitDrawer.h
+++ b/rts/Rendering/UnitDrawer.h
@@ -84,6 +84,8 @@ public:
 
 	void Update();
 
+	void UpdateGhostedBuildings();
+
 	void Draw(bool drawReflection, bool drawRefraction = false);
 	void DrawOpaquePass(bool deferredPass, bool drawReflection, bool drawRefraction);
 	void DrawShadowPass();
@@ -265,9 +267,9 @@ private:
 	std::array< std::vector<TempDrawUnit>, MODELTYPE_OTHER> tempAlphaUnits;
 
 	/// buildings that were in LOS_PREVLOS when they died and not in LOS since
-	std::array<std::vector<GhostSolidObject*>, MODELTYPE_OTHER> deadGhostBuildings;
+	std::vector<std::array<std::vector<GhostSolidObject*>, MODELTYPE_OTHER>> deadGhostBuildings;
 	/// buildings that left LOS but are still alive
-	std::array<std::vector<CUnit*>, MODELTYPE_OTHER> liveGhostBuildings;
+	std::vector<std::array<std::vector<CUnit*>, MODELTYPE_OTHER>> liveGhostBuildings;
 
 	/// units that are only rendered as icons this frame
 	std::vector<CUnit*> iconUnits;
diff --git a/rts/Sim/CMakeLists.txt b/rts/Sim/CMakeLists.txt
index 3d95542..ae26ac3 100644
--- a/rts/Sim/CMakeLists.txt
+++ b/rts/Sim/CMakeLists.txt
@@ -7,6 +7,7 @@ add_library(engineSim STATIC
 		"${CMAKE_CURRENT_SOURCE_DIR}/Features/FeatureDefHandler.cpp"
 		"${CMAKE_CURRENT_SOURCE_DIR}/Features/FeatureHandler.cpp"
 		"${CMAKE_CURRENT_SOURCE_DIR}/Misc/AllyTeam.cpp"
+		"${CMAKE_CURRENT_SOURCE_DIR}/Misc/BuildingMaskMap.cpp"
 		"${CMAKE_CURRENT_SOURCE_DIR}/Misc/CategoryHandler.cpp"
 		"${CMAKE_CURRENT_SOURCE_DIR}/Misc/CollisionHandler.cpp"
 		"${CMAKE_CURRENT_SOURCE_DIR}/Misc/CollisionVolume.cpp"
diff --git a/rts/Sim/Misc/BuildingMaskMap.cpp b/rts/Sim/Misc/BuildingMaskMap.cpp
new file mode 100644
index 0000000..74d6f85
--- /dev/null
+++ b/rts/Sim/Misc/BuildingMaskMap.cpp
@@ -0,0 +1,33 @@
+#include "BuildingMaskMap.h"
+#include "GlobalConstants.h"
+
+BuildingMaskMap* buildingMaskMap = nullptr;
+
+CR_BIND(BuildingMaskMap, ())
+CR_REG_METADATA(BuildingMaskMap, (
+	CR_MEMBER(maskMap)
+	))
+
+
+bool BuildingMaskMap::CheckBounds(unsigned int x, unsigned int z)
+{
+	return ((x < mapDims.hmapx) && (z < mapDims.hmapy));
+}
+
+// sets mask value for tile[x,z] in 2*SQUARE_SIZE coordinates
+bool BuildingMaskMap::SetTileMask(unsigned int x, unsigned int z, boost::uint16_t value)
+{
+	if (!CheckBounds(x, z))
+		return false;
+
+	maskMap[x + z * mapDims.hmapx] = value;
+	return true;
+}
+
+// tests previously set mask for tile[x,z] in 2*SQUARE_SIZE coordinates against supplied value
+// true - construction is allowed, false - it's not
+bool BuildingMaskMap::TestTileMaskUnsafe(unsigned int x, unsigned int z, boost::uint16_t value)
+{
+	assert(CheckBounds(x, z));
+	return (maskMap[x + z * mapDims.hmapx] & value) == value;
+}
\ No newline at end of file
diff --git a/rts/Sim/Misc/BuildingMaskMap.h b/rts/Sim/Misc/BuildingMaskMap.h
new file mode 100644
index 0000000..9db16a8
--- /dev/null
+++ b/rts/Sim/Misc/BuildingMaskMap.h
@@ -0,0 +1,37 @@
+/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
+
+#ifndef BUILDINGMASKMAP_H
+#define BUILDINGMASKMAP_H
+
+#include <vector>
+
+#include "System/creg/creg_cond.h"
+
+#include "Map/ReadMap.h"
+
+class BuildingMaskMap
+{
+
+	CR_DECLARE_STRUCT(BuildingMaskMap)
+
+public:
+	BuildingMaskMap() {
+		maskMap.clear();
+
+		// we are going to operate in 2*SQUARE_SIZE space as spring snaps buildings to 2*SQUARE_SIZE based grid
+		maskMap.resize(mapDims.hmapx * mapDims.hmapy, 1); //1st bit set to 1 constitutes for "normal tile"
+	};
+
+	bool SetTileMask(unsigned int x, unsigned int z, boost::uint16_t value);
+	bool TestTileMask(unsigned int x, unsigned int z, boost::uint16_t value);
+	bool TestTileMaskUnsafe(unsigned int x, unsigned int z, boost::uint16_t value);
+
+private:
+	bool CheckBounds(unsigned int x, unsigned int z);
+private:
+	std::vector<boost::uint16_t> maskMap;
+};
+
+extern BuildingMaskMap* buildingMaskMap;
+
+#endif
diff --git a/rts/Sim/Misc/ModInfo.cpp b/rts/Sim/Misc/ModInfo.cpp
index a485f39..680035c 100644
--- a/rts/Sim/Misc/ModInfo.cpp
+++ b/rts/Sim/Misc/ModInfo.cpp
@@ -79,6 +79,8 @@ void CModInfo::ResetState()
 
 	pathFinderSystem = PFS_TYPE_DEFAULT;
 	pfUpdateRate     = 0.0f;
+
+	allowTake = true;
 }
 
 void CModInfo::Init(const char* modArchive)
@@ -116,6 +118,7 @@ void CModInfo::Init(const char* modArchive)
 		pathFinderSystem = system.GetInt("pathFinderSystem", PFS_TYPE_DEFAULT) % PFS_NUM_TYPES;
 		pfUpdateRate = system.GetFloat("pathFinderUpdateRate", 0.007f);
 
+		allowTake = system.GetBool("allowTake", true);
 	}
 
 	{
diff --git a/rts/Sim/Misc/ModInfo.h b/rts/Sim/Misc/ModInfo.h
index aa6831f..1ec6f33 100644
--- a/rts/Sim/Misc/ModInfo.h
+++ b/rts/Sim/Misc/ModInfo.h
@@ -146,6 +146,8 @@ public:
 	/// which pathfinder system (DEFAULT/legacy or QTPFS) the mod will use
 	int pathFinderSystem;
 	float pfUpdateRate;
+
+	bool allowTake;
 };
 
 extern CModInfo modInfo;
diff --git a/rts/Sim/MoveTypes/GroundMoveType.cpp b/rts/Sim/MoveTypes/GroundMoveType.cpp
index 075f0f2..a49f72a 100644
--- a/rts/Sim/MoveTypes/GroundMoveType.cpp
+++ b/rts/Sim/MoveTypes/GroundMoveType.cpp
@@ -472,9 +472,10 @@ bool CGroundMoveType::FollowPath()
 	bool wantReverse = false;
 
 	if (WantToStop()) {
-		// keep flatFrontDir in sync; acceleration is applied along it
+		currWayPoint.y = -1.0f;
+		nextWayPoint.y = -1.0f;
+		SetMainHeading();
 		ChangeSpeed(0.0f, false);
-		ChangeHeading(owner->heading);
 	} else {
 		ASSERT_SYNCED(currWayPoint);
 		ASSERT_SYNCED(nextWayPoint);
diff --git a/rts/Sim/MoveTypes/MoveDefHandler.cpp b/rts/Sim/MoveTypes/MoveDefHandler.cpp
index 7b9707e..ef7042e 100644
--- a/rts/Sim/MoveTypes/MoveDefHandler.cpp
+++ b/rts/Sim/MoveTypes/MoveDefHandler.cpp
@@ -350,13 +350,10 @@ bool MoveDef::TestMoveSquare(
 
 	// GetPosSpeedMod only checks *one* square of terrain
 	// (heightmap/slopemap/typemap), not the blocking-map
-	for (int z = zMin; (z <= zMax) && retTestMove; z++) {
-		for (int x = xMin; (x <= xMax) && retTestMove; x++) {
-			const CMoveMath::BlockType blockBits = CMoveMath::SquareIsBlocked(*this, xTestMoveSqr + x, zTestMoveSqr + z, collider);
-
-			maxBlockBit |= blockBits;
-			retTestMove &= (!testObjects || (blockBits & CMoveMath::BLOCK_STRUCTURE) == 0);
-		}
+	if (retTestMove) {
+		const CMoveMath::BlockType blockBits = CMoveMath::RangeIsBlocked(*this, xTestMoveSqr + xMin, xTestMoveSqr + xMax, zTestMoveSqr + zMin, zTestMoveSqr + zMax, collider);
+		maxBlockBit |= blockBits;
+		retTestMove &= (!testObjects || (blockBits & CMoveMath::BLOCK_STRUCTURE) == 0);
 	}
 
 	// don't use std::min or |= because the values might be garbage
diff --git a/rts/Sim/MoveTypes/MoveMath/MoveMath.cpp b/rts/Sim/MoveTypes/MoveMath/MoveMath.cpp
index d18b9bc..18df17b 100644
--- a/rts/Sim/MoveTypes/MoveMath/MoveMath.cpp
+++ b/rts/Sim/MoveTypes/MoveMath/MoveMath.cpp
@@ -106,7 +106,6 @@ float CMoveMath::GetPosSpeedMod(const MoveDef& moveDef, unsigned xSquare, unsign
 /* Check if a given square-position is accessable by the MoveDef footprint. */
 CMoveMath::BlockType CMoveMath::IsBlockedNoSpeedModCheck(const MoveDef& moveDef, int xSquare, int zSquare, const CSolidObject* collider)
 {
-	BlockType ret = BLOCK_NONE;
 	const int xmin = xSquare - moveDef.xsizeh, xmax = xSquare + moveDef.xsizeh;
 	if ((unsigned)xmin >= mapDims.mapx || (unsigned)xmax >= mapDims.mapx)
 		return BLOCK_IMPASSABLE;
@@ -114,6 +113,7 @@ CMoveMath::BlockType CMoveMath::IsBlockedNoSpeedModCheck(const MoveDef& moveDef,
 	if ((unsigned)zmin >= mapDims.mapy || (unsigned)zmax >= mapDims.mapy)
 		return BLOCK_IMPASSABLE;
 
+	BlockType ret = BLOCK_NONE;
 	const int xstep = 2, zstep = 2;
 
 	// (footprints are point-symmetric around <xSquare, zSquare>)
@@ -252,3 +252,35 @@ CMoveMath::BlockType CMoveMath::SquareIsBlocked(const MoveDef& moveDef, int xSqu
 	return r;
 }
 
+CMoveMath::BlockType CMoveMath::RangeIsBlocked(const MoveDef& moveDef, int xmin, int xmax, int zmin, int zmax, const CSolidObject* collider)
+{
+	if ((unsigned)xmin >= mapDims.mapx || (unsigned)xmax >= mapDims.mapx)
+		return BLOCK_IMPASSABLE;
+
+	if ((unsigned)zmin >= mapDims.mapy || (unsigned)zmax >= mapDims.mapy)
+		return BLOCK_IMPASSABLE;
+
+	BlockType ret = BLOCK_NONE;
+	const int xstep = 2, zstep = 2;
+	const int tempNum = gs->GetTempNum();
+
+	// (footprints are point-symmetric around <xSquare, zSquare>)
+	for (int z = zmin; z <= zmax; z += zstep) {
+		const int zOffset = z * mapDims.mapx;
+		for (int x = xmin; x <= xmax; x += xstep) {
+			const BlockingMapCell& cell = groundBlockingObjectMap->GetCellUnsafeConst(zOffset + x);
+			for (CSolidObject* collidee: cell) {
+				if (collidee->tempNum == tempNum)
+					continue;
+
+				collidee->tempNum = tempNum;
+				ret |= ObjectBlockType(moveDef, collidee, collider);
+				if (ret & BLOCK_STRUCTURE)
+					return ret;
+			}
+		}
+	}
+
+	return ret;
+}
+
diff --git a/rts/Sim/MoveTypes/MoveMath/MoveMath.h b/rts/Sim/MoveTypes/MoveMath/MoveMath.h
index cc5ac77..e844e78 100644
--- a/rts/Sim/MoveTypes/MoveMath/MoveMath.h
+++ b/rts/Sim/MoveTypes/MoveMath/MoveMath.h
@@ -70,6 +70,7 @@ public:
 	static BlockType SquareIsBlocked(const MoveDef& moveDef, const float3& pos, const CSolidObject* collider) {
 		return (SquareIsBlocked(moveDef, pos.x / SQUARE_SIZE, pos.z / SQUARE_SIZE, collider));
 	}
+	static BlockType RangeIsBlocked(const MoveDef& moveDef, int xmin, int xmax, int zmin, int zmax, const CSolidObject* collider);
 
 public:
 	static bool noHoverWaterMove;
diff --git a/rts/Sim/Units/UnitDef.cpp b/rts/Sim/Units/UnitDef.cpp
index 298df00..fb53a2f 100644
--- a/rts/Sim/Units/UnitDef.cpp
+++ b/rts/Sim/Units/UnitDef.cpp
@@ -598,6 +598,7 @@ UnitDef::UnitDef(const LuaTable& udTable, const std::string& unitName, int id)
 	xsize = std::max(1 * SPRING_FOOTPRINT_SCALE, (udTable.GetInt("footprintX", 1) * SPRING_FOOTPRINT_SCALE));
 	zsize = std::max(1 * SPRING_FOOTPRINT_SCALE, (udTable.GetInt("footprintZ", 1) * SPRING_FOOTPRINT_SCALE));
 
+	buildingMask = (boost::uint16_t)udTable.GetInt("buildingMask", 1); //1st bit set to 1 constitutes for "normal building"
 	if (IsImmobileUnit()) {
 		CreateYardMap(udTable.GetString("yardMap", ""));
 	}
diff --git a/rts/Sim/Units/UnitDef.h b/rts/Sim/Units/UnitDef.h
index 1859f12..1a99cec 100644
--- a/rts/Sim/Units/UnitDef.h
+++ b/rts/Sim/Units/UnitDef.h
@@ -195,6 +195,9 @@ public:
 	///< (only non-mobile ground units can have these)
 	std::vector<YardMapStatus> yardmap;
 
+	///< buildingMask used to disallow construction on certain map squares
+	boost::uint16_t buildingMask;
+
 	std::vector<std::string> modelCEGTags;
 	std::vector<std::string> pieceCEGTags;
 
diff --git a/rts/System/TimeProfiler.cpp b/rts/System/TimeProfiler.cpp
index baa5411..06eecce 100644
--- a/rts/System/TimeProfiler.cpp
+++ b/rts/System/TimeProfiler.cpp
@@ -52,6 +52,8 @@ BasicTimer::BasicTimer(const std::string& myname)
 	nameIterator = hashToName.find(hash);
 	if (nameIterator == hashToName.end()) {
 		nameIterator = hashToName.insert(std::pair<int,std::string>(hash, myname)).first;
+	} else {
+		assert(nameIterator->second == myname);
 	}
 }
 
@@ -64,6 +66,8 @@ BasicTimer::BasicTimer(const char* myname)
 	nameIterator = hashToName.find(hash);
 	if (nameIterator == hashToName.end()) {
 		nameIterator = hashToName.insert(std::pair<int,std::string>(hash, myname)).first;
+	} else {
+		assert(nameIterator->second == myname);
 	}
 }
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/spring.git



More information about the Pkg-games-commits mailing list