Merge pull request #1808 from tumultenrx/master
Monsters will now attack. Additional checks have been added when generating spawn.
This commit is contained in:
commit
ebf0126dc9
@ -85,7 +85,7 @@ void cAggressiveMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
|
||||
if (ReachedFinalDestination() && !LineOfSight.Trace(GetPosition(), AttackDirection, (int)AttackDirection.Length()))
|
||||
{
|
||||
// Attack if reached destination, target isn't null, and have a clear line of sight to target (so won't attack through walls)
|
||||
Attack(a_Dt / 1000);
|
||||
Attack(a_Dt);
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,8 +95,7 @@ void cAggressiveMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
|
||||
|
||||
void cAggressiveMonster::Attack(std::chrono::milliseconds a_Dt)
|
||||
{
|
||||
m_AttackInterval += a_Dt.count() * m_AttackRate;
|
||||
|
||||
m_AttackInterval += (static_cast<float>(a_Dt.count()) / 1000) * m_AttackRate;
|
||||
if ((m_Target == nullptr) || (m_AttackInterval < 3.0))
|
||||
{
|
||||
return;
|
||||
|
@ -32,7 +32,7 @@ void cBlaze::GetDrops(cItems & a_Drops, cEntity * a_Killer)
|
||||
|
||||
void cBlaze::Attack(std::chrono::milliseconds a_Dt)
|
||||
{
|
||||
m_AttackInterval += a_Dt.count() * m_AttackRate;
|
||||
m_AttackInterval += (static_cast<float>(a_Dt.count()) / 1000) * m_AttackRate;
|
||||
|
||||
if ((m_Target != nullptr) && (m_AttackInterval > 3.0))
|
||||
{
|
||||
|
@ -34,7 +34,7 @@ void cGhast::GetDrops(cItems & a_Drops, cEntity * a_Killer)
|
||||
|
||||
void cGhast::Attack(std::chrono::milliseconds a_Dt)
|
||||
{
|
||||
m_AttackInterval += a_Dt.count() * m_AttackRate;
|
||||
m_AttackInterval += (static_cast<float>(a_Dt.count()) / 1000) * m_AttackRate;
|
||||
|
||||
if ((m_Target != nullptr) && (m_AttackInterval > 3.0))
|
||||
{
|
||||
|
@ -69,8 +69,7 @@ void cSkeleton::MoveToPosition(const Vector3d & a_Position)
|
||||
|
||||
void cSkeleton::Attack(std::chrono::milliseconds a_Dt)
|
||||
{
|
||||
m_AttackInterval += a_Dt.count() * m_AttackRate;
|
||||
|
||||
m_AttackInterval += (static_cast<float>(a_Dt.count()) / 1000) * m_AttackRate;
|
||||
if ((m_Target != nullptr) && (m_AttackInterval > 3.0))
|
||||
{
|
||||
// Setting this higher gives us more wiggle room for attackrate
|
||||
|
@ -667,18 +667,23 @@ void cWorld::Start(void)
|
||||
void cWorld::GenerateRandomSpawn(void)
|
||||
{
|
||||
LOGD("Generating random spawnpoint...");
|
||||
|
||||
bool foundSpawnPoint = false;
|
||||
// Look for a spawn point at most 100 chunks away from map center:
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
EMCSBiome biome = GetBiomeAt((int)m_SpawnX, (int)m_SpawnZ);
|
||||
|
||||
if (
|
||||
(biome != biOcean) && (biome != biFrozenOcean) && // The biome is acceptable (don't want a small ocean island)
|
||||
!IsBlockWaterOrIce(GetBlock((int)m_SpawnX, GetHeight((int)m_SpawnX, (int)m_SpawnZ), (int)m_SpawnZ)) // The terrain is acceptable (don't want to spawn inside a lake / river)
|
||||
)
|
||||
{
|
||||
// A good spawnpoint was found
|
||||
break;
|
||||
if (CheckPlayerSpawnPoint((int)m_SpawnX, GetHeight((int)m_SpawnX, (int)m_SpawnZ), (int)m_SpawnZ))
|
||||
{
|
||||
// A good spawnpoint was found
|
||||
foundSpawnPoint = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Try a neighboring chunk:
|
||||
if ((GetTickRandomNumber(4) % 2) == 0) // Randomise whether to increment X or Z coords
|
||||
@ -692,8 +697,63 @@ void cWorld::GenerateRandomSpawn(void)
|
||||
} // for i - 100*
|
||||
|
||||
m_SpawnY = (double)GetHeight((int)m_SpawnX, (int)m_SpawnZ) + 1.6f; // 1.6f to accomodate player height
|
||||
if (foundSpawnPoint)
|
||||
{
|
||||
LOGINFO("Generated random spawnpoint position at {%i, %i, %i}", (int)m_SpawnX, (int)m_SpawnY, (int)m_SpawnZ);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGINFO("Did not find an acceptable spawnpoint. Generated a random spawnpoint position at {%i, %i, %i}", (int)m_SpawnX, (int)m_SpawnY, (int)m_SpawnZ);
|
||||
} // Maybe widen the search instead?
|
||||
|
||||
LOGINFO("Generated random spawnpoint position {%i, %i, %i}", (int)m_SpawnX, (int)m_SpawnY, (int)m_SpawnZ);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cWorld::CheckPlayerSpawnPoint(int a_PosX, int a_PosY, int a_PosZ)
|
||||
{
|
||||
static const struct
|
||||
{
|
||||
int x, z;
|
||||
} Coords[] =
|
||||
{
|
||||
{ 0, 0 },
|
||||
{ -1, 0 },
|
||||
{ 1, 0 },
|
||||
{ 0, -1 },
|
||||
{ 0, 1 },
|
||||
};
|
||||
|
||||
// Checking that spawnblock and surrounding blocks are air and not water/lava
|
||||
for (size_t i = 0; i < ARRAYCOUNT(Coords); i++)
|
||||
{
|
||||
BLOCKTYPE BlockType = GetBlock(a_PosX + Coords[i].x, a_PosY, a_PosZ + Coords[i].x);
|
||||
|
||||
if (cBlockInfo::IsSolid(BlockType) || IsBlockLiquid(BlockType))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
} // for i - Coords[]
|
||||
|
||||
// Check if block below is solid
|
||||
BLOCKTYPE BlockType = GetBlock(a_PosX, a_PosY - 1, a_PosZ);
|
||||
if (!cBlockInfo::IsSolid(BlockType))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Checking that all the blocks above the spawnpoint is air.
|
||||
for (int i = a_PosY; i < cChunkDef::Height; i++)
|
||||
{
|
||||
BLOCKTYPE BlockType = GetBlock(a_PosX, i, a_PosZ);
|
||||
if (cBlockInfo::IsSolid(BlockType))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1077,6 +1077,9 @@ private:
|
||||
/** <summary>Generates a random spawnpoint on solid land by walking chunks and finding their biomes</summary> */
|
||||
void GenerateRandomSpawn(void);
|
||||
|
||||
/** Check if player starting point is acceptable **/
|
||||
bool CheckPlayerSpawnPoint(int a_PosX, int a_PosY, int a_PosZ);
|
||||
|
||||
/** Chooses a reasonable transition from the current weather to a new weather **/
|
||||
eWeather ChooseNewWeather(void);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user