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

