Fix mob attack interval
This commit is contained in:
parent
e2a053263f
commit
21df3cb0d8
@ -75,7 +75,6 @@ void cAggressiveMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
|
||||
if (TargetIsInRange() && !LineOfSight.Trace(MyHeadPosition, AttackDirection, static_cast<int>(AttackDirection.Length())) && (GetHealth() > 0.0))
|
||||
{
|
||||
// Attack if reached destination, target isn't null, and have a clear line of sight to target (so won't attack through walls)
|
||||
StopMovingToPosition();
|
||||
Attack(a_Dt);
|
||||
}
|
||||
}
|
||||
@ -86,14 +85,13 @@ void cAggressiveMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
|
||||
|
||||
bool cAggressiveMonster::Attack(std::chrono::milliseconds a_Dt)
|
||||
{
|
||||
m_AttackInterval += (static_cast<float>(a_Dt.count()) / 1000) * m_AttackRate;
|
||||
if ((m_Target == nullptr) || (m_AttackInterval < 3.0))
|
||||
if ((m_Target == nullptr) || (m_AttackCoolDownTicksLeft != 0))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Setting this higher gives us more wiggle room for attackrate
|
||||
m_AttackInterval = 0.0;
|
||||
ResetAttackCooldown();
|
||||
m_Target->TakeDamage(dtMobAttack, this, m_AttackDamage, 0);
|
||||
|
||||
return true;
|
||||
|
@ -34,9 +34,7 @@ void cBlaze::GetDrops(cItems & a_Drops, cEntity * a_Killer)
|
||||
|
||||
bool cBlaze::Attack(std::chrono::milliseconds a_Dt)
|
||||
{
|
||||
m_AttackInterval += (static_cast<float>(a_Dt.count()) / 1000) * m_AttackRate;
|
||||
|
||||
if ((m_Target != nullptr) && (m_AttackInterval > 3.0))
|
||||
if ((m_Target != nullptr) && (m_AttackCoolDownTicksLeft == 0))
|
||||
{
|
||||
// Setting this higher gives us more wiggle room for attackrate
|
||||
Vector3d Speed = GetLookVector() * 20;
|
||||
@ -53,7 +51,7 @@ bool cBlaze::Attack(std::chrono::milliseconds a_Dt)
|
||||
return false;
|
||||
}
|
||||
m_World->BroadcastSpawnEntity(*FireCharge);
|
||||
m_AttackInterval = 0.0;
|
||||
ResetAttackCooldown();
|
||||
// ToDo: Shoot 3 fireballs instead of 1.
|
||||
return true;
|
||||
}
|
||||
|
@ -34,9 +34,7 @@ void cGhast::GetDrops(cItems & a_Drops, cEntity * a_Killer)
|
||||
|
||||
bool cGhast::Attack(std::chrono::milliseconds a_Dt)
|
||||
{
|
||||
m_AttackInterval += (static_cast<float>(a_Dt.count()) / 1000) * m_AttackRate;
|
||||
|
||||
if ((m_Target != nullptr) && (m_AttackInterval > 3.0))
|
||||
if ((m_Target != nullptr) && (m_AttackCoolDownTicksLeft == 0))
|
||||
{
|
||||
// Setting this higher gives us more wiggle room for attackrate
|
||||
Vector3d Speed = GetLookVector() * 20;
|
||||
@ -53,8 +51,7 @@ bool cGhast::Attack(std::chrono::milliseconds a_Dt)
|
||||
return false;
|
||||
}
|
||||
m_World->BroadcastSpawnEntity(*GhastBall);
|
||||
m_AttackInterval = 0.0;
|
||||
|
||||
ResetAttackCooldown();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -88,7 +88,7 @@ cMonster::cMonster(const AString & a_ConfigName, eMonsterType a_MobType, const A
|
||||
, m_AttackRate(3)
|
||||
, m_AttackDamage(1)
|
||||
, m_AttackRange(1)
|
||||
, m_AttackInterval(0)
|
||||
, m_AttackCoolDownTicksLeft(0)
|
||||
, m_SightDistance(25)
|
||||
, m_DropChanceWeapon(0.085f)
|
||||
, m_DropChanceHelmet(0.085f)
|
||||
@ -214,6 +214,11 @@ void cMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
|
||||
super::Tick(a_Dt, a_Chunk);
|
||||
GET_AND_VERIFY_CURRENT_CHUNK(Chunk, POSX_TOINT, POSZ_TOINT);
|
||||
|
||||
if (m_AttackCoolDownTicksLeft > 0)
|
||||
{
|
||||
m_AttackCoolDownTicksLeft -= 1;
|
||||
}
|
||||
|
||||
if (m_Health <= 0)
|
||||
{
|
||||
// The mob is dead, but we're still animating the "puff" they leave when they die
|
||||
@ -690,6 +695,15 @@ void cMonster::InStateEscaping(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
|
||||
|
||||
|
||||
|
||||
void cMonster::ResetAttackCooldown()
|
||||
{
|
||||
m_AttackCoolDownTicksLeft = static_cast<int>(3 * 20 * m_AttackRate); // A second has 20 ticks, an attack rate of 1 means 1 hit every 3 seconds
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cMonster::SetCustomName(const AString & a_CustomName)
|
||||
{
|
||||
m_CustomName = a_CustomName;
|
||||
|
@ -101,6 +101,7 @@ public:
|
||||
void SetDropChanceLeggings(float a_DropChanceLeggings) { m_DropChanceLeggings = a_DropChanceLeggings; }
|
||||
void SetDropChanceBoots(float a_DropChanceBoots) { m_DropChanceBoots = a_DropChanceBoots; }
|
||||
void SetCanPickUpLoot(bool a_CanPickUpLoot) { m_CanPickUpLoot = a_CanPickUpLoot; }
|
||||
void ResetAttackCooldown();
|
||||
|
||||
/** Sets whether the mob burns in daylight. Only evaluated at next burn-decision tick */
|
||||
void SetBurnsInDaylight(bool a_BurnsInDaylight) { m_BurnsInDaylight = a_BurnsInDaylight; }
|
||||
@ -220,7 +221,7 @@ protected:
|
||||
float m_AttackRate;
|
||||
int m_AttackDamage;
|
||||
int m_AttackRange;
|
||||
float m_AttackInterval;
|
||||
int m_AttackCoolDownTicksLeft;
|
||||
int m_SightDistance;
|
||||
|
||||
float m_DropChanceWeapon;
|
||||
|
@ -50,9 +50,9 @@ void cSkeleton::GetDrops(cItems & a_Drops, cEntity * a_Killer)
|
||||
|
||||
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
|
||||
cFastRandom Random;
|
||||
m_AttackInterval += (static_cast<float>(a_Dt.count()) / 1000) * m_AttackRate;
|
||||
if ((m_Target != nullptr) && (m_AttackInterval > 3.0))
|
||||
if ((m_Target != nullptr) && (m_AttackCoolDownTicksLeft == 0))
|
||||
{
|
||||
Vector3d Inaccuracy = Vector3d(Random.NextFloat(0.5) - 0.25, Random.NextFloat(0.5) - 0.25, Random.NextFloat(0.5) - 0.25);
|
||||
Vector3d Speed = (m_Target->GetPosition() + Inaccuracy - GetPosition()) * 5;
|
||||
@ -69,8 +69,8 @@ bool cSkeleton::Attack(std::chrono::milliseconds a_Dt)
|
||||
return false;
|
||||
}
|
||||
m_World->BroadcastSpawnEntity(*Arrow);
|
||||
m_AttackInterval = 0.0;
|
||||
|
||||
ResetAttackCooldown();
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -228,15 +228,11 @@ void cWolf::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
|
||||
}
|
||||
else
|
||||
{
|
||||
MoveToPosition(m_Target->GetPosition());
|
||||
if (TargetIsInRange())
|
||||
{
|
||||
StopMovingToPosition();
|
||||
Attack(a_Dt);
|
||||
}
|
||||
else
|
||||
{
|
||||
MoveToPosition(m_Target->GetPosition());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user