From 8bff3e5af220070ecc789ef551c0b8428b8953ef Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 31 May 2014 22:28:51 +0100 Subject: Implemented end and nether portals --- src/Entities/Entity.cpp | 117 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) (limited to 'src/Entities/Entity.cpp') diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 1226a2319..b5c272cf2 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -629,6 +629,7 @@ void cEntity::Tick(float a_Dt, cChunk & a_Chunk) // Handle drowning HandleAir(); } + DetectPortal(); // None of the above functions change position, we remain in the chunk of NextChunk HandlePhysics(a_Dt, *NextChunk); @@ -1039,6 +1040,122 @@ void cEntity::DetectCacti(void) +void cEntity::DetectPortal() +{ + int X = POSX_TOINT, Y = POSY_TOINT, Z = POSZ_TOINT; + if ((Y > 0) && (Y < cChunkDef::Height)) + { + switch (GetWorld()->GetBlock(X, Y, Z)) + { + case E_BLOCK_NETHER_PORTAL: + { + switch (GetWorld()->GetDimension()) + { + case dimNether: + { + AString OverworldName = GetWorld()->GetName().substr(0, GetWorld()->GetName().size() - 7); + cFile::CreateFolder(FILE_IO_PREFIX + OverworldName); + cIniFile File; + File.ReadFile(OverworldName + "/world.ini"); + File.SetValue("General", "Dimension", "Overworld"); + File.WriteFile(OverworldName + "/world.ini"); + + MoveToWorld(OverworldName, cRoot::Get()->CreateAndInitializeWorld(OverworldName)); + break; + } + case dimOverworld: + { + AString NetherWorldName = GetWorld()->GetName() + "_nether"; + cFile::CreateFolder(FILE_IO_PREFIX + NetherWorldName); + cIniFile File; + File.ReadFile(NetherWorldName + "/world.ini"); + File.SetValue("General", "Dimension", "Nether"); + File.WriteFile(NetherWorldName + "/world.ini"); + + MoveToWorld(NetherWorldName, cRoot::Get()->CreateAndInitializeWorld(NetherWorldName)); + break; + } + default: break; + } + break; + } + case E_BLOCK_END_PORTAL: + { + switch (GetWorld()->GetDimension()) + { + case dimEnd: + { + AString OverworldName = GetWorld()->GetName().substr(0, GetWorld()->GetName().size() - 4); + cFile::CreateFolder(FILE_IO_PREFIX + OverworldName); + cIniFile File; + File.ReadFile(OverworldName + "/world.ini"); + File.SetValue("General", "Dimension", "Overworld"); + File.WriteFile(OverworldName + "/world.ini"); + + MoveToWorld(OverworldName, cRoot::Get()->CreateAndInitializeWorld(OverworldName)); + break; + } + case dimOverworld: + { + AString EndWorldName = GetWorld()->GetName() + "_end"; + cFile::CreateFolder(FILE_IO_PREFIX + EndWorldName); + cIniFile File; + File.ReadFile(EndWorldName + "/world.ini"); + File.SetValue("General", "Dimension", "End"); + File.WriteFile(EndWorldName + "/world.ini"); + + MoveToWorld(EndWorldName, cRoot::Get()->CreateAndInitializeWorld(EndWorldName)); + break; + } + default: break; + } + } + default: break; + } + } +} + + + + + +bool cEntity::MoveToWorld(const AString & a_WorldName, cWorld * a_World) +{ + 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); + return false; + } + } + else + { + World = a_World; + } + + if (GetWorld() == World) + { + return false; + } + + // Remove all links to the old world + GetWorld()->RemoveEntity(this); + GetWorld()->BroadcastDestroyEntity(*this); + + // Add to all the necessary parts of the new world + SetWorld(World); + World->AddEntity(this); + + return true; +} + + + + + void cEntity::SetSwimState(cChunk & a_Chunk) { int RelY = (int)floor(GetPosY() + 0.1); -- cgit v1.2.3 From 576f89c1d5bdb067c0ca06237440f754d80bd13c Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 1 Jun 2014 18:46:59 +0100 Subject: Implemented bed homes + Implemented bed home positions * Fixed some inventory and health server/client mismatches after world change --- src/Entities/Entity.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/Entities/Entity.cpp') diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index b5c272cf2..de6c628e9 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -1093,6 +1093,12 @@ void cEntity::DetectPortal() File.WriteFile(OverworldName + "/world.ini"); MoveToWorld(OverworldName, cRoot::Get()->CreateAndInitializeWorld(OverworldName)); + + if (IsPlayer()) + { + cPlayer * Player = (cPlayer *)this; + Player->TeleportToCoords(Player->GetLastBedPos().x, Player->GetLastBedPos().y, Player->GetLastBedPos().z); + } break; } case dimOverworld: -- cgit v1.2.3 From 01f38d883602045e84fdf98bf3395e97608d9aad Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 4 Jun 2014 13:22:50 +0100 Subject: Added checks for no downfall biomes --- src/Entities/Entity.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/Entities/Entity.cpp') diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index de6c628e9..16264a608 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -869,7 +869,7 @@ void cEntity::TickBurning(cChunk & a_Chunk) // Remember the current burning state: bool HasBeenBurning = (m_TicksLeftBurning > 0); - if (m_World->IsWeatherWet()) + if (IsBiomeNoDownfall(a_Chunk.GetBiomeAt(POSX_TOINT - a_Chunk.GetPosX() * cChunkDef::Width, POSZ_TOINT - a_Chunk.GetPosZ() * cChunkDef::Width)) || GetWorld()->IsWeatherWet()) { if (POSY_TOINT > m_World->GetHeight(POSX_TOINT, POSZ_TOINT)) { -- cgit v1.2.3 From ccbf6cc446ad67fbba8163d4d4d61456c1ba0bc6 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 4 Jun 2014 20:00:55 +0100 Subject: Configurable portals --- src/Entities/Entity.cpp | 45 ++++++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 13 deletions(-) (limited to 'src/Entities/Entity.cpp') diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 16264a608..7d9c10ec6 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -1042,6 +1042,11 @@ void cEntity::DetectCacti(void) void cEntity::DetectPortal() { + if (!GetWorld()->AreNetherPortalsEnabled() && !GetWorld()->AreEndPortalsEnabled()) + { + return; + } + int X = POSX_TOINT, Y = POSY_TOINT, Z = POSZ_TOINT; if ((Y > 0) && (Y < cChunkDef::Height)) { @@ -1049,11 +1054,18 @@ void cEntity::DetectPortal() { case E_BLOCK_NETHER_PORTAL: { + if (!GetWorld()->AreNetherPortalsEnabled()) + { + return; + } + switch (GetWorld()->GetDimension()) { case dimNether: { - AString OverworldName = GetWorld()->GetName().substr(0, GetWorld()->GetName().size() - 7); + cIniFile OwnIni; OwnIni.ReadFile(GetWorld()->GetIniFileName()); + AString OverworldName = OwnIni.GetValue("General", "OverworldName", cRoot::Get()->GetDefaultWorld()->GetName()); + cFile::CreateFolder(FILE_IO_PREFIX + OverworldName); cIniFile File; File.ReadFile(OverworldName + "/world.ini"); @@ -1065,14 +1077,14 @@ void cEntity::DetectPortal() } case dimOverworld: { - AString NetherWorldName = GetWorld()->GetName() + "_nether"; - cFile::CreateFolder(FILE_IO_PREFIX + NetherWorldName); + cFile::CreateFolder(FILE_IO_PREFIX + GetWorld()->GetNetherWorldName()); cIniFile File; - File.ReadFile(NetherWorldName + "/world.ini"); + File.ReadFile(GetWorld()->GetNetherWorldName() + "/world.ini"); File.SetValue("General", "Dimension", "Nether"); - File.WriteFile(NetherWorldName + "/world.ini"); + File.SetValue("General", "OverworldName", GetWorld()->GetName()); + File.WriteFile(GetWorld()->GetNetherWorldName() + "/world.ini"); - MoveToWorld(NetherWorldName, cRoot::Get()->CreateAndInitializeWorld(NetherWorldName)); + MoveToWorld(GetWorld()->GetNetherWorldName(), cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetNetherWorldName())); break; } default: break; @@ -1081,11 +1093,18 @@ void cEntity::DetectPortal() } case E_BLOCK_END_PORTAL: { + if (!GetWorld()->AreEndPortalsEnabled()) + { + return; + } + switch (GetWorld()->GetDimension()) { case dimEnd: { - AString OverworldName = GetWorld()->GetName().substr(0, GetWorld()->GetName().size() - 4); + cIniFile OwnIni; OwnIni.ReadFile(GetWorld()->GetIniFileName()); + AString OverworldName = OwnIni.GetValue("General", "OverworldName", cRoot::Get()->GetDefaultWorld()->GetName()); + cFile::CreateFolder(FILE_IO_PREFIX + OverworldName); cIniFile File; File.ReadFile(OverworldName + "/world.ini"); @@ -1103,14 +1122,14 @@ void cEntity::DetectPortal() } case dimOverworld: { - AString EndWorldName = GetWorld()->GetName() + "_end"; - cFile::CreateFolder(FILE_IO_PREFIX + EndWorldName); + cFile::CreateFolder(FILE_IO_PREFIX + GetWorld()->GetEndWorldName()); cIniFile File; - File.ReadFile(EndWorldName + "/world.ini"); + File.ReadFile(GetWorld()->GetEndWorldName() + "/world.ini"); File.SetValue("General", "Dimension", "End"); - File.WriteFile(EndWorldName + "/world.ini"); + File.SetValue("General", "OverworldName", GetWorld()->GetName()); + File.WriteFile(GetWorld()->GetEndWorldName() + "/world.ini"); - MoveToWorld(EndWorldName, cRoot::Get()->CreateAndInitializeWorld(EndWorldName)); + MoveToWorld(GetWorld()->GetEndWorldName(), cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetEndWorldName())); break; } default: break; @@ -1133,7 +1152,7 @@ bool cEntity::MoveToWorld(const AString & a_WorldName, cWorld * a_World) World = cRoot::Get()->GetWorld(a_WorldName); if (World == NULL) { - LOG("%s: Couldn't find world \"%s\".", __FUNCTION__, a_WorldName); + LOG("%s: Couldn't find world \"%s\".", __FUNCTION__, a_WorldName.c_str()); return false; } } -- cgit v1.2.3 From 873043c8e46dfd1ec764fbd5b673173ffe88271f Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 4 Jun 2014 21:51:19 +0100 Subject: Suggestions --- src/Entities/Entity.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/Entities/Entity.cpp') diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 7d9c10ec6..2d8f385cb 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -1063,7 +1063,8 @@ void cEntity::DetectPortal() { case dimNether: { - cIniFile OwnIni; OwnIni.ReadFile(GetWorld()->GetIniFileName()); + cIniFile OwnIni; + OwnIni.ReadFile(GetWorld()->GetIniFileName()); AString OverworldName = OwnIni.GetValue("General", "OverworldName", cRoot::Get()->GetDefaultWorld()->GetName()); cFile::CreateFolder(FILE_IO_PREFIX + OverworldName); @@ -1102,7 +1103,8 @@ void cEntity::DetectPortal() { case dimEnd: { - cIniFile OwnIni; OwnIni.ReadFile(GetWorld()->GetIniFileName()); + cIniFile OwnIni; + OwnIni.ReadFile(GetWorld()->GetIniFileName()); AString OverworldName = OwnIni.GetValue("General", "OverworldName", cRoot::Get()->GetDefaultWorld()->GetName()); cFile::CreateFolder(FILE_IO_PREFIX + OverworldName); -- cgit v1.2.3 From 35b79e5d710862f957bc494638a8d8906992665d Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 10 Jun 2014 20:43:27 +0100 Subject: Portal improvements and suggestions --- src/Entities/Entity.cpp | 130 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 89 insertions(+), 41 deletions(-) (limited to 'src/Entities/Entity.cpp') diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 2d8f385cb..4b376a1fe 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -12,6 +12,7 @@ #include "../Bindings/PluginManager.h" #include "../Tracer.h" #include "Player.h" +#include "BlockArea.h" @@ -1047,6 +1048,28 @@ void cEntity::DetectPortal() return; } + class cPortalChunkLoader : public cChunkStay + { + public: + cPortalChunkLoader(cEntity * a_Entity, Vector3i & a_PortalPos) : + m_Entity(a_Entity), + m_PortalPos(a_PortalPos) + {} + + private: + virtual bool OnAllChunksAvailable(void) override + { + m_Entity->CreateExitPortal(m_PortalPos.x, m_PortalPos.y, m_PortalPos.z); + return true; + } + + virtual void OnChunkAvailable(int a_ChunkX, int a_ChunkZ) override {}; + virtual void OnDisabled(void) override {}; + + cEntity * m_Entity; + Vector3i m_PortalPos; + }; + int X = POSX_TOINT, Y = POSY_TOINT, Z = POSZ_TOINT; if ((Y > 0) && (Y < cChunkDef::Height)) { @@ -1061,31 +1084,31 @@ void cEntity::DetectPortal() switch (GetWorld()->GetDimension()) { - case dimNether: + case dimNether: MoveToWorld(GetWorld()->GetLinkedOverworldName(), cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetLinkedOverworldName())); break; + case dimOverworld: { - cIniFile OwnIni; - OwnIni.ReadFile(GetWorld()->GetIniFileName()); - AString OverworldName = OwnIni.GetValue("General", "OverworldName", cRoot::Get()->GetDefaultWorld()->GetName()); + if (IsPlayer()) + { + ((cPlayer *)this)->AwardAchievement(achEnterPortal); + } + MoveToWorld(GetWorld()->GetNetherWorldName(), cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetNetherWorldName(), dimNether, GetWorld()->GetName())); + + cChunkStay * Stay = new cPortalChunkLoader(this, Vector3i(X, Y, Z)); - cFile::CreateFolder(FILE_IO_PREFIX + OverworldName); - cIniFile File; - File.ReadFile(OverworldName + "/world.ini"); - File.SetValue("General", "Dimension", "Overworld"); - File.WriteFile(OverworldName + "/world.ini"); + int MinChunkX, MaxChunkX; + int MinChunkZ, MaxChunkZ; + cChunkDef::BlockToChunk(X - 128, Z - 128, MinChunkX, MinChunkZ); + cChunkDef::BlockToChunk(X + 128, Z + 128, MaxChunkX, MaxChunkZ); - MoveToWorld(OverworldName, cRoot::Get()->CreateAndInitializeWorld(OverworldName)); - break; - } - case dimOverworld: - { - cFile::CreateFolder(FILE_IO_PREFIX + GetWorld()->GetNetherWorldName()); - cIniFile File; - File.ReadFile(GetWorld()->GetNetherWorldName() + "/world.ini"); - File.SetValue("General", "Dimension", "Nether"); - File.SetValue("General", "OverworldName", GetWorld()->GetName()); - File.WriteFile(GetWorld()->GetNetherWorldName() + "/world.ini"); - - MoveToWorld(GetWorld()->GetNetherWorldName(), cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetNetherWorldName())); + for (int OtherMinChunkX = MinChunkX; OtherMinChunkX <= MaxChunkX; ++OtherMinChunkX) + { + for (int OtherMinChunkZ = MinChunkZ; OtherMinChunkZ <= MaxChunkZ; ++OtherMinChunkZ) + { + Stay->Add(OtherMinChunkX, OtherMinChunkZ); + } + } + + Stay->Enable(*GetWorld()->GetChunkMap()); break; } default: break; @@ -1103,17 +1126,7 @@ void cEntity::DetectPortal() { case dimEnd: { - cIniFile OwnIni; - OwnIni.ReadFile(GetWorld()->GetIniFileName()); - AString OverworldName = OwnIni.GetValue("General", "OverworldName", cRoot::Get()->GetDefaultWorld()->GetName()); - - cFile::CreateFolder(FILE_IO_PREFIX + OverworldName); - cIniFile File; - File.ReadFile(OverworldName + "/world.ini"); - File.SetValue("General", "Dimension", "Overworld"); - File.WriteFile(OverworldName + "/world.ini"); - - MoveToWorld(OverworldName, cRoot::Get()->CreateAndInitializeWorld(OverworldName)); + MoveToWorld(GetWorld()->GetLinkedOverworldName(), cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetLinkedOverworldName())); if (IsPlayer()) { @@ -1124,14 +1137,11 @@ void cEntity::DetectPortal() } case dimOverworld: { - cFile::CreateFolder(FILE_IO_PREFIX + GetWorld()->GetEndWorldName()); - cIniFile File; - File.ReadFile(GetWorld()->GetEndWorldName() + "/world.ini"); - File.SetValue("General", "Dimension", "End"); - File.SetValue("General", "OverworldName", GetWorld()->GetName()); - File.WriteFile(GetWorld()->GetEndWorldName() + "/world.ini"); - - MoveToWorld(GetWorld()->GetEndWorldName(), cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetEndWorldName())); + if (IsPlayer()) + { + ((cPlayer *)this)->AwardAchievement(achEnterTheEnd); + } + MoveToWorld(GetWorld()->GetEndWorldName(), cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetEndWorldName(), dimEnd, GetWorld()->GetName())); break; } default: break; @@ -1146,6 +1156,44 @@ void cEntity::DetectPortal() +void cEntity::CreateExitPortal(int a_BlockX, int a_BlockY, int a_BlockZ) +{ + cBlockArea Area; + Area.Read(GetWorld(), a_BlockX - 128, a_BlockX + 128, 0, 128, a_BlockZ - 128, a_BlockZ + 128); + for (int x = a_BlockX - 128; x <= a_BlockX + 128; ++x) for (int y = 0; y <= 128; ++y) for (int z = a_BlockZ - 128; z <= a_BlockZ + 128; ++z) + { + if ( + (Area.GetBlockType(x, y, z) == E_BLOCK_NETHER_PORTAL) && + ( + (Area.GetBlockType(x, (int)floor(y + GetHeight()), z) == E_BLOCK_NETHER_PORTAL) || + (Area.GetBlockType(x, (int)floor(y - GetHeight()), z) == E_BLOCK_NETHER_PORTAL) + ) + ) + { + TeleportToCoords(x, y, z); + return; + } + } + + int MinX = std::max(a_BlockX - (int)ceil(GetWidth()), a_BlockX - 2), MaxX = std::max(a_BlockX + (int)ceil(GetWidth()), a_BlockX + 1); + int MinY = std::max(a_BlockY - (int)ceil(GetHeight()), a_BlockY - 2), MaxY = std::max(a_BlockY + (int)ceil(GetHeight()), a_BlockY + 1); + + for (int y = MinY; y < MaxY + 1; y += MaxY - MinY) for (int x = MinX; x < MaxX + 1; ++x) + { + Area.SetBlockType(x, y, a_BlockZ, E_BLOCK_OBSIDIAN); + } + for (int y = MinY; y < MaxY + 1; ++y) for (int x = MinX; x < MaxX + 1; x += MaxX - MinX) + { + Area.SetBlockType(x, y, a_BlockZ, E_BLOCK_OBSIDIAN); + } + + Area.Write(GetWorld(), MinX, MinY, a_BlockZ); +} + + + + + bool cEntity::MoveToWorld(const AString & a_WorldName, cWorld * a_World) { cWorld * World; -- cgit v1.2.3 From 29567c56107c86b70da130f995564beb2eaf424c Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Thu, 12 Jun 2014 15:21:07 +0100 Subject: Portals animate and delay correctly --- src/Entities/Entity.cpp | 121 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 93 insertions(+), 28 deletions(-) (limited to 'src/Entities/Entity.cpp') diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 334cf5aa7..a7b6cca27 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -1051,15 +1051,16 @@ void cEntity::DetectPortal() class cPortalChunkLoader : public cChunkStay { public: - cPortalChunkLoader(cEntity * a_Entity, Vector3i & a_PortalPos) : + cPortalChunkLoader(cEntity * a_Entity, cWorld & a_World, Vector3i & a_PortalPos) : m_Entity(a_Entity), - m_PortalPos(a_PortalPos) + m_PortalPos(a_PortalPos), + m_World(a_World) {} private: virtual bool OnAllChunksAvailable(void) override { - m_Entity->CreateExitPortal(m_PortalPos.x, m_PortalPos.y, m_PortalPos.z); + cEntity::CreateExitPortal(m_PortalPos.x, m_PortalPos.y, m_PortalPos.z, m_Entity->GetWidth(), m_Entity->GetHeight(), m_World, m_Entity->GetUniqueID()); return true; } @@ -1068,6 +1069,7 @@ void cEntity::DetectPortal() cEntity * m_Entity; Vector3i m_PortalPos; + cWorld & m_World; }; int X = POSX_TOINT, Y = POSY_TOINT, Z = POSZ_TOINT; @@ -1077,106 +1079,167 @@ void cEntity::DetectPortal() { case E_BLOCK_NETHER_PORTAL: { - if (!GetWorld()->AreNetherPortalsEnabled()) + if (!GetWorld()->AreNetherPortalsEnabled() || m_PortalCooldownData.second) { return; } + if (m_PortalCooldownData.first != 80) + { + m_PortalCooldownData.first++; + return; + } + m_PortalCooldownData.first = 0; + switch (GetWorld()->GetDimension()) { - case dimNether: MoveToWorld(GetWorld()->GetLinkedOverworldName(), cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetLinkedOverworldName())); break; + case dimNether: + { + m_PortalCooldownData.second = true; // Stop portals from working on respawn + + if (IsPlayer()) + { + ((cPlayer *)this)->GetClientHandle()->SendRespawn(dimOverworld); + } + MoveToWorld(GetWorld()->GetLinkedOverworldName(), cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetLinkedOverworldName()), false); + + return; + } case dimOverworld: { + m_PortalCooldownData.second = 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())); + MoveToWorld(GetWorld()->GetNetherWorldName(), cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetNetherWorldName(), dimNether, GetWorld()->GetName()), false); - cChunkStay * Stay = new cPortalChunkLoader(this, Vector3i(X, Y, Z)); + cChunkStay * Stay = new cPortalChunkLoader(this, *cRoot::Get()->GetWorld(GetWorld()->GetNetherWorldName()), Vector3i(X, Y, Z)); int MinChunkX, MaxChunkX; int MinChunkZ, MaxChunkZ; cChunkDef::BlockToChunk(X - 128, Z - 128, MinChunkX, MinChunkZ); cChunkDef::BlockToChunk(X + 128, Z + 128, MaxChunkX, MaxChunkZ); - for (int OtherMinChunkX = MinChunkX; OtherMinChunkX <= MaxChunkX; ++OtherMinChunkX) + for (int ChunkX = MinChunkX; ChunkX <= MaxChunkX; ++ChunkX) { - for (int OtherMinChunkZ = MinChunkZ; OtherMinChunkZ <= MaxChunkZ; ++OtherMinChunkZ) + for (int ChunkZ = MinChunkZ; ChunkZ <= MaxChunkZ; ++ChunkZ) { - Stay->Add(OtherMinChunkX, OtherMinChunkZ); + LOG("Queue %i %i", ChunkX, ChunkZ); + Stay->Add(ChunkX, ChunkZ); } } Stay->Enable(*GetWorld()->GetChunkMap()); - break; + return; } default: break; } - break; + return; } case E_BLOCK_END_PORTAL: { - if (!GetWorld()->AreEndPortalsEnabled()) + if (!GetWorld()->AreEndPortalsEnabled() || m_PortalCooldownData.second) + { + return; + } + + if (m_PortalCooldownData.first != 80) { + m_PortalCooldownData.first++; return; } + m_PortalCooldownData.first = 0; switch (GetWorld()->GetDimension()) { case dimEnd: { - MoveToWorld(GetWorld()->GetLinkedOverworldName(), cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetLinkedOverworldName())); + m_PortalCooldownData.second = true; // Stop portals from working on respawn if (IsPlayer()) { cPlayer * Player = (cPlayer *)this; Player->TeleportToCoords(Player->GetLastBedPos().x, Player->GetLastBedPos().y, Player->GetLastBedPos().z); + Player->GetClientHandle()->SendRespawn(dimOverworld); } - break; + MoveToWorld(GetWorld()->GetLinkedOverworldName(), cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetLinkedOverworldName()), false); + + return; } case dimOverworld: { + m_PortalCooldownData.second = 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())); - break; + MoveToWorld(GetWorld()->GetEndWorldName(), cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetEndWorldName(), dimEnd, GetWorld()->GetName()), false); + + return; } default: break; } + return; } default: break; } } + + // Allow portals to work again + m_PortalCooldownData.second = false; + m_PortalCooldownData.first = 0; } -void cEntity::CreateExitPortal(int a_BlockX, int a_BlockY, int a_BlockZ) +void cEntity::CreateExitPortal(int a_BlockX, int a_BlockY, int a_BlockZ, double a_EntityWidth, double a_EntityHeight, cWorld & a_World, int a_UniqueIDToTeleport) { cBlockArea Area; - Area.Read(GetWorld(), a_BlockX - 128, a_BlockX + 128, 0, 128, a_BlockZ - 128, a_BlockZ + 128); + Area.Read(&a_World, a_BlockX - 128, a_BlockX + 128, 0, 128, a_BlockZ - 128, a_BlockZ + 128); for (int x = a_BlockX - 128; x <= a_BlockX + 128; ++x) for (int y = 0; y <= 128; ++y) for (int z = a_BlockZ - 128; z <= a_BlockZ + 128; ++z) { if ( (Area.GetBlockType(x, y, z) == E_BLOCK_NETHER_PORTAL) && ( - (Area.GetBlockType(x, (int)floor(y + GetHeight()), z) == E_BLOCK_NETHER_PORTAL) || - (Area.GetBlockType(x, (int)floor(y - GetHeight()), z) == E_BLOCK_NETHER_PORTAL) + (Area.GetBlockType(x, (int)floor(y + a_EntityHeight), z) == E_BLOCK_NETHER_PORTAL) || + (Area.GetBlockType(x, (int)floor(y - a_EntityHeight), z) == E_BLOCK_NETHER_PORTAL) ) ) { - TeleportToCoords(x, y, z); + class cTeleportEntityToPortalCallback : public cEntityCallback + { + public: + cTeleportEntityToPortalCallback(int a_X, int a_Y, int a_Z) : + m_X(a_X), + m_Y(a_Y), + m_Z(a_Z) + {} + + virtual bool Item(cEntity * a_Entity) override + { + a_Entity->TeleportToCoords(m_X, m_Y, m_Z); + return true; + } + + private: + int m_X, m_Y, m_Z; + }; + + cTeleportEntityToPortalCallback TETPC(x, y, z); + a_World.DoWithEntityByID(a_UniqueIDToTeleport, TETPC); return; } } - int MinX = std::max(a_BlockX - (int)ceil(GetWidth()), a_BlockX - 2), MaxX = std::max(a_BlockX + (int)ceil(GetWidth()), a_BlockX + 1); - int MinY = std::max(a_BlockY - (int)ceil(GetHeight()), a_BlockY - 2), MaxY = std::max(a_BlockY + (int)ceil(GetHeight()), a_BlockY + 1); + int MinX = std::max(a_BlockX - (int)ceil(a_EntityWidth), a_BlockX - 2), MaxX = std::max(a_BlockX + (int)ceil(a_EntityWidth), a_BlockX + 1); + int MinY = std::max(a_BlockY - (int)ceil(a_EntityHeight), a_BlockY - 2), MaxY = std::max(a_BlockY + (int)ceil(a_EntityHeight), a_BlockY + 1); for (int y = MinY; y < MaxY + 1; y += MaxY - MinY) for (int x = MinX; x < MaxX + 1; ++x) { @@ -1187,15 +1250,17 @@ void cEntity::CreateExitPortal(int a_BlockX, int a_BlockY, int a_BlockZ) Area.SetBlockType(x, y, a_BlockZ, E_BLOCK_OBSIDIAN); } - Area.Write(GetWorld(), MinX, MinY, a_BlockZ); + Area.Write(&a_World, MinX, MinY, a_BlockZ); } -bool cEntity::MoveToWorld(const AString & a_WorldName, cWorld * a_World) +bool cEntity::MoveToWorld(const AString & a_WorldName, cWorld * a_World, bool a_ShouldSendRespawn) { + UNUSED(a_ShouldSendRespawn); + cWorld * World; if (a_World == NULL) { @@ -1213,6 +1278,7 @@ bool cEntity::MoveToWorld(const AString & a_WorldName, cWorld * a_World) if (GetWorld() == World) { + // Don't move to same world return false; } @@ -1220,8 +1286,7 @@ bool cEntity::MoveToWorld(const AString & a_WorldName, cWorld * a_World) GetWorld()->RemoveEntity(this); GetWorld()->BroadcastDestroyEntity(*this); - // Add to all the necessary parts of the new world - SetWorld(World); + // Queue add to new world World->AddEntity(this); return true; -- cgit v1.2.3 From e10940d57cf8500eb306e986d7cc2d79bca00467 Mon Sep 17 00:00:00 2001 From: worktycho Date: Thu, 12 Jun 2014 17:24:14 +0100 Subject: Fixed compile --- src/Entities/Entity.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/Entities/Entity.cpp') diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index a7b6cca27..1c8818fe5 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -1051,7 +1051,7 @@ void cEntity::DetectPortal() class cPortalChunkLoader : public cChunkStay { public: - cPortalChunkLoader(cEntity * a_Entity, cWorld & a_World, Vector3i & a_PortalPos) : + cPortalChunkLoader(cEntity * a_Entity, cWorld & a_World, const Vector3i & a_PortalPos) : m_Entity(a_Entity), m_PortalPos(a_PortalPos), m_World(a_World) -- cgit v1.2.3 From 8a80843ddf062b4a2df622d661628e4c77b9c399 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 14 Jun 2014 10:18:16 +0100 Subject: Reverted portal creation code It wasn't really working and needs more development --- src/Entities/Entity.cpp | 100 ------------------------------------------------ 1 file changed, 100 deletions(-) (limited to 'src/Entities/Entity.cpp') diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 1c8818fe5..d42c49abe 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -12,7 +12,6 @@ #include "../Bindings/PluginManager.h" #include "../Tracer.h" #include "Player.h" -#include "BlockArea.h" @@ -1048,30 +1047,6 @@ void cEntity::DetectPortal() return; } - class cPortalChunkLoader : public cChunkStay - { - public: - cPortalChunkLoader(cEntity * a_Entity, cWorld & a_World, const Vector3i & a_PortalPos) : - m_Entity(a_Entity), - m_PortalPos(a_PortalPos), - m_World(a_World) - {} - - private: - virtual bool OnAllChunksAvailable(void) override - { - cEntity::CreateExitPortal(m_PortalPos.x, m_PortalPos.y, m_PortalPos.z, m_Entity->GetWidth(), m_Entity->GetHeight(), m_World, m_Entity->GetUniqueID()); - return true; - } - - virtual void OnChunkAvailable(int a_ChunkX, int a_ChunkZ) override {}; - virtual void OnDisabled(void) override {}; - - cEntity * m_Entity; - Vector3i m_PortalPos; - cWorld & m_World; - }; - int X = POSX_TOINT, Y = POSY_TOINT, Z = POSZ_TOINT; if ((Y > 0) && (Y < cChunkDef::Height)) { @@ -1115,24 +1090,7 @@ void cEntity::DetectPortal() ((cPlayer *)this)->GetClientHandle()->SendRespawn(dimNether); } MoveToWorld(GetWorld()->GetNetherWorldName(), cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetNetherWorldName(), dimNether, GetWorld()->GetName()), false); - - cChunkStay * Stay = new cPortalChunkLoader(this, *cRoot::Get()->GetWorld(GetWorld()->GetNetherWorldName()), Vector3i(X, Y, Z)); - - int MinChunkX, MaxChunkX; - int MinChunkZ, MaxChunkZ; - cChunkDef::BlockToChunk(X - 128, Z - 128, MinChunkX, MinChunkZ); - cChunkDef::BlockToChunk(X + 128, Z + 128, MaxChunkX, MaxChunkZ); - for (int ChunkX = MinChunkX; ChunkX <= MaxChunkX; ++ChunkX) - { - for (int ChunkZ = MinChunkZ; ChunkZ <= MaxChunkZ; ++ChunkZ) - { - LOG("Queue %i %i", ChunkX, ChunkZ); - Stay->Add(ChunkX, ChunkZ); - } - } - - Stay->Enable(*GetWorld()->GetChunkMap()); return; } default: break; @@ -1199,64 +1157,6 @@ void cEntity::DetectPortal() -void cEntity::CreateExitPortal(int a_BlockX, int a_BlockY, int a_BlockZ, double a_EntityWidth, double a_EntityHeight, cWorld & a_World, int a_UniqueIDToTeleport) -{ - cBlockArea Area; - Area.Read(&a_World, a_BlockX - 128, a_BlockX + 128, 0, 128, a_BlockZ - 128, a_BlockZ + 128); - for (int x = a_BlockX - 128; x <= a_BlockX + 128; ++x) for (int y = 0; y <= 128; ++y) for (int z = a_BlockZ - 128; z <= a_BlockZ + 128; ++z) - { - if ( - (Area.GetBlockType(x, y, z) == E_BLOCK_NETHER_PORTAL) && - ( - (Area.GetBlockType(x, (int)floor(y + a_EntityHeight), z) == E_BLOCK_NETHER_PORTAL) || - (Area.GetBlockType(x, (int)floor(y - a_EntityHeight), z) == E_BLOCK_NETHER_PORTAL) - ) - ) - { - class cTeleportEntityToPortalCallback : public cEntityCallback - { - public: - cTeleportEntityToPortalCallback(int a_X, int a_Y, int a_Z) : - m_X(a_X), - m_Y(a_Y), - m_Z(a_Z) - {} - - virtual bool Item(cEntity * a_Entity) override - { - a_Entity->TeleportToCoords(m_X, m_Y, m_Z); - return true; - } - - private: - int m_X, m_Y, m_Z; - }; - - cTeleportEntityToPortalCallback TETPC(x, y, z); - a_World.DoWithEntityByID(a_UniqueIDToTeleport, TETPC); - return; - } - } - - int MinX = std::max(a_BlockX - (int)ceil(a_EntityWidth), a_BlockX - 2), MaxX = std::max(a_BlockX + (int)ceil(a_EntityWidth), a_BlockX + 1); - int MinY = std::max(a_BlockY - (int)ceil(a_EntityHeight), a_BlockY - 2), MaxY = std::max(a_BlockY + (int)ceil(a_EntityHeight), a_BlockY + 1); - - for (int y = MinY; y < MaxY + 1; y += MaxY - MinY) for (int x = MinX; x < MaxX + 1; ++x) - { - Area.SetBlockType(x, y, a_BlockZ, E_BLOCK_OBSIDIAN); - } - for (int y = MinY; y < MaxY + 1; ++y) for (int x = MinX; x < MaxX + 1; x += MaxX - MinX) - { - Area.SetBlockType(x, y, a_BlockZ, E_BLOCK_OBSIDIAN); - } - - Area.Write(&a_World, MinX, MinY, a_BlockZ); -} - - - - - bool cEntity::MoveToWorld(const AString & a_WorldName, cWorld * a_World, bool a_ShouldSendRespawn) { UNUSED(a_ShouldSendRespawn); -- cgit v1.2.3 From 1296c5dce71f59f1d7b2bfd1791a22daa26f2cb3 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 21 Jun 2014 20:42:10 +0100 Subject: More suggestions --- src/Entities/Entity.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/Entities/Entity.cpp') diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index d42c49abe..9110cd83b 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -869,7 +869,7 @@ void cEntity::TickBurning(cChunk & a_Chunk) // Remember the current burning state: bool HasBeenBurning = (m_TicksLeftBurning > 0); - if (IsBiomeNoDownfall(a_Chunk.GetBiomeAt(POSX_TOINT - a_Chunk.GetPosX() * cChunkDef::Width, POSZ_TOINT - a_Chunk.GetPosZ() * cChunkDef::Width)) || GetWorld()->IsWeatherWet()) + if (GetWorld()->IsWeatherWetAt(POSX_TOINT, POSZ_TOINT)) { if (POSY_TOINT > m_World->GetHeight(POSX_TOINT, POSZ_TOINT)) { -- cgit v1.2.3 From 6e681269d9dfb33b5b73f4f01a61def247b3aee7 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 21 Jun 2014 22:07:38 +0100 Subject: Fixed invalid iterators --- src/Entities/Entity.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/Entities/Entity.cpp') diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 9110cd83b..9a8c6586d 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -57,6 +57,7 @@ cEntity::cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z, d , m_Width(a_Width) , m_Height(a_Height) , m_InvulnerableTicks(0) + , m_IsTravellingThroughPortal(false) { cCSLock Lock(m_CSCount); m_EntityCount++; @@ -1183,7 +1184,7 @@ bool cEntity::MoveToWorld(const AString & a_WorldName, cWorld * a_World, bool a_ } // Remove all links to the old world - GetWorld()->RemoveEntity(this); + SetIsTravellingThroughPortal(true); // cChunk handles entity removal GetWorld()->BroadcastDestroyEntity(*this); // Queue add to new world -- cgit v1.2.3 From e709652257da1ba06a6642b4978365b14bc11a22 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 22 Jun 2014 00:21:39 +0100 Subject: Conforms to standards --- src/Entities/Entity.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/Entities/Entity.cpp') diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index fadd12135..d4edc9144 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -37,6 +37,7 @@ cEntity::cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z, d , m_Gravity(-9.81f) , m_LastPos(a_X, a_Y, a_Z) , m_IsInitialized(false) + , m_IsTravellingThroughPortal(false) , m_EntityType(a_EntityType) , m_World(NULL) , m_IsFireproof(false) @@ -57,7 +58,6 @@ cEntity::cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z, d , m_Width(a_Width) , m_Height(a_Height) , m_InvulnerableTicks(0) - , m_IsTravellingThroughPortal(false) { cCSLock Lock(m_CSCount); m_EntityCount++; -- cgit v1.2.3 From 719551c31f5ed0d3cbad9797dd81a6bf1ae4e5a2 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 18 Jul 2014 20:12:27 +0100 Subject: Fix failed merge and other issues --- src/Entities/Entity.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/Entities/Entity.cpp') diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index e5e4cf4cb..bd1839580 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -1028,7 +1028,7 @@ void cEntity::DetectCacti(void) void cEntity::DetectPortal() { - if (!GetWorld()->AreNetherPortalsEnabled() && !GetWorld()->AreEndPortalsEnabled()) + if (!GetWorld()->GetNetherWorldName().empty() && !GetWorld()->GetEndWorldName().empty()) { return; } @@ -1040,7 +1040,7 @@ void cEntity::DetectPortal() { case E_BLOCK_NETHER_PORTAL: { - if (!GetWorld()->AreNetherPortalsEnabled() || m_PortalCooldownData.second) + if (GetWorld()->GetNetherWorldName().empty() || m_PortalCooldownData.second) { return; } @@ -1085,7 +1085,7 @@ void cEntity::DetectPortal() } case E_BLOCK_END_PORTAL: { - if (!GetWorld()->AreEndPortalsEnabled() || m_PortalCooldownData.second) + if (GetWorld()->GetNetherWorldName().empty() || m_PortalCooldownData.second) { return; } -- cgit v1.2.3 From 6ab9afd0fd808fad99cd8387c72ce461c37aef80 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 20 Jul 2014 10:46:45 +0100 Subject: Bug and crash fixes * Fixes end portals' solidity * Fixed crashes to do with multithreading and removing an entity from the wrong world * Fixed crashes due to bad merge * Fixed crashes due to an object being deleted twice * Simplified cWorld::Start() and added comments to configuration files --- src/Entities/Entity.cpp | 48 ++++++++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 18 deletions(-) (limited to 'src/Entities/Entity.cpp') diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index bd1839580..4768d38ae 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -37,7 +37,7 @@ cEntity::cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z, d , m_Gravity(-9.81f) , m_LastPos(a_X, a_Y, a_Z) , m_IsInitialized(false) - , m_IsTravellingThroughPortal(false) + , m_WorldTravellingFrom(NULL) , m_EntityType(a_EntityType) , m_World(NULL) , m_IsFireproof(false) @@ -1028,10 +1028,11 @@ void cEntity::DetectCacti(void) void cEntity::DetectPortal() { - if (!GetWorld()->GetNetherWorldName().empty() && !GetWorld()->GetEndWorldName().empty()) + if (GetWorld()->GetDimension() == dimOverworld) { - return; + if (GetWorld()->GetNetherWorldName().empty() && GetWorld()->GetEndWorldName().empty()) { return; } } + else if (GetWorld()->GetLinkedOverworldName().empty()) { return; } int X = POSX_TOINT, Y = POSY_TOINT, Z = POSZ_TOINT; if ((Y > 0) && (Y < cChunkDef::Height)) @@ -1040,7 +1041,7 @@ void cEntity::DetectPortal() { case E_BLOCK_NETHER_PORTAL: { - if (GetWorld()->GetNetherWorldName().empty() || m_PortalCooldownData.second) + if (m_PortalCooldownData.second) { return; } @@ -1054,8 +1055,13 @@ void cEntity::DetectPortal() switch (GetWorld()->GetDimension()) { - case dimNether: + case dimNether: { + if (GetWorld()->GetLinkedOverworldName().empty()) + { + return; + } + m_PortalCooldownData.second = true; // Stop portals from working on respawn if (IsPlayer()) @@ -1068,6 +1074,11 @@ void cEntity::DetectPortal() } case dimOverworld: { + if (GetWorld()->GetNetherWorldName().empty()) + { + return; + } + m_PortalCooldownData.second = true; // Stop portals from working on respawn if (IsPlayer()) @@ -1079,28 +1090,25 @@ void cEntity::DetectPortal() return; } - default: break; + default: return; } - return; } case E_BLOCK_END_PORTAL: { - if (GetWorld()->GetNetherWorldName().empty() || m_PortalCooldownData.second) - { - return; - } - - if (m_PortalCooldownData.first != 80) + if (m_PortalCooldownData.second) { - m_PortalCooldownData.first++; return; } - m_PortalCooldownData.first = 0; switch (GetWorld()->GetDimension()) { case dimEnd: { + if (GetWorld()->GetLinkedOverworldName().empty()) + { + return; + } + m_PortalCooldownData.second = true; // Stop portals from working on respawn if (IsPlayer()) @@ -1115,6 +1123,11 @@ void cEntity::DetectPortal() } case dimOverworld: { + if (GetWorld()->GetEndWorldName().empty()) + { + return; + } + m_PortalCooldownData.second = true; // Stop portals from working on respawn if (IsPlayer()) @@ -1126,9 +1139,8 @@ void cEntity::DetectPortal() return; } - default: break; + default: return; } - return; } default: break; } @@ -1169,7 +1181,7 @@ bool cEntity::MoveToWorld(const AString & a_WorldName, cWorld * a_World, bool a_ } // Remove all links to the old world - SetIsTravellingThroughPortal(true); // cChunk handles entity removal + SetWorldTravellingFrom(GetWorld()); // cChunk handles entity removal GetWorld()->BroadcastDestroyEntity(*this); // Queue add to new world -- cgit v1.2.3 From 8050a5b98a3003c2a4bed39b896b4a3a4c1068c0 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 21 Jul 2014 22:49:06 +0100 Subject: Suggestions --- src/Entities/Entity.cpp | 78 +++++++++++++++++++++++++++---------------------- 1 file changed, 43 insertions(+), 35 deletions(-) (limited to 'src/Entities/Entity.cpp') 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); -- cgit v1.2.3 From a28b0dc1201dca7c34d9a6c33232157e45a6d4f8 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 22 Jul 2014 17:26:48 +0100 Subject: Speed improvements, crash fixes, & self-suggestions --- src/Entities/Entity.cpp | 59 ++++++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 30 deletions(-) (limited to 'src/Entities/Entity.cpp') diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index a7340a29c..68bfabb30 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -614,11 +614,13 @@ void cEntity::Tick(float a_Dt, cChunk & a_Chunk) // Handle drowning HandleAir(); + } + + if (!DetectPortal()) // Our chunk is invalid if we have moved to another world + { + // None of the above functions changed position, we remain in the chunk of NextChunk + HandlePhysics(a_Dt, *NextChunk); } - DetectPortal(); - - // None of the above functions change position, we remain in the chunk of NextChunk - HandlePhysics(a_Dt, *NextChunk); } } @@ -1026,18 +1028,18 @@ void cEntity::DetectCacti(void) -void cEntity::DetectPortal() +bool cEntity::DetectPortal() { if (GetWorld()->GetDimension() == dimOverworld) { if (GetWorld()->GetNetherWorldName().empty() && GetWorld()->GetEndWorldName().empty()) { - return; + return false; } } else if (GetWorld()->GetLinkedOverworldName().empty()) { - return; + return false; } int X = POSX_TOINT, Y = POSY_TOINT, Z = POSZ_TOINT; @@ -1049,13 +1051,13 @@ void cEntity::DetectPortal() { if (m_PortalCooldownData.m_ShouldPreventTeleportation) { - return; + return false; } if (IsPlayer() && !((cPlayer *)this)->IsGameModeCreative() && m_PortalCooldownData.m_TicksDelayed != 80) { m_PortalCooldownData.m_TicksDelayed++; - return; + return false; } m_PortalCooldownData.m_TicksDelayed = 0; @@ -1065,7 +1067,7 @@ void cEntity::DetectPortal() { if (GetWorld()->GetLinkedOverworldName().empty()) { - return; + return false; } m_PortalCooldownData.m_ShouldPreventTeleportation = true; // Stop portals from working on respawn @@ -1074,15 +1076,14 @@ void cEntity::DetectPortal() { ((cPlayer *)this)->GetClientHandle()->SendRespawn(dimOverworld); } - MoveToWorld(cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetLinkedOverworldName()), false); - - return; + + return MoveToWorld(cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetLinkedOverworldName()), false); } case dimOverworld: { if (GetWorld()->GetNetherWorldName().empty()) { - return; + return false; } m_PortalCooldownData.m_ShouldPreventTeleportation = true; // Stop portals from working on respawn @@ -1092,18 +1093,17 @@ void cEntity::DetectPortal() ((cPlayer *)this)->AwardAchievement(achEnterPortal); ((cPlayer *)this)->GetClientHandle()->SendRespawn(dimNether); } - MoveToWorld(cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetNetherWorldName(), dimNether, GetWorld()->GetName()), false); - - return; + + return MoveToWorld(cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetNetherWorldName(), dimNether, GetWorld()->GetName()), false); } - default: return; + default: return false; } } case E_BLOCK_END_PORTAL: { if (m_PortalCooldownData.m_ShouldPreventTeleportation) { - return; + return false; } switch (GetWorld()->GetDimension()) @@ -1112,7 +1112,7 @@ void cEntity::DetectPortal() { if (GetWorld()->GetLinkedOverworldName().empty()) { - return; + return false; } m_PortalCooldownData.m_ShouldPreventTeleportation = true; // Stop portals from working on respawn @@ -1122,16 +1122,15 @@ void cEntity::DetectPortal() cPlayer * Player = (cPlayer *)this; Player->TeleportToCoords(Player->GetLastBedPos().x, Player->GetLastBedPos().y, Player->GetLastBedPos().z); Player->GetClientHandle()->SendRespawn(dimOverworld); - } - MoveToWorld(cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetLinkedOverworldName()), false); + } - return; + return MoveToWorld(cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetLinkedOverworldName()), false); } case dimOverworld: { if (GetWorld()->GetEndWorldName().empty()) { - return; + return false; } m_PortalCooldownData.m_ShouldPreventTeleportation = true; // Stop portals from working on respawn @@ -1140,12 +1139,11 @@ void cEntity::DetectPortal() { ((cPlayer *)this)->AwardAchievement(achEnterTheEnd); ((cPlayer *)this)->GetClientHandle()->SendRespawn(dimEnd); - } - MoveToWorld(cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetEndWorldName(), dimEnd, GetWorld()->GetName()), false); + } - return; + return MoveToWorld(cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetEndWorldName(), dimEnd, GetWorld()->GetName()), false); } - default: return; + default: return false; } } default: break; @@ -1155,6 +1153,7 @@ void cEntity::DetectPortal() // Allow portals to work again m_PortalCooldownData.m_ShouldPreventTeleportation = false; m_PortalCooldownData.m_ShouldPreventTeleportation = 0; + return false; } @@ -1164,7 +1163,7 @@ void cEntity::DetectPortal() bool cEntity::MoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn) { UNUSED(a_ShouldSendRespawn); - ASSERT(a_World == NULL); + ASSERT(a_World != NULL); if (GetWorld() == a_World) { @@ -1173,7 +1172,7 @@ bool cEntity::MoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn) } // Remove all links to the old world - SetWorldTravellingFrom(GetWorld()); // cChunk handles entity removal + SetWorldTravellingFrom(GetWorld()); // cChunk handles entity removal GetWorld()->BroadcastDestroyEntity(*this); // Queue add to new world -- cgit v1.2.3 From 1156914dd60b4949116e57ec1480f81c39b6f292 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 23 Jul 2014 21:12:59 +0100 Subject: Suggestions --- src/Entities/Entity.cpp | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'src/Entities/Entity.cpp') diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 68bfabb30..45c347aeb 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -1034,11 +1034,13 @@ bool cEntity::DetectPortal() { if (GetWorld()->GetNetherWorldName().empty() && GetWorld()->GetEndWorldName().empty()) { + // Teleportation to either dimension not enabled, don't bother proceeding return false; } } else if (GetWorld()->GetLinkedOverworldName().empty()) { + // Overworld teleportation disabled, abort return false; } @@ -1051,11 +1053,13 @@ bool cEntity::DetectPortal() { if (m_PortalCooldownData.m_ShouldPreventTeleportation) { + // Just exited a portal, don't teleport again return false; } if (IsPlayer() && !((cPlayer *)this)->IsGameModeCreative() && m_PortalCooldownData.m_TicksDelayed != 80) { + // Delay teleportation for four seconds if the entity is a non-creative player m_PortalCooldownData.m_TicksDelayed++; return false; } @@ -1070,11 +1074,11 @@ bool cEntity::DetectPortal() return false; } - m_PortalCooldownData.m_ShouldPreventTeleportation = 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); + ((cPlayer *)this)->GetClientHandle()->SendRespawn(dimOverworld); // Send a respawn packet before world is loaded/generated so the client isn't left in limbo } return MoveToWorld(cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetLinkedOverworldName()), false); @@ -1086,7 +1090,7 @@ bool cEntity::DetectPortal() return false; } - m_PortalCooldownData.m_ShouldPreventTeleportation = true; // Stop portals from working on respawn + m_PortalCooldownData.m_ShouldPreventTeleportation = true; if (IsPlayer()) { @@ -1115,7 +1119,7 @@ bool cEntity::DetectPortal() return false; } - m_PortalCooldownData.m_ShouldPreventTeleportation = true; // Stop portals from working on respawn + m_PortalCooldownData.m_ShouldPreventTeleportation = true; if (IsPlayer()) { @@ -1133,7 +1137,7 @@ bool cEntity::DetectPortal() return false; } - m_PortalCooldownData.m_ShouldPreventTeleportation = true; // Stop portals from working on respawn + m_PortalCooldownData.m_ShouldPreventTeleportation = true; if (IsPlayer()) { @@ -1152,7 +1156,7 @@ bool cEntity::DetectPortal() // Allow portals to work again m_PortalCooldownData.m_ShouldPreventTeleportation = false; - m_PortalCooldownData.m_ShouldPreventTeleportation = 0; + m_PortalCooldownData.m_TicksDelayed = 0; return false; } @@ -1160,7 +1164,7 @@ bool cEntity::DetectPortal() -bool cEntity::MoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn) +bool cEntity::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn) { UNUSED(a_ShouldSendRespawn); ASSERT(a_World != NULL); @@ -1172,11 +1176,12 @@ bool cEntity::MoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn) } // Remove all links to the old world - SetWorldTravellingFrom(GetWorld()); // cChunk handles entity removal + SetWorldTravellingFrom(GetWorld()); // cChunk::Tick() handles entity removal GetWorld()->BroadcastDestroyEntity(*this); // Queue add to new world a_World->AddEntity(this); + SetWorld(a_World); return true; } @@ -1194,7 +1199,7 @@ bool cEntity::MoveToWorld(const AString & a_WorldName, bool a_ShouldSendRespawn) return false; } - return MoveToWorld(World, a_ShouldSendRespawn); + return DoMoveToWorld(World, a_ShouldSendRespawn); } -- cgit v1.2.3 From cb77b39dc6ff19698c504525259aa2c3170aadae Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 29 Jul 2014 16:36:24 +0100 Subject: Detrailed whitespace --- src/Entities/Entity.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/Entities/Entity.cpp') diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 261afd89d..da578013d 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -617,7 +617,7 @@ void cEntity::Tick(float a_Dt, cChunk & a_Chunk) // Handle drowning HandleAir(); - } + } if (!DetectPortal()) // Our chunk is invalid if we have moved to another world { @@ -1129,7 +1129,7 @@ bool cEntity::DetectPortal() cPlayer * Player = (cPlayer *)this; Player->TeleportToCoords(Player->GetLastBedPos().x, Player->GetLastBedPos().y, Player->GetLastBedPos().z); Player->GetClientHandle()->SendRespawn(dimOverworld); - } + } return MoveToWorld(cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetLinkedOverworldName()), false); } @@ -1146,7 +1146,7 @@ bool cEntity::DetectPortal() { ((cPlayer *)this)->AwardAchievement(achEnterTheEnd); ((cPlayer *)this)->GetClientHandle()->SendRespawn(dimEnd); - } + } return MoveToWorld(cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetEndWorldName(), dimEnd, GetWorld()->GetName()), false); } -- cgit v1.2.3