6 #include "../BlockInfo.h"
8 #include "../Bindings/PluginManager.h"
9 #include "../BoundingBox.h"
10 #include "../Blocks/BlockHandler.h"
11 #include "../Blocks/BlockFarmland.h"
12 #include "../EffectID.h"
13 #include "../Mobs/Monster.h"
21 m_LastGroundHeight(0),
34 std::vector<cEntityEffect *> EffectsToTick;
54 EffectsToTick.push_back(Effect);
61 for (
auto * Effect : EffectsToTick)
63 Effect->OnTick(*
this);
67 if ((!
IsPlayer()) || (!
static_cast<cPlayer *
>(
this)->IsGameModeSpectator()))
90 v3Delta *= 1.0 / (v3Delta.
Length() + 0.01);
189 if (
cPluginManager::Get()->CallHookEntityAddEffect(*
this, a_EffectType, a_Duration, a_Intensity, a_DistanceModifier))
200 a_Duration =
static_cast<int>(a_Duration * a_DistanceModifier);
206 ExistingEffect->second->OnDeactivate(*
this);
226 auto Effect = std::move(itr->second);
228 Effect->OnDeactivate(*
this);
271 if (Monster == a_Monster)
307 static const auto HalfWidth =
GetWidth() / 2;
308 static const auto EPS = 0.0001;
328 bool IsFootOnSlimeBlock =
false;
334 } CrossSampleCoords[] =
346 static const Vector3i BlockSampleOffsets[] =
355 bool OnGround =
false;
356 for (
size_t i = 0; i <
ARRAYCOUNT(CrossSampleCoords); i++)
361 Vector3d CrossTestPosition =
GetPosition() +
Vector3d(CrossSampleCoords[i].x * HalfWidth, -EPS, CrossSampleCoords[i].z * HalfWidth);
364 for (
size_t j = 0; j <
ARRAYCOUNT(BlockSampleOffsets); j++)
366 Vector3i BlockTestPosition = CrossTestPosition.
Floor() + BlockSampleOffsets[j];
393 bool FallDamageAbsorbed = IsFootInWater;
398 bool ShouldBounceOnSlime =
true;
402 auto Player =
static_cast<cPlayer *
>(
this);
405 FallDamageAbsorbed |= Player->
IsFlying() || Player->IsClimbing();
408 ShouldBounceOnSlime = !Player->IsCrouched();
409 FallDamageAbsorbed |= (IsFootOnSlimeBlock && ShouldBounceOnSlime);
414 FallDamageAbsorbed |= IsFootOnSlimeBlock;
419 if (IsFootOnSlimeBlock && ShouldBounceOnSlime)
435 auto Damage =
static_cast<int>(FallHeight - 3.0);
440 if ((Damage > 0) && !FallDamageAbsorbed)
444 Damage =
static_cast<int>(
static_cast<float>(Damage) * 0.33);
449 Damage = std::clamp(
static_cast<int>(
static_cast<float>(Damage) * 0.2), 1, 20);
458 (Damage - 1.f) * ((0.3f - 0.1f) / (15.f - 1.f)) + 0.1f,
459 static_cast<int>((Damage - 1.f) * ((50.f - 20.f) / (15.f - 1.f)) + 20.f),
460 { { BlockBelow, 0 } }
471 if (
GetWorld()->IsFarmlandTramplingEnabled())
493 if (a_FallHeight <= 0.6875)
528 bool ShouldTrample =
true;
532 if (a_FallHeight <= 1.0625)
534 ShouldTrample = Random.RandBool(0.25);
536 else if (a_FallHeight <= 1.5625)
538 ShouldTrample = Random.RandBool(0.66);
585 std::map<cEntityEffect::eType, cEntityEffect *> Effects;
588 Effects.insert({ Effect.first, Effect.second.get() });
634 auto & inv =
static_cast<cPlayer *
>(
this)->GetInventory();
637 inv.SetEquippedItem({});
642 inv.SetShieldSlot({});
662 for (
unsigned int i = 0; i < a_NumTries; i++)
664 const int DestX = Random.RandInt(a_MinBoxCorner.
x, a_MaxBoxCorner.
x);
665 int DestY = Random.RandInt(a_MinBoxCorner.
y, a_MaxBoxCorner.
y);
666 const int DestZ = Random.RandInt(a_MinBoxCorner.
z, a_MaxBoxCorner.
z);
672 DestBlock = a_World.
GetBlock({DestX, DestY, DestZ});
684 for (
int j = 1; j <= a_HeightRequired; j++)
700 a_Destination =
Vector3d(DestX + 0.5, DestY + 1, DestZ + 0.5);
721 Vector3i MinCorner(a_Centre.
x - a_HalfCubeWidth, a_Centre.
y - a_HalfCubeWidth, a_Centre.
z - a_HalfCubeWidth);
722 Vector3i MaxCorner(a_Centre.
x + a_HalfCubeWidth, a_Centre.
y + a_HalfCubeWidth, a_Centre.
z + a_HalfCubeWidth);
bool IsBlockWater(BLOCKTYPE a_BlockType)
bool IsBlockLiquid(BLOCKTYPE a_BlockType)
@ E_ITEM_TOTEM_OF_UNDYING
unsigned char NIBBLETYPE
The datatype used by nibbledata (meta, light, skylight)
unsigned char BLOCKTYPE
The datatype used by blockdata.
eDamageType
Damage type, used in the TakeDamageInfo structure and related functions.
MTRand & GetRandomProvider()
Returns the current thread's random number source.
#define ARRAYCOUNT(X)
Evaluates to the number of elements in an array (compile-time!)
Vector3< double > Vector3d
static cPluginManager * Get(void)
Returns the instance of the Plugin Manager (there is only ever one)
static bool IsSolid(BLOCKTYPE Block)
Is this block solid (player cannot walk through)?
static void TurnToDirt(cChunk &a_Chunk, Vector3i a_AbsPos)
Turns farmland into dirt.
virtual bool IsInsideBlock(const Vector3d a_RelPosition, const NIBBLETYPE a_BlockMeta) const
Tests if a_RelPosition is inside the block, where a_RelPosition is relative to the origin of the bloc...
static const cBlockHandler & For(BLOCKTYPE a_BlockType)
Represents two sets of coords, minimum and maximum for each direction.
Vector3d GetMax(void) const
Vector3d GetMin(void) const
static bool IsValidHeight(Vector3i a_BlockPosition)
Validates a height-coordinate.
virtual bool IsElytraFlying(void) const
bool IsPlayer(void) const
cBoundingBox GetBoundingBox() const
virtual void Tick(std::chrono::milliseconds a_Dt, cChunk &a_Chunk)
bool IsAttachedTo(const cEntity *a_Entity) const
Returns true if this entity is attached to the specified entity.
void AddSpeed(double a_AddSpeedX, double a_AddSpeedY, double a_AddSpeedZ)
virtual void HandleAir(void)
Called in each tick to handle air-related processing i.e.
bool IsTicking(void) const
Returns true if the entity is valid and ticking.
void SetGravity(float a_Gravity)
virtual bool IsFireproof(void) const
float GetWidth(void) const
virtual bool IsHeadInWater(void) const
Returns true if any part of the entity is in a water block.
UInt32 GetUniqueID(void) const
eEntityType GetEntityType(void) const
double GetPosY(void) const
void TakeDamage(cEntity &a_Attacker)
Makes this pawn take damage from an attack by a_Attacker.
float GetHeight(void) const
void SetAirDrag(float a_AirDrag)
virtual void KilledBy(TakeDamageInfo &a_TDI)
Called when the health drops below zero.
virtual void OnRemoveFromWorld(cWorld &a_World)
Called when the entity is removed from a world.
const Vector3d & GetPosition(void) const
Exported in ManualBindings.
cWorld * GetWorld(void) const
virtual void ResetPosition(Vector3d a_NewPos)
Set the entities position and last sent position.
eType
All types of entity effects (numbers correspond to protocol / storage types)
int GetDuration(void) const
Returns the duration of the effect.
virtual void OnActivate(cPawn &a_Target)
Called when the effect is first added to an entity.
int GetTicks(void) const
Returns how many ticks this effect has been active for.
static std::unique_ptr< cEntityEffect > CreateEntityEffect(cEntityEffect::eType a_EffectType, int a_Duration, short a_Intensity, double a_DistanceModifier)
Creates a pointer to the proper entity effect from the effect type.
void HandleFarmlandTrampling(double a_FallHeight, BLOCKTYPE a_BlockAtFoot, BLOCKTYPE a_BlockBelow)
Handles farmland trampling when hitting the ground.
void ClearEntityEffects(void)
Removes all currently applied entity effects (used when drinking milk)
bool DeductTotem(eDamageType a_DamageType)
Attempt to activate a Totem of Undying.
tEffectMap m_EntityEffects
std::map< cEntityEffect::eType, std::unique_ptr< cEntityEffect > > tEffectMap
virtual bool IsInvisible() const override
cEntityEffect * GetEntityEffect(cEntityEffect::eType a_EffectType) const
Returns the entity effect, if it is currently applied or nullptr if not.
virtual void ResetPosition(Vector3d a_NewPosition) override
Set the entities position and last sent position.
virtual void HandleFalling(void)
void TargetingMe(cMonster *a_Monster)
Add the monster to the list of monsters targeting this pawn.
void StopEveryoneFromTargetingMe()
Tells all pawns which are targeting us to stop targeting us.
std::map< cEntityEffect::eType, cEntityEffect * > GetEntityEffects() const
Returns all entity effects.
std::vector< cMonster * > m_TargetingMe
A list of all monsters that are targeting this pawn.
bool HasEntityEffect(cEntityEffect::eType a_EffectType) const
Returns true, if the entity effect is currently applied.
virtual void HandleAir(void) override
Called in each tick to handle air-related processing i.e.
void AddEntityEffect(cEntityEffect::eType a_EffectType, int a_EffectDurationTicks, short a_EffectIntensity, double a_DistanceModifier=1)
Applies an entity effect.
double m_LastGroundHeight
void RemoveEntityEffect(cEntityEffect::eType a_EffectType)
Removes a currently applied entity effect.
static bool FindTeleportDestination(cWorld &a_World, const int a_HeightRequired, const unsigned int a_NumTries, Vector3d &a_Destination, const Vector3i a_MinBoxCorner, const Vector3i a_MaxBoxCorner)
virtual void Tick(std::chrono::milliseconds a_Dt, cChunk &a_Chunk) override
virtual void OnRemoveFromWorld(cWorld &a_World) override
Called when the entity is removed from a world.
cPawn(eEntityType a_EntityType, float a_Width, float a_Height)
virtual bool IsFireproof(void) const override
void NoLongerTargetingMe(cMonster *a_Monster)
Remove the monster from the list of monsters targeting this pawn.
virtual void KilledBy(TakeDamageInfo &a_TDI) override
Called when the health drops below zero.
bool IsFlying(void) const
Returns true if the player is currently flying.
cPawn * GetTarget()
Returns the current target.
void UnsafeUnsetTarget()
Unset the target without notifying the target entity.
Vector3< int > Floor(void) const
Returns a new Vector3i with coords set to std::floor() of this vector's coords.
double Length(void) const
bool DoWithChunkAt(Vector3i a_BlockPos, cChunkCallback a_Callback)
Calls the callback for the chunk at the block position specified, with ChunkMapCS locked.
virtual void BroadcastEntityAnimation(const cEntity &a_Entity, EntityAnimation a_Animation, const cClientHandle *a_Exclude=nullptr) override
BLOCKTYPE GetBlock(Vector3i a_BlockPos) const
Returns the block type at the specified position.
virtual void BroadcastParticleEffect(const AString &a_ParticleName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, const cClientHandle *a_Exclude=nullptr) override
virtual bool ForEachEntityInBox(const cBoundingBox &a_Box, cEntityCallback a_Callback) override
Calls the callback for each entity that has a nonempty intersection with the specified boundingbox.
NIBBLETYPE GetBlockMeta(Vector3i a_BlockPos) const
Returns the block meta at the specified position.
void CollectPickupsByEntity(cEntity &a_Entity)
virtual void BroadcastEntityEffect(const cEntity &a_Entity, int a_EffectID, int a_Amplifier, int a_Duration, const cClientHandle *a_Exclude=nullptr) override
virtual void BroadcastRemoveEntityEffect(const cEntity &a_Entity, int a_EffectID, const cClientHandle *a_Exclude=nullptr) override