8 #include "../Bindings/PluginManager.h" 10 #include "../ClientHandle.h" 11 #include "../LineBlockTracer.h" 12 #include "../BoundingBox.h" 13 #include "../ChunkMap.h" 33 #define ANGLE_TO_PROTO(X) static_cast<Byte>(X * 255 / 360) 43 public cBlockTracer::cCallbacks
74 cBoundingBox bb(a_BlockX, a_BlockX + 1, a_BlockY, a_BlockY + 1, a_BlockZ, a_BlockZ + 1);
84 if (
cPluginManager::Get()->CallHookProjectileHitBlock(*m_Projectile, a_BlockX, a_BlockY, a_BlockZ, Face, Intersection))
94 LOGD(
"WEIRD! block tracer reports a hit, but BBox tracer doesn't. Ignoring the hit.");
105 m_SlowdownCoeff = std::min(m_SlowdownCoeff, 0.9);
112 m_SlowdownCoeff = std::min(m_SlowdownCoeff, 0.8);
135 m_NextPos(a_NextPos),
163 if (!EntBox.CalcLineIntersection(m_Pos, m_NextPos, LineCoeff, Face))
174 static_cast<cPlayer &
>(a_Entity).IsGameModeSpectator()
189 if (LineCoeff < m_MinCoeff)
192 m_MinCoeff = LineCoeff;
193 m_HitEntity = &a_Entity;
207 bool HasHit(
void)
const {
return (m_MinCoeff < 1); }
228 super(etProjectile, a_Pos, a_Width, a_Height),
229 m_ProjectileKind(a_Kind),
231 ((a_Creator != nullptr) ? a_Creator->GetUniqueID() :
cEntity::INVALID_ID),
232 ((a_Creator != nullptr) ? (a_Creator->IsPlayer() ? static_cast<
cPlayer *>(a_Creator)->GetName() :
"") :
""),
233 ((a_Creator != nullptr) ? a_Creator->GetEquippedWeapon().m_Enchantments :
cEnchantments())
266 const cItem * a_Item,
271 if (a_Speed !=
nullptr)
278 case pkArrow:
return cpp14::make_unique<cArrowEntity> (a_Creator, a_Pos, Speed);
279 case pkEgg:
return cpp14::make_unique<cThrownEggEntity> (a_Creator, a_Pos, Speed);
280 case pkEnderPearl:
return cpp14::make_unique<cThrownEnderPearlEntity>(a_Creator, a_Pos, Speed);
281 case pkSnowball:
return cpp14::make_unique<cThrownSnowballEntity> (a_Creator, a_Pos, Speed);
282 case pkGhastFireball:
return cpp14::make_unique<cGhastFireballEntity> (a_Creator, a_Pos, Speed);
283 case pkFireCharge:
return cpp14::make_unique<cFireChargeEntity> (a_Creator, a_Pos, Speed);
284 case pkExpBottle:
return cpp14::make_unique<cExpBottleEntity> (a_Creator, a_Pos, Speed);
285 case pkSplashPotion:
return cpp14::make_unique<cSplashPotionEntity> (a_Creator, a_Pos, Speed, *a_Item);
286 case pkWitherSkull:
return cpp14::make_unique<cWitherSkullEntity> (a_Creator, a_Pos, Speed);
289 ASSERT(a_Item !=
nullptr);
295 return cpp14::make_unique<cFireworkEntity>(a_Creator, a_Pos, *a_Item);
300 LOGWARNING(
"%s: Unknown projectile kind: %d", __FUNCTION__, a_Kind);
315 FLOGD(
"Projectile {0}: pos {1:.02f}, hit solid block at face {2}",
333 auto EntityHit =
static_cast<cPawn *
>(&a_EntityHit);
336 static_cast<cPlayer&
>(a_Hitter).NotifyNearbyWolves(EntityHit,
true);
353 case pkEgg:
return "Egg";
393 auto DtSec = std::chrono::duration_cast<std::chrono::duration<double>>(a_Dt);
397 const Vector3d NextPos = Pos + DeltaSpeed;
402 if (EntityCollisionCallback.
HasHit())
408 FLOGD(
"Projectile {0} has hit an entity {1} ({2}) at {3:.02f} (coeff {4:.03f})",
439 NewSpeed -= NewSpeed * (
m_AirDrag * 20.0f) * DtSec.count();
#define ANGLE_TO_PROTO(X)
Converts an angle in radians into a byte representation used by the network protocol.
bool CallHookProjectileHitEntity(cProjectileEntity &a_Projectile, cEntity &a_HitEntity)
double GetPitch(void) const
cProjectileEntity * m_Projectile
CreatorData m_CreatorData
The structure for containing the entity ID and name who has created this projectile The ID and / or n...
static bool IsSolid(BLOCKTYPE a_Type)
unsigned char BLOCKTYPE
The datatype used by blockdata.
AString GetMCAClassName(void) const
Returns the string that is used as the entity type (class name) in MCA files.
cProjectileTracerCallback(cProjectileEntity *a_Projectile)
void SetPosition(double a_PosX, double a_PosY, double a_PosZ)
void Expand(double a_ExpandX, double a_ExpandY, double a_ExpandZ)
Expands the bounding box by the specified amount in each direction (so the box becomes larger by 2 * ...
cFireworkItem m_FireworkItem
long int GetTicksAlive(void) const
Gets number of ticks this entity has existed for.
void SendSpawnObject(const cEntity &a_Entity, char a_ObjectType, int a_ObjectData, Byte a_Yaw, Byte a_Pitch)
AString GetCreatorName(void) const
Returns the name of the player that created the projectile Will be empty for non-player creators...
cEntity * GetHitEntity(void) const
Returns the nearest entity that was hit, after the enumeration has been completed.
const Vector3d & GetSpeed(void) const
Exported in ManualBindings.
virtual void Tick(std::chrono::milliseconds a_Dt, cChunk &a_Chunk) override
cProjectileEntity * m_Projectile
UInt32 m_UniqueID
The ID of the entity that is guaranteed to be unique within a single run of the server.
unsigned char NIBBLETYPE
The datatype used by nibbledata (meta, light, skylight)
Represents two sets of coords, minimum and maximum for each direction.
double GetWidth(void) const
eKind
The kind of the projectile.
static cPluginManager * Get(void)
Returns the instance of the Plugin Manager (there is only ever one)
bool DoWithEntityByID(UInt32 a_UniqueID, cEntityCallback a_Callback)
Calls the callback if the entity with the specified ID is found, with the entity object as the callba...
double GetSlowdownCoeff(void) const
double GetHeight(void) const
float m_AirDrag
Stores the air drag that is applied to the entity every tick, measured in speed ratio per tick Acts a...
virtual void OnHitSolidBlock(Vector3d a_HitPos, eBlockFace a_HitFace)
Called by the physics blocktracer when the entity hits a solid block, the hit position and the face h...
bool CalcLineIntersection(Vector3d a_LinePoint1, Vector3d a_LinePoint2, double &a_LineCoeff, eBlockFace &a_Face) const
Returns true if this bounding box is intersected by the line specified by its two points Also calcula...
static std::unique_ptr< cProjectileEntity > Create(eKind a_Kind, cEntity *a_Creator, Vector3d a_Pos, const cItem *a_Item, const Vector3d *a_Speed=nullptr)
Creates a new instance of the specified projectile entity.
bool ForEachEntity(cEntityCallback a_Callback)
Calls the callback for each entity; returns true if all entities processed, false if the callback abo...
void StartBurning(int a_TicksLeftBurning)
Puts the entity on fire for the specified amount of ticks.
bool IsTicking(void) const
Returns true if the entity is valid and ticking.
bool IsMinecart(void) const
void SetPitchFromSpeed(void)
Sets the pitch to match the speed vector (entity gies "face-forward")
double GetMinCoeff(void) const
Returns the line coeff where the hit was encountered, after the enumeration has been completed...
void LOGWARNING(const char *a_Format, fmt::ArgList a_ArgList)
virtual void SpawnOn(cClientHandle &a_Client) override
Descendants override this function to send a command to the specified client to spawn the entity on t...
virtual void CollectedBy(cPlayer &a_Dest)
Called by Chunk when the projectile is eligible for player collection.
const Vector3d & m_NextPos
void SetGravity(float a_Gravity)
void SetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ)
Sets the speed of the entity, measured in m / sec.
double GetYaw(void) const
eBlockFace
Block face constants, used in PlayerDigging and PlayerBlockPlacement packets and bbox collision calc...
bool IsPlayer(void) const
void SetYawFromSpeed(void)
Sets the rotation to match the speed vector (entity goes "face-forward")
bool Trace(double a_StartX, double a_StartY, double a_StartZ, double a_EndX, double a_EndY, double a_EndZ)
Traces one line between Start and End; returns true if the entire line was traced (until OnNoMoreHits...
virtual cItem GetEquippedWeapon(void) const
Returns the curently equipped weapon; empty item if none.
bool m_IsInGround
True if the projectile has hit the ground and is stuck there.
const Vector3d & GetPosition(void) const
Exported in ManualBindings.
float m_Gravity
Stores gravity that is applied to an entity every tick For realistic effects, this should be negative...
eKind m_ProjectileKind
The type of projectile I am.
virtual void HandlePhysics(std::chrono::milliseconds a_Dt, cChunk &a_Chunk) override
Handles the physics of the entity - updates position based on speed, updates speed based on environme...
void SetAirDrag(float a_AirDrag)
virtual void OnHitEntity(cEntity &a_EntityHit, Vector3d a_HitPos)
Called by the physics blocktracer when the entity hits another entity.
UInt32 GetCreatorUniqueID(void)
Returns the unique ID of the entity who created this projectile May return an ID <0.
std::vector< int > m_Colours
Class that stores item enchantments or stored-enchantments The enchantments may be serialized to a st...
cProjectileEntityCollisionCallback(cProjectileEntity *a_Projectile, const Vector3d &a_Pos, const Vector3d &a_NextPos)
virtual const char * GetClass(void) const
Returns the topmost class name for the object.
void StopBurning(void)
Stops the entity from burning, resets all burning timers.
virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, eBlockFace a_EntryFace) override
cProjectileEntity(eKind a_Kind, cEntity *a_Creator, Vector3d a_Pos, double a_Width, double a_Height)
void SendEntityMetadata(const cEntity &a_Entity)
#define UNREACHABLE(x)
Use to mark code that should be impossible to reach.
UInt32 GetUniqueID(void) const
virtual void Tick(std::chrono::milliseconds a_Dt, cChunk &a_Chunk)
bool HasHit(void) const
Returns true if the callback has encountered a true hit.
virtual void BroadcastMovementUpdate(const cClientHandle *a_Exclude=nullptr)
Updates clients of changes in the entity.