Unified the way mobs are spawned (egg vs natural). Fixed deadlocks in mob moving. Fixed mob destroying code.
Should fix FS #400 and partially fix FS #381 git-svn-id: http://mc-server.googlecode.com/svn/trunk@1626 0a769ca7-a7f5-676a-18bf-c427514a06d6master
parent
ce1a56836a
commit
4fe7801cfc
|
@ -123,7 +123,7 @@ cChunk::~cChunk()
|
||||||
{
|
{
|
||||||
if (!(*itr)->IsPlayer())
|
if (!(*itr)->IsPlayer())
|
||||||
{
|
{
|
||||||
(*itr)->Destroy();
|
(*itr)->Destroy(false);
|
||||||
delete *itr;
|
delete *itr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -173,13 +173,17 @@ void cEntity::WrapSpeed(void)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cEntity::Destroy(void)
|
void cEntity::Destroy(bool a_ShouldBroadcast)
|
||||||
{
|
{
|
||||||
if (!m_IsInitialized)
|
if (!m_IsInitialized)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (a_ShouldBroadcast)
|
||||||
|
{
|
||||||
m_World->BroadcastDestroyEntity(*this);
|
m_World->BroadcastDestroyEntity(*this);
|
||||||
|
}
|
||||||
|
|
||||||
m_IsInitialized = false;
|
m_IsInitialized = false;
|
||||||
|
|
||||||
|
|
|
@ -161,7 +161,8 @@ public:
|
||||||
inline int GetUniqueID(void) const { return m_UniqueID; }
|
inline int GetUniqueID(void) const { return m_UniqueID; }
|
||||||
inline bool IsDestroyed(void) const { return !m_IsInitialized; }
|
inline bool IsDestroyed(void) const { return !m_IsInitialized; }
|
||||||
|
|
||||||
void Destroy(void);
|
/// Schedules the entity for destroying; if a_ShouldBroadcast is set to true, broadcasts the DestroyEntity packet
|
||||||
|
void Destroy(bool a_ShouldBroadcast = true);
|
||||||
|
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ void cFallingBlock::Tick(float a_Dt, cChunk & a_Chunk)
|
||||||
// Fallen out of this world, just continue falling until out of sight, then destroy:
|
// Fallen out of this world, just continue falling until out of sight, then destroy:
|
||||||
if (BlockY < 100)
|
if (BlockY < 100)
|
||||||
{
|
{
|
||||||
Destroy();
|
Destroy(true);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ void cFallingBlock::Tick(float a_Dt, cChunk & a_Chunk)
|
||||||
// Fallen onto a block that breaks this into pickups (e. g. half-slab)
|
// Fallen onto a block that breaks this into pickups (e. g. half-slab)
|
||||||
// Must finish the fall with coords one below the block:
|
// Must finish the fall with coords one below the block:
|
||||||
cSandSimulator::FinishFalling(m_World, BlockX, BlockY, BlockZ, m_BlockType, m_BlockMeta);
|
cSandSimulator::FinishFalling(m_World, BlockX, BlockY, BlockZ, m_BlockType, m_BlockMeta);
|
||||||
Destroy();
|
Destroy(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (!cSandSimulator::CanContinueFallThrough(BlockBelow))
|
else if (!cSandSimulator::CanContinueFallThrough(BlockBelow))
|
||||||
|
@ -93,7 +93,7 @@ void cFallingBlock::Tick(float a_Dt, cChunk & a_Chunk)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
cSandSimulator::FinishFalling(m_World, BlockX, BlockY + 1, BlockZ, m_BlockType, m_BlockMeta);
|
cSandSimulator::FinishFalling(m_World, BlockX, BlockY + 1, BlockZ, m_BlockType, m_BlockMeta);
|
||||||
Destroy();
|
Destroy(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,7 +95,7 @@ void cMonster::Tick(float a_Dt, cChunk & a_Chunk)
|
||||||
m_DestroyTimer += a_Dt / 1000;
|
m_DestroyTimer += a_Dt / 1000;
|
||||||
if (m_DestroyTimer > 1)
|
if (m_DestroyTimer > 1)
|
||||||
{
|
{
|
||||||
Destroy();
|
Destroy(true);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -134,7 +134,12 @@ void cMonster::Tick(float a_Dt, cChunk & a_Chunk)
|
||||||
{
|
{
|
||||||
Vector3f NormSpeed = Vector3f(GetSpeed()).NormalizeCopy();
|
Vector3f NormSpeed = Vector3f(GetSpeed()).NormalizeCopy();
|
||||||
Vector3f NextBlock = Vector3f( GetPosition() ) + NormSpeed;
|
Vector3f NextBlock = Vector3f( GetPosition() ) + NormSpeed;
|
||||||
double NextHeight = (double)GetWorld()->GetHeight( (int)NextBlock.x, (int)NextBlock.z );
|
int NextHeight;
|
||||||
|
if (!m_World->TryGetHeight((int)NextBlock.x, (int)NextBlock.z, NextHeight))
|
||||||
|
{
|
||||||
|
// The chunk at NextBlock is not loaded
|
||||||
|
return;
|
||||||
|
}
|
||||||
if( NextHeight > (GetPosY() - 1.0) && (NextHeight - GetPosY()) < 2.5 )
|
if( NextHeight > (GetPosY() - 1.0) && (NextHeight - GetPosY()) < 2.5 )
|
||||||
{
|
{
|
||||||
m_bOnGround = false;
|
m_bOnGround = false;
|
||||||
|
|
|
@ -93,7 +93,7 @@ void cPickup::Tick(float a_Dt, cChunk & a_Chunk)
|
||||||
m_Timer += a_Dt; // In case we have to destroy the pickup in the same tick.
|
m_Timer += a_Dt; // In case we have to destroy the pickup in the same tick.
|
||||||
if (m_Timer > 500.f)
|
if (m_Timer > 500.f)
|
||||||
{
|
{
|
||||||
Destroy();
|
Destroy(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,20 +104,20 @@ void cPickup::Tick(float a_Dt, cChunk & a_Chunk)
|
||||||
{
|
{
|
||||||
if (m_Timer > 500.f) // 0.5 second
|
if (m_Timer > 500.f) // 0.5 second
|
||||||
{
|
{
|
||||||
Destroy();
|
Destroy(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_Timer > 1000 * 60 * 5) // 5 minutes
|
if (m_Timer > 1000 * 60 * 5) // 5 minutes
|
||||||
{
|
{
|
||||||
Destroy();
|
Destroy(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetPosY() < -8) // Out of this world and no more visible!
|
if (GetPosY() < -8) // Out of this world and no more visible!
|
||||||
{
|
{
|
||||||
Destroy();
|
Destroy(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ void cTNTEntity::Tick(float a_Dt, cChunk & a_Chunk)
|
||||||
m_Counter += delta_time;
|
m_Counter += delta_time;
|
||||||
if (m_Counter > m_MaxFuseTime) // Check if we go KABOOOM
|
if (m_Counter > m_MaxFuseTime) // Check if we go KABOOOM
|
||||||
{
|
{
|
||||||
Destroy();
|
Destroy(true);
|
||||||
LOGD("BOOM at {%f,%f,%f}", GetPosX(), GetPosY(), GetPosZ());
|
LOGD("BOOM at {%f,%f,%f}", GetPosX(), GetPosY(), GetPosZ());
|
||||||
m_World->DoExplosiontAt(4.0, (int)floor(GetPosX()), (int)floor(GetPosY()), (int)floor(GetPosZ()));
|
m_World->DoExplosiontAt(4.0, (int)floor(GetPosX()), (int)floor(GetPosY()), (int)floor(GetPosZ()));
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -621,65 +621,55 @@ void cWorld::TickSpawnMobs(float a_Dt)
|
||||||
SpawnPos = (*itr)->GetPosition();
|
SpawnPos = (*itr)->GetPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
cMonster * Monster = NULL;
|
int dayRand = (m_TickRand.randInt() / 7) % 6;
|
||||||
int dayRand = m_TickRand.randInt() % 6;
|
int nightRand = (m_TickRand.randInt() / 11) % 10;
|
||||||
int nightRand = m_TickRand.randInt() % 10;
|
|
||||||
|
|
||||||
SpawnPos += Vector3d((double)(m_TickRand.randInt() % 64) - 32, (double)(m_TickRand.randInt() % 64) - 32, (double)(m_TickRand.randInt() % 64) - 32);
|
SpawnPos += Vector3d((double)(m_TickRand.randInt() % 64) - 32, (double)(m_TickRand.randInt() % 64) - 32, (double)(m_TickRand.randInt() % 64) - 32);
|
||||||
int Height = GetHeight((int)SpawnPos.x, (int)SpawnPos.z);
|
int Height = GetHeight((int)SpawnPos.x, (int)SpawnPos.z);
|
||||||
|
|
||||||
|
int MobType = -1;
|
||||||
if (m_TimeOfDay >= 12000 + 1000)
|
if (m_TimeOfDay >= 12000 + 1000)
|
||||||
{
|
{
|
||||||
if (GetBiomeAt((int)SpawnPos.x, (int)SpawnPos.z) == biHell) // Spawn nether mobs
|
if (GetBiomeAt((int)SpawnPos.x, (int)SpawnPos.z) == biHell) // Spawn nether mobs
|
||||||
{
|
{
|
||||||
if (nightRand == 1)
|
switch (nightRand)
|
||||||
Monster = new cZombie();
|
{
|
||||||
else if (nightRand == 5)
|
case 1: MobType = E_ENTITY_TYPE_ZOMBIE; break; // _X 2013_06_25: Really? Zombies in the Nether?
|
||||||
Monster = new cGhast();
|
case 5: MobType = E_ENTITY_TYPE_GHAST; break;
|
||||||
else if (nightRand == 6)
|
case 6: MobType = E_ENTITY_TYPE_ZOMBIE_PIGMAN; break;
|
||||||
Monster = new cZombiepigman();
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (nightRand == 0) //random percent to spawn for night
|
switch (nightRand)
|
||||||
Monster = new cSpider();
|
{
|
||||||
else if (nightRand == 2)
|
case 0: MobType = E_ENTITY_TYPE_SPIDER; break;
|
||||||
Monster = new cEnderman();
|
case 2: MobType = E_ENTITY_TYPE_ENDERMAN; break;
|
||||||
else if (nightRand == 3)
|
case 3: MobType = E_ENTITY_TYPE_CREEPER; break;
|
||||||
Monster = new cCreeper();
|
case 4: MobType = E_ENTITY_TYPE_CAVE_SPIDER; break;
|
||||||
else if (nightRand == 4)
|
case 7: MobType = E_ENTITY_TYPE_SLIME; break;
|
||||||
Monster = new cCavespider();
|
case 8: MobType = E_ENTITY_TYPE_SILVERFISH; break;
|
||||||
else if (nightRand == 7)
|
case 9: MobType = E_ENTITY_TYPE_SKELETON; break;
|
||||||
Monster = new cSlime();
|
}
|
||||||
else if (nightRand == 8)
|
|
||||||
Monster = new cSilverfish();
|
|
||||||
else if (nightRand == 9)
|
|
||||||
Monster = new cSkeleton();
|
|
||||||
}
|
}
|
||||||
//end random percent to spawn for night
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (dayRand == 0) //random percent to spawn for day
|
switch (dayRand)
|
||||||
Monster = new cChicken();
|
{
|
||||||
else if (dayRand == 1)
|
case 0: MobType = E_ENTITY_TYPE_CHICKEN; break;
|
||||||
Monster = new cCow();
|
case 1: MobType = E_ENTITY_TYPE_COW; break;
|
||||||
else if (dayRand == 2)
|
case 2: MobType = E_ENTITY_TYPE_PIG; break;
|
||||||
Monster = new cPig();
|
case 3: MobType = E_ENTITY_TYPE_SHEEP; break;
|
||||||
else if (dayRand == 3)
|
case 4: MobType = E_ENTITY_TYPE_SQUID; break;
|
||||||
Monster = new cSheep();
|
case 5: MobType = E_ENTITY_TYPE_WOLF; break;
|
||||||
else if (dayRand == 4)
|
}
|
||||||
Monster = new cSquid();
|
|
||||||
else if (dayRand == 5)
|
|
||||||
Monster = new cWolf();
|
|
||||||
//end random percent to spawn for day
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Monster)
|
if (MobType >= 0)
|
||||||
{
|
{
|
||||||
Monster->Initialize(this);
|
// A proper mob type was selected, now spawn the mob:
|
||||||
Monster->TeleportTo(SpawnPos.x, (double)(Height) + 2, SpawnPos.z);
|
SpawnMob(SpawnPos.x, SpawnPos.y, SpawnPos.z, MobType);
|
||||||
BroadcastSpawn(*Monster);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue