Merge pull request #2859 from LogicParrot/attack2
Fix mob attack interval
This commit is contained in:
commit
d4e99aedb1
@ -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))
|
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)
|
// 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);
|
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)
|
bool cAggressiveMonster::Attack(std::chrono::milliseconds a_Dt)
|
||||||
{
|
{
|
||||||
m_AttackInterval += (static_cast<float>(a_Dt.count()) / 1000) * m_AttackRate;
|
if ((m_Target == nullptr) || (m_AttackCoolDownTicksLeft != 0))
|
||||||
if ((m_Target == nullptr) || (m_AttackInterval < 3.0))
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setting this higher gives us more wiggle room for attackrate
|
// Setting this higher gives us more wiggle room for attackrate
|
||||||
m_AttackInterval = 0.0;
|
ResetAttackCooldown();
|
||||||
m_Target->TakeDamage(dtMobAttack, this, m_AttackDamage, 0);
|
m_Target->TakeDamage(dtMobAttack, this, m_AttackDamage, 0);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -34,9 +34,7 @@ void cBlaze::GetDrops(cItems & a_Drops, cEntity * a_Killer)
|
|||||||
|
|
||||||
bool cBlaze::Attack(std::chrono::milliseconds a_Dt)
|
bool cBlaze::Attack(std::chrono::milliseconds a_Dt)
|
||||||
{
|
{
|
||||||
m_AttackInterval += (static_cast<float>(a_Dt.count()) / 1000) * m_AttackRate;
|
if ((m_Target != nullptr) && (m_AttackCoolDownTicksLeft == 0))
|
||||||
|
|
||||||
if ((m_Target != nullptr) && (m_AttackInterval > 3.0))
|
|
||||||
{
|
{
|
||||||
// Setting this higher gives us more wiggle room for attackrate
|
// Setting this higher gives us more wiggle room for attackrate
|
||||||
Vector3d Speed = GetLookVector() * 20;
|
Vector3d Speed = GetLookVector() * 20;
|
||||||
@ -53,7 +51,7 @@ bool cBlaze::Attack(std::chrono::milliseconds a_Dt)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_World->BroadcastSpawnEntity(*FireCharge);
|
m_World->BroadcastSpawnEntity(*FireCharge);
|
||||||
m_AttackInterval = 0.0;
|
ResetAttackCooldown();
|
||||||
// ToDo: Shoot 3 fireballs instead of 1.
|
// ToDo: Shoot 3 fireballs instead of 1.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -34,9 +34,7 @@ void cGhast::GetDrops(cItems & a_Drops, cEntity * a_Killer)
|
|||||||
|
|
||||||
bool cGhast::Attack(std::chrono::milliseconds a_Dt)
|
bool cGhast::Attack(std::chrono::milliseconds a_Dt)
|
||||||
{
|
{
|
||||||
m_AttackInterval += (static_cast<float>(a_Dt.count()) / 1000) * m_AttackRate;
|
if ((m_Target != nullptr) && (m_AttackCoolDownTicksLeft == 0))
|
||||||
|
|
||||||
if ((m_Target != nullptr) && (m_AttackInterval > 3.0))
|
|
||||||
{
|
{
|
||||||
// Setting this higher gives us more wiggle room for attackrate
|
// Setting this higher gives us more wiggle room for attackrate
|
||||||
Vector3d Speed = GetLookVector() * 20;
|
Vector3d Speed = GetLookVector() * 20;
|
||||||
@ -53,8 +51,7 @@ bool cGhast::Attack(std::chrono::milliseconds a_Dt)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_World->BroadcastSpawnEntity(*GhastBall);
|
m_World->BroadcastSpawnEntity(*GhastBall);
|
||||||
m_AttackInterval = 0.0;
|
ResetAttackCooldown();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -88,7 +88,7 @@ cMonster::cMonster(const AString & a_ConfigName, eMonsterType a_MobType, const A
|
|||||||
, m_AttackRate(3)
|
, m_AttackRate(3)
|
||||||
, m_AttackDamage(1)
|
, m_AttackDamage(1)
|
||||||
, m_AttackRange(1)
|
, m_AttackRange(1)
|
||||||
, m_AttackInterval(0)
|
, m_AttackCoolDownTicksLeft(0)
|
||||||
, m_SightDistance(25)
|
, m_SightDistance(25)
|
||||||
, m_DropChanceWeapon(0.085f)
|
, m_DropChanceWeapon(0.085f)
|
||||||
, m_DropChanceHelmet(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);
|
super::Tick(a_Dt, a_Chunk);
|
||||||
GET_AND_VERIFY_CURRENT_CHUNK(Chunk, POSX_TOINT, POSZ_TOINT);
|
GET_AND_VERIFY_CURRENT_CHUNK(Chunk, POSX_TOINT, POSZ_TOINT);
|
||||||
|
|
||||||
|
if (m_AttackCoolDownTicksLeft > 0)
|
||||||
|
{
|
||||||
|
m_AttackCoolDownTicksLeft -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_Health <= 0)
|
if (m_Health <= 0)
|
||||||
{
|
{
|
||||||
// The mob is dead, but we're still animating the "puff" they leave when they die
|
// 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)
|
void cMonster::SetCustomName(const AString & a_CustomName)
|
||||||
{
|
{
|
||||||
m_CustomName = a_CustomName;
|
m_CustomName = a_CustomName;
|
||||||
|
@ -101,6 +101,7 @@ public:
|
|||||||
void SetDropChanceLeggings(float a_DropChanceLeggings) { m_DropChanceLeggings = a_DropChanceLeggings; }
|
void SetDropChanceLeggings(float a_DropChanceLeggings) { m_DropChanceLeggings = a_DropChanceLeggings; }
|
||||||
void SetDropChanceBoots(float a_DropChanceBoots) { m_DropChanceBoots = a_DropChanceBoots; }
|
void SetDropChanceBoots(float a_DropChanceBoots) { m_DropChanceBoots = a_DropChanceBoots; }
|
||||||
void SetCanPickUpLoot(bool a_CanPickUpLoot) { m_CanPickUpLoot = a_CanPickUpLoot; }
|
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 */
|
/** Sets whether the mob burns in daylight. Only evaluated at next burn-decision tick */
|
||||||
void SetBurnsInDaylight(bool a_BurnsInDaylight) { m_BurnsInDaylight = a_BurnsInDaylight; }
|
void SetBurnsInDaylight(bool a_BurnsInDaylight) { m_BurnsInDaylight = a_BurnsInDaylight; }
|
||||||
@ -220,7 +221,7 @@ protected:
|
|||||||
float m_AttackRate;
|
float m_AttackRate;
|
||||||
int m_AttackDamage;
|
int m_AttackDamage;
|
||||||
int m_AttackRange;
|
int m_AttackRange;
|
||||||
float m_AttackInterval;
|
int m_AttackCoolDownTicksLeft;
|
||||||
int m_SightDistance;
|
int m_SightDistance;
|
||||||
|
|
||||||
float m_DropChanceWeapon;
|
float m_DropChanceWeapon;
|
||||||
|
@ -50,9 +50,9 @@ void cSkeleton::GetDrops(cItems & a_Drops, cEntity * a_Killer)
|
|||||||
|
|
||||||
bool cSkeleton::Attack(std::chrono::milliseconds a_Dt)
|
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;
|
cFastRandom Random;
|
||||||
m_AttackInterval += (static_cast<float>(a_Dt.count()) / 1000) * m_AttackRate;
|
if ((m_Target != nullptr) && (m_AttackCoolDownTicksLeft == 0))
|
||||||
if ((m_Target != nullptr) && (m_AttackInterval > 3.0))
|
|
||||||
{
|
{
|
||||||
Vector3d Inaccuracy = Vector3d(Random.NextFloat(0.5) - 0.25, Random.NextFloat(0.5) - 0.25, Random.NextFloat(0.5) - 0.25);
|
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;
|
Vector3d Speed = (m_Target->GetPosition() + Inaccuracy - GetPosition()) * 5;
|
||||||
@ -69,8 +69,8 @@ bool cSkeleton::Attack(std::chrono::milliseconds a_Dt)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_World->BroadcastSpawnEntity(*Arrow);
|
m_World->BroadcastSpawnEntity(*Arrow);
|
||||||
m_AttackInterval = 0.0;
|
ResetAttackCooldown();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -241,15 +241,11 @@ void cWolf::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
MoveToPosition(m_Target->GetPosition());
|
||||||
if (TargetIsInRange())
|
if (TargetIsInRange())
|
||||||
{
|
{
|
||||||
StopMovingToPosition();
|
|
||||||
Attack(a_Dt);
|
Attack(a_Dt);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
MoveToPosition(m_Target->GetPosition());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user