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 ++++++++++++++++++++++++++++++++++++++++++++++++ src/Entities/Entity.h | 6 +++ src/Entities/Player.cpp | 36 ++++++++++----- src/Entities/Player.h | 2 +- 4 files changed, 150 insertions(+), 11 deletions(-) (limited to 'src/Entities') 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); diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h index 0c393c0f5..da8256606 100644 --- a/src/Entities/Entity.h +++ b/src/Entities/Entity.h @@ -323,6 +323,9 @@ public: /** Detects the time for application of cacti damage */ virtual void DetectCacti(void); + + /** Detects whether we are in a portal block and begins teleportation procedures if so */ + virtual void DetectPortal(void); /// Handles when the entity is in the void virtual void TickInVoid(cChunk & a_Chunk); @@ -365,6 +368,9 @@ 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); // tolua_end diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 0dfdcfd8b..140b98d5d 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -134,7 +134,7 @@ cPlayer::~cPlayer(void) SaveToDisk(); - m_World->RemovePlayer( this ); + m_World->RemovePlayer(this); m_ClientHandle = NULL; @@ -150,8 +150,6 @@ cPlayer::~cPlayer(void) void cPlayer::Destroyed() { CloseWindow(false); - - m_ClientHandle = NULL; } @@ -952,7 +950,7 @@ void cPlayer::Respawn(void) m_LifetimeTotalXp = 0; // ToDo: send score to client? How? - m_ClientHandle->SendRespawn(); + m_ClientHandle->SendRespawn(*GetWorld()); // Extinguish the fire: StopBurning(); @@ -1574,12 +1572,25 @@ void cPlayer::TossItems(const cItems & a_Items) -bool cPlayer::MoveToWorld(const char * a_WorldName) +bool cPlayer::MoveToWorld(const AString & a_WorldName, cWorld * a_World) { - cWorld * World = cRoot::Get()->GetWorld(a_WorldName); - if (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); + return false; + } + } + else + { + World = a_World; + } + + if (GetWorld() == World) { - LOG("%s: Couldn't find world \"%s\".", __FUNCTION__, a_WorldName); return false; } @@ -1588,11 +1599,11 @@ bool cPlayer::MoveToWorld(const char * a_WorldName) // Remove all links to the old world m_World->RemovePlayer(this); m_ClientHandle->RemoveFromAllChunks(); - m_World->RemoveEntity(this); // If the dimension is different, we can send the respawn packet // http://wiki.vg/Protocol#0x09 says "don't send if dimension is the same" as of 2013_07_02 - m_ClientHandle->MoveToWorld(*World, (OldDimension != World->GetDimension())); + bool SendRespawn = OldDimension != World->GetDimension(); + m_ClientHandle->MoveToWorld(*World, SendRespawn); // Add player to all the necessary parts of the new world SetWorld(World); @@ -1600,6 +1611,11 @@ bool cPlayer::MoveToWorld(const char * a_WorldName) World->AddEntity(this); World->AddPlayer(this); + if (SendRespawn) + { + GetClientHandle()->SendPlayerMoveLook(); + } + return true; } diff --git a/src/Entities/Player.h b/src/Entities/Player.h index b7cb27d6c..582f79b86 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -328,7 +328,7 @@ public: void SetVisible( bool a_bVisible ); // tolua_export bool IsVisible(void) const { return m_bVisible; } // tolua_export - bool MoveToWorld(const char * a_WorldName); // tolua_export + virtual bool MoveToWorld(const AString & a_WorldName, cWorld * a_World = NULL) override; // tolua_export bool SaveToDisk(void); bool LoadFromDisk(void); -- 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 ++++++ src/Entities/Player.cpp | 35 ++++++++++++++++++++++------------- src/Entities/Player.h | 15 ++++++++++++--- 3 files changed, 40 insertions(+), 16 deletions(-) (limited to 'src/Entities') 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: diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 140b98d5d..3058d6e94 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -82,13 +82,13 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) m_PlayerName = a_PlayerName; - if (!LoadFromDisk()) + cWorld * World; + if (!LoadFromDisk(World)) { m_Inventory.Clear(); - cWorld * DefaultWorld = cRoot::Get()->GetDefaultWorld(); - SetPosX(DefaultWorld->GetSpawnX()); - SetPosY(DefaultWorld->GetSpawnY()); - SetPosZ(DefaultWorld->GetSpawnZ()); + SetPosX(World->GetSpawnX()); + SetPosY(World->GetSpawnY()); + SetPosZ(World->GetSpawnZ()); LOGD("Player \"%s\" is connecting for the first time, spawning at default world spawn {%.2f, %.2f, %.2f}", a_PlayerName.c_str(), GetPosX(), GetPosY(), GetPosZ() @@ -101,11 +101,6 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) if (m_GameMode == gmNotSet) { - cWorld * World = cRoot::Get()->GetWorld(GetLoadedWorldName()); - if (World == NULL) - { - World = cRoot::Get()->GetDefaultWorld(); - } if (World->IsGameModeCreative()) { m_CanFly = true; @@ -955,7 +950,7 @@ void cPlayer::Respawn(void) // Extinguish the fire: StopBurning(); - TeleportToCoords(GetWorld()->GetSpawnX(), GetWorld()->GetSpawnY(), GetWorld()->GetSpawnZ()); + TeleportToCoords(GetLastBedPos().x, GetLastBedPos().y, GetLastBedPos().z); SetVisible(true); } @@ -1614,6 +1609,8 @@ bool cPlayer::MoveToWorld(const AString & a_WorldName, cWorld * a_World) if (SendRespawn) { GetClientHandle()->SendPlayerMoveLook(); + GetClientHandle()->SendHealth(); + GetClientHandle()->SendWholeInventory((cWindow &)GetInventory()); } return true; @@ -1662,8 +1659,14 @@ void cPlayer::LoadPermissionsFromDisk() -bool cPlayer::LoadFromDisk() +bool cPlayer::LoadFromDisk(cWorld * a_World) { + a_World = cRoot::Get()->GetWorld(GetLoadedWorldName()); + if (a_World == NULL) + { + a_World = cRoot::Get()->GetDefaultWorld(); + } + LoadPermissionsFromDisk(); // Log player permissions, cause it's what the cool kids do @@ -1724,6 +1727,9 @@ bool cPlayer::LoadFromDisk() m_LifetimeTotalXp = (short) root.get("xpTotal", 0).asInt(); m_CurrentXp = (short) root.get("xpCurrent", 0).asInt(); m_IsFlying = root.get("isflying", 0).asBool(); + m_LastBedPos.x = root.get("SpawnX", a_World->GetSpawnX()).asInt(); + m_LastBedPos.y = root.get("SpawnY", a_World->GetSpawnY()).asInt(); + m_LastBedPos.z = root.get("SpawnZ", a_World->GetSpawnZ()).asInt(); m_GameMode = (eGameMode) root.get("gamemode", eGameMode_NotSet).asInt(); @@ -1742,7 +1748,7 @@ bool cPlayer::LoadFromDisk() StatSerializer.Load(); LOGD("Player \"%s\" was read from file, spawning at {%.2f, %.2f, %.2f} in world \"%s\"", - GetName().c_str(), GetPosX(), GetPosY(), GetPosZ(), m_LoadedWorldName.c_str() + GetName().c_str(), GetPosX(), GetPosY(), GetPosZ(), GetLoadedWorldName().c_str() ); return true; @@ -1784,6 +1790,9 @@ bool cPlayer::SaveToDisk() root["foodExhaustion"] = m_FoodExhaustionLevel; root["world"] = GetWorld()->GetName(); root["isflying"] = IsFlying(); + root["SpawnX"] = GetLastBedPos().x; + root["SpawnY"] = GetLastBedPos().y; + root["SpawnZ"] = GetLastBedPos().z; if (m_GameMode == GetWorld()->GetGameMode()) { diff --git a/src/Entities/Player.h b/src/Entities/Player.h index 582f79b86..5c0b61064 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -331,7 +331,7 @@ public: virtual bool MoveToWorld(const AString & a_WorldName, cWorld * a_World = NULL) override; // tolua_export bool SaveToDisk(void); - bool LoadFromDisk(void); + bool LoadFromDisk(cWorld * a_World); void LoadPermissionsFromDisk(void); // tolua_export const AString & GetLoadedWorldName() { return m_LoadedWorldName; } @@ -391,11 +391,19 @@ public: /** If true the player can fly even when he's not in creative. */ void SetCanFly(bool a_CanFly); + /** Gets the last position that the player slept in */ + Vector3i GetLastBedPos(void) const { return m_LastBedPos; } + + /** Sets the player's bed (home) position */ + void SetBedPos(const Vector3i & a_Pos) { m_LastBedPos = a_Pos; } + /** Update movement-related statistics. */ void UpdateMovementStats(const Vector3d & a_DeltaPos); /** Returns wheter the player can fly or not. */ virtual bool CanFly(void) const { return m_CanFly; } + + // tolua_end // cEntity overrides: @@ -450,6 +458,9 @@ protected: cWindow * m_CurrentWindow; cWindow * m_InventoryWindow; + /** The player's last saved bed position */ + Vector3i m_LastBedPos; + char m_Color; eGameMode m_GameMode; @@ -508,8 +519,6 @@ protected: cStatManager m_Stats; - - void ResolvePermissions(void); void ResolveGroups(void); -- 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') 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 74cd4f552152f73d0d46cf726bcef472841e2da5 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 4 Jun 2014 18:59:56 +0100 Subject: Suggestions --- src/Entities/Player.cpp | 2 +- src/Entities/Player.h | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) (limited to 'src/Entities') diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 02a55566c..8e4c89f68 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1659,7 +1659,7 @@ void cPlayer::LoadPermissionsFromDisk() -bool cPlayer::LoadFromDisk(cWorld * a_World) +bool cPlayer::LoadFromDisk(cWorld *& a_World) { a_World = cRoot::Get()->GetWorld(GetLoadedWorldName()); if (a_World == NULL) diff --git a/src/Entities/Player.h b/src/Entities/Player.h index 5c0b61064..39031fbfb 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -127,7 +127,7 @@ public: inline const cItem & GetEquippedItem(void) const { return GetInventory().GetEquippedItem(); } // tolua_export - /** Returns whether the player is climbing (ladders, vines e.t.c). */ + /** Returns whether the player is climbing (ladders, vines etc.) */ bool IsClimbing(void) const; virtual void TeleportToCoords(double a_PosX, double a_PosY, double a_PosZ) override; @@ -330,8 +330,13 @@ public: virtual bool MoveToWorld(const AString & a_WorldName, cWorld * a_World = NULL) override; // tolua_export + /** Saves all player data, such as inventory, to JSON */ bool SaveToDisk(void); - bool LoadFromDisk(cWorld * a_World); + + /** Loads player data from JSON to the object + Takes a (NULL) cWorld pointer which it will assign a value to based on either the loaded world or default world + */ + bool LoadFromDisk(cWorld *& a_World); void LoadPermissionsFromDisk(void); // tolua_export const AString & GetLoadedWorldName() { return m_LoadedWorldName; } @@ -342,8 +347,7 @@ public: void SendExperience(void); - // In UI windows, the item that the player is dragging: - bool IsDraggingItem(void) const { return !m_DraggingItem.IsEmpty(); } + /** In UI windows, the item that the player is dragging */ cItem & GetDraggingItem(void) {return m_DraggingItem; } // In UI windows, when inventory-painting: -- 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 ++++++++++++++++++++++++++++++++------------- src/Entities/Player.cpp | 2 +- 2 files changed, 33 insertions(+), 14 deletions(-) (limited to 'src/Entities') 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; } } diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 8e4c89f68..eebc9ecf9 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1610,7 +1610,7 @@ bool cPlayer::MoveToWorld(const AString & a_WorldName, cWorld * a_World) { GetClientHandle()->SendPlayerMoveLook(); GetClientHandle()->SendHealth(); - GetClientHandle()->SendWholeInventory((cWindow &)GetInventory()); + GetClientHandle()->SendWholeInventory(*GetWindow()); } return true; -- 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 ++++-- src/Entities/Player.cpp | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'src/Entities') 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); diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index eebc9ecf9..c2f384abf 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -89,6 +89,7 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) SetPosX(World->GetSpawnX()); SetPosY(World->GetSpawnY()); SetPosZ(World->GetSpawnZ()); + SetBedPos(Vector3i(World->GetSpawnX(), World->GetSpawnY(), World->GetSpawnZ())); LOGD("Player \"%s\" is connecting for the first time, spawning at default world spawn {%.2f, %.2f, %.2f}", a_PlayerName.c_str(), GetPosX(), GetPosY(), GetPosZ() -- cgit v1.2.3 From f22a1b226ca1f5969ab9882c3f9c6f00c6c90aa2 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Thu, 5 Jun 2014 08:25:26 +0100 Subject: Fixed compilation --- src/Entities/Player.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/Entities') diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index c2f384abf..af4299e4b 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1576,7 +1576,7 @@ bool cPlayer::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 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 +++++++++++++++++++++++++++++++++--------------- src/Entities/Entity.h | 3 ++ 2 files changed, 92 insertions(+), 41 deletions(-) (limited to 'src/Entities') 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; diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h index da8256606..b2317aaac 100644 --- a/src/Entities/Entity.h +++ b/src/Entities/Entity.h @@ -335,6 +335,9 @@ public: /// Called when the entity finishes burning virtual void OnFinishedBurning(void); + + /** Creates exit portal at given coordinates */ + void CreateExitPortal(int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_begin -- 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 +++++++++++++++++++++++++++++++++++++----------- src/Entities/Entity.h | 10 +++- src/Entities/Player.cpp | 21 +++------ src/Entities/Player.h | 10 ++-- 4 files changed, 112 insertions(+), 50 deletions(-) (limited to 'src/Entities') 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; diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h index 934e0302b..4d922aa11 100644 --- a/src/Entities/Entity.h +++ b/src/Entities/Entity.h @@ -338,7 +338,7 @@ public: virtual void OnFinishedBurning(void); /** Creates exit portal at given coordinates */ - void CreateExitPortal(int a_BlockX, int a_BlockY, int a_BlockZ); + static void CreateExitPortal(int a_BlockX, int a_BlockY, int a_BlockZ, double a_EntityWidth, double a_EntityHeight, cWorld & a_World, int a_UniqueIDToTeleport); // tolua_begin @@ -374,7 +374,7 @@ public: 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); + virtual bool MoveToWorld(const AString & a_WorldName, cWorld * a_World = NULL, bool a_ShouldSendRespawn = true); // tolua_end @@ -510,6 +510,12 @@ protected: /** Air level of a mobile */ int m_AirLevel; int m_AirTickTimer; + + /** Portal delay timer and cooldown boolean + First value is to delay sending the repsawn 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; private: /** Measured in degrees, [-180, +180) */ diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 4d6688694..a346e68cf 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -948,7 +948,7 @@ void cPlayer::Respawn(void) m_LifetimeTotalXp = 0; // ToDo: send score to client? How? - m_ClientHandle->SendRespawn(*GetWorld()); + m_ClientHandle->SendRespawn(GetWorld()->GetDimension()); // Extinguish the fire: StopBurning(); @@ -1570,7 +1570,7 @@ void cPlayer::TossItems(const cItems & a_Items) -bool cPlayer::MoveToWorld(const AString & a_WorldName, cWorld * a_World) +bool cPlayer::MoveToWorld(const AString & a_WorldName, cWorld * a_World, bool a_ShouldSendRespawn) { cWorld * World; if (a_World == NULL) @@ -1589,31 +1589,22 @@ bool cPlayer::MoveToWorld(const AString & a_WorldName, cWorld * a_World) if (GetWorld() == World) { + // Don't move to same world return false; } // Send the respawn packet: - if (m_ClientHandle != NULL) + if (a_ShouldSendRespawn && (m_ClientHandle != NULL)) { - m_ClientHandle->SendRespawn(*World); + m_ClientHandle->SendRespawn(World->GetDimension()); } - // Remove all links to the old world + // Remove player from old world m_World->RemovePlayer(this); - // If the dimension is different, we can send the respawn packet - // http://wiki.vg/Protocol#0x09 says "don't send if dimension is the same" as of 2013_07_02 - // Queue adding player to the new world, including all the necessary adjustments to the object World->AddPlayer(this); - if (GetWorld()->GetDimension() != World->GetDimension()) - { - GetClientHandle()->SendPlayerMoveLook(); - GetClientHandle()->SendHealth(); - GetClientHandle()->SendWholeInventory(*GetWindow()); - } - return true; } diff --git a/src/Entities/Player.h b/src/Entities/Player.h index 99a0e601c..8f319f1ae 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -323,14 +323,14 @@ public: virtual void Killed(cEntity * a_Victim) override; - void Respawn(void); // tolua_export + void Respawn(void); // tolua_export - void SetVisible( bool a_bVisible ); // tolua_export - bool IsVisible(void) const { return m_bVisible; } // tolua_export + void SetVisible(bool a_bVisible); // tolua_export + bool IsVisible(void) const { return m_bVisible; } // tolua_export /** 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) override; // tolua_export + virtual bool MoveToWorld(const AString & a_WorldName, cWorld * a_World = NULL, bool a_ShouldSendRespawn = true) override; // tolua_export /** Saves all player data, such as inventory, to JSON */ bool SaveToDisk(void); @@ -339,7 +339,7 @@ public: Takes a (NULL) cWorld pointer which it will assign a value to based on either the loaded world or default world */ bool LoadFromDisk(cWorld *& a_World); - void LoadPermissionsFromDisk(void); // tolua_export + void LoadPermissionsFromDisk(void); // tolua_export const AString & GetLoadedWorldName() { return m_LoadedWorldName; } -- 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') 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 ------------------------------------------------ src/Entities/Entity.h | 3 -- 2 files changed, 103 deletions(-) (limited to 'src/Entities') 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); diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h index 4d922aa11..9f3b06c29 100644 --- a/src/Entities/Entity.h +++ b/src/Entities/Entity.h @@ -336,9 +336,6 @@ public: /// Called when the entity finishes burning virtual void OnFinishedBurning(void); - - /** Creates exit portal at given coordinates */ - static void CreateExitPortal(int a_BlockX, int a_BlockY, int a_BlockZ, double a_EntityWidth, double a_EntityHeight, cWorld & a_World, int a_UniqueIDToTeleport); // tolua_begin -- cgit v1.2.3 From b2fbcaf1bf43ca1f0e6df48de8584149cbe50222 Mon Sep 17 00:00:00 2001 From: archshift Date: Sun, 15 Jun 2014 20:27:27 -0700 Subject: Implemented PR suggestions Furnace.txt: newline BlockID: removed extraneous dimension mapping cEntity: fixed typo cPlayer: WorldPtr typedef --- src/Entities/Entity.h | 2 +- src/Entities/Player.cpp | 2 +- src/Entities/Player.h | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src/Entities') diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h index 9f3b06c29..8975803a2 100644 --- a/src/Entities/Entity.h +++ b/src/Entities/Entity.h @@ -509,7 +509,7 @@ protected: int m_AirTickTimer; /** Portal delay timer and cooldown boolean - First value is to delay sending the repsawn packet (which triggers the Entering the {Dimension} screen). + 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; diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index a346e68cf..c26c18690 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1651,7 +1651,7 @@ void cPlayer::LoadPermissionsFromDisk() -bool cPlayer::LoadFromDisk(cWorld *& a_World) +bool cPlayer::LoadFromDisk(cWorldPtr & a_World) { a_World = cRoot::Get()->GetWorld(GetLoadedWorldName()); if (a_World == NULL) diff --git a/src/Entities/Player.h b/src/Entities/Player.h index 8f319f1ae..b1fef1b68 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -335,10 +335,11 @@ public: /** Saves all player data, such as inventory, to JSON */ bool SaveToDisk(void); + typedef cWorld * cWorldPtr; /** Loads player data from JSON to the object Takes a (NULL) cWorld pointer which it will assign a value to based on either the loaded world or default world */ - bool LoadFromDisk(cWorld *& a_World); + bool LoadFromDisk(cWorldPtr & a_World); void LoadPermissionsFromDisk(void); // tolua_export const AString & GetLoadedWorldName() { return m_LoadedWorldName; } -- 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 +- src/Entities/Player.cpp | 2 +- src/Entities/Player.h | 6 ++++-- 3 files changed, 6 insertions(+), 4 deletions(-) (limited to 'src/Entities') 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)) { diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index c26c18690..e975abdf5 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1599,7 +1599,7 @@ bool cPlayer::MoveToWorld(const AString & a_WorldName, cWorld * a_World, bool a_ m_ClientHandle->SendRespawn(World->GetDimension()); } - // Remove player from old world + // Remove player from the old world m_World->RemovePlayer(this); // Queue adding player to the new world, including all the necessary adjustments to the object diff --git a/src/Entities/Player.h b/src/Entities/Player.h index b1fef1b68..c72d1eb8d 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -350,7 +350,7 @@ public: void SendExperience(void); - /** In UI windows, the item that the player is dragging */ + /** In UI windows, get the item that the player is dragging */ cItem & GetDraggingItem(void) {return m_DraggingItem; } // In UI windows, when inventory-painting: @@ -398,7 +398,9 @@ public: /** If true the player can fly even when he's not in creative. */ void SetCanFly(bool a_CanFly); - /** Gets the last position that the player slept in */ + /** Gets the last position that the player slept in + This is initialised to the world spawn point if the player has not slept in a bed as of yet + */ Vector3i GetLastBedPos(void) const { return m_LastBedPos; } /** Sets the player's bed (home) position */ -- 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 ++- src/Entities/Entity.h | 10 +++++++++- src/Entities/Player.cpp | 1 + 3 files changed, 12 insertions(+), 2 deletions(-) (limited to 'src/Entities') 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 diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h index 8975803a2..0293968ab 100644 --- a/src/Entities/Entity.h +++ b/src/Entities/Entity.h @@ -374,6 +374,12 @@ public: virtual bool MoveToWorld(const AString & a_WorldName, cWorld * a_World = NULL, bool a_ShouldSendRespawn = true); // tolua_end + + /** Returns if the entity is travelling through a portal. Set to true by MoveToWorld and to false when the entity is removed by the old chunk */ + bool IsTravellingThroughPortal(void) const { return m_IsTravellingThroughPortal; } + + /** Sets if the entity has begun travelling through a portal or not */ + void SetIsTravellingThroughPortal(bool a_Flag) { m_IsTravellingThroughPortal = a_Flag; } /// Updates clients of changes in the entity. virtual void BroadcastMovementUpdate(const cClientHandle * a_Exclude = NULL); @@ -470,6 +476,9 @@ protected: /** True when entity is initialised (Initialize()) and false when destroyed pending deletion (Destroy()) */ bool m_IsInitialized; + /** True when entity is being moved across worlds, false anytime else */ + bool m_IsTravellingThroughPortal; + eEntityType m_EntityType; cWorld * m_World; @@ -492,7 +501,6 @@ protected: /// Time, in ticks, since the last damage dealt by the void. Reset to zero when moving out of the void. int m_TicksSinceLastVoidDamage; - virtual void Destroyed(void) {} // Called after the entity has been destroyed /** Called in each tick to handle air-related processing i.e. drowning */ diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index e975abdf5..b72f14f57 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1600,6 +1600,7 @@ bool cPlayer::MoveToWorld(const AString & a_WorldName, cWorld * a_World, bool a_ } // Remove player from the old world + SetIsTravellingThroughPortal(true); // cChunk handles entity removal m_World->RemovePlayer(this); // Queue adding player to the new world, including all the necessary adjustments to the object -- 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') 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 +++--- src/Entities/Player.cpp | 40 ++++++++-------------------------------- src/Entities/Player.h | 11 +---------- 3 files changed, 12 insertions(+), 45 deletions(-) (limited to 'src/Entities') 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; } diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 1acc8a962..2a91600e7 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1695,12 +1695,7 @@ void cPlayer::LoadPermissionsFromDisk() -<<<<<<< HEAD bool cPlayer::LoadFromDisk(cWorldPtr & a_World) -======= - -bool cPlayer::LoadFromDisk(void) ->>>>>>> master { a_World = cRoot::Get()->GetWorld(GetLoadedWorldName()); if (a_World == NULL) @@ -1711,7 +1706,7 @@ bool cPlayer::LoadFromDisk(void) LoadPermissionsFromDisk(); // Load from the UUID file: - if (LoadFromFile(GetUUIDFileName(m_UUID))) + if (LoadFromFile(GetUUIDFileName(m_UUID), a_World)) { return true; } @@ -1720,7 +1715,7 @@ bool cPlayer::LoadFromDisk(void) AString OfflineUUID = cClientHandle::GenerateOfflineUUID(GetName()); if (cRoot::Get()->GetServer()->ShouldLoadOfflinePlayerData()) { - if (LoadFromFile(GetUUIDFileName(OfflineUUID))) + if (LoadFromFile(GetUUIDFileName(OfflineUUID), a_World)) { return true; } @@ -1730,7 +1725,7 @@ bool cPlayer::LoadFromDisk(void) if (cRoot::Get()->GetServer()->ShouldLoadNamedPlayerData()) { AString OldStyleFileName = Printf("players/%s.json", GetName().c_str()); - if (LoadFromFile(OldStyleFileName)) + if (LoadFromFile(OldStyleFileName, a_World)) { // Save in new format and remove the old file if (SaveToDisk()) @@ -1752,7 +1747,7 @@ bool cPlayer::LoadFromDisk(void) -bool cPlayer::LoadFromFile(const AString & a_FileName) +bool cPlayer::LoadFromFile(const AString & a_FileName, cWorld * a_World) { // Load the data from the file: cFile f; @@ -1860,28 +1855,6 @@ bool cPlayer::SaveToDisk() cEnderChestEntity::SaveToJson(JSON_EnderChestInventory, m_EnderChestContents); Json::Value root; -<<<<<<< HEAD - root["position"] = JSON_PlayerPosition; - root["rotation"] = JSON_PlayerRotation; - root["inventory"] = JSON_Inventory; - root["health"] = m_Health; - root["xpTotal"] = m_LifetimeTotalXp; - root["xpCurrent"] = m_CurrentXp; - root["air"] = m_AirLevel; - root["food"] = m_FoodLevel; - root["foodSaturation"] = m_FoodSaturationLevel; - root["foodTickTimer"] = m_FoodTickTimer; - root["foodExhaustion"] = m_FoodExhaustionLevel; - root["world"] = GetWorld()->GetName(); - root["isflying"] = IsFlying(); - root["SpawnX"] = GetLastBedPos().x; - root["SpawnY"] = GetLastBedPos().y; - root["SpawnZ"] = GetLastBedPos().z; - - if (m_GameMode == GetWorld()->GetGameMode()) - { - root["gamemode"] = (int) eGameMode_NotSet; -======= root["position"] = JSON_PlayerPosition; root["rotation"] = JSON_PlayerRotation; root["inventory"] = JSON_Inventory; @@ -1896,6 +1869,10 @@ bool cPlayer::SaveToDisk() root["foodExhaustion"] = m_FoodExhaustionLevel; root["isflying"] = IsFlying(); root["lastknownname"] = GetName(); + root["SpawnX"] = GetLastBedPos().x; + root["SpawnY"] = GetLastBedPos().y; + root["SpawnZ"] = GetLastBedPos().z; + if (m_World != NULL) { root["world"] = m_World->GetName(); @@ -1907,7 +1884,6 @@ bool cPlayer::SaveToDisk() { root["gamemode"] = (int) m_GameMode; } ->>>>>>> master } else { diff --git a/src/Entities/Player.h b/src/Entities/Player.h index f84cc5f55..ad434f036 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -326,11 +326,6 @@ public: virtual void Killed(cEntity * a_Victim) override; - void Respawn(void); // tolua_export - - void SetVisible(bool a_bVisible); // tolua_export - bool IsVisible(void) const { return m_bVisible; } // tolua_export - void Respawn(void); // tolua_export void SetVisible( bool a_bVisible ); // tolua_export @@ -352,7 +347,7 @@ Takes a (NULL) cWorld pointer which it will assign a value to based on either th /** Loads the player data from the specified file. Returns true on success, false on failure. */ - bool LoadFromFile(const AString & a_FileName); + bool LoadFromFile(const AString & a_FileName, cWorld * a_World); void LoadPermissionsFromDisk(void); // tolua_export @@ -544,8 +539,6 @@ protected: cStatManager m_Stats; -<<<<<<< HEAD -======= /** Flag representing whether the player is currently in a bed Set by a right click on unoccupied bed, unset by a time fast forward or teleport */ bool m_bIsInBed; @@ -563,8 +556,6 @@ protected: If no ClientHandle is given, the UUID is initialized to empty. */ AString m_UUID; - ->>>>>>> master /** Sets the speed and sends it to the client, so that they are forced to move so. */ virtual void DoSetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ) override; -- 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 ++++++++++++++++++++++++++++++------------------ src/Entities/Entity.h | 15 +++++++++------ src/Entities/Player.cpp | 35 +++++++++++++++++------------------ src/Entities/Player.h | 15 +++++++++------ 4 files changed, 65 insertions(+), 48 deletions(-) (limited to 'src/Entities') 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 diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h index 8b6fc05f7..eea48a12f 100644 --- a/src/Entities/Entity.h +++ b/src/Entities/Entity.h @@ -387,11 +387,11 @@ public: // tolua_end - /** Returns if the entity is travelling through a portal. Set to true by MoveToWorld and to false when the entity is removed by the old chunk */ - bool IsTravellingThroughPortal(void) const { return m_IsTravellingThroughPortal; } + /** Returns if the entity is travelling away from a specified world */ + bool IsWorldTravellingFrom(cWorld * a_World) const { return (m_WorldTravellingFrom == a_World); } - /** Sets if the entity has begun travelling through a portal or not */ - void SetIsTravellingThroughPortal(bool a_Flag) { m_IsTravellingThroughPortal = a_Flag; } + /** Sets the world the entity will be leaving */ + void SetWorldTravellingFrom(cWorld * a_World) { (m_WorldTravellingFrom = a_World); } /// Updates clients of changes in the entity. virtual void BroadcastMovementUpdate(const cClientHandle * a_Exclude = NULL); @@ -491,8 +491,11 @@ protected: /** True when entity is initialised (Initialize()) and false when destroyed pending deletion (Destroy()) */ bool m_IsInitialized; - /** True when entity is being moved across worlds, false anytime else */ - bool m_IsTravellingThroughPortal; + /** World entity is travelling from + Set by MoveToWorld and back to NULL when the entity is removed by the old chunk + Can't be a simple boolean as context switches between worlds may leave the new chunk processing (and therefore immediately removing) the entity before the old chunk could remove it + */ + cWorld * m_WorldTravellingFrom; eEntityType m_EntityType; diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 2a91600e7..0b1b4ce5f 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -88,7 +88,7 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) : m_PlayerName = a_PlayerName; - cWorld * World; + cWorld * World = NULL; if (!LoadFromDisk(World)) { m_Inventory.Clear(); @@ -136,8 +136,6 @@ cPlayer::~cPlayer(void) SaveToDisk(); - m_World->RemovePlayer(this); - m_ClientHandle = NULL; delete m_InventoryWindow; @@ -979,7 +977,7 @@ void cPlayer::Respawn(void) m_LifetimeTotalXp = 0; // ToDo: send score to client? How? - m_ClientHandle->SendRespawn(GetWorld()->GetDimension()); + m_ClientHandle->SendRespawn(GetWorld()->GetDimension(), true); // Extinguish the fire: StopBurning(); @@ -1643,11 +1641,12 @@ bool cPlayer::MoveToWorld(const AString & a_WorldName, cWorld * a_World, bool a_ } // Remove player from the old world - SetIsTravellingThroughPortal(true); // cChunk handles entity removal - m_World->RemovePlayer(this); + SetWorldTravellingFrom(GetWorld()); // cChunk handles entity removal + GetWorld()->RemovePlayer(this); // Queue adding player to the new world, including all the necessary adjustments to the object World->AddPlayer(this); + SetWorld(World); return true; } @@ -1697,12 +1696,6 @@ void cPlayer::LoadPermissionsFromDisk() bool cPlayer::LoadFromDisk(cWorldPtr & a_World) { - a_World = cRoot::Get()->GetWorld(GetLoadedWorldName()); - if (a_World == NULL) - { - a_World = cRoot::Get()->GetDefaultWorld(); - } - LoadPermissionsFromDisk(); // Load from the UUID file: @@ -1740,6 +1733,11 @@ bool cPlayer::LoadFromDisk(cWorldPtr & a_World) LOG("Player data file not found for %s (%s, offline %s), will be reset to defaults.", GetName().c_str(), m_UUID.c_str(), OfflineUUID.c_str() ); + + if (a_World == NULL) + { + a_World = cRoot::Get()->GetDefaultWorld(); + } return false; } @@ -1747,7 +1745,7 @@ bool cPlayer::LoadFromDisk(cWorldPtr & a_World) -bool cPlayer::LoadFromFile(const AString & a_FileName, cWorld * a_World) +bool cPlayer::LoadFromFile(const AString & a_FileName, cWorldPtr & a_World) { // Load the data from the file: cFile f; @@ -1800,9 +1798,6 @@ bool cPlayer::LoadFromFile(const AString & a_FileName, cWorld * a_World) m_LifetimeTotalXp = (short) root.get("xpTotal", 0).asInt(); m_CurrentXp = (short) root.get("xpCurrent", 0).asInt(); m_IsFlying = root.get("isflying", 0).asBool(); - m_LastBedPos.x = root.get("SpawnX", a_World->GetSpawnX()).asInt(); - m_LastBedPos.y = root.get("SpawnY", a_World->GetSpawnY()).asInt(); - m_LastBedPos.z = root.get("SpawnZ", a_World->GetSpawnZ()).asInt(); m_GameMode = (eGameMode) root.get("gamemode", eGameMode_NotSet).asInt(); @@ -1815,6 +1810,11 @@ bool cPlayer::LoadFromFile(const AString & a_FileName, cWorld * a_World) cEnderChestEntity::LoadFromJson(root["enderchestinventory"], m_EnderChestContents); m_LoadedWorldName = root.get("world", "world").asString(); + a_World = cRoot::Get()->GetWorld(GetLoadedWorldName(), true); + + m_LastBedPos.x = root.get("SpawnX", a_World->GetSpawnX()).asInt(); + m_LastBedPos.y = root.get("SpawnY", a_World->GetSpawnY()).asInt(); + m_LastBedPos.z = root.get("SpawnZ", a_World->GetSpawnZ()).asInt(); // Load the player stats. // We use the default world name (like bukkit) because stats are shared between dimensions/worlds. @@ -1822,7 +1822,7 @@ bool cPlayer::LoadFromFile(const AString & a_FileName, cWorld * a_World) StatSerializer.Load(); LOGD("Player %s was read from file \"%s\", spawning at {%.2f, %.2f, %.2f} in world \"%s\"", - GetName().c_str(), a_FileName.c_str(), GetPosX(), GetPosY(), GetPosZ(), m_LoadedWorldName.c_str() + GetName().c_str(), a_FileName.c_str(), GetPosX(), GetPosY(), GetPosZ(), a_World->GetName().c_str() ); return true; @@ -1834,7 +1834,6 @@ bool cPlayer::LoadFromFile(const AString & a_FileName, cWorld * a_World) bool cPlayer::SaveToDisk() { - cFile::CreateFolder(FILE_IO_PREFIX + AString("players")); cFile::CreateFolder(FILE_IO_PREFIX + AString("players/") + m_UUID.substr(0, 2)); // create the JSON data diff --git a/src/Entities/Player.h b/src/Entities/Player.h index ad434f036..226ec5e68 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -340,14 +340,17 @@ public: typedef cWorld * cWorldPtr; - /** Loads the player data from the disk file. -Takes a (NULL) cWorld pointer which it will assign a value to based on either the loaded world or default world - Returns true on success, false on failure. */ + /** Loads the player data from the disk file + Takes a (NULL) cWorld pointer which it will assign a value to based on either the loaded world or default world by calling LoadFromFile() + Returns true on success, false on failure + */ bool LoadFromDisk(cWorldPtr & a_World); - /** Loads the player data from the specified file. - Returns true on success, false on failure. */ - bool LoadFromFile(const AString & a_FileName, cWorld * a_World); + /** Loads the player data from the specified file + Takes a (NULL) cWorld pointer which it will assign a value to based on either the loaded world or default world + Returns true on success, false on failure + */ + bool LoadFromFile(const AString & a_FileName, cWorldPtr & a_World); void LoadPermissionsFromDisk(void); // tolua_export -- 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 +++++++++++++++++++++++++++---------------------- src/Entities/Entity.h | 30 +++++++++++++------ src/Entities/Player.cpp | 25 ++++------------ src/Entities/Player.h | 2 +- 4 files changed, 70 insertions(+), 65 deletions(-) (limited to 'src/Entities') 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); -- 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 ++++++++++++++++++++++++------------------------- src/Entities/Entity.h | 6 +++-- src/Entities/Player.cpp | 6 +++-- src/Entities/Player.h | 1 - 4 files changed, 37 insertions(+), 35 deletions(-) (limited to 'src/Entities') 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 diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h index 1679b00d6..62a4097f3 100644 --- a/src/Entities/Entity.h +++ b/src/Entities/Entity.h @@ -337,8 +337,10 @@ public: /** Detects the time for application of cacti damage */ virtual void DetectCacti(void); - /** Detects whether we are in a portal block and begins teleportation procedures if so */ - virtual void DetectPortal(void); + /** Detects whether we are in a portal block and begins teleportation procedures if so + Returns true if MoveToWorld() was called, false if not + */ + virtual bool DetectPortal(void); /// Handles when the entity is in the void virtual void TickInVoid(cChunk & a_Chunk); diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index e54e10a08..087ac448f 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -95,7 +95,7 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) : SetPosX(World->GetSpawnX()); SetPosY(World->GetSpawnY()); SetPosZ(World->GetSpawnZ()); - SetBedPos(Vector3i(World->GetSpawnX(), World->GetSpawnY(), World->GetSpawnZ())); + SetBedPos(Vector3i((int)World->GetSpawnX(), (int)World->GetSpawnY(), (int)World->GetSpawnZ())); LOGD("Player \"%s\" is connecting for the first time, spawning at default world spawn {%.2f, %.2f, %.2f}", a_PlayerName.c_str(), GetPosX(), GetPosY(), GetPosZ() @@ -1611,6 +1611,8 @@ void cPlayer::TossItems(const cItems & a_Items) bool cPlayer::MoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn) { + ASSERT(a_World != NULL); + if (GetWorld() == a_World) { // Don't move to same world @@ -1624,7 +1626,7 @@ bool cPlayer::MoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn) } // Remove player from the old world - SetWorldTravellingFrom(GetWorld()); // cChunk handles entity removal + SetWorldTravellingFrom(GetWorld()); // cChunk handles entity removal GetWorld()->RemovePlayer(this); // Queue adding player to the new world, including all the necessary adjustments to the object diff --git a/src/Entities/Player.h b/src/Entities/Player.h index 400377381..d1b3a0339 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -424,7 +424,6 @@ public: /** Returns wheter the player can fly or not. */ virtual bool CanFly(void) const { return m_CanFly; } - // tolua_end // cEntity overrides: -- cgit v1.2.3 From 396739cc0faf01a099acbe669c5a9def98d3aaae Mon Sep 17 00:00:00 2001 From: Howaner Date: Wed, 23 Jul 2014 16:32:09 +0200 Subject: Fix item durability. Fixes #1181 --- src/Entities/Entity.cpp | 13 ++++++++----- src/Entities/Player.cpp | 4 ++-- src/Entities/Player.h | 2 +- 3 files changed, 11 insertions(+), 8 deletions(-) (limited to 'src/Entities') diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index db0fd0fd6..6c3d7b40c 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 "Items/ItemHandler.h" @@ -289,11 +290,6 @@ void cEntity::SetPitchFromSpeed(void) bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) { - if (cRoot::Get()->GetPluginManager()->CallHookTakeDamage(*this, a_TDI)) - { - return false; - } - if (m_Health <= 0) { // Can't take damage if already dead @@ -306,10 +302,17 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) return false; } + if (cRoot::Get()->GetPluginManager()->CallHookTakeDamage(*this, a_TDI)) + { + return false; + } + if ((a_TDI.Attacker != NULL) && (a_TDI.Attacker->IsPlayer())) { cPlayer * Player = (cPlayer *)a_TDI.Attacker; + Player->GetEquippedItem().GetHandler()->OnEntityAttack(Player, this); + // IsOnGround() only is false if the player is moving downwards // TODO: Better damage increase, and check for enchantments (and use magic critical instead of plain) if (!Player->IsOnGround()) diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index fcc8eb9a0..afe5965aa 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1929,14 +1929,14 @@ cPlayer::StringList cPlayer::GetResolvedPermissions() -void cPlayer::UseEquippedItem(void) +void cPlayer::UseEquippedItem(int a_Amount) { if (IsGameModeCreative()) // No damage in creative { return; } - if (GetInventory().DamageEquippedItem()) + if (GetInventory().DamageEquippedItem(a_Amount)) { m_World->BroadcastSoundEffect("random.break", GetPosX(), GetPosY(), GetPosZ(), 0.5f, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64)); } diff --git a/src/Entities/Player.h b/src/Entities/Player.h index 26db2050b..e89d9f48f 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -349,7 +349,7 @@ public: const AString & GetLoadedWorldName() { return m_LoadedWorldName; } - void UseEquippedItem(void); + void UseEquippedItem(int a_Amount = 1); void SendHealth(void); -- 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 ++++++++++++++--------- src/Entities/Entity.h | 8 +++++--- src/Entities/Player.cpp | 2 +- src/Entities/Player.h | 6 +++--- 4 files changed, 23 insertions(+), 16 deletions(-) (limited to 'src/Entities') 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); } diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h index 62a4097f3..4b096b475 100644 --- a/src/Entities/Entity.h +++ b/src/Entities/Entity.h @@ -385,15 +385,17 @@ public: virtual void TeleportToCoords(double a_PosX, double a_PosY, double a_PosZ); /** Moves entity to specified world, taking a world pointer */ - virtual bool MoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn = true); + bool MoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn = true) { return DoMoveToWorld(a_World, a_ShouldSendRespawn); } /** Moves entity to specified world, taking a world name */ bool MoveToWorld(const AString & a_WorldName, bool a_ShouldSendRespawn = true); // tolua_end + virtual bool DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn); + /** 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; } @@ -500,7 +502,7 @@ protected: bool m_IsInitialized; /** World entity is travelling from - Set by MoveToWorld and back to NULL when the entity is removed by the old chunk + Set to a valid world pointer by MoveToWorld; reset to NULL when the entity is removed from the old world Can't be a simple boolean as context switches between worlds may leave the new chunk processing (and therefore immediately removing) the entity before the old chunk could remove it */ cWorld * m_WorldTravellingFrom; diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 087ac448f..406da8baa 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1609,7 +1609,7 @@ void cPlayer::TossItems(const cItems & a_Items) -bool cPlayer::MoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn) +bool cPlayer::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn) { ASSERT(a_World != NULL); diff --git a/src/Entities/Player.h b/src/Entities/Player.h index d1b3a0339..c28802eec 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(cWorld * a_World, bool a_ShouldSendRespawn = true) override; // tolua_export + virtual bool DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn) override; /** Saves all player data, such as inventory, to JSON */ bool SaveToDisk(void); @@ -341,13 +341,13 @@ public: typedef cWorld * cWorldPtr; /** Loads the player data from the disk file - Takes a (NULL) cWorld pointer which it will assign a value to based on either the loaded world or default world by calling LoadFromFile() + Sets a_World to the world where the player will spawn, based on the stored world name or the default world by calling LoadFromFile() Returns true on success, false on failure */ bool LoadFromDisk(cWorldPtr & a_World); /** Loads the player data from the specified file - Takes a (NULL) cWorld pointer which it will assign a value to based on either the loaded world or default world + Sets a_World to the world where the player will spawn, based on the stored world name or the default world Returns true on success, false on failure */ bool LoadFromFile(const AString & a_FileName, cWorldPtr & a_World); -- cgit v1.2.3 From a5cca16abe524fdbd756908ac157a0c9881463f3 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 27 Jul 2014 00:39:39 +0200 Subject: Add "Broadcasting" settings to world.ini --- src/Entities/Player.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'src/Entities') diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index fcc8eb9a0..393afc3b6 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -890,7 +890,7 @@ void cPlayer::KilledBy(TakeDamageInfo & a_TDI) m_World->SpawnItemPickups(Pickups, GetPosX(), GetPosY(), GetPosZ(), 10); SaveToDisk(); // Save it, yeah the world is a tough place ! - if (a_TDI.Attacker == NULL) + if ((a_TDI.Attacker == NULL) && m_World->ShouldBroadcastDeathMessages()) { AString DamageText; switch (a_TDI.DamageType) @@ -1208,11 +1208,13 @@ unsigned int cPlayer::AwardAchievement(const eStatistic a_Ach) } else { - // First time, announce it - cCompositeChat Msg; - Msg.SetMessageType(mtSuccess); - Msg.AddShowAchievementPart(GetName(), cStatInfo::GetName(a_Ach)); - m_World->BroadcastChat(Msg); + if (m_World->ShouldBroadcastAchievementMessages()) + { + cCompositeChat Msg; + Msg.SetMessageType(mtSuccess); + Msg.AddShowAchievementPart(GetName(), cStatInfo::GetName(a_Ach)); + m_World->BroadcastChat(Msg); + } // Increment the statistic StatValue New = m_Stats.AddValue(a_Ach); -- 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') 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 From 4f5d73b7704e351365a987b421c35f1384afa240 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 29 Jul 2014 20:50:30 +0100 Subject: Slight cleanup after portals --- src/Entities/Player.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/Entities') diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index ffdcca2ec..cf3322968 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1627,7 +1627,7 @@ bool cPlayer::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn) // Remove player from the old world SetWorldTravellingFrom(GetWorld()); // cChunk handles entity removal - GetWorld()->RemovePlayer(this); + GetWorld()->RemovePlayer(this, false); // Queue adding player to the new world, including all the necessary adjustments to the object a_World->AddPlayer(this); -- cgit v1.2.3 From 487c57242964ef4a86fc4f41c1c538d9df9ec892 Mon Sep 17 00:00:00 2001 From: archshift Date: Tue, 29 Jul 2014 19:14:56 -0700 Subject: Entity.h: Moved constants out of some unnamed enum --- src/Entities/Entity.h | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'src/Entities') diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h index e66194ca2..b9c280b6b 100644 --- a/src/Entities/Entity.h +++ b/src/Entities/Entity.h @@ -128,20 +128,20 @@ public: esFireworkExploding = 17, } ; - enum - { - FIRE_TICKS_PER_DAMAGE = 10, ///< How many ticks to wait between damaging an entity when it stands in fire - FIRE_DAMAGE = 1, ///< How much damage to deal when standing in fire - LAVA_TICKS_PER_DAMAGE = 10, ///< How many ticks to wait between damaging an entity when it stands in lava - LAVA_DAMAGE = 5, ///< How much damage to deal when standing in lava - BURN_TICKS_PER_DAMAGE = 20, ///< How many ticks to wait between damaging an entity when it is burning - BURN_DAMAGE = 1, ///< How much damage to deal when the entity is burning - BURN_TICKS = 200, ///< How long to keep an entity burning after it has stood in lava / fire - MAX_AIR_LEVEL = 300, ///< Maximum air an entity can have - DROWNING_TICKS = 20, ///< Number of ticks per heart of damage - VOID_BOUNDARY = -46, ///< At what position Y to begin applying void damage - FALL_DAMAGE_HEIGHT = 4 ///< At what position Y fall damage is applied - } ; + static const int FIRE_TICKS_PER_DAMAGE = 10; ///< Ticks to wait between damaging an entity when it stands in fire + static const int FIRE_DAMAGE = 1; ///< Damage to deal when standing in fire + static const int LAVA_TICKS_PER_DAMAGE = 10; ///< Ticks to wait between damaging an entity when it stands in lava + static const int LAVA_DAMAGE = 5; ///< Damage to deal when standing in lava + static const int BURN_TICKS_PER_DAMAGE = 20; ///< Ticks to wait between damaging an entity when it is burning + static const int BURN_DAMAGE = 1; ///< Damage to deal when the entity is burning + + static const int BURN_TICKS = 200; ///< Ticks to keep an entity burning after it has stood in lava / fire + + static const int MAX_AIR_LEVEL = 300; ///< Maximum air an entity can have + static const int DROWNING_TICKS = 20; ///< Number of ticks per heart of damage + + static const int VOID_BOUNDARY = -46; ///< Y position to begin applying void damage + static const int FALL_DAMAGE_HEIGHT = 4; ///< Y difference after which fall damage is applied cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z, double a_Width, double a_Height); virtual ~cEntity(); -- cgit v1.2.3