From 5d00247cce71aae67660623799b66f51bce2b88a Mon Sep 17 00:00:00 2001 From: DarkoGNU <42816979+DarkoGNU@users.noreply.github.com> Date: Sat, 7 May 2022 01:24:50 +0200 Subject: Implement ranged attack for snow golems. Fix failed assertion (#5417) * Implement ranged attack for snow golemas. Fix failed assertion when stopping the server * Decrease snowball speed * Adjust accuracy for snow golems * Use a getter instead of m_World --- Server/monsters.ini | 2 +- src/Mobs/SnowGolem.cpp | 37 +++++++++++++++++++++++++++++++++ src/Mobs/SnowGolem.h | 1 + src/WorldStorage/NBTChunkSerializer.cpp | 1 + 4 files changed, 40 insertions(+), 1 deletion(-) diff --git a/Server/monsters.ini b/Server/monsters.ini index 2cd5e8892..fb8f3babc 100644 --- a/Server/monsters.ini +++ b/Server/monsters.ini @@ -157,7 +157,7 @@ SightDistance=25.0 [SnowGolem] AttackDamage=0.0 -AttackRange=1.0 +AttackRange=10.0 AttackRate=1.0 MaxHealth=4 SightDistance=25.0 diff --git a/src/Mobs/SnowGolem.cpp b/src/Mobs/SnowGolem.cpp index 3b66311a1..fabcfb070 100644 --- a/src/Mobs/SnowGolem.cpp +++ b/src/Mobs/SnowGolem.cpp @@ -5,6 +5,7 @@ #include "SnowGolem.h" #include "../BlockInfo.h" #include "../World.h" +#include "../Entities/ThrownSnowballEntity.h" @@ -56,3 +57,39 @@ void cSnowGolem::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) } } } + + + + + +bool cSnowGolem::Attack(std::chrono::milliseconds a_Dt) +{ + UNUSED(a_Dt); + + // Comment inherited from skeletons + StopMovingToPosition(); // Todo handle this in a better way, the snowman does some uneeded recalcs due to inStateChasing + + if ((GetTarget() != nullptr) && (m_AttackCoolDownTicksLeft == 0)) + { + auto & Random = GetRandomProvider(); + Vector3d Inaccuracy = Vector3d(Random.RandReal(-0.75, 0.75), Random.RandReal(-0.75, 0.75), Random.RandReal(-0.75, 0.75)); + + // The projectile is launched from the head + const auto HeadPos = GetPosition().addedY(1.5); + // It aims around the head / chest + const auto TargetPos = GetTarget()->GetPosition().addedY(GetTarget()->GetHeight() * 0.75); + // With this data, we can calculate the speed + const auto Speed = (TargetPos + Inaccuracy - HeadPos) * 5; + + auto Snowball = std::make_unique(this, HeadPos, Speed); + auto SnowballPtr = Snowball.get(); + if (!SnowballPtr->Initialize(std::move(Snowball), *GetWorld())) + { + return false; + } + + ResetAttackCooldown(); + return true; + } + return false; +} diff --git a/src/Mobs/SnowGolem.h b/src/Mobs/SnowGolem.h index 8504965cb..6c6e88868 100644 --- a/src/Mobs/SnowGolem.h +++ b/src/Mobs/SnowGolem.h @@ -20,6 +20,7 @@ public: virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; + virtual bool Attack(std::chrono::milliseconds a_Dt) override; } ; diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index e50c70051..edb70e632 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -1064,6 +1064,7 @@ public: case cProjectileEntity::pkFireCharge: case cProjectileEntity::pkWitherSkull: case cProjectileEntity::pkEnderPearl: + case cProjectileEntity::pkSnowball: { break; } -- cgit v1.2.3