1
0
Fork 0

Fix mob attack interval

This commit is contained in:
LogicParrot 2016-01-12 12:11:10 +02:00
parent e2a053263f
commit 21df3cb0d8
7 changed files with 28 additions and 24 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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());
}
}
}