summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/inifile/iniFile.cpp2
-rw-r--r--src/BlockID.h2
-rw-r--r--src/Chunk.cpp6
-rw-r--r--src/ChunkMap.cpp1
-rw-r--r--src/Entities/Entity.cpp78
-rw-r--r--src/Entities/Entity.h30
-rw-r--r--src/Entities/Player.cpp25
-rw-r--r--src/Entities/Player.h2
-rw-r--r--src/World.cpp135
-rw-r--r--src/World.h7
10 files changed, 161 insertions, 127 deletions
diff --git a/lib/inifile/iniFile.cpp b/lib/inifile/iniFile.cpp
index 30f93e5a3..2bf6c91ed 100644
--- a/lib/inifile/iniFile.cpp
+++ b/lib/inifile/iniFile.cpp
@@ -585,7 +585,7 @@ Int64 cIniFile::GetValueSetI(const AString & keyname, const AString & valuename,
AString Data;
Printf(Data, "%lld", defValue);
AString resultstring = GetValueSet(keyname, valuename, Data);
- Int64 result;
+ Int64 result = defValue;
#ifdef _WIN32
sscanf_s(resultstring.c_str(), "%lld", &result);
#else
diff --git a/src/BlockID.h b/src/BlockID.h
index 37eed8eda..08c576886 100644
--- a/src/BlockID.h
+++ b/src/BlockID.h
@@ -924,7 +924,7 @@ extern int StringToMobType(const AString & a_MobString);
extern eDimension StringToDimension(const AString & a_DimensionString);
/** Translates a dimension enum to dimension string.
-Takes a string and returns "Overworld" on failure
+Takes an eDimension enum value and returns "Overworld" on failure
*/
extern AString DimensionToString(eDimension a_Dimension);
diff --git a/src/Chunk.cpp b/src/Chunk.cpp
index 4588de9f3..7850b7e31 100644
--- a/src/Chunk.cpp
+++ b/src/Chunk.cpp
@@ -596,7 +596,7 @@ void cChunk::Tick(float a_Dt)
for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end();)
{
- if ((*itr)->IsDestroyed()) // Remove all entities that were scheduled for removal:
+ if ((*itr)->IsDestroyed()) // Remove all entities that were scheduled for removal:
{
LOGD("Destroying entity #%i (%s)", (*itr)->GetUniqueID(), (*itr)->GetClass());
MarkDirty();
@@ -604,13 +604,13 @@ void cChunk::Tick(float a_Dt)
itr = m_Entities.erase(itr);
delete ToDelete;
}
- else if ((*itr)->IsWorldTravellingFrom(m_World)) // Remove all entities that are travelling to another world
+ else if ((*itr)->IsWorldTravellingFrom(m_World)) // Remove all entities that are travelling to another world
{
MarkDirty();
(*itr)->SetWorldTravellingFrom(NULL);
itr = m_Entities.erase(itr);
}
- else if ( // If any entity moved out of the chunk, move it to the neighbor:
+ else if ( // If any entity moved out of the chunk, move it to the neighbor:
((*itr)->GetChunkX() != m_PosX) ||
((*itr)->GetChunkZ() != m_PosZ)
)
diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp
index 3cfa5c3f5..e91f77d27 100644
--- a/src/ChunkMap.cpp
+++ b/src/ChunkMap.cpp
@@ -2427,7 +2427,6 @@ bool cChunkMap::ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinCh
{
for (int x = a_MinChunkX; x <= a_MaxChunkX; x++)
{
- LOG("Request %i %i", x, z);
cChunkPtr Chunk = GetChunkNoLoad(x, ZERO_CHUNK_Y, z);
if ((Chunk == NULL) || (!Chunk->IsValid()))
{
diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp
index 4768d38ae..1254541ed 100644
--- a/src/Entities/Entity.cpp
+++ b/src/Entities/Entity.cpp
@@ -1030,9 +1030,15 @@ void cEntity::DetectPortal()
{
if (GetWorld()->GetDimension() == dimOverworld)
{
- if (GetWorld()->GetNetherWorldName().empty() && GetWorld()->GetEndWorldName().empty()) { return; }
+ if (GetWorld()->GetNetherWorldName().empty() && GetWorld()->GetEndWorldName().empty())
+ {
+ return;
+ }
+ }
+ else if (GetWorld()->GetLinkedOverworldName().empty())
+ {
+ return;
}
- else if (GetWorld()->GetLinkedOverworldName().empty()) { return; }
int X = POSX_TOINT, Y = POSY_TOINT, Z = POSZ_TOINT;
if ((Y > 0) && (Y < cChunkDef::Height))
@@ -1041,17 +1047,17 @@ void cEntity::DetectPortal()
{
case E_BLOCK_NETHER_PORTAL:
{
- if (m_PortalCooldownData.second)
+ if (m_PortalCooldownData.m_ShouldPreventTeleportation)
{
return;
}
- if (m_PortalCooldownData.first != 80)
+ if (IsPlayer() && !((cPlayer *)this)->IsGameModeCreative() && m_PortalCooldownData.m_TicksDelayed != 80)
{
- m_PortalCooldownData.first++;
+ m_PortalCooldownData.m_TicksDelayed++;
return;
}
- m_PortalCooldownData.first = 0;
+ m_PortalCooldownData.m_TicksDelayed = 0;
switch (GetWorld()->GetDimension())
{
@@ -1062,13 +1068,13 @@ void cEntity::DetectPortal()
return;
}
- m_PortalCooldownData.second = true; // Stop portals from working on respawn
+ m_PortalCooldownData.m_ShouldPreventTeleportation = true; // Stop portals from working on respawn
if (IsPlayer())
{
((cPlayer *)this)->GetClientHandle()->SendRespawn(dimOverworld);
}
- MoveToWorld(GetWorld()->GetLinkedOverworldName(), cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetLinkedOverworldName()), false);
+ MoveToWorld(cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetLinkedOverworldName()), false);
return;
}
@@ -1079,14 +1085,14 @@ void cEntity::DetectPortal()
return;
}
- m_PortalCooldownData.second = true; // Stop portals from working on respawn
+ m_PortalCooldownData.m_ShouldPreventTeleportation = true; // Stop portals from working on respawn
if (IsPlayer())
{
((cPlayer *)this)->AwardAchievement(achEnterPortal);
((cPlayer *)this)->GetClientHandle()->SendRespawn(dimNether);
}
- MoveToWorld(GetWorld()->GetNetherWorldName(), cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetNetherWorldName(), dimNether, GetWorld()->GetName()), false);
+ MoveToWorld(cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetNetherWorldName(), dimNether, GetWorld()->GetName()), false);
return;
}
@@ -1095,7 +1101,7 @@ void cEntity::DetectPortal()
}
case E_BLOCK_END_PORTAL:
{
- if (m_PortalCooldownData.second)
+ if (m_PortalCooldownData.m_ShouldPreventTeleportation)
{
return;
}
@@ -1109,7 +1115,7 @@ void cEntity::DetectPortal()
return;
}
- m_PortalCooldownData.second = true; // Stop portals from working on respawn
+ m_PortalCooldownData.m_ShouldPreventTeleportation = true; // Stop portals from working on respawn
if (IsPlayer())
{
@@ -1117,7 +1123,7 @@ void cEntity::DetectPortal()
Player->TeleportToCoords(Player->GetLastBedPos().x, Player->GetLastBedPos().y, Player->GetLastBedPos().z);
Player->GetClientHandle()->SendRespawn(dimOverworld);
}
- MoveToWorld(GetWorld()->GetLinkedOverworldName(), cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetLinkedOverworldName()), false);
+ MoveToWorld(cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetLinkedOverworldName()), false);
return;
}
@@ -1128,14 +1134,14 @@ void cEntity::DetectPortal()
return;
}
- m_PortalCooldownData.second = true; // Stop portals from working on respawn
+ m_PortalCooldownData.m_ShouldPreventTeleportation = true; // Stop portals from working on respawn
if (IsPlayer())
{
((cPlayer *)this)->AwardAchievement(achEnterTheEnd);
((cPlayer *)this)->GetClientHandle()->SendRespawn(dimEnd);
}
- MoveToWorld(GetWorld()->GetEndWorldName(), cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetEndWorldName(), dimEnd, GetWorld()->GetName()), false);
+ MoveToWorld(cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetEndWorldName(), dimEnd, GetWorld()->GetName()), false);
return;
}
@@ -1147,34 +1153,20 @@ void cEntity::DetectPortal()
}
// Allow portals to work again
- m_PortalCooldownData.second = false;
- m_PortalCooldownData.first = 0;
+ m_PortalCooldownData.m_ShouldPreventTeleportation = false;
+ m_PortalCooldownData.m_ShouldPreventTeleportation = 0;
}
-bool cEntity::MoveToWorld(const AString & a_WorldName, cWorld * a_World, bool a_ShouldSendRespawn)
+bool cEntity::MoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn)
{
UNUSED(a_ShouldSendRespawn);
+ ASSERT(a_World == NULL);
- cWorld * World;
- if (a_World == NULL)
- {
- World = cRoot::Get()->GetWorld(a_WorldName);
- if (World == NULL)
- {
- LOG("%s: Couldn't find world \"%s\".", __FUNCTION__, a_WorldName.c_str());
- return false;
- }
- }
- else
- {
- World = a_World;
- }
-
- if (GetWorld() == World)
+ if (GetWorld() == a_World)
{
// Don't move to same world
return false;
@@ -1185,7 +1177,7 @@ bool cEntity::MoveToWorld(const AString & a_WorldName, cWorld * a_World, bool a_
GetWorld()->BroadcastDestroyEntity(*this);
// Queue add to new world
- World->AddEntity(this);
+ a_World->AddEntity(this);
return true;
}
@@ -1194,6 +1186,22 @@ bool cEntity::MoveToWorld(const AString & a_WorldName, cWorld * a_World, bool a_
+bool cEntity::MoveToWorld(const AString & a_WorldName, bool a_ShouldSendRespawn)
+{
+ cWorld * World = cRoot::Get()->GetWorld(a_WorldName);
+ if (World == NULL)
+ {
+ LOG("%s: Couldn't find world \"%s\".", __FUNCTION__, a_WorldName.c_str());
+ return false;
+ }
+
+ return MoveToWorld(World, a_ShouldSendRespawn);
+}
+
+
+
+
+
void cEntity::SetSwimState(cChunk & a_Chunk)
{
int RelY = (int)floor(GetPosY() + 0.1);
diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h
index eea48a12f..58254a493 100644
--- a/src/Entities/Entity.h
+++ b/src/Entities/Entity.h
@@ -382,16 +382,19 @@ public:
/// Teleports to the coordinates specified
virtual void TeleportToCoords(double a_PosX, double a_PosY, double a_PosZ);
- /** Moves entity to specified world */
- virtual bool MoveToWorld(const AString & a_WorldName, cWorld * a_World = NULL, bool a_ShouldSendRespawn = true);
+ /** Moves entity to specified world, taking a world pointer */
+ virtual bool MoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn = true);
+
+ /** Moves entity to specified world, taking a world name */
+ bool MoveToWorld(const AString & a_WorldName, bool a_ShouldSendRespawn = true);
// tolua_end
/** Returns if the entity is travelling away from a specified world */
- bool IsWorldTravellingFrom(cWorld * a_World) const { return (m_WorldTravellingFrom == a_World); }
+ bool IsWorldTravellingFrom(cWorld * a_World) const { return m_WorldTravellingFrom == a_World; }
/** Sets the world the entity will be leaving */
- void SetWorldTravellingFrom(cWorld * a_World) { (m_WorldTravellingFrom = a_World); }
+ void SetWorldTravellingFrom(cWorld * a_World) { m_WorldTravellingFrom = a_World; }
/// Updates clients of changes in the entity.
virtual void BroadcastMovementUpdate(const cClientHandle * a_Exclude = NULL);
@@ -538,11 +541,20 @@ protected:
int m_AirLevel;
int m_AirTickTimer;
- /** Portal delay timer and cooldown boolean
- First value is to delay sending the respawn packet (which triggers the Entering the {Dimension} screen).
- Second value is to prevent a teleportation loop by ensuring we do not reenter a portal that we came out of.
- */
- std::pair<unsigned short, bool> m_PortalCooldownData;
+ /** Structure storing the portal delay timer and cooldown boolean */
+ struct sPortalCooldownData
+ {
+ /** Ticks since entry of portal, used to delay teleportation */
+ unsigned short m_TicksDelayed;
+
+ /** Whether the entity has just exited the portal, and should therefore not be teleported again
+ This prevents teleportation loops, and is reset when the entity has moved out of the portal
+ */
+ bool m_ShouldPreventTeleportation;
+ };
+
+ /** Portal delay timer and cooldown boolean data */
+ sPortalCooldownData m_PortalCooldownData;
private:
/** Measured in degrees, [-180, +180) */
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index 0b1b4ce5f..1159891cd 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -1611,24 +1611,9 @@ void cPlayer::TossItems(const cItems & a_Items)
-bool cPlayer::MoveToWorld(const AString & a_WorldName, cWorld * a_World, bool a_ShouldSendRespawn)
+bool cPlayer::MoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn)
{
- cWorld * World;
- if (a_World == NULL)
- {
- World = cRoot::Get()->GetWorld(a_WorldName);
- if (World == NULL)
- {
- LOG("%s: Couldn't find world \"%s\".", __FUNCTION__, a_WorldName.c_str());
- return false;
- }
- }
- else
- {
- World = a_World;
- }
-
- if (GetWorld() == World)
+ if (GetWorld() == a_World)
{
// Don't move to same world
return false;
@@ -1637,7 +1622,7 @@ bool cPlayer::MoveToWorld(const AString & a_WorldName, cWorld * a_World, bool a_
// Send the respawn packet:
if (a_ShouldSendRespawn && (m_ClientHandle != NULL))
{
- m_ClientHandle->SendRespawn(World->GetDimension());
+ m_ClientHandle->SendRespawn(a_World->GetDimension());
}
// Remove player from the old world
@@ -1645,8 +1630,8 @@ bool cPlayer::MoveToWorld(const AString & a_WorldName, cWorld * a_World, bool a_
GetWorld()->RemovePlayer(this);
// Queue adding player to the new world, including all the necessary adjustments to the object
- World->AddPlayer(this);
- SetWorld(World);
+ a_World->AddPlayer(this);
+ SetWorld(a_World); // Chunks may be streamed before cWorld::AddPlayer() sets the world to the new value
return true;
}
diff --git a/src/Entities/Player.h b/src/Entities/Player.h
index 226ec5e68..f972063bb 100644
--- a/src/Entities/Player.h
+++ b/src/Entities/Player.h
@@ -333,7 +333,7 @@ public:
/** Moves the player to the specified world.
Returns true if successful, false on failure (world not found). */
- virtual bool MoveToWorld(const AString & a_WorldName, cWorld * a_World = NULL, bool a_ShouldSendRespawn = true) override; // tolua_export
+ virtual bool MoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn = true) override; // tolua_export
/** Saves all player data, such as inventory, to JSON */
bool SaveToDisk(void);
diff --git a/src/World.cpp b/src/World.cpp
index d27ad1eb4..2af8fc59e 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -512,7 +512,7 @@ void cWorld::InitializeSpawn(void)
-void cWorld::Start()
+void cWorld::Start(void)
{
m_SpawnX = 0;
m_SpawnY = cChunkDef::Height;
@@ -594,61 +594,8 @@ void cWorld::Start()
m_TNTShrapnelLevel = (eShrapnelLevel)Clamp(TNTShrapnelLevel, (int)slNone, (int)slAll);
m_Weather = (eWeather) Clamp(Weather, (int)wSunny, (int)wStorm);
- switch (GetDimension())
- {
- case dimEnd:
- {
- IniFile.GetValueSet("Generator", "BiomeGen", "Constant");
- IniFile.GetValueSet("Generator", "ConstantBiome", "End");
- IniFile.GetValueSet("Generator", "HeightGen", "Biomal");
- IniFile.GetValueSet("Generator", "CompositionGen", "End");
- break;
- }
- case dimOverworld:
- {
- IniFile.GetValueSet("Generator", "BiomeGen", "MultiStepMap");
- IniFile.GetValueSet("Generator", "HeightGen", "DistortedHeightmap");
- IniFile.GetValueSet("Generator", "CompositionGen", "DistortedHeightmap");
- IniFile.GetValueSet("Generator", "Finishers", "Ravines, WormNestCaves, WaterLakes, WaterSprings, LavaLakes, LavaSprings, OreNests, Mineshafts, Trees, SprinkleFoliage, Ice, Snow, Lilypads, BottomLava, DeadBushes, PreSimulator");
- break;
- }
- case dimNether:
- {
- IniFile.GetValueSet("Generator", "BiomeGen", "Constant");
- IniFile.GetValueSet("Generator", "ConstantBiome", "Nether");
- IniFile.GetValueSet("Generator", "HeightGen", "Flat");
- IniFile.GetValueSet("Generator", "FlatHeight", "128");
- IniFile.GetValueSet("Generator", "CompositionGen", "Nether");
- IniFile.GetValueSet("Generator", "Finishers", "WormNestCaves, BottomLava, LavaSprings, NetherClumpFoliage, NetherForts, PreSimulator");
- IniFile.GetValueSet("Generator", "BottomLavaHeight", "30");
- break;
- }
- }
-
- // Load allowed mobs:
- const char * DefaultMonsters = "";
- switch (m_Dimension)
- {
- case dimOverworld: DefaultMonsters = "bat, cavespider, chicken, cow, creeper, enderman, horse, mooshroom, ocelot, pig, sheep, silverfish, skeleton, slime, spider, squid, wolf, zombie"; break;
- case dimNether: DefaultMonsters = "blaze, ghast, magmacube, skeleton, zombie, zombiepigman"; break;
- case dimEnd: DefaultMonsters = "enderman"; break;
- }
- m_bAnimals = IniFile.GetValueSetB("Monsters", "AnimalsOn", true);
- AString AllMonsters = IniFile.GetValueSet("Monsters", "Types", DefaultMonsters);
- AStringVector SplitList = StringSplitAndTrim(AllMonsters, ",");
- for (AStringVector::const_iterator itr = SplitList.begin(), end = SplitList.end(); itr != end; ++itr)
- {
- cMonster::eType ToAdd = cMonster::StringToMobType(*itr);
- if (ToAdd != cMonster::mtInvalidType)
- {
- m_AllowedMobs.insert(ToAdd);
- LOGD("Allowed mob: %s", itr->c_str());
- }
- else
- {
- LOG("World \"%s\": Unknown mob type: %s", m_WorldName.c_str(), itr->c_str());
- }
- }
+ InitialiseGeneratorDefaults(IniFile);
+ InitialiseAndLoadMobSpawningValues(IniFile);
m_ChunkMap = new cChunkMap(this);
@@ -745,6 +692,82 @@ eWeather cWorld::ChooseNewWeather()
+void cWorld::InitialiseGeneratorDefaults(cIniFile & a_IniFile)
+{
+ switch (GetDimension())
+ {
+ case dimEnd:
+ {
+ a_IniFile.GetValueSet("Generator", "BiomeGen", "Constant");
+ a_IniFile.GetValueSet("Generator", "ConstantBiome", "End");
+ a_IniFile.GetValueSet("Generator", "HeightGen", "Biomal");
+ a_IniFile.GetValueSet("Generator", "CompositionGen", "End");
+ break;
+ }
+ case dimOverworld:
+ {
+ a_IniFile.GetValueSet("Generator", "BiomeGen", "MultiStepMap");
+ a_IniFile.GetValueSet("Generator", "HeightGen", "DistortedHeightmap");
+ a_IniFile.GetValueSet("Generator", "CompositionGen", "DistortedHeightmap");
+ a_IniFile.GetValueSet("Generator", "Finishers", "Ravines, WormNestCaves, WaterLakes, WaterSprings, LavaLakes, LavaSprings, OreNests, Mineshafts, Trees, SprinkleFoliage, Ice, Snow, Lilypads, BottomLava, DeadBushes, PreSimulator");
+ break;
+ }
+ case dimNether:
+ {
+ a_IniFile.GetValueSet("Generator", "BiomeGen", "Constant");
+ a_IniFile.GetValueSet("Generator", "ConstantBiome", "Nether");
+ a_IniFile.GetValueSet("Generator", "HeightGen", "Flat");
+ a_IniFile.GetValueSet("Generator", "FlatHeight", "128");
+ a_IniFile.GetValueSet("Generator", "CompositionGen", "Nether");
+ a_IniFile.GetValueSet("Generator", "Finishers", "WormNestCaves, BottomLava, LavaSprings, NetherClumpFoliage, NetherForts, PreSimulator");
+ a_IniFile.GetValueSet("Generator", "BottomLavaHeight", "30");
+ break;
+ }
+ }
+}
+
+
+
+
+
+void cWorld::InitialiseAndLoadMobSpawningValues(cIniFile & a_IniFile)
+{
+ AString DefaultMonsters;
+ switch (m_Dimension)
+ {
+ case dimOverworld: DefaultMonsters = "bat, cavespider, chicken, cow, creeper, enderman, horse, mooshroom, ocelot, pig, sheep, silverfish, skeleton, slime, spider, squid, wolf, zombie"; break;
+ case dimNether: DefaultMonsters = "blaze, ghast, magmacube, skeleton, zombie, zombiepigman"; break;
+ case dimEnd: DefaultMonsters = "enderman"; break;
+ }
+
+ m_bAnimals = a_IniFile.GetValueSetB("Monsters", "AnimalsOn", true);
+ AString AllMonsters = a_IniFile.GetValueSet("Monsters", "Types", DefaultMonsters);
+
+ if (!m_bAnimals)
+ {
+ return;
+ }
+
+ AStringVector SplitList = StringSplitAndTrim(AllMonsters, ",");
+ for (AStringVector::const_iterator itr = SplitList.begin(), end = SplitList.end(); itr != end; ++itr)
+ {
+ cMonster::eType ToAdd = cMonster::StringToMobType(*itr);
+ if (ToAdd != cMonster::mtInvalidType)
+ {
+ m_AllowedMobs.insert(ToAdd);
+ LOGD("Allowed mob: %s", itr->c_str());
+ }
+ else
+ {
+ LOG("World \"%s\": Unknown mob type: %s", m_WorldName.c_str(), itr->c_str());
+ }
+ }
+}
+
+
+
+
+
void cWorld::Stop(void)
{
// Delete the clients that have been in this world:
diff --git a/src/World.h b/src/World.h
index 09cbc6b48..879da3cb9 100644
--- a/src/World.h
+++ b/src/World.h
@@ -1030,6 +1030,13 @@ private:
/** Adds the players queued in the m_PlayersToAdd queue into the m_Players list.
Assumes it is called from the Tick thread. */
void AddQueuedPlayers(void);
+
+ /** Sets generator values to dimension specific defaults, if those values do not exist */
+ void InitialiseGeneratorDefaults(cIniFile & a_IniFile);
+
+ /** Sets mob spawning values if nonexistant to their dimension specific defaults */
+ void InitialiseAndLoadMobSpawningValues(cIniFile & a_IniFile);
+
}; // tolua_export