summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MCServer/Plugins/Debuggers/Debuggers.lua2
-rw-r--r--Tools/QtBiomeVisualiser/BiomeView.h1
-rw-r--r--Tools/QtBiomeVisualiser/ChunkCache.h1
-rw-r--r--Tools/QtBiomeVisualiser/ChunkLoader.h2
-rw-r--r--Tools/QtBiomeVisualiser/ChunkSource.cpp4
-rw-r--r--Tools/QtBiomeVisualiser/ChunkSource.h1
-rw-r--r--Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro1
m---------lib/SQLiteCpp0
-rw-r--r--src/Blocks/BlockHandler.cpp2
-rw-r--r--src/Defines.h2
-rw-r--r--src/Entities/Player.cpp29
-rw-r--r--src/Entities/Player.h3
-rw-r--r--src/Generating/BioGen.cpp148
-rw-r--r--src/Protocol/Protocol17x.cpp2
-rw-r--r--src/Root.cpp4
-rw-r--r--src/Server.cpp7
-rw-r--r--src/Server.h8
-rw-r--r--src/VoronoiMap.cpp91
-rw-r--r--src/VoronoiMap.h13
-rw-r--r--src/World.h3
20 files changed, 224 insertions, 100 deletions
diff --git a/MCServer/Plugins/Debuggers/Debuggers.lua b/MCServer/Plugins/Debuggers/Debuggers.lua
index 0e7e647d5..66e06cb72 100644
--- a/MCServer/Plugins/Debuggers/Debuggers.lua
+++ b/MCServer/Plugins/Debuggers/Debuggers.lua
@@ -1502,7 +1502,7 @@ function OnPlayerJoined(a_Player)
-- Test composite chat chaining:
a_Player:SendMessage(cCompositeChat()
:AddTextPart("Hello, ")
- :AddUrlPart(a_Player:GetName(), "www.mc-server.org", "u@2")
+ :AddUrlPart(a_Player:GetName(), "http://www.mc-server.org", "u@2")
:AddSuggestCommandPart(", and welcome.", "/help", "u")
:AddRunCommandPart(" SetDay", "/time set 0")
)
diff --git a/Tools/QtBiomeVisualiser/BiomeView.h b/Tools/QtBiomeVisualiser/BiomeView.h
index 86af8bcaf..f0521571d 100644
--- a/Tools/QtBiomeVisualiser/BiomeView.h
+++ b/Tools/QtBiomeVisualiser/BiomeView.h
@@ -1,6 +1,7 @@
#pragma once
#include <QWidget>
+#include <memory>
#include "ChunkCache.h"
#include "ChunkSource.h"
diff --git a/Tools/QtBiomeVisualiser/ChunkCache.h b/Tools/QtBiomeVisualiser/ChunkCache.h
index 0134bc7af..8d198f02f 100644
--- a/Tools/QtBiomeVisualiser/ChunkCache.h
+++ b/Tools/QtBiomeVisualiser/ChunkCache.h
@@ -3,6 +3,7 @@
#include <QObject>
#include <QCache>
#include <QMutex>
+#include <memory>
diff --git a/Tools/QtBiomeVisualiser/ChunkLoader.h b/Tools/QtBiomeVisualiser/ChunkLoader.h
index 3565434b9..4d026a45e 100644
--- a/Tools/QtBiomeVisualiser/ChunkLoader.h
+++ b/Tools/QtBiomeVisualiser/ChunkLoader.h
@@ -1,6 +1,8 @@
#pragma once
+
#include <QObject>
#include <QRunnable>
+#include <memory>
diff --git a/Tools/QtBiomeVisualiser/ChunkSource.cpp b/Tools/QtBiomeVisualiser/ChunkSource.cpp
index 9e0ea5751..2235816bc 100644
--- a/Tools/QtBiomeVisualiser/ChunkSource.cpp
+++ b/Tools/QtBiomeVisualiser/ChunkSource.cpp
@@ -120,8 +120,8 @@ static void biomesToImage(cChunkDef::BiomeMap & a_Biomes, Chunk::Image & a_Image
{
// Make sure the two arrays are of the same size, compile-time.
// Note that a_Image is actually 4 items per pixel, so the array is 4 times bigger:
- static const char Check1[4 * ARRAYCOUNT(a_Biomes) - ARRAYCOUNT(a_Image) + 1];
- static const char Check2[ARRAYCOUNT(a_Image) - 4 * ARRAYCOUNT(a_Biomes) + 1];
+ static const char Check1[4 * ARRAYCOUNT(a_Biomes) - ARRAYCOUNT(a_Image) + 1] = {};
+ static const char Check2[ARRAYCOUNT(a_Image) - 4 * ARRAYCOUNT(a_Biomes) + 1] = {};
// Convert the biomes into color:
for (size_t i = 0; i < ARRAYCOUNT(a_Biomes); i++)
diff --git a/Tools/QtBiomeVisualiser/ChunkSource.h b/Tools/QtBiomeVisualiser/ChunkSource.h
index a485e473a..868e4a144 100644
--- a/Tools/QtBiomeVisualiser/ChunkSource.h
+++ b/Tools/QtBiomeVisualiser/ChunkSource.h
@@ -1,5 +1,6 @@
#pragma once
#include <QString>
+#include <QMutex>
#include "Chunk.h"
diff --git a/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro b/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro
index 0b42f076d..e6b65e628 100644
--- a/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro
+++ b/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro
@@ -55,5 +55,6 @@ INCLUDEPATH += $$_PRO_FILE_PWD_ \
$$_PRO_FILE_PWD_/../../lib
+CONFIG += C++11
diff --git a/lib/SQLiteCpp b/lib/SQLiteCpp
-Subproject 203c2fb68bbf871eaf4ca98756a113d74d620de
+Subproject 55edadd56d0d6f506954ad00c3b9a5d425814a2
diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp
index cee2f4b99..30b303cfd 100644
--- a/src/Blocks/BlockHandler.cpp
+++ b/src/Blocks/BlockHandler.cpp
@@ -427,7 +427,7 @@ void cBlockHandler::DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterfac
if (a_CanDrop)
{
if ((a_Digger != NULL) && (a_Digger->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchSilkTouch) > 0))
- {
+ {
switch (m_BlockType)
{
case E_BLOCK_CAKE:
diff --git a/src/Defines.h b/src/Defines.h
index 78c58034e..6355b75b4 100644
--- a/src/Defines.h
+++ b/src/Defines.h
@@ -115,12 +115,14 @@ enum eGameMode
eGameMode_Survival = 0,
eGameMode_Creative = 1,
eGameMode_Adventure = 2,
+ eGameMode_Spectator = 3,
// Easier-to-use synonyms:
gmNotSet = eGameMode_NotSet,
gmSurvival = eGameMode_Survival,
gmCreative = eGameMode_Creative,
gmAdventure = eGameMode_Adventure,
+ gmSpectator = eGameMode_Spectator,
// These two are used to check GameMode for validity when converting from integers.
gmMax, // Gets automatically assigned
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index ea795e346..38d42be14 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -451,6 +451,11 @@ void cPlayer::CancelChargingBow(void)
void cPlayer::SetTouchGround(bool a_bTouchGround)
{
+ if (IsGameModeSpectator()) // You can fly through the ground in Spectator
+ {
+ return;
+ }
+
m_bTouchGround = a_bTouchGround;
if (!m_bTouchGround)
@@ -585,7 +590,7 @@ bool cPlayer::Feed(int a_Food, double a_Saturation)
void cPlayer::AddFoodExhaustion(double a_Exhaustion)
{
- if (!IsGameModeCreative())
+ if (!(IsGameModeCreative() || IsGameModeSpectator()))
{
m_FoodExhaustionLevel = std::min(m_FoodExhaustionLevel + a_Exhaustion, 40.0);
}
@@ -823,9 +828,9 @@ bool cPlayer::DoTakeDamage(TakeDamageInfo & a_TDI)
{
if ((a_TDI.DamageType != dtInVoid) && (a_TDI.DamageType != dtPlugin))
{
- if (IsGameModeCreative())
+ if (IsGameModeCreative() || IsGameModeSpectator())
{
- // No damage / health in creative mode if not void or plugin damage
+ // No damage / health in creative or spectator mode if not void or plugin damage
return false;
}
}
@@ -1043,6 +1048,14 @@ bool cPlayer::IsGameModeAdventure(void) const
+bool cPlayer::IsGameModeSpectator(void) const
+{
+ return (m_GameMode == gmSpectator) || // Either the player is explicitly in Spectator
+ ((m_GameMode == gmNotSet) && m_World->IsGameModeSpectator()); // or they inherit from the world and the world is Adventure
+}
+
+
+
void cPlayer::SetTeam(cTeam * a_Team)
{
@@ -1158,7 +1171,7 @@ void cPlayer::SetGameMode(eGameMode a_GameMode)
m_GameMode = a_GameMode;
m_ClientHandle->SendGameMode(a_GameMode);
- if (!IsGameModeCreative())
+ if (!(IsGameModeCreative() || IsGameModeSpectator()))
{
SetFlying(false);
SetCanFly(false);
@@ -1340,6 +1353,7 @@ void cPlayer::MoveTo( const Vector3d & a_NewPos)
void cPlayer::SetVisible(bool a_bVisible)
{
+ // Need to Check if the player or other players are in gamemode spectator, but will break compatibility
if (a_bVisible && !m_bVisible) // Make visible
{
m_bVisible = true;
@@ -1500,6 +1514,11 @@ void cPlayer::TossPickup(const cItem & a_Item)
void cPlayer::TossItems(const cItems & a_Items)
{
+ if (IsGameModeSpectator()) // Players can't toss items in spectator
+ {
+ return;
+ }
+
m_Stats.AddValue(statItemsDropped, (StatValue)a_Items.Size());
double vX = 0, vY = 0, vZ = 0;
@@ -1786,7 +1805,7 @@ bool cPlayer::SaveToDisk()
void cPlayer::UseEquippedItem(int a_Amount)
{
- if (IsGameModeCreative()) // No damage in creative
+ if (IsGameModeCreative() || IsGameModeSpectator()) // No damage in creative or spectator
{
return;
}
diff --git a/src/Entities/Player.h b/src/Entities/Player.h
index 9821cc6d9..d64dd6b99 100644
--- a/src/Entities/Player.h
+++ b/src/Entities/Player.h
@@ -171,6 +171,9 @@ public:
/** Returns true if the player is in Adventure mode, either explicitly, or by inheriting from current world */
bool IsGameModeAdventure(void) const;
+ /** Returns true if the player is in Spectator mode, either explicitly, or by inheriting from current world */
+ bool IsGameModeSpectator(void) const;
+
AString GetIP(void) const { return m_IP; } // tolua_export
/** Returns the associated team, NULL if none */
diff --git a/src/Generating/BioGen.cpp b/src/Generating/BioGen.cpp
index 60ad4e3eb..217ca8f80 100644
--- a/src/Generating/BioGen.cpp
+++ b/src/Generating/BioGen.cpp
@@ -13,72 +13,6 @@
////////////////////////////////////////////////////////////////////////////////
-// cBiomeGen:
-
-cBiomeGen * cBiomeGen::CreateBiomeGen(cIniFile & a_IniFile, int a_Seed, bool & a_CacheOffByDefault)
-{
- AString BiomeGenName = a_IniFile.GetValueSet("Generator", "BiomeGen", "");
- if (BiomeGenName.empty())
- {
- LOGWARN("[Generator] BiomeGen value not set in world.ini, using \"MultiStepMap\".");
- BiomeGenName = "MultiStepMap";
- }
-
- cBiomeGen * res = NULL;
- a_CacheOffByDefault = false;
- if (NoCaseCompare(BiomeGenName, "constant") == 0)
- {
- res = new cBioGenConstant;
- a_CacheOffByDefault = true; // we're generating faster than a cache would retrieve data :)
- }
- else if (NoCaseCompare(BiomeGenName, "checkerboard") == 0)
- {
- res = new cBioGenCheckerboard;
- a_CacheOffByDefault = true; // we're (probably) generating faster than a cache would retrieve data
- }
- else if (NoCaseCompare(BiomeGenName, "voronoi") == 0)
- {
- res = new cBioGenVoronoi(a_Seed);
- }
- else if (NoCaseCompare(BiomeGenName, "distortedvoronoi") == 0)
- {
- res = new cBioGenDistortedVoronoi(a_Seed);
- }
- else if (NoCaseCompare(BiomeGenName, "twolevel") == 0)
- {
- res = new cBioGenTwoLevel(a_Seed);
- }
- else
- {
- if (NoCaseCompare(BiomeGenName, "multistepmap") != 0)
- {
- LOGWARNING("Unknown BiomeGen \"%s\", using \"MultiStepMap\" instead.", BiomeGenName.c_str());
- }
- res = new cBioGenMultiStepMap(a_Seed);
-
- /*
- // Performance-testing:
- LOGINFO("Measuring performance of cBioGenMultiStepMap...");
- clock_t BeginTick = clock();
- for (int x = 0; x < 5000; x++)
- {
- cChunkDef::BiomeMap Biomes;
- res->GenBiomes(x * 5, x * 5, Biomes);
- }
- clock_t Duration = clock() - BeginTick;
- LOGINFO("cBioGenMultiStepMap for 5000 chunks took %d ticks (%.02f sec)", Duration, (double)Duration / CLOCKS_PER_SEC);
- //*/
- }
- res->InitializeBiomeGen(a_IniFile);
-
- return res;
-}
-
-
-
-
-
-////////////////////////////////////////////////////////////////////////////////
// cBioGenConstant:
void cBioGenConstant::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap)
@@ -402,8 +336,13 @@ void cBioGenVoronoi::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap &
void cBioGenVoronoi::InitializeBiomeGen(cIniFile & a_IniFile)
{
super::InitializeBiomeGen(a_IniFile);
- m_Voronoi.SetCellSize(a_IniFile.GetValueSetI("Generator", "VoronoiCellSize", 64));
- InitializeBiomes (a_IniFile.GetValueSet ("Generator", "VoronoiBiomes", ""));
+ int CellSize = a_IniFile.GetValueSetI("Generator", "VoronoiCellSize", 128);
+ int JitterSize = a_IniFile.GetValueSetI("Generator", "VoronoiJitterSize", CellSize);
+ int OddRowOffset = a_IniFile.GetValueSetI("Generator", "VoronoiOddRowOffset", 0);
+ m_Voronoi.SetCellSize(CellSize);
+ m_Voronoi.SetJitterSize(JitterSize);
+ m_Voronoi.SetOddRowOffset(OddRowOffset);
+ InitializeBiomes(a_IniFile.GetValueSet ("Generator", "VoronoiBiomes", ""));
}
@@ -846,9 +785,10 @@ void cBioGenTwoLevel::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap
{
for (int x = 0; x < cChunkDef::Width; x++)
{
- int MinDist1, MinDist2;
- int BiomeGroup = m_VoronoiLarge.GetValueAt(DistortX[x][z], DistortZ[x][z], MinDist1, MinDist2) / 7;
- int BiomeIdx = m_VoronoiSmall.GetValueAt(DistortX[x][z], DistortZ[x][z], MinDist1, MinDist2) / 11;
+ int SeedX, SeedZ, MinDist2;
+ int BiomeGroup = m_VoronoiLarge.GetValueAt(DistortX[x][z], DistortZ[x][z], SeedX, SeedZ, MinDist2) / 7;
+ int BiomeIdx = m_VoronoiSmall.GetValueAt(DistortX[x][z], DistortZ[x][z], SeedX, SeedZ, MinDist2) / 11;
+ int MinDist1 = (DistortX[x][z] - SeedX) * (DistortX[x][z] - SeedX) + (DistortZ[x][z] - SeedZ) * (DistortZ[x][z] - SeedZ);
cChunkDef::SetBiome(a_BiomeMap, x, z, SelectBiome(BiomeGroup, BiomeIdx, (MinDist1 < MinDist2 / 4) ? 0 : 1));
}
}
@@ -987,3 +927,69 @@ void cBioGenTwoLevel::InitializeBiomeGen(cIniFile & a_IniFile)
+
+////////////////////////////////////////////////////////////////////////////////
+// cBiomeGen:
+
+cBiomeGen * cBiomeGen::CreateBiomeGen(cIniFile & a_IniFile, int a_Seed, bool & a_CacheOffByDefault)
+{
+ AString BiomeGenName = a_IniFile.GetValueSet("Generator", "BiomeGen", "");
+ if (BiomeGenName.empty())
+ {
+ LOGWARN("[Generator] BiomeGen value not set in world.ini, using \"MultiStepMap\".");
+ BiomeGenName = "MultiStepMap";
+ }
+
+ cBiomeGen * res = NULL;
+ a_CacheOffByDefault = false;
+ if (NoCaseCompare(BiomeGenName, "constant") == 0)
+ {
+ res = new cBioGenConstant;
+ a_CacheOffByDefault = true; // we're generating faster than a cache would retrieve data :)
+ }
+ else if (NoCaseCompare(BiomeGenName, "checkerboard") == 0)
+ {
+ res = new cBioGenCheckerboard;
+ a_CacheOffByDefault = true; // we're (probably) generating faster than a cache would retrieve data
+ }
+ else if (NoCaseCompare(BiomeGenName, "voronoi") == 0)
+ {
+ res = new cBioGenVoronoi(a_Seed);
+ }
+ else if (NoCaseCompare(BiomeGenName, "distortedvoronoi") == 0)
+ {
+ res = new cBioGenDistortedVoronoi(a_Seed);
+ }
+ else if (NoCaseCompare(BiomeGenName, "twolevel") == 0)
+ {
+ res = new cBioGenTwoLevel(a_Seed);
+ }
+ else
+ {
+ if (NoCaseCompare(BiomeGenName, "multistepmap") != 0)
+ {
+ LOGWARNING("Unknown BiomeGen \"%s\", using \"MultiStepMap\" instead.", BiomeGenName.c_str());
+ }
+ res = new cBioGenMultiStepMap(a_Seed);
+
+ /*
+ // Performance-testing:
+ LOGINFO("Measuring performance of cBioGenMultiStepMap...");
+ clock_t BeginTick = clock();
+ for (int x = 0; x < 5000; x++)
+ {
+ cChunkDef::BiomeMap Biomes;
+ res->GenBiomes(x * 5, x * 5, Biomes);
+ }
+ clock_t Duration = clock() - BeginTick;
+ LOGINFO("cBioGenMultiStepMap for 5000 chunks took %d ticks (%.02f sec)", Duration, (double)Duration / CLOCKS_PER_SEC);
+ //*/
+ }
+ res->InitializeBiomeGen(a_IniFile);
+
+ return res;
+}
+
+
+
+
diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp
index 4f71b53b0..7d80e79fb 100644
--- a/src/Protocol/Protocol17x.cpp
+++ b/src/Protocol/Protocol17x.cpp
@@ -104,7 +104,7 @@ cProtocol172::cProtocol172(cClientHandle * a_Client, const AString & a_ServerAdd
// If BC is setup with ip_forward == true, it sends additional data in the login packet's ServerAddress field:
// hostname\00ip-address\00uuid\00profile-properties-as-json
AStringVector Params;
- if (SplitZeroTerminatedStrings(a_ServerAddress, Params) && (Params.size() == 4))
+ if (cRoot::Get()->GetServer()->ShouldAllowBungeeCord() && SplitZeroTerminatedStrings(a_ServerAddress, Params) && (Params.size() == 4))
{
LOGD("Player at %s connected via BungeeCord", Params[1].c_str());
m_ServerAddress = Params[0];
diff --git a/src/Root.cpp b/src/Root.cpp
index 86a497a76..966a9b4ba 100644
--- a/src/Root.cpp
+++ b/src/Root.cpp
@@ -113,8 +113,8 @@ void cRoot::Start(void)
LOG("--- Started Log ---\n");
#ifdef BUILD_ID
- LOG("MCServer " BUILD_SERIES_NAME " build id: " BUILD_ID );
- LOG("from commit id: " BUILD_COMMIT_ID " built at: " BUILD_DATETIME );
+ LOG("MCServer " BUILD_SERIES_NAME " build id: " BUILD_ID);
+ LOG("from commit id: " BUILD_COMMIT_ID " built at: " BUILD_DATETIME);
#endif
cDeadlockDetect dd;
diff --git a/src/Server.cpp b/src/Server.cpp
index 069e2a169..969ffd693 100644
--- a/src/Server.cpp
+++ b/src/Server.cpp
@@ -259,6 +259,13 @@ bool cServer::InitServer(cIniFile & a_SettingsIni)
m_ServerID = sid.str();
m_ServerID.resize(16, '0');
}
+
+ // Check if both BungeeCord and online mode are on, if so, warn the admin:
+ m_ShouldAllowBungeeCord = a_SettingsIni.GetValueSetB("Authentication", "AllowBungeeCord", false);
+ if (m_ShouldAllowBungeeCord && m_ShouldAuthenticate)
+ {
+ LOGWARNING("WARNING: BungeeCord is allowed and server set to online mode. This is unsafe and will not work properly. Disable either authentication or BungeeCord in settings.ini.");
+ }
m_ShouldLoadOfflinePlayerData = a_SettingsIni.GetValueSetB("PlayerData", "LoadOfflinePlayerData", false);
m_ShouldLoadNamedPlayerData = a_SettingsIni.GetValueSetB("PlayerData", "LoadNamedPlayerData", true);
diff --git a/src/Server.h b/src/Server.h
index f20e6932f..6d659fa40 100644
--- a/src/Server.h
+++ b/src/Server.h
@@ -131,6 +131,11 @@ public: // tolua_export
Loaded from the settings.ini [PlayerData].LoadNamedPlayerData setting. */
bool ShouldLoadNamedPlayerData(void) const { return m_ShouldLoadNamedPlayerData; }
+ /** Returns true if BungeeCord logins (that specify the player's UUID) are allowed.
+ Read from settings, admins should set this to true only when they chain to BungeeCord,
+ it makes the server vulnerable to identity theft through direct connections. */
+ bool ShouldAllowBungeeCord(void) const { return m_ShouldAllowBungeeCord; }
+
private:
friend class cRoot; // so cRoot can create and destroy cServer
@@ -230,6 +235,9 @@ private:
This allows a seamless transition from name-based to UUID-based player storage.
Loaded from the settings.ini [PlayerData].LoadNamedPlayerData setting. */
bool m_ShouldLoadNamedPlayerData;
+
+ /** True if BungeeCord handshake packets (with player UUID) should be accepted. */
+ bool m_ShouldAllowBungeeCord;
cServer(void);
diff --git a/src/VoronoiMap.cpp b/src/VoronoiMap.cpp
index 68147ebfc..5ad634fe4 100644
--- a/src/VoronoiMap.cpp
+++ b/src/VoronoiMap.cpp
@@ -59,8 +59,8 @@ void cVoronoiMap::SetOddRowOffset(int a_OddRowOffset)
int cVoronoiMap::GetValueAt(int a_X, int a_Y)
{
- int MinDist1, MinDist2;
- return GetValueAt(a_X, a_Y, MinDist1, MinDist2);
+ int SeedX, SeedY, MinDist2;
+ return GetValueAt(a_X, a_Y, SeedX, SeedY, MinDist2);
}
@@ -69,41 +69,47 @@ int cVoronoiMap::GetValueAt(int a_X, int a_Y)
int cVoronoiMap::GetValueAt(int a_X, int a_Y, int & a_MinDist)
{
- int MinDist2;
- return GetValueAt(a_X, a_Y, a_MinDist, MinDist2);
+ int SeedX, SeedY, MinDist2;
+ int res = GetValueAt(a_X, a_Y, SeedX, SeedY, MinDist2);
+ a_MinDist = (a_X - SeedX) * (a_X - SeedX) + (a_Y - SeedY) * (a_Y - SeedY);
+ return res;
}
-int cVoronoiMap::GetValueAt(int a_X, int a_Y, int & a_MinDist1, int & a_MinDist2)
+int cVoronoiMap::GetValueAt(
+ int a_X, int a_Y, // Coords to query
+ int & a_NearestSeedX, int & a_NearestSeedY, // Coords of the closest cell
+ int & a_MinDist2 // Distance to the second closest cell
+)
{
- // Note that due to historical reasons, the algorithm uses XZ coords, while the input uses XY coords.
- // This is because the algorithm was first implemented directly in the biome generators which use MC coords.
-
int CellX = a_X / m_CellSize;
- int CellZ = a_Y / m_CellSize;
+ int CellY = a_Y / m_CellSize;
- UpdateCell(CellX, CellZ);
+ UpdateCell(CellX, CellY);
// Get 5x5 neighboring cell seeds, compare distance to each. Return the value in the minumim-distance cell
+ int NearestSeedX = 0, NearestSeedY = 0;
int MinDist = m_CellSize * m_CellSize * 16; // There has to be a cell closer than this
int MinDist2 = MinDist;
int res = 0; // Will be overriden
for (int x = 0; x < 5; x++)
{
- for (int z = 0; z < 5; z++)
+ for (int y = 0; y < 5; y++)
{
- int SeedX = m_SeedX[x][z];
- int SeedZ = m_SeedZ[x][z];
+ int SeedX = m_SeedX[x][y];
+ int SeedY = m_SeedZ[x][y];
- int Dist = (SeedX - a_X) * (SeedX - a_X) + (SeedZ - a_Y) * (SeedZ - a_Y);
+ int Dist = (SeedX - a_X) * (SeedX - a_X) + (SeedY - a_Y) * (SeedY - a_Y);
if (Dist < MinDist)
{
+ NearestSeedX = SeedX;
+ NearestSeedY = SeedY;
MinDist2 = MinDist;
MinDist = Dist;
- res = m_Noise3.IntNoise2DInt(x + CellX - 2, z + CellZ - 2);
+ res = m_Noise3.IntNoise2DInt(x + CellX - 2, y + CellY - 2);
}
else if (Dist < MinDist2)
{
@@ -112,7 +118,8 @@ int cVoronoiMap::GetValueAt(int a_X, int a_Y, int & a_MinDist1, int & a_MinDist2
} // for z
} // for x
- a_MinDist1 = MinDist;
+ a_NearestSeedX = NearestSeedX;
+ a_NearestSeedY = NearestSeedY;
a_MinDist2 = MinDist2;
return res;
}
@@ -121,6 +128,58 @@ int cVoronoiMap::GetValueAt(int a_X, int a_Y, int & a_MinDist1, int & a_MinDist2
+void cVoronoiMap::FindNearestSeeds(
+ int a_X, int a_Y,
+ int & a_NearestSeedX, int & a_NearestSeedY,
+ int & a_SecondNearestSeedX, int & a_SecondNearestSeedY
+)
+{
+ int CellX = a_X / m_CellSize;
+ int CellY = a_Y / m_CellSize;
+
+ UpdateCell(CellX, CellY);
+
+ // Get 5x5 neighboring cell seeds, compare distance to each. Return the value in the minumim-distance cell
+ int NearestSeedX = 0, NearestSeedY = 0;
+ int SecondNearestSeedX = 0, SecondNearestSeedY = 0;
+ int MinDist = m_CellSize * m_CellSize * 16; // There has to be a cell closer than this
+ int MinDist2 = MinDist;
+ for (int x = 0; x < 5; x++)
+ {
+ for (int y = 0; y < 5; y++)
+ {
+ int SeedX = m_SeedX[x][y];
+ int SeedY = m_SeedZ[x][y];
+
+ int Dist = (SeedX - a_X) * (SeedX - a_X) + (SeedY - a_Y) * (SeedY - a_Y);
+ if (Dist < MinDist)
+ {
+ SecondNearestSeedX = NearestSeedX;
+ SecondNearestSeedY = NearestSeedY;
+ MinDist2 = MinDist;
+ NearestSeedX = SeedX;
+ NearestSeedY = SeedY;
+ MinDist = Dist;
+ }
+ else if (Dist < MinDist2)
+ {
+ SecondNearestSeedX = SeedX;
+ SecondNearestSeedY = SeedY;
+ MinDist2 = Dist;
+ }
+ } // for z
+ } // for x
+
+ a_NearestSeedX = NearestSeedX;
+ a_NearestSeedY = NearestSeedY;
+ a_SecondNearestSeedX = SecondNearestSeedX;
+ a_SecondNearestSeedY = SecondNearestSeedY;
+}
+
+
+
+
+
void cVoronoiMap::UpdateCell(int a_CellX, int a_CellZ)
{
// If the specified cell is currently cached, bail out:
diff --git a/src/VoronoiMap.h b/src/VoronoiMap.h
index 49f6c1da1..dfb11e9ce 100644
--- a/src/VoronoiMap.h
+++ b/src/VoronoiMap.h
@@ -40,7 +40,18 @@ public:
/** Returns the value in the cell into which the specified point lies,
and the distances to the 2 nearest Voronoi seeds. Uses a cache. */
- int GetValueAt(int a_X, int a_Y, int & a_MinDistance1, int & a_MinDistance2);
+ int GetValueAt(
+ int a_X, int a_Y, // Coords to query
+ int & a_NearestSeedX, int & a_NearestSeedY, // Coords of the closest cell's seed
+ int & a_MinDist2 // Distance to the second closest cell's seed
+ );
+
+ /** Finds the nearest and second nearest seeds, returns their coords. */
+ void FindNearestSeeds(
+ int a_X, int a_Y,
+ int & a_NearestSeedX, int & a_NearestSeedY,
+ int & a_SecondNearestSeedX, int & a_SecondNearestSeedY
+ );
protected:
/// The noise used for generating Voronoi seeds
diff --git a/src/World.h b/src/World.h
index 0c57e6611..8b40037af 100644
--- a/src/World.h
+++ b/src/World.h
@@ -188,6 +188,9 @@ public:
/** Returns true if the world is in Adventure mode */
bool IsGameModeAdventure(void) const { return (m_GameMode == gmAdventure); }
+ /** Returns true if the world is in Spectator mode */
+ bool IsGameModeSpectator(void) const { return (m_GameMode == gmSpectator); }
+
bool IsPVPEnabled(void) const { return m_bEnabledPVP; }
bool IsDeepSnowEnabled(void) const { return m_IsDeepSnowEnabled; }