From 8050a5b98a3003c2a4bed39b896b4a3a4c1068c0 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 21 Jul 2014 22:49:06 +0100 Subject: [PATCH] Suggestions --- lib/inifile/iniFile.cpp | 2 +- src/BlockID.h | 2 +- src/Chunk.cpp | 6 +- src/ChunkMap.cpp | 1 - src/Entities/Entity.cpp | 78 ++++++++++++----------- src/Entities/Entity.h | 30 ++++++--- src/Entities/Player.cpp | 25 ++------ src/Entities/Player.h | 2 +- src/World.cpp | 135 +++++++++++++++++++++++----------------- src/World.h | 7 +++ 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 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