1
0
Fork 0

Implemented end and nether portals

This commit is contained in:
Tiger Wang 2014-05-31 22:28:51 +01:00
parent 60a37c1370
commit 8bff3e5af2
23 changed files with 254 additions and 92 deletions

View File

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

View File

@ -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 */

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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)
{

View File

@ -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, ",");

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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