summaryrefslogtreecommitdiffstats
path: root/src/Entities/Entity.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Entities/Entity.cpp')
-rw-r--r--src/Entities/Entity.cpp76
1 files changed, 69 insertions, 7 deletions
diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp
index 4a909a1fd..bb9d3c44b 100644
--- a/src/Entities/Entity.cpp
+++ b/src/Entities/Entity.cpp
@@ -13,6 +13,7 @@
#include "Player.h"
#include "Items/ItemHandler.h"
#include "../FastRandom.h"
+#include "../NetherPortalScanner.h"
@@ -42,6 +43,7 @@ cEntity::cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z, d
m_WorldTravellingFrom(nullptr),
m_EntityType(a_EntityType),
m_World(nullptr),
+ m_IsWorldChangeScheduled(false),
m_IsFireproof(false),
m_TicksSinceLastBurnDamage(0),
m_TicksSinceLastLavaDamage(0),
@@ -396,7 +398,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI)
}
}
- int ThornsLevel = 0;
+ unsigned int ThornsLevel = 0;
const cItem ArmorItems[] = { GetEquippedHelmet(), GetEquippedChestplate(), GetEquippedLeggings(), GetEquippedBoots() };
for (size_t i = 0; i < ARRAYCOUNT(ArmorItems); i++)
{
@@ -742,6 +744,13 @@ void cEntity::KilledBy(TakeDamageInfo & a_TDI)
return;
}
+ // If the victim is a player the hook is handled by the cPlayer class
+ if (!IsPlayer())
+ {
+ AString emptystring = AString("");
+ cRoot::Get()->GetPluginManager()->CallHookKilled(*this, a_TDI, emptystring);
+ }
+
// Drop loot:
cItems Drops;
GetDrops(Drops, a_TDI.Attacker);
@@ -1260,9 +1269,35 @@ void cEntity::DetectCacti(void)
+void cEntity::ScheduleMoveToWorld(cWorld * a_World, Vector3d a_NewPosition, bool a_SetPortalCooldown)
+{
+ m_NewWorld = a_World;
+ m_NewWorldPosition = a_NewPosition;
+ m_IsWorldChangeScheduled = true;
+ m_WorldChangeSetPortalCooldown = a_SetPortalCooldown;
+}
+
+
+
bool cEntity::DetectPortal()
{
+ // If somebody scheduled a world change with ScheduleMoveToWorld, change worlds now.
+ if (m_IsWorldChangeScheduled)
+ {
+ m_IsWorldChangeScheduled = false;
+
+ if (m_WorldChangeSetPortalCooldown)
+ {
+ // Delay the portal check.
+ m_PortalCooldownData.m_TicksDelayed = 0;
+ m_PortalCooldownData.m_ShouldPreventTeleportation = true;
+ }
+
+ MoveToWorld(m_NewWorld, false, m_NewWorldPosition);
+ return true;
+ }
+
if (GetWorld()->GetDimension() == dimOverworld)
{
if (GetWorld()->GetLinkedNetherWorldName().empty() && GetWorld()->GetLinkedEndWorldName().empty())
@@ -1312,8 +1347,15 @@ bool cEntity::DetectPortal()
// Send a respawn packet before world is loaded / generated so the client isn't left in limbo
((cPlayer *)this)->GetClientHandle()->SendRespawn(dimOverworld);
}
-
- return MoveToWorld(cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetLinkedOverworldName()), false);
+
+ Vector3d TargetPos = GetPosition();
+ TargetPos.x *= 8.0;
+ TargetPos.z *= 8.0;
+
+ cWorld * TargetWorld = cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetLinkedOverworldName(), dimNether, GetWorld()->GetName(), false);
+ LOGD("Jumping nether -> overworld");
+ new cNetherPortalScanner(this, TargetWorld, TargetPos, 256);
+ return true;
}
else
{
@@ -1329,8 +1371,15 @@ bool cEntity::DetectPortal()
((cPlayer *)this)->AwardAchievement(achEnterPortal);
((cPlayer *)this)->GetClientHandle()->SendRespawn(dimNether);
}
-
- return MoveToWorld(cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetLinkedNetherWorldName(), dimNether, GetWorld()->GetName()), false);
+
+ Vector3d TargetPos = GetPosition();
+ TargetPos.x /= 8.0;
+ TargetPos.z /= 8.0;
+
+ cWorld * TargetWorld = cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetLinkedNetherWorldName(), dimNether, GetWorld()->GetName(), false);
+ LOGD("Jumping overworld -> nether");
+ new cNetherPortalScanner(this, TargetWorld, TargetPos, 128);
+ return true;
}
}
case E_BLOCK_END_PORTAL:
@@ -1392,7 +1441,7 @@ bool cEntity::DetectPortal()
-bool cEntity::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn)
+bool cEntity::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn, Vector3d a_NewPosition)
{
UNUSED(a_ShouldSendRespawn);
ASSERT(a_World != nullptr);
@@ -1403,14 +1452,27 @@ bool cEntity::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn)
return false;
}
+ // Ask the plugins if the entity is allowed to changing the world
+ if (cRoot::Get()->GetPluginManager()->CallHookEntityChangingWorld(*this, *a_World))
+ {
+ // A Plugin doesn't allow the entity to changing the world
+ return false;
+ }
+
// Remove all links to the old world
SetWorldTravellingFrom(GetWorld()); // cChunk::Tick() handles entity removal
GetWorld()->BroadcastDestroyEntity(*this);
+ SetPosition(a_NewPosition);
+
// Queue add to new world
a_World->AddEntity(this);
+ cWorld * OldWorld = cRoot::Get()->GetWorld(GetWorld()->GetName()); // Required for the hook HOOK_ENTITY_CHANGED_WORLD
SetWorld(a_World);
+ // Entity changed the world, call the hook
+ cRoot::Get()->GetPluginManager()->CallHookEntityChangedWorld(*this, *OldWorld);
+
return true;
}
@@ -1427,7 +1489,7 @@ bool cEntity::MoveToWorld(const AString & a_WorldName, bool a_ShouldSendRespawn)
return false;
}
- return DoMoveToWorld(World, a_ShouldSendRespawn);
+ return DoMoveToWorld(World, a_ShouldSendRespawn, GetPosition());
}