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 <[email protected]>
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

_______________________________________________
Pkg-games-commits mailing list
[email protected]
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-games-commits

Reply via email to