Implemented end and nether portals
This commit is contained in:
parent
60a37c1370
commit
8bff3e5af2
|
@ -638,30 +638,22 @@ void cChunk::Tick(float a_Dt)
|
||||||
for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr)
|
for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr)
|
||||||
{
|
{
|
||||||
// Mobs are tickes inside MobTick (as we don't have to tick them if they are far away from players)
|
// Mobs are tickes inside MobTick (as we don't have to tick them if they are far away from players)
|
||||||
if (!((*itr)->IsMob()))
|
// Don't tick things queued to be removed
|
||||||
|
if (!((*itr)->IsMob()) && (std::find(m_EntitiesToRemove.begin(), m_EntitiesToRemove.end(), (*itr)->GetUniqueID()) == m_EntitiesToRemove.end()))
|
||||||
{
|
{
|
||||||
(*itr)->Tick(a_Dt, *this);
|
(*itr)->Tick(a_Dt, *this);
|
||||||
}
|
}
|
||||||
} // for itr - m_Entitites[]
|
} // for itr - m_Entitites[]
|
||||||
|
|
||||||
// Remove all entities that were scheduled for removal:
|
|
||||||
for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end();)
|
for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end();)
|
||||||
{
|
{
|
||||||
if ((*itr)->IsDestroyed())
|
auto itr2 = std::find(m_EntitiesToRemove.begin(), m_EntitiesToRemove.end(), (*itr)->GetUniqueID());
|
||||||
|
if (itr2 != m_EntitiesToRemove.end())
|
||||||
{
|
{
|
||||||
LOGD("Destroying entity #%i (%s)", (*itr)->GetUniqueID(), (*itr)->GetClass());
|
|
||||||
cEntity * ToDelete = *itr;
|
|
||||||
itr = m_Entities.erase(itr);
|
itr = m_Entities.erase(itr);
|
||||||
delete ToDelete;
|
m_EntitiesToRemove.erase(itr2);
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
++itr;
|
else if ( // If any entity moved out of the chunk, move it to the neighbor:
|
||||||
} // for itr - m_Entitites[]
|
|
||||||
|
|
||||||
// If any entity moved out of the chunk, move it to the neighbor:
|
|
||||||
for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end();)
|
|
||||||
{
|
|
||||||
if (
|
|
||||||
((*itr)->GetChunkX() != m_PosX) ||
|
((*itr)->GetChunkX() != m_PosX) ||
|
||||||
((*itr)->GetChunkZ() != m_PosZ)
|
((*itr)->GetChunkZ() != m_PosZ)
|
||||||
)
|
)
|
||||||
|
@ -670,10 +662,20 @@ void cChunk::Tick(float a_Dt)
|
||||||
itr = m_Entities.erase(itr);
|
itr = m_Entities.erase(itr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if ((*itr)->IsDestroyed()) // Remove all entities that were scheduled for removal:
|
||||||
|
{
|
||||||
|
LOGD("Destroying entity #%i (%s)", (*itr)->GetUniqueID(), (*itr)->GetClass());
|
||||||
|
cEntity * ToDelete = *itr;
|
||||||
|
itr = m_Entities.erase(itr);
|
||||||
|
delete ToDelete;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
++itr;
|
++itr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} // for itr - m_Entitites[]
|
||||||
|
|
||||||
ApplyWeatherToTop();
|
ApplyWeatherToTop();
|
||||||
}
|
}
|
||||||
|
@ -1847,7 +1849,7 @@ void cChunk::RemoveBlockEntity( cBlockEntity* a_BlockEntity )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunk::AddClient(cClientHandle* a_Client)
|
bool cChunk::AddClient(cClientHandle * a_Client)
|
||||||
{
|
{
|
||||||
for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
|
for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
|
||||||
{
|
{
|
||||||
|
@ -1878,7 +1880,7 @@ bool cChunk::AddClient(cClientHandle* a_Client)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cChunk::RemoveClient( cClientHandle* a_Client )
|
void cChunk::RemoveClient(cClientHandle * a_Client)
|
||||||
{
|
{
|
||||||
for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
|
for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
|
||||||
{
|
{
|
||||||
|
@ -1891,7 +1893,7 @@ void cChunk::RemoveClient( cClientHandle* a_Client )
|
||||||
|
|
||||||
if (!a_Client->IsDestroyed())
|
if (!a_Client->IsDestroyed())
|
||||||
{
|
{
|
||||||
for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr )
|
for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
// DEBUG:
|
// DEBUG:
|
||||||
|
@ -1911,7 +1913,7 @@ void cChunk::RemoveClient( cClientHandle* a_Client )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunk::HasClient( cClientHandle* a_Client )
|
bool cChunk::HasClient(cClientHandle* a_Client)
|
||||||
{
|
{
|
||||||
for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
|
for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
|
||||||
{
|
{
|
||||||
|
@ -1954,18 +1956,13 @@ void cChunk::AddEntity(cEntity * a_Entity)
|
||||||
|
|
||||||
void cChunk::RemoveEntity(cEntity * a_Entity)
|
void cChunk::RemoveEntity(cEntity * a_Entity)
|
||||||
{
|
{
|
||||||
size_t SizeBefore = m_Entities.size();
|
m_EntitiesToRemove.push_back(a_Entity->GetUniqueID());
|
||||||
m_Entities.remove(a_Entity);
|
|
||||||
size_t SizeAfter = m_Entities.size();
|
|
||||||
|
|
||||||
if (SizeBefore != SizeAfter)
|
|
||||||
{
|
|
||||||
// Mark as dirty if it was a server-generated entity:
|
// Mark as dirty if it was a server-generated entity:
|
||||||
if (!a_Entity->IsPlayer())
|
if (!a_Entity->IsPlayer())
|
||||||
{
|
{
|
||||||
MarkDirty();
|
MarkDirty();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1974,6 +1971,11 @@ void cChunk::RemoveEntity(cEntity * a_Entity)
|
||||||
|
|
||||||
bool cChunk::HasEntity(int a_EntityID)
|
bool cChunk::HasEntity(int a_EntityID)
|
||||||
{
|
{
|
||||||
|
if (std::find(m_EntitiesToRemove.begin(), m_EntitiesToRemove.end(), a_EntityID) != m_EntitiesToRemove.end())
|
||||||
|
{
|
||||||
|
return false; // If EntitiesToRemove contains our ID, this chunk doesn't have it, as it should be removed soon
|
||||||
|
}
|
||||||
|
|
||||||
for (cEntityList::const_iterator itr = m_Entities.begin(), end = m_Entities.end(); itr != end; ++itr)
|
for (cEntityList::const_iterator itr = m_Entities.begin(), end = m_Entities.end(); itr != end; ++itr)
|
||||||
{
|
{
|
||||||
if ((*itr)->GetUniqueID() == a_EntityID)
|
if ((*itr)->GetUniqueID() == a_EntityID)
|
||||||
|
|
|
@ -411,6 +411,7 @@ private:
|
||||||
// A critical section is not needed, because all chunk access is protected by its parent ChunkMap's csLayers
|
// A critical section is not needed, because all chunk access is protected by its parent ChunkMap's csLayers
|
||||||
cClientHandleList m_LoadedByClient;
|
cClientHandleList m_LoadedByClient;
|
||||||
cEntityList m_Entities;
|
cEntityList m_Entities;
|
||||||
|
std::vector<int> m_EntitiesToRemove;
|
||||||
cBlockEntityList m_BlockEntities;
|
cBlockEntityList m_BlockEntities;
|
||||||
|
|
||||||
/** Number of times the chunk has been requested to stay (by various cChunkStay objects); if zero, the chunk can be unloaded */
|
/** Number of times the chunk has been requested to stay (by various cChunkStay objects); if zero, the chunk can be unloaded */
|
||||||
|
|
|
@ -125,7 +125,6 @@ cClientHandle::~cClientHandle()
|
||||||
}
|
}
|
||||||
if (World != NULL)
|
if (World != NULL)
|
||||||
{
|
{
|
||||||
World->RemovePlayer(m_Player);
|
|
||||||
m_Player->Destroy();
|
m_Player->Destroy();
|
||||||
}
|
}
|
||||||
delete m_Player;
|
delete m_Player;
|
||||||
|
@ -1754,7 +1753,7 @@ void cClientHandle::MoveToWorld(cWorld & a_World, bool a_SendRespawnPacket)
|
||||||
|
|
||||||
if (a_SendRespawnPacket)
|
if (a_SendRespawnPacket)
|
||||||
{
|
{
|
||||||
SendRespawn();
|
SendRespawn(a_World);
|
||||||
}
|
}
|
||||||
|
|
||||||
cWorld * World = m_Player->GetWorld();
|
cWorld * World = m_Player->GetWorld();
|
||||||
|
@ -2373,9 +2372,9 @@ void cClientHandle::SendRemoveEntityEffect(const cEntity & a_Entity, int a_Effec
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cClientHandle::SendRespawn(void)
|
void cClientHandle::SendRespawn(const cWorld & a_World)
|
||||||
{
|
{
|
||||||
m_Protocol->SendRespawn();
|
m_Protocol->SendRespawn(a_World);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -149,7 +149,7 @@ public:
|
||||||
void SendPlayerSpawn (const cPlayer & a_Player);
|
void SendPlayerSpawn (const cPlayer & a_Player);
|
||||||
void SendPluginMessage (const AString & a_Channel, const AString & a_Message); // Exported in ManualBindings.cpp
|
void SendPluginMessage (const AString & a_Channel, const AString & a_Message); // Exported in ManualBindings.cpp
|
||||||
void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID);
|
void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID);
|
||||||
void SendRespawn (void);
|
void SendRespawn (const cWorld & a_World);
|
||||||
void SendExperience (void);
|
void SendExperience (void);
|
||||||
void SendExperienceOrb (const cExpOrb & a_ExpOrb);
|
void SendExperienceOrb (const cExpOrb & a_ExpOrb);
|
||||||
void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode);
|
void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode);
|
||||||
|
|
|
@ -629,6 +629,7 @@ void cEntity::Tick(float a_Dt, cChunk & a_Chunk)
|
||||||
// Handle drowning
|
// Handle drowning
|
||||||
HandleAir();
|
HandleAir();
|
||||||
}
|
}
|
||||||
|
DetectPortal();
|
||||||
|
|
||||||
// None of the above functions change position, we remain in the chunk of NextChunk
|
// None of the above functions change position, we remain in the chunk of NextChunk
|
||||||
HandlePhysics(a_Dt, *NextChunk);
|
HandlePhysics(a_Dt, *NextChunk);
|
||||||
|
@ -1039,6 +1040,122 @@ void cEntity::DetectCacti(void)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cEntity::DetectPortal()
|
||||||
|
{
|
||||||
|
int X = POSX_TOINT, Y = POSY_TOINT, Z = POSZ_TOINT;
|
||||||
|
if ((Y > 0) && (Y < cChunkDef::Height))
|
||||||
|
{
|
||||||
|
switch (GetWorld()->GetBlock(X, Y, Z))
|
||||||
|
{
|
||||||
|
case E_BLOCK_NETHER_PORTAL:
|
||||||
|
{
|
||||||
|
switch (GetWorld()->GetDimension())
|
||||||
|
{
|
||||||
|
case dimNether:
|
||||||
|
{
|
||||||
|
AString OverworldName = GetWorld()->GetName().substr(0, GetWorld()->GetName().size() - 7);
|
||||||
|
cFile::CreateFolder(FILE_IO_PREFIX + OverworldName);
|
||||||
|
cIniFile File;
|
||||||
|
File.ReadFile(OverworldName + "/world.ini");
|
||||||
|
File.SetValue("General", "Dimension", "Overworld");
|
||||||
|
File.WriteFile(OverworldName + "/world.ini");
|
||||||
|
|
||||||
|
MoveToWorld(OverworldName, cRoot::Get()->CreateAndInitializeWorld(OverworldName));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case dimOverworld:
|
||||||
|
{
|
||||||
|
AString NetherWorldName = GetWorld()->GetName() + "_nether";
|
||||||
|
cFile::CreateFolder(FILE_IO_PREFIX + NetherWorldName);
|
||||||
|
cIniFile File;
|
||||||
|
File.ReadFile(NetherWorldName + "/world.ini");
|
||||||
|
File.SetValue("General", "Dimension", "Nether");
|
||||||
|
File.WriteFile(NetherWorldName + "/world.ini");
|
||||||
|
|
||||||
|
MoveToWorld(NetherWorldName, cRoot::Get()->CreateAndInitializeWorld(NetherWorldName));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case E_BLOCK_END_PORTAL:
|
||||||
|
{
|
||||||
|
switch (GetWorld()->GetDimension())
|
||||||
|
{
|
||||||
|
case dimEnd:
|
||||||
|
{
|
||||||
|
AString OverworldName = GetWorld()->GetName().substr(0, GetWorld()->GetName().size() - 4);
|
||||||
|
cFile::CreateFolder(FILE_IO_PREFIX + OverworldName);
|
||||||
|
cIniFile File;
|
||||||
|
File.ReadFile(OverworldName + "/world.ini");
|
||||||
|
File.SetValue("General", "Dimension", "Overworld");
|
||||||
|
File.WriteFile(OverworldName + "/world.ini");
|
||||||
|
|
||||||
|
MoveToWorld(OverworldName, cRoot::Get()->CreateAndInitializeWorld(OverworldName));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case dimOverworld:
|
||||||
|
{
|
||||||
|
AString EndWorldName = GetWorld()->GetName() + "_end";
|
||||||
|
cFile::CreateFolder(FILE_IO_PREFIX + EndWorldName);
|
||||||
|
cIniFile File;
|
||||||
|
File.ReadFile(EndWorldName + "/world.ini");
|
||||||
|
File.SetValue("General", "Dimension", "End");
|
||||||
|
File.WriteFile(EndWorldName + "/world.ini");
|
||||||
|
|
||||||
|
MoveToWorld(EndWorldName, cRoot::Get()->CreateAndInitializeWorld(EndWorldName));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cEntity::MoveToWorld(const AString & a_WorldName, cWorld * a_World)
|
||||||
|
{
|
||||||
|
cWorld * World;
|
||||||
|
if (a_World == NULL)
|
||||||
|
{
|
||||||
|
World = cRoot::Get()->GetWorld(a_WorldName);
|
||||||
|
if (World == NULL)
|
||||||
|
{
|
||||||
|
LOG("%s: Couldn't find world \"%s\".", __FUNCTION__, a_WorldName);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
World = a_World;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetWorld() == World)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove all links to the old world
|
||||||
|
GetWorld()->RemoveEntity(this);
|
||||||
|
GetWorld()->BroadcastDestroyEntity(*this);
|
||||||
|
|
||||||
|
// Add to all the necessary parts of the new world
|
||||||
|
SetWorld(World);
|
||||||
|
World->AddEntity(this);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cEntity::SetSwimState(cChunk & a_Chunk)
|
void cEntity::SetSwimState(cChunk & a_Chunk)
|
||||||
{
|
{
|
||||||
int RelY = (int)floor(GetPosY() + 0.1);
|
int RelY = (int)floor(GetPosY() + 0.1);
|
||||||
|
|
|
@ -324,6 +324,9 @@ public:
|
||||||
/** Detects the time for application of cacti damage */
|
/** Detects the time for application of cacti damage */
|
||||||
virtual void DetectCacti(void);
|
virtual void DetectCacti(void);
|
||||||
|
|
||||||
|
/** Detects whether we are in a portal block and begins teleportation procedures if so */
|
||||||
|
virtual void DetectPortal(void);
|
||||||
|
|
||||||
/// Handles when the entity is in the void
|
/// Handles when the entity is in the void
|
||||||
virtual void TickInVoid(cChunk & a_Chunk);
|
virtual void TickInVoid(cChunk & a_Chunk);
|
||||||
|
|
||||||
|
@ -366,6 +369,9 @@ public:
|
||||||
/// Teleports to the coordinates specified
|
/// Teleports to the coordinates specified
|
||||||
virtual void TeleportToCoords(double a_PosX, double a_PosY, double a_PosZ);
|
virtual void TeleportToCoords(double a_PosX, double a_PosY, double a_PosZ);
|
||||||
|
|
||||||
|
/** Moves entity to specified world */
|
||||||
|
virtual bool MoveToWorld(const AString & a_WorldName, cWorld * a_World = NULL);
|
||||||
|
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
||||||
/// Updates clients of changes in the entity.
|
/// Updates clients of changes in the entity.
|
||||||
|
|
|
@ -134,7 +134,7 @@ cPlayer::~cPlayer(void)
|
||||||
|
|
||||||
SaveToDisk();
|
SaveToDisk();
|
||||||
|
|
||||||
m_World->RemovePlayer( this );
|
m_World->RemovePlayer(this);
|
||||||
|
|
||||||
m_ClientHandle = NULL;
|
m_ClientHandle = NULL;
|
||||||
|
|
||||||
|
@ -150,8 +150,6 @@ cPlayer::~cPlayer(void)
|
||||||
void cPlayer::Destroyed()
|
void cPlayer::Destroyed()
|
||||||
{
|
{
|
||||||
CloseWindow(false);
|
CloseWindow(false);
|
||||||
|
|
||||||
m_ClientHandle = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -952,7 +950,7 @@ void cPlayer::Respawn(void)
|
||||||
m_LifetimeTotalXp = 0;
|
m_LifetimeTotalXp = 0;
|
||||||
// ToDo: send score to client? How?
|
// ToDo: send score to client? How?
|
||||||
|
|
||||||
m_ClientHandle->SendRespawn();
|
m_ClientHandle->SendRespawn(*GetWorld());
|
||||||
|
|
||||||
// Extinguish the fire:
|
// Extinguish the fire:
|
||||||
StopBurning();
|
StopBurning();
|
||||||
|
@ -1574,25 +1572,38 @@ void cPlayer::TossItems(const cItems & a_Items)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cPlayer::MoveToWorld(const char * a_WorldName)
|
bool cPlayer::MoveToWorld(const AString & a_WorldName, cWorld * a_World)
|
||||||
{
|
{
|
||||||
cWorld * World = cRoot::Get()->GetWorld(a_WorldName);
|
cWorld * World;
|
||||||
|
if (a_World == NULL)
|
||||||
|
{
|
||||||
|
World = cRoot::Get()->GetWorld(a_WorldName);
|
||||||
if (World == NULL)
|
if (World == NULL)
|
||||||
{
|
{
|
||||||
LOG("%s: Couldn't find world \"%s\".", __FUNCTION__, a_WorldName);
|
LOG("%s: Couldn't find world \"%s\".", __FUNCTION__, a_WorldName);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
World = a_World;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetWorld() == World)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
eDimension OldDimension = m_World->GetDimension();
|
eDimension OldDimension = m_World->GetDimension();
|
||||||
|
|
||||||
// Remove all links to the old world
|
// Remove all links to the old world
|
||||||
m_World->RemovePlayer(this);
|
m_World->RemovePlayer(this);
|
||||||
m_ClientHandle->RemoveFromAllChunks();
|
m_ClientHandle->RemoveFromAllChunks();
|
||||||
m_World->RemoveEntity(this);
|
|
||||||
|
|
||||||
// If the dimension is different, we can send the respawn packet
|
// If the dimension is different, we can send the respawn packet
|
||||||
// http://wiki.vg/Protocol#0x09 says "don't send if dimension is the same" as of 2013_07_02
|
// http://wiki.vg/Protocol#0x09 says "don't send if dimension is the same" as of 2013_07_02
|
||||||
m_ClientHandle->MoveToWorld(*World, (OldDimension != World->GetDimension()));
|
bool SendRespawn = OldDimension != World->GetDimension();
|
||||||
|
m_ClientHandle->MoveToWorld(*World, SendRespawn);
|
||||||
|
|
||||||
// Add player to all the necessary parts of the new world
|
// Add player to all the necessary parts of the new world
|
||||||
SetWorld(World);
|
SetWorld(World);
|
||||||
|
@ -1600,6 +1611,11 @@ bool cPlayer::MoveToWorld(const char * a_WorldName)
|
||||||
World->AddEntity(this);
|
World->AddEntity(this);
|
||||||
World->AddPlayer(this);
|
World->AddPlayer(this);
|
||||||
|
|
||||||
|
if (SendRespawn)
|
||||||
|
{
|
||||||
|
GetClientHandle()->SendPlayerMoveLook();
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -328,7 +328,7 @@ public:
|
||||||
void SetVisible( bool a_bVisible ); // tolua_export
|
void SetVisible( bool a_bVisible ); // tolua_export
|
||||||
bool IsVisible(void) const { return m_bVisible; } // tolua_export
|
bool IsVisible(void) const { return m_bVisible; } // tolua_export
|
||||||
|
|
||||||
bool MoveToWorld(const char * a_WorldName); // tolua_export
|
virtual bool MoveToWorld(const AString & a_WorldName, cWorld * a_World = NULL) override; // tolua_export
|
||||||
|
|
||||||
bool SaveToDisk(void);
|
bool SaveToDisk(void);
|
||||||
bool LoadFromDisk(void);
|
bool LoadFromDisk(void);
|
||||||
|
|
|
@ -95,7 +95,7 @@ void cBioGenConstant::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap
|
||||||
|
|
||||||
void cBioGenConstant::InitializeBiomeGen(cIniFile & a_IniFile)
|
void cBioGenConstant::InitializeBiomeGen(cIniFile & a_IniFile)
|
||||||
{
|
{
|
||||||
AString Biome = a_IniFile.GetValueSet("Generator", "ConstantBiome", "Plains");
|
AString Biome = a_IniFile.GetValueSet("Generator", "ConstantBiome", "");
|
||||||
m_Biome = StringToBiome(Biome);
|
m_Biome = StringToBiome(Biome);
|
||||||
if (m_Biome == biInvalidBiome)
|
if (m_Biome == biInvalidBiome)
|
||||||
{
|
{
|
||||||
|
|
|
@ -39,7 +39,6 @@ cTerrainCompositionGen * cTerrainCompositionGen::CreateCompositionGen(cIniFile &
|
||||||
{
|
{
|
||||||
LOGWARN("[Generator] CompositionGen value not set in world.ini, using \"Biomal\".");
|
LOGWARN("[Generator] CompositionGen value not set in world.ini, using \"Biomal\".");
|
||||||
CompoGenName = "Biomal";
|
CompoGenName = "Biomal";
|
||||||
a_IniFile.SetValue("Generator", "CompositionGen", CompoGenName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cTerrainCompositionGen * res = NULL;
|
cTerrainCompositionGen * res = NULL;
|
||||||
|
@ -93,7 +92,6 @@ cTerrainCompositionGen * cTerrainCompositionGen::CreateCompositionGen(cIniFile &
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOGWARN("Unknown CompositionGen \"%s\", using \"Biomal\" instead.", CompoGenName.c_str());
|
LOGWARN("Unknown CompositionGen \"%s\", using \"Biomal\" instead.", CompoGenName.c_str());
|
||||||
a_IniFile.DeleteValue("Generator", "CompositionGen");
|
|
||||||
a_IniFile.SetValue("Generator", "CompositionGen", "Biomal");
|
a_IniFile.SetValue("Generator", "CompositionGen", "Biomal");
|
||||||
return CreateCompositionGen(a_IniFile, a_BiomeGen, a_HeightGen, a_Seed);
|
return CreateCompositionGen(a_IniFile, a_BiomeGen, a_HeightGen, a_Seed);
|
||||||
}
|
}
|
||||||
|
@ -291,19 +289,7 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
|
||||||
int Seed = m_ChunkGenerator.GetSeed();
|
int Seed = m_ChunkGenerator.GetSeed();
|
||||||
eDimension Dimension = StringToDimension(a_IniFile.GetValue("General", "Dimension", "Overworld"));
|
eDimension Dimension = StringToDimension(a_IniFile.GetValue("General", "Dimension", "Overworld"));
|
||||||
|
|
||||||
// Older configuration used "Structures" in addition to "Finishers"; we don't distinguish between the two anymore (#398)
|
AString Finishers = a_IniFile.GetValueSet("Generator", "Finishers", "");
|
||||||
// Therefore, we load Structures from the ini file for compatibility, but move its contents over to Finishers:
|
|
||||||
AString Structures = a_IniFile.GetValue("Generator", "Structures", "");
|
|
||||||
AString Finishers = a_IniFile.GetValueSet("Generator", "Finishers", "Ravines, WormNestCaves, WaterLakes, LavaLakes, OreNests, Trees, SprinkleFoliage, Ice, Snow, Lilypads, BottomLava, DeadBushes, PreSimulator");
|
|
||||||
if (!Structures.empty())
|
|
||||||
{
|
|
||||||
LOGINFO("[Generator].Structures is deprecated, moving the contents to [Generator].Finishers.");
|
|
||||||
// Structures used to generate before Finishers, so place them first:
|
|
||||||
Structures.append(", ");
|
|
||||||
Finishers = Structures + Finishers;
|
|
||||||
a_IniFile.SetValue("Generator", "Finishers", Finishers);
|
|
||||||
}
|
|
||||||
a_IniFile.DeleteValue("Generator", "Structures");
|
|
||||||
|
|
||||||
// Create all requested finishers:
|
// Create all requested finishers:
|
||||||
AStringVector Str = StringSplitAndTrim(Finishers, ",");
|
AStringVector Str = StringSplitAndTrim(Finishers, ",");
|
||||||
|
|
|
@ -50,7 +50,7 @@ cEndGen::cEndGen(int a_Seed) :
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cEndGen::Initialize(cIniFile & a_IniFile)
|
void cEndGen::InitializeCompoGen(cIniFile & a_IniFile)
|
||||||
{
|
{
|
||||||
m_IslandSizeX = a_IniFile.GetValueSetI("Generator", "EndGenIslandSizeX", m_IslandSizeX);
|
m_IslandSizeX = a_IniFile.GetValueSetI("Generator", "EndGenIslandSizeX", m_IslandSizeX);
|
||||||
m_IslandSizeY = a_IniFile.GetValueSetI("Generator", "EndGenIslandSizeY", m_IslandSizeY);
|
m_IslandSizeY = a_IniFile.GetValueSetI("Generator", "EndGenIslandSizeY", m_IslandSizeY);
|
||||||
|
|
|
@ -23,8 +23,6 @@ class cEndGen :
|
||||||
public:
|
public:
|
||||||
cEndGen(int a_Seed);
|
cEndGen(int a_Seed);
|
||||||
|
|
||||||
void Initialize(cIniFile & a_IniFile);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/// Seed for the noise
|
/// Seed for the noise
|
||||||
|
@ -66,4 +64,5 @@ protected:
|
||||||
|
|
||||||
// cTerrainCompositionGen overrides:
|
// cTerrainCompositionGen overrides:
|
||||||
virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc) override;
|
virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc) override;
|
||||||
|
virtual void InitializeCompoGen(cIniFile & a_IniFile) override;
|
||||||
} ;
|
} ;
|
||||||
|
|
|
@ -100,7 +100,7 @@ public:
|
||||||
virtual void SendPlayerSpawn (const cPlayer & a_Player) = 0;
|
virtual void SendPlayerSpawn (const cPlayer & a_Player) = 0;
|
||||||
virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) = 0;
|
virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) = 0;
|
||||||
virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) = 0;
|
virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) = 0;
|
||||||
virtual void SendRespawn (void) = 0;
|
virtual void SendRespawn (const cWorld & a_World) = 0;
|
||||||
virtual void SendExperience (void) = 0;
|
virtual void SendExperience (void) = 0;
|
||||||
virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) = 0;
|
virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) = 0;
|
||||||
virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) = 0;
|
virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) = 0;
|
||||||
|
|
|
@ -831,12 +831,12 @@ void cProtocol125::SendRemoveEntityEffect(const cEntity & a_Entity, int a_Effect
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cProtocol125::SendRespawn(void)
|
void cProtocol125::SendRespawn(const cWorld & a_World)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSPacket);
|
cCSLock Lock(m_CSPacket);
|
||||||
cPlayer * Player = m_Client->GetPlayer();
|
cPlayer * Player = m_Client->GetPlayer();
|
||||||
WriteByte (PACKET_RESPAWN);
|
WriteByte (PACKET_RESPAWN);
|
||||||
WriteInt ((int)(Player->GetWorld()->GetDimension()));
|
WriteInt ((int)(a_World.GetDimension()));
|
||||||
WriteByte (2); // TODO: Difficulty; 2 = Normal
|
WriteByte (2); // TODO: Difficulty; 2 = Normal
|
||||||
WriteChar ((char)Player->GetGameMode());
|
WriteChar ((char)Player->GetGameMode());
|
||||||
WriteShort (256); // Current world height
|
WriteShort (256); // Current world height
|
||||||
|
|
|
@ -72,7 +72,7 @@ public:
|
||||||
virtual void SendPlayerSpawn (const cPlayer & a_Player) override;
|
virtual void SendPlayerSpawn (const cPlayer & a_Player) override;
|
||||||
virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) override;
|
virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) override;
|
||||||
virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override;
|
virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override;
|
||||||
virtual void SendRespawn (void) override;
|
virtual void SendRespawn (const cWorld & a_World) override;
|
||||||
virtual void SendExperience (void) override;
|
virtual void SendExperience (void) override;
|
||||||
virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override;
|
virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override;
|
||||||
virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override;
|
virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override;
|
||||||
|
|
|
@ -158,10 +158,10 @@ void cProtocol161::SendPlayerMaxSpeed(void)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cProtocol161::SendRespawn(void)
|
void cProtocol161::SendRespawn(const cWorld & a_World)
|
||||||
{
|
{
|
||||||
// Besides sending the respawn, we need to also send the player max speed, otherwise the client reverts to super-fast
|
// Besides sending the respawn, we need to also send the player max speed, otherwise the client reverts to super-fast
|
||||||
super::SendRespawn();
|
super::SendRespawn(a_World);
|
||||||
SendPlayerMaxSpeed();
|
SendPlayerMaxSpeed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ protected:
|
||||||
virtual void SendGameMode (eGameMode a_GameMode) override;
|
virtual void SendGameMode (eGameMode a_GameMode) override;
|
||||||
virtual void SendHealth (void) override;
|
virtual void SendHealth (void) override;
|
||||||
virtual void SendPlayerMaxSpeed(void) override;
|
virtual void SendPlayerMaxSpeed(void) override;
|
||||||
virtual void SendRespawn (void) override;
|
virtual void SendRespawn (const cWorld & a_World) override;
|
||||||
virtual void SendWindowOpen (const cWindow & a_Window) override;
|
virtual void SendWindowOpen (const cWindow & a_Window) override;
|
||||||
|
|
||||||
virtual int ParseEntityAction (void) override;
|
virtual int ParseEntityAction (void) override;
|
||||||
|
|
|
@ -983,11 +983,11 @@ void cProtocol172::SendRemoveEntityEffect(const cEntity & a_Entity, int a_Effect
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cProtocol172::SendRespawn(void)
|
void cProtocol172::SendRespawn(const cWorld & a_World)
|
||||||
{
|
{
|
||||||
cPacketizer Pkt(*this, 0x07); // Respawn packet
|
cPacketizer Pkt(*this, 0x07); // Respawn packet
|
||||||
cPlayer * Player = m_Client->GetPlayer();
|
cPlayer * Player = m_Client->GetPlayer();
|
||||||
Pkt.WriteInt(Player->GetWorld()->GetDimension());
|
Pkt.WriteInt((int)a_World.GetDimension());
|
||||||
Pkt.WriteByte(2); // TODO: Difficulty (set to Normal)
|
Pkt.WriteByte(2); // TODO: Difficulty (set to Normal)
|
||||||
Pkt.WriteByte((Byte)Player->GetEffectiveGameMode());
|
Pkt.WriteByte((Byte)Player->GetEffectiveGameMode());
|
||||||
Pkt.WriteString("default");
|
Pkt.WriteString("default");
|
||||||
|
|
|
@ -104,7 +104,7 @@ public:
|
||||||
virtual void SendPlayerSpawn (const cPlayer & a_Player) override;
|
virtual void SendPlayerSpawn (const cPlayer & a_Player) override;
|
||||||
virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) override;
|
virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) override;
|
||||||
virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override;
|
virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override;
|
||||||
virtual void SendRespawn (void) override;
|
virtual void SendRespawn (const cWorld & a_World) override;
|
||||||
virtual void SendSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch) override; // a_Src coords are Block * 8
|
virtual void SendSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch) override; // a_Src coords are Block * 8
|
||||||
virtual void SendExperience (void) override;
|
virtual void SendExperience (void) override;
|
||||||
virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override;
|
virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override;
|
||||||
|
|
|
@ -555,10 +555,10 @@ void cProtocolRecognizer::SendRemoveEntityEffect(const cEntity & a_Entity, int a
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cProtocolRecognizer::SendRespawn(void)
|
void cProtocolRecognizer::SendRespawn(const cWorld & a_World)
|
||||||
{
|
{
|
||||||
ASSERT(m_Protocol != NULL);
|
ASSERT(m_Protocol != NULL);
|
||||||
m_Protocol->SendRespawn();
|
m_Protocol->SendRespawn(a_World);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -107,7 +107,7 @@ public:
|
||||||
virtual void SendPlayerSpawn (const cPlayer & a_Player) override;
|
virtual void SendPlayerSpawn (const cPlayer & a_Player) override;
|
||||||
virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) override;
|
virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) override;
|
||||||
virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override;
|
virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override;
|
||||||
virtual void SendRespawn (void) override;
|
virtual void SendRespawn (const cWorld & a_World) override;
|
||||||
virtual void SendExperience (void) override;
|
virtual void SendExperience (void) override;
|
||||||
virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override;
|
virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override;
|
||||||
virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override;
|
virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override;
|
||||||
|
|
17
src/Root.cpp
17
src/Root.cpp
|
@ -320,7 +320,7 @@ cWorld * cRoot::CreateAndInitializeWorld(const AString & a_WorldName)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
cWorld* NewWorld = new cWorld(a_WorldName.c_str());
|
cWorld * NewWorld = new cWorld(a_WorldName.c_str());
|
||||||
m_WorldsByName[a_WorldName] = NewWorld;
|
m_WorldsByName[a_WorldName] = NewWorld;
|
||||||
NewWorld->Start();
|
NewWorld->Start();
|
||||||
NewWorld->InitializeSpawn();
|
NewWorld->InitializeSpawn();
|
||||||
|
@ -372,7 +372,7 @@ void cRoot::UnloadWorlds(void)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
cWorld* cRoot::GetDefaultWorld()
|
cWorld * cRoot::GetDefaultWorld()
|
||||||
{
|
{
|
||||||
return m_pDefaultWorld;
|
return m_pDefaultWorld;
|
||||||
}
|
}
|
||||||
|
@ -381,12 +381,14 @@ cWorld* cRoot::GetDefaultWorld()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
cWorld* cRoot::GetWorld( const AString & a_WorldName )
|
cWorld * cRoot::GetWorld(const AString & a_WorldName)
|
||||||
{
|
{
|
||||||
WorldMap::iterator itr = m_WorldsByName.find( a_WorldName );
|
WorldMap::iterator itr = m_WorldsByName.find(a_WorldName);
|
||||||
if( itr != m_WorldsByName.end() )
|
if (itr != m_WorldsByName.end())
|
||||||
|
{
|
||||||
return itr->second;
|
return itr->second;
|
||||||
return 0;
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -398,11 +400,14 @@ bool cRoot::ForEachWorld(cWorldListCallback & a_Callback)
|
||||||
for (WorldMap::iterator itr = m_WorldsByName.begin(), itr2 = itr; itr != m_WorldsByName.end(); itr = itr2)
|
for (WorldMap::iterator itr = m_WorldsByName.begin(), itr2 = itr; itr != m_WorldsByName.end(); itr = itr2)
|
||||||
{
|
{
|
||||||
++itr2;
|
++itr2;
|
||||||
|
if (itr->second != NULL)
|
||||||
|
{
|
||||||
if (a_Callback.Item(itr->second))
|
if (a_Callback.Item(itr->second))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -571,6 +571,37 @@ void cWorld::Start(void)
|
||||||
m_GameMode = (eGameMode) Clamp(GameMode, (int)gmSurvival, (int)gmAdventure);
|
m_GameMode = (eGameMode) Clamp(GameMode, (int)gmSurvival, (int)gmAdventure);
|
||||||
m_TNTShrapnelLevel = (eShrapnelLevel)Clamp(TNTShrapnelLevel, (int)slNone, (int)slAll);
|
m_TNTShrapnelLevel = (eShrapnelLevel)Clamp(TNTShrapnelLevel, (int)slNone, (int)slAll);
|
||||||
|
|
||||||
|
switch (GetDimension())
|
||||||
|
{
|
||||||
|
case dimEnd:
|
||||||
|
{
|
||||||
|
IniFile.GetValueSet("Generator", "BiomeGen", "Constant");
|
||||||
|
IniFile.GetValueSet("Generator", "ConstantBiome", "End");
|
||||||
|
IniFile.GetValueSet("Generator", "HeightGen", "Biomal");
|
||||||
|
IniFile.GetValueSet("Generator", "CompositionGen", "End");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case dimOverworld:
|
||||||
|
{
|
||||||
|
IniFile.GetValueSet("Generator", "BiomeGen", "MultiStepMap");
|
||||||
|
IniFile.GetValueSet("Generator", "HeightGen", "DistortedHeightmap");
|
||||||
|
IniFile.GetValueSet("Generator", "CompositionGen", "DistortedHeightmap");
|
||||||
|
IniFile.GetValueSet("Generator", "Finishers", "Ravines, WormNestCaves, WaterLakes, WaterSprings, LavaLakes, LavaSprings, OreNests, Mineshafts, Trees, SprinkleFoliage, Ice, Snow, Lilypads, BottomLava, DeadBushes, PreSimulator");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case dimNether:
|
||||||
|
{
|
||||||
|
IniFile.GetValueSet("Generator", "BiomeGen", "Constant");
|
||||||
|
IniFile.GetValueSet("Generator", "ConstantBiome", "Nether");
|
||||||
|
IniFile.GetValueSet("Generator", "HeightGen", "Flat");
|
||||||
|
IniFile.GetValueSet("Generator", "FlatHeight", "128");
|
||||||
|
IniFile.GetValueSet("Generator", "CompositionGen", "Nether");
|
||||||
|
IniFile.GetValueSet("Generator", "Finishers", "WormNestCaves, BottomLava, LavaSprings, NetherClumpFoliage, NetherForts, PreSimulator");
|
||||||
|
IniFile.GetValueSet("Generator", "BottomLavaHeight", "30");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Load allowed mobs:
|
// Load allowed mobs:
|
||||||
const char * DefaultMonsters = "";
|
const char * DefaultMonsters = "";
|
||||||
switch (m_Dimension)
|
switch (m_Dimension)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user