Add skeleton bow pulling animation (#5355)

* Added basic skeleton bow animation

* Fixing style
This commit is contained in:
Persson-dev 2021-12-29 20:30:09 +01:00 committed by GitHub
parent fec64bb91c
commit 1edc6c8601
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 106 additions and 6 deletions

View File

@ -10,7 +10,8 @@
cSkeleton::cSkeleton(void) :
Super("Skeleton", mtSkeleton, "entity.skeleton.hurt", "entity.skeleton.death", "entity.skeleton.ambient", 0.6f, 1.99f)
Super("Skeleton", mtSkeleton, "entity.skeleton.hurt", "entity.skeleton.death", "entity.skeleton.ambient", 0.6f, 1.99f),
m_ChargingBow(false)
{
}
@ -36,10 +37,40 @@ void cSkeleton::GetDrops(cItems & a_Drops, cEntity * a_Killer)
void cSkeleton::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
Super::Tick(a_Dt, a_Chunk);
if (!IsTicking())
{
// The base class tick destroyed us
return;
}
if (m_ChargingBow && (m_EMState == IDLE))
{
// releasing bow if no more target is found
m_ChargingBow = false;
m_World->BroadcastEntityMetadata(*this);
}
}
bool cSkeleton::Attack(std::chrono::milliseconds a_Dt)
{
StopMovingToPosition(); // Todo handle this in a better way, the skeleton does some uneeded recalcs due to inStateChasing
auto & Random = GetRandomProvider();
if (!m_ChargingBow)
{
// updating pulling animation
m_ChargingBow = true;
m_World->BroadcastEntityMetadata(*this);
}
if ((GetTarget() != nullptr) && (m_AttackCoolDownTicksLeft == 0))
{
Vector3d Inaccuracy = Vector3d(Random.RandReal<double>(-0.25, 0.25), Random.RandReal<double>(-0.25, 0.25), Random.RandReal<double>(-0.25, 0.25));
@ -53,6 +84,10 @@ bool cSkeleton::Attack(std::chrono::milliseconds a_Dt)
return false;
}
// releasing bow after arrow was shot
m_ChargingBow = false;
m_World->BroadcastEntityMetadata(*this);
ResetAttackCooldown();
return true;
}

View File

@ -18,10 +18,18 @@ public:
CLASS_PROTODEF(cSkeleton)
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;
virtual void SpawnOn(cClientHandle & a_ClientHandle) override;
virtual bool IsUndead(void) override { return true; }
bool IsChargingBow() const { return m_ChargingBow; }
private:
bool m_ChargingBow;
} ;

View File

@ -795,6 +795,19 @@ void cProtocol_1_10_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_
break;
} // case mtSheep
case mtSkeleton:
{
auto & Skeleton = static_cast<const cSkeleton &>(a_Mob);
a_Pkt.WriteBEUInt8(LIVING_ACTIVE_HAND);
a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE);
a_Pkt.WriteBEUInt8(Skeleton.IsChargingBow() ? 0x01 : 0x00);
a_Pkt.WriteBEUInt8(SKELETON_ARMS_SWINGING);
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
a_Pkt.WriteBool(Skeleton.IsChargingBow());
break;
} // case mtSkeleton
case mtSlime:
{
auto & Slime = static_cast<const cSlime &>(a_Mob);
@ -958,7 +971,6 @@ void cProtocol_1_10_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_
case mtIronGolem:
case mtMooshroom:
case mtSilverfish:
case mtSkeleton:
case mtSnowGolem:
case mtStray:
case mtSpider:

View File

@ -1102,6 +1102,19 @@ void cProtocol_1_11_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_
break;
} // case mtSheep
case mtSkeleton:
{
auto & Skeleton = static_cast<const cSkeleton &>(a_Mob);
a_Pkt.WriteBEUInt8(LIVING_ACTIVE_HAND);
a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE);
a_Pkt.WriteBEUInt8(Skeleton.IsChargingBow() ? 0x01 : 0x00);
a_Pkt.WriteBEUInt8(ABSTRACT_SKELETON_ARMS_SWINGING);
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
a_Pkt.WriteBool(Skeleton.IsChargingBow());
break;
} // case mtSkeleton
case mtSlime:
{
auto & Slime = static_cast<const cSlime &>(a_Mob);
@ -1260,7 +1273,6 @@ void cProtocol_1_11_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_
case mtIronGolem:
case mtMooshroom:
case mtSilverfish:
case mtSkeleton:
case mtStray:
case mtSpider:
case mtSquid:

View File

@ -788,6 +788,19 @@ void cProtocol_1_12::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mo
break;
} // case mtSheep
case mtSkeleton:
{
auto & Skeleton = static_cast<const cSkeleton &>(a_Mob);
a_Pkt.WriteBEUInt8(LIVING_ACTIVE_HAND);
a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE);
a_Pkt.WriteBEUInt8(Skeleton.IsChargingBow() ? 0x01 : 0x00);
a_Pkt.WriteBEUInt8(ABSTRACT_SKELETON_ARMS_SWINGING);
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
a_Pkt.WriteBool(Skeleton.IsChargingBow());
break;
} // case mtSkeleton
case mtSlime:
{
auto & Slime = static_cast<const cSlime &>(a_Mob);
@ -967,7 +980,6 @@ void cProtocol_1_12::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mo
case mtGiant:
case mtSilverfish:
case mtSkeleton:
case mtSquid:
{
// Mobs with no extra fields

View File

@ -337,6 +337,7 @@ UInt8 cProtocol_1_13::GetEntityMetadataID(EntityMetadata a_Metadata) const
case EntityMetadata::IllagerFlags: return Insentient;
case EntityMetadata::SpeIlagerSpell: return Insentient + 1;
case EntityMetadata::VexFlags: return Insentient;
case EntityMetadata::AbstractSkeletonArmsSwinging: return Insentient;
case EntityMetadata::SpiderClimbing: return Insentient;
case EntityMetadata::WitchAggresive: return Insentient;
case EntityMetadata::WitherFirstHeadTarget: return Insentient;
@ -366,7 +367,6 @@ UInt8 cProtocol_1_13::GetEntityMetadataID(EntityMetadata a_Metadata) const
case EntityMetadata::EntityPose:
case EntityMetadata::AreaEffectCloudParticleParameter1:
case EntityMetadata::AreaEffectCloudParticleParameter2:
case EntityMetadata::AbstractSkeletonArmsSwinging:
case EntityMetadata::ZombieUnusedWasType: break;
}
UNREACHABLE("Retrieved invalid metadata for protocol");
@ -1184,6 +1184,17 @@ void cProtocol_1_13::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mo
break;
} // case mtSheep
case mtSkeleton:
{
auto & Skeleton = static_cast<const cSkeleton &>(a_Mob);
WriteEntityMetadata(a_Pkt, EntityMetadata::LivingActiveHand, EntityMetadataType::Byte);
a_Pkt.WriteBEUInt8(Skeleton.IsChargingBow() ? 0x01 : 0x00);
WriteEntityMetadata(a_Pkt, EntityMetadata::AbstractSkeletonArmsSwinging, EntityMetadataType::Boolean);
a_Pkt.WriteBool(Skeleton.IsChargingBow());
break;
} // case mtSkeleton
case mtSlime:
{
auto & Slime = static_cast<const cSlime &>(a_Mob);
@ -1354,7 +1365,6 @@ void cProtocol_1_13::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mo
case mtGiant:
case mtSilverfish:
case mtSkeleton:
case mtSquid:
case mtWitherSkeleton:
{

View File

@ -2110,9 +2110,20 @@ void cProtocol_1_9_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_M
case mtSkeleton:
{
auto & Skeleton = static_cast<const cSkeleton &>(a_Mob);
a_Pkt.WriteBEUInt8(11);
a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
a_Pkt.WriteVarInt32(0);
// Index 5 and 12 used for charging bow client animation.
a_Pkt.WriteBEUInt8(5);
a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE);
a_Pkt.WriteBEInt8(0x02 | (Skeleton.IsChargingBow() ? 0x01 : 0x00));
a_Pkt.WriteBEUInt8(12);
a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE);
a_Pkt.WriteBool(Skeleton.IsChargingBow());
break;
}
case mtSlime: