summaryrefslogtreecommitdiffstats
path: root/src/Entities
diff options
context:
space:
mode:
Diffstat (limited to 'src/Entities')
-rw-r--r--src/Entities/ArrowEntity.cpp13
-rw-r--r--src/Entities/CMakeLists.txt8
-rw-r--r--src/Entities/EnderCrystal.cpp2
-rw-r--r--src/Entities/Entity.cpp76
-rw-r--r--src/Entities/Entity.h49
-rw-r--r--src/Entities/ExpOrb.cpp4
-rw-r--r--src/Entities/FallingBlock.cpp2
-rw-r--r--src/Entities/FireChargeEntity.cpp10
-rw-r--r--src/Entities/FireChargeEntity.h2
-rw-r--r--src/Entities/GhastFireballEntity.cpp8
-rw-r--r--src/Entities/GhastFireballEntity.h2
-rw-r--r--src/Entities/HangingEntity.h20
-rw-r--r--src/Entities/ItemFrame.cpp6
-rw-r--r--src/Entities/Minecart.cpp17
-rw-r--r--src/Entities/Minecart.h2
-rw-r--r--src/Entities/Painting.cpp2
-rw-r--r--src/Entities/Pawn.cpp4
-rw-r--r--src/Entities/Pickup.cpp7
-rw-r--r--src/Entities/Player.cpp195
-rw-r--r--src/Entities/Player.h200
-rw-r--r--src/Entities/ProjectileEntity.cpp7
-rw-r--r--src/Entities/SplashPotionEntity.cpp12
-rw-r--r--src/Entities/ThrownEnderPearlEntity.cpp4
-rw-r--r--src/Entities/ThrownSnowballEntity.cpp2
24 files changed, 400 insertions, 254 deletions
diff --git a/src/Entities/ArrowEntity.cpp b/src/Entities/ArrowEntity.cpp
index 32952100c..492cf2a56 100644
--- a/src/Entities/ArrowEntity.cpp
+++ b/src/Entities/ArrowEntity.cpp
@@ -84,7 +84,7 @@ void cArrowEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFa
int X = BlockHit.x, Y = BlockHit.y, Z = BlockHit.z;
m_HitBlockPos = Vector3i(X, Y, Z);
-
+
// Broadcast arrow hit sound
m_World->BroadcastSoundEffect("random.bowhit", (double)X, (double)Y, (double)Z, 0.5f, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64));
@@ -108,15 +108,15 @@ void cArrowEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos)
Damage += m_World->GetTickRandomNumber(Damage / 2 + 2);
}
- int PowerLevel = m_CreatorData.m_Enchantments.GetLevel(cEnchantments::enchPower);
+ unsigned int PowerLevel = m_CreatorData.m_Enchantments.GetLevel(cEnchantments::enchPower);
if (PowerLevel > 0)
{
int ExtraDamage = (int)ceil(0.25 * (PowerLevel + 1));
Damage += ExtraDamage;
}
- int KnockbackAmount = 1;
- int PunchLevel = m_CreatorData.m_Enchantments.GetLevel(cEnchantments::enchPunch);
+ // int KnockbackAmount = 1;
+ unsigned int PunchLevel = m_CreatorData.m_Enchantments.GetLevel(cEnchantments::enchPunch);
if (PunchLevel > 0)
{
Vector3d LookVector = GetLookVector();
@@ -130,8 +130,9 @@ void cArrowEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos)
a_EntityHit.SetSpeed(FinalSpeed);
}
- a_EntityHit.TakeDamage(dtRangedAttack, this, Damage, KnockbackAmount);
-
+ // a_EntityHit.TakeDamage(dtRangedAttack, this, Damage, KnockbackAmount); // TODO fix knockback.
+ a_EntityHit.TakeDamage(dtRangedAttack, this, Damage, 0); // Until knockback is fixed.
+
if (IsOnFire() && !a_EntityHit.IsSubmerged() && !a_EntityHit.IsSwimming())
{
a_EntityHit.StartBurning(100);
diff --git a/src/Entities/CMakeLists.txt b/src/Entities/CMakeLists.txt
index 5d10e1680..7261e85c0 100644
--- a/src/Entities/CMakeLists.txt
+++ b/src/Entities/CMakeLists.txt
@@ -60,6 +60,14 @@ SET (HDRS
ThrownSnowballEntity.h
WitherSkullEntity.h)
+if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
+ set_source_files_properties(ArrowEntity.cpp PROPERTIES COMPILE_FLAGS "-Wno-error=old-style-cast")
+ set_source_files_properties(Entity.cpp PROPERTIES COMPILE_FLAGS "-Wno-error=sign-conversion -Wno-error=global-constructors -Wno-error=switch-enum -Wno-error=old-style-cast")
+ set_source_files_properties(EntityEffect.cpp PROPERTIES COMPILE_FLAGS "-Wno-error=switch-enum -Wno-error=old-style-cast")
+ set_source_files_properties(Floater.cpp PROPERTIES COMPILE_FLAGS "-Wno-error=sign-conversion -Wno-error=old-style-cast")
+ set_source_files_properties(Player.cpp PROPERTIES COMPILE_FLAGS "-Wno-error=sign-conversion -Wno-error=switch-enum -Wno-error=conversion -Wno-error=old-style-cast")
+endif()
+
if(NOT MSVC)
add_library(Entities ${SRCS} ${HDRS})
diff --git a/src/Entities/EnderCrystal.cpp b/src/Entities/EnderCrystal.cpp
index 7a911d4db..b71d70bdd 100644
--- a/src/Entities/EnderCrystal.cpp
+++ b/src/Entities/EnderCrystal.cpp
@@ -22,7 +22,7 @@ cEnderCrystal::cEnderCrystal(double a_X, double a_Y, double a_Z)
void cEnderCrystal::SpawnOn(cClientHandle & a_ClientHandle)
{
- a_ClientHandle.SendSpawnObject(*this, 51, 0, (Byte)GetYaw(), (Byte)GetPitch());
+ a_ClientHandle.SendSpawnObject(*this, 51, 0, static_cast<Byte>(GetYaw()), static_cast<Byte>(GetPitch()));
}
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());
}
diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h
index fecbb9bf5..f54e130eb 100644
--- a/src/Entities/Entity.h
+++ b/src/Entities/Entity.h
@@ -205,8 +205,8 @@ public:
double GetSpeedZ (void) const { return m_Speed.z; }
double GetWidth (void) const { return m_Width; }
- int GetChunkX(void) const {return (int)floor(m_Pos.x / cChunkDef::Width); }
- int GetChunkZ(void) const {return (int)floor(m_Pos.z / cChunkDef::Width); }
+ int GetChunkX(void) const {return static_cast<int>(floor(m_Pos.x / cChunkDef::Width)); }
+ int GetChunkZ(void) const {return static_cast<int>(floor(m_Pos.z / cChunkDef::Width)); }
void SetHeadYaw (double a_HeadYaw);
void SetHeight (double a_Height);
@@ -350,31 +350,31 @@ public:
*/
virtual bool DetectPortal(void);
- /// Handles when the entity is in the void
+ /** Handles when the entity is in the void */
virtual void TickInVoid(cChunk & a_Chunk);
- /// Called when the entity starts burning
+ /** Called when the entity starts burning */
virtual void OnStartedBurning(void);
- /// Called when the entity finishes burning
+ /** Called when the entity finishes burning */
virtual void OnFinishedBurning(void);
// tolua_begin
- /// Sets the maximum value for the health
+ /** Sets the maximum value for the health */
void SetMaxHealth(int a_MaxHealth);
int GetMaxHealth(void) const { return m_MaxHealth; }
- /// Sets whether the entity is fireproof
+ /** Sets whether the entity is fireproof */
void SetIsFireproof(bool a_IsFireproof);
bool IsFireproof(void) const { return m_IsFireproof; }
- /// Puts the entity on fire for the specified amount of ticks
+ /** Puts the entity on fire for the specified amount of ticks */
void StartBurning(int a_TicksLeftBurning);
- /// Stops the entity from burning, resets all burning timers
+ /** Stops the entity from burning, resets all burning timers */
void StopBurning(void);
// tolua_end
@@ -386,21 +386,26 @@ public:
// tolua_begin
- /// Teleports to the entity specified
+ /** Teleports to the entity specified */
virtual void TeleportToEntity(cEntity & a_Entity);
- /// Teleports to the coordinates specified
+ /** Teleports to the coordinates specified */
virtual void TeleportToCoords(double a_PosX, double a_PosY, double a_PosZ);
+ /** Schedules a MoveToWorld call to occur on the next Tick of the entity */
+ void ScheduleMoveToWorld(cWorld * a_World, Vector3d a_NewPosition, bool a_SetPortalCooldown = false);
+
+ bool MoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn, Vector3d a_NewPosition) { return DoMoveToWorld(a_World, a_ShouldSendRespawn, a_NewPosition); }
+
/** Moves entity to specified world, taking a world pointer */
- bool MoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn = true) { return DoMoveToWorld(a_World, a_ShouldSendRespawn); }
+ bool MoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn = true) { return MoveToWorld(a_World, a_ShouldSendRespawn, GetPosition()); }
/** 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);
+ virtual bool DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn, Vector3d a_NewPosition);
/** Returns if the entity is travelling away from a specified world */
bool IsWorldTravellingFrom(cWorld * a_World) const { return (m_WorldTravellingFrom == a_World); }
@@ -530,23 +535,29 @@ protected:
eEntityType m_EntityType;
cWorld * m_World;
+
+ /** State variables for ScheduleMoveToWorld. */
+ bool m_IsWorldChangeScheduled;
+ bool m_WorldChangeSetPortalCooldown;
+ cWorld * m_NewWorld;
+ Vector3d m_NewWorldPosition;
- /// Whether the entity is capable of taking fire or lava damage.
+ /** Whether the entity is capable of taking fire or lava damage. */
bool m_IsFireproof;
- /// Time, in ticks, since the last damage dealt by being on fire. Valid only if on fire (IsOnFire())
+ /** Time, in ticks, since the last damage dealt by being on fire. Valid only if on fire (IsOnFire()) */
int m_TicksSinceLastBurnDamage;
- /// Time, in ticks, since the last damage dealt by standing in lava. Reset to zero when moving out of lava.
+ /** Time, in ticks, since the last damage dealt by standing in lava. Reset to zero when moving out of lava. */
int m_TicksSinceLastLavaDamage;
- /// Time, in ticks, since the last damage dealt by standing in fire. Reset to zero when moving out of fire.
+ /** Time, in ticks, since the last damage dealt by standing in fire. Reset to zero when moving out of fire. */
int m_TicksSinceLastFireDamage;
- /// Time, in ticks, until the entity extinguishes its fire
+ /** Time, in ticks, until the entity extinguishes its fire */
int m_TicksLeftBurning;
- /// Time, in ticks, since the last damage dealt by the void. Reset to zero when moving out of the void.
+ /** Time, in ticks, since the last damage dealt by the void. Reset to zero when moving out of the void. */
int m_TicksSinceLastVoidDamage;
/** Does the actual speed-setting. The default implementation just sets the member variable value;
diff --git a/src/Entities/ExpOrb.cpp b/src/Entities/ExpOrb.cpp
index db7f6f2c8..676370508 100644
--- a/src/Entities/ExpOrb.cpp
+++ b/src/Entities/ExpOrb.cpp
@@ -56,12 +56,12 @@ void cExpOrb::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
LOGD("Player %s picked up an ExpOrb. His reward is %i", a_ClosestPlayer->GetName().c_str(), m_Reward);
a_ClosestPlayer->DeltaExperience(m_Reward);
- m_World->BroadcastSoundEffect("random.orb", GetPosX(), GetPosY(), GetPosZ(), 0.5f, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64));
+ m_World->BroadcastSoundEffect("random.orb", GetPosX(), GetPosY(), GetPosZ(), 0.5f, (0.75f + (static_cast<float>((GetUniqueID() * 23) % 32)) / 64));
Destroy();
}
a_Distance.Normalize();
- a_Distance *= ((float) (5.5 - Distance));
+ a_Distance *= (static_cast<float>(5.5 - Distance));
SetSpeedX( a_Distance.x);
SetSpeedY( a_Distance.y);
SetSpeedZ( a_Distance.z);
diff --git a/src/Entities/FallingBlock.cpp b/src/Entities/FallingBlock.cpp
index 4a165909a..bae13ea66 100644
--- a/src/Entities/FallingBlock.cpp
+++ b/src/Entities/FallingBlock.cpp
@@ -38,7 +38,7 @@ void cFallingBlock::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
// GetWorld()->BroadcastTeleportEntity(*this); // Test position
int BlockX = POSX_TOINT;
- int BlockY = (int)(GetPosY() - 0.5);
+ int BlockY = static_cast<int>(GetPosY() - 0.5);
int BlockZ = POSZ_TOINT;
if (BlockY < 0)
diff --git a/src/Entities/FireChargeEntity.cpp b/src/Entities/FireChargeEntity.cpp
index f6c665156..10d83b8dd 100644
--- a/src/Entities/FireChargeEntity.cpp
+++ b/src/Entities/FireChargeEntity.cpp
@@ -19,11 +19,11 @@ cFireChargeEntity::cFireChargeEntity(cEntity * a_Creator, double a_X, double a_Y
-void cFireChargeEntity::Explode(int a_BlockX, int a_BlockY, int a_BlockZ)
+void cFireChargeEntity::Explode(Vector3i a_Block)
{
- if (m_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_AIR)
+ if (m_World->GetBlock(a_Block) == E_BLOCK_AIR)
{
- m_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_FIRE, 1);
+ m_World->SetBlock(a_Block.x, a_Block.y, a_Block.z, E_BLOCK_FIRE, 1);
}
}
@@ -34,7 +34,7 @@ void cFireChargeEntity::Explode(int a_BlockX, int a_BlockY, int a_BlockZ)
void cFireChargeEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace)
{
Destroy();
- Explode((int)floor(a_HitPos.x), (int)floor(a_HitPos.y), (int)floor(a_HitPos.z));
+ Explode(a_HitPos.Floor());
}
@@ -44,7 +44,7 @@ void cFireChargeEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_
void cFireChargeEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos)
{
Destroy();
- Explode((int)floor(a_HitPos.x), (int)floor(a_HitPos.y), (int)floor(a_HitPos.z));
+ Explode(a_HitPos.Floor());
// TODO: Some entities are immune to hits
a_EntityHit.StartBurning(5 * 20); // 5 seconds of burning
diff --git a/src/Entities/FireChargeEntity.h b/src/Entities/FireChargeEntity.h
index eb08f5324..25f04cb7c 100644
--- a/src/Entities/FireChargeEntity.h
+++ b/src/Entities/FireChargeEntity.h
@@ -32,7 +32,7 @@ public:
protected:
- void Explode(int a_BlockX, int a_BlockY, int a_BlockZ);
+ void Explode(Vector3i a_Block);
// cProjectileEntity overrides:
virtual void OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) override;
diff --git a/src/Entities/GhastFireballEntity.cpp b/src/Entities/GhastFireballEntity.cpp
index c64fb2a17..1adfd1bc0 100644
--- a/src/Entities/GhastFireballEntity.cpp
+++ b/src/Entities/GhastFireballEntity.cpp
@@ -19,9 +19,9 @@ cGhastFireballEntity::cGhastFireballEntity(cEntity * a_Creator, double a_X, doub
-void cGhastFireballEntity::Explode(int a_BlockX, int a_BlockY, int a_BlockZ)
+void cGhastFireballEntity::Explode(Vector3i a_Block)
{
- m_World->DoExplosionAt(1, a_BlockX, a_BlockY, a_BlockZ, true, esGhastFireball, this);
+ m_World->DoExplosionAt(1, a_Block.x, a_Block.y, a_Block.z, true, esGhastFireball, this);
}
@@ -31,7 +31,7 @@ void cGhastFireballEntity::Explode(int a_BlockX, int a_BlockY, int a_BlockZ)
void cGhastFireballEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace)
{
Destroy();
- Explode((int)floor(a_HitPos.x), (int)floor(a_HitPos.y), (int)floor(a_HitPos.z));
+ Explode(a_HitPos.Floor());
}
@@ -41,5 +41,5 @@ void cGhastFireballEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace
void cGhastFireballEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos)
{
Destroy();
- Explode((int)floor(a_HitPos.x), (int)floor(a_HitPos.y), (int)floor(a_HitPos.z));
+ Explode(a_HitPos.Floor());
}
diff --git a/src/Entities/GhastFireballEntity.h b/src/Entities/GhastFireballEntity.h
index bbce89d31..dc136dfc2 100644
--- a/src/Entities/GhastFireballEntity.h
+++ b/src/Entities/GhastFireballEntity.h
@@ -32,7 +32,7 @@ public:
protected:
- void Explode(int a_BlockX, int a_BlockY, int a_BlockZ);
+ void Explode(Vector3i a_Block);
// cProjectileEntity overrides:
virtual void OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) override;
diff --git a/src/Entities/HangingEntity.h b/src/Entities/HangingEntity.h
index 9d783006c..003c22082 100644
--- a/src/Entities/HangingEntity.h
+++ b/src/Entities/HangingEntity.h
@@ -46,6 +46,9 @@ public:
protected:
+ Byte m_Facing;
+
+
virtual void SpawnOn(cClientHandle & a_ClientHandle) override;
virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override
{
@@ -53,6 +56,7 @@ protected:
UNUSED(a_Chunk);
}
+
/** Converts protocol hanging item facing to eBlockFace values */
inline static eBlockFace ProtocolFaceToBlockFace(Byte a_ProtocolFace)
{
@@ -77,6 +81,7 @@ protected:
return Dir;
}
+
/** Converts eBlockFace values to protocol hanging item faces */
inline static Byte BlockFaceToProtocolFace(eBlockFace a_BlockFace)
{
@@ -89,21 +94,28 @@ protected:
case BLOCK_FACE_ZM: Dir = 2; break;
case BLOCK_FACE_XM: Dir = 1; break;
case BLOCK_FACE_XP: Dir = 3; break;
- default:
+ case BLOCK_FACE_YP:
+ case BLOCK_FACE_YM:
+ case BLOCK_FACE_NONE:
{
// Uncomment when entities are initialised with their real data, instead of dummy values:
// LOGINFO("Invalid facing (%d) in a cHangingEntity, adjusting to BLOCK_FACE_XP.", a_BlockFace);
// ASSERT(!"Tried to convert a bad facing!");
Dir = cHangingEntity::BlockFaceToProtocolFace(BLOCK_FACE_XP);
+ break;
}
+ #if !defined(__clang__)
+ default:
+ {
+ ASSERT(!"Unknown BLOCK_FACE");
+ return 0;
+ }
+ #endif
}
return Dir;
}
-
- Byte m_Facing;
-
}; // tolua_export
diff --git a/src/Entities/ItemFrame.cpp b/src/Entities/ItemFrame.cpp
index 4e6e38f1f..6317eba85 100644
--- a/src/Entities/ItemFrame.cpp
+++ b/src/Entities/ItemFrame.cpp
@@ -62,7 +62,7 @@ void cItemFrame::KilledBy(TakeDamageInfo & a_TDI)
return;
}
- if ((a_TDI.Attacker != nullptr) && a_TDI.Attacker->IsPlayer() && !((cPlayer *)a_TDI.Attacker)->IsGameModeCreative())
+ if ((a_TDI.Attacker != nullptr) && a_TDI.Attacker->IsPlayer() && !static_cast<cPlayer *>(a_TDI.Attacker)->IsGameModeCreative())
{
cItems Item;
Item.push_back(m_Item);
@@ -83,7 +83,7 @@ void cItemFrame::KilledBy(TakeDamageInfo & a_TDI)
void cItemFrame::GetDrops(cItems & a_Items, cEntity * a_Killer)
{
- if ((a_Killer != nullptr) && a_Killer->IsPlayer() && !((cPlayer *)a_Killer)->IsGameModeCreative())
+ if ((a_Killer != nullptr) && a_Killer->IsPlayer() && !static_cast<cPlayer *>(a_Killer)->IsGameModeCreative())
{
a_Items.push_back(cItem(E_ITEM_ITEM_FRAME));
}
@@ -96,7 +96,7 @@ void cItemFrame::GetDrops(cItems & a_Items, cEntity * a_Killer)
void cItemFrame::SpawnOn(cClientHandle & a_ClientHandle)
{
super::SpawnOn(a_ClientHandle);
- a_ClientHandle.SendSpawnObject(*this, 71, GetProtocolFacing(), (Byte)GetYaw(), (Byte)GetPitch());
+ a_ClientHandle.SendSpawnObject(*this, 71, GetProtocolFacing(), static_cast<Byte>(GetYaw()), static_cast<Byte>(GetPitch()));
a_ClientHandle.SendEntityMetadata(*this);
}
diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp
index b80759d24..7274a7a41 100644
--- a/src/Entities/Minecart.cpp
+++ b/src/Entities/Minecart.cpp
@@ -106,7 +106,7 @@ cMinecart::cMinecart(ePayload a_Payload, double a_X, double a_Y, double a_Z) :
void cMinecart::SpawnOn(cClientHandle & a_ClientHandle)
{
- a_ClientHandle.SendSpawnVehicle(*this, 10, (char)m_Payload); // 10 = Minecarts
+ a_ClientHandle.SendSpawnVehicle(*this, 10, static_cast<char>(m_Payload)); // 10 = Minecarts
a_ClientHandle.SendEntityMetadata(*this);
}
@@ -725,11 +725,11 @@ bool cMinecart::TestBlockCollision(NIBBLETYPE a_RailMeta)
{
if (GetSpeedZ() > 0)
{
- BLOCKTYPE Block = m_World->GetBlock(POSX_TOINT, POSY_TOINT, (int)ceil(GetPosZ()));
+ BLOCKTYPE Block = m_World->GetBlock(POSX_TOINT, POSY_TOINT, static_cast<int>(ceil(GetPosZ())));
if (!IsBlockRail(Block) && cBlockInfo::IsSolid(Block))
{
// We could try to detect a block in front based purely on coordinates, but xoft made a bounding box system - why not use? :P
- cBoundingBox bbBlock(Vector3d(POSX_TOINT, POSY_TOINT, (int)ceil(GetPosZ())), 0.5, 1);
+ cBoundingBox bbBlock(Vector3d(POSX_TOINT, POSY_TOINT, static_cast<int>(ceil(GetPosZ()))), 0.5, 1);
cBoundingBox bbMinecart(Vector3d(GetPosX(), floor(GetPosY()), GetPosZ()), GetWidth() / 2, GetHeight());
if (bbBlock.DoesIntersect(bbMinecart))
@@ -762,10 +762,10 @@ bool cMinecart::TestBlockCollision(NIBBLETYPE a_RailMeta)
{
if (GetSpeedX() > 0)
{
- BLOCKTYPE Block = m_World->GetBlock((int)ceil(GetPosX()), POSY_TOINT, POSZ_TOINT);
+ BLOCKTYPE Block = m_World->GetBlock(static_cast<int>(ceil(GetPosX())), POSY_TOINT, POSZ_TOINT);
if (!IsBlockRail(Block) && cBlockInfo::IsSolid(Block))
{
- cBoundingBox bbBlock(Vector3d((int)ceil(GetPosX()), POSY_TOINT, POSZ_TOINT), 0.5, 1);
+ cBoundingBox bbBlock(Vector3d(static_cast<int>(ceil(GetPosX())), POSY_TOINT, POSZ_TOINT), 0.5, 1);
cBoundingBox bbMinecart(Vector3d(GetPosX(), floor(GetPosY()), GetPosZ()), GetWidth() / 2, GetHeight());
if (bbBlock.DoesIntersect(bbMinecart))
@@ -1003,7 +1003,7 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta)
bool cMinecart::DoTakeDamage(TakeDamageInfo & TDI)
{
- if ((TDI.Attacker != nullptr) && TDI.Attacker->IsPlayer() && ((cPlayer *)TDI.Attacker)->IsGameModeCreative())
+ if ((TDI.Attacker != nullptr) && TDI.Attacker->IsPlayer() && static_cast<cPlayer *>(TDI.Attacker)->IsGameModeCreative())
{
Destroy();
TDI.FinalDamage = GetMaxHealth(); // Instant hit for creative
@@ -1051,11 +1051,6 @@ bool cMinecart::DoTakeDamage(TakeDamageInfo & TDI)
Drops.push_back(cItem(E_ITEM_MINECART_WITH_HOPPER, 1, 0));
break;
}
- default:
- {
- ASSERT(!"Unhandled minecart type when spawning pickup!");
- return true;
- }
}
m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY(), GetPosZ());
diff --git a/src/Entities/Minecart.h b/src/Entities/Minecart.h
index d1736e9b9..05eaf16e9 100644
--- a/src/Entities/Minecart.h
+++ b/src/Entities/Minecart.h
@@ -135,7 +135,7 @@ protected:
virtual void Destroyed() override;
// cItemGrid::cListener overrides:
- virtual void OnSlotChanged(cItemGrid * a_Grid, int a_SlotNum)
+ virtual void OnSlotChanged(cItemGrid * a_Grid, int a_SlotNum) override
{
UNUSED(a_SlotNum);
ASSERT(a_Grid == &m_Contents);
diff --git a/src/Entities/Painting.cpp b/src/Entities/Painting.cpp
index 02a8f6ed0..d73c2a245 100644
--- a/src/Entities/Painting.cpp
+++ b/src/Entities/Painting.cpp
@@ -33,7 +33,7 @@ void cPainting::SpawnOn(cClientHandle & a_Client)
void cPainting::GetDrops(cItems & a_Items, cEntity * a_Killer)
{
- if ((a_Killer != nullptr) && a_Killer->IsPlayer() && !((cPlayer *)a_Killer)->IsGameModeCreative())
+ if ((a_Killer != nullptr) && a_Killer->IsPlayer() && !static_cast<cPlayer *>(a_Killer)->IsGameModeCreative())
{
a_Items.push_back(cItem(E_ITEM_PAINTING));
}
diff --git a/src/Entities/Pawn.cpp b/src/Entities/Pawn.cpp
index fcb686e28..2cd0f2f0e 100644
--- a/src/Entities/Pawn.cpp
+++ b/src/Entities/Pawn.cpp
@@ -75,10 +75,10 @@ void cPawn::AddEntityEffect(cEntityEffect::eType a_EffectType, int a_Duration, s
{
return;
}
- a_Duration = (int)(a_Duration * a_DistanceModifier);
+ a_Duration = static_cast<int>(a_Duration * a_DistanceModifier);
m_EntityEffects[a_EffectType] = cEntityEffect::CreateEntityEffect(a_EffectType, a_Duration, a_Intensity, a_DistanceModifier);
- m_World->BroadcastEntityEffect(*this, a_EffectType, a_Intensity, a_Duration);
+ m_World->BroadcastEntityEffect(*this, a_EffectType, a_Intensity, static_cast<short>(a_Duration));
m_EntityEffects[a_EffectType]->OnActivate(*this);
}
diff --git a/src/Entities/Pickup.cpp b/src/Entities/Pickup.cpp
index f2f76dbf9..e4576a8f2 100644
--- a/src/Entities/Pickup.cpp
+++ b/src/Entities/Pickup.cpp
@@ -38,7 +38,7 @@ public:
Vector3d EntityPos = a_Entity->GetPosition();
double Distance = (EntityPos - m_Position).Length();
- cItem & Item = ((cPickup *)a_Entity)->GetItem();
+ cItem & Item = static_cast<cPickup *>(a_Entity)->GetItem();
if ((Distance < 1.2) && Item.IsEqual(m_Pickup->GetItem()))
{
short CombineCount = Item.m_ItemCount;
@@ -52,7 +52,7 @@ public:
return false;
}
- m_Pickup->GetItem().AddCount((char)CombineCount);
+ m_Pickup->GetItem().AddCount(static_cast<char>(CombineCount));
Item.m_ItemCount -= CombineCount;
if (Item.m_ItemCount <= 0)
@@ -228,8 +228,9 @@ bool cPickup::CollectedBy(cPlayer & a_Dest)
m_Item.m_ItemCount -= NumAdded;
m_World->BroadcastCollectEntity(*this, a_Dest);
+
// Also send the "pop" sound effect with a somewhat random pitch (fast-random using EntityID ;)
- m_World->BroadcastSoundEffect("random.pop", GetPosX(), GetPosY(), GetPosZ(), 0.5, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64));
+ m_World->BroadcastSoundEffect("random.pop", GetPosX(), GetPosY(), GetPosZ(), 0.5, (0.75f + (static_cast<float>((GetUniqueID() * 23) % 32)) / 64));
if (m_Item.m_ItemCount <= 0)
{
// All of the pickup has been collected, schedule the pickup for destroying
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index 607a663de..3e1e2b7ea 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -16,6 +16,7 @@
#include "../Items/ItemHandler.h"
#include "../Vector3.h"
#include "../FastRandom.h"
+#include <cmath>
#include "../WorldStorage/StatSerializer.h"
#include "../CompositeChat.h"
@@ -94,7 +95,7 @@ cPlayer::cPlayer(cClientHandlePtr a_Client, const AString & a_PlayerName) :
SetMaxHealth(MAX_HEALTH);
m_Health = MAX_HEALTH;
-
+
m_LastPlayerListTime = std::chrono::steady_clock::now();
m_PlayerName = a_PlayerName;
@@ -106,7 +107,7 @@ cPlayer::cPlayer(cClientHandlePtr a_Client, const AString & a_PlayerName) :
SetPosY(World->GetSpawnY());
SetPosZ(World->GetSpawnZ());
SetBedPos(Vector3i(static_cast<int>(World->GetSpawnX()), static_cast<int>(World->GetSpawnY()), static_cast<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()
);
@@ -128,7 +129,14 @@ cPlayer::cPlayer(cClientHandlePtr a_Client, const AString & a_PlayerName) :
m_IsFlying = true;
}
}
-
+
+ if (m_GameMode == gmSpectator) // If player is reconnecting to the server in spectator mode
+ {
+ m_CanFly = true;
+ m_IsFlying = true;
+ m_bVisible = false;
+ }
+
cRoot::Get()->GetServer()->PlayerCreated(this);
}
@@ -145,17 +153,17 @@ cPlayer::~cPlayer(void)
}
LOGD("Deleting cPlayer \"%s\" at %p, ID %d", GetName().c_str(), this, GetUniqueID());
-
+
// Notify the server that the player is being destroyed
cRoot::Get()->GetServer()->PlayerDestroying(this);
SaveToDisk();
m_ClientHandle = nullptr;
-
+
delete m_InventoryWindow;
m_InventoryWindow = nullptr;
-
+
LOGD("Player %p deleted", this);
}
@@ -201,7 +209,7 @@ void cPlayer::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
m_ClientHandle = nullptr;
return;
}
-
+
if (!m_ClientHandle->IsPlaying())
{
// We're not yet in the game, ignore everything
@@ -210,21 +218,21 @@ void cPlayer::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
}
m_Stats.AddValue(statMinutesPlayed, 1);
-
+
if (!a_Chunk.IsValid())
{
// This may happen if the cPlayer is created before the chunks have the chance of being loaded / generated (#83)
return;
}
-
+
super::Tick(a_Dt, a_Chunk);
-
+
// Handle charging the bow:
if (m_IsChargingBow)
{
m_BowCharge += 1;
}
-
+
// Handle updating experience
if (m_bDirtyExperience)
{
@@ -236,7 +244,7 @@ void cPlayer::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
// Apply food exhaustion from movement:
ApplyFoodExhaustionFromMovement();
-
+
if (cRoot::Get()->GetPluginManager()->CallHookPlayerMoving(*this, m_LastPos, GetPosition()))
{
CanMove = false;
@@ -257,10 +265,10 @@ void cPlayer::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
FinishEating();
}
-
+
HandleFood();
}
-
+
if (m_IsFishing)
{
HandleFloater();
@@ -460,7 +468,7 @@ void cPlayer::SetTouchGround(bool a_bTouchGround)
{
return;
}
-
+
m_bTouchGround = a_bTouchGround;
if (!m_bTouchGround)
@@ -509,7 +517,7 @@ void cPlayer::SetTouchGround(bool a_bTouchGround)
{
// cPlayer makes sure damage isn't applied in creative, no need to check here
TakeDamage(dtFalling, nullptr, Damage, Damage, 0);
-
+
// Fall particles
GetWorld()->BroadcastSoundParticleEffect(2006, POSX_TOINT, static_cast<int>(GetPosY()) - 1, POSZ_TOINT, Damage /* Used as particle effect speed modifier */);
}
@@ -541,7 +549,7 @@ void cPlayer::SetFoodLevel(int a_FoodLevel)
m_FoodSaturationLevel = 5.0;
return;
}
-
+
m_FoodLevel = FoodLevel;
SendHealth();
}
@@ -609,7 +617,7 @@ void cPlayer::StartEating(void)
{
// Set the timer:
m_EatingFinishTick = m_World->GetWorldAge() + EATING_TICKS;
-
+
// Send the packets:
m_World->BroadcastEntityAnimation(*this, 3);
m_World->BroadcastEntityMetadata(*this);
@@ -623,7 +631,7 @@ void cPlayer::FinishEating(void)
{
// Reset the timer:
m_EatingFinishTick = -1;
-
+
// Send the packets:
m_ClientHandle->SendEntityStatus(*this, esPlayerEatingAccepted);
m_World->BroadcastEntityMetadata(*this);
@@ -757,7 +765,7 @@ void cPlayer::SetSprintingMaxSpeed(double a_Speed)
void cPlayer::SetFlyingMaxSpeed(double a_Speed)
{
m_FlyingMaxSpeed = a_Speed;
-
+
// Update the flying speed, always:
m_ClientHandle->SendPlayerAbilities();
}
@@ -769,7 +777,7 @@ void cPlayer::SetFlyingMaxSpeed(double a_Speed)
void cPlayer::SetCrouch(bool a_IsCrouched)
{
// Set the crouch status, broadcast to all visible players
-
+
if (a_IsCrouched == m_IsCrouched)
{
// No change
@@ -790,7 +798,7 @@ void cPlayer::SetSprint(bool a_IsSprinting)
// No change
return;
}
-
+
m_IsSprinting = a_IsSprinting;
m_ClientHandle->SendPlayerMaxSpeed();
}
@@ -876,7 +884,7 @@ bool cPlayer::DoTakeDamage(TakeDamageInfo & a_TDI)
}
}
}
-
+
if (super::DoTakeDamage(a_TDI))
{
// Any kind of damage adds food exhaustion
@@ -913,11 +921,11 @@ void cPlayer::KilledBy(TakeDamageInfo & a_TDI)
{
Pickups.Add(cItem(E_ITEM_RED_APPLE));
}
-
m_Stats.AddValue(statItemsDropped, (StatValue)Pickups.Size());
m_World->SpawnItemPickups(Pickups, GetPosX(), GetPosY(), GetPosZ(), 10);
SaveToDisk(); // Save it, yeah the world is a tough place !
+ cPluginManager * PluginManager = cRoot::Get()->GetPluginManager();
if ((a_TDI.Attacker == nullptr) && m_World->ShouldBroadcastDeathMessages())
{
@@ -943,7 +951,12 @@ void cPlayer::KilledBy(TakeDamageInfo & a_TDI)
case dtExplosion: DamageText = "blew up"; break;
default: DamageText = "died, somehow; we've no idea how though"; break;
}
- GetWorld()->BroadcastChatDeath(Printf("%s %s", GetName().c_str(), DamageText.c_str()));
+ AString DeathMessage = Printf("%s %s", GetName().c_str(), DamageText.c_str());
+ PluginManager->CallHookKilled(*this, a_TDI, DeathMessage);
+ if (DeathMessage != AString(""))
+ {
+ GetWorld()->BroadcastChatDeath(DeathMessage);
+ }
}
else if (a_TDI.Attacker == nullptr) // && !m_World->ShouldBroadcastDeathMessages() by fallthrough
{
@@ -952,15 +965,23 @@ void cPlayer::KilledBy(TakeDamageInfo & a_TDI)
else if (a_TDI.Attacker->IsPlayer())
{
cPlayer * Killer = (cPlayer *)a_TDI.Attacker;
-
- GetWorld()->BroadcastChatDeath(Printf("%s was killed by %s", GetName().c_str(), Killer->GetName().c_str()));
+ AString DeathMessage = Printf("%s was killed by %s", GetName().c_str(), Killer->GetName().c_str());
+ PluginManager->CallHookKilled(*this, a_TDI, DeathMessage);
+ if (DeathMessage != AString(""))
+ {
+ GetWorld()->BroadcastChatDeath(DeathMessage);
+ }
}
else
{
AString KillerClass = a_TDI.Attacker->GetClass();
KillerClass.erase(KillerClass.begin()); // Erase the 'c' of the class (e.g. "cWitch" -> "Witch")
-
- GetWorld()->BroadcastChatDeath(Printf("%s was killed by a %s", GetName().c_str(), KillerClass.c_str()));
+ AString DeathMessage = Printf("%s was killed by a %s", GetName().c_str(), KillerClass.c_str());
+ PluginManager->CallHookKilled(*this, a_TDI, DeathMessage);
+ if (DeathMessage != AString(""))
+ {
+ GetWorld()->BroadcastChatDeath(DeathMessage);
+ }
}
m_Stats.AddValue(statDeaths);
@@ -1005,7 +1026,7 @@ void cPlayer::Respawn(void)
m_Health = GetMaxHealth();
SetInvulnerableTicks(20);
-
+
// Reset food level:
m_FoodLevel = MAX_FOOD_LEVEL;
m_FoodSaturationLevel = 5.0;
@@ -1017,7 +1038,7 @@ void cPlayer::Respawn(void)
// ToDo: send score to client? How?
m_ClientHandle->SendRespawn(GetWorld()->GetDimension(), true);
-
+
// Extinguish the fire:
StopBurning();
@@ -1151,7 +1172,7 @@ void cPlayer::CloseWindow(bool a_CanRefuse)
m_CurrentWindow = m_InventoryWindow;
return;
}
-
+
if (m_CurrentWindow->ClosedByPlayer(*this, a_CanRefuse) || !a_CanRefuse)
{
// Close accepted, go back to inventory window (the default):
@@ -1189,21 +1210,17 @@ void cPlayer::SetGameMode(eGameMode a_GameMode)
LOGWARNING("%s: Setting invalid gamemode: %d", GetName().c_str(), a_GameMode);
return;
}
-
+
if (m_GameMode == a_GameMode)
{
// Gamemode already set
return;
}
-
+
m_GameMode = a_GameMode;
m_ClientHandle->SendGameMode(a_GameMode);
- if (!(IsGameModeCreative() || IsGameModeSpectator()))
- {
- SetFlying(false);
- SetCanFly(false);
- }
+ SetCapabilities();
m_World->BroadcastPlayerListUpdateGameMode(*this);
}
@@ -1215,6 +1232,30 @@ void cPlayer::SetGameMode(eGameMode a_GameMode)
void cPlayer::LoginSetGameMode( eGameMode a_GameMode)
{
m_GameMode = a_GameMode;
+
+ SetCapabilities();
+}
+
+
+
+
+
+void cPlayer::SetCapabilities()
+{
+ if (!IsGameModeCreative() || IsGameModeSpectator())
+ {
+ SetFlying(false);
+ SetCanFly(false);
+ }
+
+ if (IsGameModeSpectator())
+ {
+ SetVisible(false);
+ }
+ else
+ {
+ SetVisible(true);
+ }
}
@@ -1306,12 +1347,12 @@ void cPlayer::SendRotation(double a_YawDegrees, double a_PitchDegrees)
Vector3d cPlayer::GetThrowStartPos(void) const
{
Vector3d res = GetEyePosition();
-
+
// Adjust the position to be just outside the player's bounding box:
res.x += 0.16 * cos(GetPitch());
res.y += -0.1;
res.z += 0.16 * sin(GetPitch());
-
+
return res;
}
@@ -1323,9 +1364,9 @@ Vector3d cPlayer::GetThrowSpeed(double a_SpeedCoeff) const
{
Vector3d res = GetLookVector();
res.Normalize();
-
+
// TODO: Add a slight random change (+-0.0075 in each direction)
-
+
return res * a_SpeedCoeff;
}
@@ -1370,13 +1411,13 @@ void cPlayer::MoveTo( const Vector3d & a_NewPos)
}
return;
}
-
+
// TODO: should do some checks to see if player is not moving through terrain
// TODO: Official server refuses position packets too far away from each other, kicking "hacked" clients; we should, too
Vector3d DeltaPos = a_NewPos - GetPosition();
UpdateMovementStats(DeltaPos);
-
+
SetPosition( a_NewPos);
SetStance(a_NewPos.y + 1.62);
}
@@ -1411,7 +1452,7 @@ bool cPlayer::HasPermission(const AString & a_Permission)
// Empty permission request is always granted
return true;
}
-
+
AStringVector Split = StringSplit(a_Permission, ".");
// Iterate over all restrictions; if any matches, then return failure:
@@ -1583,7 +1624,7 @@ void cPlayer::TossItems(const cItems & a_Items)
{
return;
}
-
+
m_Stats.AddValue(statItemsDropped, (StatValue)a_Items.Size());
double vX = 0, vY = 0, vZ = 0;
@@ -1593,10 +1634,7 @@ void cPlayer::TossItems(const cItems & a_Items)
}
-
-
-
-bool cPlayer::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn)
+bool cPlayer::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn, Vector3d a_NewPosition)
{
ASSERT(a_World != nullptr);
@@ -1605,7 +1643,14 @@ bool cPlayer::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn)
// Don't move to same world
return false;
}
-
+
+ // Ask the plugins if the player is allowed to changing the world
+ if (cRoot::Get()->GetPluginManager()->CallHookEntityChangingWorld(*this, *a_World))
+ {
+ // A Plugin doesn't allow the player to changing the world
+ return false;
+ }
+
// Send the respawn packet:
if (a_ShouldSendRespawn && (m_ClientHandle != nullptr))
{
@@ -1619,8 +1664,11 @@ bool cPlayer::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn)
SetWorldTravellingFrom(GetWorld()); // cChunk handles entity removal
GetWorld()->RemovePlayer(this, false);
+ SetPosition(a_NewPosition);
+
// Queue adding player to the new world, including all the necessary adjustments to the object
a_World->AddPlayer(this);
+ cWorld * OldWorld = cRoot::Get()->GetWorld(GetWorld()->GetName()); // Required for the hook HOOK_ENTITY_CHANGED_WORLD
SetWorld(a_World); // Chunks may be streamed before cWorld::AddPlayer() sets the world to the new value
// Update the view distance.
@@ -1634,7 +1682,10 @@ bool cPlayer::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn)
// Broadcast the player into the new world.
a_World->BroadcastSpawnEntity(*this);
-
+
+ // Player changed the world, call the hook
+ cRoot::Get()->GetPluginManager()->CallHookEntityChangedWorld(*this, *OldWorld);
+
return true;
}
@@ -1651,7 +1702,7 @@ bool cPlayer::LoadFromDisk(cWorldPtr & a_World)
{
return true;
}
-
+
// Load from the offline UUID file, if allowed:
AString OfflineUUID = cClientHandle::GenerateOfflineUUID(GetName());
const char * OfflineUsage = " (unused)";
@@ -1663,7 +1714,7 @@ bool cPlayer::LoadFromDisk(cWorldPtr & a_World)
return true;
}
}
-
+
// Load from the old-style name-based file, if allowed:
if (cRoot::Get()->GetServer()->ShouldLoadNamedPlayerData())
{
@@ -1678,7 +1729,7 @@ bool cPlayer::LoadFromDisk(cWorldPtr & a_World)
return true;
}
}
-
+
// None of the files loaded successfully
LOG("Player data file not found for %s (%s, offline %s%s), will be reset to defaults.",
GetName().c_str(), m_UUID.c_str(), OfflineUUID.c_str(), OfflineUsage
@@ -1755,7 +1806,7 @@ bool cPlayer::LoadFromFile(const AString & a_FileName, cWorldPtr & a_World)
{
m_CanFly = true;
}
-
+
m_Inventory.LoadFromJson(root["inventory"]);
cEnderChestEntity::LoadFromJson(root["enderchestinventory"], m_EnderChestContents);
@@ -1774,11 +1825,11 @@ bool cPlayer::LoadFromFile(const AString & a_FileName, cWorldPtr & a_World)
// We use the default world name (like bukkit) because stats are shared between dimensions / worlds.
cStatSerializer StatSerializer(cRoot::Get()->GetDefaultWorld()->GetName(), GetName(), &m_Stats);
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(), a_World->GetName().c_str()
);
-
+
return true;
}
@@ -2128,20 +2179,18 @@ void cPlayer::ApplyFoodExhaustionFromMovement()
return;
}
- // Process exhaustion every two ticks as that is how frequently m_LastPos is updated
- // Otherwise, we apply exhaustion for a 'movement' every tick, one of which is an already processed value
- if (GetWorld()->GetWorldAge() % 2 != 0)
- {
- return;
- }
-
// Calculate the distance travelled, update the last pos:
- Vector3d Movement(GetPosition() - m_LastPos);
- Movement.y = 0; // Only take XZ movement into account
+ double SpeedX = m_Speed.x;
+ double SpeedZ = m_Speed.z;
+ double BaseExhaustion(sqrt((SpeedX * SpeedX) + (SpeedZ * SpeedZ)));
// Apply the exhaustion based on distance travelled:
- double BaseExhaustion = Movement.Length();
- if (IsSprinting())
+ if (IsFlying() || IsClimbing())
+ {
+ // Apply no exhaustion when flying or climbing.
+ BaseExhaustion = 0;
+ }
+ else if (IsSprinting())
{
// 0.1 pt per meter sprinted
BaseExhaustion = BaseExhaustion * 0.1;
@@ -2337,7 +2386,7 @@ AString cPlayer::GetUUIDFileName(const AString & a_UUID)
{
AString UUID = cMojangAPI::MakeUUIDDashed(a_UUID);
ASSERT(UUID.length() == 36);
-
+
AString res("players/");
res.append(UUID, 0, 2);
res.push_back('/');
@@ -2345,7 +2394,3 @@ AString cPlayer::GetUUIDFileName(const AString & a_UUID)
res.append(".json");
return res;
}
-
-
-
-
diff --git a/src/Entities/Player.h b/src/Entities/Player.h
index a0cd9b1d6..dffb61677 100644
--- a/src/Entities/Player.h
+++ b/src/Entities/Player.h
@@ -26,42 +26,42 @@ class cPlayer :
public cPawn
{
typedef cPawn super;
-
+
public:
static const int MAX_HEALTH;
-
+
static const int MAX_FOOD_LEVEL;
-
+
/** Number of ticks it takes to eat an item */
static const int EATING_TICKS;
-
+
// tolua_end
-
+
CLASS_PROTODEF(cPlayer)
-
+
cPlayer(cClientHandlePtr a_Client, const AString & a_PlayerName);
-
+
virtual ~cPlayer();
virtual void SpawnOn(cClientHandle & a_Client) override;
-
+
virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
virtual void HandlePhysics(std::chrono::milliseconds a_Dt, cChunk &) override { UNUSED(a_Dt); }
/** Returns the curently equipped weapon; empty item if none */
virtual cItem GetEquippedWeapon(void) const override { return m_Inventory.GetEquippedItem(); }
-
+
/** Returns the currently equipped helmet; empty item if none */
virtual cItem GetEquippedHelmet(void) const override { return m_Inventory.GetEquippedHelmet(); }
-
+
/** Returns the currently equipped chestplate; empty item if none */
virtual cItem GetEquippedChestplate(void) const override { return m_Inventory.GetEquippedChestplate(); }
/** Returns the currently equipped leggings; empty item if none */
virtual cItem GetEquippedLeggings(void) const override { return m_Inventory.GetEquippedLeggings(); }
-
+
/** Returns the currently equipped boots; empty item if none */
virtual cItem GetEquippedBoots(void) const override { return m_Inventory.GetEquippedBoots(); }
@@ -104,16 +104,16 @@ public:
static int CalcLevelFromXp(int a_CurrentXp);
// tolua_end
-
+
/** Starts charging the equipped bow */
void StartChargingBow(void);
-
+
/** Finishes charging the current bow. Returns the number of ticks for which the bow has been charged */
int FinishChargingBow(void);
-
+
/** Cancels the current bow charging */
void CancelChargingBow(void);
-
+
/** Returns true if the player is currently charging the bow */
bool IsChargingBow(void) const { return m_IsChargingBow; }
@@ -128,7 +128,7 @@ public:
/** Gets the contents of the player's associated enderchest */
cItemGrid & GetEnderChestContents(void) { return m_EnderChestContents; }
-
+
inline const cItem & GetEquippedItem(void) const { return GetInventory().GetEquippedItem(); } // tolua_export
/** Returns whether the player is climbing (ladders, vines etc.) */
@@ -137,43 +137,49 @@ public:
virtual void TeleportToCoords(double a_PosX, double a_PosY, double a_PosZ) override;
// tolua_begin
-
+
/** Sends the "look" packet to the player, forcing them to set their rotation to the specified values.
a_YawDegrees is clipped to range [-180, +180),
a_PitchDegrees is clipped to range [-180, +180) but the client only uses [-90, +90]
*/
void SendRotation(double a_YawDegrees, double a_PitchDegrees);
-
+
/** Returns the position where projectiles thrown by this player should start, player eye position + adjustment */
Vector3d GetThrowStartPos(void) const;
-
+
/** Returns the initial speed vector of a throw, with a 3D length of a_SpeedCoeff. */
Vector3d GetThrowSpeed(double a_SpeedCoeff) const;
-
+
/** Returns the current gamemode. Partly OBSOLETE, you should use IsGameModeXXX() functions wherever applicable */
eGameMode GetGameMode(void) const { return m_GameMode; }
-
+
/** Returns the current effective gamemode (inherited gamemode is resolved before returning) */
eGameMode GetEffectiveGameMode(void) const { return (m_GameMode == gmNotSet) ? m_World->GetGameMode() : m_GameMode; }
-
+
/** Sets the gamemode for the player.
The gamemode may be gmNotSet, in that case the player inherits the world's gamemode.
Updates the gamemode on the client (sends the packet)
*/
void SetGameMode(eGameMode a_GameMode);
+ // Sets the current gamemode, doesn't check validity, doesn't send update packets to client
+ void LoginSetGameMode(eGameMode a_GameMode);
+
+ // Updates player's capabilities - flying, visibility, etc. from their gamemode.
+ void SetCapabilities();
+
/** Returns true if the player is in Creative mode, either explicitly, or by inheriting from current world */
bool IsGameModeCreative(void) const;
-
+
/** Returns true if the player is in Survival mode, either explicitly, or by inheriting from current world */
bool IsGameModeSurvival(void) const;
-
+
/** Returns true if the player is in Adventure mode, either explicitly, or by inheriting from current world */
bool IsGameModeAdventure(void) const;
-
+
/** Returns true if the player is in Spectator mode, either explicitly, or by inheriting from current world */
bool IsGameModeSpectator(void) const;
-
+
AString GetIP(void) const { return m_IP; } // tolua_export
/** Returns the associated team, nullptr if none */
@@ -195,11 +201,8 @@ public:
If the achievement has been already awarded to the player, this method will just increment the stat counter.
Returns the _new_ stat value. (0 = Could not award achievement) */
unsigned int AwardAchievement(const eStatistic a_Ach);
-
+
void SetIP(const AString & a_IP);
-
- // Sets the current gamemode, doesn't check validity, doesn't send update packets to client
- void LoginSetGameMode(eGameMode a_GameMode);
/** Forces the player to move in the given direction.
@deprecated Use SetSpeed instead. */
@@ -210,15 +213,15 @@ public:
cWindow * GetWindow(void) { return m_CurrentWindow; } // tolua_export
const cWindow * GetWindow(void) const { return m_CurrentWindow; }
-
+
/** Opens the specified window; closes the current one first using CloseWindow() */
void OpenWindow(cWindow * a_Window); // Exported in ManualBindings.cpp
-
+
// tolua_begin
-
+
/** Closes the current window, resets current window to m_InventoryWindow. A plugin may refuse the closing if a_CanRefuse is true */
void CloseWindow(bool a_CanRefuse = true);
-
+
/** Closes the current window if it matches the specified ID, resets current window to m_InventoryWindow */
void CloseWindowIfID(char a_WindowID, bool a_CanRefuse = true);
@@ -232,18 +235,23 @@ public:
// tolua_begin
- void SendMessage (const AString & a_Message) { m_ClientHandle->SendChat(a_Message, mtCustom); }
- void SendMessageInfo (const AString & a_Message) { m_ClientHandle->SendChat(a_Message, mtInformation); }
- void SendMessageFailure (const AString & a_Message) { m_ClientHandle->SendChat(a_Message, mtFailure); }
- void SendMessageSuccess (const AString & a_Message) { m_ClientHandle->SendChat(a_Message, mtSuccess); }
- void SendMessageWarning (const AString & a_Message) { m_ClientHandle->SendChat(a_Message, mtWarning); }
- void SendMessageFatal (const AString & a_Message) { m_ClientHandle->SendChat(a_Message, mtFailure); }
- void SendMessagePrivateMsg(const AString & a_Message, const AString & a_Sender) { m_ClientHandle->SendChat(a_Message, mtPrivateMessage, a_Sender); }
- void SendMessage (const cCompositeChat & a_Message) { m_ClientHandle->SendChat(a_Message); }
+ void SendMessage (const AString & a_Message) { m_ClientHandle->SendChat(a_Message, mtCustom); }
+ void SendMessageInfo (const AString & a_Message) { m_ClientHandle->SendChat(a_Message, mtInformation); }
+ void SendMessageFailure (const AString & a_Message) { m_ClientHandle->SendChat(a_Message, mtFailure); }
+ void SendMessageSuccess (const AString & a_Message) { m_ClientHandle->SendChat(a_Message, mtSuccess); }
+ void SendMessageWarning (const AString & a_Message) { m_ClientHandle->SendChat(a_Message, mtWarning); }
+ void SendMessageFatal (const AString & a_Message) { m_ClientHandle->SendChat(a_Message, mtFailure); }
+ void SendMessagePrivateMsg (const AString & a_Message, const AString & a_Sender) { m_ClientHandle->SendChat(a_Message, mtPrivateMessage, a_Sender); }
+ void SendMessage (const cCompositeChat & a_Message) { m_ClientHandle->SendChat(a_Message); }
+
+ void SendSystemMessage (const AString & a_Message) { m_ClientHandle->SendChatSystem(a_Message, mtCustom); }
+ void SendAboveActionBarMessage(const AString & a_Message) { m_ClientHandle->SendChatAboveActionBar(a_Message, mtCustom); }
+ void SendSystemMessage (const cCompositeChat & a_Message) { m_ClientHandle->SendChatSystem(a_Message); }
+ void SendAboveActionBarMessage(const cCompositeChat & a_Message) { m_ClientHandle->SendChatAboveActionBar(a_Message); }
const AString & GetName(void) const { return m_PlayerName; }
void SetName(const AString & a_Name) { m_PlayerName = a_Name; }
-
+
// tolua_end
bool HasPermission(const AString & a_Permission); // tolua_export
@@ -260,7 +268,7 @@ public:
const AStringVector & GetRestrictions(void) const { return m_Restrictions; } // Exported in ManualBindings.cpp
// tolua_begin
-
+
/** Returns the full color code to use for this player, based on their rank.
The returned value either is empty, or includes the cChatColor::Delimiter. */
AString GetColor(void) const;
@@ -279,15 +287,15 @@ public:
/** Heals the player by the specified amount of HPs (positive only); sends health update */
virtual void Heal(int a_Health) override;
-
+
int GetFoodLevel (void) const { return m_FoodLevel; }
double GetFoodSaturationLevel (void) const { return m_FoodSaturationLevel; }
int GetFoodTickTimer (void) const { return m_FoodTickTimer; }
double GetFoodExhaustionLevel (void) const { return m_FoodExhaustionLevel; }
-
+
/** Returns true if the player is satiated, i. e. their foodlevel is at the max and they cannot eat anymore */
bool IsSatiated(void) const { return (m_FoodLevel >= MAX_FOOD_LEVEL); }
-
+
void SetFoodLevel (int a_FoodLevel);
void SetFoodSaturationLevel (double a_FoodSaturationLevel);
void SetFoodTickTimer (int a_FoodTickTimer);
@@ -298,10 +306,10 @@ public:
/** Adds the specified exhaustion to m_FoodExhaustion. Expects only positive values. */
void AddFoodExhaustion(double a_Exhaustion);
-
+
/** Returns true if the player is currently in the process of eating the currently equipped item */
bool IsEating(void) const { return (m_EatingFinishTick >= 0); }
-
+
/** Returns true if the player is currently flying. */
bool IsFlying(void) const { return m_IsFlying; }
@@ -329,16 +337,16 @@ public:
GetWorld()->BroadcastEntityAnimation(*this, 2);
}
}
-
+
/** Starts eating the currently equipped item. Resets the eating timer and sends the proper animation packet */
void StartEating(void);
-
+
/** Finishes eating the currently equipped item. Consumes the item, updates health and broadcasts the packets */
void FinishEating(void);
-
+
/** Aborts the current eating operation */
void AbortEating(void);
-
+
virtual void KilledBy(TakeDamageInfo & a_TDI) override;
virtual void Killed(cEntity * a_Victim) override;
@@ -350,75 +358,75 @@ public:
/** Moves the player to the specified world.
Returns true if successful, false on failure (world not found). */
- virtual bool DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn) override;
+ virtual bool DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn, Vector3d a_NewPosition) override;
/** Saves all player data, such as inventory, to JSON */
bool SaveToDisk(void);
typedef cWorld * cWorldPtr;
-
+
/** Loads the player data from the disk file
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
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);
-
+
const AString & GetLoadedWorldName() { return m_LoadedWorldName; }
void UseEquippedItem(int a_Amount = 1);
-
+
void SendHealth(void);
void SendExperience(void);
-
+
/** In UI windows, get the item that the player is dragging */
cItem & GetDraggingItem(void) {return m_DraggingItem; }
-
+
// In UI windows, when inventory-painting:
/** Clears the list of slots that are being inventory-painted. To be used by cWindow only */
void ClearInventoryPaintSlots(void);
-
+
/** Adds a slot to the list for inventory painting. To be used by cWindow only */
void AddInventoryPaintSlot(int a_SlotNum);
-
+
/** Returns the list of slots currently stored for inventory painting. To be used by cWindow only */
const cSlotNums & GetInventoryPaintSlots(void) const;
-
+
// tolua_begin
-
+
/** Returns the current relative maximum speed (takes current sprinting / flying state into account) */
double GetMaxSpeed(void) const;
-
+
/** Gets the normal relative maximum speed */
double GetNormalMaxSpeed(void) const { return m_NormalMaxSpeed; }
-
+
/** Gets the sprinting relative maximum speed */
double GetSprintingMaxSpeed(void) const { return m_SprintingMaxSpeed; }
-
+
/** Gets the flying relative maximum speed */
double GetFlyingMaxSpeed(void) const { return m_FlyingMaxSpeed; }
-
+
/** Sets the normal relative maximum speed. Sends the update to player, if needed. */
void SetNormalMaxSpeed(double a_Speed);
-
+
/** Sets the sprinting relative maximum speed. Sends the update to player, if needed. */
void SetSprintingMaxSpeed(double a_Speed);
-
+
/** Sets the flying relative maximum speed. Sends the update to player, if needed. */
void SetFlyingMaxSpeed(double a_Speed);
-
+
/** Sets the crouch status, broadcasts to all visible players */
void SetCrouch(bool a_IsCrouched);
-
+
/** Starts or stops sprinting, sends the max speed update to the client, if needed */
void SetSprint(bool a_IsSprinting);
-
+
/** Flags the player as flying */
void SetFlying(bool a_IsFlying);
@@ -442,17 +450,17 @@ public:
/** Sets the player's bed (home) position */
void SetBedPos(const Vector3i & a_Pos) { m_LastBedPos = a_Pos; }
-
+
// tolua_end
/** Update movement-related statistics. */
void UpdateMovementStats(const Vector3d & a_DeltaPos);
-
+
// tolua_begin
/** Returns wheter the player can fly or not. */
virtual bool CanFly(void) const { return m_CanFly; }
-
+
/** Returns the UUID (short format) that has been read from the client, or empty string if not available. */
const AString & GetUUID(void) const { return m_UUID; }
@@ -483,16 +491,16 @@ public:
bool PlaceBlocks(const sSetBlockVector & a_Blocks);
// cEntity overrides:
- virtual bool IsCrouched (void) const { return m_IsCrouched; }
- virtual bool IsSprinting(void) const { return m_IsSprinting; }
- virtual bool IsRclking (void) const { return IsEating() || IsChargingBow(); }
+ virtual bool IsCrouched (void) const override { return m_IsCrouched; }
+ virtual bool IsSprinting(void) const override { return m_IsSprinting; }
+ virtual bool IsRclking (void) const override { return IsEating() || IsChargingBow(); }
- virtual void Detach(void);
+ virtual void Detach(void) override;
/** Called by cClientHandle when the client is being destroyed.
The player removes its m_ClientHandle ownership so that the ClientHandle gets deleted. */
void RemoveClientHandle(void);
-
+
protected:
typedef std::vector<std::vector<AString> > AStringVectorVector;
@@ -535,16 +543,16 @@ protected:
// Food-related variables:
/** Represents the food bar, one point equals half a "drumstick" */
int m_FoodLevel;
-
+
/** "Overcharge" for the m_FoodLevel; is depleted before m_FoodLevel */
double m_FoodSaturationLevel;
-
+
/** Count-up to the healing or damaging action, based on m_FoodLevel */
int m_FoodTickTimer;
-
+
/** A "buffer" which adds up hunger before it is substracted from m_FoodSaturationLevel or m_FoodLevel. Each action adds a little */
double m_FoodExhaustionLevel;
-
+
float m_LastJumpHeight;
float m_LastGroundHeight;
bool m_bTouchGround;
@@ -564,31 +572,31 @@ protected:
eGameMode m_GameMode;
AString m_IP;
-
+
/** The item being dragged by the cursor while in a UI window */
cItem m_DraggingItem;
std::chrono::steady_clock::time_point m_LastPlayerListTime;
cClientHandlePtr m_ClientHandle;
-
+
cSlotNums m_InventoryPaintSlots;
-
+
/** Max speed, relative to the game default.
1 means regular speed, 2 means twice as fast, 0.5 means half-speed.
Default value is 1. */
double m_NormalMaxSpeed;
-
+
/** Max speed, relative to the game default max speed, when sprinting.
1 means regular speed, 2 means twice as fast, 0.5 means half-speed.
Default value is 1.3. */
double m_SprintingMaxSpeed;
-
+
/** Max speed, relative to the game default flying max speed, when flying.
1 means regular speed, 2 means twice as fast, 0.5 means half-speed.
Default value is 1. */
double m_FlyingMaxSpeed;
-
+
bool m_IsCrouched;
bool m_IsSprinting;
bool m_IsFlying;
@@ -629,7 +637,7 @@ protected:
Will not apply food penalties if found to be true; will set to false after processing
*/
bool m_bIsTeleporting;
-
+
/** The short UUID (no dashes) of the player, as read from the ClientHandle.
If no ClientHandle is given, the UUID is initialized to empty. */
AString m_UUID;
@@ -642,14 +650,14 @@ protected:
void ResolvePermissions(void);
void ResolveGroups(void);
- virtual void Destroyed(void);
+ virtual void Destroyed(void) override;
/** Filters out damage for creative mode / friendly fire */
virtual bool DoTakeDamage(TakeDamageInfo & TDI) override;
/** Stops players from burning in creative mode */
virtual void TickBurning(cChunk & a_Chunk) override;
-
+
/** Called in each tick to handle food-related processing */
void HandleFood(void);
@@ -666,7 +674,3 @@ protected:
This can be used both for online and offline UUIDs. */
AString GetUUIDFileName(const AString & a_UUID);
} ; // tolua_export
-
-
-
-
diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp
index 05b7669cd..8e2e412dd 100644
--- a/src/Entities/ProjectileEntity.cpp
+++ b/src/Entities/ProjectileEntity.cpp
@@ -30,7 +30,7 @@
/// Converts an angle in radians into a byte representation used by the network protocol
-#define ANGLE_TO_PROTO(X) (Byte)(X * 255 / 360)
+#define ANGLE_TO_PROTO(X) static_cast<Byte>(X * 255 / 360)
@@ -222,7 +222,7 @@ cProjectileEntity::cProjectileEntity(eKind a_Kind, cEntity * a_Creator, double a
m_ProjectileKind(a_Kind),
m_CreatorData(
((a_Creator != nullptr) ? a_Creator->GetUniqueID() : cEntity::INVALID_ID),
- ((a_Creator != nullptr) ? (a_Creator->IsPlayer() ? ((cPlayer *)a_Creator)->GetName() : "") : ""),
+ ((a_Creator != nullptr) ? (a_Creator->IsPlayer() ? static_cast<cPlayer *>(a_Creator)->GetName() : "") : ""),
((a_Creator != nullptr) ? a_Creator->GetEquippedWeapon().m_Enchantments : cEnchantments())
),
m_IsInGround(false)
@@ -238,7 +238,7 @@ cProjectileEntity::cProjectileEntity(eKind a_Kind, cEntity * a_Creator, double a
cProjectileEntity::cProjectileEntity(eKind a_Kind, cEntity * a_Creator, const Vector3d & a_Pos, const Vector3d & a_Speed, double a_Width, double a_Height) :
super(etProjectile, a_Pos.x, a_Pos.y, a_Pos.z, a_Width, a_Height),
m_ProjectileKind(a_Kind),
- m_CreatorData(a_Creator->GetUniqueID(), a_Creator->IsPlayer() ? ((cPlayer *)a_Creator)->GetName() : "", a_Creator->GetEquippedWeapon().m_Enchantments),
+ m_CreatorData(a_Creator->GetUniqueID(), a_Creator->IsPlayer() ? static_cast<cPlayer *>(a_Creator)->GetName() : "", a_Creator->GetEquippedWeapon().m_Enchantments),
m_IsInGround(false)
{
SetSpeed(a_Speed);
@@ -281,6 +281,7 @@ cProjectileEntity * cProjectileEntity::Create(eKind a_Kind, cEntity * a_Creator,
return new cFireworkEntity(a_Creator, a_X, a_Y, a_Z, *a_Item);
}
+ case pkFishingFloat: break;
}
LOGWARNING("%s: Unknown projectile kind: %d", __FUNCTION__, a_Kind);
diff --git a/src/Entities/SplashPotionEntity.cpp b/src/Entities/SplashPotionEntity.cpp
index fd1a0179b..926fd1abe 100644
--- a/src/Entities/SplashPotionEntity.cpp
+++ b/src/Entities/SplashPotionEntity.cpp
@@ -9,7 +9,7 @@
/// Converts an angle in radians into a byte representation used by the network protocol
-#define ANGLE_TO_PROTO(X) (Byte)(X * 255 / 360)
+#define ANGLE_TO_PROTO(X) static_cast<Byte>(X * 255 / 360)
////////////////////////////////////////////////////////////////////////////////
// cSplashPotionEntityCallback:
@@ -51,7 +51,7 @@ public:
double Reduction = -0.25 * SplashDistance + 1.0;
Reduction = std::max(Reduction, 0.0);
- ((cPawn *) a_Entity)->AddEntityEffect(m_EntityEffectType, m_EntityEffect.GetDuration(), m_EntityEffect.GetIntensity(), Reduction);
+ static_cast<cPawn *>(a_Entity)->AddEntityEffect(m_EntityEffectType, m_EntityEffect.GetDuration(), m_EntityEffect.GetIntensity(), Reduction);
return false;
}
@@ -116,7 +116,13 @@ void cSplashPotionEntity::Splash(const Vector3d & a_HitPos)
cSplashPotionCallback Callback(a_HitPos, m_EntityEffectType, m_EntityEffect);
m_World->ForEachEntity(Callback);
- m_World->BroadcastSoundParticleEffect(2002, (int)floor(a_HitPos.x), (int)floor(a_HitPos.y), (int)floor(a_HitPos.z), m_PotionColor);
+ m_World->BroadcastSoundParticleEffect(
+ 2002,
+ FloorC(a_HitPos.x),
+ FloorC(a_HitPos.y),
+ FloorC(a_HitPos.z),
+ m_PotionColor
+ );
}
diff --git a/src/Entities/ThrownEnderPearlEntity.cpp b/src/Entities/ThrownEnderPearlEntity.cpp
index f01cdc18c..12d826042 100644
--- a/src/Entities/ThrownEnderPearlEntity.cpp
+++ b/src/Entities/ThrownEnderPearlEntity.cpp
@@ -77,9 +77,9 @@ void cThrownEnderPearlEntity::TeleportCreator(const Vector3d & a_HitPos)
class cProjectileCreatorCallbackForPlayers : public cPlayerListCallback
{
public:
- cProjectileCreatorCallbackForPlayers(cEntity * a_Attacker, Vector3i a_HitPos) :
+ cProjectileCreatorCallbackForPlayers(cEntity * a_Attacker, Vector3i a_CallbackHitPos) :
m_Attacker(a_Attacker),
- m_HitPos(a_HitPos)
+ m_HitPos(a_CallbackHitPos)
{
}
diff --git a/src/Entities/ThrownSnowballEntity.cpp b/src/Entities/ThrownSnowballEntity.cpp
index 24db1e7ee..b28205d44 100644
--- a/src/Entities/ThrownSnowballEntity.cpp
+++ b/src/Entities/ThrownSnowballEntity.cpp
@@ -32,7 +32,7 @@ void cThrownSnowballEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d &
int TotalDamage = 0;
if (a_EntityHit.IsMob())
{
- eMonsterType MobType = ((cMonster &) a_EntityHit).GetMobType();
+ eMonsterType MobType = static_cast<cMonster &>(a_EntityHit).GetMobType();
if (MobType == mtBlaze)
{
TotalDamage = 3;