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)
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
} // for itr - m_Entitites[]
|
||||
|
||||
// Remove all entities that were scheduled for removal:
|
||||
for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end();)
|
||||
{
|
||||
if ((*itr)->IsDestroyed())
|
||||
{
|
||||
LOGD("Destroying entity #%i (%s)", (*itr)->GetUniqueID(), (*itr)->GetClass());
|
||||
cEntity * ToDelete = *itr;
|
||||
itr = m_Entities.erase(itr);
|
||||
delete ToDelete;
|
||||
continue;
|
||||
}
|
||||
++itr;
|
||||
} // 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 (
|
||||
auto itr2 = std::find(m_EntitiesToRemove.begin(), m_EntitiesToRemove.end(), (*itr)->GetUniqueID());
|
||||
if (itr2 != m_EntitiesToRemove.end())
|
||||
{
|
||||
itr = m_Entities.erase(itr);
|
||||
m_EntitiesToRemove.erase(itr2);
|
||||
}
|
||||
else if ( // If any entity moved out of the chunk, move it to the neighbor:
|
||||
((*itr)->GetChunkX() != m_PosX) ||
|
||||
((*itr)->GetChunkZ() != m_PosZ)
|
||||
)
|
||||
@ -671,9 +663,19 @@ void cChunk::Tick(float a_Dt)
|
||||
}
|
||||
else
|
||||
{
|
||||
++itr;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // for itr - m_Entitites[]
|
||||
|
||||
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)
|
||||
{
|
||||
@ -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)
|
||||
{
|
||||
@ -1886,12 +1888,12 @@ void cChunk::RemoveClient( cClientHandle* a_Client )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
m_LoadedByClient.erase(itr);
|
||||
|
||||
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:
|
||||
@ -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)
|
||||
{
|
||||
@ -1942,9 +1944,9 @@ void cChunk::AddEntity(cEntity * a_Entity)
|
||||
{
|
||||
MarkDirty();
|
||||
}
|
||||
|
||||
|
||||
ASSERT(std::find(m_Entities.begin(), m_Entities.end(), a_Entity) == m_Entities.end()); // Not there already
|
||||
|
||||
|
||||
m_Entities.push_back(a_Entity);
|
||||
}
|
||||
|
||||
@ -1954,17 +1956,12 @@ void cChunk::AddEntity(cEntity * a_Entity)
|
||||
|
||||
void cChunk::RemoveEntity(cEntity * a_Entity)
|
||||
{
|
||||
size_t SizeBefore = m_Entities.size();
|
||||
m_Entities.remove(a_Entity);
|
||||
size_t SizeAfter = m_Entities.size();
|
||||
|
||||
if (SizeBefore != SizeAfter)
|
||||
m_EntitiesToRemove.push_back(a_Entity->GetUniqueID());
|
||||
|
||||
// Mark as dirty if it was a server-generated entity:
|
||||
if (!a_Entity->IsPlayer())
|
||||
{
|
||||
// Mark as dirty if it was a server-generated entity:
|
||||
if (!a_Entity->IsPlayer())
|
||||
{
|
||||
MarkDirty();
|
||||
}
|
||||
MarkDirty();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1974,6 +1971,11 @@ void cChunk::RemoveEntity(cEntity * a_Entity)
|
||||
|
||||
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)
|
||||
{
|
||||
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
|
||||
cClientHandleList m_LoadedByClient;
|
||||
cEntityList m_Entities;
|
||||
std::vector<int> m_EntitiesToRemove;
|
||||
cBlockEntityList m_BlockEntities;
|
||||
|
||||
/** 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)
|
||||
{
|
||||
World->RemovePlayer(m_Player);
|
||||
m_Player->Destroy();
|
||||
}
|
||||
delete m_Player;
|
||||
@ -1754,7 +1753,7 @@ void cClientHandle::MoveToWorld(cWorld & a_World, bool a_SendRespawnPacket)
|
||||
|
||||
if (a_SendRespawnPacket)
|
||||
{
|
||||
SendRespawn();
|
||||
SendRespawn(a_World);
|
||||
}
|
||||
|
||||
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 SendPluginMessage (const AString & a_Channel, const AString & a_Message); // Exported in ManualBindings.cpp
|
||||
void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID);
|
||||
void SendRespawn (void);
|
||||
void SendRespawn (const cWorld & a_World);
|
||||
void SendExperience (void);
|
||||
void SendExperienceOrb (const cExpOrb & a_ExpOrb);
|
||||
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
|
||||
HandleAir();
|
||||
}
|
||||
DetectPortal();
|
||||
|
||||
// None of the above functions change position, we remain in the chunk of 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)
|
||||
{
|
||||
int RelY = (int)floor(GetPosY() + 0.1);
|
||||
|
@ -323,6 +323,9 @@ public:
|
||||
|
||||
/** Detects the time for application of cacti damage */
|
||||
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
|
||||
virtual void TickInVoid(cChunk & a_Chunk);
|
||||
@ -365,6 +368,9 @@ public:
|
||||
|
||||
/// Teleports to the coordinates specified
|
||||
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
|
||||
|
||||
|
@ -134,7 +134,7 @@ cPlayer::~cPlayer(void)
|
||||
|
||||
SaveToDisk();
|
||||
|
||||
m_World->RemovePlayer( this );
|
||||
m_World->RemovePlayer(this);
|
||||
|
||||
m_ClientHandle = NULL;
|
||||
|
||||
@ -150,8 +150,6 @@ cPlayer::~cPlayer(void)
|
||||
void cPlayer::Destroyed()
|
||||
{
|
||||
CloseWindow(false);
|
||||
|
||||
m_ClientHandle = NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -952,7 +950,7 @@ void cPlayer::Respawn(void)
|
||||
m_LifetimeTotalXp = 0;
|
||||
// ToDo: send score to client? How?
|
||||
|
||||
m_ClientHandle->SendRespawn();
|
||||
m_ClientHandle->SendRespawn(*GetWorld());
|
||||
|
||||
// Extinguish the fire:
|
||||
StopBurning();
|
||||
@ -1574,12 +1572,25 @@ 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);
|
||||
if (World == NULL)
|
||||
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)
|
||||
{
|
||||
LOG("%s: Couldn't find world \"%s\".", __FUNCTION__, a_WorldName);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1588,11 +1599,11 @@ bool cPlayer::MoveToWorld(const char * a_WorldName)
|
||||
// Remove all links to the old world
|
||||
m_World->RemovePlayer(this);
|
||||
m_ClientHandle->RemoveFromAllChunks();
|
||||
m_World->RemoveEntity(this);
|
||||
|
||||
// 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
|
||||
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
|
||||
SetWorld(World);
|
||||
@ -1600,6 +1611,11 @@ bool cPlayer::MoveToWorld(const char * a_WorldName)
|
||||
World->AddEntity(this);
|
||||
World->AddPlayer(this);
|
||||
|
||||
if (SendRespawn)
|
||||
{
|
||||
GetClientHandle()->SendPlayerMoveLook();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -328,7 +328,7 @@ public:
|
||||
void SetVisible( bool a_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 LoadFromDisk(void);
|
||||
|
@ -95,7 +95,7 @@ void cBioGenConstant::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap
|
||||
|
||||
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);
|
||||
if (m_Biome == biInvalidBiome)
|
||||
{
|
||||
|
@ -39,7 +39,6 @@ cTerrainCompositionGen * cTerrainCompositionGen::CreateCompositionGen(cIniFile &
|
||||
{
|
||||
LOGWARN("[Generator] CompositionGen value not set in world.ini, using \"Biomal\".");
|
||||
CompoGenName = "Biomal";
|
||||
a_IniFile.SetValue("Generator", "CompositionGen", CompoGenName);
|
||||
}
|
||||
|
||||
cTerrainCompositionGen * res = NULL;
|
||||
@ -93,7 +92,6 @@ cTerrainCompositionGen * cTerrainCompositionGen::CreateCompositionGen(cIniFile &
|
||||
else
|
||||
{
|
||||
LOGWARN("Unknown CompositionGen \"%s\", using \"Biomal\" instead.", CompoGenName.c_str());
|
||||
a_IniFile.DeleteValue("Generator", "CompositionGen");
|
||||
a_IniFile.SetValue("Generator", "CompositionGen", "Biomal");
|
||||
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();
|
||||
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)
|
||||
// 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");
|
||||
AString Finishers = a_IniFile.GetValueSet("Generator", "Finishers", "");
|
||||
|
||||
// Create all requested 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_IslandSizeY = a_IniFile.GetValueSetI("Generator", "EndGenIslandSizeY", m_IslandSizeY);
|
||||
|
@ -23,8 +23,6 @@ class cEndGen :
|
||||
public:
|
||||
cEndGen(int a_Seed);
|
||||
|
||||
void Initialize(cIniFile & a_IniFile);
|
||||
|
||||
protected:
|
||||
|
||||
/// Seed for the noise
|
||||
@ -66,4 +64,5 @@ protected:
|
||||
|
||||
// cTerrainCompositionGen overrides:
|
||||
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 SendPluginMessage (const AString & a_Channel, const AString & a_Message) = 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 SendExperienceOrb (const cExpOrb & a_ExpOrb) = 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);
|
||||
cPlayer * Player = m_Client->GetPlayer();
|
||||
WriteByte (PACKET_RESPAWN);
|
||||
WriteInt ((int)(Player->GetWorld()->GetDimension()));
|
||||
WriteInt ((int)(a_World.GetDimension()));
|
||||
WriteByte (2); // TODO: Difficulty; 2 = Normal
|
||||
WriteChar ((char)Player->GetGameMode());
|
||||
WriteShort (256); // Current world height
|
||||
|
@ -72,7 +72,7 @@ public:
|
||||
virtual void SendPlayerSpawn (const cPlayer & a_Player) 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 SendRespawn (void) override;
|
||||
virtual void SendRespawn (const cWorld & a_World) override;
|
||||
virtual void SendExperience (void) override;
|
||||
virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) 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
|
||||
super::SendRespawn();
|
||||
super::SendRespawn(a_World);
|
||||
SendPlayerMaxSpeed();
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ protected:
|
||||
virtual void SendGameMode (eGameMode a_GameMode) override;
|
||||
virtual void SendHealth (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 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
|
||||
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((Byte)Player->GetEffectiveGameMode());
|
||||
Pkt.WriteString("default");
|
||||
|
@ -104,7 +104,7 @@ public:
|
||||
virtual void SendPlayerSpawn (const cPlayer & a_Player) 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 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 SendExperience (void) 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);
|
||||
m_Protocol->SendRespawn();
|
||||
m_Protocol->SendRespawn(a_World);
|
||||
}
|
||||
|
||||
|
||||
|
@ -107,7 +107,7 @@ public:
|
||||
virtual void SendPlayerSpawn (const cPlayer & a_Player) 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 SendRespawn (void) override;
|
||||
virtual void SendRespawn (const cWorld & a_World) override;
|
||||
virtual void SendExperience (void) override;
|
||||
virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override;
|
||||
virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override;
|
||||
|
21
src/Root.cpp
21
src/Root.cpp
@ -320,7 +320,7 @@ cWorld * cRoot::CreateAndInitializeWorld(const AString & a_WorldName)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
cWorld* NewWorld = new cWorld(a_WorldName.c_str());
|
||||
cWorld * NewWorld = new cWorld(a_WorldName.c_str());
|
||||
m_WorldsByName[a_WorldName] = NewWorld;
|
||||
NewWorld->Start();
|
||||
NewWorld->InitializeSpawn();
|
||||
@ -372,7 +372,7 @@ void cRoot::UnloadWorlds(void)
|
||||
|
||||
|
||||
|
||||
cWorld* cRoot::GetDefaultWorld()
|
||||
cWorld * cRoot::GetDefaultWorld()
|
||||
{
|
||||
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 );
|
||||
if( itr != m_WorldsByName.end() )
|
||||
WorldMap::iterator itr = m_WorldsByName.find(a_WorldName);
|
||||
if (itr != m_WorldsByName.end())
|
||||
{
|
||||
return itr->second;
|
||||
return 0;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -398,9 +400,12 @@ bool cRoot::ForEachWorld(cWorldListCallback & a_Callback)
|
||||
for (WorldMap::iterator itr = m_WorldsByName.begin(), itr2 = itr; itr != m_WorldsByName.end(); itr = itr2)
|
||||
{
|
||||
++itr2;
|
||||
if (a_Callback.Item(itr->second))
|
||||
if (itr->second != NULL)
|
||||
{
|
||||
return false;
|
||||
if (a_Callback.Item(itr->second))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -571,6 +571,37 @@ void cWorld::Start(void)
|
||||
m_GameMode = (eGameMode) Clamp(GameMode, (int)gmSurvival, (int)gmAdventure);
|
||||
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:
|
||||
const char * DefaultMonsters = "";
|
||||
switch (m_Dimension)
|
||||
|
Loading…
Reference in New Issue
Block a user