From 3d94a7ea560f00585f454476928ba4ba3ec28ef7 Mon Sep 17 00:00:00 2001 From: Howaner Date: Wed, 17 Sep 2014 17:45:13 +0200 Subject: Created MobSpawnerEntity class. --- src/BlockEntities/BlockEntity.h | 2 +- src/BlockEntities/CMakeLists.txt | 2 + src/BlockEntities/MobSpawnerEntity.cpp | 92 ++++++++++++++++++++++++++++++++++ src/BlockEntities/MobSpawnerEntity.h | 70 ++++++++++++++++++++++++++ 4 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 src/BlockEntities/MobSpawnerEntity.cpp create mode 100644 src/BlockEntities/MobSpawnerEntity.h diff --git a/src/BlockEntities/BlockEntity.h b/src/BlockEntities/BlockEntity.h index 5710f8543..e9d3a00ae 100644 --- a/src/BlockEntities/BlockEntity.h +++ b/src/BlockEntities/BlockEntity.h @@ -87,7 +87,7 @@ public: virtual void SendTo(cClientHandle & a_Client) = 0; /// Ticks the entity; returns true if the chunk should be marked as dirty as a result of this ticking. By default does nothing. - virtual bool Tick(float a_Dt, cChunk & /* a_Chunk */) + virtual bool Tick(float a_Dt, cChunk & a_Chunk) { UNUSED(a_Dt); return false; diff --git a/src/BlockEntities/CMakeLists.txt b/src/BlockEntities/CMakeLists.txt index d87594b0d..5f4af288d 100644 --- a/src/BlockEntities/CMakeLists.txt +++ b/src/BlockEntities/CMakeLists.txt @@ -18,6 +18,7 @@ SET (SRCS HopperEntity.cpp JukeboxEntity.cpp MobHeadEntity.cpp + MobSpawnerEntity.cpp NoteEntity.cpp SignEntity.cpp) @@ -36,6 +37,7 @@ SET (HDRS HopperEntity.h JukeboxEntity.h MobHeadEntity.h + MobSpawnerEntity.h NoteEntity.h SignEntity.h) diff --git a/src/BlockEntities/MobSpawnerEntity.cpp b/src/BlockEntities/MobSpawnerEntity.cpp new file mode 100644 index 000000000..1db1aad9b --- /dev/null +++ b/src/BlockEntities/MobSpawnerEntity.cpp @@ -0,0 +1,92 @@ + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "MobSpawnerEntity.h" +#include "../World.h" +#include "json/json.h" + + + + + +cMobSpawnerEntity::cMobSpawnerEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) + : super(E_BLOCK_MOB_SPAWNER, a_BlockX, a_BlockY, a_BlockZ, a_World) + , m_EntityName("Pig") + , m_SpawnDelay(20) + , m_MinSpawnDelay(200) + , m_MaxSpawnDelay(800) + , m_MaxNearbyEntities(6) + , m_ActivatingRange(16) + , m_SpawnRange(4) +{ +} + + + + + +cMobSpawnerEntity::~cMobSpawnerEntity() +{ + +} + + + + + +bool cMobSpawnerEntity::Tick(float a_Dt, cChunk & a_Chunk) +{ + +} + + + + + +void cMobSpawnerEntity::UsedBy(cPlayer * a_Player) +{ + if (IsPlayingRecord()) + { + EjectRecord(); + } + else + { + const cItem & HeldItem = a_Player->GetEquippedItem(); + if (PlayRecord(HeldItem.m_ItemType)) + { + a_Player->GetInventory().RemoveOneEquippedItem(); + } + } +} + + + + + +bool cMobSpawnerEntity::LoadFromJson(const Json::Value & a_Value) +{ + m_PosX = a_Value.get("x", 0).asInt(); + m_PosY = a_Value.get("y", 0).asInt(); + m_PosZ = a_Value.get("z", 0).asInt(); + + m_Record = a_Value.get("Record", 0).asInt(); + + return true; +} + + + + + +void cMobSpawnerEntity::SaveToJson(Json::Value & a_Value) +{ + a_Value["x"] = m_PosX; + a_Value["y"] = m_PosY; + a_Value["z"] = m_PosZ; + + a_Value["Record"] = m_Record; +} + + + + diff --git a/src/BlockEntities/MobSpawnerEntity.h b/src/BlockEntities/MobSpawnerEntity.h new file mode 100644 index 000000000..b173214a5 --- /dev/null +++ b/src/BlockEntities/MobSpawnerEntity.h @@ -0,0 +1,70 @@ + +#pragma once + +#include "BlockEntity.h" +#include "../Entities/Player.h" + + + + + +namespace Json +{ + class Value; +} + + + + + +// tolua_begin + +class cMobSpawnerEntity : + public cBlockEntity +{ + typedef cBlockEntity super; +public: + + // tolua_end + + cMobSpawnerEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); + virtual ~cMobSpawnerEntity(); + + bool LoadFromJson(const Json::Value & a_Value); + virtual void SaveToJson(Json::Value & a_Value) override; + + virtual bool Tick(float a_Dt, cChunk & a_Chunk) override; + + // tolua_begin + + /** Returns the entity who will be spawn by this mob spawner. */ + const AString & GetEntityName(void) const { return m_EntityName; } + + // tolua_end + + static const char * GetClassStatic(void) { return "cMobSpawnerEntity"; } + + virtual void UsedBy(cPlayer * a_Player) override; + virtual void SendTo(cClientHandle &) override {} + +private: + /** The entity to spawn. */ + AString m_EntityName; + + int m_SpawnDelay; + int m_MinSpawnDelay; + int m_MaxSpawnDelay; + + /** The mob spawner spawns only mobs when the count of nearby entities (without players) is lesser than this number. */ + short m_MaxNearbyEntities; + + /** The mob spawner spawns only mobs when a player is in the range of the mob spawner. */ + short m_ActivatingRange; + + /** The range coefficient for spawning entities around. */ + short m_SpawnRange; +} ; // tolua_end + + + + -- cgit v1.2.3 From 718eb227abe3b9a0e5277d663e32c6e10d51ab52 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 19 Sep 2014 23:00:54 +0200 Subject: Implemented mob spawner. --- src/BlockEntities/BlockEntity.cpp | 6 +- src/BlockEntities/MobSpawnerEntity.cpp | 310 +++++++++++++++++++++++++++++--- src/BlockEntities/MobSpawnerEntity.h | 50 +++--- src/Blocks/BlockMobSpawner.h | 12 ++ src/Chunk.cpp | 7 +- src/MobSpawner.cpp | 13 +- src/MobSpawner.h | 5 +- src/Mobs/Monster.h | 2 +- src/Protocol/Protocol17x.cpp | 14 +- src/WorldStorage/NBTChunkSerializer.cpp | 15 ++ src/WorldStorage/NBTChunkSerializer.h | 26 +-- 11 files changed, 393 insertions(+), 67 deletions(-) diff --git a/src/BlockEntities/BlockEntity.cpp b/src/BlockEntities/BlockEntity.cpp index 05ad03a3d..a969f493e 100644 --- a/src/BlockEntities/BlockEntity.cpp +++ b/src/BlockEntities/BlockEntity.cpp @@ -14,10 +14,11 @@ #include "FlowerPotEntity.h" #include "FurnaceEntity.h" #include "HopperEntity.h" +#include "MobHeadEntity.h" +#include "MobSpawnerEntity.h" #include "JukeboxEntity.h" #include "NoteEntity.h" #include "SignEntity.h" -#include "MobHeadEntity.h" @@ -35,8 +36,9 @@ cBlockEntity * cBlockEntity::CreateByBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE case E_BLOCK_ENDER_CHEST: return new cEnderChestEntity (a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_FLOWER_POT: return new cFlowerPotEntity (a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_FURNACE: return new cFurnaceEntity (a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_World); - case E_BLOCK_HEAD: return new cMobHeadEntity (a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_HOPPER: return new cHopperEntity (a_BlockX, a_BlockY, a_BlockZ, a_World); + case E_BLOCK_HEAD: return new cMobHeadEntity (a_BlockX, a_BlockY, a_BlockZ, a_World); + case E_BLOCK_MOB_SPAWNER: return new cMobSpawnerEntity (a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_JUKEBOX: return new cJukeboxEntity (a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_LIT_FURNACE: return new cFurnaceEntity (a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_World); case E_BLOCK_SIGN_POST: return new cSignEntity (a_BlockType, a_BlockX, a_BlockY, a_BlockZ, a_World); diff --git a/src/BlockEntities/MobSpawnerEntity.cpp b/src/BlockEntities/MobSpawnerEntity.cpp index 1db1aad9b..2b963c3f9 100644 --- a/src/BlockEntities/MobSpawnerEntity.cpp +++ b/src/BlockEntities/MobSpawnerEntity.cpp @@ -2,22 +2,22 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "MobSpawnerEntity.h" -#include "../World.h" #include "json/json.h" +#include "../World.h" +#include "../FastRandom.h" +#include "../MobSpawner.h" +#include "../Items/ItemSpawnEgg.h" + cMobSpawnerEntity::cMobSpawnerEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) : super(E_BLOCK_MOB_SPAWNER, a_BlockX, a_BlockY, a_BlockZ, a_World) - , m_EntityName("Pig") - , m_SpawnDelay(20) - , m_MinSpawnDelay(200) - , m_MaxSpawnDelay(800) - , m_MaxNearbyEntities(6) - , m_ActivatingRange(16) - , m_SpawnRange(4) + , m_Entity(cMonster::mtPig) + , m_SpawnDelay(100) + , m_IsActive(false) { } @@ -25,37 +25,170 @@ cMobSpawnerEntity::cMobSpawnerEntity(int a_BlockX, int a_BlockY, int a_BlockZ, c -cMobSpawnerEntity::~cMobSpawnerEntity() +void cMobSpawnerEntity::SendTo(cClientHandle & a_Client) { - + a_Client.SendUpdateBlockEntity(*this); } -bool cMobSpawnerEntity::Tick(float a_Dt, cChunk & a_Chunk) +void cMobSpawnerEntity::UsedBy(cPlayer * a_Player) +{ + if (a_Player->GetEquippedItem().m_ItemType == E_ITEM_SPAWN_EGG) + { + cMonster::eType MonsterType = cItemSpawnEggHandler::ItemDamageToMonsterType(a_Player->GetEquippedItem().m_ItemDamage); + if (MonsterType == cMonster::mtInvalidType) + { + return; + } + + m_Entity = MonsterType; + ResetTimer(); + if (!a_Player->IsGameModeCreative()) + { + a_Player->GetInventory().RemoveOneEquippedItem(); + } + LOGD("Changed monster spawner entity to %s!", GetEntityName().c_str()); + } +} + + + + + +void cMobSpawnerEntity::UpdateActiveState(void) { - + if (GetNearbyPlayersNum() > 0) + { + m_IsActive = true; + } + else + { + m_IsActive = false; + } } -void cMobSpawnerEntity::UsedBy(cPlayer * a_Player) +bool cMobSpawnerEntity::Tick(float a_Dt, cChunk & a_Chunk) { - if (IsPlayingRecord()) + // Update the active flag every 5 seconds + if ((m_World->GetWorldAge() % 100) == 0) + { + UpdateActiveState(); + } + + if (!m_IsActive) + { + return false; + } + + if (m_SpawnDelay <= 0) { - EjectRecord(); + SpawnEntity(); + return true; } else { - const cItem & HeldItem = a_Player->GetEquippedItem(); - if (PlayRecord(HeldItem.m_ItemType)) + m_SpawnDelay--; + } + return false; +} + + + + + +void cMobSpawnerEntity::ResetTimer(void) +{ + m_SpawnDelay = 200 + m_World->GetTickRandomNumber(600); + m_World->BroadcastBlockEntity(m_PosX, m_PosY, m_PosZ); +} + + + + + +void cMobSpawnerEntity::SpawnEntity(void) +{ + int NearbyEntities = GetNearbyEntityNum(m_Entity); + if (NearbyEntities >= 6) + { + ResetTimer(); + return; + } + + class cCallback : public cChunkCallback + { + public: + cCallback(int a_RelX, int a_RelY, int a_RelZ, cMonster::eType a_MobType, int a_NearbyEntitiesNum) : + m_RelX(a_RelX), + m_RelY(a_RelY), + m_RelZ(a_RelZ), + m_MobType(a_MobType), + m_NearbyEntitiesNum(a_NearbyEntitiesNum) { - a_Player->GetInventory().RemoveOneEquippedItem(); } + + virtual bool Item(cChunk * a_Chunk) + { + cFastRandom Random; + + bool EntitiesSpawned = false; + for (size_t i = 0; i < 4; i++) + { + if (m_NearbyEntitiesNum >= 6) + { + break; + } + + int RelX = (int) (m_RelX + (double)(Random.NextFloat() - Random.NextFloat()) * 4.0); + int RelY = m_RelY + Random.NextInt(3) - 1; + int RelZ = (int) (m_RelZ + (double)(Random.NextFloat() - Random.NextFloat()) * 4.0); + + cChunk * Chunk = a_Chunk->GetRelNeighborChunkAdjustCoords(RelX, RelZ); + if ((Chunk == NULL) || !Chunk->IsValid()) + { + continue; + } + EMCSBiome Biome = Chunk->GetBiomeAt(RelX, RelZ); + + if (cMobSpawner::CanSpawnHere(Chunk, RelX, RelY, RelZ, m_MobType, Biome)) + { + double PosX = Chunk->GetPosX() * cChunkDef::Width + RelX; + double PosZ = Chunk->GetPosZ() * cChunkDef::Width + RelZ; + + cMonster * Monster = cMonster::NewMonsterFromType(m_MobType); + if (Monster == NULL) + { + continue; + } + + Monster->SetPosition(PosX, RelY, PosZ); + Monster->SetYaw(Random.NextFloat() * 360.0f); + if (Chunk->GetWorld()->SpawnMobFinalize(Monster) != cMonster::mtInvalidType) + { + EntitiesSpawned = true; + Chunk->BroadcastSoundParticleEffect(2004, (int)(PosX * 8.0), (int)(RelY * 8.0), (int)(PosZ * 8.0), 0); + m_NearbyEntitiesNum++; + } + } + } + return EntitiesSpawned; + } + protected: + int m_RelX, m_RelY, m_RelZ; + cMonster::eType m_MobType; + int m_NearbyEntitiesNum; + } Callback(m_RelX, m_PosY, m_RelZ, m_Entity, NearbyEntities); + + if (m_World->DoWithChunk(GetChunkX(), GetChunkZ(), Callback)) + { + ResetTimer(); } } @@ -69,8 +202,6 @@ bool cMobSpawnerEntity::LoadFromJson(const Json::Value & a_Value) m_PosY = a_Value.get("y", 0).asInt(); m_PosZ = a_Value.get("z", 0).asInt(); - m_Record = a_Value.get("Record", 0).asInt(); - return true; } @@ -83,8 +214,145 @@ void cMobSpawnerEntity::SaveToJson(Json::Value & a_Value) a_Value["x"] = m_PosX; a_Value["y"] = m_PosY; a_Value["z"] = m_PosZ; +} + + + + + +AString cMobSpawnerEntity::GetEntityName() const +{ + switch (m_Entity) + { + case cMonster::mtBat: return "Bat"; + case cMonster::mtBlaze: return "Blaze"; + case cMonster::mtCaveSpider: return "CaveSpider"; + case cMonster::mtChicken: return "Chicken"; + case cMonster::mtCow: return "Cow"; + case cMonster::mtCreeper: return "Creeper"; + case cMonster::mtEnderDragon: return "EnderDragon"; + case cMonster::mtEnderman: return "Enderman"; + case cMonster::mtGhast: return "Ghast"; + case cMonster::mtGiant: return "Giant"; + case cMonster::mtHorse: return "EntityHorse"; + case cMonster::mtIronGolem: return "VillagerGolem"; + case cMonster::mtMagmaCube: return "LavaSlime"; + case cMonster::mtMooshroom: return "MushroomCow"; + case cMonster::mtOcelot: return "Ozelot"; + case cMonster::mtPig: return "Pig"; + case cMonster::mtSheep: return "Sheep"; + case cMonster::mtSilverfish: return "Silverfish"; + case cMonster::mtSkeleton: return "Skeleton"; + case cMonster::mtSlime: return "Slime"; + case cMonster::mtSnowGolem: return "SnowMan"; + case cMonster::mtSpider: return "Spider"; + case cMonster::mtSquid: return "Squid"; + case cMonster::mtVillager: return "Villager"; + case cMonster::mtWitch: return "Witch"; + case cMonster::mtWither: return "WitherBoss"; + case cMonster::mtWolf: return "Wolf"; + case cMonster::mtZombie: return "Zombie"; + case cMonster::mtZombiePigman: return "PigZombie"; + default: + { + ASSERT(!"Unknown monster type!"); + return "Pig"; + } + } +} + + + + + +int cMobSpawnerEntity::GetNearbyPlayersNum(void) +{ + Vector3d SpawnerPos(m_PosX + 0.5, m_PosY + 0.5, m_PosZ + 0.5); + int NumPlayers = 0; + + class cCallback : public cChunkDataCallback + { + public: + cCallback(Vector3d a_SpawnerPos, int & a_NumPlayers) : + m_SpawnerPos(a_SpawnerPos), + m_NumPlayers(a_NumPlayers) + { + } + + virtual void Entity(cEntity * a_Entity) override + { + if (!a_Entity->IsPlayer()) + { + return; + } + + if ((m_SpawnerPos - a_Entity->GetPosition()).Length() <= 16) + { + m_NumPlayers++; + } + } + + protected: + Vector3d m_SpawnerPos; + int & m_NumPlayers; + } Callback(SpawnerPos, NumPlayers); + + int ChunkX = GetChunkX(); + int ChunkZ = GetChunkZ(); + m_World->ForEachChunkInRect(ChunkX - 1, ChunkX + 1, ChunkZ - 1, ChunkZ + 1, Callback); + + return NumPlayers; +} + + + + + +int cMobSpawnerEntity::GetNearbyEntityNum(cMonster::eType a_EntityType) +{ + Vector3d SpawnerPos(m_PosX + 0.5, m_PosY + 0.5, m_PosZ + 0.5); + int NumEntities = 0; + + class cCallback : public cChunkDataCallback + { + public: + cCallback(Vector3d a_SpawnerPos, cMonster::eType a_EntityType, int & a_NumEntities) : + m_SpawnerPos(a_SpawnerPos), + m_EntityType(a_EntityType), + m_NumEntities(a_NumEntities) + { + } + + virtual void Entity(cEntity * a_Entity) override + { + if (!a_Entity->IsMob()) + { + return; + } + + cMonster * Mob = (cMonster *)a_Entity; + if (Mob->GetMobType() != m_EntityType) + { + return; + } + + if (((m_SpawnerPos - a_Entity->GetPosition()).Length() <= 8) && (Diff(m_SpawnerPos.y, a_Entity->GetPosY()) <= 4.0)) + { + m_NumEntities++; + } + } + + protected: + Vector3d m_SpawnerPos; + cMonster::eType m_EntityType; + int & m_NumEntities; + } Callback(SpawnerPos, a_EntityType, NumEntities); + + int ChunkX = GetChunkX(); + int ChunkZ = GetChunkZ(); + m_World->ForEachChunkInRect(ChunkX - 1, ChunkX + 1, ChunkZ - 1, ChunkZ + 1, Callback); - a_Value["Record"] = m_Record; + return NumEntities; } diff --git a/src/BlockEntities/MobSpawnerEntity.h b/src/BlockEntities/MobSpawnerEntity.h index b173214a5..b12a97d65 100644 --- a/src/BlockEntities/MobSpawnerEntity.h +++ b/src/BlockEntities/MobSpawnerEntity.h @@ -28,41 +28,51 @@ public: // tolua_end cMobSpawnerEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); - virtual ~cMobSpawnerEntity(); - - bool LoadFromJson(const Json::Value & a_Value); - virtual void SaveToJson(Json::Value & a_Value) override; + virtual void SendTo(cClientHandle & a_Client) override; + virtual void UsedBy(cPlayer * a_Player) override; virtual bool Tick(float a_Dt, cChunk & a_Chunk) override; // tolua_begin - /** Returns the entity who will be spawn by this mob spawner. */ - const AString & GetEntityName(void) const { return m_EntityName; } + /** Upate the active flag from the mob spawner. This function will called every 5 seconds from the Tick() function. */ + void UpdateActiveState(void); + + /** Sets the spawn delay to a new random value. */ + void ResetTimer(void); + + /** Spawns the entity. This function automaticly change the spawn delay! */ + void SpawnEntity(void); + + /** Returns the entity type who will be spawn by this mob spawner. */ + cMonster::eType GetEntity(void) const { return m_Entity; } + + /** Sets the entity type who will be spawn by this mob spawner. */ + void SetEntity(cMonster::eType a_EntityType) { m_Entity = a_EntityType; } + + /** Returns the entity name. (Required by the protocol) */ + AString GetEntityName(void) const; + + /** Returns the spawn delay. */ + int GetSpawnDelay(void) const { return m_SpawnDelay; } + + int GetNearbyPlayersNum(void); + int GetNearbyEntityNum(cMonster::eType a_EntityType); // tolua_end + bool LoadFromJson(const Json::Value & a_Value); + virtual void SaveToJson(Json::Value & a_Value) override; + static const char * GetClassStatic(void) { return "cMobSpawnerEntity"; } - - virtual void UsedBy(cPlayer * a_Player) override; - virtual void SendTo(cClientHandle &) override {} private: /** The entity to spawn. */ - AString m_EntityName; + cMonster::eType m_Entity; int m_SpawnDelay; - int m_MinSpawnDelay; - int m_MaxSpawnDelay; - - /** The mob spawner spawns only mobs when the count of nearby entities (without players) is lesser than this number. */ - short m_MaxNearbyEntities; - - /** The mob spawner spawns only mobs when a player is in the range of the mob spawner. */ - short m_ActivatingRange; - /** The range coefficient for spawning entities around. */ - short m_SpawnRange; + bool m_IsActive; } ; // tolua_end diff --git a/src/Blocks/BlockMobSpawner.h b/src/Blocks/BlockMobSpawner.h index a51fbaafc..d5e7c273f 100644 --- a/src/Blocks/BlockMobSpawner.h +++ b/src/Blocks/BlockMobSpawner.h @@ -19,6 +19,18 @@ public: } + virtual void OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override + { + a_ChunkInterface.UseBlockEntity(a_Player, a_BlockX, a_BlockY, a_BlockZ); + } + + + virtual bool IsUseable() override + { + return true; + } + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { // No pickups diff --git a/src/Chunk.cpp b/src/Chunk.cpp index e75acb03b..c799f65fd 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -16,13 +16,14 @@ #include "BlockEntities/ChestEntity.h" #include "BlockEntities/DispenserEntity.h" #include "BlockEntities/DropperEntity.h" +#include "BlockEntities/FlowerPotEntity.h" #include "BlockEntities/FurnaceEntity.h" #include "BlockEntities/HopperEntity.h" #include "BlockEntities/JukeboxEntity.h" +#include "BlockEntities/MobHeadEntity.h" +#include "BlockEntities/MobSpawnerEntity.h" #include "BlockEntities/NoteEntity.h" #include "BlockEntities/SignEntity.h" -#include "BlockEntities/MobHeadEntity.h" -#include "BlockEntities/FlowerPotEntity.h" #include "Entities/Pickup.h" #include "Item.h" #include "Noise.h" @@ -1344,6 +1345,7 @@ void cChunk::CreateBlockEntities(void) case E_BLOCK_NOTE_BLOCK: case E_BLOCK_JUKEBOX: case E_BLOCK_FLOWER_POT: + case E_BLOCK_MOB_SPAWNER: { if (!HasBlockEntityAt(x + m_PosX * Width, y, z + m_PosZ * Width)) { @@ -1475,6 +1477,7 @@ void cChunk::SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, case E_BLOCK_NOTE_BLOCK: case E_BLOCK_JUKEBOX: case E_BLOCK_FLOWER_POT: + case E_BLOCK_MOB_SPAWNER: { AddBlockEntity(cBlockEntity::CreateByBlockType(a_BlockType, a_BlockMeta, WorldPos.x, WorldPos.y, WorldPos.z, m_World)); break; diff --git a/src/MobSpawner.cpp b/src/MobSpawner.cpp index db05b70af..2350ffe85 100644 --- a/src/MobSpawner.cpp +++ b/src/MobSpawner.cpp @@ -126,8 +126,9 @@ cMonster::eType cMobSpawner::ChooseMobType(EMCSBiome a_Biome) bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, cMonster::eType a_MobType, EMCSBiome a_Biome) { + cFastRandom Random; BLOCKTYPE TargetBlock = E_BLOCK_AIR; - if (m_AllowedTypes.find(a_MobType) != m_AllowedTypes.end() && a_Chunk->UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, TargetBlock)) + if (a_Chunk->UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, TargetBlock)) { if ((a_RelY + 1 > cChunkDef::Height) || (a_RelY - 1 < 0)) { @@ -177,7 +178,7 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R (BlockBelow == E_BLOCK_GRASS) || (BlockBelow == E_BLOCK_LEAVES) || (BlockBelow == E_BLOCK_NEW_LEAVES) ) && (a_RelY >= 62) && - (m_Random.NextInt(3, a_Biome) != 0) + (Random.NextInt(3, a_Biome) != 0) ); } @@ -238,7 +239,7 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R (!cBlockInfo::IsTransparent(BlockBelow)) && (SkyLight <= 7) && (BlockLight <= 7) && - (m_Random.NextInt(2, a_Biome) == 0) + (Random.NextInt(2, a_Biome) == 0) ); } @@ -262,7 +263,7 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R (TargetBlock == E_BLOCK_AIR) && (BlockAbove == E_BLOCK_AIR) && (!cBlockInfo::IsTransparent(BlockBelow)) && - (m_Random.NextInt(20, a_Biome) == 0) + (Random.NextInt(20, a_Biome) == 0) ); } @@ -322,8 +323,8 @@ cMonster* cMobSpawner::TryToSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, // Make sure we are looking at the right chunk to spawn in a_Chunk = a_Chunk->GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ); - - if (CanSpawnHere(a_Chunk, a_RelX, a_RelY, a_RelZ, m_MobType, a_Biome)) + + if ((m_AllowedTypes.find(m_MobType) != m_AllowedTypes.end()) && CanSpawnHere(a_Chunk, a_RelX, a_RelY, a_RelZ, m_MobType, a_Biome)) { cMonster * newMob = cMonster::NewMonsterFromType(m_MobType); if (newMob) diff --git a/src/MobSpawner.h b/src/MobSpawner.h index f3c56fe2d..e139f6923 100644 --- a/src/MobSpawner.h +++ b/src/MobSpawner.h @@ -51,9 +51,10 @@ public : typedef const std::set tSpawnedContainer; tSpawnedContainer & getSpawned(void); + /** Returns true if specified type of mob can spawn on specified block */ + static bool CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, cMonster::eType a_MobType, EMCSBiome a_Biome); + protected : - // return true if specified type of mob can spawn on specified block - bool CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, cMonster::eType a_MobType, EMCSBiome a_Biome); // return a random type that can spawn on specified biome. // returns E_ENTITY_TYPE_DONOTUSE if none is possible diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h index ca3c04c23..86c882d47 100644 --- a/src/Mobs/Monster.h +++ b/src/Mobs/Monster.h @@ -96,7 +96,7 @@ public: virtual bool ReachedDestination(void); // tolua_begin - eType GetMobType(void) const {return m_MobType; } + eType GetMobType(void) const { return m_MobType; } eFamily GetMobFamily(void) const; // tolua_end diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 7d80e79fb..49a62e4f3 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -40,6 +40,7 @@ Implements the 1.7.x protocol classes: #include "../BlockEntities/BeaconEntity.h" #include "../BlockEntities/CommandBlockEntity.h" #include "../BlockEntities/MobHeadEntity.h" +#include "../BlockEntities/MobSpawnerEntity.h" #include "../BlockEntities/FlowerPotEntity.h" #include "Bindings/PluginManager.h" @@ -2695,6 +2696,18 @@ void cProtocol172::cPacketizer::WriteBlockEntity(const cBlockEntity & a_BlockEnt Writer.AddString("id", "FlowerPot"); // "Tile Entity ID" - MC wiki; vanilla server always seems to send this though break; } + case E_BLOCK_MOB_SPAWNER: + { + cMobSpawnerEntity & MobSpawnerEntity = (cMobSpawnerEntity &)a_BlockEntity; + + Writer.AddInt("x", MobSpawnerEntity.GetPosX()); + Writer.AddInt("y", MobSpawnerEntity.GetPosY()); + Writer.AddInt("z", MobSpawnerEntity.GetPosZ()); + Writer.AddString("EntityId", MobSpawnerEntity.GetEntityName()); + Writer.AddShort("Delay", MobSpawnerEntity.GetSpawnDelay()); + Writer.AddString("id", "MobSpawner"); + break; + } default: break; } @@ -3151,4 +3164,3 @@ void cProtocol176::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) - diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index 68e541eba..a2bf3f8e1 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -18,6 +18,7 @@ #include "../BlockEntities/FurnaceEntity.h" #include "../BlockEntities/HopperEntity.h" #include "../BlockEntities/JukeboxEntity.h" +#include "../BlockEntities/MobSpawnerEntity.h" #include "../BlockEntities/NoteEntity.h" #include "../BlockEntities/SignEntity.h" #include "../BlockEntities/MobHeadEntity.h" @@ -278,6 +279,19 @@ void cNBTChunkSerializer::AddJukeboxEntity(cJukeboxEntity * a_Jukebox) +void cNBTChunkSerializer::AddMobSpawnerEntity(cMobSpawnerEntity * a_MobSpawner) +{ + m_Writer.BeginCompound(""); + AddBasicTileEntity(a_MobSpawner, "MobSpawner"); + m_Writer.AddString("EntityId", a_MobSpawner->GetEntityName()); + m_Writer.AddShort("Delay", (Int16)a_MobSpawner->GetSpawnDelay()); + m_Writer.EndCompound(); +} + + + + + void cNBTChunkSerializer::AddNoteEntity(cNoteEntity * a_Note) { m_Writer.BeginCompound(""); @@ -862,6 +876,7 @@ void cNBTChunkSerializer::BlockEntity(cBlockEntity * a_Entity) case E_BLOCK_HOPPER: AddHopperEntity ((cHopperEntity *) a_Entity); break; case E_BLOCK_JUKEBOX: AddJukeboxEntity ((cJukeboxEntity *) a_Entity); break; case E_BLOCK_LIT_FURNACE: AddFurnaceEntity ((cFurnaceEntity *) a_Entity); break; + case E_BLOCK_MOB_SPAWNER: AddMobSpawnerEntity ((cMobSpawnerEntity *) a_Entity); break; case E_BLOCK_NOTE_BLOCK: AddNoteEntity ((cNoteEntity *) a_Entity); break; case E_BLOCK_SIGN_POST: AddSignEntity ((cSignEntity *) a_Entity); break; case E_BLOCK_TRAPPED_CHEST: AddChestEntity ((cChestEntity *) a_Entity, a_Entity->GetBlockType()); break; diff --git a/src/WorldStorage/NBTChunkSerializer.h b/src/WorldStorage/NBTChunkSerializer.h index 4c229a65c..7ff4b0e9b 100644 --- a/src/WorldStorage/NBTChunkSerializer.h +++ b/src/WorldStorage/NBTChunkSerializer.h @@ -32,6 +32,7 @@ class cJukeboxEntity; class cNoteEntity; class cSignEntity; class cMobHeadEntity; +class cMobSpawnerEntity; class cFlowerPotEntity; class cFallingBlock; class cMinecart; @@ -93,19 +94,20 @@ protected: void AddItemGrid(const cItemGrid & a_Grid, int a_BeginSlotNum = 0); // Block entities: - void AddBasicTileEntity(cBlockEntity * a_Entity, const char * a_EntityTypeID); - void AddBeaconEntity (cBeaconEntity * a_Entity); - void AddChestEntity (cChestEntity * a_Entity, BLOCKTYPE a_ChestType); - void AddDispenserEntity(cDispenserEntity * a_Entity); - void AddDropperEntity (cDropperEntity * a_Entity); - void AddFurnaceEntity (cFurnaceEntity * a_Furnace); - void AddHopperEntity (cHopperEntity * a_Entity); - void AddJukeboxEntity (cJukeboxEntity * a_Jukebox); - void AddNoteEntity (cNoteEntity * a_Note); - void AddSignEntity (cSignEntity * a_Sign); - void AddMobHeadEntity (cMobHeadEntity * a_MobHead); + void AddBasicTileEntity (cBlockEntity * a_Entity, const char * a_EntityTypeID); + void AddBeaconEntity (cBeaconEntity * a_Entity); + void AddChestEntity (cChestEntity * a_Entity, BLOCKTYPE a_ChestType); + void AddDispenserEntity (cDispenserEntity * a_Entity); + void AddDropperEntity (cDropperEntity * a_Entity); + void AddFurnaceEntity (cFurnaceEntity * a_Furnace); + void AddHopperEntity (cHopperEntity * a_Entity); + void AddJukeboxEntity (cJukeboxEntity * a_Jukebox); + void AddMobSpawnerEntity (cMobSpawnerEntity * a_MobSpawner); + void AddNoteEntity (cNoteEntity * a_Note); + void AddSignEntity (cSignEntity * a_Sign); + void AddMobHeadEntity (cMobHeadEntity * a_MobHead); void AddCommandBlockEntity(cCommandBlockEntity * a_CmdBlock); - void AddFlowerPotEntity(cFlowerPotEntity * a_FlowerPot); + void AddFlowerPotEntity (cFlowerPotEntity * a_FlowerPot); // Entities: void AddBasicEntity (cEntity * a_Entity, const AString & a_ClassName); -- cgit v1.2.3 From 5e71d5299c9cc8c80166ab202f376ffb086a2fa7 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 27 Sep 2014 00:07:17 +0200 Subject: Fixed compile errors. --- src/BlockEntities/MobSpawnerEntity.cpp | 76 +++++++++++++++++----------------- src/BlockEntities/MobSpawnerEntity.h | 8 ++-- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/src/BlockEntities/MobSpawnerEntity.cpp b/src/BlockEntities/MobSpawnerEntity.cpp index 2b963c3f9..0d14ad647 100644 --- a/src/BlockEntities/MobSpawnerEntity.cpp +++ b/src/BlockEntities/MobSpawnerEntity.cpp @@ -15,7 +15,7 @@ cMobSpawnerEntity::cMobSpawnerEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) : super(E_BLOCK_MOB_SPAWNER, a_BlockX, a_BlockY, a_BlockZ, a_World) - , m_Entity(cMonster::mtPig) + , m_Entity(mtPig) , m_SpawnDelay(100) , m_IsActive(false) { @@ -39,7 +39,7 @@ void cMobSpawnerEntity::UsedBy(cPlayer * a_Player) if (a_Player->GetEquippedItem().m_ItemType == E_ITEM_SPAWN_EGG) { cMonster::eType MonsterType = cItemSpawnEggHandler::ItemDamageToMonsterType(a_Player->GetEquippedItem().m_ItemDamage); - if (MonsterType == cMonster::mtInvalidType) + if (MonsterType == mtInvalidType) { return; } @@ -115,7 +115,7 @@ void cMobSpawnerEntity::ResetTimer(void) void cMobSpawnerEntity::SpawnEntity(void) { - int NearbyEntities = GetNearbyEntityNum(m_Entity); + int NearbyEntities = GetNearbyMonsterNum(m_Entity); if (NearbyEntities >= 6) { ResetTimer(); @@ -125,7 +125,7 @@ void cMobSpawnerEntity::SpawnEntity(void) class cCallback : public cChunkCallback { public: - cCallback(int a_RelX, int a_RelY, int a_RelZ, cMonster::eType a_MobType, int a_NearbyEntitiesNum) : + cCallback(int a_RelX, int a_RelY, int a_RelZ, eMonsterType a_MobType, int a_NearbyEntitiesNum) : m_RelX(a_RelX), m_RelY(a_RelY), m_RelZ(a_RelZ), @@ -170,7 +170,7 @@ void cMobSpawnerEntity::SpawnEntity(void) Monster->SetPosition(PosX, RelY, PosZ); Monster->SetYaw(Random.NextFloat() * 360.0f); - if (Chunk->GetWorld()->SpawnMobFinalize(Monster) != cMonster::mtInvalidType) + if (Chunk->GetWorld()->SpawnMobFinalize(Monster) != mtInvalidType) { EntitiesSpawned = true; Chunk->BroadcastSoundParticleEffect(2004, (int)(PosX * 8.0), (int)(RelY * 8.0), (int)(PosZ * 8.0), 0); @@ -182,7 +182,7 @@ void cMobSpawnerEntity::SpawnEntity(void) } protected: int m_RelX, m_RelY, m_RelZ; - cMonster::eType m_MobType; + eMonsterType m_MobType; int m_NearbyEntitiesNum; } Callback(m_RelX, m_PosY, m_RelZ, m_Entity, NearbyEntities); @@ -224,35 +224,35 @@ AString cMobSpawnerEntity::GetEntityName() const { switch (m_Entity) { - case cMonster::mtBat: return "Bat"; - case cMonster::mtBlaze: return "Blaze"; - case cMonster::mtCaveSpider: return "CaveSpider"; - case cMonster::mtChicken: return "Chicken"; - case cMonster::mtCow: return "Cow"; - case cMonster::mtCreeper: return "Creeper"; - case cMonster::mtEnderDragon: return "EnderDragon"; - case cMonster::mtEnderman: return "Enderman"; - case cMonster::mtGhast: return "Ghast"; - case cMonster::mtGiant: return "Giant"; - case cMonster::mtHorse: return "EntityHorse"; - case cMonster::mtIronGolem: return "VillagerGolem"; - case cMonster::mtMagmaCube: return "LavaSlime"; - case cMonster::mtMooshroom: return "MushroomCow"; - case cMonster::mtOcelot: return "Ozelot"; - case cMonster::mtPig: return "Pig"; - case cMonster::mtSheep: return "Sheep"; - case cMonster::mtSilverfish: return "Silverfish"; - case cMonster::mtSkeleton: return "Skeleton"; - case cMonster::mtSlime: return "Slime"; - case cMonster::mtSnowGolem: return "SnowMan"; - case cMonster::mtSpider: return "Spider"; - case cMonster::mtSquid: return "Squid"; - case cMonster::mtVillager: return "Villager"; - case cMonster::mtWitch: return "Witch"; - case cMonster::mtWither: return "WitherBoss"; - case cMonster::mtWolf: return "Wolf"; - case cMonster::mtZombie: return "Zombie"; - case cMonster::mtZombiePigman: return "PigZombie"; + case mtBat: return "Bat"; + case mtBlaze: return "Blaze"; + case mtCaveSpider: return "CaveSpider"; + case mtChicken: return "Chicken"; + case mtCow: return "Cow"; + case mtCreeper: return "Creeper"; + case mtEnderDragon: return "EnderDragon"; + case mtEnderman: return "Enderman"; + case mtGhast: return "Ghast"; + case mtGiant: return "Giant"; + case mtHorse: return "EntityHorse"; + case mtIronGolem: return "VillagerGolem"; + case mtMagmaCube: return "LavaSlime"; + case mtMooshroom: return "MushroomCow"; + case mtOcelot: return "Ozelot"; + case mtPig: return "Pig"; + case mtSheep: return "Sheep"; + case mtSilverfish: return "Silverfish"; + case mtSkeleton: return "Skeleton"; + case mtSlime: return "Slime"; + case mtSnowGolem: return "SnowMan"; + case mtSpider: return "Spider"; + case mtSquid: return "Squid"; + case mtVillager: return "Villager"; + case mtWitch: return "Witch"; + case mtWither: return "WitherBoss"; + case mtWolf: return "Wolf"; + case mtZombie: return "Zombie"; + case mtZombiePigman: return "PigZombie"; default: { ASSERT(!"Unknown monster type!"); @@ -308,7 +308,7 @@ int cMobSpawnerEntity::GetNearbyPlayersNum(void) -int cMobSpawnerEntity::GetNearbyEntityNum(cMonster::eType a_EntityType) +int cMobSpawnerEntity::GetNearbyMonsterNum(eMonsterType a_EntityType) { Vector3d SpawnerPos(m_PosX + 0.5, m_PosY + 0.5, m_PosZ + 0.5); int NumEntities = 0; @@ -316,7 +316,7 @@ int cMobSpawnerEntity::GetNearbyEntityNum(cMonster::eType a_EntityType) class cCallback : public cChunkDataCallback { public: - cCallback(Vector3d a_SpawnerPos, cMonster::eType a_EntityType, int & a_NumEntities) : + cCallback(Vector3d a_SpawnerPos, eMonsterType a_EntityType, int & a_NumEntities) : m_SpawnerPos(a_SpawnerPos), m_EntityType(a_EntityType), m_NumEntities(a_NumEntities) @@ -344,7 +344,7 @@ int cMobSpawnerEntity::GetNearbyEntityNum(cMonster::eType a_EntityType) protected: Vector3d m_SpawnerPos; - cMonster::eType m_EntityType; + eMonsterType m_EntityType; int & m_NumEntities; } Callback(SpawnerPos, a_EntityType, NumEntities); diff --git a/src/BlockEntities/MobSpawnerEntity.h b/src/BlockEntities/MobSpawnerEntity.h index b12a97d65..7fec2699c 100644 --- a/src/BlockEntities/MobSpawnerEntity.h +++ b/src/BlockEntities/MobSpawnerEntity.h @@ -45,10 +45,10 @@ public: void SpawnEntity(void); /** Returns the entity type who will be spawn by this mob spawner. */ - cMonster::eType GetEntity(void) const { return m_Entity; } + eMonsterType GetEntity(void) const { return m_Entity; } /** Sets the entity type who will be spawn by this mob spawner. */ - void SetEntity(cMonster::eType a_EntityType) { m_Entity = a_EntityType; } + void SetEntity(eMonsterType a_EntityType) { m_Entity = a_EntityType; } /** Returns the entity name. (Required by the protocol) */ AString GetEntityName(void) const; @@ -57,7 +57,7 @@ public: int GetSpawnDelay(void) const { return m_SpawnDelay; } int GetNearbyPlayersNum(void); - int GetNearbyEntityNum(cMonster::eType a_EntityType); + int GetNearbyMonsterNum(eMonsterType a_EntityType); // tolua_end @@ -68,7 +68,7 @@ public: private: /** The entity to spawn. */ - cMonster::eType m_Entity; + eMonsterType m_Entity; int m_SpawnDelay; -- cgit v1.2.3 From 6d5a8892f34f4034b38da467268de9d489e1024e Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 19 Oct 2014 00:29:34 +0100 Subject: Use std::thread --- src/ByteBuffer.cpp | 74 ------------------ src/ByteBuffer.h | 4 - src/Globals.h | 2 +- src/Logger.cpp | 2 +- src/OSSupport/CMakeLists.txt | 2 - src/OSSupport/CriticalSection.cpp | 4 +- src/OSSupport/CriticalSection.h | 2 +- src/OSSupport/IsThread.cpp | 158 +++++++------------------------------- src/OSSupport/IsThread.h | 44 +---------- src/OSSupport/Thread.cpp | 137 --------------------------------- src/OSSupport/Thread.h | 26 ------- src/Root.cpp | 30 +++++--- src/Root.h | 6 +- 13 files changed, 59 insertions(+), 432 deletions(-) delete mode 100644 src/OSSupport/Thread.cpp delete mode 100644 src/OSSupport/Thread.h diff --git a/src/ByteBuffer.cpp b/src/ByteBuffer.cpp index dc6b32a44..d03b6bbe4 100644 --- a/src/ByteBuffer.cpp +++ b/src/ByteBuffer.cpp @@ -109,46 +109,12 @@ public: -#ifdef _DEBUG - -/// Simple RAII class that uses one internal unsigned long for checking if two threads are using an object simultanously -class cSingleThreadAccessChecker -{ -public: - cSingleThreadAccessChecker(unsigned long * a_ThreadID) : - m_ThreadID(a_ThreadID) - { - ASSERT((*a_ThreadID == 0) || (*a_ThreadID == cIsThread::GetCurrentID())); - } - - ~cSingleThreadAccessChecker() - { - *m_ThreadID = 0; - } - -protected: - unsigned long * m_ThreadID; -} ; - -#define CHECK_THREAD cSingleThreadAccessChecker Checker(const_cast(&m_ThreadID)) - -#else - #define CHECK_THREAD -#endif - - - - - //////////////////////////////////////////////////////////////////////////////// // cByteBuffer: cByteBuffer::cByteBuffer(size_t a_BufferSize) : m_Buffer(new char[a_BufferSize + 1]), m_BufferSize(a_BufferSize + 1), - #ifdef _DEBUG - m_ThreadID(0), - #endif // _DEBUG m_DataStart(0), m_WritePos(0), m_ReadPos(0) @@ -174,7 +140,6 @@ cByteBuffer::~cByteBuffer() bool cByteBuffer::Write(const void * a_Bytes, size_t a_Count) { - CHECK_THREAD; CheckValid(); // Store the current free space for a check after writing: @@ -221,7 +186,6 @@ bool cByteBuffer::Write(const void * a_Bytes, size_t a_Count) size_t cByteBuffer::GetFreeSpace(void) const { - CHECK_THREAD; CheckValid(); if (m_WritePos >= m_DataStart) { @@ -243,7 +207,6 @@ size_t cByteBuffer::GetFreeSpace(void) const /// Returns the number of bytes that are currently in the ringbuffer. Note GetReadableBytes() size_t cByteBuffer::GetUsedSpace(void) const { - CHECK_THREAD; CheckValid(); ASSERT(m_BufferSize >= GetFreeSpace()); ASSERT((m_BufferSize - GetFreeSpace()) >= 1); @@ -257,7 +220,6 @@ size_t cByteBuffer::GetUsedSpace(void) const /// Returns the number of bytes that are currently available for reading (may be less than UsedSpace due to some data having been read already) size_t cByteBuffer::GetReadableSpace(void) const { - CHECK_THREAD; CheckValid(); if (m_ReadPos > m_WritePos) { @@ -276,7 +238,6 @@ size_t cByteBuffer::GetReadableSpace(void) const bool cByteBuffer::CanReadBytes(size_t a_Count) const { - CHECK_THREAD; CheckValid(); return (a_Count <= GetReadableSpace()); } @@ -287,7 +248,6 @@ bool cByteBuffer::CanReadBytes(size_t a_Count) const bool cByteBuffer::CanWriteBytes(size_t a_Count) const { - CHECK_THREAD; CheckValid(); return (a_Count <= GetFreeSpace()); } @@ -298,7 +258,6 @@ bool cByteBuffer::CanWriteBytes(size_t a_Count) const bool cByteBuffer::ReadChar(char & a_Value) { - CHECK_THREAD; CheckValid(); NEEDBYTES(1); ReadBuf(&a_Value, 1); @@ -311,7 +270,6 @@ bool cByteBuffer::ReadChar(char & a_Value) bool cByteBuffer::ReadByte(unsigned char & a_Value) { - CHECK_THREAD; CheckValid(); NEEDBYTES(1); ReadBuf(&a_Value, 1); @@ -324,7 +282,6 @@ bool cByteBuffer::ReadByte(unsigned char & a_Value) bool cByteBuffer::ReadBEShort(short & a_Value) { - CHECK_THREAD; CheckValid(); NEEDBYTES(2); ReadBuf(&a_Value, 2); @@ -338,7 +295,6 @@ bool cByteBuffer::ReadBEShort(short & a_Value) bool cByteBuffer::ReadBEInt(int & a_Value) { - CHECK_THREAD; CheckValid(); NEEDBYTES(4); ReadBuf(&a_Value, 4); @@ -352,7 +308,6 @@ bool cByteBuffer::ReadBEInt(int & a_Value) bool cByteBuffer::ReadBEInt64(Int64 & a_Value) { - CHECK_THREAD; CheckValid(); NEEDBYTES(8); ReadBuf(&a_Value, 8); @@ -366,7 +321,6 @@ bool cByteBuffer::ReadBEInt64(Int64 & a_Value) bool cByteBuffer::ReadBEFloat(float & a_Value) { - CHECK_THREAD; CheckValid(); NEEDBYTES(4); ReadBuf(&a_Value, 4); @@ -380,7 +334,6 @@ bool cByteBuffer::ReadBEFloat(float & a_Value) bool cByteBuffer::ReadBEDouble(double & a_Value) { - CHECK_THREAD; CheckValid(); NEEDBYTES(8); ReadBuf(&a_Value, 8); @@ -394,7 +347,6 @@ bool cByteBuffer::ReadBEDouble(double & a_Value) bool cByteBuffer::ReadBool(bool & a_Value) { - CHECK_THREAD; CheckValid(); NEEDBYTES(1); char Value = 0; @@ -409,7 +361,6 @@ bool cByteBuffer::ReadBool(bool & a_Value) bool cByteBuffer::ReadBEUTF16String16(AString & a_Value) { - CHECK_THREAD; CheckValid(); short Length; if (!ReadBEShort(Length)) @@ -430,7 +381,6 @@ bool cByteBuffer::ReadBEUTF16String16(AString & a_Value) bool cByteBuffer::ReadVarInt(UInt32 & a_Value) { - CHECK_THREAD; CheckValid(); UInt32 Value = 0; int Shift = 0; @@ -452,7 +402,6 @@ bool cByteBuffer::ReadVarInt(UInt32 & a_Value) bool cByteBuffer::ReadVarUTF8String(AString & a_Value) { - CHECK_THREAD; CheckValid(); UInt32 Size = 0; if (!ReadVarInt(Size)) @@ -472,7 +421,6 @@ bool cByteBuffer::ReadVarUTF8String(AString & a_Value) bool cByteBuffer::ReadLEInt(int & a_Value) { - CHECK_THREAD; CheckValid(); NEEDBYTES(4); ReadBuf(&a_Value, 4); @@ -515,7 +463,6 @@ bool cByteBuffer::ReadPosition(int & a_BlockX, int & a_BlockY, int & a_BlockZ) bool cByteBuffer::WriteChar(char a_Value) { - CHECK_THREAD; CheckValid(); PUTBYTES(1); return WriteBuf(&a_Value, 1); @@ -527,7 +474,6 @@ bool cByteBuffer::WriteChar(char a_Value) bool cByteBuffer::WriteByte(unsigned char a_Value) { - CHECK_THREAD; CheckValid(); PUTBYTES(1); return WriteBuf(&a_Value, 1); @@ -539,7 +485,6 @@ bool cByteBuffer::WriteByte(unsigned char a_Value) bool cByteBuffer::WriteBEShort(short a_Value) { - CHECK_THREAD; CheckValid(); PUTBYTES(2); u_short Converted = htons((u_short)a_Value); @@ -552,7 +497,6 @@ bool cByteBuffer::WriteBEShort(short a_Value) bool cByteBuffer::WriteBEUShort(unsigned short a_Value) { - CHECK_THREAD; CheckValid(); PUTBYTES(2); u_short Converted = htons((u_short)a_Value); @@ -565,7 +509,6 @@ bool cByteBuffer::WriteBEUShort(unsigned short a_Value) bool cByteBuffer::WriteBEInt(int a_Value) { - CHECK_THREAD; CheckValid(); PUTBYTES(4); UInt32 Converted = HostToNetwork4(&a_Value); @@ -578,7 +521,6 @@ bool cByteBuffer::WriteBEInt(int a_Value) bool cByteBuffer::WriteBEInt64(Int64 a_Value) { - CHECK_THREAD; CheckValid(); PUTBYTES(8); UInt64 Converted = HostToNetwork8(&a_Value); @@ -591,7 +533,6 @@ bool cByteBuffer::WriteBEInt64(Int64 a_Value) bool cByteBuffer::WriteBEFloat(float a_Value) { - CHECK_THREAD; CheckValid(); PUTBYTES(4); UInt32 Converted = HostToNetwork4(&a_Value); @@ -604,7 +545,6 @@ bool cByteBuffer::WriteBEFloat(float a_Value) bool cByteBuffer::WriteBEDouble(double a_Value) { - CHECK_THREAD; CheckValid(); PUTBYTES(8); UInt64 Converted = HostToNetwork8(&a_Value); @@ -618,7 +558,6 @@ bool cByteBuffer::WriteBEDouble(double a_Value) bool cByteBuffer::WriteBool(bool a_Value) { - CHECK_THREAD; CheckValid(); return WriteChar(a_Value ? 1 : 0); } @@ -629,7 +568,6 @@ bool cByteBuffer::WriteBool(bool a_Value) bool cByteBuffer::WriteVarInt(UInt32 a_Value) { - CHECK_THREAD; CheckValid(); // A 32-bit integer can be encoded by at most 5 bytes: @@ -650,7 +588,6 @@ bool cByteBuffer::WriteVarInt(UInt32 a_Value) bool cByteBuffer::WriteVarUTF8String(const AString & a_Value) { - CHECK_THREAD; CheckValid(); PUTBYTES(a_Value.size() + 1); // This is a lower-bound on the bytes that will be actually written. Fail early. bool res = WriteVarInt((UInt32)(a_Value.size())); @@ -667,7 +604,6 @@ bool cByteBuffer::WriteVarUTF8String(const AString & a_Value) bool cByteBuffer::WriteLEInt(int a_Value) { - CHECK_THREAD; CheckValid(); #ifdef IS_LITTLE_ENDIAN return WriteBuf((const char *)&a_Value, 4); @@ -692,7 +628,6 @@ bool cByteBuffer::WritePosition(int a_BlockX, int a_BlockY, int a_BlockZ) bool cByteBuffer::ReadBuf(void * a_Buffer, size_t a_Count) { - CHECK_THREAD; CheckValid(); NEEDBYTES(a_Count); char * Dst = (char *)a_Buffer; // So that we can do byte math @@ -725,7 +660,6 @@ bool cByteBuffer::ReadBuf(void * a_Buffer, size_t a_Count) bool cByteBuffer::WriteBuf(const void * a_Buffer, size_t a_Count) { - CHECK_THREAD; CheckValid(); PUTBYTES(a_Count); char * Src = (char *)a_Buffer; // So that we can do byte math @@ -755,7 +689,6 @@ bool cByteBuffer::WriteBuf(const void * a_Buffer, size_t a_Count) bool cByteBuffer::ReadString(AString & a_String, size_t a_Count) { - CHECK_THREAD; CheckValid(); NEEDBYTES(a_Count); a_String.clear(); @@ -790,7 +723,6 @@ bool cByteBuffer::ReadString(AString & a_String, size_t a_Count) bool cByteBuffer::ReadUTF16String(AString & a_String, size_t a_NumChars) { // Reads 2 * a_NumChars bytes and interprets it as a UTF16 string, converting it into UTF8 string a_String - CHECK_THREAD; CheckValid(); AString RawData; if (!ReadString(RawData, a_NumChars * 2)) @@ -807,7 +739,6 @@ bool cByteBuffer::ReadUTF16String(AString & a_String, size_t a_NumChars) bool cByteBuffer::SkipRead(size_t a_Count) { - CHECK_THREAD; CheckValid(); if (!CanReadBytes(a_Count)) { @@ -823,7 +754,6 @@ bool cByteBuffer::SkipRead(size_t a_Count) void cByteBuffer::ReadAll(AString & a_Data) { - CHECK_THREAD; CheckValid(); ReadString(a_Data, GetReadableSpace()); } @@ -858,7 +788,6 @@ bool cByteBuffer::ReadToByteBuffer(cByteBuffer & a_Dst, size_t a_NumBytes) void cByteBuffer::CommitRead(void) { - CHECK_THREAD; CheckValid(); m_DataStart = m_ReadPos; } @@ -869,7 +798,6 @@ void cByteBuffer::CommitRead(void) void cByteBuffer::ResetRead(void) { - CHECK_THREAD; CheckValid(); m_ReadPos = m_DataStart; } @@ -882,7 +810,6 @@ void cByteBuffer::ReadAgain(AString & a_Out) { // Return the data between m_DataStart and m_ReadPos (the data that has been read but not committed) // Used by ProtoProxy to repeat communication twice, once for parsing and the other time for the remote party - CHECK_THREAD; CheckValid(); size_t DataStart = m_DataStart; if (m_ReadPos < m_DataStart) @@ -902,7 +829,6 @@ void cByteBuffer::ReadAgain(AString & a_Out) void cByteBuffer::AdvanceReadPos(size_t a_Count) { - CHECK_THREAD; CheckValid(); m_ReadPos += a_Count; if (m_ReadPos >= m_BufferSize) diff --git a/src/ByteBuffer.h b/src/ByteBuffer.h index 70de419f0..e80763772 100644 --- a/src/ByteBuffer.h +++ b/src/ByteBuffer.h @@ -130,10 +130,6 @@ protected: char * m_Buffer; size_t m_BufferSize; // Total size of the ringbuffer - #ifdef _DEBUG - volatile unsigned long m_ThreadID; // Thread that is currently accessing the object, checked via cSingleThreadAccessChecker - #endif // _DEBUG - size_t m_DataStart; // Where the data starts in the ringbuffer size_t m_WritePos; // Where the data ends in the ringbuffer size_t m_ReadPos; // Where the next read will start in the ringbuffer diff --git a/src/Globals.h b/src/Globals.h index b84607355..f6c722594 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -239,6 +239,7 @@ template class SizeChecker; // STL stuff: +#include #include #include #include @@ -259,7 +260,6 @@ template class SizeChecker; #include "OSSupport/CriticalSection.h" #include "OSSupport/Semaphore.h" #include "OSSupport/Event.h" - #include "OSSupport/Thread.h" #include "OSSupport/File.h" #include "Logger.h" #else diff --git a/src/Logger.cpp b/src/Logger.cpp index cb528e8ab..fad4a5e75 100644 --- a/src/Logger.cpp +++ b/src/Logger.cpp @@ -45,7 +45,7 @@ void cLogger::LogSimple(AString a_Message, eLogLevel a_LogLevel) AString Line; #ifdef _DEBUG - Printf(Line, "[%04lx|%02d:%02d:%02d] %s\n", cIsThread::GetCurrentID(), timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, a_Message.c_str()); + Printf(Line, "[%04lx|%02d:%02d:%02d] %s\n", std::this_thread::get_id().hash(), timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, a_Message.c_str()); #else Printf(Line, "[%02d:%02d:%02d] %s\n", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, a_Message.c_str()); #endif diff --git a/src/OSSupport/CMakeLists.txt b/src/OSSupport/CMakeLists.txt index 429949c59..1c8da5ddd 100644 --- a/src/OSSupport/CMakeLists.txt +++ b/src/OSSupport/CMakeLists.txt @@ -16,7 +16,6 @@ SET (SRCS Sleep.cpp Socket.cpp SocketThreads.cpp - Thread.cpp Timer.cpp) SET (HDRS @@ -32,7 +31,6 @@ SET (HDRS Sleep.h Socket.h SocketThreads.h - Thread.h Timer.h) if(NOT MSVC) diff --git a/src/OSSupport/CriticalSection.cpp b/src/OSSupport/CriticalSection.cpp index 5dfc8b5f9..3e8e7498d 100644 --- a/src/OSSupport/CriticalSection.cpp +++ b/src/OSSupport/CriticalSection.cpp @@ -59,7 +59,7 @@ void cCriticalSection::Lock() #ifdef _DEBUG m_IsLocked += 1; - m_OwningThreadID = cIsThread::GetCurrentID(); + m_OwningThreadID = std::this_thread::get_id(); #endif // _DEBUG } @@ -97,7 +97,7 @@ bool cCriticalSection::IsLocked(void) bool cCriticalSection::IsLockedByCurrentThread(void) { - return ((m_IsLocked > 0) && (m_OwningThreadID == cIsThread::GetCurrentID())); + return ((m_IsLocked > 0) && (m_OwningThreadID == std::this_thread::get_id())); } #endif // _DEBUG diff --git a/src/OSSupport/CriticalSection.h b/src/OSSupport/CriticalSection.h index c3c6e57f0..7822a5471 100644 --- a/src/OSSupport/CriticalSection.h +++ b/src/OSSupport/CriticalSection.h @@ -27,7 +27,7 @@ public: private: #ifdef _DEBUG int m_IsLocked; // Number of times this CS is locked - unsigned long m_OwningThreadID; + std::thread::id m_OwningThreadID; #endif // _DEBUG #ifdef _WIN32 diff --git a/src/OSSupport/IsThread.cpp b/src/OSSupport/IsThread.cpp index 1a436623a..4864ef28b 100644 --- a/src/OSSupport/IsThread.cpp +++ b/src/OSSupport/IsThread.cpp @@ -5,65 +5,18 @@ // This class will eventually suupersede the old cThread class #include "Globals.h" - #include "IsThread.h" -// When in MSVC, the debugger provides "thread naming" by catching special exceptions. Interface here: -#if defined(_MSC_VER) && defined(_DEBUG) -// -// Usage: SetThreadName (-1, "MainThread"); -// - -// Code adapted from MSDN: http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx - -const DWORD MS_VC_EXCEPTION = 0x406D1388; - -#pragma pack(push, 8) -typedef struct tagTHREADNAME_INFO -{ - DWORD dwType; // Must be 0x1000. - LPCSTR szName; // Pointer to name (in user addr space). - DWORD dwThreadID; // Thread ID (-1 = caller thread). - DWORD dwFlags; // Reserved for future use, must be zero. -} THREADNAME_INFO; -#pragma pack(pop) - -static void SetThreadName(DWORD dwThreadID, const char * threadName) -{ - THREADNAME_INFO info; - info.dwType = 0x1000; - info.szName = threadName; - info.dwThreadID = dwThreadID; - info.dwFlags = 0; - - __try - { - RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR *)&info); - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - } -} -#endif // _MSC_VER && _DEBUG - - - - - //////////////////////////////////////////////////////////////////////////////// // cIsThread: -cIsThread::cIsThread(const AString & iThreadName) : +cIsThread::cIsThread(const AString & a_ThreadName) : m_ShouldTerminate(false), - m_ThreadName(iThreadName), - #ifdef _WIN32 - m_ThreadID(0), - #endif - m_Handle(NULL_HANDLE) + m_ThreadName(a_ThreadName) { } @@ -83,35 +36,16 @@ cIsThread::~cIsThread() bool cIsThread::Start(void) { - ASSERT(m_Handle == NULL_HANDLE); // Has already started one thread? - #ifdef _WIN32 - // Create the thread suspended, so that the mHandle variable is valid in the thread procedure - m_ThreadID = 0; - m_Handle = CreateThread(NULL, 0, thrExecute, this, CREATE_SUSPENDED, &m_ThreadID); - if (m_Handle == NULL) - { - LOGERROR("ERROR: Could not create thread \"%s\", GLE = %u!", m_ThreadName.c_str(), (unsigned)GetLastError()); - return false; - } - ResumeThread(m_Handle); - - #if defined(_DEBUG) && defined(_MSC_VER) - // Thread naming is available only in MSVC - if (!m_ThreadName.empty()) - { - SetThreadName(m_ThreadID, m_ThreadName.c_str()); - } - #endif // _DEBUG and _MSC_VER - - #else // _WIN32 - if (pthread_create(&m_Handle, NULL, thrExecute, this)) - { - LOGERROR("ERROR: Could not create thread \"%s\", !", m_ThreadName.c_str()); - return false; - } - #endif // else _WIN32 - - return true; + try + { + m_Thread = std::thread(&cIsThread::Execute, this); + return true; + } + catch (std::system_error & a_Exception) + { + LOGERROR("ERROR: Could not create thread \"%s\", error = %s!", m_ThreadName.c_str(), a_Exception.code(), a_Exception.what()); + return false; + } } @@ -120,10 +54,6 @@ bool cIsThread::Start(void) void cIsThread::Stop(void) { - if (m_Handle == NULL_HANDLE) - { - return; - } m_ShouldTerminate = true; Wait(); } @@ -133,60 +63,30 @@ void cIsThread::Stop(void) bool cIsThread::Wait(void) -{ - if (m_Handle == NULL_HANDLE) - { - return true; - } - +{ #ifdef LOGD // ProtoProxy doesn't have LOGD LOGD("Waiting for thread %s to finish", m_ThreadName.c_str()); #endif // LOGD - - #ifdef _WIN32 - int res = WaitForSingleObject(m_Handle, INFINITE); - m_Handle = NULL; - - #ifdef LOGD // ProtoProxy doesn't have LOGD - LOGD("Thread %s finished", m_ThreadName.c_str()); - #endif // LOGD - - return (res == WAIT_OBJECT_0); - #else // _WIN32 - int res = pthread_join(m_Handle, NULL); - m_Handle = NULL_HANDLE; - - #ifdef LOGD // ProtoProxy doesn't have LOGD - LOGD("Thread %s finished", m_ThreadName.c_str()); - #endif // LOGD - - return (res == 0); - #endif // else _WIN32 -} - - - + if (m_Thread.joinable()) + { + try + { + m_Thread.join(); + return true; + } + catch (std::system_error & a_Exception) + { + LOGERROR("ERROR: Could wait for thread \"%s\" to finish, error = %s!", m_ThreadName.c_str(), a_Exception.code(), a_Exception.what()); + return false; + } + } -unsigned long cIsThread::GetCurrentID(void) -{ - #ifdef _WIN32 - return (unsigned long) GetCurrentThreadId(); - #else - return (unsigned long) pthread_self(); + #ifdef LOGD // ProtoProxy doesn't have LOGD + LOGD("Thread %s finished", m_ThreadName.c_str()); #endif -} - - - -bool cIsThread::IsCurrentThread(void) const -{ - #ifdef _WIN32 - return (GetCurrentThreadId() == m_ThreadID); - #else - return (m_Handle == pthread_self()); - #endif + return true; } diff --git a/src/OSSupport/IsThread.h b/src/OSSupport/IsThread.h index 5de5f31c4..8dfad84cb 100644 --- a/src/OSSupport/IsThread.h +++ b/src/OSSupport/IsThread.h @@ -44,53 +44,13 @@ public: /// Waits for the thread to finish. Doesn't signalize the ShouldTerminate flag bool Wait(void); - - /// Returns the OS-dependent thread ID for the caller's thread - static unsigned long GetCurrentID(void); /** Returns true if the thread calling this function is the thread contained within this object. */ - bool IsCurrentThread(void) const; + bool IsCurrentThread(void) const { return std::this_thread::get_id() == m_Thread.get_id(); } protected: AString m_ThreadName; - - // Value used for "no handle": - #ifdef _WIN32 - #define NULL_HANDLE NULL - #else - #define NULL_HANDLE 0 - #endif - - #ifdef _WIN32 - - DWORD m_ThreadID; - HANDLE m_Handle; - - static DWORD __stdcall thrExecute(LPVOID a_Param) - { - // Create a window so that the thread can be identified by 3rd party tools: - HWND IdentificationWnd = CreateWindowA("STATIC", ((cIsThread *)a_Param)->m_ThreadName.c_str(), 0, 0, 0, 0, WS_OVERLAPPED, NULL, NULL, NULL, NULL); - - // Run the thread: - ((cIsThread *)a_Param)->Execute(); - - // Destroy the identification window: - DestroyWindow(IdentificationWnd); - - return 0; - } - - #else // _WIN32 - - pthread_t m_Handle; - - static void * thrExecute(void * a_Param) - { - ((cIsThread *)a_Param)->Execute(); - return NULL; - } - - #endif // else _WIN32 + std::thread m_Thread; } ; diff --git a/src/OSSupport/Thread.cpp b/src/OSSupport/Thread.cpp deleted file mode 100644 index faaccce96..000000000 --- a/src/OSSupport/Thread.cpp +++ /dev/null @@ -1,137 +0,0 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - - - - - -// When in MSVC, the debugger provides "thread naming" by catching special exceptions. Interface here: -#ifdef _MSC_VER -// -// Usage: SetThreadName (-1, "MainThread"); -// - -// Code adapted from MSDN: http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx - -const DWORD MS_VC_EXCEPTION = 0x406D1388; - -#pragma pack(push, 8) -typedef struct tagTHREADNAME_INFO -{ - DWORD dwType; // Must be 0x1000. - LPCSTR szName; // Pointer to name (in user addr space). - DWORD dwThreadID; // Thread ID (-1 = caller thread). - DWORD dwFlags; // Reserved for future use, must be zero. -} THREADNAME_INFO; -#pragma pack(pop) - -static void SetThreadName(DWORD dwThreadID, const char * threadName) -{ - THREADNAME_INFO info; - info.dwType = 0x1000; - info.szName = threadName; - info.dwThreadID = dwThreadID; - info.dwFlags = 0; - - __try - { - RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR *)&info); - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - } -} -#endif // _MSC_VER - - - - - -cThread::cThread( ThreadFunc a_ThreadFunction, void* a_Param, const char* a_ThreadName /* = 0 */) - : m_ThreadFunction( a_ThreadFunction) - , m_Param( a_Param) - , m_Event( new cEvent()) - , m_StopEvent( 0) -{ - if (a_ThreadName) - { - m_ThreadName.assign(a_ThreadName); - } -} - - - - - -cThread::~cThread() -{ - delete m_Event; - m_Event = NULL; - - if (m_StopEvent) - { - m_StopEvent->Wait(); - delete m_StopEvent; - m_StopEvent = NULL; - } -} - - - - - -void cThread::Start( bool a_bWaitOnDelete /* = true */) -{ - if (a_bWaitOnDelete) - m_StopEvent = new cEvent(); - -#ifndef _WIN32 - pthread_t SndThread; - if (pthread_create( &SndThread, NULL, MyThread, this)) - LOGERROR("ERROR: Could not create thread!"); -#else - DWORD ThreadID = 0; - HANDLE hThread = CreateThread(NULL // security - , 0 // stack size - , (LPTHREAD_START_ROUTINE) MyThread // function name - , this // parameters - , 0 // flags - , &ThreadID); // thread id - CloseHandle( hThread); - - #ifdef _MSC_VER - if (!m_ThreadName.empty()) - { - SetThreadName(ThreadID, m_ThreadName.c_str()); - } - #endif // _MSC_VER -#endif - - // Wait until thread has actually been created - m_Event->Wait(); -} - - - - - -#ifdef _WIN32 -unsigned long cThread::MyThread(void* a_Param) -#else -void *cThread::MyThread( void *a_Param) -#endif -{ - cThread* self = (cThread*)a_Param; - cEvent* StopEvent = self->m_StopEvent; - - ThreadFunc* ThreadFunction = self->m_ThreadFunction; - void* ThreadParam = self->m_Param; - - // Set event to let other thread know this thread has been created and it's safe to delete the cThread object - self->m_Event->Set(); - - ThreadFunction( ThreadParam); - - if (StopEvent) StopEvent->Set(); - return 0; -} diff --git a/src/OSSupport/Thread.h b/src/OSSupport/Thread.h deleted file mode 100644 index 7ee352c82..000000000 --- a/src/OSSupport/Thread.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -class cThread -{ -public: - typedef void (ThreadFunc)(void*); - cThread( ThreadFunc a_ThreadFunction, void* a_Param, const char* a_ThreadName = 0); - ~cThread(); - - void Start( bool a_bWaitOnDelete = true); - void WaitForThread(); -private: - ThreadFunc* m_ThreadFunction; - -#ifdef _WIN32 - static unsigned long MyThread(void* a_Param); -#else - static void *MyThread( void *lpParam); -#endif - - void* m_Param; - cEvent* m_Event; - cEvent* m_StopEvent; - - AString m_ThreadName; -}; diff --git a/src/Root.cpp b/src/Root.cpp index 2d08c2c70..2cfbf0817 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -43,7 +43,6 @@ cRoot* cRoot::s_Root = NULL; cRoot::cRoot(void) : m_pDefaultWorld(NULL), - m_InputThread(NULL), m_Server(NULL), m_MonsterConfig(NULL), m_CraftingRecipes(NULL), @@ -69,26 +68,24 @@ cRoot::~cRoot() -void cRoot::InputThread(void * a_Params) +void cRoot::InputThread(cRoot * a_Params) { - cRoot & self = *(cRoot*)a_Params; - cLogCommandOutputCallback Output; - while (!self.m_bStop && !self.m_bRestart && !m_TerminateEventRaised && std::cin.good()) + while (!a_Params->m_bStop && !a_Params->m_bRestart && !m_TerminateEventRaised && std::cin.good()) { AString Command; std::getline(std::cin, Command); if (!Command.empty()) { - self.ExecuteConsoleCommand(TrimString(Command), Output); + a_Params->ExecuteConsoleCommand(TrimString(Command), Output); } } if (m_TerminateEventRaised || !std::cin.good()) { // We have come here because the std::cin has received an EOF / a terminate signal has been sent, and the server is still running; stop the server: - self.m_bStop = true; + a_Params->m_bStop = true; } } @@ -191,8 +188,14 @@ void cRoot::Start(void) #if !defined(ANDROID_NDK) LOGD("Starting InputThread..."); - m_InputThread = new cThread( InputThread, this, "cRoot::InputThread"); - m_InputThread->Start( false); // We should NOT wait? Otherwise we can't stop the server from other threads than the input thread + try + { + m_InputThread = std::thread(InputThread, this); + } + catch (std::system_error & a_Exception) + { + LOGERROR("ERROR: Could not create input thread, error = %s!", a_Exception.code(), a_Exception.what()); + } #endif long long finishmseconds = Time.GetNowTime(); @@ -214,7 +217,14 @@ void cRoot::Start(void) } #if !defined(ANDROID_NDK) - delete m_InputThread; m_InputThread = NULL; + try + { + m_InputThread.join(); + } + catch (std::system_error & a_Exception) + { + LOGERROR("ERROR: Could not wait for input thread to finish, error = %s!", a_Exception.code(), a_Exception.what()); + } #endif // Stop the server: diff --git a/src/Root.h b/src/Root.h index 84c6a98ec..7c7798315 100644 --- a/src/Root.h +++ b/src/Root.h @@ -174,7 +174,7 @@ private: cCriticalSection m_CSPendingCommands; cCommandQueue m_PendingCommands; - cThread * m_InputThread; + std::thread m_InputThread; cServer * m_Server; cMonsterConfig * m_MonsterConfig; @@ -207,10 +207,10 @@ private: /// Does the actual work of executing a command void DoExecuteConsoleCommand(const AString & a_Cmd); - - static void InputThread(void* a_Params); static cRoot* s_Root; + + static void InputThread(cRoot * a_Params); }; // tolua_export -- cgit v1.2.3 From aa19a3afb0b94e8b5fe055eeb38b1fb2ee1a67b0 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 19 Oct 2014 14:10:18 +0100 Subject: Migrated random generators to std::random --- src/Chunk.cpp | 1 - src/ClientHandle.cpp | 12 - src/FastRandom.cpp | 116 +++++----- src/FastRandom.h | 36 ++- src/Generating/ChunkGenerator.cpp | 2 +- src/Globals.h | 1 + src/MersenneTwister.h | 456 -------------------------------------- src/Mobs/Monster.cpp | 1 - src/Mobs/Witch.cpp | 1 + src/Mobs/Witch.h | 1 - src/ProbabDistrib.cpp | 2 +- src/Root.cpp | 22 +- src/Root.h | 2 +- src/Server.cpp | 2 - src/World.cpp | 1 - src/World.h | 2 +- 16 files changed, 102 insertions(+), 556 deletions(-) delete mode 100644 src/MersenneTwister.h diff --git a/src/Chunk.cpp b/src/Chunk.cpp index d03e0bf21..959fbd18f 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -27,7 +27,6 @@ #include "Item.h" #include "Noise.h" #include "Root.h" -#include "MersenneTwister.h" #include "Entities/Player.h" #include "BlockArea.h" #include "Bindings/PluginManager.h" diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index f15d845ef..7d0f2de06 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -25,8 +25,6 @@ #include "Root.h" #include "Protocol/Authenticator.h" -#include "MersenneTwister.h" - #include "Protocol/ProtocolRecognizer.h" #include "CompositeChat.h" #include "Items/ItemSword.h" @@ -45,16 +43,6 @@ -#define RECI_RAND_MAX (1.f/RAND_MAX) -inline int fRadRand(MTRand & r1, int a_BlockCoord) -{ - return a_BlockCoord * 32 + (int)(16 * ((float)r1.rand() * RECI_RAND_MAX) * 16 - 8); -} - - - - - int cClientHandle::s_ClientCount = 0; diff --git a/src/FastRandom.cpp b/src/FastRandom.cpp index 42bf5f3f9..cfafc7486 100644 --- a/src/FastRandom.cpp +++ b/src/FastRandom.cpp @@ -4,13 +4,15 @@ // Implements the cFastRandom class representing a fast random number generator #include "Globals.h" -#include #include "FastRandom.h" +//////////////////////////////////////////////////////////////////////////////// +// cFastRandom: + #if 0 && defined(_DEBUG) // Self-test // Both ints and floats are quick-tested to see if the random is calculated correctly, checking the range in ASSERTs, @@ -83,16 +85,8 @@ public: - -int cFastRandom::m_SeedCounter = 0; - - - - - cFastRandom::cFastRandom(void) : - m_Seed(m_SeedCounter++), - m_Counter(0) + m_LinearRand(static_cast(std::chrono::system_clock::now().time_since_epoch().count())) { } @@ -102,82 +96,96 @@ cFastRandom::cFastRandom(void) : int cFastRandom::NextInt(int a_Range) { - ASSERT(a_Range <= 1000000); // The random is not sufficiently linearly distributed with bigger ranges - ASSERT(a_Range > 0); - - // Make the m_Counter operations as minimal as possible, to emulate atomicity - int Counter = m_Counter++; - - // Use a_Range, m_Counter and m_Seed as inputs to the pseudorandom function: - int n = a_Range + Counter * 57 + m_Seed * 57 * 57; - n = (n << 13) ^ n; - n = ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff); - return ((n / 11) % a_Range); + m_IntDistribution = std::uniform_int_distribution<>(0, a_Range - 1); + return m_IntDistribution(m_LinearRand); } + int cFastRandom::NextInt(int a_Range, int a_Salt) { - ASSERT(a_Range <= 1000000); // The random is not sufficiently linearly distributed with bigger ranges - ASSERT(a_Range > 0); - - // Make the m_Counter operations as minimal as possible, to emulate atomicity - int Counter = m_Counter++; - - // Use a_Range, a_Salt, m_Counter and m_Seed as inputs to the pseudorandom function: - int n = a_Range + Counter * 57 + m_Seed * 57 * 57 + a_Salt * 57 * 57 * 57; - n = (n << 13) ^ n; - n = ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff); - return ((n / 11) % a_Range); + m_LinearRand.seed(a_Salt); + m_IntDistribution = std::uniform_int_distribution<>(0, a_Range - 1); + return m_IntDistribution(m_LinearRand); } + float cFastRandom::NextFloat(float a_Range) { - // Make the m_Counter operations as minimal as possible, to emulate atomicity - int Counter = m_Counter++; - - // Use a_Range, a_Salt, m_Counter and m_Seed as inputs to the pseudorandom function: - int n = (int)a_Range + Counter * 57 + m_Seed * 57 * 57; - n = (n << 13) ^ n; - n = ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff); - - // Convert the integer into float with the specified range: - return (((float)n / (float)0x7fffffff) * a_Range); + m_FloatDistribution = std::uniform_real_distribution(0, a_Range - 1); + return m_FloatDistribution(m_LinearRand); } + float cFastRandom::NextFloat(float a_Range, int a_Salt) { - // Make the m_Counter operations as minimal as possible, to emulate atomicity - int Counter = m_Counter++; - - // Use a_Range, a_Salt, m_Counter and m_Seed as inputs to the pseudorandom function: - int n = (int)a_Range + Counter * 57 + m_Seed * 57 * 57 + a_Salt * 57 * 57 * 57; - n = (n << 13) ^ n; - n = ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff); - - // Convert the integer into float with the specified range: - return (((float)n / (float)0x7fffffff) * a_Range); + m_LinearRand.seed(a_Salt); + m_FloatDistribution = std::uniform_real_distribution(0, a_Range - 1); + return m_FloatDistribution(m_LinearRand); } + int cFastRandom::GenerateRandomInteger(int a_Begin, int a_End) { - cFastRandom Random; - return Random.NextInt(a_End - a_Begin + 1) + a_Begin; + m_IntDistribution = std::uniform_int_distribution<>(a_Begin, a_End - 1); + return m_IntDistribution(m_LinearRand); +} + + + + + +//////////////////////////////////////////////////////////////////////////////// +// MTRand: + +MTRand::MTRand() : + m_MersenneRand(static_cast(std::chrono::system_clock::now().time_since_epoch().count())) +{ +} + + + + + +int MTRand::randInt(int a_Range) +{ + m_IntDistribution = std::uniform_int_distribution<>(0, a_Range); + return m_IntDistribution(m_MersenneRand); +} + + + + + +int MTRand::randInt() +{ + m_IntDistribution = std::uniform_int_distribution<>(0, std::numeric_limits::max()); + return m_IntDistribution(m_MersenneRand); +} + + + + + +double MTRand::rand(double a_Range) +{ + m_DoubleDistribution = std::uniform_real_distribution<>(0, a_Range); + return m_DoubleDistribution(m_MersenneRand); } diff --git a/src/FastRandom.h b/src/FastRandom.h index cebebad96..37d7f6eef 100644 --- a/src/FastRandom.h +++ b/src/FastRandom.h @@ -22,6 +22,7 @@ salts, the values they get will be different. #pragma once +#include @@ -30,6 +31,7 @@ salts, the values they get will be different. class cFastRandom { public: + cFastRandom(void); /// Returns a random int in the range [0 .. a_Range - 1]; a_Range must be less than 1M @@ -49,15 +51,33 @@ public: /** Returns a random int in the range [a_Begin .. a_End] */ int GenerateRandomInteger(int a_Begin, int a_End); - -protected: - int m_Seed; - int m_Counter; - - /// Counter that is used to initialize the seed, incremented for each object created - static int m_SeedCounter; -} ; +private: + + std::minstd_rand m_LinearRand; + std::uniform_int_distribution<> m_IntDistribution; + std::uniform_real_distribution m_FloatDistribution; +}; + + + + + +class MTRand +{ +public: + + MTRand(void); + + int randInt(int a_Range); + + int randInt(void); + double rand(double a_Range); +private: + std::mt19937 m_MersenneRand; + std::uniform_int_distribution<> m_IntDistribution; + std::uniform_real_distribution<> m_DoubleDistribution; +}; \ No newline at end of file diff --git a/src/Generating/ChunkGenerator.cpp b/src/Generating/ChunkGenerator.cpp index d615456c1..20b6b7066 100644 --- a/src/Generating/ChunkGenerator.cpp +++ b/src/Generating/ChunkGenerator.cpp @@ -6,7 +6,7 @@ #include "ChunkDesc.h" #include "ComposableGenerator.h" #include "Noise3DGenerator.h" -#include "../MersenneTwister.h" +#include "FastRandom.h" diff --git a/src/Globals.h b/src/Globals.h index f6c722594..6e6bb9c92 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -240,6 +240,7 @@ template class SizeChecker; // STL stuff: #include +#include #include #include #include diff --git a/src/MersenneTwister.h b/src/MersenneTwister.h deleted file mode 100644 index 759b8a1ae..000000000 --- a/src/MersenneTwister.h +++ /dev/null @@ -1,456 +0,0 @@ -// MersenneTwister.h -// Mersenne Twister random number generator -- a C++ class MTRand -// Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus -// Richard J. Wagner v1.1 28 September 2009 wagnerr@umich.edu - -// The Mersenne Twister is an algorithm for generating random numbers. It -// was designed with consideration of the flaws in various other generators. -// The period, 2^19937-1, and the order of equidistribution, 623 dimensions, -// are far greater. The generator is also fast; it avoids multiplication and -// division, and it benefits from caches and pipelines. For more information -// see the inventors' web page at -// http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html - -// Reference -// M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally -// Equidistributed Uniform Pseudo-Random Number Generator", ACM Transactions on -// Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30. - -// Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, -// Copyright (C) 2000 - 2009, Richard J. Wagner -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// -// 1. Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// 3. The names of its contributors may not be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#ifndef MERSENNETWISTER_H -#define MERSENNETWISTER_H - -// Not thread safe (unless auto-initialization is avoided and each thread has -// its own MTRand object) - -#include -#include -#include -#include -#include - -class MTRand { -// Data -public: - typedef UInt32 uint32; // unsigned integer type, at least 32 bits - - enum { N = 624 }; // length of state vector - enum { SAVE = N + 1 }; // length of array for save() - -protected: - enum { M = 397 }; // period parameter - - uint32 state[N]; // internal state - uint32 *pNext; // next value to get from state - uint32 left; // number of values left before reload needed - -// Methods -public: - MTRand( const uint32 oneSeed ); // initialize with a simple uint32 - MTRand( uint32 *const bigSeed, uint32 const seedLength = N ); // or array - MTRand(); // auto-initialize with /dev/urandom or time() and clock() - MTRand( const MTRand& o ); // copy - - // Do NOT use for CRYPTOGRAPHY without securely hashing several returned - // values together, otherwise the generator state can be learned after - // reading 624 consecutive values. - - // Access to 32-bit random numbers - uint32 randInt(); // integer in [0,2^32-1] - uint32 randInt( const uint32 n ); // integer in [0,n] for n < 2^32 - double rand(); // real number in [0,1] - double rand( const double n ); // real number in [0,n] - double randExc(); // real number in [0,1) - double randExc( const double n ); // real number in [0,n) - double randDblExc(); // real number in (0,1) - double randDblExc( const double n ); // real number in (0,n) - double operator()(); // same as rand() - - // Access to 53-bit random numbers (capacity of IEEE double precision) - double rand53(); // real number in [0,1) - - // Access to nonuniform random number distributions - double randNorm( const double mean = 0.0, const double stddev = 1.0 ); - - // Re-seeding functions with same behavior as initializers - void seed( const uint32 oneSeed ); - void seed( uint32 *const bigSeed, const uint32 seedLength = N ); - void seed(); - - // Saving and loading generator state - void save( uint32* saveArray ) const; // to array of size SAVE - void load( uint32 *const loadArray ); // from such array - friend std::ostream& operator<<( std::ostream& os, const MTRand& mtrand ); - friend std::istream& operator>>( std::istream& is, MTRand& mtrand ); - MTRand& operator=( const MTRand& o ); - -protected: - void initialize( const uint32 oneSeed ); - void reload(); - uint32 hiBit( const uint32 u ) const { return u & 0x80000000UL; } - uint32 loBit( const uint32 u ) const { return u & 0x00000001UL; } - uint32 loBits( const uint32 u ) const { return u & 0x7fffffffUL; } - uint32 mixBits( const uint32 u, const uint32 v ) const - { return hiBit(u) | loBits(v); } - uint32 magic( const uint32 u ) const - { return loBit(u) ? 0x9908b0dfUL : 0x0UL; } - uint32 twist( const uint32 m, const uint32 s0, const uint32 s1 ) const - { return m ^ (mixBits(s0,s1)>>1) ^ magic(s1); } - static uint32 hash( time_t t, clock_t c ); -}; - -// Functions are defined in order of usage to assist inlining - -inline MTRand::uint32 MTRand::hash( time_t t, clock_t c ) -{ - // Get a uint32 from t and c - // Better than uint32(x) in case x is floating point in [0,1] - // Based on code by Lawrence Kirby (fred@genesis.demon.co.uk) - - static uint32 differ = 0; // guarantee time-based seeds will change - - uint32 h1 = 0; - unsigned char *p = (unsigned char *) &t; - for( size_t i = 0; i < sizeof(t); ++i ) - { - h1 *= UCHAR_MAX + 2U; - h1 += p[i]; - } - uint32 h2 = 0; - p = (unsigned char *) &c; - for( size_t j = 0; j < sizeof(c); ++j ) - { - h2 *= UCHAR_MAX + 2U; - h2 += p[j]; - } - return ( h1 + differ++ ) ^ h2; -} - -inline void MTRand::initialize( const uint32 seed ) -{ - // Initialize generator state with seed - // See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier. - // In previous versions, most significant bits (MSBs) of the seed affect - // only MSBs of the state array. Modified 9 Jan 2002 by Makoto Matsumoto. - uint32 *s = state; - uint32 *r = state; - uint32 i = 1; - *s++ = seed & 0xffffffffUL; - for( ; i < N; ++i ) - { - *s++ = ( 1812433253UL * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffUL; - r++; - } -} - -inline void MTRand::reload() -{ - // Generate N new values in state - // Made clearer and faster by Matthew Bellew (matthew.bellew@home.com) - static const int MmN = int(M) - int(N); // in case enums are unsigned - uint32 *p = state; - int i; - for( i = N - M; i--; ++p ) - *p = twist( p[M], p[0], p[1] ); - for( i = M; --i; ++p ) - *p = twist( p[MmN], p[0], p[1] ); - *p = twist( p[MmN], p[0], state[0] ); - - left = N, pNext = state; -} - -inline void MTRand::seed( const uint32 oneSeed ) -{ - // Seed the generator with a simple uint32 - initialize(oneSeed); - reload(); -} - -inline void MTRand::seed( uint32 *const bigSeed, const uint32 seedLength ) -{ - // Seed the generator with an array of uint32's - // There are 2^19937-1 possible initial states. This function allows - // all of those to be accessed by providing at least 19937 bits (with a - // default seed length of N = 624 uint32's). Any bits above the lower 32 - // in each element are discarded. - // Just call seed() if you want to get array from /dev/urandom - initialize(19650218UL); - uint32 i = 1; - uint32 j = 0; - uint32 k = ( (uint32)N > seedLength ? (uint32)N : seedLength ); - for( ; k; --k ) - { - state[i] = - state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1664525UL ); - state[i] += ( bigSeed[j] & 0xffffffffUL ) + j; - state[i] &= 0xffffffffUL; - ++i; ++j; - if( i >= N ) { state[0] = state[N-1]; i = 1; } - if( j >= seedLength ) j = 0; - } - for( k = N - 1; k; --k ) - { - state[i] = - state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL ); - state[i] -= i; - state[i] &= 0xffffffffUL; - ++i; - if( i >= N ) { state[0] = state[N-1]; i = 1; } - } - state[0] = 0x80000000UL; // MSB is 1, assuring non-zero initial array - reload(); -} - -inline void MTRand::seed() -{ - // Seed the generator with an array from /dev/urandom if available - // Otherwise use a hash of time() and clock() values - - // First try getting an array from /dev/urandom - - /* // Commented out by FakeTruth because doing this 200 times a tick is SUUUUPEERRR SLOW!!~~!\D5Ne - FILE* urandom = fopen( "/dev/urandom", "rb" ); - if( urandom ) - { - uint32 bigSeed[N]; - register uint32 *s = bigSeed; - register int i = N; - register bool success = true; - while( success && i-- ) - success = fread( s++, sizeof(uint32), 1, urandom ); - fclose(urandom); - if( success ) { seed( bigSeed, N ); return; } - } - */ - - // Was not successful, so use time() and clock() instead - seed( hash( time(NULL), clock() ) ); -} - -inline MTRand::MTRand( const uint32 oneSeed ) - { seed(oneSeed); } - -inline MTRand::MTRand( uint32 *const bigSeed, const uint32 seedLength ) - { seed(bigSeed,seedLength); } - -inline MTRand::MTRand() - { seed(); } - -inline MTRand::MTRand( const MTRand& o ) -{ - const uint32 *t = o.state; - uint32 *s = state; - int i = N; - for( ; i--; *s++ = *t++ ) {} - left = o.left; - pNext = &state[N-left]; -} - -inline MTRand::uint32 MTRand::randInt() -{ - // Pull a 32-bit integer from the generator state - // Every other access function simply transforms the numbers extracted here - - if( left == 0 ) reload(); - --left; - - uint32 s1; - s1 = *pNext++; - s1 ^= (s1 >> 11); - s1 ^= (s1 << 7) & 0x9d2c5680UL; - s1 ^= (s1 << 15) & 0xefc60000UL; - return ( s1 ^ (s1 >> 18) ); -} - -inline MTRand::uint32 MTRand::randInt( const uint32 n ) -{ - // Find which bits are used in n - // Optimized by Magnus Jonsson (magnus@smartelectronix.com) - uint32 used = n; - used |= used >> 1; - used |= used >> 2; - used |= used >> 4; - used |= used >> 8; - used |= used >> 16; - - // Draw numbers until one is found in [0,n] - uint32 i; - do - i = randInt() & used; // toss unused bits to shorten search - while( i > n ); - return i; -} - -inline double MTRand::rand() - { return double(randInt()) * (1.0/4294967295.0); } - -inline double MTRand::rand( const double n ) - { return rand() * n; } - -inline double MTRand::randExc() - { return double(randInt()) * (1.0/4294967296.0); } - -inline double MTRand::randExc( const double n ) - { return randExc() * n; } - -inline double MTRand::randDblExc() - { return ( double(randInt()) + 0.5 ) * (1.0/4294967296.0); } - -inline double MTRand::randDblExc( const double n ) - { return randDblExc() * n; } - -inline double MTRand::rand53() -{ - uint32 a = randInt() >> 5, b = randInt() >> 6; - return ( a * 67108864.0 + b ) * (1.0/9007199254740992.0); // by Isaku Wada -} - -inline double MTRand::randNorm( const double mean, const double stddev ) -{ - // Return a real number from a normal (Gaussian) distribution with given - // mean and standard deviation by polar form of Box-Muller transformation - double x, y, r; - do - { - x = 2.0 * rand() - 1.0; - y = 2.0 * rand() - 1.0; - r = x * x + y * y; - } - while ( r >= 1.0 || r == 0.0 ); - double s = sqrt( -2.0 * log(r) / r ); - return mean + x * s * stddev; -} - -inline double MTRand::operator()() -{ - return rand(); -} - -inline void MTRand::save( uint32* saveArray ) const -{ - const uint32 *s = state; - uint32 *sa = saveArray; - int i = N; - for( ; i--; *sa++ = *s++ ) {} - *sa = left; -} - -inline void MTRand::load( uint32 *const loadArray ) -{ - uint32 *s = state; - uint32 *la = loadArray; - int i = N; - for( ; i--; *s++ = *la++ ) {} - left = *la; - pNext = &state[N-left]; -} - -inline std::ostream& operator<<( std::ostream& os, const MTRand& mtrand ) -{ - const MTRand::uint32 *s = mtrand.state; - int i = mtrand.N; - for( ; i--; os << *s++ << "\t" ) {} - return os << mtrand.left; -} - -inline std::istream& operator>>( std::istream& is, MTRand& mtrand ) -{ - MTRand::uint32 *s = mtrand.state; - int i = mtrand.N; - for( ; i--; is >> *s++ ) {} - is >> mtrand.left; - mtrand.pNext = &mtrand.state[mtrand.N-mtrand.left]; - return is; -} - -inline MTRand& MTRand::operator=( const MTRand& o ) -{ - if( this == &o ) return (*this); - const uint32 *t = o.state; - uint32 *s = state; - int i = N; - for( ; i--; *s++ = *t++ ) {} - left = o.left; - pNext = &state[N-left]; - return (*this); -} - -#endif // MERSENNETWISTER_H - -// Change log: -// -// v0.1 - First release on 15 May 2000 -// - Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus -// - Translated from C to C++ -// - Made completely ANSI compliant -// - Designed convenient interface for initialization, seeding, and -// obtaining numbers in default or user-defined ranges -// - Added automatic seeding from /dev/urandom or time() and clock() -// - Provided functions for saving and loading generator state -// -// v0.2 - Fixed bug which reloaded generator one step too late -// -// v0.3 - Switched to clearer, faster reload() code from Matthew Bellew -// -// v0.4 - Removed trailing newline in saved generator format to be consistent -// with output format of built-in types -// -// v0.5 - Improved portability by replacing static const int's with enum's and -// clarifying return values in seed(); suggested by Eric Heimburg -// - Removed MAXINT constant; use 0xffffffffUL instead -// -// v0.6 - Eliminated seed overflow when uint32 is larger than 32 bits -// - Changed integer [0,n] generator to give better uniformity -// -// v0.7 - Fixed operator precedence ambiguity in reload() -// - Added access for real numbers in (0,1) and (0,n) -// -// v0.8 - Included time.h header to properly support time_t and clock_t -// -// v1.0 - Revised seeding to match 26 Jan 2002 update of Nishimura and Matsumoto -// - Allowed for seeding with arrays of any length -// - Added access for real numbers in [0,1) with 53-bit resolution -// - Added access for real numbers from normal (Gaussian) distributions -// - Increased overall speed by optimizing twist() -// - Doubled speed of integer [0,n] generation -// - Fixed out-of-range number generation on 64-bit machines -// - Improved portability by substituting literal constants for long enum's -// - Changed license from GNU LGPL to BSD -// -// v1.1 - Corrected parameter label in randNorm from "variance" to "stddev" -// - Changed randNorm algorithm from basic to polar form for efficiency -// - Updated includes from deprecated to standard forms -// - Cleaned declarations and definitions to please Intel compiler -// - Revised twist() operator to work on ones'-complement machines -// - Fixed reload() function to work when N and M are unsigned -// - Added copy constructor and copy operator from Salvador Espana diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 73dbcb3c3..34dd08f37 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -9,7 +9,6 @@ #include "../Entities/Player.h" #include "../Entities/ExpOrb.h" #include "../MonsterConfig.h" -#include "../MersenneTwister.h" #include "../Chunk.h" #include "../FastRandom.h" diff --git a/src/Mobs/Witch.cpp b/src/Mobs/Witch.cpp index 6956f7b7a..947be0011 100644 --- a/src/Mobs/Witch.cpp +++ b/src/Mobs/Witch.cpp @@ -2,6 +2,7 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "Witch.h" +#include "FastRandom.h" diff --git a/src/Mobs/Witch.h b/src/Mobs/Witch.h index bd059f61d..85d3e1447 100644 --- a/src/Mobs/Witch.h +++ b/src/Mobs/Witch.h @@ -2,7 +2,6 @@ #pragma once #include "AggressiveMonster.h" -#include "../MersenneTwister.h" diff --git a/src/ProbabDistrib.cpp b/src/ProbabDistrib.cpp index 7a5869dcc..c34c75982 100644 --- a/src/ProbabDistrib.cpp +++ b/src/ProbabDistrib.cpp @@ -5,7 +5,7 @@ #include "Globals.h" #include "ProbabDistrib.h" -#include "MersenneTwister.h" +#include "FastRandom.h" diff --git a/src/Root.cpp b/src/Root.cpp index 924ebcc1a..c8a268a78 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -68,24 +68,24 @@ cRoot::~cRoot() -void cRoot::InputThread(cRoot * a_Params) +void cRoot::InputThread(cRoot & a_Params) { cLogCommandOutputCallback Output; - while (!a_Params->m_bStop && !a_Params->m_bRestart && !m_TerminateEventRaised && std::cin.good()) + while (!a_Params.m_bStop && !a_Params.m_bRestart && !m_TerminateEventRaised && std::cin.good()) { AString Command; std::getline(std::cin, Command); if (!Command.empty()) { - a_Params->ExecuteConsoleCommand(TrimString(Command), Output); + a_Params.ExecuteConsoleCommand(TrimString(Command), Output); } } if (m_TerminateEventRaised || !std::cin.good()) { // We have come here because the std::cin has received an EOF / a terminate signal has been sent, and the server is still running; stop the server: - a_Params->m_bStop = true; + a_Params.m_bStop = true; } } @@ -191,7 +191,8 @@ void cRoot::Start(void) LOGD("Starting InputThread..."); try { - m_InputThread = std::thread(InputThread, this); + m_InputThread = std::thread(InputThread, std::ref(*this)); + m_InputThread.detach(); } catch (std::system_error & a_Exception) { @@ -217,17 +218,6 @@ void cRoot::Start(void) m_bStop = true; } - #if !defined(ANDROID_NDK) - try - { - m_InputThread.join(); - } - catch (std::system_error & a_Exception) - { - LOGERROR("ERROR: Could not wait for input thread to finish, error = %s!", a_Exception.code(), a_Exception.what()); - } - #endif - // Stop the server: m_WebAdmin->Stop(); LOG("Shutting down server..."); diff --git a/src/Root.h b/src/Root.h index 85800a4a8..c6bea4902 100644 --- a/src/Root.h +++ b/src/Root.h @@ -210,7 +210,7 @@ private: static cRoot* s_Root; - static void InputThread(cRoot * a_Params); + static void InputThread(cRoot & a_Params); }; // tolua_export diff --git a/src/Server.cpp b/src/Server.cpp index 8e5755a75..c5f4f9042 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -20,8 +20,6 @@ #include "Protocol/ProtocolRecognizer.h" #include "CommandOutput.h" -#include "MersenneTwister.h" - #include "inifile/iniFile.h" #include "Vector3.h" diff --git a/src/World.cpp b/src/World.cpp index 1f9361386..56f0d6ce5 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -45,7 +45,6 @@ #include "MobCensus.h" #include "MobSpawner.h" -#include "MersenneTwister.h" #include "Generating/Trees.h" #include "Bindings/PluginManager.h" #include "Blocks/BlockHandler.h" diff --git a/src/World.h b/src/World.h index bb43d7fba..338721553 100644 --- a/src/World.h +++ b/src/World.h @@ -10,7 +10,6 @@ #define MAX_PLAYERS 65535 #include "Simulator/SimulatorManager.h" -#include "MersenneTwister.h" #include "ChunkMap.h" #include "WorldStorage/WorldStorage.h" #include "Generating/ChunkGenerator.h" @@ -26,6 +25,7 @@ #include "MapManager.h" #include "Blocks/WorldInterface.h" #include "Blocks/BroadcastInterface.h" +#include "FastRandom.h" -- cgit v1.2.3 From bde99d684e0bb51adaa053a240abe61cf4af07fb Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 20 Oct 2014 18:59:40 +0100 Subject: Migrated cSleep and cTimer to std::chrono --- src/CMakeLists.txt | 1 - src/ClientHandle.cpp | 18 +++++------------- src/ClientHandle.h | 10 +++++----- src/DeadlockDetect.cpp | 8 ++++---- src/DeadlockDetect.h | 2 +- src/Entities/Player.cpp | 12 ++++-------- src/Entities/Player.h | 2 +- src/Globals.h | 1 - src/OSSupport/CMakeLists.txt | 2 -- src/OSSupport/IsThread.h | 2 +- src/OSSupport/Sleep.cpp | 19 ------------------- src/OSSupport/Sleep.h | 7 ------- src/OSSupport/Timer.cpp | 37 ------------------------------------- src/OSSupport/Timer.h | 32 -------------------------------- src/Root.cpp | 12 +++--------- src/Server.cpp | 16 ++++++---------- src/World.cpp | 27 +++++++++++---------------- src/main.cpp | 5 ++++- 18 files changed, 45 insertions(+), 168 deletions(-) delete mode 100644 src/OSSupport/Sleep.cpp delete mode 100644 src/OSSupport/Sleep.h delete mode 100644 src/OSSupport/Timer.cpp delete mode 100644 src/OSSupport/Timer.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9d0e2cede..e322b842b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -112,7 +112,6 @@ SET (HDRS MapManager.h Matrix4.h MemoryLeak.h - MersenneTwister.h MobCensus.h MobFamilyCollecter.h MobProximityCounter.h diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 7d0f2de06..3dcbaa6a9 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -16,7 +16,6 @@ #include "Mobs/Monster.h" #include "ChatColor.h" #include "OSSupport/Socket.h" -#include "OSSupport/Timer.h" #include "Items/ItemHandler.h" #include "Blocks/BlockHandler.h" #include "Blocks/BlockSlab.h" @@ -63,8 +62,6 @@ cClientHandle::cClientHandle(const cSocket * a_Socket, int a_ViewDistance) : m_TimeSinceLastPacket(0), m_Ping(1000), m_PingID(1), - m_PingStartTime(0), - m_LastPingTime(1000), m_BlockDigAnimStage(-1), m_BlockDigAnimSpeed(0), m_BlockDigAnimX(0), @@ -87,9 +84,7 @@ cClientHandle::cClientHandle(const cSocket * a_Socket, int a_ViewDistance) : s_ClientCount++; // Not protected by CS because clients are always constructed from the same thread m_UniqueID = s_ClientCount; - - cTimer t1; - m_LastPingTime = t1.GetNowTime(); + m_LastPingTime = std::chrono::steady_clock::now(); LOGD("New ClientHandle created at %p", this); } @@ -383,8 +378,7 @@ void cClientHandle::Authenticate(const AString & a_Name, const AString & a_UUID, // Delay the first ping until the client "settles down" // This should fix #889, "BadCast exception, cannot convert bit to fm" error in client - cTimer t1; - m_LastPingTime = t1.GetNowTime() + 3000; // Send the first KeepAlive packet in 3 seconds + m_LastPingTime = std::chrono::steady_clock::now() + std::chrono::seconds(3); // Send the first KeepAlive packet in 3 seconds cRoot::Get()->GetPluginManager()->CallHookPlayerSpawned(*m_Player); } @@ -1694,8 +1688,7 @@ void cClientHandle::HandleKeepAlive(int a_KeepAliveID) { if (a_KeepAliveID == m_PingID) { - cTimer t1; - m_Ping = (short)((t1.GetNowTime() - m_PingStartTime) / 2); + m_Ping = std::chrono::steady_clock::now() - m_PingStartTime; } } @@ -1919,11 +1912,10 @@ void cClientHandle::Tick(float a_Dt) // Send a ping packet: if (m_State == csPlaying) { - cTimer t1; - if ((m_LastPingTime + cClientHandle::PING_TIME_MS <= t1.GetNowTime())) + if ((m_LastPingTime + cClientHandle::PING_TIME_MS <= std::chrono::steady_clock::now())) { m_PingID++; - m_PingStartTime = t1.GetNowTime(); + m_PingStartTime = std::chrono::steady_clock::now(); m_Protocol->SendKeepAlive(m_PingID); m_LastPingTime = m_PingStartTime; } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 9733ff32d..ef7974efd 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -210,7 +210,7 @@ public: const AString & GetUsername(void) const; void SetUsername( const AString & a_Username); - inline short GetPing(void) const { return m_Ping; } + inline short GetPing(void) const { return static_cast(std::chrono::duration_cast(m_Ping).count()); } void SetViewDistance(int a_ViewDistance); int GetViewDistance(void) const { return m_ViewDistance; } @@ -367,11 +367,11 @@ private: /** Seconds since the last packet data was received (updated in Tick(), reset in DataReceived()) */ float m_TimeSinceLastPacket; - short m_Ping; + std::chrono::steady_clock::duration m_Ping; int m_PingID; - long long m_PingStartTime; - long long m_LastPingTime; - static const unsigned short PING_TIME_MS = 1000; // Vanilla sends 1 per 20 ticks (1 second or every 1000 ms) + std::chrono::steady_clock::time_point m_PingStartTime; + std::chrono::steady_clock::time_point m_LastPingTime; + std::chrono::milliseconds PING_TIME_MS = std::chrono::milliseconds(1000); // Vanilla sends 1 per 20 ticks (1 second or every 1000 ms) // Values required for block dig animation int m_BlockDigAnimStage; // Current stage of the animation; -1 if not digging diff --git a/src/DeadlockDetect.cpp b/src/DeadlockDetect.cpp index 7f703416c..81a328af8 100644 --- a/src/DeadlockDetect.cpp +++ b/src/DeadlockDetect.cpp @@ -13,8 +13,8 @@ -/// Number of milliseconds per cycle -const int CYCLE_MILLISECONDS = 100; +/** Number of milliseconds per cycle */ +#define CYCLE_MILLISECONDS 100 @@ -87,7 +87,7 @@ void cDeadlockDetect::Execute(void) } Checker(this); cRoot::Get()->ForEachWorld(Checker); - cSleep::MilliSleep(CYCLE_MILLISECONDS); + std::this_thread::sleep_for(std::chrono::milliseconds(CYCLE_MILLISECONDS)); } // while (should run) } @@ -119,7 +119,7 @@ void cDeadlockDetect::CheckWorldAge(const AString & a_WorldName, Int64 a_Age) if (WorldAge.m_Age == a_Age) { WorldAge.m_NumCyclesSame += 1; - if (WorldAge.m_NumCyclesSame > (1000 * m_IntervalSec) / CYCLE_MILLISECONDS) + if (WorldAge.m_NumCyclesSame > (m_IntervalSec * 1000) / CYCLE_MILLISECONDS) { DeadlockDetected(); } diff --git a/src/DeadlockDetect.h b/src/DeadlockDetect.h index 6aa98acbb..57027e923 100644 --- a/src/DeadlockDetect.h +++ b/src/DeadlockDetect.h @@ -28,7 +28,7 @@ class cDeadlockDetect : public: cDeadlockDetect(void); - /// Starts the detection. Hides cIsThread's Start, because we need some initialization + /** Starts the detection. Hides cIsThread's Start, because we need some initialization */ bool Start(int a_IntervalSec); protected: diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 6bd0a3d20..24daba048 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -11,7 +11,6 @@ #include "../BlockEntities/BlockEntity.h" #include "../BlockEntities/EnderChestEntity.h" #include "../Root.h" -#include "../OSSupport/Timer.h" #include "../Chunk.h" #include "../Items/ItemHandler.h" #include "../Vector3.h" @@ -27,7 +26,7 @@ #define PLAYER_INVENTORY_SAVE_INTERVAL 6000 // 1000 = once per second -#define PLAYER_LIST_TIME_MS 1000 +#define PLAYER_LIST_TIME_MS std::chrono::milliseconds(1000) @@ -91,9 +90,7 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) : SetMaxHealth(MAX_HEALTH); m_Health = MAX_HEALTH; - cTimer t1; - m_LastPlayerListTime = t1.GetNowTime(); - + m_LastPlayerListTime = std::chrono::steady_clock::now(); m_PlayerName = a_PlayerName; cWorld * World = NULL; @@ -264,11 +261,10 @@ void cPlayer::Tick(float a_Dt, cChunk & a_Chunk) m_Inventory.UpdateItems(); // Send Player List (Once per m_LastPlayerListTime/1000 ms) - cTimer t1; - if (m_LastPlayerListTime + PLAYER_LIST_TIME_MS <= t1.GetNowTime()) + if (m_LastPlayerListTime + PLAYER_LIST_TIME_MS <= std::chrono::steady_clock::now()) { m_World->BroadcastPlayerListUpdatePing(*this); - m_LastPlayerListTime = t1.GetNowTime(); + m_LastPlayerListTime = std::chrono::steady_clock::now(); } if (IsFlying()) diff --git a/src/Entities/Player.h b/src/Entities/Player.h index 22d6a2ae2..8dd5bdb19 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -516,7 +516,7 @@ protected: /** The item being dragged by the cursor while in a UI window */ cItem m_DraggingItem; - long long m_LastPlayerListTime; + std::chrono::steady_clock::time_point m_LastPlayerListTime; cClientHandle * m_ClientHandle; diff --git a/src/Globals.h b/src/Globals.h index 6e6bb9c92..b90542af0 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -257,7 +257,6 @@ template class SizeChecker; #ifndef TEST_GLOBALS // Common headers (part 1, without macros): #include "StringUtils.h" - #include "OSSupport/Sleep.h" #include "OSSupport/CriticalSection.h" #include "OSSupport/Semaphore.h" #include "OSSupport/Event.h" diff --git a/src/OSSupport/CMakeLists.txt b/src/OSSupport/CMakeLists.txt index 1c8da5ddd..45df0c1a3 100644 --- a/src/OSSupport/CMakeLists.txt +++ b/src/OSSupport/CMakeLists.txt @@ -13,7 +13,6 @@ SET (SRCS IsThread.cpp ListenThread.cpp Semaphore.cpp - Sleep.cpp Socket.cpp SocketThreads.cpp Timer.cpp) @@ -28,7 +27,6 @@ SET (HDRS ListenThread.h Queue.h Semaphore.h - Sleep.h Socket.h SocketThreads.h Timer.h) diff --git a/src/OSSupport/IsThread.h b/src/OSSupport/IsThread.h index 8dfad84cb..ba6a48898 100644 --- a/src/OSSupport/IsThread.h +++ b/src/OSSupport/IsThread.h @@ -33,7 +33,7 @@ protected: volatile bool m_ShouldTerminate; public: - cIsThread(const AString & iThreadName); + cIsThread(const AString & a_ThreadName); virtual ~cIsThread(); /// Starts the thread; returns without waiting for the actual start diff --git a/src/OSSupport/Sleep.cpp b/src/OSSupport/Sleep.cpp deleted file mode 100644 index 297d668d7..000000000 --- a/src/OSSupport/Sleep.cpp +++ /dev/null @@ -1,19 +0,0 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#ifndef _WIN32 - #include -#endif - - - - - -void cSleep::MilliSleep( unsigned int a_MilliSeconds) -{ -#ifdef _WIN32 - Sleep(a_MilliSeconds); // Don't tick too much -#else - usleep(a_MilliSeconds*1000); -#endif -} diff --git a/src/OSSupport/Sleep.h b/src/OSSupport/Sleep.h deleted file mode 100644 index 57d29682c..000000000 --- a/src/OSSupport/Sleep.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -class cSleep -{ -public: - static void MilliSleep( unsigned int a_MilliSeconds); -}; diff --git a/src/OSSupport/Timer.cpp b/src/OSSupport/Timer.cpp deleted file mode 100644 index fd838dd0d..000000000 --- a/src/OSSupport/Timer.cpp +++ /dev/null @@ -1,37 +0,0 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "Timer.h" - - - - - - -cTimer::cTimer(void) -{ - #ifdef _WIN32 - QueryPerformanceFrequency(&m_TicksPerSecond); - #endif -} - - - - - -long long cTimer::GetNowTime(void) -{ - #ifdef _WIN32 - LARGE_INTEGER now; - QueryPerformanceCounter(&now); - return ((now.QuadPart * 1000) / m_TicksPerSecond.QuadPart); - #else - struct timeval now; - gettimeofday(&now, NULL); - return (long long)now.tv_sec * 1000 + (long long)now.tv_usec / 1000; - #endif -} - - - - diff --git a/src/OSSupport/Timer.h b/src/OSSupport/Timer.h deleted file mode 100644 index a059daa41..000000000 --- a/src/OSSupport/Timer.h +++ /dev/null @@ -1,32 +0,0 @@ - -// Timer.h - -// Declares the cTimer class representing an OS-independent of retrieving current time with msec accuracy - - - - - -#pragma once - - - - - -class cTimer -{ -public: - cTimer(void); - - // Returns the current time expressed in milliseconds - long long GetNowTime(void); -private: - - #ifdef _WIN32 - LARGE_INTEGER m_TicksPerSecond; - #endif -} ; - - - - diff --git a/src/Root.cpp b/src/Root.cpp index c8a268a78..1271e8648 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -16,7 +16,6 @@ #include "Protocol/ProtocolRecognizer.h" // for protocol version constants #include "CommandOutput.h" #include "DeadlockDetect.h" -#include "OSSupport/Timer.h" #include "LoggerListeners.h" #include "BuildInfo.h" @@ -118,9 +117,7 @@ void cRoot::Start(void) m_bStop = false; while (!m_bStop) { - cTimer Time; - long long mseconds = Time.GetNowTime(); - + auto BeginTime = std::chrono::steady_clock::now(); m_bRestart = false; LoadGlobalSettings(); @@ -200,17 +197,14 @@ void cRoot::Start(void) } #endif - long long finishmseconds = Time.GetNowTime(); - finishmseconds -= mseconds; - - LOG("Startup complete, took %lld ms!", finishmseconds); + LOG("Startup complete, took %lld ms!", std::chrono::duration_cast(std::chrono::steady_clock::now() - BeginTime).count()); #ifdef _WIN32 EnableMenuItem(hmenu, SC_CLOSE, MF_ENABLED); // Re-enable close button #endif while (!m_bStop && !m_bRestart && !m_TerminateEventRaised) // These are modified by external threads { - cSleep::MilliSleep(1000); + std::this_thread::sleep_for(std::chrono::seconds(1)); } if (m_TerminateEventRaised) diff --git a/src/Server.cpp b/src/Server.cpp index c5f4f9042..f29683b21 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -4,7 +4,6 @@ #include "Server.h" #include "ClientHandle.h" -#include "OSSupport/Timer.h" #include "Mobs/Monster.h" #include "OSSupport/Socket.h" #include "Root.h" @@ -73,22 +72,19 @@ cServer::cTickThread::cTickThread(cServer & a_Server) : void cServer::cTickThread::Execute(void) { - cTimer Timer; - - long long msPerTick = 50; - long long LastTime = Timer.GetNowTime(); + auto LastTime = std::chrono::steady_clock::now(); + static const auto msPerTick = std::chrono::milliseconds(50); while (!m_ShouldTerminate) { - long long NowTime = Timer.GetNowTime(); - float DeltaTime = (float)(NowTime-LastTime); - m_ShouldTerminate = !m_Server.Tick(DeltaTime); - long long TickTime = Timer.GetNowTime() - NowTime; + auto NowTime = std::chrono::steady_clock::now(); + m_ShouldTerminate = !m_Server.Tick(std::chrono::duration_cast(NowTime - LastTime).count()); + auto TickTime = std::chrono::steady_clock::now() - NowTime; if (TickTime < msPerTick) { // Stretch tick time until it's at least msPerTick - cSleep::MilliSleep((unsigned int)(msPerTick - TickTime)); + std::this_thread::sleep_for(msPerTick -TickTime); } LastTime = NowTime; diff --git a/src/World.cpp b/src/World.cpp index 56f0d6ce5..010fc0d87 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -11,7 +11,6 @@ #include "inifile/iniFile.h" #include "ChunkMap.h" #include "Generating/ChunkDesc.h" -#include "OSSupport/Timer.h" #include "SetChunkData.h" // Serializers @@ -109,7 +108,7 @@ protected: // Wait for 2 sec, but be "reasonably wakeable" when the thread is to finish for (int i = 0; i < 20; i++) { - cSleep::MilliSleep(100); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); if (m_ShouldTerminate) { return; @@ -159,7 +158,7 @@ protected: // Wait for 2 sec, but be "reasonably wakeable" when the thread is to finish for (int i = 0; i < 20; i++) { - cSleep::MilliSleep(100); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); if (m_ShouldTerminate) { return; @@ -167,8 +166,7 @@ protected: } } // for (-ever) } - -} ; +}; @@ -201,23 +199,20 @@ cWorld::cTickThread::cTickThread(cWorld & a_World) : void cWorld::cTickThread::Execute(void) { - cTimer Timer; - - const Int64 msPerTick = 50; - Int64 LastTime = Timer.GetNowTime(); + auto LastTime = std::chrono::steady_clock::now(); + static const auto msPerTick = std::chrono::milliseconds(50); + auto TickTime = std::chrono::steady_clock::duration(50); - Int64 TickDuration = 50; while (!m_ShouldTerminate) { - Int64 NowTime = Timer.GetNowTime(); - float DeltaTime = (float)(NowTime - LastTime); - m_World.Tick(DeltaTime, (int)TickDuration); - TickDuration = Timer.GetNowTime() - NowTime; + auto NowTime = std::chrono::steady_clock::now(); + m_World.Tick(std::chrono::duration_cast(NowTime - LastTime).count(), std::chrono::duration_cast>(TickTime).count()); + TickTime = std::chrono::steady_clock::now() - NowTime; - if (TickDuration < msPerTick) + if (TickTime < msPerTick) { // Stretch tick time until it's at least msPerTick - cSleep::MilliSleep((unsigned int)(msPerTick - TickDuration)); + std::this_thread::sleep_for(msPerTick -TickTime); } LastTime = NowTime; diff --git a/src/main.cpp b/src/main.cpp index 86ecd4000..b1cfd6976 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -160,7 +160,10 @@ BOOL CtrlHandler(DWORD fdwCtrlType) if (fdwCtrlType == CTRL_CLOSE_EVENT) // Console window closed via 'x' button, Windows will try to close immediately, therefore... { - while (!g_ServerTerminated) { cSleep::MilliSleep(100); } // Delay as much as possible to try to get the server to shut down cleanly + while (!g_ServerTerminated) + { + std::this_thread::sleep_for(std::chrono::milliseconds(50)); // Delay as much as possible to try to get the server to shut down cleanly + } } return TRUE; -- cgit v1.2.3 From a324333c11c7cc981104ae0483a0203c34e0e991 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 20 Oct 2014 21:26:18 +0100 Subject: Use std::recusive_mutex --- src/OSSupport/CriticalSection.cpp | 48 ++++----------------------------------- src/OSSupport/CriticalSection.h | 11 +++------ src/OSSupport/IsThread.cpp | 2 +- 3 files changed, 9 insertions(+), 52 deletions(-) diff --git a/src/OSSupport/CriticalSection.cpp b/src/OSSupport/CriticalSection.cpp index 3e8e7498d..13a3e4d9f 100644 --- a/src/OSSupport/CriticalSection.cpp +++ b/src/OSSupport/CriticalSection.cpp @@ -1,6 +1,5 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules -#include "IsThread.h" @@ -9,41 +8,12 @@ //////////////////////////////////////////////////////////////////////////////// // cCriticalSection: +#ifdef _DEBUG cCriticalSection::cCriticalSection() { - #ifdef _WIN32 - InitializeCriticalSection(&m_CriticalSection); - #else - pthread_mutexattr_init(&m_Attributes); - pthread_mutexattr_settype(&m_Attributes, PTHREAD_MUTEX_RECURSIVE); - - if (pthread_mutex_init(&m_CriticalSection, &m_Attributes) != 0) - { - LOGERROR("Could not initialize Critical Section!"); - } - #endif - - #ifdef _DEBUG - m_IsLocked = 0; - #endif // _DEBUG -} - - - - - -cCriticalSection::~cCriticalSection() -{ - #ifdef _WIN32 - DeleteCriticalSection(&m_CriticalSection); - #else - if (pthread_mutex_destroy(&m_CriticalSection) != 0) - { - LOGWARNING("Could not destroy Critical Section!"); - } - pthread_mutexattr_destroy(&m_Attributes); - #endif + m_IsLocked = 0; } +#endif // _DEBUG @@ -51,11 +21,7 @@ cCriticalSection::~cCriticalSection() void cCriticalSection::Lock() { - #ifdef _WIN32 - EnterCriticalSection(&m_CriticalSection); - #else - pthread_mutex_lock(&m_CriticalSection); - #endif + m_Mutex.lock(); #ifdef _DEBUG m_IsLocked += 1; @@ -74,11 +40,7 @@ void cCriticalSection::Unlock() m_IsLocked -= 1; #endif // _DEBUG - #ifdef _WIN32 - LeaveCriticalSection(&m_CriticalSection); - #else - pthread_mutex_unlock(&m_CriticalSection); - #endif + m_Mutex.unlock(); } diff --git a/src/OSSupport/CriticalSection.h b/src/OSSupport/CriticalSection.h index 7822a5471..19e4f78af 100644 --- a/src/OSSupport/CriticalSection.h +++ b/src/OSSupport/CriticalSection.h @@ -1,5 +1,6 @@ #pragma once +#include @@ -8,8 +9,6 @@ class cCriticalSection { public: - cCriticalSection(void); - ~cCriticalSection(); void Lock(void); void Unlock(void); @@ -17,6 +16,7 @@ public: // IsLocked/IsLockedByCurrentThread are only used in ASSERT statements, but because of the changes with ASSERT they must always be defined // The fake versions (in Release) will not effect the program in any way #ifdef _DEBUG + cCriticalSection(void); bool IsLocked(void); bool IsLockedByCurrentThread(void); #else @@ -30,12 +30,7 @@ private: std::thread::id m_OwningThreadID; #endif // _DEBUG - #ifdef _WIN32 - CRITICAL_SECTION m_CriticalSection; - #else // _WIN32 - pthread_mutex_t m_CriticalSection; - pthread_mutexattr_t m_Attributes; - #endif // else _WIN32 + std::recursive_mutex m_Mutex; } ALIGN_8; diff --git a/src/OSSupport/IsThread.cpp b/src/OSSupport/IsThread.cpp index 4864ef28b..94c867d19 100644 --- a/src/OSSupport/IsThread.cpp +++ b/src/OSSupport/IsThread.cpp @@ -63,7 +63,7 @@ void cIsThread::Stop(void) bool cIsThread::Wait(void) -{ +{ #ifdef LOGD // ProtoProxy doesn't have LOGD LOGD("Waiting for thread %s to finish", m_ThreadName.c_str()); #endif // LOGD -- cgit v1.2.3 From 987f79afdd8945966d0dfa2d52539e005f771590 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 20 Oct 2014 21:55:07 +0100 Subject: En masse NULL -> nullptr replace --- src/AllocationPool.h | 6 +- src/Bindings/DeprecatedBindings.cpp | 36 ++-- src/Bindings/LuaChunkStay.cpp | 2 +- src/Bindings/LuaState.cpp | 54 +++--- src/Bindings/LuaState.h | 6 +- src/Bindings/LuaWindow.cpp | 14 +- src/Bindings/ManualBindings.cpp | 270 +++++++++++++-------------- src/Bindings/ManualBindings_RankManager.cpp | 2 +- src/Bindings/PluginLua.cpp | 14 +- src/Bindings/PluginManager.cpp | 32 ++-- src/Bindings/PluginManager.h | 4 +- src/Bindings/WebPlugin.cpp | 8 +- src/BlockArea.cpp | 88 ++++----- src/BlockArea.h | 8 +- src/BlockEntities/BeaconEntity.cpp | 10 +- src/BlockEntities/BlockEntity.cpp | 2 +- src/BlockEntities/BlockEntity.h | 4 +- src/BlockEntities/BlockEntityWithItems.h | 6 +- src/BlockEntities/ChestEntity.cpp | 6 +- src/BlockEntities/CommandBlockEntity.cpp | 2 +- src/BlockEntities/DispenserEntity.cpp | 4 +- src/BlockEntities/DropSpenserEntity.cpp | 6 +- src/BlockEntities/EnderChestEntity.cpp | 6 +- src/BlockEntities/FlowerPotEntity.cpp | 2 +- src/BlockEntities/FlowerPotEntity.h | 2 +- src/BlockEntities/FurnaceEntity.cpp | 8 +- src/BlockEntities/HopperEntity.cpp | 24 +-- src/BlockEntities/MobHeadEntity.h | 2 +- src/BlockEntities/NoteEntity.h | 2 +- src/BlockEntities/SignEntity.h | 2 +- src/BlockInfo.cpp | 4 +- src/BlockInfo.h | 2 +- src/Blocks/BlockDirt.h | 2 +- src/Blocks/BlockHandler.cpp | 8 +- src/Blocks/BlockHandler.h | 2 +- src/Blocks/BlockLeaves.h | 2 +- src/Blocks/BlockPiston.cpp | 2 +- src/Blocks/BlockVine.h | 2 +- src/Blocks/BroadcastInterface.h | 4 +- src/ByteBuffer.cpp | 2 +- src/Chunk.cpp | 102 +++++----- src/Chunk.h | 48 ++--- src/ChunkData.cpp | 52 +++--- src/ChunkData.h | 6 +- src/ChunkMap.cpp | 278 ++++++++++++++-------------- src/ChunkMap.h | 50 ++--- src/ChunkSender.cpp | 16 +- src/ChunkSender.h | 2 +- src/ChunkStay.cpp | 14 +- src/ClientHandle.cpp | 52 +++--- src/CraftingRecipes.cpp | 18 +- src/CraftingRecipes.h | 4 +- src/Defines.h | 12 +- src/Entities/ArrowEntity.cpp | 2 +- src/Entities/Boat.cpp | 4 +- src/Entities/Entity.cpp | 56 +++--- src/Entities/Entity.h | 14 +- src/Entities/EntityEffect.cpp | 10 +- src/Entities/ExpOrb.cpp | 2 +- src/Entities/Floater.cpp | 2 +- src/Entities/ItemFrame.cpp | 4 +- src/Entities/Minecart.cpp | 14 +- src/Entities/Minecart.h | 4 +- src/Entities/Painting.cpp | 2 +- src/Entities/Player.cpp | 60 +++--- src/Entities/Player.h | 4 +- src/Entities/ProjectileEntity.cpp | 16 +- src/Entities/ProjectileEntity.h | 4 +- src/FurnaceRecipe.cpp | 8 +- src/FurnaceRecipe.h | 2 +- src/Generating/BioGen.cpp | 6 +- src/Generating/ChunkDesc.cpp | 4 +- src/Generating/ChunkDesc.h | 2 +- src/Generating/ChunkGenerator.cpp | 18 +- src/Generating/CompoGen.cpp | 4 +- src/Generating/ComposableGenerator.cpp | 6 +- src/Generating/DungeonRoomsFinisher.cpp | 2 +- src/Generating/GridStructGen.cpp | 2 +- src/Generating/HeiGen.cpp | 6 +- src/Generating/MineShafts.cpp | 18 +- src/Generating/PieceGenerator.cpp | 4 +- src/Generating/Prefab.cpp | 6 +- src/Generating/PrefabPiecePool.cpp | 6 +- src/Generating/VillageGen.cpp | 4 +- src/HTTPServer/HTTPConnection.cpp | 16 +- src/HTTPServer/HTTPConnection.h | 6 +- src/HTTPServer/HTTPFormParser.cpp | 4 +- src/HTTPServer/HTTPMessage.cpp | 2 +- src/HTTPServer/HTTPServer.cpp | 10 +- src/Inventory.cpp | 12 +- src/Inventory.h | 4 +- src/Item.cpp | 2 +- src/ItemGrid.cpp | 2 +- src/Items/ItemBow.h | 8 +- src/Items/ItemEmptyMap.h | 2 +- src/Items/ItemHandler.cpp | 4 +- src/Items/ItemItemFrame.h | 2 +- src/Items/ItemMap.h | 2 +- src/Items/ItemMinecart.h | 2 +- src/LeakFinder.h | 8 +- src/LightingThread.cpp | 8 +- src/LightingThread.h | 2 +- src/LineBlockTracer.cpp | 4 +- src/LinearUpscale.h | 8 +- src/LoggerListeners.cpp | 2 +- src/Map.cpp | 18 +- src/MapManager.cpp | 8 +- src/MapManager.h | 4 +- src/MobSpawner.cpp | 2 +- src/Mobs/AggressiveMonster.cpp | 6 +- src/Mobs/Blaze.cpp | 8 +- src/Mobs/Blaze.h | 2 +- src/Mobs/CaveSpider.cpp | 4 +- src/Mobs/CaveSpider.h | 2 +- src/Mobs/Chicken.cpp | 2 +- src/Mobs/Chicken.h | 2 +- src/Mobs/Cow.cpp | 2 +- src/Mobs/Cow.h | 2 +- src/Mobs/Creeper.cpp | 4 +- src/Mobs/Creeper.h | 2 +- src/Mobs/EnderDragon.h | 2 +- src/Mobs/Enderman.cpp | 10 +- src/Mobs/Enderman.h | 2 +- src/Mobs/Ghast.cpp | 8 +- src/Mobs/Ghast.h | 2 +- src/Mobs/Giant.h | 2 +- src/Mobs/Horse.cpp | 6 +- src/Mobs/Horse.h | 2 +- src/Mobs/IronGolem.h | 2 +- src/Mobs/MagmaCube.h | 2 +- src/Mobs/Monster.cpp | 28 +-- src/Mobs/Mooshroom.cpp | 2 +- src/Mobs/Mooshroom.h | 2 +- src/Mobs/PassiveAggressiveMonster.cpp | 2 +- src/Mobs/PassiveMonster.cpp | 4 +- src/Mobs/Pig.cpp | 6 +- src/Mobs/Pig.h | 2 +- src/Mobs/Sheep.cpp | 2 +- src/Mobs/Sheep.h | 2 +- src/Mobs/Skeleton.cpp | 8 +- src/Mobs/Skeleton.h | 2 +- src/Mobs/Slime.cpp | 2 +- src/Mobs/Slime.h | 2 +- src/Mobs/SnowGolem.h | 2 +- src/Mobs/Spider.cpp | 4 +- src/Mobs/Spider.h | 2 +- src/Mobs/Squid.cpp | 2 +- src/Mobs/Squid.h | 2 +- src/Mobs/Villager.cpp | 2 +- src/Mobs/Witch.cpp | 2 +- src/Mobs/Witch.h | 2 +- src/Mobs/Wither.h | 2 +- src/Mobs/Wolf.cpp | 4 +- src/Mobs/Zombie.cpp | 2 +- src/Mobs/Zombie.h | 2 +- src/Mobs/ZombiePigman.cpp | 4 +- src/Mobs/ZombiePigman.h | 2 +- src/MonsterConfig.cpp | 2 +- src/Noise.cpp | 16 +- src/Noise.h | 12 +- src/OSSupport/Errors.cpp | 4 +- src/OSSupport/Event.cpp | 6 +- src/OSSupport/File.cpp | 22 +-- src/OSSupport/GZipFile.cpp | 14 +- src/OSSupport/ListenThread.cpp | 2 +- src/OSSupport/Semaphore.cpp | 4 +- src/OSSupport/Socket.cpp | 2 +- src/OSSupport/SocketThreads.cpp | 14 +- src/OSSupport/SocketThreads.h | 2 +- src/PolarSSL++/BlockingSslClientSocket.cpp | 4 +- src/PolarSSL++/CallbackSslContext.cpp | 6 +- src/PolarSSL++/CryptoKey.cpp | 2 +- src/PolarSSL++/SslContext.cpp | 8 +- src/Protocol/MojangAPI.cpp | 16 +- src/Protocol/MojangAPI.h | 6 +- src/Protocol/Protocol17x.cpp | 6 +- src/Protocol/Protocol18x.cpp | 6 +- src/Protocol/ProtocolRecognizer.cpp | 154 +++++++-------- src/RCONServer.cpp | 8 +- src/RankManager.cpp | 6 +- src/RankManager.h | 2 +- src/Root.cpp | 40 ++-- src/Scoreboard.cpp | 20 +- src/Scoreboard.h | 8 +- src/Server.cpp | 22 +-- src/SetChunkData.cpp | 10 +- src/SetChunkData.h | 2 +- src/Simulator/DelayedFluidSimulator.cpp | 4 +- src/Simulator/FireSimulator.cpp | 4 +- src/Simulator/FloodyFluidSimulator.cpp | 4 +- src/Simulator/FluidSimulator.cpp | 2 +- src/Simulator/FluidSimulator.h | 2 +- src/Simulator/NoopRedstoneSimulator.h | 2 +- src/Simulator/SandSimulator.cpp | 2 +- src/Simulator/VaporizeFluidSimulator.cpp | 2 +- src/StackWalker.h | 12 +- src/StringUtils.cpp | 4 +- src/UI/SlotArea.cpp | 40 ++-- src/UI/Window.cpp | 38 ++-- src/UI/Window.h | 6 +- src/UI/WindowOwner.h | 4 +- src/WebAdmin.cpp | 10 +- src/World.cpp | 70 +++---- src/World.h | 90 ++++----- src/WorldStorage/NBTChunkSerializer.cpp | 2 +- src/WorldStorage/ScoreboardSerializer.cpp | 6 +- src/WorldStorage/WSSAnvil.cpp | 88 ++++----- src/WorldStorage/WSSAnvil.h | 6 +- src/WorldStorage/WorldStorage.cpp | 4 +- src/XMLParser.h | 116 ++++++------ src/main.cpp | 8 +- 211 files changed, 1439 insertions(+), 1439 deletions(-) diff --git a/src/AllocationPool.h b/src/AllocationPool.h index 61431a548..7c358cc84 100644 --- a/src/AllocationPool.h +++ b/src/AllocationPool.h @@ -45,7 +45,7 @@ class cListAllocationPool : public cAllocationPool for (size_t i = 0; i < NumElementsInReserve; i++) { void * space = malloc(sizeof(T)); - if (space == NULL) + if (space == nullptr) { m_Callbacks->OnStartUsingReserve(); break; @@ -68,7 +68,7 @@ class cListAllocationPool : public cAllocationPool if (m_FreeList.size() <= NumElementsInReserve) { void * space = malloc(sizeof(T)); - if (space != NULL) + if (space != nullptr) { return new(space) T; } @@ -90,7 +90,7 @@ class cListAllocationPool : public cAllocationPool } virtual void Free(T * a_ptr) override { - if (a_ptr == NULL) + if (a_ptr == nullptr) { return; } diff --git a/src/Bindings/DeprecatedBindings.cpp b/src/Bindings/DeprecatedBindings.cpp index 02aa15be4..ded7a0142 100644 --- a/src/Bindings/DeprecatedBindings.cpp +++ b/src/Bindings/DeprecatedBindings.cpp @@ -29,7 +29,7 @@ static int tolua_get_AllToLua_g_BlockLightValue(lua_State* tolua_S) BlockType = (int)tolua_tonumber(tolua_S, 2, 0); if ((BlockType < 0) || (BlockType > E_BLOCK_MAX_TYPE_ID)) { - tolua_error(tolua_S, "array indexing out of range.", NULL); + tolua_error(tolua_S, "array indexing out of range.", nullptr); } tolua_pushnumber(tolua_S, (lua_Number)cBlockInfo::GetLightValue((BLOCKTYPE)BlockType)); return 1; @@ -55,7 +55,7 @@ static int tolua_get_AllToLua_g_BlockSpreadLightFalloff(lua_State* tolua_S) BlockType = (int)tolua_tonumber(tolua_S, 2, 0); if ((BlockType < 0) || (BlockType > E_BLOCK_MAX_TYPE_ID)) { - tolua_error(tolua_S, "array indexing out of range.", NULL); + tolua_error(tolua_S, "array indexing out of range.", nullptr); } tolua_pushnumber(tolua_S, (lua_Number)cBlockInfo::GetSpreadLightFalloff((BLOCKTYPE)BlockType)); return 1; @@ -81,7 +81,7 @@ static int tolua_get_AllToLua_g_BlockTransparent(lua_State* tolua_S) BlockType = (int)tolua_tonumber(tolua_S, 2, 0); if ((BlockType < 0) || (BlockType > E_BLOCK_MAX_TYPE_ID)) { - tolua_error(tolua_S, "array indexing out of range.", NULL); + tolua_error(tolua_S, "array indexing out of range.", nullptr); } tolua_pushboolean(tolua_S, cBlockInfo::IsTransparent((BLOCKTYPE)BlockType)); return 1; @@ -107,7 +107,7 @@ static int tolua_get_AllToLua_g_BlockOneHitDig(lua_State* tolua_S) BlockType = (int)tolua_tonumber(tolua_S, 2, 0); if ((BlockType < 0) || (BlockType > E_BLOCK_MAX_TYPE_ID)) { - tolua_error(tolua_S, "array indexing out of range.", NULL); + tolua_error(tolua_S, "array indexing out of range.", nullptr); } tolua_pushboolean(tolua_S, cBlockInfo::IsOneHitDig((BLOCKTYPE)BlockType)); return 1; @@ -133,7 +133,7 @@ static int tolua_get_AllToLua_g_BlockPistonBreakable(lua_State* tolua_S) BlockType = (int)tolua_tonumber(tolua_S, 2, 0); if ((BlockType < 0) || (BlockType > E_BLOCK_MAX_TYPE_ID)) { - tolua_error(tolua_S, "array indexing out of range.", NULL); + tolua_error(tolua_S, "array indexing out of range.", nullptr); } tolua_pushboolean(tolua_S, cBlockInfo::IsPistonBreakable((BLOCKTYPE)BlockType)); return 1; @@ -159,7 +159,7 @@ static int tolua_get_AllToLua_g_BlockIsSnowable(lua_State* tolua_S) BlockType = (int)tolua_tonumber(tolua_S, 2, 0); if ((BlockType < 0) || (BlockType > E_BLOCK_MAX_TYPE_ID)) { - tolua_error(tolua_S, "array indexing out of range.", NULL); + tolua_error(tolua_S, "array indexing out of range.", nullptr); } tolua_pushboolean(tolua_S, cBlockInfo::IsSnowable((BLOCKTYPE)BlockType)); return 1; @@ -185,7 +185,7 @@ static int tolua_get_AllToLua_g_BlockIsSolid(lua_State* tolua_S) BlockType = (int)tolua_tonumber(tolua_S, 2, 0); if ((BlockType < 0) || (BlockType > E_BLOCK_MAX_TYPE_ID)) { - tolua_error(tolua_S, "array indexing out of range.", NULL); + tolua_error(tolua_S, "array indexing out of range.", nullptr); } tolua_pushboolean(tolua_S, (bool)cBlockInfo::IsSolid((BLOCKTYPE)BlockType)); return 1; @@ -211,7 +211,7 @@ static int tolua_get_AllToLua_g_BlockFullyOccupiesVoxel(lua_State* tolua_S) BlockType = (int)tolua_tonumber(tolua_S, 2, 0); if ((BlockType < 0) || (BlockType > E_BLOCK_MAX_TYPE_ID)) { - tolua_error(tolua_S, "array indexing out of range.", NULL); + tolua_error(tolua_S, "array indexing out of range.", nullptr); } tolua_pushboolean(tolua_S, (bool)cBlockInfo::FullyOccupiesVoxel((BLOCKTYPE)BlockType)); return 1; @@ -224,16 +224,16 @@ static int tolua_get_AllToLua_g_BlockFullyOccupiesVoxel(lua_State* tolua_S) void DeprecatedBindings::Bind(lua_State * tolua_S) { - tolua_beginmodule(tolua_S, NULL); - - tolua_array(tolua_S, "g_BlockLightValue", tolua_get_AllToLua_g_BlockLightValue, NULL); - tolua_array(tolua_S, "g_BlockSpreadLightFalloff", tolua_get_AllToLua_g_BlockSpreadLightFalloff, NULL); - tolua_array(tolua_S, "g_BlockTransparent", tolua_get_AllToLua_g_BlockTransparent, NULL); - tolua_array(tolua_S, "g_BlockOneHitDig", tolua_get_AllToLua_g_BlockOneHitDig, NULL); - tolua_array(tolua_S, "g_BlockPistonBreakable", tolua_get_AllToLua_g_BlockPistonBreakable, NULL); - tolua_array(tolua_S, "g_BlockIsSnowable", tolua_get_AllToLua_g_BlockIsSnowable, NULL); - tolua_array(tolua_S, "g_BlockIsSolid", tolua_get_AllToLua_g_BlockIsSolid, NULL); - tolua_array(tolua_S, "g_BlockFullyOccupiesVoxel", tolua_get_AllToLua_g_BlockFullyOccupiesVoxel, NULL); + tolua_beginmodule(tolua_S, nullptr); + + tolua_array(tolua_S, "g_BlockLightValue", tolua_get_AllToLua_g_BlockLightValue, nullptr); + tolua_array(tolua_S, "g_BlockSpreadLightFalloff", tolua_get_AllToLua_g_BlockSpreadLightFalloff, nullptr); + tolua_array(tolua_S, "g_BlockTransparent", tolua_get_AllToLua_g_BlockTransparent, nullptr); + tolua_array(tolua_S, "g_BlockOneHitDig", tolua_get_AllToLua_g_BlockOneHitDig, nullptr); + tolua_array(tolua_S, "g_BlockPistonBreakable", tolua_get_AllToLua_g_BlockPistonBreakable, nullptr); + tolua_array(tolua_S, "g_BlockIsSnowable", tolua_get_AllToLua_g_BlockIsSnowable, nullptr); + tolua_array(tolua_S, "g_BlockIsSolid", tolua_get_AllToLua_g_BlockIsSolid, nullptr); + tolua_array(tolua_S, "g_BlockFullyOccupiesVoxel", tolua_get_AllToLua_g_BlockFullyOccupiesVoxel, nullptr); tolua_endmodule(tolua_S); } diff --git a/src/Bindings/LuaChunkStay.cpp b/src/Bindings/LuaChunkStay.cpp index 23da12f68..e50ffb75b 100644 --- a/src/Bindings/LuaChunkStay.cpp +++ b/src/Bindings/LuaChunkStay.cpp @@ -13,7 +13,7 @@ cLuaChunkStay::cLuaChunkStay(cPluginLua & a_Plugin) : m_Plugin(a_Plugin), - m_LuaState(NULL) + m_LuaState(nullptr) { } diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index 142242162..3b4ce3376 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -46,7 +46,7 @@ const cLuaState::cRet cLuaState::Return = {}; // cLuaState: cLuaState::cLuaState(const AString & a_SubsystemName) : - m_LuaState(NULL), + m_LuaState(nullptr), m_IsOwned(false), m_SubsystemName(a_SubsystemName), m_NumCurrentFunctionArgs(-1) @@ -90,7 +90,7 @@ cLuaState::~cLuaState() void cLuaState::Create(void) { - if (m_LuaState != NULL) + if (m_LuaState != nullptr) { LOGWARNING("%s: Trying to create an already-existing LuaState, ignoring.", __FUNCTION__); return; @@ -119,7 +119,7 @@ void cLuaState::RegisterAPILibs(void) void cLuaState::Close(void) { - if (m_LuaState == NULL) + if (m_LuaState == nullptr) { LOGWARNING("%s: Trying to close an invalid LuaState, ignoring.", __FUNCTION__); return; @@ -134,7 +134,7 @@ void cLuaState::Close(void) return; } lua_close(m_LuaState); - m_LuaState = NULL; + m_LuaState = nullptr; m_IsOwned = false; } @@ -144,7 +144,7 @@ void cLuaState::Close(void) void cLuaState::Attach(lua_State * a_State) { - if (m_LuaState != NULL) + if (m_LuaState != nullptr) { LOGINFO("%s: Already contains a LuaState (0x%p), will be closed / detached.", __FUNCTION__, m_LuaState); if (m_IsOwned) @@ -166,7 +166,7 @@ void cLuaState::Attach(lua_State * a_State) void cLuaState::Detach(void) { - if (m_LuaState == NULL) + if (m_LuaState == nullptr) { return; } @@ -179,7 +179,7 @@ void cLuaState::Detach(void) Close(); return; } - m_LuaState = NULL; + m_LuaState = nullptr; } @@ -828,7 +828,7 @@ void cLuaState::GetStackValue(int a_StackPos, AString & a_Value) { size_t len = 0; const char * data = lua_tolstring(m_LuaState, a_StackPos, &len); - if (data != NULL) + if (data != nullptr) { a_Value.assign(data, len); } @@ -878,7 +878,7 @@ void cLuaState::GetStackValue(int a_StackPos, pBoundingBox & a_ReturnedVal) { if (lua_isnil(m_LuaState, a_StackPos)) { - a_ReturnedVal = NULL; + a_ReturnedVal = nullptr; return; } tolua_Error err; @@ -896,7 +896,7 @@ void cLuaState::GetStackValue(int a_StackPos, pWorld & a_ReturnedVal) { if (lua_isnil(m_LuaState, a_StackPos)) { - a_ReturnedVal = NULL; + a_ReturnedVal = nullptr; return; } tolua_Error err; @@ -961,7 +961,7 @@ bool cLuaState::CheckParamUserTable(int a_StartParam, const char * a_UserTable, lua_Debug entry; VERIFY(lua_getstack(m_LuaState, 0, &entry)); VERIFY(lua_getinfo (m_LuaState, "n", &entry)); - AString ErrMsg = Printf("#ferror in function '%s'.", (entry.name != NULL) ? entry.name : "?"); + AString ErrMsg = Printf("#ferror in function '%s'.", (entry.name != nullptr) ? entry.name : "?"); tolua_error(m_LuaState, ErrMsg.c_str(), &tolua_err); return false; } // for i - Param @@ -994,7 +994,7 @@ bool cLuaState::CheckParamUserType(int a_StartParam, const char * a_UserType, in lua_Debug entry; VERIFY(lua_getstack(m_LuaState, 0, &entry)); VERIFY(lua_getinfo (m_LuaState, "n", &entry)); - AString ErrMsg = Printf("#ferror in function '%s'.", (entry.name != NULL) ? entry.name : "?"); + AString ErrMsg = Printf("#ferror in function '%s'.", (entry.name != nullptr) ? entry.name : "?"); tolua_error(m_LuaState, ErrMsg.c_str(), &tolua_err); return false; } // for i - Param @@ -1027,7 +1027,7 @@ bool cLuaState::CheckParamTable(int a_StartParam, int a_EndParam) lua_Debug entry; VERIFY(lua_getstack(m_LuaState, 0, &entry)); VERIFY(lua_getinfo (m_LuaState, "n", &entry)); - AString ErrMsg = Printf("#ferror in function '%s'.", (entry.name != NULL) ? entry.name : "?"); + AString ErrMsg = Printf("#ferror in function '%s'.", (entry.name != nullptr) ? entry.name : "?"); tolua_error(m_LuaState, ErrMsg.c_str(), &tolua_err); return false; } // for i - Param @@ -1060,7 +1060,7 @@ bool cLuaState::CheckParamNumber(int a_StartParam, int a_EndParam) lua_Debug entry; VERIFY(lua_getstack(m_LuaState, 0, &entry)); VERIFY(lua_getinfo (m_LuaState, "n", &entry)); - AString ErrMsg = Printf("#ferror in function '%s'.", (entry.name != NULL) ? entry.name : "?"); + AString ErrMsg = Printf("#ferror in function '%s'.", (entry.name != nullptr) ? entry.name : "?"); tolua_error(m_LuaState, ErrMsg.c_str(), &tolua_err); return false; } // for i - Param @@ -1093,7 +1093,7 @@ bool cLuaState::CheckParamString(int a_StartParam, int a_EndParam) lua_Debug entry; VERIFY(lua_getstack(m_LuaState, 0, &entry)); VERIFY(lua_getinfo (m_LuaState, "n", &entry)); - AString ErrMsg = Printf("#ferror in function '%s'.", (entry.name != NULL) ? entry.name : "?"); + AString ErrMsg = Printf("#ferror in function '%s'.", (entry.name != nullptr) ? entry.name : "?"); tolua_error(m_LuaState, ErrMsg.c_str(), &tolua_err); return false; } // for i - Param @@ -1126,7 +1126,7 @@ bool cLuaState::CheckParamFunction(int a_StartParam, int a_EndParam) VERIFY(lua_getstack(m_LuaState, 0, &entry)); VERIFY(lua_getinfo (m_LuaState, "n", &entry)); luaL_error(m_LuaState, "Error in function '%s' parameter #%d. Function expected, got %s", - (entry.name != NULL) ? entry.name : "?", i, GetTypeText(i).c_str() + (entry.name != nullptr) ? entry.name : "?", i, GetTypeText(i).c_str() ); return false; } // for i - Param @@ -1159,7 +1159,7 @@ bool cLuaState::CheckParamFunctionOrNil(int a_StartParam, int a_EndParam) VERIFY(lua_getstack(m_LuaState, 0, &entry)); VERIFY(lua_getinfo (m_LuaState, "n", &entry)); luaL_error(m_LuaState, "Error in function '%s' parameter #%d. Function expected, got %s", - (entry.name != NULL) ? entry.name : "?", i, GetTypeText(i).c_str() + (entry.name != nullptr) ? entry.name : "?", i, GetTypeText(i).c_str() ); return false; } // for i - Param @@ -1183,7 +1183,7 @@ bool cLuaState::CheckParamEnd(int a_Param) lua_Debug entry; VERIFY(lua_getstack(m_LuaState, 0, &entry)); VERIFY(lua_getinfo (m_LuaState, "n", &entry)); - AString ErrMsg = Printf("#ferror in function '%s': Too many arguments.", (entry.name != NULL) ? entry.name : "?"); + AString ErrMsg = Printf("#ferror in function '%s': Too many arguments.", (entry.name != nullptr) ? entry.name : "?"); tolua_error(m_LuaState, ErrMsg.c_str(), &tolua_err); return false; } @@ -1362,7 +1362,7 @@ int cLuaState::CopyStackFrom(cLuaState & a_SrcLuaState, int a_SrcStart, int a_Sr case LUA_TUSERDATA: { // Get the class name: - const char * type = NULL; + const char * type = nullptr; if (lua_getmetatable(a_SrcLuaState, i) == 0) { LOGWARNING("%s: Unknown class in pos %d, cannot copy.", __FUNCTION__, i); @@ -1374,7 +1374,7 @@ int cLuaState::CopyStackFrom(cLuaState & a_SrcLuaState, int a_SrcStart, int a_Sr lua_pop(a_SrcLuaState, 1); // Stack -1 // Copy the value: - void * ud = tolua_touserdata(a_SrcLuaState, i, NULL); + void * ud = tolua_touserdata(a_SrcLuaState, i, nullptr); tolua_pushusertype(m_LuaState, ud, type); break; } @@ -1400,7 +1400,7 @@ void cLuaState::ToString(int a_StackPos, AString & a_String) { size_t len; const char * s = lua_tolstring(m_LuaState, a_StackPos, &len); - if (s != NULL) + if (s != nullptr) { a_String.assign(s, len); } @@ -1422,7 +1422,7 @@ void cLuaState::LogStack(const char * a_Header) void cLuaState::LogStack(lua_State * a_LuaState, const char * a_Header) { // Format string consisting only of %s is used to appease the compiler - LOG("%s", (a_Header != NULL) ? a_Header : "Lua C API Stack contents:"); + LOG("%s", (a_Header != nullptr) ? a_Header : "Lua C API Stack contents:"); for (int i = lua_gettop(a_LuaState); i > 0; i--) { AString Value; @@ -1459,7 +1459,7 @@ int cLuaState::ReportFnCallErrors(lua_State * a_LuaState) // cLuaState::cRef: cLuaState::cRef::cRef(void) : - m_LuaState(NULL), + m_LuaState(nullptr), m_Ref(LUA_REFNIL) { } @@ -1469,7 +1469,7 @@ cLuaState::cRef::cRef(void) : cLuaState::cRef::cRef(cLuaState & a_LuaState, int a_StackPos) : - m_LuaState(NULL), + m_LuaState(nullptr), m_Ref(LUA_REFNIL) { RefStack(a_LuaState, a_StackPos); @@ -1481,7 +1481,7 @@ cLuaState::cRef::cRef(cLuaState & a_LuaState, int a_StackPos) : cLuaState::cRef::~cRef() { - if (m_LuaState != NULL) + if (m_LuaState != nullptr) { UnRef(); } @@ -1494,7 +1494,7 @@ cLuaState::cRef::~cRef() void cLuaState::cRef::RefStack(cLuaState & a_LuaState, int a_StackPos) { ASSERT(a_LuaState.IsValid()); - if (m_LuaState != NULL) + if (m_LuaState != nullptr) { UnRef(); } @@ -1515,7 +1515,7 @@ void cLuaState::cRef::UnRef(void) { luaL_unref(*m_LuaState, LUA_REGISTRYINDEX, m_Ref); } - m_LuaState = NULL; + m_LuaState = nullptr; m_Ref = LUA_REFNIL; } diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h index 899228a66..d1e9923b4 100644 --- a/src/Bindings/LuaState.h +++ b/src/Bindings/LuaState.h @@ -164,7 +164,7 @@ public: void Detach(void); /** Returns true if the m_LuaState is valid */ - bool IsValid(void) const { return (m_LuaState != NULL); } + bool IsValid(void) const { return (m_LuaState != nullptr); } /** Adds the specified path to package. */ void AddPackagePath(const AString & a_PathVariable, const AString & a_Path); @@ -318,10 +318,10 @@ public: void ToString(int a_StackPos, AString & a_String); /** Logs all the elements' types on the API stack, with an optional header for the listing. */ - void LogStack(const char * a_Header = NULL); + void LogStack(const char * a_Header = nullptr); /** Logs all the elements' types on the API stack, with an optional header for the listing. */ - static void LogStack(lua_State * a_LuaState, const char * a_Header = NULL); + static void LogStack(lua_State * a_LuaState, const char * a_Header = nullptr); protected: diff --git a/src/Bindings/LuaWindow.cpp b/src/Bindings/LuaWindow.cpp index c4d03b86b..35730878d 100644 --- a/src/Bindings/LuaWindow.cpp +++ b/src/Bindings/LuaWindow.cpp @@ -18,7 +18,7 @@ cLuaWindow::cLuaWindow(cWindow::WindowType a_WindowType, int a_SlotsX, int a_SlotsY, const AString & a_Title) : super(a_WindowType, a_Title), m_Contents(a_SlotsX, a_SlotsY), - m_Plugin(NULL), + m_Plugin(nullptr), m_LuaRef(LUA_REFNIL), m_OnClosingFnRef(LUA_REFNIL), m_OnSlotChangedFnRef(LUA_REFNIL) @@ -70,7 +70,7 @@ cLuaWindow::~cLuaWindow() void cLuaWindow::SetLuaRef(cPluginLua * a_Plugin, int a_LuaRef) { // Either m_Plugin is not set or equal to the passed plugin; only one plugin can use one cLuaWindow object - ASSERT((m_Plugin == NULL) || (m_Plugin == a_Plugin)); + ASSERT((m_Plugin == nullptr) || (m_Plugin == a_Plugin)); ASSERT(m_LuaRef == LUA_REFNIL); m_Plugin = a_Plugin; m_LuaRef = a_LuaRef; @@ -82,7 +82,7 @@ void cLuaWindow::SetLuaRef(cPluginLua * a_Plugin, int a_LuaRef) bool cLuaWindow::IsLuaReferenced(void) const { - return ((m_Plugin != NULL) && (m_LuaRef != LUA_REFNIL)); + return ((m_Plugin != nullptr) && (m_LuaRef != LUA_REFNIL)); } @@ -92,7 +92,7 @@ bool cLuaWindow::IsLuaReferenced(void) const void cLuaWindow::SetOnClosing(cPluginLua * a_Plugin, int a_FnRef) { // Either m_Plugin is not set or equal to the passed plugin; only one plugin can use one cLuaWindow object - ASSERT((m_Plugin == NULL) || (m_Plugin == a_Plugin)); + ASSERT((m_Plugin == nullptr) || (m_Plugin == a_Plugin)); // If there already was a function, unreference it first if (m_OnClosingFnRef != LUA_REFNIL) @@ -112,7 +112,7 @@ void cLuaWindow::SetOnClosing(cPluginLua * a_Plugin, int a_FnRef) void cLuaWindow::SetOnSlotChanged(cPluginLua * a_Plugin, int a_FnRef) { // Either m_Plugin is not set or equal to the passed plugin; only one plugin can use one cLuaWindow object - ASSERT((m_Plugin == NULL) || (m_Plugin == a_Plugin)); + ASSERT((m_Plugin == nullptr) || (m_Plugin == a_Plugin)); // If there already was a function, unreference it first if (m_OnSlotChangedFnRef != LUA_REFNIL) @@ -134,7 +134,7 @@ bool cLuaWindow::ClosedByPlayer(cPlayer & a_Player, bool a_CanRefuse) // First notify the plugin through the registered callback: if (m_OnClosingFnRef != LUA_REFNIL) { - ASSERT(m_Plugin != NULL); + ASSERT(m_Plugin != nullptr); if (m_Plugin->CallbackWindowClosing(m_OnClosingFnRef, *this, a_Player, a_CanRefuse)) { // The callback disagrees (the higher levels check the CanRefuse flag compliance) @@ -153,7 +153,7 @@ void cLuaWindow::Destroy(void) { super::Destroy(); - if ((m_LuaRef != LUA_REFNIL) && (m_Plugin != NULL)) + if ((m_LuaRef != LUA_REFNIL) && (m_Plugin != nullptr)) { // The object is referenced by Lua, un-reference it m_Plugin->Unreference(m_LuaRef); diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 0558533ce..a4a5d79b4 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -145,13 +145,13 @@ static AString GetLogMessage(lua_State * tolua_S) tolua_Error err; if (tolua_isusertype(tolua_S, 1, "cCompositeChat", false, &err)) { - return ((cCompositeChat *)tolua_tousertype(tolua_S, 1, NULL))->ExtractText(); + return ((cCompositeChat *)tolua_tousertype(tolua_S, 1, nullptr))->ExtractText(); } else { size_t len = 0; const char * str = lua_tolstring(tolua_S, 1, &len); - if (str != NULL) + if (str != nullptr) { return AString(str, len); } @@ -170,7 +170,7 @@ static int tolua_LOG(lua_State * tolua_S) tolua_Error err; if (tolua_isusertype(tolua_S, 1, "cCompositeChat", false, &err)) { - LogLevel = cCompositeChat::MessageTypeToLogLevel(((cCompositeChat *)tolua_tousertype(tolua_S, 1, NULL))->GetMessageType()); + LogLevel = cCompositeChat::MessageTypeToLogLevel(((cCompositeChat *)tolua_tousertype(tolua_S, 1, nullptr))->GetMessageType()); } // Log the message: @@ -264,7 +264,7 @@ static cPluginLua * GetLuaPlugin(lua_State * L) { LOGWARNING("%s: cannot get plugin instance, what have you done to my Lua state?", __FUNCTION__); lua_pop(L, 1); - return NULL; + return nullptr; } cPluginLua * Plugin = (cPluginLua *)lua_topointer(L, -1); lua_pop(L, 1); @@ -312,10 +312,10 @@ static int tolua_DoWith(lua_State* tolua_S) return lua_do_error(tolua_S, "Error in function call '#funcname#': Requires 2 or 3 arguments, got %i", NumArgs); } - Ty1 * self = (Ty1 *) tolua_tousertype(tolua_S, 1, NULL); + Ty1 * self = (Ty1 *) tolua_tousertype(tolua_S, 1, nullptr); const char * ItemName = tolua_tocppstring(tolua_S, 2, ""); - if ((ItemName == NULL) || (ItemName[0] == 0)) + if ((ItemName == nullptr) || (ItemName[0] == 0)) { return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a non-empty string for parameter #1", NumArgs); } @@ -406,7 +406,7 @@ static int tolua_DoWithID(lua_State* tolua_S) return lua_do_error(tolua_S, "Error in function call '#funcname#': Requires 2 or 3 arguments, got %i", NumArgs); } - Ty1 * self = (Ty1 *)tolua_tousertype(tolua_S, 1, NULL); + Ty1 * self = (Ty1 *)tolua_tousertype(tolua_S, 1, nullptr); int ItemID = (int)tolua_tonumber(tolua_S, 2, 0); if (!lua_isfunction(tolua_S, 3)) @@ -496,7 +496,7 @@ static int tolua_DoWithXYZ(lua_State* tolua_S) return lua_do_error(tolua_S, "Error in function call '#funcname#': Requires 4 or 5 arguments, got %i", NumArgs); } - Ty1 * self = (Ty1 *) tolua_tousertype(tolua_S, 1, NULL); + Ty1 * self = (Ty1 *) tolua_tousertype(tolua_S, 1, nullptr); if (!lua_isnumber(tolua_S, 2) || !lua_isnumber(tolua_S, 3) || !lua_isnumber(tolua_S, 4)) { return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a number for parameters #1, #2 and #3"); @@ -591,7 +591,7 @@ static int tolua_ForEachInChunk(lua_State * tolua_S) return lua_do_error(tolua_S, "Error in function call '#funcname#': Requires 3 or 4 arguments, got %i", NumArgs); } - Ty1 * self = (Ty1 *) tolua_tousertype(tolua_S, 1, NULL); + Ty1 * self = (Ty1 *) tolua_tousertype(tolua_S, 1, nullptr); if (!lua_isnumber(tolua_S, 2) || !lua_isnumber(tolua_S, 3)) { return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a number for parameters #1 and #2"); @@ -694,10 +694,10 @@ static int tolua_ForEachInBox(lua_State * tolua_S) } // Get the params: - Ty1 * Self = NULL; - cBoundingBox * Box = NULL; + Ty1 * Self = nullptr; + cBoundingBox * Box = nullptr; L.GetStackValues(1, Self, Box); - if ((Self == NULL) || (Box == NULL)) + if ((Self == nullptr) || (Box == nullptr)) { LOGWARNING("Invalid world (%p) or boundingbox (%p)", Self, Box); L.LogStackTrace(); @@ -760,8 +760,8 @@ static int tolua_ForEach(lua_State * tolua_S) return lua_do_error(tolua_S, "Error in function call '#funcname#': Requires 1 or 2 arguments, got %i", NumArgs); } - Ty1 * self = (Ty1 *)tolua_tousertype(tolua_S, 1, NULL); - if (self == NULL) + Ty1 * self = (Ty1 *)tolua_tousertype(tolua_S, 1, nullptr); + if (self == nullptr) { return lua_do_error(tolua_S, "Error in function call '#funcname#': Not called on an object instance"); } @@ -857,14 +857,14 @@ static int tolua_cWorld_GetBlockInfo(lua_State * tolua_S) else #endif { - cWorld * self = (cWorld *) tolua_tousertype (tolua_S, 1, NULL); + cWorld * self = (cWorld *) tolua_tousertype (tolua_S, 1, nullptr); int BlockX = (int) tolua_tonumber (tolua_S, 2, 0); int BlockY = (int) tolua_tonumber (tolua_S, 3, 0); int BlockZ = (int) tolua_tonumber (tolua_S, 4, 0); #ifndef TOLUA_RELEASE - if (self == NULL) + if (self == nullptr) { - tolua_error(tolua_S, "invalid 'self' in function 'GetBlockInfo'", NULL); + tolua_error(tolua_S, "invalid 'self' in function 'GetBlockInfo'", nullptr); } #endif { @@ -912,14 +912,14 @@ static int tolua_cWorld_GetBlockTypeMeta(lua_State * tolua_S) else #endif { - cWorld * self = (cWorld *) tolua_tousertype (tolua_S, 1, NULL); + cWorld * self = (cWorld *) tolua_tousertype (tolua_S, 1, nullptr); int BlockX = (int) tolua_tonumber (tolua_S, 2, 0); int BlockY = (int) tolua_tonumber (tolua_S, 3, 0); int BlockZ = (int) tolua_tonumber (tolua_S, 4, 0); #ifndef TOLUA_RELEASE - if (self == NULL) + if (self == nullptr) { - tolua_error(tolua_S, "invalid 'self' in function 'GetBlockTypeMeta'", NULL); + tolua_error(tolua_S, "invalid 'self' in function 'GetBlockTypeMeta'", nullptr); } #endif { @@ -964,14 +964,14 @@ static int tolua_cWorld_GetSignLines(lua_State * tolua_S) else #endif { - cWorld * self = (cWorld *) tolua_tousertype (tolua_S, 1, NULL); + cWorld * self = (cWorld *) tolua_tousertype (tolua_S, 1, nullptr); int BlockX = (int) tolua_tonumber (tolua_S, 2, 0); int BlockY = (int) tolua_tonumber (tolua_S, 3, 0); int BlockZ = (int) tolua_tonumber (tolua_S, 4, 0); #ifndef TOLUA_RELEASE - if (self == NULL) + if (self == nullptr) { - tolua_error(tolua_S, "invalid 'self' in function 'GetSignLines'", NULL); + tolua_error(tolua_S, "invalid 'self' in function 'GetSignLines'", nullptr); } #endif { @@ -1022,7 +1022,7 @@ static int tolua_cWorld_SetSignLines(lua_State * tolua_S) else #endif { - cWorld * self = (cWorld *) tolua_tousertype (tolua_S, 1, NULL); + cWorld * self = (cWorld *) tolua_tousertype (tolua_S, 1, nullptr); int BlockX = (int) tolua_tonumber (tolua_S, 2, 0); int BlockY = (int) tolua_tonumber (tolua_S, 3, 0); int BlockZ = (int) tolua_tonumber (tolua_S, 4, 0); @@ -1030,11 +1030,11 @@ static int tolua_cWorld_SetSignLines(lua_State * tolua_S) const AString Line2 = tolua_tocppstring(tolua_S, 6, 0); const AString Line3 = tolua_tocppstring(tolua_S, 7, 0); const AString Line4 = tolua_tocppstring(tolua_S, 8, 0); - cPlayer * Player = (cPlayer *)tolua_tousertype (tolua_S, 9, NULL); + cPlayer * Player = (cPlayer *)tolua_tousertype (tolua_S, 9, nullptr); #ifndef TOLUA_RELEASE - if (self == NULL) + if (self == nullptr) { - tolua_error(tolua_S, "invalid 'self' in function 'SetSignLines' / 'UpdateSign'", NULL); + tolua_error(tolua_S, "invalid 'self' in function 'SetSignLines' / 'UpdateSign'", nullptr); } #endif { @@ -1071,13 +1071,13 @@ static int tolua_cWorld_TryGetHeight(lua_State * tolua_S) else #endif { - cWorld * self = (cWorld *) tolua_tousertype (tolua_S, 1, NULL); + cWorld * self = (cWorld *) tolua_tousertype (tolua_S, 1, nullptr); int BlockX = (int) tolua_tonumber (tolua_S, 2, 0); int BlockZ = (int) tolua_tonumber (tolua_S, 3, 0); #ifndef TOLUA_RELEASE - if (self == NULL) + if (self == nullptr) { - tolua_error(tolua_S, "Invalid 'self' in function 'TryGetHeight'", NULL); + tolua_error(tolua_S, "Invalid 'self' in function 'TryGetHeight'", nullptr); } #endif { @@ -1136,15 +1136,15 @@ static int tolua_cWorld_QueueTask(lua_State * tolua_S) // Retrieve the cPlugin from the LuaState: cPluginLua * Plugin = GetLuaPlugin(tolua_S); - if (Plugin == NULL) + if (Plugin == nullptr) { // An error message has been already printed in GetLuaPlugin() return 0; } // Retrieve the args: - cWorld * self = (cWorld *)tolua_tousertype(tolua_S, 1, NULL); - if (self == NULL) + cWorld * self = (cWorld *)tolua_tousertype(tolua_S, 1, nullptr); + if (self == nullptr) { return lua_do_error(tolua_S, "Error in function call '#funcname#': Not called on an object instance"); } @@ -1200,7 +1200,7 @@ static int tolua_cWorld_ScheduleTask(lua_State * tolua_S) // Retrieve the cPlugin from the LuaState: cPluginLua * Plugin = GetLuaPlugin(tolua_S); - if (Plugin == NULL) + if (Plugin == nullptr) { // An error message has been already printed in GetLuaPlugin() return 0; @@ -1216,8 +1216,8 @@ static int tolua_cWorld_ScheduleTask(lua_State * tolua_S) { return 0; } - cWorld * World = (cWorld *)tolua_tousertype(tolua_S, 1, NULL); - if (World == NULL) + cWorld * World = (cWorld *)tolua_tousertype(tolua_S, 1, nullptr); + if (World == nullptr) { return lua_do_error(tolua_S, "Error in function call '#funcname#': Not called on an object instance"); } @@ -1241,7 +1241,7 @@ static int tolua_cWorld_ScheduleTask(lua_State * tolua_S) static int tolua_cPluginManager_GetAllPlugins(lua_State * tolua_S) { - cPluginManager * self = (cPluginManager *)tolua_tousertype(tolua_S, 1, NULL); + cPluginManager * self = (cPluginManager *)tolua_tousertype(tolua_S, 1, nullptr); const cPluginManager::PluginMap & AllPlugins = self->GetAllPlugins(); @@ -1252,7 +1252,7 @@ static int tolua_cPluginManager_GetAllPlugins(lua_State * tolua_S) { const cPlugin* Plugin = iter->second; tolua_pushstring(tolua_S, iter->first.c_str()); - if (Plugin != NULL) + if (Plugin != nullptr) { tolua_pushusertype(tolua_S, (void *)Plugin, "const cPlugin"); } @@ -1274,7 +1274,7 @@ static int tolua_cPluginManager_GetAllPlugins(lua_State * tolua_S) static int tolua_cPluginManager_GetCurrentPlugin(lua_State * S) { cPluginLua * Plugin = GetLuaPlugin(S); - if (Plugin == NULL) + if (Plugin == nullptr) { // An error message has already been printed in GetLuaPlugin() return 0; @@ -1305,7 +1305,7 @@ static int tolua_cPluginManager_AddHook_FnRef(cPluginManager * a_PluginManager, // Retrieve the cPlugin from the LuaState: cPluginLua * Plugin = GetLuaPlugin(S); - if (Plugin == NULL) + if (Plugin == nullptr) { // An error message has been already printed in GetLuaPlugin() return 0; @@ -1344,8 +1344,8 @@ static int tolua_cPluginManager_AddHook_DefFn(cPluginManager * a_PluginManager, // The arg types have already been checked // Retrieve and check the cPlugin parameter - cPluginLua * Plugin = (cPluginLua *)tolua_tousertype(S, a_ParamIdx, NULL); - if (Plugin == NULL) + cPluginLua * Plugin = (cPluginLua *)tolua_tousertype(S, a_ParamIdx, nullptr); + if (Plugin == nullptr) { LOGWARNING("cPluginManager.AddHook(): Invalid Plugin parameter, expected a valid cPlugin object. Hook not added"); S.LogStackTrace(); @@ -1370,7 +1370,7 @@ static int tolua_cPluginManager_AddHook_DefFn(cPluginManager * a_PluginManager, // Get the standard name for the callback function: const char * FnName = cPluginLua::GetHookFnName(HookType); - if (FnName == NULL) + if (FnName == nullptr) { LOGWARNING("cPluginManager.AddHook(): Unknown hook type (%d). Hook not added.", HookType); S.LogStackTrace(); @@ -1417,8 +1417,8 @@ static int tolua_cPluginManager_AddHook(lua_State * tolua_S) if (tolua_isusertype(S, 1, "cPluginManager", 0, &err)) { // Style 2 or 3, retrieve the PlgMgr instance - PlgMgr = (cPluginManager *)tolua_tousertype(S, 1, NULL); - if (PlgMgr == NULL) + PlgMgr = (cPluginManager *)tolua_tousertype(S, 1, nullptr); + if (PlgMgr == nullptr) { LOGWARNING("Malformed plugin, use cPluginManager.AddHook(HOOK_TYPE, CallbackFunction). Fixing the call for you."); S.LogStackTrace(); @@ -1465,8 +1465,8 @@ static int tolua_cPluginManager_ForEachCommand(lua_State * tolua_S) return 0; } - cPluginManager * self = (cPluginManager *)tolua_tousertype(tolua_S, 1, NULL); - if (self == NULL) + cPluginManager * self = (cPluginManager *)tolua_tousertype(tolua_S, 1, nullptr); + if (self == nullptr) { LOGWARN("Error in function call 'ForEachCommand': Not called on an object instance"); return 0; @@ -1542,8 +1542,8 @@ static int tolua_cPluginManager_ForEachConsoleCommand(lua_State * tolua_S) return 0; } - cPluginManager * self = (cPluginManager *)tolua_tousertype(tolua_S, 1, NULL); - if (self == NULL) + cPluginManager * self = (cPluginManager *)tolua_tousertype(tolua_S, 1, nullptr); + if (self == nullptr) { LOGWARN("Error in function call 'ForEachConsoleCommand': Not called on an object instance"); return 0; @@ -1617,7 +1617,7 @@ static int tolua_cPluginManager_BindCommand(lua_State * L) cPluginManager.BindCommand(Command, Permission, Function, HelpString) -- without the "self" param */ cPluginLua * Plugin = GetLuaPlugin(L); - if (Plugin == NULL) + if (Plugin == nullptr) { return 0; } @@ -1687,7 +1687,7 @@ static int tolua_cPluginManager_BindConsoleCommand(lua_State * L) // Get the plugin identification out of LuaState: cPluginLua * Plugin = GetLuaPlugin(L); - if (Plugin == NULL) + if (Plugin == nullptr) { return 0; } @@ -1775,7 +1775,7 @@ static int tolua_cPluginManager_CallPlugin(lua_State * tolua_S) // If requesting calling the current plugin, refuse: cPluginLua * ThisPlugin = GetLuaPlugin(L); - if (ThisPlugin == NULL) + if (ThisPlugin == nullptr) { return 0; } @@ -1843,14 +1843,14 @@ static int tolua_cWorld_ChunkStay(lua_State * tolua_S) } cPluginLua * Plugin = GetLuaPlugin(tolua_S); - if (Plugin == NULL) + if (Plugin == nullptr) { return 0; } // Read the params: - cWorld * World = (cWorld *)tolua_tousertype(tolua_S, 1, NULL); - if (World == NULL) + cWorld * World = (cWorld *)tolua_tousertype(tolua_S, 1, nullptr); + if (World == nullptr) { LOGWARNING("World:ChunkStay(): invalid world parameter"); L.LogStackTrace(); @@ -1862,7 +1862,7 @@ static int tolua_cWorld_ChunkStay(lua_State * tolua_S) if (!ChunkStay->AddChunks(2)) { delete ChunkStay; - ChunkStay = NULL; + ChunkStay = nullptr; return 0; } @@ -1889,8 +1889,8 @@ static int tolua_cPlayer_GetPermissions(lua_State * tolua_S) } // Get the params: - cPlayer * self = (cPlayer *)tolua_tousertype(tolua_S, 1, NULL); - if (self == NULL) + cPlayer * self = (cPlayer *)tolua_tousertype(tolua_S, 1, nullptr); + if (self == nullptr) { LOGWARNING("%s: invalid self (%p)", __FUNCTION__, self); return 0; @@ -1911,15 +1911,15 @@ static int tolua_cPlayer_OpenWindow(lua_State * tolua_S) // Retrieve the plugin instance from the Lua state cPluginLua * Plugin = GetLuaPlugin(tolua_S); - if (Plugin == NULL) + if (Plugin == nullptr) { return 0; } // Get the parameters: - cPlayer * self = (cPlayer *)tolua_tousertype(tolua_S, 1, NULL); - cWindow * wnd = (cWindow *)tolua_tousertype(tolua_S, 2, NULL); - if ((self == NULL) || (wnd == NULL)) + cPlayer * self = (cPlayer *)tolua_tousertype(tolua_S, 1, nullptr); + cWindow * wnd = (cWindow *)tolua_tousertype(tolua_S, 2, nullptr); + if ((self == nullptr) || (wnd == nullptr)) { LOGWARNING("%s: invalid self (%p) or wnd (%p)", __FUNCTION__, self, wnd); return 0; @@ -1992,15 +1992,15 @@ static int tolua_SetObjectCallback(lua_State * tolua_S) // Retrieve the plugin instance from the Lua state cPluginLua * Plugin = GetLuaPlugin(tolua_S); - if (Plugin == NULL) + if (Plugin == nullptr) { // Warning message has already been printed by GetLuaPlugin(), bail out silently return 0; } // Get the parameters - self and the function reference: - OBJTYPE * self = (OBJTYPE *)tolua_tousertype(tolua_S, 1, NULL); - if (self == NULL) + OBJTYPE * self = (OBJTYPE *)tolua_tousertype(tolua_S, 1, nullptr); + if (self == nullptr) { LOGWARNING("%s: invalid self (%p)", __FUNCTION__, self); return 0; @@ -2023,7 +2023,7 @@ static int tolua_SetObjectCallback(lua_State * tolua_S) static int tolua_cPluginLua_AddWebTab(lua_State * tolua_S) { - cPluginLua * self = (cPluginLua *)tolua_tousertype(tolua_S, 1, NULL); + cPluginLua * self = (cPluginLua *)tolua_tousertype(tolua_S, 1, nullptr); tolua_Error tolua_err; tolua_err.array = 0; @@ -2067,7 +2067,7 @@ static int tolua_cPluginLua_AddWebTab(lua_State * tolua_S) static int tolua_cPluginLua_AddTab(lua_State* tolua_S) { - cPluginLua * self = (cPluginLua *) tolua_tousertype(tolua_S, 1, NULL); + cPluginLua * self = (cPluginLua *) tolua_tousertype(tolua_S, 1, nullptr); LOGWARN("WARNING: Using deprecated function AddTab()! Use AddWebTab() instead. (plugin \"%s\" in folder \"%s\")", self->GetName().c_str(), self->GetDirectory().c_str() ); @@ -2087,7 +2087,7 @@ static int tolua_cPlugin_Call(lua_State * tolua_S) L.LogStackTrace(); // Retrieve the params: plugin and the function name to call - cPluginLua * TargetPlugin = (cPluginLua *) tolua_tousertype(tolua_S, 1, NULL); + cPluginLua * TargetPlugin = (cPluginLua *) tolua_tousertype(tolua_S, 1, nullptr); AString FunctionName = tolua_tostring(tolua_S, 2, ""); // Call the function: @@ -2142,7 +2142,7 @@ static int tolua_push_StringStringMap(lua_State* tolua_S, std::map< std::string, static int tolua_get_HTTPRequest_Params(lua_State* tolua_S) { - HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S, 1, NULL); + HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S, 1, nullptr); return tolua_push_StringStringMap(tolua_S, self->Params); } @@ -2152,7 +2152,7 @@ static int tolua_get_HTTPRequest_Params(lua_State* tolua_S) static int tolua_get_HTTPRequest_PostParams(lua_State* tolua_S) { - HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S, 1, NULL); + HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S, 1, nullptr); return tolua_push_StringStringMap(tolua_S, self->PostParams); } @@ -2162,7 +2162,7 @@ static int tolua_get_HTTPRequest_PostParams(lua_State* tolua_S) static int tolua_get_HTTPRequest_FormData(lua_State* tolua_S) { - HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S, 1, NULL); + HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S, 1, nullptr); std::map< std::string, HTTPFormData >& FormData = self->FormData; lua_newtable(tolua_S); @@ -2185,7 +2185,7 @@ static int tolua_get_HTTPRequest_FormData(lua_State* tolua_S) static int tolua_cWebAdmin_GetPlugins(lua_State * tolua_S) { - cWebAdmin * self = (cWebAdmin *)tolua_tousertype(tolua_S, 1, NULL); + cWebAdmin * self = (cWebAdmin *)tolua_tousertype(tolua_S, 1, nullptr); const cWebAdmin::PluginList & AllPlugins = self->GetPlugins(); @@ -2266,7 +2266,7 @@ static int tolua_AllToLua_cWebAdmin_GetURLEncodedString(lua_State * tolua_S) static int tolua_cWebPlugin_GetTabNames(lua_State * tolua_S) { - cWebPlugin* self = (cWebPlugin*) tolua_tousertype(tolua_S, 1, NULL); + cWebPlugin* self = (cWebPlugin*) tolua_tousertype(tolua_S, 1, nullptr); const cWebPlugin::TabNameList & TabNames = self->GetTabNames(); @@ -2302,8 +2302,8 @@ static int tolua_cClientHandle_SendPluginMessage(lua_State * L) { return 0; } - cClientHandle * Client = (cClientHandle *)tolua_tousertype(L, 1, NULL); - if (Client == NULL) + cClientHandle * Client = (cClientHandle *)tolua_tousertype(L, 1, nullptr); + if (Client == nullptr) { LOGWARNING("ClientHandle is nil in cClientHandle:SendPluginMessage()"); S.LogStackTrace(); @@ -2548,11 +2548,11 @@ static int Lua_ItemGrid_GetSlotCoords(lua_State * L) } { - const cItemGrid * self = (const cItemGrid *)tolua_tousertype(L, 1, NULL); + const cItemGrid * self = (const cItemGrid *)tolua_tousertype(L, 1, nullptr); int SlotNum = (int)tolua_tonumber(L, 2, 0); - if (self == NULL) + if (self == nullptr) { - tolua_error(L, "invalid 'self' in function 'cItemGrid:GetSlotCoords'", NULL); + tolua_error(L, "invalid 'self' in function 'cItemGrid:GetSlotCoords'", nullptr); return 0; } int X, Y; @@ -2689,7 +2689,7 @@ static int tolua_cLineBlockTracer_Trace(lua_State * tolua_S) } // Trace: - cWorld * World = (cWorld *)tolua_tousertype(L, idx, NULL); + cWorld * World = (cWorld *)tolua_tousertype(L, idx, nullptr); cLuaBlockTracerCallbacks Callbacks(L, idx + 1); double StartX = tolua_tonumber(L, idx + 2, 0); double StartY = tolua_tonumber(L, idx + 3, 0); @@ -2719,8 +2719,8 @@ static int tolua_cRoot_GetFurnaceRecipe(lua_State * tolua_S) } // Check the input param: - cItem * Input = (cItem *)tolua_tousertype(L, 2, NULL); - if (Input == NULL) + cItem * Input = (cItem *)tolua_tousertype(L, 2, nullptr); + if (Input == nullptr) { LOGWARNING("cRoot:GetFurnaceRecipe: the Input parameter is nil or missing."); return 0; @@ -2729,7 +2729,7 @@ static int tolua_cRoot_GetFurnaceRecipe(lua_State * tolua_S) // Get the recipe for the input cFurnaceRecipe * FR = cRoot::Get()->GetFurnaceRecipe(); const cFurnaceRecipe::cRecipe * Recipe = FR->GetRecipeFrom(*Input); - if (Recipe == NULL) + if (Recipe == nullptr) { // There is no such furnace recipe for this input, return no value return 0; @@ -2760,10 +2760,10 @@ static int tolua_cHopperEntity_GetOutputBlockPos(lua_State * tolua_S) { return 0; } - cHopperEntity * self = (cHopperEntity *)tolua_tousertype(tolua_S, 1, NULL); - if (self == NULL) + cHopperEntity * self = (cHopperEntity *)tolua_tousertype(tolua_S, 1, nullptr); + if (self == nullptr) { - tolua_error(tolua_S, "invalid 'self' in function 'cHopperEntity::GetOutputBlockPos()'", NULL); + tolua_error(tolua_S, "invalid 'self' in function 'cHopperEntity::GetOutputBlockPos()'", nullptr); return 0; } @@ -2800,10 +2800,10 @@ static int tolua_cBlockArea_GetBlockTypeMeta(lua_State * tolua_S) return 0; } - cBlockArea * self = (cBlockArea *)tolua_tousertype(tolua_S, 1, NULL); - if (self == NULL) + cBlockArea * self = (cBlockArea *)tolua_tousertype(tolua_S, 1, nullptr); + if (self == nullptr) { - tolua_error(tolua_S, "invalid 'self' in function 'cBlockArea:GetRelBlockTypeMeta'", NULL); + tolua_error(tolua_S, "invalid 'self' in function 'cBlockArea:GetRelBlockTypeMeta'", nullptr); return 0; } int BlockX = (int)tolua_tonumber(tolua_S, 2, 0); @@ -2834,10 +2834,10 @@ static int tolua_cBlockArea_GetOrigin(lua_State * tolua_S) return 0; } - cBlockArea * self = (cBlockArea *)tolua_tousertype(tolua_S, 1, NULL); - if (self == NULL) + cBlockArea * self = (cBlockArea *)tolua_tousertype(tolua_S, 1, nullptr); + if (self == nullptr) { - tolua_error(tolua_S, "invalid 'self' in function 'cBlockArea:GetOrigin'", NULL); + tolua_error(tolua_S, "invalid 'self' in function 'cBlockArea:GetOrigin'", nullptr); return 0; } @@ -2866,10 +2866,10 @@ static int tolua_cBlockArea_GetRelBlockTypeMeta(lua_State * tolua_S) return 0; } - cBlockArea * self = (cBlockArea *)tolua_tousertype(tolua_S, 1, NULL); - if (self == NULL) + cBlockArea * self = (cBlockArea *)tolua_tousertype(tolua_S, 1, nullptr); + if (self == nullptr) { - tolua_error(tolua_S, "invalid 'self' in function 'cBlockArea:GetRelBlockTypeMeta'", NULL); + tolua_error(tolua_S, "invalid 'self' in function 'cBlockArea:GetRelBlockTypeMeta'", nullptr); return 0; } int BlockX = (int)tolua_tonumber(tolua_S, 2, 0); @@ -2900,10 +2900,10 @@ static int tolua_cBlockArea_GetSize(lua_State * tolua_S) return 0; } - cBlockArea * self = (cBlockArea *)tolua_tousertype(tolua_S, 1, NULL); - if (self == NULL) + cBlockArea * self = (cBlockArea *)tolua_tousertype(tolua_S, 1, nullptr); + if (self == nullptr) { - tolua_error(tolua_S, "invalid 'self' in function 'cBlockArea:GetSize'", NULL); + tolua_error(tolua_S, "invalid 'self' in function 'cBlockArea:GetSize'", nullptr); return 0; } @@ -2931,10 +2931,10 @@ static int tolua_cBlockArea_GetCoordRange(lua_State * tolua_S) return 0; } - cBlockArea * self = (cBlockArea *)tolua_tousertype(tolua_S, 1, NULL); - if (self == NULL) + cBlockArea * self = (cBlockArea *)tolua_tousertype(tolua_S, 1, nullptr); + if (self == nullptr) { - tolua_error(tolua_S, "invalid 'self' in function 'cBlockArea:GetSize'", NULL); + tolua_error(tolua_S, "invalid 'self' in function 'cBlockArea:GetSize'", nullptr); return 0; } @@ -2962,10 +2962,10 @@ static int tolua_cBlockArea_LoadFromSchematicFile(lua_State * tolua_S) { return 0; } - cBlockArea * self = (cBlockArea *)tolua_tousertype(tolua_S, 1, NULL); - if (self == NULL) + cBlockArea * self = (cBlockArea *)tolua_tousertype(tolua_S, 1, nullptr); + if (self == nullptr) { - tolua_error(tolua_S, "invalid 'self' in function 'cBlockArea::LoadFromSchematicFile'", NULL); + tolua_error(tolua_S, "invalid 'self' in function 'cBlockArea::LoadFromSchematicFile'", nullptr); return 0; } @@ -2992,10 +2992,10 @@ static int tolua_cBlockArea_LoadFromSchematicString(lua_State * tolua_S) { return 0; } - cBlockArea * self = (cBlockArea *)tolua_tousertype(tolua_S, 1, NULL); - if (self == NULL) + cBlockArea * self = (cBlockArea *)tolua_tousertype(tolua_S, 1, nullptr); + if (self == nullptr) { - tolua_error(tolua_S, "invalid 'self' in function 'cBlockArea::LoadFromSchematicFile'", NULL); + tolua_error(tolua_S, "invalid 'self' in function 'cBlockArea::LoadFromSchematicFile'", nullptr); return 0; } @@ -3023,10 +3023,10 @@ static int tolua_cBlockArea_SaveToSchematicFile(lua_State * tolua_S) { return 0; } - cBlockArea * self = (cBlockArea *)tolua_tousertype(tolua_S, 1, NULL); - if (self == NULL) + cBlockArea * self = (cBlockArea *)tolua_tousertype(tolua_S, 1, nullptr); + if (self == nullptr) { - tolua_error(tolua_S, "invalid 'self' in function 'cBlockArea::SaveToSchematicFile'", NULL); + tolua_error(tolua_S, "invalid 'self' in function 'cBlockArea::SaveToSchematicFile'", nullptr); return 0; } AString Filename = tolua_tostring(tolua_S, 2, 0); @@ -3051,10 +3051,10 @@ static int tolua_cBlockArea_SaveToSchematicString(lua_State * tolua_S) { return 0; } - cBlockArea * self = (cBlockArea *)tolua_tousertype(tolua_S, 1, NULL); - if (self == NULL) + cBlockArea * self = (cBlockArea *)tolua_tousertype(tolua_S, 1, nullptr); + if (self == nullptr) { - tolua_error(tolua_S, "invalid 'self' in function 'cBlockArea::SaveToSchematicFile'", NULL); + tolua_error(tolua_S, "invalid 'self' in function 'cBlockArea::SaveToSchematicFile'", nullptr); return 0; } @@ -3085,10 +3085,10 @@ static int tolua_cCompositeChat_AddRunCommandPart(lua_State * tolua_S) { return 0; } - cCompositeChat * self = (cCompositeChat *)tolua_tousertype(tolua_S, 1, NULL); - if (self == NULL) + cCompositeChat * self = (cCompositeChat *)tolua_tousertype(tolua_S, 1, nullptr); + if (self == nullptr) { - tolua_error(tolua_S, "invalid 'self' in function 'cCompositeChat:AddRunCommandPart'", NULL); + tolua_error(tolua_S, "invalid 'self' in function 'cCompositeChat:AddRunCommandPart'", nullptr); return 0; } @@ -3122,10 +3122,10 @@ static int tolua_cCompositeChat_AddSuggestCommandPart(lua_State * tolua_S) { return 0; } - cCompositeChat * self = (cCompositeChat *)tolua_tousertype(tolua_S, 1, NULL); - if (self == NULL) + cCompositeChat * self = (cCompositeChat *)tolua_tousertype(tolua_S, 1, nullptr); + if (self == nullptr) { - tolua_error(tolua_S, "invalid 'self' in function 'cCompositeChat:AddSuggestCommandPart'", NULL); + tolua_error(tolua_S, "invalid 'self' in function 'cCompositeChat:AddSuggestCommandPart'", nullptr); return 0; } @@ -3159,10 +3159,10 @@ static int tolua_cCompositeChat_AddTextPart(lua_State * tolua_S) { return 0; } - cCompositeChat * self = (cCompositeChat *)tolua_tousertype(tolua_S, 1, NULL); - if (self == NULL) + cCompositeChat * self = (cCompositeChat *)tolua_tousertype(tolua_S, 1, nullptr); + if (self == nullptr) { - tolua_error(tolua_S, "invalid 'self' in function 'cCompositeChat:AddTextPart'", NULL); + tolua_error(tolua_S, "invalid 'self' in function 'cCompositeChat:AddTextPart'", nullptr); return 0; } @@ -3195,10 +3195,10 @@ static int tolua_cCompositeChat_AddUrlPart(lua_State * tolua_S) { return 0; } - cCompositeChat * self = (cCompositeChat *)tolua_tousertype(tolua_S, 1, NULL); - if (self == NULL) + cCompositeChat * self = (cCompositeChat *)tolua_tousertype(tolua_S, 1, nullptr); + if (self == nullptr) { - tolua_error(tolua_S, "invalid 'self' in function 'cCompositeChat:AddUrlPart'", NULL); + tolua_error(tolua_S, "invalid 'self' in function 'cCompositeChat:AddUrlPart'", nullptr); return 0; } @@ -3232,10 +3232,10 @@ static int tolua_cCompositeChat_ParseText(lua_State * tolua_S) { return 0; } - cCompositeChat * self = (cCompositeChat *)tolua_tousertype(tolua_S, 1, NULL); - if (self == NULL) + cCompositeChat * self = (cCompositeChat *)tolua_tousertype(tolua_S, 1, nullptr); + if (self == nullptr) { - tolua_error(tolua_S, "invalid 'self' in function 'cCompositeChat:ParseText'", NULL); + tolua_error(tolua_S, "invalid 'self' in function 'cCompositeChat:ParseText'", nullptr); return 0; } @@ -3267,10 +3267,10 @@ static int tolua_cCompositeChat_SetMessageType(lua_State * tolua_S) { return 0; } - cCompositeChat * self = (cCompositeChat *)tolua_tousertype(tolua_S, 1, NULL); - if (self == NULL) + cCompositeChat * self = (cCompositeChat *)tolua_tousertype(tolua_S, 1, nullptr); + if (self == nullptr) { - tolua_error(tolua_S, "invalid 'self' in function 'cCompositeChat:SetMessageType'", NULL); + tolua_error(tolua_S, "invalid 'self' in function 'cCompositeChat:SetMessageType'", nullptr); return 0; } @@ -3299,10 +3299,10 @@ static int tolua_cCompositeChat_UnderlineUrls(lua_State * tolua_S) { return 0; } - cCompositeChat * self = (cCompositeChat *)tolua_tousertype(tolua_S, 1, NULL); - if (self == NULL) + cCompositeChat * self = (cCompositeChat *)tolua_tousertype(tolua_S, 1, nullptr); + if (self == nullptr) { - tolua_error(tolua_S, "invalid 'self' in function 'cCompositeChat:UnderlineUrls'", NULL); + tolua_error(tolua_S, "invalid 'self' in function 'cCompositeChat:UnderlineUrls'", nullptr); return 0; } @@ -3320,7 +3320,7 @@ static int tolua_cCompositeChat_UnderlineUrls(lua_State * tolua_S) void ManualBindings::Bind(lua_State * tolua_S) { - tolua_beginmodule(tolua_S, NULL); + tolua_beginmodule(tolua_S, nullptr); tolua_function(tolua_S, "Clamp", tolua_Clamp); tolua_function(tolua_S, "StringSplit", tolua_StringSplit); tolua_function(tolua_S, "StringSplitAndTrim", tolua_StringSplitAndTrim); @@ -3447,7 +3447,7 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_function(tolua_S, "AddWebTab", tolua_cPluginLua_AddWebTab); tolua_endmodule(tolua_S); - tolua_cclass(tolua_S, "HTTPRequest", "HTTPRequest", "", NULL); + tolua_cclass(tolua_S, "HTTPRequest", "HTTPRequest", "", nullptr); tolua_beginmodule(tolua_S, "HTTPRequest"); // tolua_variable(tolua_S, "Method", tolua_get_HTTPRequest_Method, tolua_set_HTTPRequest_Method); // tolua_variable(tolua_S, "Path", tolua_get_HTTPRequest_Path, tolua_set_HTTPRequest_Path); diff --git a/src/Bindings/ManualBindings_RankManager.cpp b/src/Bindings/ManualBindings_RankManager.cpp index 66174bf86..fa1b88b6a 100644 --- a/src/Bindings/ManualBindings_RankManager.cpp +++ b/src/Bindings/ManualBindings_RankManager.cpp @@ -1044,7 +1044,7 @@ void ManualBindings::BindRankManager(lua_State * tolua_S) { // Create the cRankManager class in the API: tolua_usertype(tolua_S, "cRankManager"); - tolua_cclass(tolua_S, "cRankManager", "cRankManager", "", NULL); + tolua_cclass(tolua_S, "cRankManager", "cRankManager", "", nullptr); // Fill in the functions (alpha-sorted): tolua_beginmodule(tolua_S, "cRankManager"); diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index eec31e8a6..391d8bcbe 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -1487,7 +1487,7 @@ void cPluginLua::ClearCommands(void) cCSLock Lock(m_CriticalSection); // Unreference the bound functions so that Lua can GC them - if (m_LuaState != NULL) + if (m_LuaState != nullptr) { for (CommandMap::iterator itr = m_Commands.begin(), end = m_Commands.end(); itr != end; ++itr) { @@ -1506,7 +1506,7 @@ void cPluginLua::ClearConsoleCommands(void) cCSLock Lock(m_CriticalSection); // Unreference the bound functions so that Lua can GC them - if (m_LuaState != NULL) + if (m_LuaState != nullptr) { for (CommandMap::iterator itr = m_ConsoleCommands.begin(), end = m_ConsoleCommands.end(); itr != end; ++itr) { @@ -1523,7 +1523,7 @@ void cPluginLua::ClearConsoleCommands(void) bool cPluginLua::CanAddOldStyleHook(int a_HookType) { const char * FnName = GetHookFnName(a_HookType); - if (FnName == NULL) + if (FnName == nullptr) { // Unknown hook ID LOGWARNING("Plugin %s wants to add an unknown hook ID (%d). The plugin need not work properly.", @@ -1614,7 +1614,7 @@ const char * cPluginLua::GetHookFnName(int a_HookType) } // switch (a_Hook) LOGWARNING("Requested name of an unknown hook type function: %d (max is %d)", a_HookType, cPluginManager::HOOK_MAX); ASSERT(!"Unknown hook requested!"); - return NULL; + return nullptr; } @@ -1627,12 +1627,12 @@ bool cPluginLua::AddHookRef(int a_HookType, int a_FnRefIdx) // Check if the function reference is valid: cLuaState::cRef * Ref = new cLuaState::cRef(m_LuaState, a_FnRefIdx); - if ((Ref == NULL) || !Ref->IsValid()) + if ((Ref == nullptr) || !Ref->IsValid()) { LOGWARNING("Plugin %s tried to add a hook %d with bad handler function.", GetName().c_str(), a_HookType); m_LuaState.LogStackTrace(); delete Ref; - Ref = NULL; + Ref = nullptr; return false; } @@ -1700,7 +1700,7 @@ AString cPluginLua::HandleWebRequest(const HTTPRequest * a_Request) } } - if (Tab != NULL) + if (Tab != nullptr) { AString Contents = Printf("WARNING: WebPlugin tab '%s' did not return a string!", Tab->Title.c_str()); if (!m_LuaState.Call(Tab->UserData, a_Request, cLuaState::Return, Contents)) diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index 479e71951..e549aefa3 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -66,7 +66,7 @@ void cPluginManager::FindPlugins(void) // First get a clean list of only the currently running plugins, we don't want to mess those up for (PluginMap::iterator itr = m_Plugins.begin(); itr != m_Plugins.end();) { - if (itr->second == NULL) + if (itr->second == nullptr) { PluginMap::iterator thiz = itr; ++thiz; @@ -89,7 +89,7 @@ void cPluginManager::FindPlugins(void) // Add plugin name/directory to the list if (m_Plugins.find(*itr) == m_Plugins.end()) { - m_Plugins[*itr] = NULL; + m_Plugins[*itr] = nullptr; } } } @@ -151,7 +151,7 @@ void cPluginManager::ReloadPluginsNow(cIniFile & a_SettingsIni) // Remove invalid plugins from the PluginMap. for (PluginMap::iterator itr = m_Plugins.begin(); itr != m_Plugins.end();) { - if (itr->second == NULL) + if (itr->second == nullptr) { PluginMap::iterator thiz = itr; ++thiz; @@ -1445,7 +1445,7 @@ cPluginManager::CommandResult cPluginManager::HandleCommand(cPlayer & a_Player, return crNoPermission; } - ASSERT(cmd->second.m_Plugin != NULL); + ASSERT(cmd->second.m_Plugin != nullptr); if (!cmd->second.m_Plugin->HandleCommand(Split, a_Player)) { @@ -1463,7 +1463,7 @@ cPlugin * cPluginManager::GetPlugin( const AString & a_Plugin) const { for (PluginMap::const_iterator itr = m_Plugins.begin(); itr != m_Plugins.end(); ++itr) { - if (itr->second == NULL) continue; + if (itr->second == nullptr) continue; if (itr->second->GetName().compare(a_Plugin) == 0) { return itr->second; @@ -1513,7 +1513,7 @@ bool cPluginManager::DisablePlugin(const AString & a_PluginName) if (itr->first.compare(a_PluginName) == 0) // _X 2013_02_01: wtf? Isn't this supposed to be what find() does? { m_DisablePluginList.push_back(itr->second); - itr->second = NULL; // Get rid of this thing right away + itr->second = nullptr; // Get rid of this thing right away return true; } return false; @@ -1558,12 +1558,12 @@ void cPluginManager::RemovePlugin(cPlugin * a_Plugin) RemovePluginCommands(a_Plugin); RemovePluginConsoleCommands(a_Plugin); RemoveHooks(a_Plugin); - if (a_Plugin != NULL) + if (a_Plugin != nullptr) { a_Plugin->OnDisable(); } delete a_Plugin; - a_Plugin = NULL; + a_Plugin = nullptr; } @@ -1572,7 +1572,7 @@ void cPluginManager::RemovePlugin(cPlugin * a_Plugin) void cPluginManager::RemovePluginCommands(cPlugin * a_Plugin) { - if (a_Plugin != NULL) + if (a_Plugin != nullptr) { a_Plugin->ClearCommands(); } @@ -1670,7 +1670,7 @@ cPluginManager::CommandResult cPluginManager::ForceExecuteCommand(cPlayer & a_Pl void cPluginManager::RemovePluginConsoleCommands(cPlugin * a_Plugin) { - if (a_Plugin != NULL) + if (a_Plugin != nullptr) { a_Plugin->ClearConsoleCommands(); } @@ -1699,7 +1699,7 @@ bool cPluginManager::BindConsoleCommand(const AString & a_Command, cPlugin * a_P CommandMap::iterator cmd = m_ConsoleCommands.find(a_Command); if (cmd != m_ConsoleCommands.end()) { - if (cmd->second.m_Plugin == NULL) + if (cmd->second.m_Plugin == nullptr) { LOGWARNING("Console command \"%s\" is already bound internally by MCServer, cannot bind in plugin \"%s\".", a_Command.c_str(), a_Plugin->GetName().c_str()); } @@ -1759,14 +1759,14 @@ bool cPluginManager::ExecuteConsoleCommand(const AStringVector & a_Split, cComma return false; } - if (cmd->second.m_Plugin == NULL) + if (cmd->second.m_Plugin == nullptr) { // This is a built-in command return false; } // Ask plugins first if a command is okay to execute the console command: - if (CallHookExecuteCommand(NULL, a_Split)) + if (CallHookExecuteCommand(nullptr, a_Split)) { a_Output.Out("Command \"%s\" was stopped by the HOOK_EXECUTE_COMMAND hook", a_Split[0].c_str()); return false; @@ -1788,7 +1788,7 @@ void cPluginManager::TabCompleteCommand(const AString & a_Text, AStringVector & // Command name doesn't match continue; } - if ((a_Player != NULL) && !a_Player->HasPermission(itr->second.m_Permission)) + if ((a_Player != nullptr) && !a_Player->HasPermission(itr->second.m_Permission)) { // Player doesn't have permission for the command continue; @@ -1814,7 +1814,7 @@ bool cPluginManager::DoWithPlugin(const AString & a_PluginName, cPluginCallback { // TODO: Implement locking for plugins PluginMap::iterator itr = m_Plugins.find(a_PluginName); - if ((itr == m_Plugins.end()) || (itr->second == NULL)) + if ((itr == m_Plugins.end()) || (itr->second == nullptr)) { return false; } @@ -1848,7 +1848,7 @@ void cPluginManager::AddHook(cPlugin * a_Plugin, int a_Hook) { if (!a_Plugin) { - LOGWARN("Called cPluginManager::AddHook() with a_Plugin == NULL"); + LOGWARN("Called cPluginManager::AddHook() with a_Plugin == nullptr"); return; } PluginList & Plugins = m_Hooks[a_Hook]; diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index c69850be6..bc8c1f5e6 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -190,7 +190,7 @@ public: bool CallHookCraftingNoRecipe (cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe * a_Recipe); bool CallHookDisconnect (cClientHandle & a_Client, const AString & a_Reason); bool CallHookEntityAddEffect (cEntity & a_Entity, int a_EffectType, int a_EffectDurationTicks, int a_EffectIntensity, double a_DistanceModifier); - bool CallHookExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split); // If a_Player == NULL, it is a console cmd + bool CallHookExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split); // If a_Player == nullptr, it is a console cmd bool CallHookExploded (cWorld & a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData); bool CallHookExploding (cWorld & a_World, double & a_ExplosionSize, bool & a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData); bool CallHookHandshake (cClientHandle & a_ClientHandle, const AString & a_Username); @@ -285,7 +285,7 @@ public: bool ExecuteConsoleCommand(const AStringVector & a_Split, cCommandOutputCallback & a_Output); /** Appends all commands beginning with a_Text (case-insensitive) into a_Results. - If a_Player is not NULL, only commands for which the player has permissions are added. + If a_Player is not nullptr, only commands for which the player has permissions are added. */ void TabCompleteCommand(const AString & a_Text, AStringVector & a_Results, cPlayer * a_Player); diff --git a/src/Bindings/WebPlugin.cpp b/src/Bindings/WebPlugin.cpp index eca1c74e6..5759b20e7 100644 --- a/src/Bindings/WebPlugin.cpp +++ b/src/Bindings/WebPlugin.cpp @@ -12,7 +12,7 @@ cWebPlugin::cWebPlugin() { cWebAdmin * WebAdmin = cRoot::Get()->GetWebAdmin(); - if (WebAdmin != NULL) + if (WebAdmin != nullptr) { WebAdmin->AddPlugin(this); } @@ -25,7 +25,7 @@ cWebPlugin::cWebPlugin() cWebPlugin::~cWebPlugin() { cWebAdmin * WebAdmin = cRoot::Get()->GetWebAdmin(); - if (WebAdmin != NULL) + if (WebAdmin != nullptr) { WebAdmin->RemovePlugin(this); } @@ -65,7 +65,7 @@ std::pair< AString, AString > cWebPlugin::GetTabNameForRequest(const HTTPRequest if (Split.size() > 1) { - sWebPluginTab * Tab = NULL; + sWebPluginTab * Tab = nullptr; if (Split.size() > 2) // If we got the tab name, show that page { for (TabList::iterator itr = GetTabs().begin(); itr != GetTabs().end(); ++itr) @@ -85,7 +85,7 @@ std::pair< AString, AString > cWebPlugin::GetTabNameForRequest(const HTTPRequest } } - if (Tab != NULL) + if (Tab != nullptr) { Names.first = Tab->Title; Names.second = Tab->SafeTitle; diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp index ba55528b8..4c3da0535 100644 --- a/src/BlockArea.cpp +++ b/src/BlockArea.cpp @@ -273,10 +273,10 @@ void MergeCombinatorMask(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE // cBlockArea: cBlockArea::cBlockArea(void) : - m_BlockTypes(NULL), - m_BlockMetas(NULL), - m_BlockLight(NULL), - m_BlockSkyLight(NULL) + m_BlockTypes(nullptr), + m_BlockMetas(nullptr), + m_BlockLight(nullptr), + m_BlockSkyLight(nullptr) { } @@ -295,10 +295,10 @@ cBlockArea::~cBlockArea() void cBlockArea::Clear(void) { - delete[] m_BlockTypes; m_BlockTypes = NULL; - delete[] m_BlockMetas; m_BlockMetas = NULL; - delete[] m_BlockLight; m_BlockLight = NULL; - delete[] m_BlockSkyLight; m_BlockSkyLight = NULL; + delete[] m_BlockTypes; m_BlockTypes = nullptr; + delete[] m_BlockMetas; m_BlockMetas = nullptr; + delete[] m_BlockLight; m_BlockLight = nullptr; + delete[] m_BlockSkyLight; m_BlockSkyLight = nullptr; m_Origin.Set(0, 0, 0); m_Size.Set(0, 0, 0); } @@ -711,7 +711,7 @@ void cBlockArea::Merge(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_R const NIBBLETYPE * SrcMetas = a_Src.GetBlockMetas(); NIBBLETYPE * DstMetas = m_BlockMetas; - bool IsDummyMetas = ((SrcMetas == NULL) || (DstMetas == NULL)); + bool IsDummyMetas = ((SrcMetas == nullptr) || (DstMetas == nullptr)); if (IsDummyMetas) { @@ -1013,8 +1013,8 @@ void cBlockArea::RotateCCW(void) } // for x std::swap(m_BlockTypes, NewTypes); std::swap(m_BlockMetas, NewMetas); - delete[] NewTypes; NewTypes = NULL; - delete[] NewMetas; NewMetas = NULL; + delete[] NewTypes; NewTypes = nullptr; + delete[] NewMetas; NewMetas = nullptr; std::swap(m_Size.x, m_Size.z); } @@ -1058,8 +1058,8 @@ void cBlockArea::RotateCW(void) } // for x std::swap(m_BlockTypes, NewTypes); std::swap(m_BlockMetas, NewMetas); - delete[] NewTypes; NewTypes = NULL; - delete[] NewMetas; NewMetas = NULL; + delete[] NewTypes; NewTypes = nullptr; + delete[] NewMetas; NewMetas = nullptr; std::swap(m_Size.x, m_Size.z); } @@ -1206,7 +1206,7 @@ void cBlockArea::RotateCCWNoMeta(void) } // for z } // for x std::swap(m_BlockTypes, NewTypes); - delete[] NewTypes; NewTypes = NULL; + delete[] NewTypes; NewTypes = nullptr; } if (HasBlockMetas()) { @@ -1224,7 +1224,7 @@ void cBlockArea::RotateCCWNoMeta(void) } // for z } // for x std::swap(m_BlockMetas, NewMetas); - delete[] NewMetas; NewMetas = NULL; + delete[] NewMetas; NewMetas = nullptr; } std::swap(m_Size.x, m_Size.z); } @@ -1251,7 +1251,7 @@ void cBlockArea::RotateCWNoMeta(void) } // for x } // for z std::swap(m_BlockTypes, NewTypes); - delete[] NewTypes; NewTypes = NULL; + delete[] NewTypes; NewTypes = nullptr; } if (HasBlockMetas()) { @@ -1269,7 +1269,7 @@ void cBlockArea::RotateCWNoMeta(void) } // for x } // for z std::swap(m_BlockMetas, NewMetas); - delete[] NewMetas; NewMetas = NULL; + delete[] NewMetas; NewMetas = nullptr; } std::swap(m_Size.x, m_Size.z); } @@ -1391,7 +1391,7 @@ void cBlockArea::MirrorYZNoMeta(void) void cBlockArea::SetRelBlockType(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType) { - if (m_BlockTypes == NULL) + if (m_BlockTypes == nullptr) { LOGWARNING("cBlockArea: BlockTypes have not been read!"); return; @@ -1468,7 +1468,7 @@ void cBlockArea::SetBlockSkyLight(int a_BlockX, int a_BlockY, int a_BlockZ, NIBB BLOCKTYPE cBlockArea::GetRelBlockType(int a_RelX, int a_RelY, int a_RelZ) const { - if (m_BlockTypes == NULL) + if (m_BlockTypes == nullptr) { LOGWARNING("cBlockArea: BlockTypes have not been read!"); return E_BLOCK_AIR; @@ -1555,7 +1555,7 @@ void cBlockArea::SetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOC void cBlockArea::SetRelBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) { int idx = MakeIndex(a_RelX, a_RelY, a_RelZ); - if (m_BlockTypes == NULL) + if (m_BlockTypes == nullptr) { LOGWARNING("%s: BlockTypes not available but requested to be written to.", __FUNCTION__); } @@ -1563,7 +1563,7 @@ void cBlockArea::SetRelBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, B { m_BlockTypes[idx] = a_BlockType; } - if (m_BlockMetas == NULL) + if (m_BlockMetas == nullptr) { LOGWARNING("%s: BlockMetas not available but requested to be written to.", __FUNCTION__); } @@ -1589,7 +1589,7 @@ void cBlockArea::GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOC void cBlockArea::GetRelBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const { int idx = MakeIndex(a_RelX, a_RelY, a_RelZ); - if (m_BlockTypes == NULL) + if (m_BlockTypes == nullptr) { LOGWARNING("cBlockArea: BlockTypes have not been read!"); a_BlockType = E_BLOCK_AIR; @@ -1599,7 +1599,7 @@ void cBlockArea::GetRelBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTY a_BlockType = m_BlockTypes[idx]; } - if (m_BlockMetas == NULL) + if (m_BlockMetas == nullptr) { LOGWARNING("cBlockArea: BlockMetas have not been read!"); a_BlockMeta = 0; @@ -1617,19 +1617,19 @@ void cBlockArea::GetRelBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTY int cBlockArea::GetDataTypes(void) const { int res = 0; - if (m_BlockTypes != NULL) + if (m_BlockTypes != nullptr) { res |= baTypes; } - if (m_BlockMetas != NULL) + if (m_BlockMetas != nullptr) { res |= baMetas; } - if (m_BlockLight != NULL) + if (m_BlockLight != nullptr) { res |= baLight; } - if (m_BlockSkyLight != NULL) + if (m_BlockSkyLight != nullptr) { res |= baSkyLight; } @@ -1642,12 +1642,12 @@ int cBlockArea::GetDataTypes(void) const bool cBlockArea::SetSize(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes) { - ASSERT(m_BlockTypes == NULL); // Has been cleared + ASSERT(m_BlockTypes == nullptr); // Has been cleared if (a_DataTypes & baTypes) { m_BlockTypes = new BLOCKTYPE[a_SizeX * a_SizeY * a_SizeZ]; - if (m_BlockTypes == NULL) + if (m_BlockTypes == nullptr) { return false; } @@ -1655,36 +1655,36 @@ bool cBlockArea::SetSize(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes) if (a_DataTypes & baMetas) { m_BlockMetas = new NIBBLETYPE[a_SizeX * a_SizeY * a_SizeZ]; - if (m_BlockMetas == NULL) + if (m_BlockMetas == nullptr) { delete[] m_BlockTypes; - m_BlockTypes = NULL; + m_BlockTypes = nullptr; return false; } } if (a_DataTypes & baLight) { m_BlockLight = new NIBBLETYPE[a_SizeX * a_SizeY * a_SizeZ]; - if (m_BlockLight == NULL) + if (m_BlockLight == nullptr) { delete[] m_BlockMetas; - m_BlockMetas = NULL; + m_BlockMetas = nullptr; delete[] m_BlockTypes; - m_BlockTypes = NULL; + m_BlockTypes = nullptr; return false; } } if (a_DataTypes & baSkyLight) { m_BlockSkyLight = new NIBBLETYPE[a_SizeX * a_SizeY * a_SizeZ]; - if (m_BlockSkyLight == NULL) + if (m_BlockSkyLight == nullptr) { delete[] m_BlockLight; - m_BlockLight = NULL; + m_BlockLight = nullptr; delete[] m_BlockMetas; - m_BlockMetas = NULL; + m_BlockMetas = nullptr; delete[] m_BlockTypes; - m_BlockTypes = NULL; + m_BlockTypes = nullptr; return false; } } @@ -1714,7 +1714,7 @@ int cBlockArea::MakeIndex(int a_RelX, int a_RelY, int a_RelZ) const void cBlockArea::SetRelNibble(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Value, NIBBLETYPE * a_Array) { - if (a_Array == NULL) + if (a_Array == nullptr) { LOGWARNING("cBlockArea: datatype has not been read!"); return; @@ -1737,7 +1737,7 @@ void cBlockArea::SetNibble(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE NIBBLETYPE cBlockArea::GetRelNibble(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE * a_Array) const { - if (a_Array == NULL) + if (a_Array == nullptr) { LOGWARNING("cBlockArea: datatype has not been read!"); return 16; @@ -1896,7 +1896,7 @@ void cBlockArea::cChunkReader::ChunkData(const cChunkData & a_BlockBuffer) } // Copy the blocktypes: - if (m_Area.m_BlockTypes != NULL) + if (m_Area.m_BlockTypes != nullptr) { for (int y = 0; y < SizeY; y++) { @@ -1917,7 +1917,7 @@ void cBlockArea::cChunkReader::ChunkData(const cChunkData & a_BlockBuffer) } // Copy the block metas: - if (m_Area.m_BlockMetas != NULL) + if (m_Area.m_BlockMetas != nullptr) { for (int y = 0; y < SizeY; y++) { @@ -1938,7 +1938,7 @@ void cBlockArea::cChunkReader::ChunkData(const cChunkData & a_BlockBuffer) } // Copy the blocklight: - if (m_Area.m_BlockLight != NULL) + if (m_Area.m_BlockLight != nullptr) { for (int y = 0; y < SizeY; y++) { @@ -1959,7 +1959,7 @@ void cBlockArea::cChunkReader::ChunkData(const cChunkData & a_BlockBuffer) } // Copy the skylight: - if (m_Area.m_BlockSkyLight != NULL) + if (m_Area.m_BlockSkyLight != nullptr) { for (int y = 0; y < SizeY; y++) { diff --git a/src/BlockArea.h b/src/BlockArea.h index 86f7c4f2d..348e960dd 100644 --- a/src/BlockArea.h +++ b/src/BlockArea.h @@ -282,10 +282,10 @@ public: /** Returns the datatypes that are stored in the object (bitmask of baXXX values) */ int GetDataTypes(void) const; - bool HasBlockTypes (void) const { return (m_BlockTypes != NULL); } - bool HasBlockMetas (void) const { return (m_BlockMetas != NULL); } - bool HasBlockLights (void) const { return (m_BlockLight != NULL); } - bool HasBlockSkyLights(void) const { return (m_BlockSkyLight != NULL); } + bool HasBlockTypes (void) const { return (m_BlockTypes != nullptr); } + bool HasBlockMetas (void) const { return (m_BlockMetas != nullptr); } + bool HasBlockLights (void) const { return (m_BlockLight != nullptr); } + bool HasBlockSkyLights(void) const { return (m_BlockSkyLight != nullptr); } // tolua_end diff --git a/src/BlockEntities/BeaconEntity.cpp b/src/BlockEntities/BeaconEntity.cpp index 02f45a097..85819446c 100644 --- a/src/BlockEntities/BeaconEntity.cpp +++ b/src/BlockEntities/BeaconEntity.cpp @@ -97,7 +97,7 @@ bool cBeaconEntity::SetPrimaryEffect(cEntityEffect::eType a_Effect) m_PrimaryEffect = a_Effect; // Send window update: - if (GetWindow() != NULL) + if (GetWindow() != nullptr) { GetWindow()->SetProperty(1, m_PrimaryEffect); } @@ -119,7 +119,7 @@ bool cBeaconEntity::SetSecondaryEffect(cEntityEffect::eType a_Effect) m_SecondaryEffect = a_Effect; // Send window update: - if (GetWindow() != NULL) + if (GetWindow() != nullptr) { GetWindow()->SetProperty(2, m_SecondaryEffect); } @@ -184,7 +184,7 @@ void cBeaconEntity::UpdateBeacon(void) if (m_BeaconLevel != OldBeaconLevel) { // Send window update: - if (GetWindow() != NULL) + if (GetWindow() != nullptr) { GetWindow()->SetProperty(0, m_BeaconLevel); } @@ -283,13 +283,13 @@ bool cBeaconEntity::Tick(float a_Dt, cChunk & a_Chunk) void cBeaconEntity::UsedBy(cPlayer * a_Player) { cWindow * Window = GetWindow(); - if (Window == NULL) + if (Window == nullptr) { OpenWindow(new cBeaconWindow(m_PosX, m_PosY, m_PosZ, this)); Window = GetWindow(); } - if (Window != NULL) + if (Window != nullptr) { // if (a_Player->GetWindow() != Window) // -> Because mojang doesn't send a 'close window' packet when you click the cancel button in the beacon inventory ... diff --git a/src/BlockEntities/BlockEntity.cpp b/src/BlockEntities/BlockEntity.cpp index 05ad03a3d..3d96e891e 100644 --- a/src/BlockEntities/BlockEntity.cpp +++ b/src/BlockEntities/BlockEntity.cpp @@ -48,7 +48,7 @@ cBlockEntity * cBlockEntity::CreateByBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE __FUNCTION__, a_BlockType, ItemTypeToString(a_BlockType).c_str() ); ASSERT(!"Requesting creation of an unknown block entity"); - return NULL; + return nullptr; } diff --git a/src/BlockEntities/BlockEntity.h b/src/BlockEntities/BlockEntity.h index b04d20340..ffd6ee856 100644 --- a/src/BlockEntities/BlockEntity.h +++ b/src/BlockEntities/BlockEntity.h @@ -70,8 +70,8 @@ public: /// Creates a new block entity for the specified block type /// If a_World is valid, then the entity is created bound to that world - /// Returns NULL for unknown block types - static cBlockEntity * CreateByBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World = NULL); + /// Returns nullptr for unknown block types + static cBlockEntity * CreateByBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World = nullptr); static const char * GetClassStatic(void) // Needed for ManualBindings's ForEach templates { diff --git a/src/BlockEntities/BlockEntityWithItems.h b/src/BlockEntities/BlockEntityWithItems.h index cb7bc2fb4..8c7d4749b 100644 --- a/src/BlockEntities/BlockEntityWithItems.h +++ b/src/BlockEntities/BlockEntityWithItems.h @@ -47,7 +47,7 @@ public: virtual void Destroy(void) override { // Drop the contents as pickups: - ASSERT(m_World != NULL); + ASSERT(m_World != nullptr); cItems Pickups; m_Contents.CopyToItems(Pickups); m_Contents.Clear(); @@ -78,9 +78,9 @@ protected: { UNUSED(a_SlotNum); ASSERT(a_Grid == &m_Contents); - if (m_World != NULL) + if (m_World != nullptr) { - if (GetWindow() != NULL) + if (GetWindow() != nullptr) { GetWindow()->BroadcastWholeWindow(); } diff --git a/src/BlockEntities/ChestEntity.cpp b/src/BlockEntities/ChestEntity.cpp index 19d88b646..0cd9c66e0 100644 --- a/src/BlockEntities/ChestEntity.cpp +++ b/src/BlockEntities/ChestEntity.cpp @@ -23,7 +23,7 @@ cChestEntity::cChestEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_ cChestEntity::~cChestEntity() { cWindow * Window = GetWindow(); - if (Window != NULL) + if (Window != nullptr) { Window->OwnerDestroyed(); } @@ -49,14 +49,14 @@ void cChestEntity::UsedBy(cPlayer * a_Player) { // If the window is not created, open it anew: cWindow * Window = GetWindow(); - if (Window == NULL) + if (Window == nullptr) { OpenNewWindow(); Window = GetWindow(); } // Open the window for the player: - if (Window != NULL) + if (Window != nullptr) { if (a_Player->GetWindow() != Window) { diff --git a/src/BlockEntities/CommandBlockEntity.cpp b/src/BlockEntities/CommandBlockEntity.cpp index 1a5a3f01e..b7f938ffd 100644 --- a/src/BlockEntities/CommandBlockEntity.cpp +++ b/src/BlockEntities/CommandBlockEntity.cpp @@ -154,7 +154,7 @@ void cCommandBlockEntity::SendTo(cClientHandle & a_Client) void cCommandBlockEntity::Execute() { - ASSERT(m_World != NULL); // Execute should not be called before the command block is attached to a world + ASSERT(m_World != nullptr); // Execute should not be called before the command block is attached to a world if (!m_World->AreCommandBlocksEnabled()) { diff --git a/src/BlockEntities/DispenserEntity.cpp b/src/BlockEntities/DispenserEntity.cpp index aea854dc2..82c234a14 100644 --- a/src/BlockEntities/DispenserEntity.cpp +++ b/src/BlockEntities/DispenserEntity.cpp @@ -28,7 +28,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) NIBBLETYPE Meta = a_Chunk.GetMeta(m_RelX, m_PosY, m_RelZ); AddDropSpenserDir(DispX, DispY, DispZ, Meta); cChunk * DispChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(DispX, DispZ); - if (DispChunk == NULL) + if (DispChunk == nullptr) { // Would dispense into / interact with a non-loaded chunk, ignore the tick return; @@ -190,7 +190,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) void cDispenserEntity::SpawnProjectileFromDispenser(int a_BlockX, int a_BlockY, int a_BlockZ, cProjectileEntity::eKind a_Kind, const Vector3d & a_ShootVector) { - m_World->CreateProjectile((double)a_BlockX + 0.5, (double)a_BlockY + 0.5, (double)a_BlockZ + 0.5, a_Kind, NULL, NULL, &a_ShootVector); + m_World->CreateProjectile((double)a_BlockX + 0.5, (double)a_BlockY + 0.5, (double)a_BlockZ + 0.5, a_Kind, nullptr, nullptr, &a_ShootVector); } diff --git a/src/BlockEntities/DropSpenserEntity.cpp b/src/BlockEntities/DropSpenserEntity.cpp index dac951b27..3f98836e7 100644 --- a/src/BlockEntities/DropSpenserEntity.cpp +++ b/src/BlockEntities/DropSpenserEntity.cpp @@ -28,7 +28,7 @@ cDropSpenserEntity::~cDropSpenserEntity() { // Tell window its owner is destroyed cWindow * Window = GetWindow(); - if (Window != NULL) + if (Window != nullptr) { Window->OwnerDestroyed(); } @@ -155,13 +155,13 @@ void cDropSpenserEntity::SendTo(cClientHandle & a_Client) void cDropSpenserEntity::UsedBy(cPlayer * a_Player) { cWindow * Window = GetWindow(); - if (Window == NULL) + if (Window == nullptr) { OpenWindow(new cDropSpenserWindow(m_PosX, m_PosY, m_PosZ, this)); Window = GetWindow(); } - if (Window != NULL) + if (Window != nullptr) { if (a_Player->GetWindow() != Window) { diff --git a/src/BlockEntities/EnderChestEntity.cpp b/src/BlockEntities/EnderChestEntity.cpp index 0654d97dd..e18490a1e 100644 --- a/src/BlockEntities/EnderChestEntity.cpp +++ b/src/BlockEntities/EnderChestEntity.cpp @@ -23,7 +23,7 @@ cEnderChestEntity::cEnderChestEntity(int a_BlockX, int a_BlockY, int a_BlockZ, c cEnderChestEntity::~cEnderChestEntity() { cWindow * Window = GetWindow(); - if (Window != NULL) + if (Window != nullptr) { Window->OwnerDestroyed(); } @@ -37,14 +37,14 @@ void cEnderChestEntity::UsedBy(cPlayer * a_Player) { // If the window is not created, open it anew: cWindow * Window = GetWindow(); - if (Window == NULL) + if (Window == nullptr) { OpenNewWindow(); Window = GetWindow(); } // Open the window for the player: - if (Window != NULL) + if (Window != nullptr) { if (a_Player->GetWindow() != Window) { diff --git a/src/BlockEntities/FlowerPotEntity.cpp b/src/BlockEntities/FlowerPotEntity.cpp index 01560f814..9db3b268b 100644 --- a/src/BlockEntities/FlowerPotEntity.cpp +++ b/src/BlockEntities/FlowerPotEntity.cpp @@ -59,7 +59,7 @@ void cFlowerPotEntity::Destroy(void) // Drop the contents as pickups: if (!m_Item.IsEmpty()) { - ASSERT(m_World != NULL); + ASSERT(m_World != nullptr); cItems Pickups; Pickups.Add(m_Item); m_World->SpawnItemPickups(Pickups, m_PosX + 0.5, m_PosY + 0.5, m_PosZ + 0.5); diff --git a/src/BlockEntities/FlowerPotEntity.h b/src/BlockEntities/FlowerPotEntity.h index 5b86621f5..fc886c51f 100644 --- a/src/BlockEntities/FlowerPotEntity.h +++ b/src/BlockEntities/FlowerPotEntity.h @@ -38,7 +38,7 @@ public: BLOCKENTITY_PROTODEF(cFlowerPotEntity); - /** Creates a new flowerpot entity at the specified block coords. a_World may be NULL */ + /** Creates a new flowerpot entity at the specified block coords. a_World may be nullptr */ cFlowerPotEntity(int a_BlocX, int a_BlockY, int a_BlockZ, cWorld * a_World); virtual void Destroy(void) override; diff --git a/src/BlockEntities/FurnaceEntity.cpp b/src/BlockEntities/FurnaceEntity.cpp index 284ac7de9..85f68b00b 100644 --- a/src/BlockEntities/FurnaceEntity.cpp +++ b/src/BlockEntities/FurnaceEntity.cpp @@ -26,7 +26,7 @@ enum cFurnaceEntity::cFurnaceEntity(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cWorld * a_World) : super(a_BlockType, a_BlockX, a_BlockY, a_BlockZ, ContentsWidth, ContentsHeight, a_World), m_BlockMeta(a_BlockMeta), - m_CurrentRecipe(NULL), + m_CurrentRecipe(nullptr), m_IsDestroyed(false), m_IsCooking(a_BlockType == E_BLOCK_LIT_FURNACE), m_NeedCookTime(0), @@ -45,7 +45,7 @@ cFurnaceEntity::~cFurnaceEntity() { // Tell window its owner is destroyed cWindow * Window = GetWindow(); - if (Window != NULL) + if (Window != nullptr) { Window->OwnerDestroyed(); } @@ -145,7 +145,7 @@ void cFurnaceEntity::SendTo(cClientHandle & a_Client) void cFurnaceEntity::BroadcastProgress(short a_ProgressbarID, short a_Value) { cWindow * Window = GetWindow(); - if (Window != NULL) + if (Window != nullptr) { Window->SetProperty(a_ProgressbarID, a_Value); } @@ -306,7 +306,7 @@ void cFurnaceEntity::UpdateOutput(void) bool cFurnaceEntity::CanCookInputToOutput(void) const { - if (m_CurrentRecipe == NULL) + if (m_CurrentRecipe == nullptr) { // This input cannot be cooked return false; diff --git a/src/BlockEntities/HopperEntity.cpp b/src/BlockEntities/HopperEntity.cpp index 103f516fc..5ed25ce99 100644 --- a/src/BlockEntities/HopperEntity.cpp +++ b/src/BlockEntities/HopperEntity.cpp @@ -86,14 +86,14 @@ void cHopperEntity::UsedBy(cPlayer * a_Player) { // If the window is not created, open it anew: cWindow * Window = GetWindow(); - if (Window == NULL) + if (Window == nullptr) { OpenNewWindow(); Window = GetWindow(); } // Open the window for the player: - if (Window != NULL) + if (Window != nullptr) { if (a_Player->GetWindow() != Window) { @@ -197,7 +197,7 @@ bool cHopperEntity::MovePickupsIn(cChunk & a_Chunk, Int64 a_CurrentTick) virtual bool Item(cEntity * a_Entity) override { - ASSERT(a_Entity != NULL); + ASSERT(a_Entity != nullptr); if (!a_Entity->IsPickup() || a_Entity->IsDestroyed()) { @@ -299,7 +299,7 @@ bool cHopperEntity::MoveItemsOut(cChunk & a_Chunk, Int64 a_CurrentTick) int OutRelX = OutX - a_Chunk.GetPosX() * cChunkDef::Width; int OutRelZ = OutZ - a_Chunk.GetPosZ() * cChunkDef::Width; cChunk * DestChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(OutRelX, OutRelZ); - if (DestChunk == NULL) + if (DestChunk == nullptr) { // The destination chunk has been unloaded, don't tick return false; @@ -328,7 +328,7 @@ bool cHopperEntity::MoveItemsOut(cChunk & a_Chunk, Int64 a_CurrentTick) case E_BLOCK_HOPPER: { cBlockEntityWithItems * BlockEntity = (cBlockEntityWithItems *)DestChunk->GetBlockEntity(OutX, OutY, OutZ); - if (BlockEntity == NULL) + if (BlockEntity == nullptr) { LOGWARNING("%s: A block entity was not found where expected at {%d, %d, %d}", __FUNCTION__, OutX, OutY, OutZ); return false; @@ -355,7 +355,7 @@ bool cHopperEntity::MoveItemsOut(cChunk & a_Chunk, Int64 a_CurrentTick) bool cHopperEntity::MoveItemsFromChest(cChunk & a_Chunk) { cChestEntity * MainChest = (cChestEntity *)a_Chunk.GetBlockEntity(m_PosX, m_PosY + 1, m_PosZ); - if (MainChest == NULL) + if (MainChest == nullptr) { LOGWARNING("%s: A chest entity was not found where expected, at {%d, %d, %d}", __FUNCTION__, m_PosX, m_PosY + 1, m_PosZ); return false; @@ -383,7 +383,7 @@ bool cHopperEntity::MoveItemsFromChest(cChunk & a_Chunk) int x = m_RelX + Coords[i].x; int z = m_RelZ + Coords[i].z; cChunk * Neighbor = a_Chunk.GetRelNeighborChunkAdjustCoords(x, z); - if (Neighbor == NULL) + if (Neighbor == nullptr) { continue; } @@ -396,7 +396,7 @@ bool cHopperEntity::MoveItemsFromChest(cChunk & a_Chunk) } cChestEntity * SideChest = (cChestEntity *)Neighbor->GetBlockEntity(m_PosX + Coords[i].x, m_PosY + 1, m_PosZ + Coords[i].z); - if (SideChest == NULL) + if (SideChest == nullptr) { LOGWARNING("%s: A chest entity was not found where expected, at {%d, %d, %d}", __FUNCTION__, m_PosX + Coords[i].x, m_PosY + 1, m_PosZ + Coords[i].z); } @@ -422,7 +422,7 @@ bool cHopperEntity::MoveItemsFromChest(cChunk & a_Chunk) bool cHopperEntity::MoveItemsFromFurnace(cChunk & a_Chunk) { cFurnaceEntity * Furnace = (cFurnaceEntity *)a_Chunk.GetBlockEntity(m_PosX, m_PosY + 1, m_PosZ); - if (Furnace == NULL) + if (Furnace == nullptr) { LOGWARNING("%s: A furnace entity was not found where expected, at {%d, %d, %d}", __FUNCTION__, m_PosX, m_PosY + 1, m_PosZ); return false; @@ -536,7 +536,7 @@ bool cHopperEntity::MoveItemsToChest(cChunk & a_Chunk, int a_BlockX, int a_Block { // Try the chest directly connected to the hopper: cChestEntity * ConnectedChest = (cChestEntity *)a_Chunk.GetBlockEntity(a_BlockX, a_BlockY, a_BlockZ); - if (ConnectedChest == NULL) + if (ConnectedChest == nullptr) { LOGWARNING("%s: A chest entity was not found where expected, at {%d, %d, %d}", __FUNCTION__, a_BlockX, a_BlockY, a_BlockZ); return false; @@ -566,7 +566,7 @@ bool cHopperEntity::MoveItemsToChest(cChunk & a_Chunk, int a_BlockX, int a_Block int x = RelX + Coords[i].x; int z = RelZ + Coords[i].z; cChunk * Neighbor = a_Chunk.GetRelNeighborChunkAdjustCoords(x, z); - if (Neighbor == NULL) + if (Neighbor == nullptr) { continue; } @@ -579,7 +579,7 @@ bool cHopperEntity::MoveItemsToChest(cChunk & a_Chunk, int a_BlockX, int a_Block } cChestEntity * Chest = (cChestEntity *)Neighbor->GetBlockEntity(a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z); - if (Chest == NULL) + if (Chest == nullptr) { LOGWARNING("%s: A chest entity was not found where expected, at {%d, %d, %d} (%d, %d)", __FUNCTION__, a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z, x, z); continue; diff --git a/src/BlockEntities/MobHeadEntity.h b/src/BlockEntities/MobHeadEntity.h index 7f69bc5ad..7132ef558 100644 --- a/src/BlockEntities/MobHeadEntity.h +++ b/src/BlockEntities/MobHeadEntity.h @@ -36,7 +36,7 @@ public: BLOCKENTITY_PROTODEF(cMobHeadEntity); - /** Creates a new mob head entity at the specified block coords. a_World may be NULL */ + /** Creates a new mob head entity at the specified block coords. a_World may be nullptr */ cMobHeadEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); // tolua_begin diff --git a/src/BlockEntities/NoteEntity.h b/src/BlockEntities/NoteEntity.h index 74dbde046..fc5f27d07 100644 --- a/src/BlockEntities/NoteEntity.h +++ b/src/BlockEntities/NoteEntity.h @@ -42,7 +42,7 @@ public: BLOCKENTITY_PROTODEF(cNoteEntity); - /// Creates a new note entity. a_World may be NULL + /// Creates a new note entity. a_World may be nullptr cNoteEntity(int a_X, int a_Y, int a_Z, cWorld * a_World); virtual ~cNoteEntity() {} diff --git a/src/BlockEntities/SignEntity.h b/src/BlockEntities/SignEntity.h index be13c7a32..52baa486d 100644 --- a/src/BlockEntities/SignEntity.h +++ b/src/BlockEntities/SignEntity.h @@ -36,7 +36,7 @@ public: BLOCKENTITY_PROTODEF(cSignEntity); - /// Creates a new empty sign entity at the specified block coords and block type (wall or standing). a_World may be NULL + /// Creates a new empty sign entity at the specified block coords and block type (wall or standing). a_World may be nullptr cSignEntity(BLOCKTYPE a_BlockType, int a_X, int a_Y, int a_Z, cWorld * a_World); // tolua_begin diff --git a/src/BlockInfo.cpp b/src/BlockInfo.cpp index bdd3a9c26..bcab21e77 100644 --- a/src/BlockInfo.cpp +++ b/src/BlockInfo.cpp @@ -9,7 +9,7 @@ cBlockInfo::~cBlockInfo() { delete m_Handler; - m_Handler = NULL; + m_Handler = nullptr; } @@ -17,7 +17,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) { for (unsigned int i = 0; i < 256; ++i) { - if (a_Info[i].m_Handler == NULL) + if (a_Info[i].m_Handler == nullptr) { a_Info[i].m_Handler = cBlockHandler::CreateBlockHandler((BLOCKTYPE) i); } diff --git a/src/BlockInfo.h b/src/BlockInfo.h index 1e4cf2ca0..4709f2357 100644 --- a/src/BlockInfo.h +++ b/src/BlockInfo.h @@ -102,7 +102,7 @@ protected: , m_FullyOccupiesVoxel(false) , m_CanBeTerraformed(false) , m_PlaceSound("") - , m_Handler(NULL) + , m_Handler(nullptr) {} /** Cleans up the stored values */ diff --git a/src/Blocks/BlockDirt.h b/src/Blocks/BlockDirt.h index 89dfc963d..aae6719e2 100644 --- a/src/Blocks/BlockDirt.h +++ b/src/Blocks/BlockDirt.h @@ -72,7 +72,7 @@ public: int BlockY = a_RelY + OfsY; int BlockZ = a_RelZ + OfsZ; cChunk * Chunk = a_Chunk.GetRelNeighborChunkAdjustCoords(BlockX, BlockZ); - if (Chunk == NULL) + if (Chunk == nullptr) { // Unloaded chunk continue; diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index b6ef5dd6f..60f13a747 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -99,9 +99,9 @@ public: for (BLOCKTYPE Type = 0; Type < E_BLOCK_MAX_TYPE_ID; Type++) { cBlockHandler * Handler = cBlockInfo::GetHandler(Type); - if (Handler == NULL) + if (Handler == nullptr) { - printf("NULL handler for block type %d!\n", Type); + printf("nullptr handler for block type %d!\n", Type); continue; } AString BlockName = ItemTypeToString(Type); @@ -441,7 +441,7 @@ void cBlockHandler::DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterfac if (a_CanDrop) { - if ((a_Digger != NULL) && (a_Digger->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchSilkTouch) > 0)) + if ((a_Digger != nullptr) && (a_Digger->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchSilkTouch) > 0)) { switch (m_BlockType) { @@ -562,7 +562,7 @@ void cBlockHandler::Check(cChunkInterface & a_ChunkInterface, cBlockPluginInterf { int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width; int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width; - DropBlock(a_ChunkInterface, *a_Chunk.GetWorld(), a_PluginInterface, NULL, BlockX, a_RelY, BlockZ); + DropBlock(a_ChunkInterface, *a_Chunk.GetWorld(), a_PluginInterface, nullptr, BlockX, a_RelY, BlockZ); } a_Chunk.SetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_AIR, 0); diff --git a/src/Blocks/BlockHandler.h b/src/Blocks/BlockHandler.h index 83de836cb..f2298afb5 100644 --- a/src/Blocks/BlockHandler.h +++ b/src/Blocks/BlockHandler.h @@ -78,7 +78,7 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta); /** Handles the dropping, but not destruction, of a block based on what ConvertTo(Verbatim)Pickups() returns, including the spawning of pickups and alertion of plugins - @param a_Digger The entity causing the drop; it may be NULL + @param a_Digger The entity causing the drop; it may be nullptr @param a_CanDrop Informs the handler whether the block should be dropped at all. One example when this is false is when stone is destroyed by hand @param a_DropVerbatim Calls ConvertToVerbatimPickups() instead of its counterpart, meaning the block itself is dropped by default (due to a speical tool or enchantment) */ diff --git a/src/Blocks/BlockLeaves.h b/src/Blocks/BlockLeaves.h index add571675..bd9a7414e 100644 --- a/src/Blocks/BlockLeaves.h +++ b/src/Blocks/BlockLeaves.h @@ -109,7 +109,7 @@ public: } // Decay the leaves: - DropBlock(a_ChunkInterface, a_WorldInterface, a_PluginInterface, NULL, BlockX, a_RelY, BlockZ); + DropBlock(a_ChunkInterface, a_WorldInterface, a_PluginInterface, nullptr, BlockX, a_RelY, BlockZ); a_ChunkInterface.DigBlock(a_WorldInterface, BlockX, a_RelY, BlockZ); } } ; diff --git a/src/Blocks/BlockPiston.cpp b/src/Blocks/BlockPiston.cpp index 34d11f675..8d245cabe 100644 --- a/src/Blocks/BlockPiston.cpp +++ b/src/Blocks/BlockPiston.cpp @@ -139,7 +139,7 @@ void cBlockPistonHandler::ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ, { cChunkInterface ChunkInterface(a_World->GetChunkMap()); cBlockInServerPluginInterface PluginInterface(*a_World); - Handler->DropBlock(ChunkInterface, *a_World, PluginInterface, NULL, a_BlockX, a_BlockY, a_BlockZ); + Handler->DropBlock(ChunkInterface, *a_World, PluginInterface, nullptr, a_BlockX, a_BlockY, a_BlockZ); } } diff --git a/src/Blocks/BlockVine.h b/src/Blocks/BlockVine.h index 213324cc1..04021bc47 100644 --- a/src/Blocks/BlockVine.h +++ b/src/Blocks/BlockVine.h @@ -138,7 +138,7 @@ public: { int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width; int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width; - DropBlock(a_ChunkInterface, *a_Chunk.GetWorld(), a_PluginInterface, NULL, BlockX, a_RelY, BlockZ); + DropBlock(a_ChunkInterface, *a_Chunk.GetWorld(), a_PluginInterface, nullptr, BlockX, a_RelY, BlockZ); } a_Chunk.SetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_AIR, 0); return; diff --git a/src/Blocks/BroadcastInterface.h b/src/Blocks/BroadcastInterface.h index cf332b153..bf464627d 100644 --- a/src/Blocks/BroadcastInterface.h +++ b/src/Blocks/BroadcastInterface.h @@ -7,6 +7,6 @@ public: virtual ~cBroadcastInterface() {} virtual void BroadcastUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) = 0; - virtual void BroadcastSoundEffect(const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = NULL) = 0; - virtual void BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = NULL) = 0; + virtual void BroadcastSoundEffect(const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = nullptr) = 0; + virtual void BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = nullptr) = 0; }; diff --git a/src/ByteBuffer.cpp b/src/ByteBuffer.cpp index d03b6bbe4..6406a2625 100644 --- a/src/ByteBuffer.cpp +++ b/src/ByteBuffer.cpp @@ -131,7 +131,7 @@ cByteBuffer::~cByteBuffer() { CheckValid(); delete[] m_Buffer; - m_Buffer = NULL; + m_Buffer = nullptr; } diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 2a835a43d..f70393bb8 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -94,19 +94,19 @@ cChunk::cChunk( m_RedstoneSimulatorData(a_World->GetRedstoneSimulator()->CreateChunkData()), m_AlwaysTicked(0) { - if (a_NeighborXM != NULL) + if (a_NeighborXM != nullptr) { a_NeighborXM->m_NeighborXP = this; } - if (a_NeighborXP != NULL) + if (a_NeighborXP != nullptr) { a_NeighborXP->m_NeighborXM = this; } - if (a_NeighborZM != NULL) + if (a_NeighborZM != nullptr) { a_NeighborZM->m_NeighborZP = this; } - if (a_NeighborZP != NULL) + if (a_NeighborZP != nullptr) { a_NeighborZP->m_NeighborZM = this; } @@ -140,28 +140,28 @@ cChunk::~cChunk() } } - if (m_NeighborXM != NULL) + if (m_NeighborXM != nullptr) { - m_NeighborXM->m_NeighborXP = NULL; + m_NeighborXM->m_NeighborXP = nullptr; } - if (m_NeighborXP != NULL) + if (m_NeighborXP != nullptr) { - m_NeighborXP->m_NeighborXM = NULL; + m_NeighborXP->m_NeighborXM = nullptr; } - if (m_NeighborZM != NULL) + if (m_NeighborZM != nullptr) { - m_NeighborZM->m_NeighborZP = NULL; + m_NeighborZM->m_NeighborZP = nullptr; } - if (m_NeighborZP != NULL) + if (m_NeighborZP != nullptr) { - m_NeighborZP->m_NeighborZM = NULL; + m_NeighborZP->m_NeighborZM = nullptr; } delete m_WaterSimulatorData; - m_WaterSimulatorData = NULL; + m_WaterSimulatorData = nullptr; delete m_LavaSimulatorData; - m_LavaSimulatorData = NULL; + m_LavaSimulatorData = nullptr; delete m_RedstoneSimulatorData; - m_RedstoneSimulatorData = NULL; + m_RedstoneSimulatorData = nullptr; } @@ -580,7 +580,7 @@ void cChunk::SpawnMobs(cMobSpawner& a_MobSpawner) } cEntity * newMob = a_MobSpawner.TryToSpawnHere(this, TryX, TryY, TryZ, Biome, MaxNbOfSuccess); - if (newMob == NULL) + if (newMob == nullptr) { continue; } @@ -638,7 +638,7 @@ void cChunk::Tick(float a_Dt) { // Remove all entities that are travelling to another world MarkDirty(); - (*itr)->SetWorldTravellingFrom(NULL); + (*itr)->SetWorldTravellingFrom(nullptr); itr = m_Entities.erase(itr); } else if ( @@ -667,7 +667,7 @@ void cChunk::Tick(float a_Dt) void cChunk::TickBlock(int a_RelX, int a_RelY, int a_RelZ) { cBlockHandler * Handler = BlockHandler(GetBlock(a_RelX, a_RelY, a_RelZ)); - ASSERT(Handler != NULL); // Happenned on server restart, FS #243 + ASSERT(Handler != nullptr); // Happenned on server restart, FS #243 cChunkInterface ChunkInterface(this->GetWorld()->GetChunkMap()); cBlockInServerPluginInterface PluginInterface(*this->GetWorld()); Handler->OnUpdate(ChunkInterface, *this->GetWorld(), PluginInterface, *this, a_RelX, a_RelY, a_RelZ); @@ -680,10 +680,10 @@ void cChunk::TickBlock(int a_RelX, int a_RelY, int a_RelZ) void cChunk::MoveEntityToNewChunk(cEntity * a_Entity) { cChunk * Neighbor = GetNeighborChunk(a_Entity->GetChunkX() * cChunkDef::Width, a_Entity->GetChunkZ() * cChunkDef::Width); - if (Neighbor == NULL) + if (Neighbor == nullptr) { Neighbor = m_ChunkMap->GetChunkNoLoad(a_Entity->GetChunkX(), a_Entity->GetChunkZ()); - if (Neighbor == NULL) + if (Neighbor == nullptr) { // TODO: What to do with this? LOGWARNING("%s: Failed to move entity, destination chunk unreachable. Entity lost", __FUNCTION__); @@ -846,7 +846,7 @@ void cChunk::TickBlocks(void) } cBlockHandler * Handler = BlockHandler(GetBlock(m_BlockTickX, m_BlockTickY, m_BlockTickZ)); - ASSERT(Handler != NULL); // Happenned on server restart, FS #243 + ASSERT(Handler != nullptr); // Happenned on server restart, FS #243 Handler->OnUpdate(ChunkInterface, *this->GetWorld(), PluginInterface, *this, m_BlockTickX, m_BlockTickY, m_BlockTickZ); } // for i - tickblocks } @@ -1126,7 +1126,7 @@ bool cChunk::UnboundedRelGetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE return false; } cChunk * Chunk = GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { // The chunk is not available, bail out return false; @@ -1147,7 +1147,7 @@ bool cChunk::UnboundedRelGetBlockType(int a_RelX, int a_RelY, int a_RelZ, BLOCKT return false; } cChunk * Chunk = GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { // The chunk is not available, bail out return false; @@ -1168,7 +1168,7 @@ bool cChunk::UnboundedRelGetBlockMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLE return false; } cChunk * Chunk = GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { // The chunk is not available, bail out return false; @@ -1189,7 +1189,7 @@ bool cChunk::UnboundedRelGetBlockBlockLight(int a_RelX, int a_RelY, int a_RelZ, return false; } cChunk * Chunk = GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { // The chunk is not available, bail out return false; @@ -1210,7 +1210,7 @@ bool cChunk::UnboundedRelGetBlockSkyLight(int a_RelX, int a_RelY, int a_RelZ, NI return false; } cChunk * Chunk = GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { // The chunk is not available, bail out return false; @@ -1231,7 +1231,7 @@ bool cChunk::UnboundedRelGetBlockLights(int a_RelX, int a_RelY, int a_RelZ, NIBB return false; } cChunk * Chunk = GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { // The chunk is not available, bail out return false; @@ -1253,7 +1253,7 @@ bool cChunk::UnboundedRelSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE return false; } cChunk * Chunk = GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { // The chunk is not available, bail out return false; @@ -1274,7 +1274,7 @@ bool cChunk::UnboundedRelFastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKT return false; } cChunk * Chunk = GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { // The chunk is not available, bail out return false; @@ -1295,7 +1295,7 @@ void cChunk::UnboundedQueueTickBlock(int a_RelX, int a_RelY, int a_RelZ) return; } cChunk * Chunk = GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ); - if ((Chunk != NULL) && Chunk->IsValid()) + if ((Chunk != nullptr) && Chunk->IsValid()) { Chunk->QueueTickBlock(a_RelX, a_RelY, a_RelZ); } @@ -1451,12 +1451,12 @@ void cChunk::SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, // If there was a block entity, remove it: Vector3i WorldPos = PositionToWorldPosition(a_RelX, a_RelY, a_RelZ); cBlockEntity * BlockEntity = GetBlockEntity(WorldPos); - if (BlockEntity != NULL) + if (BlockEntity != nullptr) { BlockEntity->Destroy(); RemoveBlockEntity(BlockEntity); delete BlockEntity; - BlockEntity = NULL; + BlockEntity = nullptr; } // If the new block is a block entity, create the entity object: @@ -1618,7 +1618,7 @@ void cChunk::FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockT void cChunk::SendBlockTo(int a_RelX, int a_RelY, int a_RelZ, cClientHandle * a_Client) { - if (a_Client == NULL) + if (a_Client == nullptr) { // Queue the block for all clients in the chunk (will be sent in Tick()) m_PendingSendBlocks.push_back(sSetBlock(m_PosX, m_PosZ, a_RelX, a_RelY, a_RelZ, GetBlock(a_RelX, a_RelY, a_RelZ), GetMeta(a_RelX, a_RelY, a_RelZ))); @@ -1672,7 +1672,7 @@ cBlockEntity * cChunk::GetBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ) } } // for itr - m_BlockEntities[] - return NULL; + return nullptr; } @@ -1707,7 +1707,7 @@ void cChunk::SetAlwaysTicked(bool a_AlwaysTicked) void cChunk::UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z) { cBlockEntity * be = GetBlockEntity(a_X, a_Y, a_Z); - if (be != NULL) + if (be != nullptr) { be->UsedBy(a_Player); } @@ -2663,10 +2663,10 @@ cChunk * cChunk::GetRelNeighborChunk(int a_RelX, int a_RelZ) bool ReturnThis = true; if (a_RelX < 0) { - if (m_NeighborXM != NULL) + if (m_NeighborXM != nullptr) { cChunk * Candidate = m_NeighborXM->GetRelNeighborChunk(a_RelX + cChunkDef::Width, a_RelZ); - if (Candidate != NULL) + if (Candidate != nullptr) { return Candidate; } @@ -2676,10 +2676,10 @@ cChunk * cChunk::GetRelNeighborChunk(int a_RelX, int a_RelZ) } else if (a_RelX >= cChunkDef::Width) { - if (m_NeighborXP != NULL) + if (m_NeighborXP != nullptr) { cChunk * Candidate = m_NeighborXP->GetRelNeighborChunk(a_RelX - cChunkDef::Width, a_RelZ); - if (Candidate != NULL) + if (Candidate != nullptr) { return Candidate; } @@ -2690,24 +2690,24 @@ cChunk * cChunk::GetRelNeighborChunk(int a_RelX, int a_RelZ) if (a_RelZ < 0) { - if (m_NeighborZM != NULL) + if (m_NeighborZM != nullptr) { return m_NeighborZM->GetRelNeighborChunk(a_RelX, a_RelZ + cChunkDef::Width); // For requests crossing both X and Z, the X-first way has been already tried } - return NULL; + return nullptr; } else if (a_RelZ >= cChunkDef::Width) { - if (m_NeighborZP != NULL) + if (m_NeighborZP != nullptr) { return m_NeighborZP->GetRelNeighborChunk(a_RelX, a_RelZ - cChunkDef::Width); // For requests crossing both X and Z, the X-first way has been already tried } - return NULL; + return nullptr; } - return (ReturnThis ? this : NULL); + return (ReturnThis ? this : nullptr); } @@ -2730,27 +2730,27 @@ cChunk * cChunk::GetRelNeighborChunkAdjustCoords(int & a_RelX, int & a_RelZ) con // Request for a different chunk, calculate chunk offset: int RelX = a_RelX; // Make a local copy of the coords (faster access) int RelZ = a_RelZ; - while ((RelX >= Width) && (ToReturn != NULL)) + while ((RelX >= Width) && (ToReturn != nullptr)) { RelX -= Width; ToReturn = ToReturn->m_NeighborXP; } - while ((RelX < 0) && (ToReturn != NULL)) + while ((RelX < 0) && (ToReturn != nullptr)) { RelX += Width; ToReturn = ToReturn->m_NeighborXM; } - while ((RelZ >= Width) && (ToReturn != NULL)) + while ((RelZ >= Width) && (ToReturn != nullptr)) { RelZ -= Width; ToReturn = ToReturn->m_NeighborZP; } - while ((RelZ < 0) && (ToReturn != NULL)) + while ((RelZ < 0) && (ToReturn != nullptr)) { RelZ += Width; ToReturn = ToReturn->m_NeighborZM; } - if (ToReturn != NULL) + if (ToReturn != nullptr) { a_RelX = RelX; a_RelZ = RelZ; @@ -2820,7 +2820,7 @@ void cChunk::BroadcastBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cons { // We can operate on entity pointers, we're inside the ChunkMap's CS lock which guards the list cBlockEntity * Entity = GetBlockEntity(a_BlockX, a_BlockY, a_BlockZ); - if (Entity == NULL) + if (Entity == nullptr) { return; } @@ -3157,7 +3157,7 @@ void cChunk::BroadcastUseBed(const cEntity & a_Entity, int a_BlockX, int a_Block void cChunk::SendBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cClientHandle & a_Client) { cBlockEntity * Entity = GetBlockEntity(a_BlockX, a_BlockY, a_BlockZ); - if (Entity == NULL) + if (Entity == nullptr) { return; } diff --git a/src/Chunk.h b/src/Chunk.h index 5f8fcaf7b..6f4ac5cac 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -190,13 +190,13 @@ public: void GetBlockInfo (int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_Meta, NIBBLETYPE & a_SkyLight, NIBBLETYPE & a_BlockLight); /** Returns the chunk into which the specified block belongs, by walking the neighbors. - Will return self if appropriate. Returns NULL if not reachable through neighbors. + Will return self if appropriate. Returns nullptr if not reachable through neighbors. */ cChunk * GetNeighborChunk(int a_BlockX, int a_BlockZ); /** Returns the chunk into which the relatively-specified block belongs, by walking the neighbors. - Will return self if appropriate. Returns NULL if not reachable through neighbors. + Will return self if appropriate. Returns nullptr if not reachable through neighbors. */ cChunk * GetRelNeighborChunk(int a_RelX, int a_RelZ); @@ -316,28 +316,28 @@ public: // Broadcast various packets to all clients of this chunk: // (Please keep these alpha-sorted) void BroadcastAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle); - void BroadcastBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType, const cClientHandle * a_Exclude = NULL); - void BroadcastBlockBreakAnimation(int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage, const cClientHandle * a_Exclude = NULL); - void BroadcastBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = NULL); - void BroadcastChunkData (cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = NULL); - void BroadcastCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL); - void BroadcastDestroyEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityHeadLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityMetadata (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityStatus (const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityVelocity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityAnimation (const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = NULL); - void BroadcastParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount, cClientHandle * a_Exclude = NULL); - void BroadcastRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude = NULL); - void BroadcastSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = NULL); - void BroadcastSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data, const cClientHandle * a_Exclude = NULL); - void BroadcastSpawnEntity (cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); - void BroadcastThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = NULL); + void BroadcastBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType, const cClientHandle * a_Exclude = nullptr); + void BroadcastBlockBreakAnimation(int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage, const cClientHandle * a_Exclude = nullptr); + void BroadcastBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = nullptr); + void BroadcastChunkData (cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = nullptr); + void BroadcastCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player, const cClientHandle * a_Exclude = nullptr); + void BroadcastDestroyEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr); + void BroadcastEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude = nullptr); + void BroadcastEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude = nullptr); + void BroadcastEntityHeadLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr); + void BroadcastEntityLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr); + void BroadcastEntityMetadata (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr); + void BroadcastEntityRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = nullptr); + void BroadcastEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = nullptr); + void BroadcastEntityStatus (const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude = nullptr); + void BroadcastEntityVelocity (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr); + void BroadcastEntityAnimation (const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = nullptr); + void BroadcastParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount, cClientHandle * a_Exclude = nullptr); + void BroadcastRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude = nullptr); + void BroadcastSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = nullptr); + void BroadcastSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data, const cClientHandle * a_Exclude = nullptr); + void BroadcastSpawnEntity (cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr); + void BroadcastThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = nullptr); void BroadcastUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ); void SendBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, cClientHandle & a_Client); diff --git a/src/ChunkData.cpp b/src/ChunkData.cpp index 03b0224a6..57b27c5e0 100644 --- a/src/ChunkData.cpp +++ b/src/ChunkData.cpp @@ -36,7 +36,7 @@ cChunkData::cChunkData(cAllocationPool & a_Pool) : { for (size_t i = 0; i < NumSections; i++) { - m_Sections[i] = NULL; + m_Sections[i] = nullptr; } } @@ -56,7 +56,7 @@ cChunkData::~cChunkData() for (size_t i = 0; i < NumSections; i++) { Free(m_Sections[i]); - m_Sections[i] = NULL; + m_Sections[i] = nullptr; } } @@ -96,7 +96,7 @@ cChunkData::~cChunkData() for (size_t i = 0; i < NumSections; i++) { Free(m_Sections[i]); - m_Sections[i] = NULL; + m_Sections[i] = nullptr; } } @@ -120,7 +120,7 @@ cChunkData::~cChunkData() for (size_t i = 0; i < NumSections; i++) { m_Sections[i] = other.m_Sections[i]; - other.m_Sections[i] = NULL; + other.m_Sections[i] = nullptr; } } @@ -137,7 +137,7 @@ cChunkData::~cChunkData() { Free(m_Sections[i]); m_Sections[i] = other.m_Sections[i]; - other.m_Sections[i] = NULL; + other.m_Sections[i] = nullptr; } } return *this; @@ -154,7 +154,7 @@ BLOCKTYPE cChunkData::GetBlock(int a_X, int a_Y, int a_Z) const ASSERT((a_Y >= 0) && (a_Y < cChunkDef::Height)); ASSERT((a_Z >= 0) && (a_Z < cChunkDef::Width)); int Section = a_Y / SectionHeight; - if (m_Sections[Section] != NULL) + if (m_Sections[Section] != nullptr) { int Index = cChunkDef::MakeIndexNoCheck(a_X, a_Y - (Section * SectionHeight), a_Z); return m_Sections[Section]->m_BlockTypes[Index]; @@ -182,14 +182,14 @@ void cChunkData::SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_Block) } int Section = a_RelY / SectionHeight; - if (m_Sections[Section] == NULL) + if (m_Sections[Section] == nullptr) { if (a_Block == 0x00) { return; } m_Sections[Section] = Allocate(); - if (m_Sections[Section] == NULL) + if (m_Sections[Section] == nullptr) { ASSERT(!"Failed to allocate a new section in Chunkbuffer"); return; @@ -212,7 +212,7 @@ NIBBLETYPE cChunkData::GetMeta(int a_RelX, int a_RelY, int a_RelZ) const (a_RelZ < cChunkDef::Width) && (a_RelZ > -1)) { int Section = a_RelY / SectionHeight; - if (m_Sections[Section] != NULL) + if (m_Sections[Section] != nullptr) { int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * SectionHeight), a_RelZ); return (m_Sections[Section]->m_BlockMetas[Index / 2] >> ((Index & 1) * 4)) & 0x0f; @@ -243,14 +243,14 @@ bool cChunkData::SetMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Nibble } int Section = a_RelY / SectionHeight; - if (m_Sections[Section] == NULL) + if (m_Sections[Section] == nullptr) { if ((a_Nibble & 0xf) == 0x00) { return false; } m_Sections[Section] = Allocate(); - if (m_Sections[Section] == NULL) + if (m_Sections[Section] == nullptr) { ASSERT(!"Failed to allocate a new section in Chunkbuffer"); return false; @@ -279,7 +279,7 @@ NIBBLETYPE cChunkData::GetBlockLight(int a_RelX, int a_RelY, int a_RelZ) const ) { int Section = a_RelY / SectionHeight; - if (m_Sections[Section] != NULL) + if (m_Sections[Section] != nullptr) { int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * SectionHeight), a_RelZ); return (m_Sections[Section]->m_BlockLight[Index / 2] >> ((Index & 1) * 4)) & 0x0f; @@ -302,7 +302,7 @@ NIBBLETYPE cChunkData::GetSkyLight(int a_RelX, int a_RelY, int a_RelZ) const if ((a_RelX < cChunkDef::Width) && (a_RelX > -1) && (a_RelY < cChunkDef::Height) && (a_RelY > -1) && (a_RelZ < cChunkDef::Width) && (a_RelZ > -1)) { int Section = a_RelY / SectionHeight; - if (m_Sections[Section] != NULL) + if (m_Sections[Section] != nullptr) { int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * SectionHeight), a_RelZ); return (m_Sections[Section]->m_BlockSkyLight[Index / 2] >> ((Index & 1) * 4)) & 0x0f; @@ -325,7 +325,7 @@ cChunkData cChunkData::Copy(void) const cChunkData copy(m_Pool); for (size_t i = 0; i < NumSections; i++) { - if (m_Sections[i] != NULL) + if (m_Sections[i] != nullptr) { copy.m_Sections[i] = copy.Allocate(); *copy.m_Sections[i] = *m_Sections[i]; @@ -354,7 +354,7 @@ void cChunkData::CopyBlockTypes(BLOCKTYPE * a_Dest, size_t a_Idx, size_t a_Lengt { size_t ToCopy = std::min(+SectionBlockCount - StartPos, a_Length); a_Length -= ToCopy; - if (m_Sections[i] != NULL) + if (m_Sections[i] != nullptr) { BLOCKTYPE * blockbuffer = m_Sections[i]->m_BlockTypes; memcpy(&a_Dest[(i * SectionBlockCount) + StartPos - a_Idx], blockbuffer + StartPos, sizeof(BLOCKTYPE) * ToCopy); @@ -375,7 +375,7 @@ void cChunkData::CopyMetas(NIBBLETYPE * a_Dest) const { for (size_t i = 0; i < NumSections; i++) { - if (m_Sections[i] != NULL) + if (m_Sections[i] != nullptr) { memcpy(&a_Dest[i * SectionBlockCount / 2], &m_Sections[i]->m_BlockMetas, sizeof(m_Sections[i]->m_BlockMetas)); } @@ -394,7 +394,7 @@ void cChunkData::CopyBlockLight(NIBBLETYPE * a_Dest) const { for (size_t i = 0; i < NumSections; i++) { - if (m_Sections[i] != NULL) + if (m_Sections[i] != nullptr) { memcpy(&a_Dest[i * SectionBlockCount / 2], &m_Sections[i]->m_BlockLight, sizeof(m_Sections[i]->m_BlockLight)); } @@ -413,7 +413,7 @@ void cChunkData::CopySkyLight(NIBBLETYPE * a_Dest) const { for (size_t i = 0; i < NumSections; i++) { - if (m_Sections[i] != NULL) + if (m_Sections[i] != nullptr) { memcpy(&a_Dest[i * SectionBlockCount / 2], &m_Sections[i]->m_BlockSkyLight, sizeof(m_Sections[i]->m_BlockSkyLight)); } @@ -430,12 +430,12 @@ void cChunkData::CopySkyLight(NIBBLETYPE * a_Dest) const void cChunkData::SetBlockTypes(const BLOCKTYPE * a_Src) { - ASSERT(a_Src != NULL); + ASSERT(a_Src != nullptr); for (size_t i = 0; i < NumSections; i++) { // If the section is already allocated, copy the data into it: - if (m_Sections[i] != NULL) + if (m_Sections[i] != nullptr) { memcpy(m_Sections[i]->m_BlockTypes, &a_Src[i * SectionBlockCount], sizeof(m_Sections[i]->m_BlockTypes)); continue; @@ -462,12 +462,12 @@ void cChunkData::SetBlockTypes(const BLOCKTYPE * a_Src) void cChunkData::SetMetas(const NIBBLETYPE * a_Src) { - ASSERT(a_Src != NULL); + ASSERT(a_Src != nullptr); for (size_t i = 0; i < NumSections; i++) { // If the section is already allocated, copy the data into it: - if (m_Sections[i] != NULL) + if (m_Sections[i] != nullptr) { memcpy(m_Sections[i]->m_BlockMetas, &a_Src[i * SectionBlockCount / 2], sizeof(m_Sections[i]->m_BlockMetas)); continue; @@ -495,7 +495,7 @@ void cChunkData::SetMetas(const NIBBLETYPE * a_Src) void cChunkData::SetBlockLight(const NIBBLETYPE * a_Src) { - if (a_Src == NULL) + if (a_Src == nullptr) { return; } @@ -503,7 +503,7 @@ void cChunkData::SetBlockLight(const NIBBLETYPE * a_Src) for (size_t i = 0; i < NumSections; i++) { // If the section is already allocated, copy the data into it: - if (m_Sections[i] != NULL) + if (m_Sections[i] != nullptr) { memcpy(m_Sections[i]->m_BlockLight, &a_Src[i * SectionBlockCount / 2], sizeof(m_Sections[i]->m_BlockLight)); continue; @@ -530,7 +530,7 @@ void cChunkData::SetBlockLight(const NIBBLETYPE * a_Src) void cChunkData::SetSkyLight(const NIBBLETYPE * a_Src) { - if (a_Src == NULL) + if (a_Src == nullptr) { return; } @@ -538,7 +538,7 @@ void cChunkData::SetSkyLight(const NIBBLETYPE * a_Src) for (size_t i = 0; i < NumSections; i++) { // If the section is already allocated, copy the data into it: - if (m_Sections[i] != NULL) + if (m_Sections[i] != nullptr) { memcpy(m_Sections[i]->m_BlockSkyLight, &a_Src[i * SectionBlockCount / 2], sizeof(m_Sections[i]->m_BlockSkyLight)); continue; diff --git a/src/ChunkData.h b/src/ChunkData.h index fe8b068a2..2ab629b29 100644 --- a/src/ChunkData.h +++ b/src/ChunkData.h @@ -88,12 +88,12 @@ public: /** Copies the blocklight data from the specified flat array into the internal representation. Allocates sectios that are needed for the operation. - Allows a_Src to be NULL, in which case it doesn't do anything. */ + Allows a_Src to be nullptr, in which case it doesn't do anything. */ void SetBlockLight(const NIBBLETYPE * a_Src); /** Copies the skylight data from the specified flat array into the internal representation. Allocates sectios that are needed for the operation. - Allows a_Src to be NULL, in which case it doesn't do anything. */ + Allows a_Src to be nullptr, in which case it doesn't do anything. */ void SetSkyLight(const NIBBLETYPE * a_Src); struct sChunkSection @@ -118,7 +118,7 @@ private: sChunkSection * Allocate(void); /** Frees the specified section, previously allocated using Allocate(). - Note that a_Section may be NULL. */ + Note that a_Section may be nullptr. */ void Free(sChunkSection * a_Section); /** Sets the data in the specified section to their default values. */ diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 6f56b23e0..595040a54 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -88,10 +88,10 @@ cChunkMap::cChunkLayer * cChunkMap::GetLayer(int a_LayerX, int a_LayerZ) // Not found, create new: cChunkLayer * Layer = new cChunkLayer(a_LayerX, a_LayerZ, this, *m_Pool); - if (Layer == NULL) + if (Layer == nullptr) { LOGERROR("cChunkMap: Cannot create new layer, server out of memory?"); - return NULL; + return nullptr; } m_Layers.push_back(Layer); return Layer; @@ -125,7 +125,7 @@ cChunkMap::cChunkLayer * cChunkMap::FindLayer(int a_LayerX, int a_LayerZ) } // for itr - m_Layers[] // Not found - return NULL; + return nullptr; } @@ -148,16 +148,16 @@ cChunkPtr cChunkMap::GetChunk(int a_ChunkX, int a_ChunkZ) ASSERT(m_CSLayers.IsLockedByCurrentThread()); // m_CSLayers should already be locked by the operation that called us cChunkLayer * Layer = GetLayerForChunk(a_ChunkX, a_ChunkZ); - if (Layer == NULL) + if (Layer == nullptr) { // An error must have occurred, since layers are automatically created if they don't exist - return NULL; + return nullptr; } cChunkPtr Chunk = Layer->GetChunk(a_ChunkX, a_ChunkZ); - if (Chunk == NULL) + if (Chunk == nullptr) { - return NULL; + return nullptr; } if (!Chunk->IsValid() && !Chunk->IsQueued()) { @@ -177,16 +177,16 @@ cChunkPtr cChunkMap::GetChunkNoGen(int a_ChunkX, int a_ChunkZ) ASSERT(m_CSLayers.IsLockedByCurrentThread()); // m_CSLayers should already be locked by the operation that called us cChunkLayer * Layer = GetLayerForChunk(a_ChunkX, a_ChunkZ); - if (Layer == NULL) + if (Layer == nullptr) { // An error must have occurred, since layers are automatically created if they don't exist - return NULL; + return nullptr; } cChunkPtr Chunk = Layer->GetChunk(a_ChunkX, a_ChunkZ); - if (Chunk == NULL) + if (Chunk == nullptr) { - return NULL; + return nullptr; } if (!Chunk->IsValid() && !Chunk->IsQueued()) { @@ -206,10 +206,10 @@ cChunkPtr cChunkMap::GetChunkNoLoad( int a_ChunkX, int a_ChunkZ) ASSERT(m_CSLayers.IsLockedByCurrentThread()); // m_CSLayers should already be locked by the operation that called us cChunkLayer * Layer = GetLayerForChunk( a_ChunkX, a_ChunkZ); - if (Layer == NULL) + if (Layer == nullptr) { // An error must have occurred, since layers are automatically created if they don't exist - return NULL; + return nullptr; } return Layer->GetChunk(a_ChunkX, a_ChunkZ); @@ -227,7 +227,7 @@ bool cChunkMap::LockedGetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTY int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); - if (Chunk == NULL) + if (Chunk == nullptr) { return false; } @@ -249,7 +249,7 @@ bool cChunkMap::LockedGetBlockType(int a_BlockX, int a_BlockY, int a_BlockZ, BLO int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); - if (Chunk == NULL) + if (Chunk == nullptr) { return false; } @@ -270,7 +270,7 @@ bool cChunkMap::LockedGetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIB int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); - if (Chunk == NULL) + if (Chunk == nullptr) { return false; } @@ -289,7 +289,7 @@ bool cChunkMap::LockedSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTY int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); - if (Chunk == NULL) + if (Chunk == nullptr) { return false; } @@ -308,7 +308,7 @@ bool cChunkMap::LockedFastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLO int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); - if (Chunk == NULL) + if (Chunk == nullptr) { return false; } @@ -326,9 +326,9 @@ cChunk * cChunkMap::FindChunk(int a_ChunkX, int a_ChunkZ) ASSERT(m_CSLayers.IsLockedByCurrentThread()); cChunkLayer * Layer = FindLayerForChunk(a_ChunkX, a_ChunkZ); - if (Layer == NULL) + if (Layer == nullptr) { - return NULL; + return nullptr; } return Layer->FindChunk(a_ChunkX, a_ChunkZ); } @@ -341,7 +341,7 @@ void cChunkMap::BroadcastAttachEntity(const cEntity & a_Entity, const cEntity * { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); - if (Chunk == NULL) + if (Chunk == nullptr) { return; } @@ -361,7 +361,7 @@ void cChunkMap::BroadcastBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, c z = a_BlockZ; cChunkDef::BlockToChunk(x, z, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); - if (Chunk == NULL) + if (Chunk == nullptr) { return; } @@ -380,7 +380,7 @@ void cChunkMap::BroadcastBlockBreakAnimation(int a_entityID, int a_blockX, int a cChunkDef::BlockToChunk(a_blockX, a_blockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); - if (Chunk == NULL) + if (Chunk == nullptr) { return; } @@ -398,7 +398,7 @@ void cChunkMap::BroadcastBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, c int ChunkX, ChunkZ; cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { return; } @@ -413,7 +413,7 @@ void cChunkMap::BroadcastChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSeriali { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); - if (Chunk == NULL) + if (Chunk == nullptr) { return; } @@ -429,7 +429,7 @@ void cChunkMap::BroadcastCollectEntity(const cEntity & a_Entity, const cPlayer & { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); - if (Chunk == NULL) + if (Chunk == nullptr) { return; } @@ -445,7 +445,7 @@ void cChunkMap::BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHa { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); - if (Chunk == NULL) + if (Chunk == nullptr) { return; } @@ -461,7 +461,7 @@ void cChunkMap::BroadcastEntityEffect(const cEntity & a_Entity, int a_EffectID, { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); - if (Chunk == NULL) + if (Chunk == nullptr) { return; } @@ -477,7 +477,7 @@ void cChunkMap::BroadcastEntityEquipment(const cEntity & a_Entity, short a_SlotN { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); - if (Chunk == NULL) + if (Chunk == nullptr) { return; } @@ -493,7 +493,7 @@ void cChunkMap::BroadcastEntityHeadLook(const cEntity & a_Entity, const cClientH { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); - if (Chunk == NULL) + if (Chunk == nullptr) { return; } @@ -509,7 +509,7 @@ void cChunkMap::BroadcastEntityLook(const cEntity & a_Entity, const cClientHandl { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); - if (Chunk == NULL) + if (Chunk == nullptr) { return; } @@ -525,7 +525,7 @@ void cChunkMap::BroadcastEntityMetadata(const cEntity & a_Entity, const cClientH { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); - if (Chunk == NULL) + if (Chunk == nullptr) { return; } @@ -541,7 +541,7 @@ void cChunkMap::BroadcastEntityRelMove(const cEntity & a_Entity, char a_RelX, ch { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); - if (Chunk == NULL) + if (Chunk == nullptr) { return; } @@ -557,7 +557,7 @@ void cChunkMap::BroadcastEntityRelMoveLook(const cEntity & a_Entity, char a_RelX { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); - if (Chunk == NULL) + if (Chunk == nullptr) { return; } @@ -573,7 +573,7 @@ void cChunkMap::BroadcastEntityStatus(const cEntity & a_Entity, char a_Status, c { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); - if (Chunk == NULL) + if (Chunk == nullptr) { return; } @@ -589,7 +589,7 @@ void cChunkMap::BroadcastEntityVelocity(const cEntity & a_Entity, const cClientH { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); - if (Chunk == NULL) + if (Chunk == nullptr) { return; } @@ -605,7 +605,7 @@ void cChunkMap::BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animat { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); - if (Chunk == NULL) + if (Chunk == nullptr) { return; } @@ -624,7 +624,7 @@ void cChunkMap::BroadcastParticleEffect(const AString & a_ParticleName, float a_ cChunkDef::BlockToChunk((int) a_SrcX, (int) a_SrcZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); - if (Chunk == NULL) + if (Chunk == nullptr) { return; } @@ -641,7 +641,7 @@ void cChunkMap::BroadcastRemoveEntityEffect(const cEntity & a_Entity, int a_Effe cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); - if (Chunk == NULL) + if (Chunk == nullptr) { return; } @@ -660,7 +660,7 @@ void cChunkMap::BroadcastSoundEffect(const AString & a_SoundName, double a_X, do cChunkDef::BlockToChunk((int)std::floor(a_X), (int)std::floor(a_Z), ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); - if (Chunk == NULL) + if (Chunk == nullptr) { return; } @@ -679,7 +679,7 @@ void cChunkMap::BroadcastSoundParticleEffect(int a_EffectID, int a_SrcX, int a_S cChunkDef::BlockToChunk(a_SrcX, a_SrcZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); - if (Chunk == NULL) + if (Chunk == nullptr) { return; } @@ -695,7 +695,7 @@ void cChunkMap::BroadcastSpawnEntity(cEntity & a_Entity, const cClientHandle * a { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); - if (Chunk == NULL) + if (Chunk == nullptr) { return; } @@ -713,7 +713,7 @@ void cChunkMap::BroadcastThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ, c int ChunkX, ChunkZ; cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); - if (Chunk == NULL) + if (Chunk == nullptr) { return; } @@ -732,7 +732,7 @@ void cChunkMap::BroadcastUseBed(const cEntity & a_Entity, int a_BlockX, int a_Bl cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); - if (Chunk == NULL) + if (Chunk == nullptr) { return; } @@ -750,7 +750,7 @@ void cChunkMap::SendBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cClien int ChunkX, ChunkZ; cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { return; } @@ -768,7 +768,7 @@ void cChunkMap::UseBlockEntity(cPlayer * a_Player, int a_BlockX, int a_BlockY, i int ChunkX, ChunkZ; cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { return; } @@ -783,7 +783,7 @@ bool cChunkMap::DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback & a_Callb { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkZ); - if (Chunk == NULL) + if (Chunk == nullptr) { return false; } @@ -800,7 +800,7 @@ void cChunkMap::WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ) int ChunkX, ChunkZ; cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { return; } @@ -829,7 +829,7 @@ void cChunkMap::WakeUpSimulatorsInArea(int a_MinBlockX, int a_MaxBlockX, int a_M for (int x = MinChunkX; x <= MaxChunkX; x++) { cChunkPtr Chunk = GetChunkNoGen(x, z); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { continue; } @@ -857,7 +857,7 @@ void cChunkMap::MarkRedstoneDirty(int a_ChunkX, int a_ChunkZ) { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { return; } @@ -872,7 +872,7 @@ void cChunkMap::MarkChunkDirty(int a_ChunkX, int a_ChunkZ, bool a_MarkRedstoneDi { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { return; } @@ -891,7 +891,7 @@ void cChunkMap::MarkChunkSaving(int a_ChunkX, int a_ChunkZ) { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { return; } @@ -906,7 +906,7 @@ void cChunkMap::MarkChunkSaved (int a_ChunkX, int a_ChunkZ) { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { return; } @@ -924,7 +924,7 @@ void cChunkMap::SetChunkData(cSetChunkData & a_SetChunkData) { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); - if (Chunk == NULL) + if (Chunk == nullptr) { return; } @@ -969,7 +969,7 @@ void cChunkMap::ChunkLighted( { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkZ); - if (Chunk == NULL) + if (Chunk == nullptr) { return; } @@ -985,7 +985,7 @@ bool cChunkMap::GetChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataCallback & a_ { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { return false; } @@ -1001,7 +1001,7 @@ bool cChunkMap::GetChunkBlockTypes(int a_ChunkX, int a_ChunkZ, BLOCKTYPE * a_Blo { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { return false; } @@ -1017,7 +1017,7 @@ bool cChunkMap::IsChunkQueued(int a_ChunkX, int a_ChunkZ) { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkZ); - return (Chunk != NULL) && Chunk->IsQueued(); + return (Chunk != nullptr) && Chunk->IsQueued(); } @@ -1028,7 +1028,7 @@ bool cChunkMap::IsChunkValid(int a_ChunkX, int a_ChunkZ) { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkZ); - return (Chunk != NULL) && Chunk->IsValid(); + return (Chunk != nullptr) && Chunk->IsValid(); } @@ -1039,7 +1039,7 @@ bool cChunkMap::HasChunkAnyClients(int a_ChunkX, int a_ChunkZ) { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); - return (Chunk != NULL) && Chunk->HasAnyClients(); + return (Chunk != nullptr) && Chunk->HasAnyClients(); } @@ -1054,7 +1054,7 @@ int cChunkMap::GetHeight(int a_BlockX, int a_BlockZ) int ChunkX, ChunkZ, BlockY = 0; cChunkDef::AbsoluteToRelative(a_BlockX, BlockY, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunk(ChunkX, ChunkZ); - if (Chunk == NULL) + if (Chunk == nullptr) { return 0; } @@ -1081,7 +1081,7 @@ bool cChunkMap::TryGetHeight(int a_BlockX, int a_BlockZ, int & a_Height) int ChunkX, ChunkZ, BlockY = 0; cChunkDef::AbsoluteToRelative(a_BlockX, BlockY, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { return false; } @@ -1104,7 +1104,7 @@ void cChunkMap::FastSetBlocks(sSetBlockList & a_BlockList) int ChunkZ = a_BlockList.front().ChunkZ; cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); - if ((Chunk != NULL) && Chunk->IsValid()) + if ((Chunk != nullptr) && Chunk->IsValid()) { for (sSetBlockList::iterator itr = a_BlockList.begin(); itr != a_BlockList.end();) { @@ -1193,7 +1193,7 @@ BLOCKTYPE cChunkMap::GetBlock(int a_BlockX, int a_BlockY, int a_BlockZ) cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunk(ChunkX, ChunkZ); - if ((Chunk != NULL) && Chunk->IsValid()) + if ((Chunk != nullptr) && Chunk->IsValid()) { return Chunk->GetBlock(a_BlockX, a_BlockY, a_BlockZ); } @@ -1222,7 +1222,7 @@ NIBBLETYPE cChunkMap::GetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ) cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunk( ChunkX, ChunkZ); - if ((Chunk != NULL) && Chunk->IsValid()) + if ((Chunk != nullptr) && Chunk->IsValid()) { return Chunk->GetMeta(a_BlockX, a_BlockY, a_BlockZ); } @@ -1240,7 +1240,7 @@ NIBBLETYPE cChunkMap::GetBlockSkyLight(int a_BlockX, int a_BlockY, int a_BlockZ) cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunk( ChunkX, ChunkZ); - if ((Chunk != NULL) && Chunk->IsValid()) + if ((Chunk != nullptr) && Chunk->IsValid()) { return Chunk->GetSkyLight(a_BlockX, a_BlockY, a_BlockZ); } @@ -1258,7 +1258,7 @@ NIBBLETYPE cChunkMap::GetBlockBlockLight(int a_BlockX, int a_BlockY, int a_Block cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunk( ChunkX, ChunkZ); - if ((Chunk != NULL) && Chunk->IsValid()) + if ((Chunk != nullptr) && Chunk->IsValid()) { return Chunk->GetBlockLight(a_BlockX, a_BlockY, a_BlockZ); } @@ -1277,7 +1277,7 @@ void cChunkMap::SetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYP cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunk(ChunkX, ChunkZ); - if ((Chunk != NULL) && Chunk->IsValid()) + if ((Chunk != nullptr) && Chunk->IsValid()) { Chunk->SetMeta(a_BlockX, a_BlockY, a_BlockZ, a_BlockMeta); } @@ -1300,7 +1300,7 @@ void cChunkMap::SetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_B cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunk( ChunkX, ChunkZ); - if ((Chunk != NULL) && Chunk->IsValid()) + if ((Chunk != nullptr) && Chunk->IsValid()) { Chunk->SetBlock(X, Y, Z, a_BlockType, a_BlockMeta, a_SendToClients); m_World->GetSimulatorManager()->WakeUp(a_BlockX, a_BlockY, a_BlockZ, Chunk); @@ -1319,7 +1319,7 @@ void cChunkMap::QueueSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYP cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunk(ChunkX, ChunkZ); - if ((Chunk != NULL) && Chunk->IsValid()) + if ((Chunk != nullptr) && Chunk->IsValid()) { Chunk->QueueSetBlock(X, Y, Z, a_BlockType, a_BlockMeta, a_Tick, a_PreviousBlockType); } @@ -1336,7 +1336,7 @@ bool cChunkMap::GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCK cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunk( ChunkX, ChunkZ); - if ((Chunk != NULL) && Chunk->IsValid()) + if ((Chunk != nullptr) && Chunk->IsValid()) { Chunk->GetBlockTypeMeta(X, Y, Z, a_BlockType, a_BlockMeta); return true; @@ -1355,7 +1355,7 @@ bool cChunkMap::GetBlockInfo(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunk( ChunkX, ChunkZ); - if ((Chunk != NULL) && Chunk->IsValid()) + if ((Chunk != nullptr) && Chunk->IsValid()) { Chunk->GetBlockInfo(X, Y, Z, a_BlockType, a_Meta, a_SkyLight, a_BlockLight); return true; @@ -1373,7 +1373,7 @@ void cChunkMap::ReplaceBlocks(const sSetBlockVector & a_Blocks, BLOCKTYPE a_Filt for (sSetBlockVector::const_iterator itr = a_Blocks.begin(); itr != a_Blocks.end(); ++itr) { cChunkPtr Chunk = GetChunk(itr->ChunkX, itr->ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { continue; } @@ -1394,7 +1394,7 @@ void cChunkMap::ReplaceTreeBlocks(const sSetBlockVector & a_Blocks) for (sSetBlockVector::const_iterator itr = a_Blocks.begin(); itr != a_Blocks.end(); ++itr) { cChunkPtr Chunk = GetChunk(itr->ChunkX, itr->ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { continue; } @@ -1429,7 +1429,7 @@ EMCSBiome cChunkMap::GetBiomeAt (int a_BlockX, int a_BlockZ) cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunk(ChunkX, ChunkZ); - if ((Chunk != NULL) && Chunk->IsValid()) + if ((Chunk != nullptr) && Chunk->IsValid()) { return Chunk->GetBiomeAt(X, Z); } @@ -1450,7 +1450,7 @@ bool cChunkMap::SetBiomeAt(int a_BlockX, int a_BlockZ, EMCSBiome a_Biome) cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunk(ChunkX, ChunkZ); - if ((Chunk != NULL) && Chunk->IsValid()) + if ((Chunk != nullptr) && Chunk->IsValid()) { Chunk->SetBiomeAt(X, Z, a_Biome); return true; @@ -1483,7 +1483,7 @@ bool cChunkMap::SetAreaBiome(int a_MinX, int a_MaxX, int a_MinZ, int a_MaxZ, EMC int MinRelZ = (z == MinChunkZ) ? MinZ : 0; int MaxRelZ = (z == MaxChunkZ) ? MaxZ : cChunkDef::Width - 1; cChunkPtr Chunk = GetChunkNoLoad(x, z); - if ((Chunk != NULL) && Chunk->IsValid()) + if ((Chunk != nullptr) && Chunk->IsValid()) { Chunk->SetAreaBiome(MinRelX, MaxRelX, MinRelZ, MaxRelZ, a_Biome); } @@ -1507,7 +1507,7 @@ bool cChunkMap::GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure) for (sSetBlockVector::iterator itr = a_Blocks.begin(); itr != a_Blocks.end(); ++itr) { cChunkPtr Chunk = GetChunk(itr->ChunkX, itr->ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { if (!a_ContinueOnFailure) { @@ -1535,7 +1535,7 @@ bool cChunkMap::DigBlock(int a_X, int a_Y, int a_Z) { cCSLock Lock(m_CSLayers); cChunkPtr DestChunk = GetChunk( ChunkX, ChunkZ); - if ((DestChunk == NULL) || !DestChunk->IsValid()) + if ((DestChunk == nullptr) || !DestChunk->IsValid()) { return false; } @@ -1558,7 +1558,7 @@ void cChunkMap::SendBlockTo(int a_X, int a_Y, int a_Z, cPlayer * a_Player) cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunk(ChunkX, ChunkZ); - if ((Chunk != NULL) && (Chunk->IsValid())) + if ((Chunk != nullptr) && (Chunk->IsValid())) { Chunk->SendBlockTo(a_X, a_Y, a_Z, a_Player->GetClientHandle()); } @@ -1572,12 +1572,12 @@ void cChunkMap::CompareChunkClients(int a_ChunkX1, int a_ChunkZ1, int a_ChunkX2, { cCSLock Lock(m_CSLayers); cChunkPtr Chunk1 = GetChunkNoGen(a_ChunkX1, a_ChunkZ1); - if (Chunk1 == NULL) + if (Chunk1 == nullptr) { return; } cChunkPtr Chunk2 = GetChunkNoGen(a_ChunkX2, a_ChunkZ2); - if (Chunk2 == NULL) + if (Chunk2 == nullptr) { return; } @@ -1639,7 +1639,7 @@ bool cChunkMap::AddChunkClient(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Cli { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunk(a_ChunkX, a_ChunkZ); - if (Chunk == NULL) + if (Chunk == nullptr) { return false; } @@ -1654,7 +1654,7 @@ void cChunkMap::RemoveChunkClient(int a_ChunkX, int a_ChunkZ, cClientHandle * a_ { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); - if (Chunk == NULL) + if (Chunk == nullptr) { return; } @@ -1684,7 +1684,7 @@ void cChunkMap::AddEntity(cEntity * a_Entity) cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(a_Entity->GetChunkX(), a_Entity->GetChunkZ()); if ( - (Chunk == NULL) || // Chunk not present at all + (Chunk == nullptr) || // Chunk not present at all (!Chunk->IsValid() && !a_Entity->IsPlayer()) // Chunk present, but no valid data; players need to spawn in such chunks (#953) ) { @@ -1705,7 +1705,7 @@ void cChunkMap::AddEntityIfNotPresent(cEntity * a_Entity) cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(a_Entity->GetChunkX(), a_Entity->GetChunkZ()); if ( - (Chunk == NULL) || // Chunk not present at all + (Chunk == nullptr) || // Chunk not present at all (!Chunk->IsValid() && !a_Entity->IsPlayer()) // Chunk present, but no valid data; players need to spawn in such chunks (#953) ) { @@ -1747,7 +1747,7 @@ void cChunkMap::RemoveEntity(cEntity * a_Entity) cChunkPtr Chunk = GetChunkNoGen(a_Entity->GetChunkX(), a_Entity->GetChunkZ()); // Even if a chunk is not valid, it may still contain entities such as players; make sure to remove them (#1190) - if (Chunk == NULL) + if (Chunk == nullptr) { return; } @@ -1779,7 +1779,7 @@ bool cChunkMap::ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { return false; } @@ -1805,7 +1805,7 @@ bool cChunkMap::ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback & for (int x = MinChunkX; x <= MaxChunkX; x++) { cChunkPtr Chunk = GetChunkNoGen(x, z); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { continue; } @@ -1980,7 +1980,7 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ } // Ensure that the damage dealt is inversely proportional to the distance to the TNT centre - the closer a player is, the harder they are hit - a_Entity->TakeDamage(dtExplosion, NULL, (int)((1 / DistanceFromExplosion.Length()) * 6 * m_ExplosionSize), 0); + a_Entity->TakeDamage(dtExplosion, nullptr, (int)((1 / DistanceFromExplosion.Length()) * 6 * m_ExplosionSize), 0); } // Apply force to entities around the explosion - code modified from World.cpp DoExplosionAt() @@ -2038,7 +2038,7 @@ bool cChunkMap::ForEachBlockEntityInChunk(int a_ChunkX, int a_ChunkZ, cBlockEnti { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { return false; } @@ -2053,7 +2053,7 @@ bool cChunkMap::ForEachChestInChunk(int a_ChunkX, int a_ChunkZ, cChestCallback & { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { return false; } @@ -2068,7 +2068,7 @@ bool cChunkMap::ForEachDispenserInChunk(int a_ChunkX, int a_ChunkZ, cDispenserCa { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { return false; } @@ -2083,7 +2083,7 @@ bool cChunkMap::ForEachDropperInChunk(int a_ChunkX, int a_ChunkZ, cDropperCallba { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { return false; } @@ -2098,7 +2098,7 @@ bool cChunkMap::ForEachDropSpenserInChunk(int a_ChunkX, int a_ChunkZ, cDropSpens { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { return false; } @@ -2113,7 +2113,7 @@ bool cChunkMap::ForEachFurnaceInChunk(int a_ChunkX, int a_ChunkZ, cFurnaceCallba { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { return false; } @@ -2131,7 +2131,7 @@ bool cChunkMap::DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cB cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { return false; } @@ -2149,7 +2149,7 @@ bool cChunkMap::DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeacon cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { return false; } @@ -2167,7 +2167,7 @@ bool cChunkMap::DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCa cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { return false; } @@ -2185,7 +2185,7 @@ bool cChunkMap::DoWithDispenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDis cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { return false; } @@ -2203,7 +2203,7 @@ bool cChunkMap::DoWithDropperAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDropp cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { return false; } @@ -2221,7 +2221,7 @@ bool cChunkMap::DoWithDropSpenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cD cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { return false; } @@ -2239,7 +2239,7 @@ bool cChunkMap::DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurna cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { return false; } @@ -2256,7 +2256,7 @@ bool cChunkMap::DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNot cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { return false; } @@ -2273,7 +2273,7 @@ bool cChunkMap::DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, c cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { return false; } @@ -2291,7 +2291,7 @@ bool cChunkMap::DoWithMobHeadAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHe cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { return false; } @@ -2309,7 +2309,7 @@ bool cChunkMap::DoWithFlowerPotAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFlo cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { return false; } @@ -2327,7 +2327,7 @@ bool cChunkMap::GetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, AString & cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { return false; } @@ -2352,7 +2352,7 @@ void cChunkMap::ChunkLoadFailed(int a_ChunkX, int a_ChunkZ) { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkZ); - if (Chunk == NULL) + if (Chunk == nullptr) { return; } @@ -2369,7 +2369,7 @@ bool cChunkMap::SetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, const ASt int ChunkX, ChunkZ; cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { return false; } @@ -2384,7 +2384,7 @@ void cChunkMap::MarkChunkRegenerating(int a_ChunkX, int a_ChunkZ) { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkZ); - if (Chunk == NULL) + if (Chunk == nullptr) { // Not present return; @@ -2400,7 +2400,7 @@ bool cChunkMap::IsChunkLighted(int a_ChunkX, int a_ChunkZ) { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkZ); - if (Chunk == NULL) + if (Chunk == nullptr) { // Not present return false; @@ -2421,7 +2421,7 @@ bool cChunkMap::ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinCh for (int x = a_MinChunkX; x <= a_MaxChunkX; x++) { cChunkPtr Chunk = GetChunkNoLoad(x, z); - if ((Chunk == NULL) || (!Chunk->IsValid())) + if ((Chunk == nullptr) || (!Chunk->IsValid())) { // Not present / not valid Result = false; @@ -2463,7 +2463,7 @@ bool cChunkMap::WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBl for (int x = MinChunkX; x <= MaxChunkX; x++) { cChunkPtr Chunk = GetChunkNoLoad(x, z); - if ((Chunk == NULL) || (!Chunk->IsValid())) + if ((Chunk == nullptr) || (!Chunk->IsValid())) { // Not present / not valid Result = false; @@ -2504,7 +2504,7 @@ void cChunkMap::GrowMelonPumpkin(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCK cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); - if (Chunk != NULL) + if (Chunk != nullptr) { Chunk->GrowMelonPumpkin(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_Rand); } @@ -2521,7 +2521,7 @@ void cChunkMap::GrowSugarcane(int a_BlockX, int a_BlockY, int a_BlockZ, int a_Nu cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); - if (Chunk != NULL) + if (Chunk != nullptr) { Chunk->GrowSugarcane(a_BlockX, a_BlockY, a_BlockZ, a_NumBlocksToGrow); } @@ -2538,7 +2538,7 @@ void cChunkMap::GrowCactus(int a_BlockX, int a_BlockY, int a_BlockZ, int a_NumBl cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); - if (Chunk != NULL) + if (Chunk != nullptr) { Chunk->GrowCactus(a_BlockX, a_BlockY, a_BlockZ, a_NumBlocksToGrow); } @@ -2555,7 +2555,7 @@ void cChunkMap::SetNextBlockTick(int a_BlockX, int a_BlockY, int a_BlockZ) cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); - if (Chunk != NULL) + if (Chunk != nullptr) { Chunk->SetNextBlockTick(a_BlockX, a_BlockY, a_BlockZ); } @@ -2610,7 +2610,7 @@ void cChunkMap::TickBlock(int a_BlockX, int a_BlockY, int a_BlockZ) int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) + if ((Chunk == nullptr) || !Chunk->IsValid()) { return; } @@ -2679,7 +2679,7 @@ void cChunkMap::QueueTickBlock(int a_BlockX, int a_BlockY, int a_BlockZ) cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); - if (Chunk != NULL) + if (Chunk != nullptr) { Chunk->QueueTickBlock(a_BlockX, a_BlockY, a_BlockZ); } @@ -2693,7 +2693,7 @@ void cChunkMap::SetChunkAlwaysTicked(int a_ChunkX, int a_ChunkZ, bool a_AlwaysTi { cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkZ); - if (Chunk != NULL) + if (Chunk != nullptr) { Chunk->SetAlwaysTicked(a_AlwaysTicked); } @@ -2729,7 +2729,7 @@ cChunkMap::cChunkLayer::~cChunkLayer() for (size_t i = 0; i < ARRAYCOUNT(m_Chunks); ++i) { delete m_Chunks[i]; - m_Chunks[i] = NULL; // Must zero out, because further chunk deletions query the chunkmap for entities and that would touch deleted data + m_Chunks[i] = nullptr; // Must zero out, because further chunk deletions query the chunkmap for entities and that would touch deleted data } // for i - m_Chunks[] } @@ -2747,11 +2747,11 @@ cChunkPtr cChunkMap::cChunkLayer::GetChunk( int a_ChunkX, int a_ChunkZ) if (!((LocalX < LAYER_SIZE) && (LocalZ < LAYER_SIZE) && (LocalX > -1) && (LocalZ > -1))) { ASSERT(!"Asking a cChunkLayer for a chunk that doesn't belong to it!"); - return NULL; + return nullptr; } int Index = LocalX + LocalZ * LAYER_SIZE; - if (m_Chunks[Index] == NULL) + if (m_Chunks[Index] == nullptr) { cChunk * neixm = (LocalX > 0) ? m_Chunks[Index - 1] : m_Parent->FindChunk(a_ChunkX - 1, a_ChunkZ); cChunk * neixp = (LocalX < LAYER_SIZE - 1) ? m_Chunks[Index + 1] : m_Parent->FindChunk(a_ChunkX + 1, a_ChunkZ); @@ -2774,7 +2774,7 @@ cChunk * cChunkMap::cChunkLayer::FindChunk(int a_ChunkX, int a_ChunkZ) if (!((LocalX < LAYER_SIZE) && (LocalZ < LAYER_SIZE) && (LocalX > -1) && (LocalZ > -1))) { ASSERT(!"Asking a cChunkLayer for a chunk that doesn't belong to it!"); - return NULL; + return nullptr; } int Index = LocalX + LocalZ * LAYER_SIZE; @@ -2791,7 +2791,7 @@ void cChunkMap::cChunkLayer::CollectMobCensus(cMobCensus& a_ToFill) // We do count every Mobs in the world. But we are assuming that every chunk not loaded by any client // doesn't affect us. Normally they should not have mobs because every "too far" mobs despawn // If they have (f.i. when player disconnect) we assume we don't have to make them live or despawn - if ((m_Chunks[i] != NULL) && m_Chunks[i]->IsValid() && m_Chunks[i]->HasAnyClients()) + if ((m_Chunks[i] != nullptr) && m_Chunks[i]->IsValid() && m_Chunks[i]->HasAnyClients()) { m_Chunks[i]->CollectMobCensus(a_ToFill); } @@ -2808,7 +2808,7 @@ void cChunkMap::cChunkLayer::SpawnMobs(cMobSpawner& a_MobSpawner) for (size_t i = 0; i < ARRAYCOUNT(m_Chunks); i++) { // We only spawn close to players - if ((m_Chunks[i] != NULL) && m_Chunks[i]->IsValid() && m_Chunks[i]->HasAnyClients()) + if ((m_Chunks[i] != nullptr) && m_Chunks[i]->IsValid() && m_Chunks[i]->HasAnyClients()) { m_Chunks[i]->SpawnMobs(a_MobSpawner); } @@ -2824,7 +2824,7 @@ void cChunkMap::cChunkLayer::Tick(float a_Dt) for (size_t i = 0; i < ARRAYCOUNT(m_Chunks); i++) { // Only tick chunks that are valid and should be ticked: - if ((m_Chunks[i] != NULL) && m_Chunks[i]->IsValid() && m_Chunks[i]->ShouldBeTicked()) + if ((m_Chunks[i] != nullptr) && m_Chunks[i]->IsValid() && m_Chunks[i]->ShouldBeTicked()) { m_Chunks[i]->Tick(a_Dt); } @@ -2839,7 +2839,7 @@ void cChunkMap::cChunkLayer::RemoveClient(cClientHandle * a_Client) { for (size_t i = 0; i < ARRAYCOUNT(m_Chunks); i++) { - if (m_Chunks[i] != NULL) + if (m_Chunks[i] != nullptr) { m_Chunks[i]->RemoveClient(a_Client); } @@ -2855,7 +2855,7 @@ bool cChunkMap::cChunkLayer::ForEachEntity(cEntityCallback & a_Callback) // Calls the callback for each entity in the entire world; returns true if all entities processed, false if the callback aborted by returning true for (size_t i = 0; i < ARRAYCOUNT(m_Chunks); i++) { - if ((m_Chunks[i] != NULL) && m_Chunks[i]->IsValid()) + if ((m_Chunks[i] != nullptr) && m_Chunks[i]->IsValid()) { if (!m_Chunks[i]->ForEachEntity(a_Callback)) { @@ -2875,7 +2875,7 @@ bool cChunkMap::cChunkLayer::DoWithEntityByID(int a_EntityID, cEntityCallback & // Calls the callback if the entity with the specified ID is found, with the entity object as the callback param. Returns true if entity found. for (size_t i = 0; i < ARRAYCOUNT(m_Chunks); i++) { - if ((m_Chunks[i] != NULL) && m_Chunks[i]->IsValid()) + if ((m_Chunks[i] != nullptr) && m_Chunks[i]->IsValid()) { if (m_Chunks[i]->DoWithEntityByID(a_EntityID, a_Callback, a_CallbackReturn)) { @@ -2894,7 +2894,7 @@ bool cChunkMap::cChunkLayer::HasEntity(int a_EntityID) { for (size_t i = 0; i < ARRAYCOUNT(m_Chunks); i++) { - if ((m_Chunks[i] != NULL) && m_Chunks[i]->IsValid()) + if ((m_Chunks[i] != nullptr) && m_Chunks[i]->IsValid()) { if (m_Chunks[i]->HasEntity(a_EntityID)) { @@ -2914,7 +2914,7 @@ int cChunkMap::cChunkLayer::GetNumChunksLoaded(void) const int NumChunks = 0; for (size_t i = 0; i < ARRAYCOUNT(m_Chunks); ++i) { - if (m_Chunks[i] != NULL) + if (m_Chunks[i] != nullptr) { NumChunks++; } @@ -2932,7 +2932,7 @@ void cChunkMap::cChunkLayer::GetChunkStats(int & a_NumChunksValid, int & a_NumCh int NumDirty = 0; for (size_t i = 0; i < ARRAYCOUNT(m_Chunks); ++i) { - if (m_Chunks[i] == NULL) + if (m_Chunks[i] == nullptr) { continue; } @@ -2955,7 +2955,7 @@ void cChunkMap::cChunkLayer::Save(void) cWorld * World = m_Parent->GetWorld(); for (size_t i = 0; i < ARRAYCOUNT(m_Chunks); ++i) { - if ((m_Chunks[i] != NULL) && m_Chunks[i]->IsValid() && m_Chunks[i]->IsDirty()) + if ((m_Chunks[i] != nullptr) && m_Chunks[i]->IsValid() && m_Chunks[i]->IsDirty()) { World->GetStorage().QueueSaveChunk(m_Chunks[i]->GetPosX(), m_Chunks[i]->GetPosZ()); } @@ -2971,7 +2971,7 @@ void cChunkMap::cChunkLayer::UnloadUnusedChunks(void) for (size_t i = 0; i < ARRAYCOUNT(m_Chunks); i++) { if ( - (m_Chunks[i] != NULL) && // Is valid + (m_Chunks[i] != nullptr) && // Is valid (m_Chunks[i]->CanUnload()) && // Can unload !cPluginManager::Get()->CallHookChunkUnloading(*(m_Parent->GetWorld()), m_Chunks[i]->GetPosX(), m_Chunks[i]->GetPosZ()) // Plugins agree ) @@ -2980,7 +2980,7 @@ void cChunkMap::cChunkLayer::UnloadUnusedChunks(void) // so we still need to be able to return the chunk. Therefore we first delete, then NULLify // Doing otherwise results in bug http://forum.mc-server.org/showthread.php?tid=355 delete m_Chunks[i]; - m_Chunks[i] = NULL; + m_Chunks[i] = nullptr; } } // for i - m_Chunks[] } @@ -3033,7 +3033,7 @@ void cChunkMap::AddChunkStay(cChunkStay & a_ChunkStay) for (cChunkCoordsVector::const_iterator itr = WantedChunks.begin(); itr != WantedChunks.end(); ++itr) { cChunkPtr Chunk = GetChunk(itr->m_ChunkX, itr->m_ChunkZ); - if (Chunk == NULL) + if (Chunk == nullptr) { continue; } @@ -3082,7 +3082,7 @@ void cChunkMap::DelChunkStay(cChunkStay & a_ChunkStay) for (cChunkCoordsVector::const_iterator itr = Chunks.begin(), end = Chunks.end(); itr != end; ++itr) { cChunkPtr Chunk = GetChunkNoLoad(itr->m_ChunkX, itr->m_ChunkZ); - if (Chunk == NULL) + if (Chunk == nullptr) { continue; } diff --git a/src/ChunkMap.h b/src/ChunkMap.h index 38e7f4052..51be5cb3d 100644 --- a/src/ChunkMap.h +++ b/src/ChunkMap.h @@ -70,29 +70,29 @@ public: // Broadcast respective packets to all clients of the chunk where the event is taking place // (Please keep these alpha-sorted) void BroadcastAttachEntity(const cEntity & a_Entity, const cEntity * a_Vehicle); - void BroadcastBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType, const cClientHandle * a_Exclude = NULL); - void BroadcastBlockBreakAnimation(int a_entityID, int a_blockX, int a_blockY, int a_blockZ, char a_stage, const cClientHandle * a_Exclude = NULL); + void BroadcastBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType, const cClientHandle * a_Exclude = nullptr); + void BroadcastBlockBreakAnimation(int a_entityID, int a_blockX, int a_blockY, int a_blockZ, char a_stage, const cClientHandle * a_Exclude = nullptr); void BroadcastBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude); - void BroadcastChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = NULL); - void BroadcastCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL); - void BroadcastCollectPickup(const cPickup & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL); - void BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityHeadLook(const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityLook(const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityMetadata(const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityRelMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityRelMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityStatus(const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityVelocity(const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = NULL); - void BroadcastParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount, cClientHandle * a_Exclude = NULL); - void BroadcastRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude = NULL); - void BroadcastSoundEffect(const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = NULL); - void BroadcastSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data, const cClientHandle * a_Exclude = NULL); - void BroadcastSpawnEntity(cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); - void BroadcastThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = NULL); + void BroadcastChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = nullptr); + void BroadcastCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player, const cClientHandle * a_Exclude = nullptr); + void BroadcastCollectPickup(const cPickup & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude = nullptr); + void BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr); + void BroadcastEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude = nullptr); + void BroadcastEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude = nullptr); + void BroadcastEntityHeadLook(const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr); + void BroadcastEntityLook(const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr); + void BroadcastEntityMetadata(const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr); + void BroadcastEntityRelMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = nullptr); + void BroadcastEntityRelMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = nullptr); + void BroadcastEntityStatus(const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude = nullptr); + void BroadcastEntityVelocity(const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr); + void BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = nullptr); + void BroadcastParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount, cClientHandle * a_Exclude = nullptr); + void BroadcastRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude = nullptr); + void BroadcastSoundEffect(const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = nullptr); + void BroadcastSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data, const cClientHandle * a_Exclude = nullptr); + void BroadcastSpawnEntity(cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr); + void BroadcastThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = nullptr); void BroadcastUseBed(const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ); /** Sends the block entity, if it is at the coords specified, to a_Client */ @@ -368,7 +368,7 @@ private: /** Always returns an assigned chunkptr, but the chunk needn't be valid (loaded / generated) - callers must check */ cChunkPtr GetChunk( int a_ChunkX, int a_ChunkZ); - /** Returns the specified chunk, or NULL if not created yet */ + /** Returns the specified chunk, or nullptr if not created yet */ cChunk * FindChunk(int a_ChunkX, int a_ChunkZ); int GetX(void) const {return m_LayerX; } @@ -431,10 +431,10 @@ private: typedef std::list cChunkStays; - /** Finds the cChunkLayer object responsible for the specified chunk; returns NULL if not found. Assumes m_CSLayers is locked. */ + /** Finds the cChunkLayer object responsible for the specified chunk; returns nullptr if not found. Assumes m_CSLayers is locked. */ cChunkLayer * FindLayerForChunk(int a_ChunkX, int a_ChunkZ); - /** Returns the specified cChunkLayer object; returns NULL if not found. Assumes m_CSLayers is locked. */ + /** Returns the specified cChunkLayer object; returns nullptr if not found. Assumes m_CSLayers is locked. */ cChunkLayer * FindLayer(int a_LayerX, int a_LayerZ); /** Returns the cChunkLayer object responsible for the specified chunk; creates it if not found. */ diff --git a/src/ChunkSender.cpp b/src/ChunkSender.cpp index a3151eb3f..c94004780 100644 --- a/src/ChunkSender.cpp +++ b/src/ChunkSender.cpp @@ -35,9 +35,9 @@ void cNotifyChunkSender::Call(int a_ChunkX, int a_ChunkZ) cChunkSender::cChunkSender(void) : super("ChunkSender"), - m_World(NULL), + m_World(nullptr), m_RemoveCount(0), - m_Notify(NULL) + m_Notify(nullptr) { m_Notify.SetChunkSender(this); } @@ -93,7 +93,7 @@ void cChunkSender::ChunkReady(int a_ChunkX, int a_ChunkZ) void cChunkSender::QueueSendChunkTo(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client) { - ASSERT(a_Client != NULL); + ASSERT(a_Client != nullptr); { cCSLock Lock(m_CS); if (std::find(m_SendChunks.begin(), m_SendChunks.end(), sSendChunk(a_ChunkX, a_ChunkZ, a_Client)) != m_SendChunks.end()) @@ -161,7 +161,7 @@ void cChunkSender::Execute(void) m_ChunksReady.pop_front(); Lock.Unlock(); - SendChunk(Coords.m_ChunkX, Coords.m_ChunkZ, NULL); + SendChunk(Coords.m_ChunkX, Coords.m_ChunkZ, nullptr); } else { @@ -189,10 +189,10 @@ void cChunkSender::Execute(void) void cChunkSender::SendChunk(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client) { - ASSERT(m_World != NULL); + ASSERT(m_World != nullptr); // Ask the client if it still wants the chunk: - if (a_Client != NULL) + if (a_Client != nullptr) { if (!a_Client->WantsSendChunk(a_ChunkX, a_ChunkZ)) { @@ -227,7 +227,7 @@ void cChunkSender::SendChunk(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Clien cChunkDataSerializer Data(m_BlockTypes, m_BlockMetas, m_BlockLight, m_BlockSkyLight, m_BiomeMap); // Send: - if (a_Client == NULL) + if (a_Client == nullptr) { m_World->BroadcastChunkData(a_ChunkX, a_ChunkZ, Data); } @@ -239,7 +239,7 @@ void cChunkSender::SendChunk(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Clien // Send block-entity packets: for (sBlockCoords::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr) { - if (a_Client == NULL) + if (a_Client == nullptr) { m_World->BroadcastBlockEntity(itr->m_BlockX, itr->m_BlockY, itr->m_BlockZ); } diff --git a/src/ChunkSender.h b/src/ChunkSender.h index a0e9087a9..f17029aea 100644 --- a/src/ChunkSender.h +++ b/src/ChunkSender.h @@ -158,7 +158,7 @@ protected: virtual void Entity (cEntity * a_Entity) override; virtual void BlockEntity (cBlockEntity * a_Entity) override; - /// Sends the specified chunk to a_Client, or to all chunk clients if a_Client == NULL + /// Sends the specified chunk to a_Client, or to all chunk clients if a_Client == nullptr void SendChunk(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client); } ; diff --git a/src/ChunkStay.cpp b/src/ChunkStay.cpp index 38aa89a37..0772787de 100644 --- a/src/ChunkStay.cpp +++ b/src/ChunkStay.cpp @@ -12,7 +12,7 @@ cChunkStay::cChunkStay(void) : - m_ChunkMap(NULL) + m_ChunkMap(nullptr) { } @@ -31,7 +31,7 @@ cChunkStay::~cChunkStay() void cChunkStay::Clear(void) { - ASSERT(m_ChunkMap == NULL); + ASSERT(m_ChunkMap == nullptr); m_Chunks.clear(); } @@ -41,7 +41,7 @@ void cChunkStay::Clear(void) void cChunkStay::Add(int a_ChunkX, int a_ChunkZ) { - ASSERT(m_ChunkMap == NULL); + ASSERT(m_ChunkMap == nullptr); for (cChunkCoordsVector::const_iterator itr = m_Chunks.begin(); itr != m_Chunks.end(); ++itr) { @@ -60,7 +60,7 @@ void cChunkStay::Add(int a_ChunkX, int a_ChunkZ) void cChunkStay::Remove(int a_ChunkX, int a_ChunkZ) { - ASSERT(m_ChunkMap == NULL); + ASSERT(m_ChunkMap == nullptr); for (cChunkCoordsVector::iterator itr = m_Chunks.begin(); itr != m_Chunks.end(); ++itr) { @@ -79,7 +79,7 @@ void cChunkStay::Remove(int a_ChunkX, int a_ChunkZ) void cChunkStay::Enable(cChunkMap & a_ChunkMap) { - ASSERT(m_ChunkMap == NULL); + ASSERT(m_ChunkMap == nullptr); m_OutstandingChunks = m_Chunks; m_ChunkMap = &a_ChunkMap; @@ -92,10 +92,10 @@ void cChunkStay::Enable(cChunkMap & a_ChunkMap) void cChunkStay::Disable(void) { - ASSERT(m_ChunkMap != NULL); + ASSERT(m_ChunkMap != nullptr); cChunkMap * ChunkMap = m_ChunkMap; - m_ChunkMap = NULL; + m_ChunkMap = nullptr; ChunkMap->DelChunkStay(*this); } diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 3dcbaa6a9..202a8d02f 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -55,7 +55,7 @@ cClientHandle::cClientHandle(const cSocket * a_Socket, int a_ViewDistance) : m_ViewDistance(a_ViewDistance), m_IPString(a_Socket->GetIPString()), m_OutgoingData(64 KiB), - m_Player(NULL), + m_Player(nullptr), m_HasSentDC(false), m_LastStreamedChunkX(0x7fffffff), // bogus chunk coords to force streaming upon login m_LastStreamedChunkZ(0x7fffffff), @@ -105,10 +105,10 @@ cClientHandle::~cClientHandle() m_ChunksToSend.clear(); } - if (m_Player != NULL) + if (m_Player != nullptr) { cWorld * World = m_Player->GetWorld(); - if (World != NULL) + if (World != nullptr) { if (!m_Username.empty()) { @@ -120,7 +120,7 @@ cClientHandle::~cClientHandle() m_Player->Destroy(); } delete m_Player; - m_Player = NULL; + m_Player = nullptr; } if (!m_HasSentDC) @@ -132,7 +132,7 @@ cClientHandle::~cClientHandle() cRoot::Get()->GetServer()->RemoveClient(this); delete m_Protocol; - m_Protocol = NULL; + m_Protocol = nullptr; LOGD("ClientHandle at %p deleted", this); } @@ -156,7 +156,7 @@ void cClientHandle::Destroy(void) // DEBUG: LOGD("%s: client %p, \"%s\"", __FUNCTION__, this, m_Username.c_str()); - if ((m_Player != NULL) && (m_Player->GetWorld() != NULL)) + if ((m_Player != nullptr) && (m_Player->GetWorld() != nullptr)) { RemoveFromAllChunks(); m_Player->GetWorld()->RemoveClientFromChunkSender(this); @@ -297,7 +297,7 @@ void cClientHandle::Authenticate(const AString & a_Name, const AString & a_UUID, return; } - ASSERT(m_Player == NULL); + ASSERT(m_Player == nullptr); m_Username = a_Name; @@ -318,7 +318,7 @@ void cClientHandle::Authenticate(const AString & a_Name, const AString & a_UUID, m_Player = new cPlayer(this, GetUsername()); cWorld * World = cRoot::Get()->GetWorld(m_Player->GetLoadedWorldName()); - if (World == NULL) + if (World == nullptr) { World = cRoot::Get()->GetDefaultWorld(); } @@ -394,7 +394,7 @@ void cClientHandle::StreamChunks(void) return; } - ASSERT(m_Player != NULL); + ASSERT(m_Player != nullptr); int ChunkPosX = FAST_FLOOR_DIV((int)m_Player->GetPosX(), cChunkDef::Width); int ChunkPosZ = FAST_FLOOR_DIV((int)m_Player->GetPosZ(), cChunkDef::Width); @@ -409,7 +409,7 @@ void cClientHandle::StreamChunks(void) LOGD("Streaming chunks centered on [%d, %d], view distance %d", ChunkPosX, ChunkPosZ, m_ViewDistance); cWorld * World = m_Player->GetWorld(); - ASSERT(World != NULL); + ASSERT(World != nullptr); // Remove all loaded chunks that are no longer in range; deferred to out-of-CS: cChunkCoordsList RemoveChunks; @@ -495,7 +495,7 @@ void cClientHandle::StreamChunk(int a_ChunkX, int a_ChunkZ) } cWorld * World = m_Player->GetWorld(); - ASSERT(World != NULL); + ASSERT(World != nullptr); if (World->AddChunkClient(a_ChunkX, a_ChunkZ, this)) { @@ -516,7 +516,7 @@ void cClientHandle::StreamChunk(int a_ChunkX, int a_ChunkZ) void cClientHandle::RemoveFromAllChunks() { cWorld * World = m_Player->GetWorld(); - if (World != NULL) + if (World != nullptr) { World->RemoveClientFromChunks(this); } @@ -632,7 +632,7 @@ void cClientHandle::HandlePlayerAbilities(bool a_CanFly, bool a_IsFlying, float void cClientHandle::HandlePlayerPos(double a_PosX, double a_PosY, double a_PosZ, double a_Stance, bool a_IsOnGround) { - if ((m_Player == NULL) || (m_State != csPlaying)) + if ((m_Player == nullptr) || (m_State != csPlaying)) { // The client hasn't been spawned yet and sends nonsense, we know better return; @@ -766,7 +766,7 @@ void cClientHandle::UnregisterPluginChannels(const AStringVector & a_ChannelList void cClientHandle::HandleBeaconSelection(int a_PrimaryEffect, int a_SecondaryEffect) { cWindow * Window = m_Player->GetWindow(); - if ((Window == NULL) || (Window->GetWindowType() != cWindow::wtBeacon)) + if ((Window == nullptr) || (Window->GetWindowType() != cWindow::wtBeacon)) { return; } @@ -842,7 +842,7 @@ void cClientHandle::HandleCommandBlockEntityChange(int a_EntityID, const AString void cClientHandle::HandleAnvilItemName(const AString & a_ItemName) { - if ((m_Player->GetWindow() == NULL) || (m_Player->GetWindow()->GetWindowType() != cWindow::wtAnvil)) + if ((m_Player->GetWindow() == nullptr) || (m_Player->GetWindow()->GetWindowType() != cWindow::wtAnvil)) { return; } @@ -1479,7 +1479,7 @@ void cClientHandle::HandleChat(const AString & a_Message) void cClientHandle::HandlePlayerLook(float a_Rotation, float a_Pitch, bool a_IsOnGround) { - if ((m_Player == NULL) || (m_State != csPlaying)) + if ((m_Player == nullptr) || (m_State != csPlaying)) { return; } @@ -1579,7 +1579,7 @@ void cClientHandle::HandleWindowClick(char a_WindowID, short a_SlotNum, eClickAc ); cWindow * Window = m_Player->GetWindow(); - if (Window == NULL) + if (Window == nullptr) { LOGWARNING("Player \"%s\" clicked in a non-existent window. Ignoring", m_Username.c_str()); return; @@ -1671,7 +1671,7 @@ void cClientHandle::HandleUseEntity(int a_TargetEntityID, bool a_IsLeftClick) void cClientHandle::HandleRespawn(void) { - if (m_Player == NULL) + if (m_Player == nullptr) { Destroy(); return; @@ -1760,7 +1760,7 @@ void cClientHandle::HandleEntitySprinting(int a_EntityID, bool a_IsSprinting) void cClientHandle::HandleUnmount(void) { - if (m_Player == NULL) + if (m_Player == nullptr) { return; } @@ -1865,8 +1865,8 @@ void cClientHandle::RemoveFromWorld(void) bool cClientHandle::CheckBlockInteractionsRate(void) { - ASSERT(m_Player != NULL); - ASSERT(m_Player->GetWorld() != NULL); + ASSERT(m_Player != nullptr); + ASSERT(m_Player->GetWorld() != nullptr); if (m_NumBlockChangeInteractionsThisTick > MAX_BLOCK_CHANGE_INTERACTIONS) { @@ -1897,7 +1897,7 @@ void cClientHandle::Tick(float a_Dt) Destroy(); } - if (m_Player == NULL) + if (m_Player == nullptr) { return; } @@ -2047,10 +2047,10 @@ void cClientHandle::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlock void cClientHandle::SendChat(const AString & a_Message, eMessageType a_ChatPrefix, const AString & a_AdditionalData) { cWorld * World = GetPlayer()->GetWorld(); - if (World == NULL) + if (World == nullptr) { World = cRoot::Get()->GetWorld(GetPlayer()->GetLoadedWorldName()); - if (World == NULL) + if (World == nullptr) { World = cRoot::Get()->GetDefaultWorld(); } @@ -2075,7 +2075,7 @@ void cClientHandle::SendChat(const cCompositeChat & a_Message) void cClientHandle::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) { - ASSERT(m_Player != NULL); + ASSERT(m_Player != nullptr); // Check chunks being sent, erase them from m_ChunksToSend: bool Found = false; @@ -2906,7 +2906,7 @@ void cClientHandle::HandleEnchantItem(Byte & a_WindowID, Byte & a_Enchantment) } if ( - (m_Player->GetWindow() == NULL) || + (m_Player->GetWindow() == nullptr) || (m_Player->GetWindow()->GetWindowID() != a_WindowID) || (m_Player->GetWindow()->GetWindowType() != cWindow::wtEnchantment) ) diff --git a/src/CraftingRecipes.cpp b/src/CraftingRecipes.cpp index 0828a6c74..64fb21181 100644 --- a/src/CraftingRecipes.cpp +++ b/src/CraftingRecipes.cpp @@ -59,7 +59,7 @@ cCraftingGrid::cCraftingGrid(const cCraftingGrid & a_Original) : cCraftingGrid::~cCraftingGrid() { delete[] m_Items; - m_Items = NULL; + m_Items = nullptr; } @@ -291,7 +291,7 @@ void cCraftingRecipes::GetRecipe(cPlayer & a_Player, cCraftingGrid & a_CraftingG // Built-in recipes: std::auto_ptr Recipe(FindRecipe(a_CraftingGrid.GetItems(), a_CraftingGrid.GetWidth(), a_CraftingGrid.GetHeight())); a_Recipe.Clear(); - if (Recipe.get() == NULL) + if (Recipe.get() == nullptr) { // Allow plugins to intercept a no-recipe-found situation: cRoot::Get()->GetPluginManager()->CallHookCraftingNoRecipe(a_Player, a_CraftingGrid, &a_Recipe); @@ -603,9 +603,9 @@ cCraftingRecipes::cRecipe * cCraftingRecipes::FindRecipe(const cItem * a_Craftin // Search in the possibly minimized grid, but keep the stride: const cItem * Grid = a_CraftingGrid + GridLeft + (a_GridWidth * GridTop); cRecipe * Recipe = FindRecipeCropped(Grid, GridWidth, GridHeight, a_GridWidth); - if (Recipe == NULL) + if (Recipe == nullptr) { - return NULL; + return nullptr; } // A recipe has been found, move it to correspond to the original crafting grid: @@ -637,7 +637,7 @@ cCraftingRecipes::cRecipe * cCraftingRecipes::FindRecipeCropped(const cItem * a_ for (int x = 0; x <= MaxOfsX; x++) for (int y = 0; y <= MaxOfsY; y++) { cRecipe * Recipe = MatchRecipe(a_CraftingGrid, a_GridWidth, a_GridHeight, a_GridStride, *itr, x, y); - if (Recipe != NULL) + if (Recipe != nullptr) { return Recipe; } @@ -645,7 +645,7 @@ cCraftingRecipes::cRecipe * cCraftingRecipes::FindRecipeCropped(const cItem * a_ } // for itr - m_Recipes[] // No matching recipe found - return NULL; + return nullptr; } @@ -681,7 +681,7 @@ cCraftingRecipes::cRecipe * cCraftingRecipes::MatchRecipe(const cItem * a_Crafti ) { // Doesn't match - return NULL; + return nullptr; } HasMatched[itrS->x + a_OffsetX][itrS->y + a_OffsetY] = true; } // for itrS - Recipe->m_Ingredients[] @@ -743,7 +743,7 @@ cCraftingRecipes::cRecipe * cCraftingRecipes::MatchRecipe(const cItem * a_Crafti } // for x if (!Found) { - return NULL; + return nullptr; } } // for itrS - a_Recipe->m_Ingredients[] @@ -753,7 +753,7 @@ cCraftingRecipes::cRecipe * cCraftingRecipes::MatchRecipe(const cItem * a_Crafti if (!HasMatched[x][y] && !a_CraftingGrid[x + a_GridStride * y].IsEmpty()) { // There's an unmatched item in the grid - return NULL; + return nullptr; } } // for y, for x diff --git a/src/CraftingRecipes.h b/src/CraftingRecipes.h index 5ebabe098..44444d42e 100644 --- a/src/CraftingRecipes.h +++ b/src/CraftingRecipes.h @@ -157,13 +157,13 @@ protected: /// Moves the recipe to top-left corner, sets its MinWidth / MinHeight void NormalizeIngredients(cRecipe * a_Recipe); - /// Finds a recipe matching the crafting grid. Returns a newly allocated recipe (with all its coords set) or NULL if not found. Caller must delete return value! + /// Finds a recipe matching the crafting grid. Returns a newly allocated recipe (with all its coords set) or nullptr if not found. Caller must delete return value! cRecipe * FindRecipe(const cItem * a_CraftingGrid, int a_GridWidth, int a_GridHeight); /// Same as FindRecipe, but the grid is guaranteed to be of minimal dimensions needed cRecipe * FindRecipeCropped(const cItem * a_CraftingGrid, int a_GridWidth, int a_GridHeight, int a_GridStride); - /// Checks if the grid matches the specified recipe, offset by the specified offsets. Returns a matched cRecipe * if so, or NULL if not matching. Caller must delete the return value! + /// Checks if the grid matches the specified recipe, offset by the specified offsets. Returns a matched cRecipe * if so, or nullptr if not matching. Caller must delete the return value! cRecipe * MatchRecipe(const cItem * a_CraftingGrid, int a_GridWidth, int a_GridHeight, int a_GridStride, const cRecipe * a_Recipe, int a_OffsetX, int a_OffsetY); /** Searches for anything firework related, and does the data setting if appropriate */ diff --git a/src/Defines.h b/src/Defines.h index 6355b75b4..d32b7f9c3 100644 --- a/src/Defines.h +++ b/src/Defines.h @@ -477,16 +477,16 @@ inline void AddFaceDirection(int & a_BlockX, unsigned char & a_BlockY, int & a_B -#define PI 3.14159265358979323846264338327950288419716939937510582097494459072381640628620899862803482534211706798f + inline void EulerToVector(double a_Pan, double a_Pitch, double & a_X, double & a_Y, double & a_Z) { // a_X = sinf ( a_Pan / 180 * PI) * cosf ( a_Pitch / 180 * PI); // a_Y = -sinf ( a_Pitch / 180 * PI); // a_Z = -cosf ( a_Pan / 180 * PI) * cosf ( a_Pitch / 180 * PI); - a_X = cos(a_Pan / 180 * PI) * cos(a_Pitch / 180 * PI); - a_Y = sin(a_Pan / 180 * PI) * cos(a_Pitch / 180 * PI); - a_Z = sin(a_Pitch / 180 * PI); + a_X = cos(a_Pan / 180 * M_PI) * cos(a_Pitch / 180 * M_PI); + a_Y = sin(a_Pan / 180 * M_PI) * cos(a_Pitch / 180 * M_PI); + a_Z = sin(a_Pitch / 180 * M_PI); } @@ -502,10 +502,10 @@ inline void VectorToEuler(double a_X, double a_Y, double a_Z, double & a_Pan, do } else { - a_Pan = atan2(a_Z, a_X) * 180 / PI - 90; + a_Pan = atan2(a_Z, a_X) * 180 / M_PI - 90; } - a_Pitch = atan2(a_Y, r) * 180 / PI; + a_Pitch = atan2(a_Y, r) * 180 / M_PI; } diff --git a/src/Entities/ArrowEntity.cpp b/src/Entities/ArrowEntity.cpp index 7e429c62e..30f18f677 100644 --- a/src/Entities/ArrowEntity.cpp +++ b/src/Entities/ArrowEntity.cpp @@ -217,7 +217,7 @@ void cArrowEntity::Tick(float a_Dt, cChunk & a_Chunk) int RelPosZ = m_HitBlockPos.z - a_Chunk.GetPosZ() * cChunkDef::Width; cChunk * Chunk = a_Chunk.GetRelNeighborChunkAdjustCoords(RelPosX, RelPosZ); - if (Chunk == NULL) + if (Chunk == nullptr) { // Inside an unloaded chunk, abort return; diff --git a/src/Entities/Boat.cpp b/src/Entities/Boat.cpp index 328a70846..953213bca 100644 --- a/src/Entities/Boat.cpp +++ b/src/Entities/Boat.cpp @@ -42,7 +42,7 @@ bool cBoat::DoTakeDamage(TakeDamageInfo & TDI) if (GetHealth() == 0) { - if (TDI.Attacker != NULL) + if (TDI.Attacker != nullptr) { if (TDI.Attacker->IsPlayer()) { @@ -64,7 +64,7 @@ void cBoat::OnRightClicked(cPlayer & a_Player) { super::OnRightClicked(a_Player); - if (m_Attachee != NULL) + if (m_Attachee != nullptr) { if (m_Attachee->GetUniqueID() == a_Player.GetUniqueID()) { diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index da85dec50..afc61c73f 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -29,8 +29,8 @@ cEntity::cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z, d : m_UniqueID(0) , m_Health(1) , m_MaxHealth(1) - , m_AttachedTo(NULL) - , m_Attachee(NULL) + , m_AttachedTo(nullptr) + , m_Attachee(nullptr) , m_bDirtyHead(true) , m_bDirtyOrientation(true) , m_bHasSentNoSpeed(true) @@ -38,9 +38,9 @@ cEntity::cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z, d , m_Gravity(-9.81f) , m_LastPos(a_X, a_Y, a_Z) , m_IsInitialized(false) - , m_WorldTravellingFrom(NULL) + , m_WorldTravellingFrom(nullptr) , m_EntityType(a_EntityType) - , m_World(NULL) + , m_World(nullptr) , m_IsFireproof(false) , m_TicksSinceLastBurnDamage(0) , m_TicksSinceLastLavaDamage(0) @@ -73,7 +73,7 @@ cEntity::cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z, d cEntity::~cEntity() { // Before deleting, the entity needs to have been removed from the world, if ever added - ASSERT((m_World == NULL) || !m_World->HasEntity(m_UniqueID)); + ASSERT((m_World == nullptr) || !m_World->HasEntity(m_UniqueID)); /* // DEBUG: @@ -85,11 +85,11 @@ cEntity::~cEntity() ); */ - if (m_AttachedTo != NULL) + if (m_AttachedTo != nullptr) { Detach(); } - if (m_Attachee != NULL) + if (m_Attachee != nullptr) { m_Attachee->Detach(); } @@ -242,7 +242,7 @@ void cEntity::TakeDamage(eDamageType a_DamageType, cEntity * a_Attacker, int a_R TDI.FinalDamage = a_FinalDamage; Vector3d Heading(0, 0, 0); - if (a_Attacker != NULL) + if (a_Attacker != nullptr) { Heading = a_Attacker->GetLookVector() * (a_Attacker->IsSprinting() ? 16 : 11); Heading.y = 1.6; @@ -265,7 +265,7 @@ void cEntity::SetYawFromSpeed(void) SetYaw(0); return; } - SetYaw(atan2(m_Speed.x, m_Speed.z) * 180 / PI); + SetYaw(atan2(m_Speed.x, m_Speed.z) * 180 / M_PI); } @@ -282,7 +282,7 @@ void cEntity::SetPitchFromSpeed(void) SetPitch(0); return; } - SetPitch(atan2(m_Speed.y, xz) * 180 / PI); + SetPitch(atan2(m_Speed.y, xz) * 180 / M_PI); } @@ -308,7 +308,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) return false; } - if ((a_TDI.Attacker != NULL) && (a_TDI.Attacker->IsPlayer())) + if ((a_TDI.Attacker != nullptr) && (a_TDI.Attacker->IsPlayer())) { cPlayer * Player = (cPlayer *)a_TDI.Attacker; @@ -544,7 +544,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) m_Health = std::max(m_Health, 0); // Add knockback: - if ((IsMob() || IsPlayer()) && (a_TDI.Attacker != NULL)) + if ((IsMob() || IsPlayer()) && (a_TDI.Attacker != nullptr)) { int KnockbackLevel = a_TDI.Attacker->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchKnockback); // More common enchantment if (KnockbackLevel < 1) @@ -571,7 +571,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) { KilledBy(a_TDI); - if (a_TDI.Attacker != NULL) + if (a_TDI.Attacker != nullptr) { a_TDI.Attacker->Killed(this); } @@ -778,7 +778,7 @@ void cEntity::Tick(float a_Dt, cChunk & a_Chunk) m_InvulnerableTicks--; } - if (m_AttachedTo != NULL) + if (m_AttachedTo != nullptr) { Vector3d DeltaPos = m_Pos - m_AttachedTo->GetPosition(); if (DeltaPos.Length() > 0.5) @@ -1092,7 +1092,7 @@ void cEntity::TickBurning(cChunk & a_Chunk) { if (!m_IsFireproof) { - TakeDamage(dtOnFire, NULL, BURN_DAMAGE, 0); + TakeDamage(dtOnFire, nullptr, BURN_DAMAGE, 0); } m_TicksSinceLastBurnDamage = 0; } @@ -1163,7 +1163,7 @@ void cEntity::TickBurning(cChunk & a_Chunk) { if (!m_IsFireproof) { - TakeDamage(dtLavaContact, NULL, LAVA_DAMAGE, 0); + TakeDamage(dtLavaContact, nullptr, LAVA_DAMAGE, 0); } m_TicksSinceLastLavaDamage = 0; } @@ -1184,7 +1184,7 @@ void cEntity::TickBurning(cChunk & a_Chunk) { if (!m_IsFireproof) { - TakeDamage(dtFireContact, NULL, FIRE_DAMAGE, 0); + TakeDamage(dtFireContact, nullptr, FIRE_DAMAGE, 0); } m_TicksSinceLastFireDamage = 0; } @@ -1213,7 +1213,7 @@ void cEntity::TickInVoid(cChunk & a_Chunk) { if (m_TicksSinceLastVoidDamage == 20) { - TakeDamage(dtInVoid, NULL, 2, 0); + TakeDamage(dtInVoid, nullptr, 2, 0); m_TicksSinceLastVoidDamage = 0; } else @@ -1239,7 +1239,7 @@ void cEntity::DetectCacti(void) (((GetPosY() - Y < 1) && (GetWorld()->GetBlock(X, Y, Z) == E_BLOCK_CACTUS)))) ) { - TakeDamage(dtCactusContact, NULL, 1, 0); + TakeDamage(dtCactusContact, nullptr, 1, 0); } } @@ -1380,7 +1380,7 @@ bool cEntity::DetectPortal() bool cEntity::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn) { UNUSED(a_ShouldSendRespawn); - ASSERT(a_World != NULL); + ASSERT(a_World != nullptr); if (GetWorld() == a_World) { @@ -1406,7 +1406,7 @@ bool cEntity::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn) bool cEntity::MoveToWorld(const AString & a_WorldName, bool a_ShouldSendRespawn) { cWorld * World = cRoot::Get()->GetWorld(a_WorldName); - if (World == NULL) + if (World == nullptr) { LOG("%s: Couldn't find world \"%s\".", __FUNCTION__, a_WorldName.c_str()); return false; @@ -1493,7 +1493,7 @@ void cEntity::HandleAir(void) if (m_AirTickTimer <= 0) { // Damage player - TakeDamage(dtDrowning, NULL, 1, 1, 0); + TakeDamage(dtDrowning, nullptr, 1, 1, 0); // Reset timer m_AirTickTimer = DROWNING_TICKS; } @@ -1708,7 +1708,7 @@ void cEntity::AttachTo(cEntity * a_AttachTo) // Already attached to that entity, nothing to do here return; } - if (m_AttachedTo != NULL) + if (m_AttachedTo != nullptr) { // Detach from any previous entity: Detach(); @@ -1726,14 +1726,14 @@ void cEntity::AttachTo(cEntity * a_AttachTo) void cEntity::Detach(void) { - if (m_AttachedTo == NULL) + if (m_AttachedTo == nullptr) { // Attached to no entity, our work is done return; } - m_AttachedTo->m_Attachee = NULL; - m_AttachedTo = NULL; - m_World->BroadcastAttachEntity(*this, NULL); + m_AttachedTo->m_Attachee = nullptr; + m_AttachedTo = nullptr; + m_World->BroadcastAttachEntity(*this, nullptr); } @@ -1956,7 +1956,7 @@ void cEntity::HandleSpeedFromAttachee(float a_Forward, float a_Sideways) void cEntity::SteerVehicle(float a_Forward, float a_Sideways) { - if (m_AttachedTo == NULL) + if (m_AttachedTo == nullptr) { return; } diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h index 07754791d..af545fe4a 100644 --- a/src/Entities/Entity.h +++ b/src/Entities/Entity.h @@ -32,7 +32,7 @@ #define POSZ_TOINT FloorC(GetPosZ()) #define POS_TOINT Vector3i(POSXTOINT, POSYTOINT, POSZTOINT) -#define GET_AND_VERIFY_CURRENT_CHUNK(ChunkVarName, X, Z) cChunk * ChunkVarName = a_Chunk.GetNeighborChunk(X, Z); if ((ChunkVarName == NULL) || !ChunkVarName->IsValid()) { return; } +#define GET_AND_VERIFY_CURRENT_CHUNK(ChunkVarName, X, Z) cChunk * ChunkVarName = a_Chunk.GetNeighborChunk(X, Z); if ((ChunkVarName == nullptr) || !ChunkVarName->IsValid()) { return; } @@ -309,7 +309,7 @@ public: /// Returns the currently equipped boots; empty item if none virtual cItem GetEquippedBoots(void) const { return cItem(); } - /// Called when the health drops below zero. a_Killer may be NULL (environmental damage) + /// Called when the health drops below zero. a_Killer may be nullptr (environmental damage) virtual void KilledBy(TakeDamageInfo & a_TDI); /// Called when the entity kills another entity @@ -401,7 +401,7 @@ public: void SetWorldTravellingFrom(cWorld * a_World) { m_WorldTravellingFrom = a_World; } /// Updates clients of changes in the entity. - virtual void BroadcastMovementUpdate(const cClientHandle * a_Exclude = NULL); + virtual void BroadcastMovementUpdate(const cClientHandle * a_Exclude = nullptr); /// Attaches to the specified entity; detaches from any previous one first void AttachTo(cEntity * a_AttachTo); @@ -450,7 +450,7 @@ public: virtual void OnRightClicked(cPlayer & a_Player) {} /// Returns the list of drops for this pawn when it is killed. May check a_Killer for special handling (sword of looting etc.). Called from KilledBy(). - virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) { UNUSED(a_Drops); UNUSED(a_Killer); @@ -471,10 +471,10 @@ protected: int m_Health; int m_MaxHealth; - /// The entity to which this entity is attached (vehicle), NULL if none + /// The entity to which this entity is attached (vehicle), nullptr if none cEntity * m_AttachedTo; - /// The entity which is attached to this entity (rider), NULL if none + /// The entity which is attached to this entity (rider), nullptr if none cEntity * m_Attachee; /** Stores whether head yaw has been set manually */ @@ -502,7 +502,7 @@ protected: bool m_IsInitialized; /** World entity is travelling from - Set to a valid world pointer by MoveToWorld; reset to NULL when the entity is removed from the old world + Set to a valid world pointer by MoveToWorld; reset to nullptr when the entity is removed from the old world Can't be a simple boolean as context switches between worlds may leave the new chunk processing (and therefore immediately removing) the entity before the old chunk could remove it */ cWorld * m_WorldTravellingFrom; diff --git a/src/Entities/EntityEffect.cpp b/src/Entities/EntityEffect.cpp index b1ddaa30e..bae686b77 100644 --- a/src/Entities/EntityEffect.cpp +++ b/src/Entities/EntityEffect.cpp @@ -216,7 +216,7 @@ cEntityEffect * cEntityEffect::CreateEntityEffect(cEntityEffect::eType a_EffectT } ASSERT(!"Unhandled entity effect type!"); - return NULL; + return nullptr; } @@ -329,7 +329,7 @@ void cEntityEffectInstantHealth::OnActivate(cPawn & a_Target) if (a_Target.IsMob() && ((cMonster &) a_Target).IsUndead()) { - a_Target.TakeDamage(dtPotionOfHarming, NULL, amount, 0); // TODO: Store attacker in a pointer-safe way, pass to TakeDamage + a_Target.TakeDamage(dtPotionOfHarming, nullptr, amount, 0); // TODO: Store attacker in a pointer-safe way, pass to TakeDamage return; } a_Target.Heal(amount); @@ -352,7 +352,7 @@ void cEntityEffectInstantDamage::OnActivate(cPawn & a_Target) a_Target.Heal(amount); return; } - a_Target.TakeDamage(dtPotionOfHarming, NULL, amount, 0); // TODO: Store attacker in a pointer-safe way, pass to TakeDamage + a_Target.TakeDamage(dtPotionOfHarming, nullptr, amount, 0); // TODO: Store attacker in a pointer-safe way, pass to TakeDamage } @@ -452,7 +452,7 @@ void cEntityEffectPoison::OnTick(cPawn & a_Target) // Cannot take poison damage when health is at 1 if (a_Target.GetHealth() > 1) { - a_Target.TakeDamage(dtPoisoning, NULL, 1, 0); + a_Target.TakeDamage(dtPoisoning, nullptr, 1, 0); } } } @@ -473,7 +473,7 @@ void cEntityEffectWither::OnTick(cPawn & a_Target) if ((m_Ticks % frequency) == 0) { - a_Target.TakeDamage(dtWither, NULL, 1, 0); + a_Target.TakeDamage(dtWither, nullptr, 1, 0); } } diff --git a/src/Entities/ExpOrb.cpp b/src/Entities/ExpOrb.cpp index 73d5cbfed..751308661 100644 --- a/src/Entities/ExpOrb.cpp +++ b/src/Entities/ExpOrb.cpp @@ -45,7 +45,7 @@ void cExpOrb::SpawnOn(cClientHandle & a_Client) void cExpOrb::Tick(float a_Dt, cChunk & a_Chunk) { cPlayer * a_ClosestPlayer(m_World->FindClosestPlayer(Vector3f(GetPosition()), 5)); - if (a_ClosestPlayer != NULL) + if (a_ClosestPlayer != nullptr) { Vector3f a_PlayerPos(a_ClosestPlayer->GetPosition()); a_PlayerPos.y++; diff --git a/src/Entities/Floater.cpp b/src/Entities/Floater.cpp index 159429147..5fe6a1238 100644 --- a/src/Entities/Floater.cpp +++ b/src/Entities/Floater.cpp @@ -22,7 +22,7 @@ public: m_Pos(a_Pos), m_NextPos(a_NextPos), m_MinCoeff(1), - m_HitEntity(NULL) + m_HitEntity(nullptr) { } virtual bool Item(cEntity * a_Entity) override diff --git a/src/Entities/ItemFrame.cpp b/src/Entities/ItemFrame.cpp index f512324eb..b7aac52d0 100644 --- a/src/Entities/ItemFrame.cpp +++ b/src/Entities/ItemFrame.cpp @@ -62,7 +62,7 @@ void cItemFrame::KilledBy(TakeDamageInfo & a_TDI) return; } - if ((a_TDI.Attacker != NULL) && a_TDI.Attacker->IsPlayer() && !((cPlayer *)a_TDI.Attacker)->IsGameModeCreative()) + if ((a_TDI.Attacker != nullptr) && a_TDI.Attacker->IsPlayer() && !((cPlayer *)a_TDI.Attacker)->IsGameModeCreative()) { cItems Item; Item.push_back(m_Item); @@ -83,7 +83,7 @@ void cItemFrame::KilledBy(TakeDamageInfo & a_TDI) void cItemFrame::GetDrops(cItems & a_Items, cEntity * a_Killer) { - if ((a_Killer != NULL) && a_Killer->IsPlayer() && !((cPlayer *)a_Killer)->IsGameModeCreative()) + if ((a_Killer != nullptr) && a_Killer->IsPlayer() && !((cPlayer *)a_Killer)->IsGameModeCreative()) { a_Items.push_back(cItem(E_ITEM_ITEM_FRAME)); } diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index f45e7bb69..22e046800 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -36,7 +36,7 @@ public: virtual bool Item(cEntity * a_Entity) override { - ASSERT(a_Entity != NULL); + ASSERT(a_Entity != nullptr); if (!a_Entity->IsPlayer() && !a_Entity->IsMob() && !a_Entity->IsMinecart() && !a_Entity->IsBoat()) { @@ -130,7 +130,7 @@ void cMinecart::HandlePhysics(float a_Dt, cChunk & a_Chunk) int RelPosX = POSX_TOINT - a_Chunk.GetPosX() * cChunkDef::Width; int RelPosZ = POSZ_TOINT - a_Chunk.GetPosZ() * cChunkDef::Width; cChunk * Chunk = a_Chunk.GetRelNeighborChunkAdjustCoords(RelPosX, RelPosZ); - if (Chunk == NULL) + if (Chunk == nullptr) { // Inside an unloaded chunk, bail out all processing return; @@ -806,7 +806,7 @@ bool cMinecart::TestBlockCollision(NIBBLETYPE a_RailMeta) bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) { - cMinecartCollisionCallback MinecartCollisionCallback(GetPosition(), GetHeight(), GetWidth(), GetUniqueID(), ((m_Attachee == NULL) ? -1 : m_Attachee->GetUniqueID())); + cMinecartCollisionCallback MinecartCollisionCallback(GetPosition(), GetHeight(), GetWidth(), GetUniqueID(), ((m_Attachee == nullptr) ? -1 : m_Attachee->GetUniqueID())); int ChunkX, ChunkZ; cChunkDef::BlockToChunk(POSX_TOINT, POSZ_TOINT, ChunkX, ChunkZ); m_World->ForEachEntityInChunk(ChunkX, ChunkZ, MinecartCollisionCallback); @@ -980,7 +980,7 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) bool cMinecart::DoTakeDamage(TakeDamageInfo & TDI) { - if ((TDI.Attacker != NULL) && TDI.Attacker->IsPlayer() && ((cPlayer *)TDI.Attacker)->IsGameModeCreative()) + if ((TDI.Attacker != nullptr) && TDI.Attacker->IsPlayer() && ((cPlayer *)TDI.Attacker)->IsGameModeCreative()) { Destroy(); TDI.FinalDamage = GetMaxHealth(); // Instant hit for creative @@ -1074,7 +1074,7 @@ void cRideableMinecart::OnRightClicked(cPlayer & a_Player) { super::OnRightClicked(a_Player); - if (m_Attachee != NULL) + if (m_Attachee != nullptr) { if (m_Attachee->GetUniqueID() == a_Player.GetUniqueID()) { @@ -1120,14 +1120,14 @@ void cMinecartWithChest::OnRightClicked(cPlayer & a_Player) { // If the window is not created, open it anew: cWindow * Window = GetWindow(); - if (Window == NULL) + if (Window == nullptr) { OpenNewWindow(); Window = GetWindow(); } // Open the window for the player: - if (Window != NULL) + if (Window != nullptr) { if (a_Player.GetWindow() != Window) { diff --git a/src/Entities/Minecart.h b/src/Entities/Minecart.h index ab906fd06..40e22c641 100644 --- a/src/Entities/Minecart.h +++ b/src/Entities/Minecart.h @@ -140,9 +140,9 @@ protected: { UNUSED(a_SlotNum); ASSERT(a_Grid == &m_Contents); - if (m_World != NULL) + if (m_World != nullptr) { - if (GetWindow() != NULL) + if (GetWindow() != nullptr) { GetWindow()->BroadcastWholeWindow(); } diff --git a/src/Entities/Painting.cpp b/src/Entities/Painting.cpp index e217556c7..1aa6da0a1 100644 --- a/src/Entities/Painting.cpp +++ b/src/Entities/Painting.cpp @@ -43,7 +43,7 @@ void cPainting::Tick(float a_Dt, cChunk & a_Chunk) void cPainting::GetDrops(cItems & a_Items, cEntity * a_Killer) { - if ((a_Killer != NULL) && a_Killer->IsPlayer() && !((cPlayer *)a_Killer)->IsGameModeCreative()) + if ((a_Killer != nullptr) && a_Killer->IsPlayer() && !((cPlayer *)a_Killer)->IsGameModeCreative()) { a_Items.push_back(cItem(E_ITEM_PAINTING)); } diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 24daba048..b417feb86 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -55,8 +55,8 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) : m_Stance(0.0), m_Inventory(*this), m_EnderChestContents(9, 3), - m_CurrentWindow(NULL), - m_InventoryWindow(NULL), + m_CurrentWindow(nullptr), + m_InventoryWindow(nullptr), m_GameMode(eGameMode_NotSet), m_IP(""), m_ClientHandle(a_Client), @@ -77,10 +77,10 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) : m_IsChargingBow(false), m_BowCharge(0), m_FloaterID(-1), - m_Team(NULL), + m_Team(nullptr), m_TicksUntilNextSave(PLAYER_INVENTORY_SAVE_INTERVAL), m_bIsTeleporting(false), - m_UUID((a_Client != NULL) ? a_Client->GetUUID() : ""), + m_UUID((a_Client != nullptr) ? a_Client->GetUUID() : ""), m_CustomName("") { m_InventoryWindow = new cInventoryWindow(*this); @@ -93,7 +93,7 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) : m_LastPlayerListTime = std::chrono::steady_clock::now(); m_PlayerName = a_PlayerName; - cWorld * World = NULL; + cWorld * World = nullptr; if (!LoadFromDisk(World)) { m_Inventory.Clear(); @@ -141,10 +141,10 @@ cPlayer::~cPlayer(void) SaveToDisk(); - m_ClientHandle = NULL; + m_ClientHandle = nullptr; delete m_InventoryWindow; - m_InventoryWindow = NULL; + m_InventoryWindow = nullptr; LOGD("Player %p deleted", this); } @@ -183,12 +183,12 @@ void cPlayer::SpawnOn(cClientHandle & a_Client) void cPlayer::Tick(float a_Dt, cChunk & a_Chunk) { - if (m_ClientHandle != NULL) + if (m_ClientHandle != nullptr) { if (m_ClientHandle->IsDestroyed()) { // This should not happen, because destroying a client will remove it from the world, but just in case - m_ClientHandle = NULL; + m_ClientHandle = nullptr; return; } @@ -500,7 +500,7 @@ void cPlayer::SetTouchGround(bool a_bTouchGround) if (Damage > 0) { // cPlayer makes sure damage isn't applied in creative, no need to check here - TakeDamage(dtFalling, NULL, Damage, Damage, 0); + TakeDamage(dtFalling, nullptr, Damage, Damage, 0); // Fall particles GetWorld()->BroadcastSoundParticleEffect(2006, POSX_TOINT, (int)GetPosY() - 1, POSZ_TOINT, Damage /* Used as particle effect speed modifier */); @@ -647,7 +647,7 @@ void cPlayer::AbortEating(void) void cPlayer::SendHealth(void) { - if (m_ClientHandle != NULL) + if (m_ClientHandle != nullptr) { m_ClientHandle->SendHealth(); } @@ -659,7 +659,7 @@ void cPlayer::SendHealth(void) void cPlayer::SendExperience(void) { - if (m_ClientHandle != NULL) + if (m_ClientHandle != nullptr) { m_ClientHandle->SendExperience(); m_bDirtyExperience = false; @@ -855,11 +855,11 @@ bool cPlayer::DoTakeDamage(TakeDamageInfo & a_TDI) } } - if ((a_TDI.Attacker != NULL) && (a_TDI.Attacker->IsPlayer())) + if ((a_TDI.Attacker != nullptr) && (a_TDI.Attacker->IsPlayer())) { cPlayer * Attacker = (cPlayer *)a_TDI.Attacker; - if ((m_Team != NULL) && (m_Team == Attacker->m_Team)) + if ((m_Team != nullptr) && (m_Team == Attacker->m_Team)) { if (!m_Team->AllowsFriendlyFire()) { @@ -911,7 +911,7 @@ void cPlayer::KilledBy(TakeDamageInfo & a_TDI) m_World->SpawnItemPickups(Pickups, GetPosX(), GetPosY(), GetPosZ(), 10); SaveToDisk(); // Save it, yeah the world is a tough place ! - if ((a_TDI.Attacker == NULL) && m_World->ShouldBroadcastDeathMessages()) + if ((a_TDI.Attacker == nullptr) && m_World->ShouldBroadcastDeathMessages()) { AString DamageText; switch (a_TDI.DamageType) @@ -937,7 +937,7 @@ void cPlayer::KilledBy(TakeDamageInfo & a_TDI) } GetWorld()->BroadcastChatDeath(Printf("%s %s", GetName().c_str(), DamageText.c_str())); } - else if (a_TDI.Attacker == NULL) // && !m_World->ShouldBroadcastDeathMessages() by fallthrough + else if (a_TDI.Attacker == nullptr) // && !m_World->ShouldBroadcastDeathMessages() by fallthrough { // no-op } @@ -993,7 +993,7 @@ void cPlayer::Killed(cEntity * a_Victim) void cPlayer::Respawn(void) { - ASSERT(m_World != NULL); + ASSERT(m_World != nullptr); m_Health = GetMaxHealth(); SetInvulnerableTicks(20); @@ -1103,9 +1103,9 @@ void cPlayer::SetTeam(cTeam * a_Team) cTeam * cPlayer::UpdateTeam(void) { - if (m_World == NULL) + if (m_World == nullptr) { - SetTeam(NULL); + SetTeam(nullptr); } else { @@ -1138,7 +1138,7 @@ void cPlayer::OpenWindow(cWindow * a_Window) void cPlayer::CloseWindow(bool a_CanRefuse) { - if (m_CurrentWindow == NULL) + if (m_CurrentWindow == nullptr) { m_CurrentWindow = m_InventoryWindow; return; @@ -1163,7 +1163,7 @@ void cPlayer::CloseWindow(bool a_CanRefuse) void cPlayer::CloseWindowIfID(char a_WindowID, bool a_CanRefuse) { - if ((m_CurrentWindow == NULL) || (m_CurrentWindow->GetWindowID() != a_WindowID)) + if ((m_CurrentWindow == nullptr) || (m_CurrentWindow->GetWindowID() != a_WindowID)) { return; } @@ -1350,7 +1350,7 @@ void cPlayer::MoveTo( const Vector3d & a_NewPos) // Y = -999 and X, Z = attempting to create speed, usually up to 0.03 // We cannot test m_AttachedTo, because when deattaching, the server thinks the client is already deattached while // the client may still send more of these nonsensical packets. - if (m_AttachedTo != NULL) + if (m_AttachedTo != nullptr) { Vector3d AddSpeed(a_NewPos); AddSpeed.y = 0; @@ -1577,7 +1577,7 @@ void cPlayer::TossItems(const cItems & a_Items) bool cPlayer::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn) { - ASSERT(a_World != NULL); + ASSERT(a_World != nullptr); if (GetWorld() == a_World) { @@ -1586,7 +1586,7 @@ bool cPlayer::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn) } // Send the respawn packet: - if (a_ShouldSendRespawn && (m_ClientHandle != NULL)) + if (a_ShouldSendRespawn && (m_ClientHandle != nullptr)) { m_ClientHandle->SendRespawn(a_World->GetDimension()); } @@ -1648,7 +1648,7 @@ bool cPlayer::LoadFromDisk(cWorldPtr & a_World) GetName().c_str(), m_UUID.c_str(), OfflineUUID.c_str(), OfflineUsage ); - if (a_World == NULL) + if (a_World == nullptr) { a_World = cRoot::Get()->GetDefaultWorld(); } @@ -1725,7 +1725,7 @@ bool cPlayer::LoadFromFile(const AString & a_FileName, cWorldPtr & a_World) m_LoadedWorldName = root.get("world", "world").asString(); a_World = cRoot::Get()->GetWorld(GetLoadedWorldName(), false); - if (a_World == NULL) + if (a_World == nullptr) { a_World = cRoot::Get()->GetDefaultWorld(); } @@ -1791,7 +1791,7 @@ bool cPlayer::SaveToDisk() root["SpawnY"] = GetLastBedPos().y; root["SpawnZ"] = GetLastBedPos().z; - if (m_World != NULL) + if (m_World != nullptr) { root["world"] = m_World->GetName(); if (m_GameMode == m_World->GetGameMode()) @@ -1945,7 +1945,7 @@ void cPlayer::HandleFood(void) else if ((m_FoodLevel <= 0) && (m_Health > 1)) { // Damage from starving - TakeDamage(dtStarving, NULL, 1, 1, 0); + TakeDamage(dtStarving, nullptr, 1, 1, 0); } } } @@ -2014,7 +2014,7 @@ void cPlayer::UpdateMovementStats(const Vector3d & a_DeltaPos) { StatValue Value = (StatValue)floor(a_DeltaPos.Length() * 100 + 0.5); - if (m_AttachedTo == NULL) + if (m_AttachedTo == nullptr) { if (IsClimbing()) { @@ -2087,7 +2087,7 @@ void cPlayer::ApplyFoodExhaustionFromMovement() } // If riding anything, apply no food exhaustion - if (m_AttachedTo != NULL) + if (m_AttachedTo != nullptr) { return; } diff --git a/src/Entities/Player.h b/src/Entities/Player.h index 8dd5bdb19..c643aaa8e 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -176,10 +176,10 @@ public: AString GetIP(void) const { return m_IP; } // tolua_export - /** Returns the associated team, NULL if none */ + /** Returns the associated team, nullptr if none */ cTeam * GetTeam(void) { return m_Team; } // tolua_export - /** Sets the player team, NULL if none */ + /** Sets the player team, nullptr if none */ void SetTeam(cTeam * a_Team); // tolua_end diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp index ab25ac30c..1768714f8 100644 --- a/src/Entities/ProjectileEntity.cpp +++ b/src/Entities/ProjectileEntity.cpp @@ -135,7 +135,7 @@ public: m_Pos(a_Pos), m_NextPos(a_NextPos), m_MinCoeff(1), - m_HitEntity(NULL) + m_HitEntity(nullptr) { } @@ -221,9 +221,9 @@ cProjectileEntity::cProjectileEntity(eKind a_Kind, cEntity * a_Creator, double a super(etProjectile, a_X, a_Y, a_Z, a_Width, a_Height), m_ProjectileKind(a_Kind), m_CreatorData( - ((a_Creator != NULL) ? a_Creator->GetUniqueID() : -1), - ((a_Creator != NULL) ? (a_Creator->IsPlayer() ? ((cPlayer *)a_Creator)->GetName() : "") : ""), - ((a_Creator != NULL) ? a_Creator->GetEquippedWeapon().m_Enchantments : cEnchantments()) + ((a_Creator != nullptr) ? a_Creator->GetUniqueID() : -1), + ((a_Creator != nullptr) ? (a_Creator->IsPlayer() ? ((cPlayer *)a_Creator)->GetName() : "") : ""), + ((a_Creator != nullptr) ? a_Creator->GetEquippedWeapon().m_Enchantments : cEnchantments()) ), m_IsInGround(false) { @@ -251,7 +251,7 @@ cProjectileEntity::cProjectileEntity(eKind a_Kind, cEntity * a_Creator, const Ve cProjectileEntity * cProjectileEntity::Create(eKind a_Kind, cEntity * a_Creator, double a_X, double a_Y, double a_Z, const cItem * a_Item, const Vector3d * a_Speed) { Vector3d Speed; - if (a_Speed != NULL) + if (a_Speed != nullptr) { Speed = *a_Speed; } @@ -269,10 +269,10 @@ cProjectileEntity * cProjectileEntity::Create(eKind a_Kind, cEntity * a_Creator, case pkWitherSkull: return new cWitherSkullEntity (a_Creator, a_X, a_Y, a_Z, Speed); case pkFirework: { - ASSERT(a_Item != NULL); + ASSERT(a_Item != nullptr); if (a_Item->m_FireworkItem.m_Colours.empty()) { - return NULL; + return nullptr; } return new cFireworkEntity(a_Creator, a_X, a_Y, a_Z, *a_Item); @@ -280,7 +280,7 @@ cProjectileEntity * cProjectileEntity::Create(eKind a_Kind, cEntity * a_Creator, } LOGWARNING("%s: Unknown projectile kind: %d", __FUNCTION__, a_Kind); - return NULL; + return nullptr; } diff --git a/src/Entities/ProjectileEntity.h b/src/Entities/ProjectileEntity.h index 03eda9739..3861f9ecc 100644 --- a/src/Entities/ProjectileEntity.h +++ b/src/Entities/ProjectileEntity.h @@ -46,7 +46,7 @@ public: cProjectileEntity(eKind a_Kind, cEntity * a_Creator, double a_X, double a_Y, double a_Z, double a_Width, double a_Height); cProjectileEntity(eKind a_Kind, cEntity * a_Creator, const Vector3d & a_Pos, const Vector3d & a_Speed, double a_Width, double a_Height); - static cProjectileEntity * Create(eKind a_Kind, cEntity * a_Creator, double a_X, double a_Y, double a_Z, const cItem * a_Item, const Vector3d * a_Speed = NULL); + static cProjectileEntity * Create(eKind a_Kind, cEntity * a_Creator, double a_X, double a_Y, double a_Z, const cItem * a_Item, const Vector3d * a_Speed = nullptr); /// Called by the physics blocktracer when the entity hits a solid block, the hit position and the face hit (BLOCK_FACE_) is given virtual void OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace); @@ -110,7 +110,7 @@ protected: eKind m_ProjectileKind; /** The structure for containing the entity ID and name who has created this projectile - The ID and/or name may be NULL (e.g. for dispensers/mobs) + The ID and/or name may be nullptr (e.g. for dispensers/mobs) */ CreatorData m_CreatorData; diff --git a/src/FurnaceRecipe.cpp b/src/FurnaceRecipe.cpp index d200ef3d7..9b3b2ecbe 100644 --- a/src/FurnaceRecipe.cpp +++ b/src/FurnaceRecipe.cpp @@ -43,7 +43,7 @@ cFurnaceRecipe::~cFurnaceRecipe() { ClearRecipes(); delete m_pState; - m_pState = NULL; + m_pState = nullptr; } @@ -247,9 +247,9 @@ void cFurnaceRecipe::ClearRecipes(void) { cRecipe Recipe = *itr; delete Recipe.In; - Recipe.In = NULL; + Recipe.In = nullptr; delete Recipe.Out; - Recipe.Out = NULL; + Recipe.Out = nullptr; } m_pState->Recipes.clear(); @@ -257,7 +257,7 @@ void cFurnaceRecipe::ClearRecipes(void) { cFuel Fuel = *itr; delete Fuel.In; - Fuel.In = NULL; + Fuel.In = nullptr; } m_pState->Fuel.clear(); } diff --git a/src/FurnaceRecipe.h b/src/FurnaceRecipe.h index 6a1650695..936ef706d 100644 --- a/src/FurnaceRecipe.h +++ b/src/FurnaceRecipe.h @@ -32,7 +32,7 @@ public: int CookTime; ///< How long this recipe takes to smelt, in ticks }; - /** Returns a recipe for the specified input, NULL if no recipe found */ + /** Returns a recipe for the specified input, nullptr if no recipe found */ const cRecipe * GetRecipeFrom(const cItem & a_Ingredient) const; /** Returns the amount of time that the specified fuel burns, in ticks */ diff --git a/src/Generating/BioGen.cpp b/src/Generating/BioGen.cpp index b9face1f8..d86d44bbc 100644 --- a/src/Generating/BioGen.cpp +++ b/src/Generating/BioGen.cpp @@ -69,9 +69,9 @@ cBioGenCache::cBioGenCache(cBiomeGenPtr a_BioGenToCache, int a_CacheSize) : cBioGenCache::~cBioGenCache() { delete[] m_CacheData; - m_CacheData = NULL; + m_CacheData = nullptr; delete[] m_CacheOrder; - m_CacheOrder = NULL; + m_CacheOrder = nullptr; } @@ -928,7 +928,7 @@ cBiomeGenPtr cBiomeGen::CreateBiomeGen(cIniFile & a_IniFile, int a_Seed, bool & BiomeGenName = "MultiStepMap"; } - cBiomeGen * res = NULL; + cBiomeGen * res = nullptr; a_CacheOffByDefault = false; if (NoCaseCompare(BiomeGenName, "constant") == 0) { diff --git a/src/Generating/ChunkDesc.cpp b/src/Generating/ChunkDesc.cpp index 566332b1f..020d3bd0f 100644 --- a/src/Generating/ChunkDesc.cpp +++ b/src/Generating/ChunkDesc.cpp @@ -530,10 +530,10 @@ cBlockEntity * cChunkDesc::GetBlockEntity(int a_RelX, int a_RelY, int a_RelZ) // The block entity is not created yet, try to create it and add to list: cBlockEntity * be = cBlockEntity::CreateByBlockType(GetBlockType(a_RelX, a_RelY, a_RelZ), GetBlockMeta(a_RelX, a_RelY, a_RelZ), AbsX, a_RelY, AbsZ); - if (be == NULL) + if (be == nullptr) { // No block entity for this block type - return NULL; + return nullptr; } m_BlockEntities.push_back(be); return be; diff --git a/src/Generating/ChunkDesc.h b/src/Generating/ChunkDesc.h index eeea0c957..570132790 100644 --- a/src/Generating/ChunkDesc.h +++ b/src/Generating/ChunkDesc.h @@ -172,7 +172,7 @@ public: /** Returns the block entity at the specified coords. If there is no block entity at those coords, tries to create one, based on the block type - If the blocktype doesn't support a block entity, returns NULL. */ + If the blocktype doesn't support a block entity, returns nullptr. */ cBlockEntity * GetBlockEntity(int a_RelX, int a_RelY, int a_RelZ); /** Updates the heightmap to match the current contents. diff --git a/src/Generating/ChunkGenerator.cpp b/src/Generating/ChunkGenerator.cpp index 20b6b7066..b08b9411e 100644 --- a/src/Generating/ChunkGenerator.cpp +++ b/src/Generating/ChunkGenerator.cpp @@ -28,9 +28,9 @@ const unsigned int QUEUE_SKIP_LIMIT = 500; cChunkGenerator::cChunkGenerator(void) : super("cChunkGenerator"), m_Seed(0), // Will be overwritten by the actual generator - m_Generator(NULL), - m_PluginInterface(NULL), - m_ChunkSink(NULL) + m_Generator(nullptr), + m_PluginInterface(nullptr), + m_ChunkSink(nullptr) { } @@ -80,7 +80,7 @@ bool cChunkGenerator::Start(cPluginInterface & a_PluginInterface, cChunkSink & a m_Generator = new cComposableGenerator(*this); } - if (m_Generator == NULL) + if (m_Generator == nullptr) { LOGERROR("Generator could not start, aborting the server"); return false; @@ -103,7 +103,7 @@ void cChunkGenerator::Stop(void) Wait(); delete m_Generator; - m_Generator = NULL; + m_Generator = nullptr; } @@ -144,7 +144,7 @@ void cChunkGenerator::QueueGenerateChunk(int a_ChunkX, int a_ChunkZ, bool a_Forc void cChunkGenerator::GenerateBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) { - if (m_Generator != NULL) + if (m_Generator != nullptr) { m_Generator->GenerateBiomes(a_ChunkX, a_ChunkZ, a_BiomeMap); } @@ -180,7 +180,7 @@ int cChunkGenerator::GetQueueLength(void) EMCSBiome cChunkGenerator::GetBiomeAt(int a_BlockX, int a_BlockZ) { - ASSERT(m_Generator != NULL); + ASSERT(m_Generator != nullptr); return m_Generator->GetBiomeAt(a_BlockX, a_BlockZ); } @@ -283,8 +283,8 @@ void cChunkGenerator::Execute(void) void cChunkGenerator::DoGenerate(int a_ChunkX, int a_ChunkZ) { - ASSERT(m_PluginInterface != NULL); - ASSERT(m_ChunkSink != NULL); + ASSERT(m_PluginInterface != nullptr); + ASSERT(m_ChunkSink != nullptr); ASSERT(m_ChunkSink->IsChunkQueued(a_ChunkX, a_ChunkZ)); cChunkDesc ChunkDesc(a_ChunkX, a_ChunkZ); diff --git a/src/Generating/CompoGen.cpp b/src/Generating/CompoGen.cpp index 0105fdb70..2c88f23f1 100644 --- a/src/Generating/CompoGen.cpp +++ b/src/Generating/CompoGen.cpp @@ -687,9 +687,9 @@ cCompoGenCache::cCompoGenCache(cTerrainCompositionGenPtr a_Underlying, int a_Cac cCompoGenCache::~cCompoGenCache() { delete[] m_CacheData; - m_CacheData = NULL; + m_CacheData = nullptr; delete[] m_CacheOrder; - m_CacheOrder = NULL; + m_CacheOrder = nullptr; } diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index 358d97c92..625dffa84 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -48,7 +48,7 @@ cTerrainCompositionGenPtr cTerrainCompositionGen::CreateCompositionGen(cIniFile CompoGenName = "Biomal"; } - cTerrainCompositionGen * res = NULL; + cTerrainCompositionGen * res = nullptr; if (NoCaseCompare(CompoGenName, "sameblock") == 0) { res = new cCompoGenSameBlock; @@ -102,7 +102,7 @@ cTerrainCompositionGenPtr cTerrainCompositionGen::CreateCompositionGen(cIniFile a_IniFile.SetValue("Generator", "CompositionGen", "Biomal"); return CreateCompositionGen(a_IniFile, a_BiomeGen, a_HeightGen, a_Seed); } - ASSERT(res != NULL); + ASSERT(res != nullptr); // Read the settings from the ini file: res->InitializeCompoGen(a_IniFile); @@ -145,7 +145,7 @@ void cComposableGenerator::Initialize(cIniFile & a_IniFile) void cComposableGenerator::GenerateBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) { - if (m_BiomeGen != NULL) // Quick fix for generator deinitializing before the world storage finishes loading + if (m_BiomeGen != nullptr) // Quick fix for generator deinitializing before the world storage finishes loading { m_BiomeGen->GenBiomes(a_ChunkX, a_ChunkZ, a_BiomeMap); } diff --git a/src/Generating/DungeonRoomsFinisher.cpp b/src/Generating/DungeonRoomsFinisher.cpp index 93fe8b472..3f328868d 100644 --- a/src/Generating/DungeonRoomsFinisher.cpp +++ b/src/Generating/DungeonRoomsFinisher.cpp @@ -198,7 +198,7 @@ protected: } ; cChestEntity * ChestEntity = (cChestEntity *)a_ChunkDesc.GetBlockEntity(RelX, m_FloorHeight + 1, RelZ); - ASSERT((ChestEntity != NULL) && (ChestEntity->GetBlockType() == E_BLOCK_CHEST)); + ASSERT((ChestEntity != nullptr) && (ChestEntity->GetBlockType() == E_BLOCK_CHEST)); cNoise Noise(a_ChunkDesc.GetChunkX() ^ a_ChunkDesc.GetChunkZ()); int NumSlots = 3 + ((Noise.IntNoise3DInt(a_Chest.x, a_Chest.y, a_Chest.z) / 11) % 4); int Seed = Noise.IntNoise2DInt(RelX, RelZ); diff --git a/src/Generating/GridStructGen.cpp b/src/Generating/GridStructGen.cpp index 7090f14b1..3c08c1a39 100644 --- a/src/Generating/GridStructGen.cpp +++ b/src/Generating/GridStructGen.cpp @@ -135,7 +135,7 @@ void cGridStructGen::GetStructuresForChunk(int a_ChunkX, int a_ChunkZ, cStructur int OriginX = GridX + ((m_Noise.IntNoise2DInt(GridX + 3, GridZ + 5) / 7) % (m_MaxOffsetX * 2)) - m_MaxOffsetX; int OriginZ = GridZ + ((m_Noise.IntNoise2DInt(GridX + 5, GridZ + 3) / 7) % (m_MaxOffsetZ * 2)) - m_MaxOffsetZ; cStructurePtr Structure = CreateStructure(GridX, GridZ, OriginX, OriginZ); - if (Structure.get() == NULL) + if (Structure.get() == nullptr) { Structure.reset(new cEmptyStructure(GridX, GridZ, OriginX, OriginZ)); } diff --git a/src/Generating/HeiGen.cpp b/src/Generating/HeiGen.cpp index b7d4b337c..acfefaefc 100644 --- a/src/Generating/HeiGen.cpp +++ b/src/Generating/HeiGen.cpp @@ -29,7 +29,7 @@ cTerrainHeightGenPtr cTerrainHeightGen::CreateHeightGen(cIniFile & a_IniFile, cB } a_CacheOffByDefault = false; - cTerrainHeightGen * res = NULL; + cTerrainHeightGen * res = nullptr; if (NoCaseCompare(HeightGenName, "flat") == 0) { res = new cHeiGenFlat; @@ -142,9 +142,9 @@ cHeiGenCache::cHeiGenCache(cTerrainHeightGenPtr a_HeiGenToCache, int a_CacheSize cHeiGenCache::~cHeiGenCache() { delete[] m_CacheData; - m_CacheData = NULL; + m_CacheData = nullptr; delete[] m_CacheOrder; - m_CacheOrder = NULL; + m_CacheOrder = nullptr; } diff --git a/src/Generating/MineShafts.cpp b/src/Generating/MineShafts.cpp index 0532aff39..55b3b64dd 100644 --- a/src/Generating/MineShafts.cpp +++ b/src/Generating/MineShafts.cpp @@ -112,7 +112,7 @@ class cMineShaftCorridor : public: /** Creates a new Corridor attached to the specified pivot point and direction. Checks all ParentSystem's objects and disallows intersecting. Initializes the new object to fit. - May return NULL if cannot fit. + May return nullptr if cannot fit. */ static cMineShaft * CreateAndFit( cStructGenMineShafts::cMineShaftSystem & a_ParentSystem, @@ -165,7 +165,7 @@ class cMineShaftCrossing : public: /** Creates a new Crossing attached to the specified pivot point and direction. Checks all ParentSystem's objects and disallows intersecting. Initializes the new object to fit. - May return NULL if cannot fit. + May return nullptr if cannot fit. */ static cMineShaft * CreateAndFit( cStructGenMineShafts::cMineShaftSystem & a_ParentSystem, @@ -199,7 +199,7 @@ public: /** Creates a new Staircase attached to the specified pivot point and direction. Checks all ParentSystem's objects and disallows intersecting. Initializes the new object to fit. - May return NULL if cannot fit. + May return nullptr if cannot fit. */ static cMineShaft * CreateAndFit( cStructGenMineShafts::cMineShaftSystem & a_ParentSystem, @@ -351,7 +351,7 @@ void cStructGenMineShafts::cMineShaftSystem::AppendBranch( return; } - cMineShaft * Next = NULL; + cMineShaft * Next = nullptr; int rnd = (a_Noise.IntNoise3DInt(a_PivotX, a_PivotY + a_RecursionLevel * 16, a_PivotZ) / 13) % m_ProbLevelStaircase; if (rnd < m_ProbLevelCorridor) { @@ -365,7 +365,7 @@ void cStructGenMineShafts::cMineShaftSystem::AppendBranch( { Next = cMineShaftStaircase::CreateAndFit(*this, a_PivotX, a_PivotY, a_PivotZ, a_Direction, a_Noise); } - if (Next == NULL) + if (Next == nullptr) { return; } @@ -552,7 +552,7 @@ cMineShaft * cMineShaftCorridor::CreateAndFit( } if (!a_ParentSystem.CanAppend(BoundingBox)) { - return NULL; + return nullptr; } return new cMineShaftCorridor(a_ParentSystem, BoundingBox, NumSegments, a_Direction, a_Noise); } @@ -796,7 +796,7 @@ void cMineShaftCorridor::PlaceChest(cChunkDesc & a_ChunkDesc) { a_ChunkDesc.SetBlockTypeMeta(x, m_BoundingBox.p1.y + 1, z, E_BLOCK_CHEST, Meta); cChestEntity * ChestEntity = (cChestEntity *)a_ChunkDesc.GetBlockEntity(x, m_BoundingBox.p1.y + 1, z); - ASSERT((ChestEntity != NULL) && (ChestEntity->GetBlockType() == E_BLOCK_CHEST)); + ASSERT((ChestEntity != nullptr) && (ChestEntity->GetBlockType() == E_BLOCK_CHEST)); cNoise Noise(a_ChunkDesc.GetChunkX() ^ a_ChunkDesc.GetChunkZ()); int NumSlots = 3 + ((Noise.IntNoise3DInt(x, m_BoundingBox.p1.y, z) / 11) % 4); int Seed = Noise.IntNoise2DInt(x, z); @@ -1006,7 +1006,7 @@ cMineShaft * cMineShaftCrossing::CreateAndFit( } if (!a_ParentSystem.CanAppend(BoundingBox)) { - return NULL; + return nullptr; } return new cMineShaftCrossing(a_ParentSystem, BoundingBox); } @@ -1157,7 +1157,7 @@ cMineShaft * cMineShaftStaircase::CreateAndFit( } if (!a_ParentSystem.CanAppend(Box)) { - return NULL; + return nullptr; } return new cMineShaftStaircase(a_ParentSystem, Box, a_Direction, Slope); } diff --git a/src/Generating/PieceGenerator.cpp b/src/Generating/PieceGenerator.cpp index ae4b6e36c..97aa646fc 100644 --- a/src/Generating/PieceGenerator.cpp +++ b/src/Generating/PieceGenerator.cpp @@ -289,7 +289,7 @@ cPlacedPiece::cPlacedPiece(const cPlacedPiece * a_Parent, const cPiece & a_Piece m_NumCCWRotations(a_NumCCWRotations), m_HasBeenMovedToGround(false) { - m_Depth = (m_Parent == NULL) ? 0 : (m_Parent->GetDepth() + 1); + m_Depth = (m_Parent == nullptr) ? 0 : (m_Parent->GetDepth() + 1); m_HitBox = a_Piece.RotateMoveHitBox(a_NumCCWRotations, a_Coords.x, a_Coords.y, a_Coords.z); m_HitBox.Sort(); } @@ -402,7 +402,7 @@ cPlacedPiece * cPieceGenerator::PlaceStartingPiece(int a_BlockX, int a_BlockY, i } int Rotation = Rotations[rnd % NumRotations]; - cPlacedPiece * res = new cPlacedPiece(NULL, *StartingPiece, Vector3i(a_BlockX, a_BlockY, a_BlockZ), Rotation); + cPlacedPiece * res = new cPlacedPiece(nullptr, *StartingPiece, Vector3i(a_BlockX, a_BlockY, a_BlockZ), Rotation); // Place the piece's connectors into a_OutConnectors: const cPiece::cConnectors & Conn = StartingPiece->GetConnectors(); diff --git a/src/Generating/Prefab.cpp b/src/Generating/Prefab.cpp index 6da3c3d10..761986690 100644 --- a/src/Generating/Prefab.cpp +++ b/src/Generating/Prefab.cpp @@ -328,7 +328,7 @@ void cPrefab::AddConnector(int a_RelX, int a_RelY, int a_RelZ, eBlockFace a_Dire void cPrefab::ParseCharMap(CharMap & a_CharMapOut, const char * a_CharMapDef) { - ASSERT(a_CharMapDef != NULL); + ASSERT(a_CharMapDef != nullptr); // Initialize the charmap to all-invalid values: for (size_t i = 0; i < ARRAYCOUNT(a_CharMapOut); i++) @@ -389,7 +389,7 @@ void cPrefab::ParseBlockImage(const CharMap & a_CharMap, const char * a_BlockIma void cPrefab::ParseConnectors(const char * a_ConnectorsDef) { - ASSERT(a_ConnectorsDef != NULL); + ASSERT(a_ConnectorsDef != nullptr); AStringVector Lines = StringSplitAndTrim(a_ConnectorsDef, "\n"); for (AStringVector::const_iterator itr = Lines.begin(), end = Lines.end(); itr != end; ++itr) @@ -436,7 +436,7 @@ void cPrefab::ParseConnectors(const char * a_ConnectorsDef) void cPrefab::ParseDepthWeight(const char * a_DepthWeightDef) { // The member needn't be defined at all, if so, skip: - if (a_DepthWeightDef == NULL) + if (a_DepthWeightDef == nullptr) { return; } diff --git a/src/Generating/PrefabPiecePool.cpp b/src/Generating/PrefabPiecePool.cpp index 122b9d2af..895555ef8 100644 --- a/src/Generating/PrefabPiecePool.cpp +++ b/src/Generating/PrefabPiecePool.cpp @@ -16,7 +16,7 @@ cPrefabPiecePool::cPrefabPiecePool( ) { AddPieceDefs(a_PieceDefs, a_NumPieceDefs); - if (a_StartingPieceDefs != NULL) + if (a_StartingPieceDefs != nullptr) { AddStartingPieceDefs(a_StartingPieceDefs, a_NumStartingPieceDefs); } @@ -56,7 +56,7 @@ void cPrefabPiecePool::Clear(void) void cPrefabPiecePool::AddPieceDefs(const cPrefab::sDef * a_PieceDefs, size_t a_NumPieceDefs) { - ASSERT(a_PieceDefs != NULL); + ASSERT(a_PieceDefs != nullptr); for (size_t i = 0; i < a_NumPieceDefs; i++) { cPrefab * Prefab = new cPrefab(a_PieceDefs[i]); @@ -71,7 +71,7 @@ void cPrefabPiecePool::AddPieceDefs(const cPrefab::sDef * a_PieceDefs, size_t a_ void cPrefabPiecePool::AddStartingPieceDefs(const cPrefab::sDef * a_StartingPieceDefs, size_t a_NumStartingPieceDefs) { - ASSERT(a_StartingPieceDefs != NULL); + ASSERT(a_StartingPieceDefs != nullptr); for (size_t i = 0; i < a_NumStartingPieceDefs; i++) { cPrefab * Prefab = new cPrefab(a_StartingPieceDefs[i]); diff --git a/src/Generating/VillageGen.cpp b/src/Generating/VillageGen.cpp index 1806fd427..a9b359b6a 100644 --- a/src/Generating/VillageGen.cpp +++ b/src/Generating/VillageGen.cpp @@ -385,7 +385,7 @@ cGridStructGen::cStructurePtr cVillageGen::CreateStructure(int a_GridX, int a_Gr // Check if all the biomes are village-friendly: // If just one is not, no village is created, because it's likely that an unfriendly biome is too close - cVillagePiecePool * VillagePrefabs = NULL; + cVillagePiecePool * VillagePrefabs = nullptr; BLOCKTYPE RoadBlock = E_BLOCK_GRAVEL; BLOCKTYPE WaterRoadBlock = E_BLOCK_PLANKS; int rnd = m_Noise.IntNoise2DInt(a_OriginX, a_OriginZ) / 11; @@ -432,7 +432,7 @@ cGridStructGen::cStructurePtr cVillageGen::CreateStructure(int a_GridX, int a_Gr } // Create a village based on the chosen prefabs: - if (VillagePrefabs == NULL) + if (VillagePrefabs == nullptr) { return cStructurePtr(); } diff --git a/src/HTTPServer/HTTPConnection.cpp b/src/HTTPServer/HTTPConnection.cpp index bf46bb241..d5dbf0199 100644 --- a/src/HTTPServer/HTTPConnection.cpp +++ b/src/HTTPServer/HTTPConnection.cpp @@ -15,7 +15,7 @@ cHTTPConnection::cHTTPConnection(cHTTPServer & a_HTTPServer) : m_HTTPServer(a_HTTPServer), m_State(wcsRecvHeaders), - m_CurrentRequest(NULL), + m_CurrentRequest(nullptr), m_CurrentRequestBodyRemaining(0) { // LOGD("HTTP: New connection at %p", this); @@ -29,7 +29,7 @@ cHTTPConnection::~cHTTPConnection() { // LOGD("HTTP: Connection deleting: %p", this); delete m_CurrentRequest; - m_CurrentRequest = NULL; + m_CurrentRequest = nullptr; } @@ -136,7 +136,7 @@ void cHTTPConnection::AwaitNextRequest(void) void cHTTPConnection::Terminate(void) { - if (m_CurrentRequest != NULL) + if (m_CurrentRequest != nullptr) { m_HTTPServer.RequestFinished(*this, *m_CurrentRequest); } @@ -153,7 +153,7 @@ bool cHTTPConnection::DataReceived(const char * a_Data, size_t a_Size) { case wcsRecvHeaders: { - if (m_CurrentRequest == NULL) + if (m_CurrentRequest == nullptr) { m_CurrentRequest = new cHTTPRequest; } @@ -162,7 +162,7 @@ bool cHTTPConnection::DataReceived(const char * a_Data, size_t a_Size) if (BytesConsumed == AString::npos) { delete m_CurrentRequest; - m_CurrentRequest = NULL; + m_CurrentRequest = nullptr; m_State = wcsInvalid; m_HTTPServer.CloseConnection(*this); return true; @@ -196,7 +196,7 @@ bool cHTTPConnection::DataReceived(const char * a_Data, size_t a_Size) case wcsRecvBody: { - ASSERT(m_CurrentRequest != NULL); + ASSERT(m_CurrentRequest != nullptr); if (m_CurrentRequestBodyRemaining > 0) { size_t BytesToConsume = std::min(m_CurrentRequestBodyRemaining, (size_t)a_Size); @@ -214,7 +214,7 @@ bool cHTTPConnection::DataReceived(const char * a_Data, size_t a_Size) return true; } delete m_CurrentRequest; - m_CurrentRequest = NULL; + m_CurrentRequest = nullptr; } break; } @@ -243,7 +243,7 @@ void cHTTPConnection::GetOutgoingData(AString & a_Data) void cHTTPConnection::SocketClosed(void) { - if (m_CurrentRequest != NULL) + if (m_CurrentRequest != nullptr) { m_HTTPServer.RequestFinished(*this, *m_CurrentRequest); } diff --git a/src/HTTPServer/HTTPConnection.h b/src/HTTPServer/HTTPConnection.h index 6ea8a1ae8..ccbf26466 100644 --- a/src/HTTPServer/HTTPConnection.h +++ b/src/HTTPServer/HTTPConnection.h @@ -31,10 +31,10 @@ public: enum eState { - wcsRecvHeaders, ///< Receiving request headers (m_CurrentRequest is created if NULL) + wcsRecvHeaders, ///< Receiving request headers (m_CurrentRequest is created if nullptr) wcsRecvBody, ///< Receiving request body (m_CurrentRequest is valid) - wcsRecvIdle, ///< Has received the entire body, waiting to send the response (m_CurrentRequest == NULL) - wcsSendingResp, ///< Sending response body (m_CurrentRequest == NULL) + wcsRecvIdle, ///< Has received the entire body, waiting to send the response (m_CurrentRequest == nullptr) + wcsSendingResp, ///< Sending response body (m_CurrentRequest == nullptr) wcsInvalid, ///< The request was malformed, the connection is closing } ; diff --git a/src/HTTPServer/HTTPFormParser.cpp b/src/HTTPServer/HTTPFormParser.cpp index c50c6dcf2..72872078b 100644 --- a/src/HTTPServer/HTTPFormParser.cpp +++ b/src/HTTPServer/HTTPFormParser.cpp @@ -86,7 +86,7 @@ void cHTTPFormParser::Parse(const char * a_Data, size_t a_Size) } case fpkMultipart: { - ASSERT(m_MultipartParser.get() != NULL); + ASSERT(m_MultipartParser.get() != nullptr); m_MultipartParser->Parse(a_Data, a_Size); break; } @@ -145,7 +145,7 @@ bool cHTTPFormParser::HasFormData(const cHTTPRequest & a_Request) void cHTTPFormParser::BeginMultipart(const cHTTPRequest & a_Request) { - ASSERT(m_MultipartParser.get() == NULL); + ASSERT(m_MultipartParser.get() == nullptr); m_MultipartParser.reset(new cMultipartParser(a_Request.GetContentType(), *this)); } diff --git a/src/HTTPServer/HTTPMessage.cpp b/src/HTTPServer/HTTPMessage.cpp index 65d73fd87..f6c0204ae 100644 --- a/src/HTTPServer/HTTPMessage.cpp +++ b/src/HTTPServer/HTTPMessage.cpp @@ -70,7 +70,7 @@ cHTTPRequest::cHTTPRequest(void) : super(mkRequest), m_EnvelopeParser(*this), m_IsValid(true), - m_UserData(NULL), + m_UserData(nullptr), m_HasAuth(false), m_AllowKeepAlive(false) { diff --git a/src/HTTPServer/HTTPServer.cpp b/src/HTTPServer/HTTPServer.cpp index 0c41b54b2..9ab030a1f 100644 --- a/src/HTTPServer/HTTPServer.cpp +++ b/src/HTTPServer/HTTPServer.cpp @@ -44,7 +44,7 @@ class cDebugCallbacks : UNUSED(a_Connection); cHTTPFormParser * FormParser = (cHTTPFormParser *)(a_Request.GetUserData()); - if (FormParser != NULL) + if (FormParser != nullptr) { FormParser->Parse(a_Data, a_Size); } @@ -54,7 +54,7 @@ class cDebugCallbacks : virtual void OnRequestFinished(cHTTPConnection & a_Connection, cHTTPRequest & a_Request) override { cHTTPFormParser * FormParser = (cHTTPFormParser *)(a_Request.GetUserData()); - if (FormParser != NULL) + if (FormParser != nullptr) { if (FormParser->Finish()) { @@ -124,7 +124,7 @@ class cDebugCallbacks : cHTTPServer::cHTTPServer(void) : m_ListenThreadIPv4(*this, cSocket::IPv4, "WebServer"), m_ListenThreadIPv6(*this, cSocket::IPv6, "WebServer"), - m_Callbacks(NULL) + m_Callbacks(nullptr) { } @@ -168,7 +168,7 @@ bool cHTTPServer::Initialize(const AString & a_PortsIPv4, const AString & a_Port } // Notify the admin about the HTTPS / HTTP status - if (m_Cert.get() == NULL) + if (m_Cert.get() == nullptr) { LOGWARNING("WebServer: The server is running in unsecured HTTP mode."); LOGINFO("Put a valid HTTPS certificate in file 'webadmin/httpscert.crt' and its corresponding private key to 'webadmin/httpskey.pem' (without any password) to enable HTTPS support"); @@ -235,7 +235,7 @@ void cHTTPServer::Stop(void) void cHTTPServer::OnConnectionAccepted(cSocket & a_Socket) { cHTTPConnection * Connection; - if (m_Cert.get() != NULL) + if (m_Cert.get() != nullptr) { Connection = new cSslHTTPConnection(*this, m_Cert, m_CertPrivKey); } diff --git a/src/Inventory.cpp b/src/Inventory.cpp index 832a079bc..51ac32da9 100644 --- a/src/Inventory.cpp +++ b/src/Inventory.cpp @@ -220,7 +220,7 @@ void cInventory::SetSlot(int a_SlotNum, const cItem & a_Item) int GridSlotNum = 0; cItemGrid * Grid = GetGridForSlotNum(a_SlotNum, GridSlotNum); - if (Grid == NULL) + if (Grid == nullptr) { LOGWARNING("%s(%d): requesting an invalid itemgrid. Ignoring.", __FUNCTION__, a_SlotNum); return; @@ -278,7 +278,7 @@ const cItem & cInventory::GetSlot(int a_SlotNum) const } int GridSlotNum = 0; const cItemGrid * Grid = GetGridForSlotNum(a_SlotNum, GridSlotNum); - if (Grid == NULL) + if (Grid == nullptr) { // Something went wrong, but we don't know what. We must return a value, so return the first inventory slot LOGWARNING("%s(%d): requesting an invalid ItemGrid, returning the first inventory slot instead.", __FUNCTION__, a_SlotNum); @@ -372,7 +372,7 @@ int cInventory::ChangeSlotCount(int a_SlotNum, int a_AddToCount) { int GridSlotNum = 0; cItemGrid * Grid = GetGridForSlotNum(a_SlotNum, GridSlotNum); - if (Grid == NULL) + if (Grid == nullptr) { LOGWARNING("%s: invalid slot number, expected 0 .. %d, got %d; ignoring", __FUNCTION__, invNumSlots, a_SlotNum); return -1; @@ -398,7 +398,7 @@ bool cInventory::DamageItem(int a_SlotNum, short a_Amount) int GridSlotNum = 0; cItemGrid * Grid = GetGridForSlotNum(a_SlotNum, GridSlotNum); - if (Grid == NULL) + if (Grid == nullptr) { LOGWARNING("%s(%d, %d): requesting an invalid grid, ignoring.", __FUNCTION__, a_SlotNum, a_Amount); return false; @@ -640,7 +640,7 @@ bool cInventory::LoadFromJson(Json::Value & a_Value) int GridSlotNum = 0; cItemGrid * Grid = GetGridForSlotNum(SlotIdx - 5, GridSlotNum); - ASSERT(Grid != NULL); + ASSERT(Grid != nullptr); Grid->SetSlot(GridSlotNum, Item); } // for itr - a_Value[] return true; @@ -708,7 +708,7 @@ void cInventory::OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) // Armor update needs broadcast to other players: cWorld * World = m_Owner.GetWorld(); - if ((a_ItemGrid == &m_ArmorSlots) && (World != NULL)) + if ((a_ItemGrid == &m_ArmorSlots) && (World != nullptr)) { World->BroadcastEntityEquipment( m_Owner, ArmorSlotNumToEntityEquipmentID(a_SlotNum), diff --git a/src/Inventory.h b/src/Inventory.h index 5628fb0da..4e76bc0d3 100644 --- a/src/Inventory.h +++ b/src/Inventory.h @@ -179,10 +179,10 @@ protected: cPlayer & m_Owner; - /** Returns the ItemGrid and the (grid-local) slot number for a (global) slot number; return NULL for invalid SlotNum */ + /** Returns the ItemGrid and the (grid-local) slot number for a (global) slot number; return nullptr for invalid SlotNum */ const cItemGrid * GetGridForSlotNum(int a_SlotNum, int & a_GridSlotNum) const; - /** Returns the ItemGrid and the (grid-local) slot number for a (global) slot number; return NULL for invalid SlotNum */ + /** Returns the ItemGrid and the (grid-local) slot number for a (global) slot number; return nullptr for invalid SlotNum */ cItemGrid * GetGridForSlotNum(int a_SlotNum, int & a_GridSlotNum); // cItemGrid::cListener override: diff --git a/src/Item.cpp b/src/Item.cpp index ebdf99ca5..36c444328 100644 --- a/src/Item.cpp +++ b/src/Item.cpp @@ -391,7 +391,7 @@ cItem * cItems::Get(int a_Idx) if ((a_Idx < 0) || (a_Idx >= (int)size())) { LOGWARNING("cItems: Attempt to get an out-of-bounds item at index %d; there are currently " SIZE_T_FMT " items. Returning a nil.", a_Idx, size()); - return NULL; + return nullptr; } return &at(a_Idx); } diff --git a/src/ItemGrid.cpp b/src/ItemGrid.cpp index 1977216d8..55fb36a17 100644 --- a/src/ItemGrid.cpp +++ b/src/ItemGrid.cpp @@ -28,7 +28,7 @@ cItemGrid::cItemGrid(int a_Width, int a_Height) : cItemGrid::~cItemGrid() { delete[] m_Slots; - m_Slots = NULL; + m_Slots = nullptr; } diff --git a/src/Items/ItemBow.h b/src/Items/ItemBow.h index f29cc5d59..cf2fe9ad2 100644 --- a/src/Items/ItemBow.h +++ b/src/Items/ItemBow.h @@ -29,7 +29,7 @@ public: virtual bool OnItemUse(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Dir) override { - ASSERT(a_Player != NULL); + ASSERT(a_Player != nullptr); // Check if the player has an arrow in the inventory, or is in Creative: if (!(a_Player->IsGameModeCreative() || a_Player->GetInventory().HasItems(cItem(E_ITEM_ARROW)))) @@ -45,7 +45,7 @@ public: virtual void OnItemShoot(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override { // Actual shot - produce the arrow with speed based on the ticks that the bow was charged - ASSERT(a_Player != NULL); + ASSERT(a_Player != nullptr); int BowCharge = a_Player->FinishChargingBow(); double Force = (double)BowCharge / 20.0; @@ -65,14 +65,14 @@ public: // Create the arrow entity: cArrowEntity * Arrow = new cArrowEntity(*a_Player, Force * 2); - if (Arrow == NULL) + if (Arrow == nullptr) { return; } if (!Arrow->Initialize(*a_Player->GetWorld())) { delete Arrow; - Arrow = NULL; + Arrow = nullptr; return; } a_Player->GetWorld()->BroadcastSoundEffect("random.bow", a_Player->GetPosX(), a_Player->GetPosY(), a_Player->GetPosZ(), 0.5, (float)Force); diff --git a/src/Items/ItemEmptyMap.h b/src/Items/ItemEmptyMap.h index 953673382..9238d771b 100644 --- a/src/Items/ItemEmptyMap.h +++ b/src/Items/ItemEmptyMap.h @@ -50,7 +50,7 @@ public: return true; } - if (NewMap == NULL) + if (NewMap == nullptr) { return true; } diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp index 912dde022..d1588e9d8 100644 --- a/src/Items/ItemHandler.cpp +++ b/src/Items/ItemHandler.cpp @@ -83,7 +83,7 @@ cItemHandler * cItemHandler::GetItemHandler(int a_ItemType) memset(m_ItemHandler, 0, sizeof(m_ItemHandler)); m_HandlerInitialized = true; } - if (m_ItemHandler[a_ItemType] == NULL) + if (m_ItemHandler[a_ItemType] == nullptr) { m_ItemHandler[a_ItemType] = CreateItemHandler(a_ItemType); } @@ -278,7 +278,7 @@ void cItemHandler::Deinit() for (int i = 0; i < 2267; i++) { delete m_ItemHandler[i]; - m_ItemHandler[i] = NULL; + m_ItemHandler[i] = nullptr; } memset(m_ItemHandler, 0, sizeof(m_ItemHandler)); // Don't leave any dangling pointers around, just in case m_HandlerInitialized = false; diff --git a/src/Items/ItemItemFrame.h b/src/Items/ItemItemFrame.h index 87e20ecf0..5d22c1cb8 100644 --- a/src/Items/ItemItemFrame.h +++ b/src/Items/ItemItemFrame.h @@ -37,7 +37,7 @@ public: if (!ItemFrame->Initialize(*a_World)) { delete ItemFrame; - ItemFrame = NULL; + ItemFrame = nullptr; return false; } diff --git a/src/Items/ItemMap.h b/src/Items/ItemMap.h index 056fe0fe7..2dbbb3dc0 100644 --- a/src/Items/ItemMap.h +++ b/src/Items/ItemMap.h @@ -31,7 +31,7 @@ public: { cMap * Map = a_World->GetMapManager().GetMapData((unsigned)a_Item.m_ItemDamage); - if (Map == NULL) + if (Map == nullptr) { return; } diff --git a/src/Items/ItemMinecart.h b/src/Items/ItemMinecart.h index 63038de51..ed0a4711c 100644 --- a/src/Items/ItemMinecart.h +++ b/src/Items/ItemMinecart.h @@ -56,7 +56,7 @@ public: double x = (double)a_BlockX + 0.5; double y = (double)a_BlockY + 0.5; double z = (double)a_BlockZ + 0.5; - cMinecart * Minecart = NULL; + cMinecart * Minecart = nullptr; switch (m_ItemType) { case E_ITEM_MINECART: Minecart = new cRideableMinecart (x, y, z, cItem(), 1); break; diff --git a/src/LeakFinder.h b/src/LeakFinder.h index e63b9ec5d..ceaa53782 100644 --- a/src/LeakFinder.h +++ b/src/LeakFinder.h @@ -68,7 +68,7 @@ public: LeakFinderShowCompleteCallstack = 0x1000 } LeakFinderOptions; - LeakFinderOutput(int options = OptionsAll, LPCSTR szSymPath = NULL); + LeakFinderOutput(int options = OptionsAll, LPCSTR szSymPath = nullptr); virtual void OnLeakSearchStart(LPCSTR sszLeakFinderName); virtual void OnLeakStartEntry(LPCSTR szKeyName, SIZE_T nDataSize); protected: @@ -110,7 +110,7 @@ class ZZZ_LeakFinder public: ZZZ_LeakFinder() { - m_pXml = NULL; + m_pXml = nullptr; #ifdef XML_LEAK_FINDER m_pXml = new LeakFinderXmlOutput(); #endif @@ -119,7 +119,7 @@ public: ~ZZZ_LeakFinder() { DeinitLeakFinder(m_pXml); - if (m_pXml != NULL) delete m_pXml; + if (m_pXml != nullptr) delete m_pXml; } protected: LeakFinderXmlOutput *m_pXml; @@ -148,7 +148,7 @@ ZZZ_LeakFinder zzz_LeakFinder; -extern void DumpUsedMemory(LeakFinderOutput * output = NULL); +extern void DumpUsedMemory(LeakFinderOutput * output = nullptr); diff --git a/src/LightingThread.cpp b/src/LightingThread.cpp index 652b03e46..ae5e746e7 100644 --- a/src/LightingThread.cpp +++ b/src/LightingThread.cpp @@ -91,7 +91,7 @@ public: cLightingThread::cLightingThread(void) : super("cLightingThread"), - m_World(NULL), + m_World(nullptr), m_MaxHeight(0), m_NumSeeds(0) { @@ -112,7 +112,7 @@ cLightingThread::~cLightingThread() bool cLightingThread::Start(cWorld * a_World) { - ASSERT(m_World == NULL); // Not started yet + ASSERT(m_World == nullptr); // Not started yet m_World = a_World; return super::Start(); @@ -151,7 +151,7 @@ void cLightingThread::Stop(void) void cLightingThread::QueueChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_CallbackAfter) { - ASSERT(m_World != NULL); // Did you call Start() properly? + ASSERT(m_World != nullptr); // Did you call Start() properly? cChunkStay * ChunkStay = new cLightingChunkStay(*this, a_ChunkX, a_ChunkZ, a_CallbackAfter); { @@ -310,7 +310,7 @@ void cLightingThread::LightChunk(cLightingChunkStay & a_Item) m_World->ChunkLighted(a_Item.m_ChunkX, a_Item.m_ChunkZ, BlockLight, SkyLight); - if (a_Item.m_CallbackAfter != NULL) + if (a_Item.m_CallbackAfter != nullptr) { a_Item.m_CallbackAfter->Call(a_Item.m_ChunkX, a_Item.m_ChunkZ); } diff --git a/src/LightingThread.h b/src/LightingThread.h index f71d2cf1a..87eb9c6d8 100644 --- a/src/LightingThread.h +++ b/src/LightingThread.h @@ -61,7 +61,7 @@ public: void Stop(void); /** Queues the entire chunk for lighting */ - void QueueChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_CallbackAfter = NULL); + void QueueChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_CallbackAfter = nullptr); /** Blocks until the queue is empty or the thread is terminated */ void WaitForQueueEmpty(void); diff --git a/src/LineBlockTracer.cpp b/src/LineBlockTracer.cpp index 1b42081c2..90f97cd23 100644 --- a/src/LineBlockTracer.cpp +++ b/src/LineBlockTracer.cpp @@ -198,7 +198,7 @@ bool cLineBlockTracer::Item(cChunk * a_Chunk) for (;;) { // Report the current block through the callbacks: - if (a_Chunk == NULL) + if (a_Chunk == nullptr) { m_Callbacks->OnNoChunk(); return false; @@ -228,7 +228,7 @@ bool cLineBlockTracer::Item(cChunk * a_Chunk) // Update the current chunk a_Chunk = a_Chunk->GetNeighborChunk(m_CurrentX, m_CurrentZ); - if (a_Chunk == NULL) + if (a_Chunk == nullptr) { m_Callbacks->OnNoChunk(); return false; diff --git a/src/LinearUpscale.h b/src/LinearUpscale.h index a49f4bdf9..1b0fbd89a 100644 --- a/src/LinearUpscale.h +++ b/src/LinearUpscale.h @@ -95,8 +95,8 @@ template void LinearUpscale2DArray( const int MAX_UPSCALE_X = 128; const int MAX_UPSCALE_Y = 128; - ASSERT(a_Src != NULL); - ASSERT(a_Dst != NULL); + ASSERT(a_Src != nullptr); + ASSERT(a_Dst != nullptr); ASSERT(a_SrcSizeX > 0); ASSERT(a_SrcSizeY > 0); ASSERT(a_UpscaleX > 0); @@ -166,8 +166,8 @@ template void LinearUpscale3DArray( const int MAX_UPSCALE_Y = 128; const int MAX_UPSCALE_Z = 128; - ASSERT(a_Src != NULL); - ASSERT(a_Dst != NULL); + ASSERT(a_Src != nullptr); + ASSERT(a_Dst != nullptr); ASSERT(a_SrcSizeX > 0); ASSERT(a_SrcSizeY > 0); ASSERT(a_SrcSizeZ > 0); diff --git a/src/LoggerListeners.cpp b/src/LoggerListeners.cpp index 77e2aaf67..5c7097956 100644 --- a/src/LoggerListeners.cpp +++ b/src/LoggerListeners.cpp @@ -280,7 +280,7 @@ cFileListener::cFileListener(void) { cFile::CreateFolder(FILE_IO_PREFIX + AString("logs")); AString FileName; - FileName = Printf("%s%sLOG_%d.txt", FILE_IO_PREFIX, "logs/", (int)time(NULL)); + FileName = Printf("%s%sLOG_%d.txt", FILE_IO_PREFIX, "logs/", (int)time(nullptr)); m_File.Open(FileName, cFile::fmAppend); } diff --git a/src/Map.cpp b/src/Map.cpp index c106ccd83..fbde00cf7 100644 --- a/src/Map.cpp +++ b/src/Map.cpp @@ -21,7 +21,7 @@ cMapDecorator::cMapDecorator(cMap * a_Map, eType a_Type, int a_X, int a_Z, int a , m_PixelX(a_X) , m_PixelZ(a_Z) , m_Rot(a_Rot) - , m_Player(NULL) + , m_Player(nullptr) { } @@ -43,9 +43,9 @@ cMapDecorator::cMapDecorator(cMap * a_Map, cPlayer * a_Player) void cMapDecorator::Update(void) { - if (m_Player != NULL) + if (m_Player != nullptr) { - ASSERT(m_Map != NULL); + ASSERT(m_Map != nullptr); unsigned int PixelWidth = m_Map->GetPixelWidth(); int InsideWidth = (m_Map->GetWidth() / 2) - 1; @@ -221,7 +221,7 @@ bool cMap::UpdatePixel(unsigned int a_X, unsigned int a_Z) virtual bool Item(cChunk * a_Chunk) override { - if (a_Chunk == NULL) + if (a_Chunk == nullptr) { return false; } @@ -322,7 +322,7 @@ bool cMap::UpdatePixel(unsigned int a_X, unsigned int a_Z) } } CalculatePixelCb(this, RelX, RelZ); - ASSERT(m_World != NULL); + ASSERT(m_World != nullptr); m_World->DoWithChunk(ChunkX, ChunkZ, CalculatePixelCb); SetPixel(a_X, a_Z, CalculatePixelCb.GetPixelData()); @@ -349,7 +349,7 @@ void cMap::UpdateDecorators(void) void cMap::AddPlayer(cPlayer * a_Player, Int64 a_WorldAge) { cClientHandle * Handle = a_Player->GetClientHandle(); - if (Handle == NULL) + if (Handle == nullptr) { return; } @@ -454,10 +454,10 @@ void cMap::StreamNext(cMapClient & a_Client) void cMap::UpdateClient(cPlayer * a_Player) { - ASSERT(a_Player != NULL); + ASSERT(a_Player != nullptr); cClientHandle * Handle = a_Player->GetClientHandle(); - if (Handle == NULL) + if (Handle == nullptr) { return; } @@ -498,7 +498,7 @@ void cMap::EraseData(void) eDimension cMap::GetDimension(void) const { - ASSERT(m_World != NULL); + ASSERT(m_World != nullptr); return m_World->GetDimension(); } diff --git a/src/MapManager.cpp b/src/MapManager.cpp index e7df75118..2a3ab192b 100644 --- a/src/MapManager.cpp +++ b/src/MapManager.cpp @@ -15,7 +15,7 @@ cMapManager::cMapManager(cWorld * a_World) : m_World(a_World) { - ASSERT(m_World != NULL); + ASSERT(m_World != nullptr); } @@ -27,7 +27,7 @@ bool cMapManager::DoWithMap(int a_ID, cMapCallback & a_Callback) cCSLock Lock(m_CS); cMap * Map = GetMapData(a_ID); - if (Map == NULL) + if (Map == nullptr) { return false; } @@ -68,7 +68,7 @@ cMap * cMapManager::GetMapData(unsigned int a_ID) } else { - return NULL; + return nullptr; } } @@ -83,7 +83,7 @@ cMap * cMapManager::CreateMap(int a_CenterX, int a_CenterY, int a_Scale) if (m_MapData.size() >= 65536) { LOGWARN("Could not craft map - Too many maps in use"); - return NULL; + return nullptr; } cMap Map((unsigned)m_MapData.size(), a_CenterX, a_CenterY, m_World, a_Scale); diff --git a/src/MapManager.h b/src/MapManager.h index a40ec2630..2cc6a7bce 100644 --- a/src/MapManager.h +++ b/src/MapManager.h @@ -31,12 +31,12 @@ public: cMapManager(cWorld * a_World); - /** Returns the map with the specified ID, NULL if out of range. + /** Returns the map with the specified ID, nullptr if out of range. WARNING: The returned map object is not thread safe. */ cMap * GetMapData(unsigned int a_ID); - /** Creates a new map. Returns NULL on error */ + /** Creates a new map. Returns nullptr on error */ cMap * CreateMap(int a_CenterX, int a_CenterY, int a_Scale = 3); /** Calls the callback for the map with the specified ID. diff --git a/src/MobSpawner.cpp b/src/MobSpawner.cpp index ea3fe8c72..e461fae4c 100644 --- a/src/MobSpawner.cpp +++ b/src/MobSpawner.cpp @@ -301,7 +301,7 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R cMonster* cMobSpawner::TryToSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, EMCSBiome a_Biome, int& a_MaxPackSize) { - cMonster* toReturn = NULL; + cMonster* toReturn = nullptr; if (m_NewPack) { m_MobType = ChooseMobType(a_Biome); diff --git a/src/Mobs/AggressiveMonster.cpp b/src/Mobs/AggressiveMonster.cpp index be2f71f7a..41ef26e2a 100644 --- a/src/Mobs/AggressiveMonster.cpp +++ b/src/Mobs/AggressiveMonster.cpp @@ -26,7 +26,7 @@ void cAggressiveMonster::InStateChasing(float a_Dt) { super::InStateChasing(a_Dt); - if (m_Target != NULL) + if (m_Target != nullptr) { if (m_Target->IsPlayer()) { @@ -74,7 +74,7 @@ void cAggressiveMonster::Tick(float a_Dt, cChunk & a_Chunk) CheckEventSeePlayer(); } - if (m_Target == NULL) + if (m_Target == nullptr) return; cTracer LineOfSight(GetWorld()); @@ -95,7 +95,7 @@ void cAggressiveMonster::Attack(float a_Dt) { m_AttackInterval += a_Dt * m_AttackRate; - if ((m_Target == NULL) || (m_AttackInterval < 3.0)) + if ((m_Target == nullptr) || (m_AttackInterval < 3.0)) { return; } diff --git a/src/Mobs/Blaze.cpp b/src/Mobs/Blaze.cpp index b4104d530..16869c79d 100644 --- a/src/Mobs/Blaze.cpp +++ b/src/Mobs/Blaze.cpp @@ -19,7 +19,7 @@ cBlaze::cBlaze(void) : void cBlaze::GetDrops(cItems & a_Drops, cEntity * a_Killer) { - if ((a_Killer != NULL) && (a_Killer->IsPlayer() || a_Killer->IsA("cWolf"))) + if ((a_Killer != nullptr) && (a_Killer->IsPlayer() || a_Killer->IsA("cWolf"))) { int LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); AddRandomDropItem(a_Drops, 0, 1 + LootingLevel, E_ITEM_BLAZE_ROD); @@ -34,20 +34,20 @@ void cBlaze::Attack(float a_Dt) { m_AttackInterval += a_Dt * m_AttackRate; - if (m_Target != NULL && m_AttackInterval > 3.0) + if (m_Target != nullptr && m_AttackInterval > 3.0) { // Setting this higher gives us more wiggle room for attackrate Vector3d Speed = GetLookVector() * 20; Speed.y = Speed.y + 1; cFireChargeEntity * FireCharge = new cFireChargeEntity(this, GetPosX(), GetPosY() + 1, GetPosZ(), Speed); - if (FireCharge == NULL) + if (FireCharge == nullptr) { return; } if (!FireCharge->Initialize(*m_World)) { delete FireCharge; - FireCharge = NULL; + FireCharge = nullptr; return; } m_World->BroadcastSpawnEntity(*FireCharge); diff --git a/src/Mobs/Blaze.h b/src/Mobs/Blaze.h index f283b1070..e2a4ad9f1 100644 --- a/src/Mobs/Blaze.h +++ b/src/Mobs/Blaze.h @@ -17,6 +17,6 @@ public: CLASS_PROTODEF(cBlaze) - virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; virtual void Attack(float a_Dt) override; } ; diff --git a/src/Mobs/CaveSpider.cpp b/src/Mobs/CaveSpider.cpp index 118a6e93b..045b47e73 100644 --- a/src/Mobs/CaveSpider.cpp +++ b/src/Mobs/CaveSpider.cpp @@ -45,12 +45,12 @@ void cCaveSpider::Attack(float a_Dt) void cCaveSpider::GetDrops(cItems & a_Drops, cEntity * a_Killer) { int LootingLevel = 0; - if (a_Killer != NULL) + if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); } AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_STRING); - if ((a_Killer != NULL) && (a_Killer->IsPlayer() || a_Killer->IsA("cWolf"))) + if ((a_Killer != nullptr) && (a_Killer->IsPlayer() || a_Killer->IsA("cWolf"))) { AddRandomUncommonDropItem(a_Drops, 33.0f, E_ITEM_SPIDER_EYE); } diff --git a/src/Mobs/CaveSpider.h b/src/Mobs/CaveSpider.h index f9ed10e1b..494ba1360 100644 --- a/src/Mobs/CaveSpider.h +++ b/src/Mobs/CaveSpider.h @@ -18,7 +18,7 @@ public: virtual void Tick(float a_Dt, cChunk & a_Chunk) override; virtual void Attack(float a_Dt) override; - virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; } ; diff --git a/src/Mobs/Chicken.cpp b/src/Mobs/Chicken.cpp index f7e44238f..634867cfa 100644 --- a/src/Mobs/Chicken.cpp +++ b/src/Mobs/Chicken.cpp @@ -49,7 +49,7 @@ void cChicken::Tick(float a_Dt, cChunk & a_Chunk) void cChicken::GetDrops(cItems & a_Drops, cEntity * a_Killer) { int LootingLevel = 0; - if (a_Killer != NULL) + if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); } diff --git a/src/Mobs/Chicken.h b/src/Mobs/Chicken.h index b1a50b61c..07b921884 100644 --- a/src/Mobs/Chicken.h +++ b/src/Mobs/Chicken.h @@ -16,7 +16,7 @@ public: CLASS_PROTODEF(cChicken) - virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; virtual void Tick(float a_Dt, cChunk & a_Chunk) override; virtual const cItem GetFollowedItem(void) const override { return cItem(E_ITEM_SEEDS); } diff --git a/src/Mobs/Cow.cpp b/src/Mobs/Cow.cpp index 9914df6b5..7dc6f3f37 100644 --- a/src/Mobs/Cow.cpp +++ b/src/Mobs/Cow.cpp @@ -22,7 +22,7 @@ cCow::cCow(void) : void cCow::GetDrops(cItems & a_Drops, cEntity * a_Killer) { int LootingLevel = 0; - if (a_Killer != NULL) + if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); } diff --git a/src/Mobs/Cow.h b/src/Mobs/Cow.h index 8814b7e09..ee1a4fafe 100644 --- a/src/Mobs/Cow.h +++ b/src/Mobs/Cow.h @@ -17,7 +17,7 @@ public: CLASS_PROTODEF(cCow) - virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; virtual void OnRightClicked(cPlayer & a_Player) override; virtual const cItem GetFollowedItem(void) const override { return cItem(E_ITEM_WHEAT); } diff --git a/src/Mobs/Creeper.cpp b/src/Mobs/Creeper.cpp index 02718edf8..a073224cf 100644 --- a/src/Mobs/Creeper.cpp +++ b/src/Mobs/Creeper.cpp @@ -61,13 +61,13 @@ void cCreeper::GetDrops(cItems & a_Drops, cEntity * a_Killer) } int LootingLevel = 0; - if (a_Killer != NULL) + if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); } AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_GUNPOWDER); - if ((a_Killer != NULL) && a_Killer->IsProjectile() && (((cProjectileEntity *)a_Killer)->GetCreatorUniqueID() >= 0)) + if ((a_Killer != nullptr) && a_Killer->IsProjectile() && (((cProjectileEntity *)a_Killer)->GetCreatorUniqueID() >= 0)) { class cProjectileCreatorCallback : public cEntityCallback { diff --git a/src/Mobs/Creeper.h b/src/Mobs/Creeper.h index 747daca09..bf3272e22 100644 --- a/src/Mobs/Creeper.h +++ b/src/Mobs/Creeper.h @@ -17,7 +17,7 @@ public: CLASS_PROTODEF(cCreeper) - virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; virtual bool DoTakeDamage(TakeDamageInfo & a_TDI) override; virtual void Attack(float a_Dt) override; virtual void Tick(float a_Dt, cChunk & a_Chunk) override; diff --git a/src/Mobs/EnderDragon.h b/src/Mobs/EnderDragon.h index 1d4cd657c..e4ca9dcf9 100644 --- a/src/Mobs/EnderDragon.h +++ b/src/Mobs/EnderDragon.h @@ -17,7 +17,7 @@ public: CLASS_PROTODEF(cEnderDragon) - virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; } ; diff --git a/src/Mobs/Enderman.cpp b/src/Mobs/Enderman.cpp index 567714382..56ea10245 100644 --- a/src/Mobs/Enderman.cpp +++ b/src/Mobs/Enderman.cpp @@ -15,7 +15,7 @@ class cPlayerLookCheck : { public: cPlayerLookCheck(Vector3d a_EndermanPos, int a_SightDistance) : - m_Player(NULL), + m_Player(nullptr), m_EndermanPos(a_EndermanPos), m_SightDistance(a_SightDistance) { @@ -92,7 +92,7 @@ cEnderman::cEnderman(void) : void cEnderman::GetDrops(cItems & a_Drops, cEntity * a_Killer) { int LootingLevel = 0; - if (a_Killer != NULL) + if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); } @@ -104,7 +104,7 @@ void cEnderman::GetDrops(cItems & a_Drops, cEntity * a_Killer) void cEnderman::CheckEventSeePlayer() { - if (m_Target != NULL) + if (m_Target != nullptr) { return; } @@ -115,7 +115,7 @@ void cEnderman::CheckEventSeePlayer() return; } - ASSERT(Callback.GetPlayer() != NULL); + ASSERT(Callback.GetPlayer() != nullptr); if (!CheckLight()) { @@ -196,7 +196,7 @@ void cEnderman::Tick(float a_Dt, cChunk & a_Chunk) if (IsSwimming()) { EventLosePlayer(); - TakeDamage(dtDrowning, NULL, 1, 0); + TakeDamage(dtDrowning, nullptr, 1, 0); // TODO teleport to a safe location } diff --git a/src/Mobs/Enderman.h b/src/Mobs/Enderman.h index 947c32b96..28bbceb84 100644 --- a/src/Mobs/Enderman.h +++ b/src/Mobs/Enderman.h @@ -17,7 +17,7 @@ public: CLASS_PROTODEF(cEnderman) - virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; virtual void CheckEventSeePlayer(void) override; virtual void CheckEventLostPlayer(void) override; virtual void EventLosePlayer(void) override; diff --git a/src/Mobs/Ghast.cpp b/src/Mobs/Ghast.cpp index 6aac14779..c65c0d29a 100644 --- a/src/Mobs/Ghast.cpp +++ b/src/Mobs/Ghast.cpp @@ -20,7 +20,7 @@ cGhast::cGhast(void) : void cGhast::GetDrops(cItems & a_Drops, cEntity * a_Killer) { int LootingLevel = 0; - if (a_Killer != NULL) + if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); } @@ -36,20 +36,20 @@ void cGhast::Attack(float a_Dt) { m_AttackInterval += a_Dt * m_AttackRate; - if (m_Target != NULL && m_AttackInterval > 3.0) + if (m_Target != nullptr && m_AttackInterval > 3.0) { // Setting this higher gives us more wiggle room for attackrate Vector3d Speed = GetLookVector() * 20; Speed.y = Speed.y + 1; cGhastFireballEntity * GhastBall = new cGhastFireballEntity(this, GetPosX(), GetPosY() + 1, GetPosZ(), Speed); - if (GhastBall == NULL) + if (GhastBall == nullptr) { return; } if (!GhastBall->Initialize(*m_World)) { delete GhastBall; - GhastBall = NULL; + GhastBall = nullptr; return; } m_World->BroadcastSpawnEntity(*GhastBall); diff --git a/src/Mobs/Ghast.h b/src/Mobs/Ghast.h index 1d4e6b94a..a28940a01 100644 --- a/src/Mobs/Ghast.h +++ b/src/Mobs/Ghast.h @@ -17,7 +17,7 @@ public: CLASS_PROTODEF(cGhast) - virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; virtual void Attack(float a_Dt) override; bool IsCharging(void) const {return false; } diff --git a/src/Mobs/Giant.h b/src/Mobs/Giant.h index 7c04c9b4f..8d3060940 100644 --- a/src/Mobs/Giant.h +++ b/src/Mobs/Giant.h @@ -17,7 +17,7 @@ public: CLASS_PROTODEF(cGiant) - virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; } ; diff --git a/src/Mobs/Horse.cpp b/src/Mobs/Horse.cpp index 67a09d4ab..d92f0d023 100644 --- a/src/Mobs/Horse.cpp +++ b/src/Mobs/Horse.cpp @@ -49,7 +49,7 @@ void cHorse::Tick(float a_Dt, cChunk & a_Chunk) } } - if ((m_Attachee != NULL) && (!m_bIsTame)) + if ((m_Attachee != nullptr) && (!m_bIsTame)) { if (m_TameAttemptTimes < m_TimesToTame) { @@ -113,7 +113,7 @@ void cHorse::OnRightClicked(cPlayer & a_Player) } else { - if (m_Attachee != NULL) + if (m_Attachee != nullptr) { if (m_Attachee->GetUniqueID() == a_Player.GetUniqueID()) { @@ -141,7 +141,7 @@ void cHorse::OnRightClicked(cPlayer & a_Player) void cHorse::GetDrops(cItems & a_Drops, cEntity * a_Killer) { int LootingLevel = 0; - if (a_Killer != NULL) + if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); } diff --git a/src/Mobs/Horse.h b/src/Mobs/Horse.h index 47189b3b0..4c644e512 100644 --- a/src/Mobs/Horse.h +++ b/src/Mobs/Horse.h @@ -17,7 +17,7 @@ public: CLASS_PROTODEF(cHorse) - virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; virtual void Tick(float a_Dt, cChunk & a_Chunk) override; virtual void OnRightClicked(cPlayer & a_Player) override; diff --git a/src/Mobs/IronGolem.h b/src/Mobs/IronGolem.h index c5341ed76..721ca2701 100644 --- a/src/Mobs/IronGolem.h +++ b/src/Mobs/IronGolem.h @@ -17,7 +17,7 @@ public: CLASS_PROTODEF(cIronGolem) - virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; // Iron golems do not drown nor float virtual void HandleAir(void) override {} diff --git a/src/Mobs/MagmaCube.h b/src/Mobs/MagmaCube.h index bfe63fa2e..d66ea423a 100644 --- a/src/Mobs/MagmaCube.h +++ b/src/Mobs/MagmaCube.h @@ -17,7 +17,7 @@ public: CLASS_PROTODEF(cMagmaCube) - virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; int GetSize(void) const { return m_Size; } protected: diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 34dd08f37..bcdc404c2 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -78,7 +78,7 @@ cMonster::cMonster(const AString & a_ConfigName, eMonsterType a_MobType, const A : super(etMonster, a_Width, a_Height) , m_EMState(IDLE) , m_EMPersonality(AGGRESSIVE) - , m_Target(NULL) + , m_Target(nullptr) , m_bMovingToDestination(false) , m_LastGroundHeight(POSY_TOINT) , m_IdleInterval(0) @@ -273,8 +273,8 @@ void cMonster::Tick(float a_Dt, cChunk & a_Chunk) return; } - if ((m_Target != NULL) && m_Target->IsDestroyed()) - m_Target = NULL; + if ((m_Target != nullptr) && m_Target->IsDestroyed()) + m_Target = nullptr; // Burning in daylight HandleDaylightBurning(a_Chunk); @@ -378,7 +378,7 @@ void cMonster::Tick(float a_Dt, cChunk & a_Chunk) void cMonster::SetPitchAndYawFromDestination() { Vector3d FinalDestination = m_FinalDestination; - if (m_Target != NULL) + if (m_Target != nullptr) { if (m_Target->IsPlayer()) { @@ -422,7 +422,7 @@ void cMonster::HandleFalling() if (Damage > 0) { - TakeDamage(dtFalling, NULL, Damage, Damage, 0); + TakeDamage(dtFalling, nullptr, Damage, Damage, 0); // Fall particles GetWorld()->BroadcastSoundParticleEffect(2006, POSX_TOINT, POSY_TOINT - 1, POSZ_TOINT, Damage /* Used as particle effect speed modifier */); @@ -478,7 +478,7 @@ bool cMonster::DoTakeDamage(TakeDamageInfo & a_TDI) m_World->BroadcastSoundEffect(m_SoundHurt, GetPosX(), GetPosY(), GetPosZ(), 1.0f, 0.8f); } - if (a_TDI.Attacker != NULL) + if (a_TDI.Attacker != nullptr) { m_Target = a_TDI.Attacker; } @@ -555,7 +555,7 @@ void cMonster::KilledBy(TakeDamageInfo & a_TDI) break; } } - if ((a_TDI.Attacker != NULL) && (!IsBaby())) + if ((a_TDI.Attacker != nullptr) && (!IsBaby())) { m_World->SpawnExperienceOrb(GetPosX(), GetPosY(), GetPosZ(), Reward); } @@ -592,7 +592,7 @@ void cMonster::CheckEventSeePlayer(void) // TODO: Rewrite this to use cWorld's DoWithPlayers() cPlayer * Closest = m_World->FindClosestPlayer(GetPosition(), (float)m_SightDistance, false); - if (Closest != NULL) + if (Closest != nullptr) { EventSeePlayer(Closest); } @@ -604,7 +604,7 @@ void cMonster::CheckEventSeePlayer(void) void cMonster::CheckEventLostPlayer(void) { - if (m_Target != NULL) + if (m_Target != nullptr) { if ((m_Target->GetPosition() - GetPosition()).Length() > m_SightDistance) { @@ -634,7 +634,7 @@ void cMonster::EventSeePlayer(cEntity * a_SeenPlayer) void cMonster::EventLosePlayer(void) { - m_Target = NULL; + m_Target = nullptr; m_EMState = IDLE; } @@ -696,7 +696,7 @@ void cMonster::InStateEscaping(float a_Dt) { UNUSED(a_Dt); - if (m_Target != NULL) + if (m_Target != nullptr) { Vector3d newloc = GetPosition(); newloc.x = (m_Target->GetPosition().x < newloc.x)? (newloc.x + m_SightDistance): (newloc.x - m_SightDistance); @@ -723,7 +723,7 @@ void cMonster::SetCustomName(const AString & a_CustomName) m_CustomName = a_CustomName.substr(0, 64); } - if (m_World != NULL) + if (m_World != nullptr) { m_World->BroadcastEntityMetadata(*this); } @@ -736,7 +736,7 @@ void cMonster::SetCustomName(const AString & a_CustomName) void cMonster::SetCustomNameAlwaysVisible(bool a_CustomNameAlwaysVisible) { m_CustomNameAlwaysVisible = a_CustomNameAlwaysVisible; - if (m_World != NULL) + if (m_World != nullptr) { m_World->BroadcastEntityMetadata(*this); } @@ -892,7 +892,7 @@ int cMonster::GetSpawnDelay(cMonster::eFamily a_MobFamily) cMonster * cMonster::NewMonsterFromType(eMonsterType a_MobType) { cFastRandom Random; - cMonster * toReturn = NULL; + cMonster * toReturn = nullptr; // Create the mob entity switch (a_MobType) diff --git a/src/Mobs/Mooshroom.cpp b/src/Mobs/Mooshroom.cpp index 99958720f..ec533cfca 100644 --- a/src/Mobs/Mooshroom.cpp +++ b/src/Mobs/Mooshroom.cpp @@ -25,7 +25,7 @@ cMooshroom::cMooshroom(void) : void cMooshroom::GetDrops(cItems & a_Drops, cEntity * a_Killer) { int LootingLevel = 0; - if (a_Killer != NULL) + if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); } diff --git a/src/Mobs/Mooshroom.h b/src/Mobs/Mooshroom.h index fb002c2bf..754725c92 100644 --- a/src/Mobs/Mooshroom.h +++ b/src/Mobs/Mooshroom.h @@ -17,7 +17,7 @@ public: CLASS_PROTODEF(cMooshroom) - virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; virtual void OnRightClicked(cPlayer & a_Player) override; virtual const cItem GetFollowedItem(void) const override { return cItem(E_ITEM_WHEAT); } diff --git a/src/Mobs/PassiveAggressiveMonster.cpp b/src/Mobs/PassiveAggressiveMonster.cpp index e0cc2fd21..cb8650cb9 100644 --- a/src/Mobs/PassiveAggressiveMonster.cpp +++ b/src/Mobs/PassiveAggressiveMonster.cpp @@ -26,7 +26,7 @@ bool cPassiveAggressiveMonster::DoTakeDamage(TakeDamageInfo & a_TDI) return false; } - if ((m_Target != NULL) && (m_Target->IsPlayer())) + if ((m_Target != nullptr) && (m_Target->IsPlayer())) { if (!((cPlayer *)m_Target)->IsGameModeCreative()) { diff --git a/src/Mobs/PassiveMonster.cpp b/src/Mobs/PassiveMonster.cpp index be3043e3d..1048616d0 100644 --- a/src/Mobs/PassiveMonster.cpp +++ b/src/Mobs/PassiveMonster.cpp @@ -24,7 +24,7 @@ bool cPassiveMonster::DoTakeDamage(TakeDamageInfo & a_TDI) { return false; } - if ((a_TDI.Attacker != this) && (a_TDI.Attacker != NULL)) + if ((a_TDI.Attacker != this) && (a_TDI.Attacker != nullptr)) { m_EMState = ESCAPING; } @@ -49,7 +49,7 @@ void cPassiveMonster::Tick(float a_Dt, cChunk & a_Chunk) return; } cPlayer * a_Closest_Player = m_World->FindClosestPlayer(GetPosition(), (float)m_SightDistance); - if (a_Closest_Player != NULL) + if (a_Closest_Player != nullptr) { if (a_Closest_Player->GetEquippedItem().IsEqual(FollowedItem)) { diff --git a/src/Mobs/Pig.cpp b/src/Mobs/Pig.cpp index 1f77cf613..55a4412ca 100644 --- a/src/Mobs/Pig.cpp +++ b/src/Mobs/Pig.cpp @@ -22,7 +22,7 @@ cPig::cPig(void) : void cPig::GetDrops(cItems & a_Drops, cEntity * a_Killer) { int LootingLevel = 0; - if (a_Killer != NULL) + if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); } @@ -41,7 +41,7 @@ void cPig::OnRightClicked(cPlayer & a_Player) { if (m_bIsSaddled) { - if (m_Attachee != NULL) + if (m_Attachee != nullptr) { if (m_Attachee->GetUniqueID() == a_Player.GetUniqueID()) { @@ -85,7 +85,7 @@ void cPig::Tick(float a_Dt, cChunk & a_Chunk) super::Tick(a_Dt, a_Chunk); // If the attachee player is holding a carrot-on-stick, let them drive this pig: - if (m_bIsSaddled && (m_Attachee != NULL)) + if (m_bIsSaddled && (m_Attachee != nullptr)) { if (m_Attachee->IsPlayer() && (m_Attachee->GetEquippedWeapon().m_ItemType == E_ITEM_CARROT_ON_STICK)) { diff --git a/src/Mobs/Pig.h b/src/Mobs/Pig.h index 534a0ca6f..953850b3a 100644 --- a/src/Mobs/Pig.h +++ b/src/Mobs/Pig.h @@ -17,7 +17,7 @@ public: CLASS_PROTODEF(cPig) - virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; virtual void OnRightClicked(cPlayer & a_Player) override; virtual void Tick(float a_Dt, cChunk & a_Chunk) override; diff --git a/src/Mobs/Sheep.cpp b/src/Mobs/Sheep.cpp index cbb33cb90..c46404391 100644 --- a/src/Mobs/Sheep.cpp +++ b/src/Mobs/Sheep.cpp @@ -41,7 +41,7 @@ void cSheep::GetDrops(cItems & a_Drops, cEntity * a_Killer) } int LootingLevel = 0; - if (a_Killer != NULL) + if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); } diff --git a/src/Mobs/Sheep.h b/src/Mobs/Sheep.h index 28e1c7254..16d5fddd3 100644 --- a/src/Mobs/Sheep.h +++ b/src/Mobs/Sheep.h @@ -22,7 +22,7 @@ public: CLASS_PROTODEF(cSheep) - virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; virtual void OnRightClicked(cPlayer & a_Player) override; virtual void Tick(float a_Dt, cChunk & a_Chunk) override; diff --git a/src/Mobs/Skeleton.cpp b/src/Mobs/Skeleton.cpp index cd707f4bb..f17bc307c 100644 --- a/src/Mobs/Skeleton.cpp +++ b/src/Mobs/Skeleton.cpp @@ -23,7 +23,7 @@ cSkeleton::cSkeleton(bool IsWither) : void cSkeleton::GetDrops(cItems & a_Drops, cEntity * a_Killer) { int LootingLevel = 0; - if (a_Killer != NULL) + if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); } @@ -71,20 +71,20 @@ void cSkeleton::Attack(float a_Dt) { m_AttackInterval += a_Dt * m_AttackRate; - if (m_Target != NULL && m_AttackInterval > 3.0) + if (m_Target != nullptr && m_AttackInterval > 3.0) { // Setting this higher gives us more wiggle room for attackrate Vector3d Speed = GetLookVector() * 20; Speed.y = Speed.y + 1; cArrowEntity * Arrow = new cArrowEntity(this, GetPosX(), GetPosY() + 1, GetPosZ(), Speed); - if (Arrow == NULL) + if (Arrow == nullptr) { return; } if (!Arrow->Initialize(*m_World)) { delete Arrow; - Arrow = NULL; + Arrow = nullptr; return; } m_World->BroadcastSpawnEntity(*Arrow); diff --git a/src/Mobs/Skeleton.h b/src/Mobs/Skeleton.h index 577588b32..cd1c6c3f0 100644 --- a/src/Mobs/Skeleton.h +++ b/src/Mobs/Skeleton.h @@ -17,7 +17,7 @@ public: CLASS_PROTODEF(cSkeleton) - virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; virtual void MoveToPosition(const Vector3d & a_Position) override; virtual void Attack(float a_Dt) override; virtual void SpawnOn(cClientHandle & a_ClientHandle) override; diff --git a/src/Mobs/Slime.cpp b/src/Mobs/Slime.cpp index b709ec664..1c68c5189 100644 --- a/src/Mobs/Slime.cpp +++ b/src/Mobs/Slime.cpp @@ -30,7 +30,7 @@ cSlime::cSlime(int a_Size) : void cSlime::GetDrops(cItems & a_Drops, cEntity * a_Killer) { int LootingLevel = 0; - if (a_Killer != NULL) + if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); } diff --git a/src/Mobs/Slime.h b/src/Mobs/Slime.h index f0b800f94..a177a279c 100644 --- a/src/Mobs/Slime.h +++ b/src/Mobs/Slime.h @@ -19,7 +19,7 @@ public: CLASS_PROTODEF(cSlime) // cAggressiveMonster overrides: - virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; virtual void Attack(float a_Dt) override; virtual void KilledBy(TakeDamageInfo & a_TDI) override; diff --git a/src/Mobs/SnowGolem.h b/src/Mobs/SnowGolem.h index aba89e52d..f036b1867 100644 --- a/src/Mobs/SnowGolem.h +++ b/src/Mobs/SnowGolem.h @@ -18,7 +18,7 @@ public: CLASS_PROTODEF(cSnowGolem) virtual void Tick(float a_Dt, cChunk & a_Chunk) override; - virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; } ; diff --git a/src/Mobs/Spider.cpp b/src/Mobs/Spider.cpp index 8b978ff6b..deb263c41 100644 --- a/src/Mobs/Spider.cpp +++ b/src/Mobs/Spider.cpp @@ -19,12 +19,12 @@ cSpider::cSpider(void) : void cSpider::GetDrops(cItems & a_Drops, cEntity * a_Killer) { int LootingLevel = 0; - if (a_Killer != NULL) + if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); } AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_STRING); - if ((a_Killer != NULL) && (a_Killer->IsPlayer() || a_Killer->IsA("cWolf"))) + if ((a_Killer != nullptr) && (a_Killer->IsPlayer() || a_Killer->IsA("cWolf"))) { AddRandomUncommonDropItem(a_Drops, 33.0f, E_ITEM_SPIDER_EYE); } diff --git a/src/Mobs/Spider.h b/src/Mobs/Spider.h index 813d2e266..24134c00f 100644 --- a/src/Mobs/Spider.h +++ b/src/Mobs/Spider.h @@ -17,7 +17,7 @@ public: CLASS_PROTODEF(cSpider) - virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; } ; diff --git a/src/Mobs/Squid.cpp b/src/Mobs/Squid.cpp index bd0e141a0..59ee963ae 100644 --- a/src/Mobs/Squid.cpp +++ b/src/Mobs/Squid.cpp @@ -22,7 +22,7 @@ void cSquid::GetDrops(cItems & a_Drops, cEntity * a_Killer) { // Drops 0-3 Ink Sacs int LootingLevel = 0; - if (a_Killer != NULL) + if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); } diff --git a/src/Mobs/Squid.h b/src/Mobs/Squid.h index b57340427..a46d738c6 100644 --- a/src/Mobs/Squid.h +++ b/src/Mobs/Squid.h @@ -19,7 +19,7 @@ public: CLASS_PROTODEF(cSquid) - virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; // Squids do not drown (or float) virtual void HandleAir(void) override {} diff --git a/src/Mobs/Villager.cpp b/src/Mobs/Villager.cpp index 0efd5501e..5c9999a59 100644 --- a/src/Mobs/Villager.cpp +++ b/src/Mobs/Villager.cpp @@ -30,7 +30,7 @@ bool cVillager::DoTakeDamage(TakeDamageInfo & a_TDI) return false; } - if ((a_TDI.Attacker != NULL) && a_TDI.Attacker->IsPlayer()) + if ((a_TDI.Attacker != nullptr) && a_TDI.Attacker->IsPlayer()) { if (m_World->GetTickRandomNumber(5) == 3) { diff --git a/src/Mobs/Witch.cpp b/src/Mobs/Witch.cpp index 947be0011..a3cadbaa0 100644 --- a/src/Mobs/Witch.cpp +++ b/src/Mobs/Witch.cpp @@ -20,7 +20,7 @@ cWitch::cWitch(void) : void cWitch::GetDrops(cItems & a_Drops, cEntity * a_Killer) { int LootingLevel = 0; - if (a_Killer != NULL) + if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); } diff --git a/src/Mobs/Witch.h b/src/Mobs/Witch.h index 85d3e1447..8230e1f98 100644 --- a/src/Mobs/Witch.h +++ b/src/Mobs/Witch.h @@ -17,7 +17,7 @@ public: CLASS_PROTODEF(cWitch) - virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; bool IsAngry(void) const {return ((m_EMState == ATTACKING) || (m_EMState == CHASING)); } } ; diff --git a/src/Mobs/Wither.h b/src/Mobs/Wither.h index 2403823ed..a20fed3d3 100644 --- a/src/Mobs/Wither.h +++ b/src/Mobs/Wither.h @@ -26,7 +26,7 @@ public: // cEntity overrides virtual bool Initialize(cWorld & a_World) override; - virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; virtual bool DoTakeDamage(TakeDamageInfo & a_TDI) override; virtual void Tick(float a_Dt, cChunk & a_Chunk) override; virtual void KilledBy(TakeDamageInfo & a_TDI) override; diff --git a/src/Mobs/Wolf.cpp b/src/Mobs/Wolf.cpp index 4fe1ff1d6..4711d5a7a 100644 --- a/src/Mobs/Wolf.cpp +++ b/src/Mobs/Wolf.cpp @@ -47,7 +47,7 @@ void cWolf::Attack(float a_Dt) { UNUSED(a_Dt); - if ((m_Target != NULL) && (m_Target->IsPlayer())) + if ((m_Target != nullptr) && (m_Target->IsPlayer())) { if (((cPlayer *)m_Target)->GetName() != m_OwnerName) { @@ -157,7 +157,7 @@ void cWolf::Tick(float a_Dt, cChunk & a_Chunk) } cPlayer * a_Closest_Player = m_World->FindClosestPlayer(GetPosition(), (float)m_SightDistance); - if (a_Closest_Player != NULL) + if (a_Closest_Player != nullptr) { switch (a_Closest_Player->GetEquippedItem().m_ItemType) { diff --git a/src/Mobs/Zombie.cpp b/src/Mobs/Zombie.cpp index 30225c32d..63042e252 100644 --- a/src/Mobs/Zombie.cpp +++ b/src/Mobs/Zombie.cpp @@ -24,7 +24,7 @@ cZombie::cZombie(bool a_IsVillagerZombie) : void cZombie::GetDrops(cItems & a_Drops, cEntity * a_Killer) { int LootingLevel = 0; - if (a_Killer != NULL) + if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); } diff --git a/src/Mobs/Zombie.h b/src/Mobs/Zombie.h index 118b6e6e7..809c2a6fe 100644 --- a/src/Mobs/Zombie.h +++ b/src/Mobs/Zombie.h @@ -16,7 +16,7 @@ public: CLASS_PROTODEF(cZombie) - virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; virtual void MoveToPosition(const Vector3d & a_Position) override; virtual bool IsUndead(void) override { return true; } diff --git a/src/Mobs/ZombiePigman.cpp b/src/Mobs/ZombiePigman.cpp index 05350f877..8b415b0af 100644 --- a/src/Mobs/ZombiePigman.cpp +++ b/src/Mobs/ZombiePigman.cpp @@ -19,7 +19,7 @@ cZombiePigman::cZombiePigman(void) : void cZombiePigman::GetDrops(cItems & a_Drops, cEntity * a_Killer) { int LootingLevel = 0; - if (a_Killer != NULL) + if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); } @@ -41,7 +41,7 @@ void cZombiePigman::KilledBy(TakeDamageInfo & a_TDI) { super::KilledBy(a_TDI); - if ((a_TDI.Attacker != NULL) && (a_TDI.Attacker->IsPlayer())) + if ((a_TDI.Attacker != nullptr) && (a_TDI.Attacker->IsPlayer())) { // TODO: Anger all nearby zombie pigmen // TODO: In vanilla, if one player angers ZPs, do they attack any nearby player, or only that one attacker? diff --git a/src/Mobs/ZombiePigman.h b/src/Mobs/ZombiePigman.h index bae0115eb..d8b886ca4 100644 --- a/src/Mobs/ZombiePigman.h +++ b/src/Mobs/ZombiePigman.h @@ -16,7 +16,7 @@ public: CLASS_PROTODEF(cZombiePigman) - virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; virtual void KilledBy(TakeDamageInfo & a_TDI) override; virtual bool IsUndead(void) override { return true; } diff --git a/src/MonsterConfig.cpp b/src/MonsterConfig.cpp index f5e078213..a15e413ba 100644 --- a/src/MonsterConfig.cpp +++ b/src/MonsterConfig.cpp @@ -47,7 +47,7 @@ cMonsterConfig::cMonsterConfig(void) cMonsterConfig::~cMonsterConfig() { delete m_pState; - m_pState = NULL; + m_pState = nullptr; } diff --git a/src/Noise.cpp b/src/Noise.cpp index 71e801f30..8fcfe2920 100644 --- a/src/Noise.cpp +++ b/src/Noise.cpp @@ -845,7 +845,7 @@ void cPerlinNoise::Generate2D( return; } - bool ShouldFreeWorkspace = (a_Workspace == NULL); + bool ShouldFreeWorkspace = (a_Workspace == nullptr); int ArrayCount = a_SizeX * a_SizeY; if (ShouldFreeWorkspace) { @@ -886,7 +886,7 @@ void cPerlinNoise::Generate2D( if (ShouldFreeWorkspace) { delete[] a_Workspace; - a_Workspace = NULL; + a_Workspace = nullptr; } } @@ -910,7 +910,7 @@ void cPerlinNoise::Generate3D( return; } - bool ShouldFreeWorkspace = (a_Workspace == NULL); + bool ShouldFreeWorkspace = (a_Workspace == nullptr); int ArrayCount = a_SizeX * a_SizeY * a_SizeZ; if (ShouldFreeWorkspace) { @@ -953,7 +953,7 @@ void cPerlinNoise::Generate3D( if (ShouldFreeWorkspace) { delete[] a_Workspace; - a_Workspace = NULL; + a_Workspace = nullptr; } } @@ -1015,7 +1015,7 @@ void cRidgedMultiNoise::Generate2D( return; } - bool ShouldFreeWorkspace = (a_Workspace == NULL); + bool ShouldFreeWorkspace = (a_Workspace == nullptr); int ArrayCount = a_SizeX * a_SizeY; if (ShouldFreeWorkspace) { @@ -1056,7 +1056,7 @@ void cRidgedMultiNoise::Generate2D( if (ShouldFreeWorkspace) { delete[] a_Workspace; - a_Workspace = NULL; + a_Workspace = nullptr; } } @@ -1080,7 +1080,7 @@ void cRidgedMultiNoise::Generate3D( return; } - bool ShouldFreeWorkspace = (a_Workspace == NULL); + bool ShouldFreeWorkspace = (a_Workspace == nullptr); int ArrayCount = a_SizeX * a_SizeY * a_SizeZ; if (ShouldFreeWorkspace) { @@ -1123,7 +1123,7 @@ void cRidgedMultiNoise::Generate3D( if (ShouldFreeWorkspace) { delete[] a_Workspace; - a_Workspace = NULL; + a_Workspace = nullptr; } } diff --git a/src/Noise.h b/src/Noise.h index 4cf8d4ad8..b7a90d5b7 100644 --- a/src/Noise.h +++ b/src/Noise.h @@ -155,7 +155,7 @@ public: NOISE_DATATYPE * a_Array, ///< Array to generate into int a_SizeX, ///< Count of the array NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array - NOISE_DATATYPE * a_Workspace = NULL ///< Workspace that this function can use and trash + NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash ) const; @@ -164,7 +164,7 @@ public: int a_SizeX, int a_SizeY, ///< Count of the array, in each direction NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction - NOISE_DATATYPE * a_Workspace = NULL ///< Workspace that this function can use and trash + NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash ) const; @@ -174,7 +174,7 @@ public: NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction NOISE_DATATYPE a_StartZ, NOISE_DATATYPE a_EndZ, ///< Noise-space coords of the array in the Z direction - NOISE_DATATYPE * a_Workspace = NULL ///< Workspace that this function can use and trash + NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash ) const; protected: @@ -219,7 +219,7 @@ public: NOISE_DATATYPE * a_Array, ///< Array to generate into int a_SizeX, ///< Count of the array NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array - NOISE_DATATYPE * a_Workspace = NULL ///< Workspace that this function can use and trash + NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash ) const; @@ -228,7 +228,7 @@ public: int a_SizeX, int a_SizeY, ///< Count of the array, in each direction NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction - NOISE_DATATYPE * a_Workspace = NULL ///< Workspace that this function can use and trash + NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash ) const; @@ -238,7 +238,7 @@ public: NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction NOISE_DATATYPE a_StartZ, NOISE_DATATYPE a_EndZ, ///< Noise-space coords of the array in the Z direction - NOISE_DATATYPE * a_Workspace = NULL ///< Workspace that this function can use and trash + NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash ) const; protected: diff --git a/src/OSSupport/Errors.cpp b/src/OSSupport/Errors.cpp index 9401ec257..a5361e1a6 100644 --- a/src/OSSupport/Errors.cpp +++ b/src/OSSupport/Errors.cpp @@ -10,7 +10,7 @@ AString GetOSErrorString( int a_ErrNo) #ifdef _WIN32 - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, a_ErrNo, 0, buffer, ARRAYCOUNT(buffer), NULL); + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, a_ErrNo, 0, buffer, ARRAYCOUNT(buffer), nullptr); Printf(Out, "%d: %s", a_ErrNo, buffer); if (!Out.empty() && (Out[Out.length() - 1] == '\n')) { @@ -25,7 +25,7 @@ AString GetOSErrorString( int a_ErrNo) #if !defined(__APPLE__) && ( _GNU_SOURCE) && !defined(ANDROID_NDK) // GNU version of strerror_r() char * res = strerror_r( errno, buffer, ARRAYCOUNT(buffer)); - if (res != NULL) + if (res != nullptr) { Printf(Out, "%d: %s", a_ErrNo, res); return Out; diff --git a/src/OSSupport/Event.cpp b/src/OSSupport/Event.cpp index 7cf8a826c..87bc110ce 100644 --- a/src/OSSupport/Event.cpp +++ b/src/OSSupport/Event.cpp @@ -15,8 +15,8 @@ cEvent::cEvent(void) { #ifdef _WIN32 - m_Event = CreateEvent(NULL, FALSE, FALSE, NULL); - if (m_Event == NULL) + m_Event = CreateEvent(nullptr, FALSE, FALSE, nullptr); + if (m_Event == nullptr) { LOGERROR("cEvent: cannot create event, GLE = %u. Aborting server.", (unsigned)GetLastError()); abort(); @@ -71,7 +71,7 @@ cEvent::~cEvent() { sem_destroy(m_Event); delete m_Event; - m_Event = NULL; + m_Event = nullptr; } #endif } diff --git a/src/OSSupport/File.cpp b/src/OSSupport/File.cpp index cb6031da6..8957dfaef 100644 --- a/src/OSSupport/File.cpp +++ b/src/OSSupport/File.cpp @@ -17,7 +17,7 @@ cFile::cFile(void) : #ifdef USE_STDIO_FILE - m_File(NULL) + m_File(nullptr) #else m_File(INVALID_HANDLE_VALUE) #endif // USE_STDIO_FILE @@ -31,7 +31,7 @@ cFile::cFile(void) : cFile::cFile(const AString & iFileName, eMode iMode) : #ifdef USE_STDIO_FILE - m_File(NULL) + m_File(nullptr) #else m_File(INVALID_HANDLE_VALUE) #endif // USE_STDIO_FILE @@ -64,7 +64,7 @@ bool cFile::Open(const AString & iFileName, eMode iMode) Close(); } - const char * Mode = NULL; + const char * Mode = nullptr; switch (iMode) { case fmRead: Mode = "rb"; break; @@ -72,7 +72,7 @@ bool cFile::Open(const AString & iFileName, eMode iMode) case fmReadWrite: Mode = "rb+"; break; case fmAppend: Mode = "a+"; break; } - if (Mode == NULL) + if (Mode == nullptr) { ASSERT(!"Unhandled file mode"); return false; @@ -84,7 +84,7 @@ bool cFile::Open(const AString & iFileName, eMode iMode) m_File = fopen((FILE_IO_PREFIX + iFileName).c_str(), Mode); #endif // _WIN32 - if ((m_File == NULL) && (iMode == fmReadWrite)) + if ((m_File == nullptr) && (iMode == fmReadWrite)) { // Fix for MS not following C spec, opening "a" mode files for writing at the end only // The file open operation has been tried with "read update", fails if file not found @@ -98,7 +98,7 @@ bool cFile::Open(const AString & iFileName, eMode iMode) #endif // _WIN32 } - return (m_File != NULL); + return (m_File != nullptr); } @@ -114,7 +114,7 @@ void cFile::Close(void) } fclose(m_File); - m_File = NULL; + m_File = nullptr; } @@ -123,7 +123,7 @@ void cFile::Close(void) bool cFile::IsOpen(void) const { - return (m_File != NULL); + return (m_File != nullptr); } @@ -366,7 +366,7 @@ int cFile::GetSize(const AString & a_FileName) bool cFile::CreateFolder(const AString & a_FolderPath) { #ifdef _WIN32 - return (CreateDirectoryA(a_FolderPath.c_str(), NULL) != 0); + return (CreateDirectoryA(a_FolderPath.c_str(), nullptr) != 0); #else return (mkdir(a_FolderPath.c_str(), S_IRWXU | S_IRWXG | S_IRWXO) == 0); #endif @@ -415,13 +415,13 @@ AStringVector cFile::GetFolderContents(const AString & a_Folder) { Folder = "."; } - if ((dp = opendir(Folder.c_str())) == NULL) + if ((dp = opendir(Folder.c_str())) == nullptr) { LOGERROR("Error (%i) opening directory \"%s\"\n", errno, Folder.c_str()); } else { - while ((dirp = readdir(dp)) != NULL) + while ((dirp = readdir(dp)) != nullptr) { AllFiles.push_back(dirp->d_name); } diff --git a/src/OSSupport/GZipFile.cpp b/src/OSSupport/GZipFile.cpp index 22d887783..32d84a0d5 100644 --- a/src/OSSupport/GZipFile.cpp +++ b/src/OSSupport/GZipFile.cpp @@ -11,7 +11,7 @@ cGZipFile::cGZipFile(void) : - m_File(NULL), m_Mode(fmRead) + m_File(nullptr), m_Mode(fmRead) { } @@ -30,14 +30,14 @@ cGZipFile::~cGZipFile() bool cGZipFile::Open(const AString & a_FileName, eMode a_Mode) { - if (m_File != NULL) + if (m_File != nullptr) { ASSERT(!"A file is already open in this object"); return false; } m_File = gzopen(a_FileName.c_str(), (a_Mode == fmRead) ? "r" : "w"); m_Mode = a_Mode; - return (m_File != NULL); + return (m_File != nullptr); } @@ -46,10 +46,10 @@ bool cGZipFile::Open(const AString & a_FileName, eMode a_Mode) void cGZipFile::Close(void) { - if (m_File != NULL) + if (m_File != nullptr) { gzclose(m_File); - m_File = NULL; + m_File = nullptr; } } @@ -59,7 +59,7 @@ void cGZipFile::Close(void) int cGZipFile::ReadRestOfFile(AString & a_Contents) { - if (m_File == NULL) + if (m_File == nullptr) { ASSERT(!"No file has been opened"); return -1; @@ -90,7 +90,7 @@ int cGZipFile::ReadRestOfFile(AString & a_Contents) bool cGZipFile::Write(const char * a_Contents, int a_Size) { - if (m_File == NULL) + if (m_File == nullptr) { ASSERT(!"No file has been opened"); return false; diff --git a/src/OSSupport/ListenThread.cpp b/src/OSSupport/ListenThread.cpp index 02e98acfc..b029634e9 100644 --- a/src/OSSupport/ListenThread.cpp +++ b/src/OSSupport/ListenThread.cpp @@ -214,7 +214,7 @@ void cListenThread::Execute(void) timeval tv; // On Linux select() doesn't seem to wake up when socket is closed, so let's kinda busy-wait: tv.tv_sec = 1; tv.tv_usec = 0; - if (select((int)Highest + 1, &fdRead, NULL, NULL, &tv) == -1) + if (select((int)Highest + 1, &fdRead, nullptr, nullptr, &tv) == -1) { LOG("select(R) call failed in cListenThread: \"%s\"", cSocket::GetLastErrorString().c_str()); continue; diff --git a/src/OSSupport/Semaphore.cpp b/src/OSSupport/Semaphore.cpp index c1fc7d9c7..6a2d57901 100644 --- a/src/OSSupport/Semaphore.cpp +++ b/src/OSSupport/Semaphore.cpp @@ -36,7 +36,7 @@ cSemaphore::cSemaphore( unsigned int a_MaxCount, unsigned int a_InitialCount /* } #else m_Handle = CreateSemaphore( - NULL, // security attribute + nullptr, // security attribute a_InitialCount, // initial count a_MaxCount, // maximum count 0 // name (optional) @@ -98,7 +98,7 @@ void cSemaphore::Signal() LOG("ERROR: Could not signal cSemaphore. (%i)", errno); } #else - ReleaseSemaphore( m_Handle, 1, NULL); + ReleaseSemaphore( m_Handle, 1, nullptr); #endif } diff --git a/src/OSSupport/Socket.cpp b/src/OSSupport/Socket.cpp index c07d31c8b..5025a09ad 100644 --- a/src/OSSupport/Socket.cpp +++ b/src/OSSupport/Socket.cpp @@ -292,7 +292,7 @@ bool cSocket::ConnectIPv4(const AString & a_HostNameOrAddr, unsigned short a_Por { // It is not an IP Address string, but rather a regular hostname, resolve: hostent * hp = gethostbyname(a_HostNameOrAddr.c_str()); - if (hp == NULL) + if (hp == nullptr) { LOGWARNING("%s: Could not resolve hostname \"%s\"", __FUNCTION__, a_HostNameOrAddr.c_str()); CloseSocket(); diff --git a/src/OSSupport/SocketThreads.cpp b/src/OSSupport/SocketThreads.cpp index f436318a5..7a3ef4274 100644 --- a/src/OSSupport/SocketThreads.cpp +++ b/src/OSSupport/SocketThreads.cpp @@ -61,7 +61,7 @@ bool cSocketThreads::AddClient(const cSocket & a_Socket, cCallback * a_Client) // There was an error launching the thread (but it was already logged along with the reason) LOGERROR("A new cSocketThread failed to start"); delete Thread; - Thread = NULL; + Thread = nullptr; return false; } Thread->AddClient(a_Socket, a_Client); @@ -233,7 +233,7 @@ bool cSocketThreads::cSocketThread::RemoveClient(const cCallback * a_Client) // More data to send, shut down reading and wait for the rest to get sent: m_Slots[i].m_State = sSlot::ssWritingRestOut; } - m_Slots[i].m_Client = NULL; + m_Slots[i].m_Client = nullptr; } // Notify the thread of the change: @@ -407,7 +407,7 @@ void cSocketThreads::cSocketThread::Execute(void) timeval Timeout; Timeout.tv_sec = 5; Timeout.tv_usec = 0; - if (select((int)Highest + 1, &fdRead, &fdWrite, NULL, &Timeout) == -1) + if (select((int)Highest + 1, &fdRead, &fdWrite, nullptr, &Timeout) == -1) { LOG("select() call failed in cSocketThread: \"%s\"", cSocket::GetLastErrorString().c_str()); continue; @@ -519,7 +519,7 @@ void cSocketThreads::cSocketThread::ReadFromSockets(fd_set * a_Read) } else { - if (m_Slots[i].m_Client != NULL) + if (m_Slots[i].m_Client != nullptr) { m_Slots[i].m_Client->DataReceived(Buffer, Received); } @@ -545,7 +545,7 @@ void cSocketThreads::cSocketThread::WriteToSockets(fd_set * a_Write) if (m_Slots[i].m_Outgoing.empty()) { // Request another chunk of outgoing data: - if (m_Slots[i].m_Client != NULL) + if (m_Slots[i].m_Client != nullptr) { AString Data; m_Slots[i].m_Client->GetOutgoingData(Data); @@ -573,7 +573,7 @@ void cSocketThreads::cSocketThread::WriteToSockets(fd_set * a_Write) int Err = cSocket::GetLastError(); LOGWARNING("Error %d while writing to client \"%s\", disconnecting. \"%s\"", Err, m_Slots[i].m_Socket.GetIPString().c_str(), GetOSErrorString(Err).c_str()); m_Slots[i].m_Socket.CloseSocket(); - if (m_Slots[i].m_Client != NULL) + if (m_Slots[i].m_Client != nullptr) { m_Slots[i].m_Client->SocketClosed(); } @@ -668,7 +668,7 @@ void cSocketThreads::cSocketThread::QueueOutgoingData(void) cCSLock Lock(m_Parent->m_CS); for (int i = 0; i < m_NumSlots; i++) { - if (m_Slots[i].m_Client != NULL) + if (m_Slots[i].m_Client != nullptr) { AString Data; m_Slots[i].m_Client->GetOutgoingData(Data); diff --git a/src/OSSupport/SocketThreads.h b/src/OSSupport/SocketThreads.h index 944f5f3bc..df819468d 100644 --- a/src/OSSupport/SocketThreads.h +++ b/src/OSSupport/SocketThreads.h @@ -137,7 +137,7 @@ private: /** The socket is primarily owned by this object */ cSocket m_Socket; - /** The callback to call for events. May be NULL */ + /** The callback to call for events. May be nullptr */ cCallback * m_Client; /** If sending writes only partial data, the rest is stored here for another send. diff --git a/src/PolarSSL++/BlockingSslClientSocket.cpp b/src/PolarSSL++/BlockingSslClientSocket.cpp index 699bc57ee..59e1281ac 100644 --- a/src/PolarSSL++/BlockingSslClientSocket.cpp +++ b/src/PolarSSL++/BlockingSslClientSocket.cpp @@ -48,7 +48,7 @@ bool cBlockingSslClientSocket::Connect(const AString & a_ServerName, UInt16 a_Po } // If we have been assigned a trusted CA root cert store, push it into the SSL context: - if (m_CACerts.get() != NULL) + if (m_CACerts.get() != nullptr) { m_Ssl.SetCACerts(m_CACerts, m_ExpectedPeerName); } @@ -72,7 +72,7 @@ bool cBlockingSslClientSocket::Connect(const AString & a_ServerName, UInt16 a_Po bool cBlockingSslClientSocket::SetTrustedRootCertsFromString(const AString & a_CACerts, const AString & a_ExpectedPeerName) { // Warn if used multiple times, but don't signal an error: - if (m_CACerts.get() != NULL) + if (m_CACerts.get() != nullptr) { LOGWARNING( "SSL: Trying to set multiple trusted CA root cert stores, only the last one will be used. Name: %s", diff --git a/src/PolarSSL++/CallbackSslContext.cpp b/src/PolarSSL++/CallbackSslContext.cpp index c4d19b2a0..e061e3f03 100644 --- a/src/PolarSSL++/CallbackSslContext.cpp +++ b/src/PolarSSL++/CallbackSslContext.cpp @@ -12,7 +12,7 @@ cCallbackSslContext::cCallbackSslContext(void) : - m_Callbacks(NULL) + m_Callbacks(nullptr) { // Nothing needed, but the constructor needs to exist so } @@ -32,7 +32,7 @@ cCallbackSslContext::cCallbackSslContext(cCallbackSslContext::cDataCallbacks & a int cCallbackSslContext::ReceiveEncrypted(unsigned char * a_Buffer, size_t a_NumBytes) { - if (m_Callbacks == NULL) + if (m_Callbacks == nullptr) { LOGWARNING("SSL: Trying to receive data with no callbacks, aborting."); return POLARSSL_ERR_NET_RECV_FAILED; @@ -46,7 +46,7 @@ int cCallbackSslContext::ReceiveEncrypted(unsigned char * a_Buffer, size_t a_Num int cCallbackSslContext::SendEncrypted(const unsigned char * a_Buffer, size_t a_NumBytes) { - if (m_Callbacks == NULL) + if (m_Callbacks == nullptr) { LOGWARNING("SSL: Trying to send data with no callbacks, aborting."); return POLARSSL_ERR_NET_SEND_FAILED; diff --git a/src/PolarSSL++/CryptoKey.cpp b/src/PolarSSL++/CryptoKey.cpp index 0763c387b..7c4f021b3 100644 --- a/src/PolarSSL++/CryptoKey.cpp +++ b/src/PolarSSL++/CryptoKey.cpp @@ -123,7 +123,7 @@ int cCryptoKey::ParsePrivate(const void * a_Data, size_t a_NumBytes, const AStri if (a_Password.empty()) { - return pk_parse_key(&m_Pk, (const unsigned char *)a_Data, a_NumBytes, NULL, 0); + return pk_parse_key(&m_Pk, (const unsigned char *)a_Data, a_NumBytes, nullptr, 0); } else { diff --git a/src/PolarSSL++/SslContext.cpp b/src/PolarSSL++/SslContext.cpp index 482470c3a..902267f90 100644 --- a/src/PolarSSL++/SslContext.cpp +++ b/src/PolarSSL++/SslContext.cpp @@ -46,7 +46,7 @@ int cSslContext::Initialize(bool a_IsClient, const SharedPtr & // Set the CtrDrbg context, create a new one if needed: m_CtrDrbg = a_CtrDrbg; - if (m_CtrDrbg.get() == NULL) + if (m_CtrDrbg.get() == nullptr) { m_CtrDrbg.reset(new cCtrDrbgContext); m_CtrDrbg->Initialize("MCServer", 8); @@ -98,7 +98,7 @@ void cSslContext::SetOwnCert(const cX509CertPtr & a_OwnCert, const cRsaPrivateKe ASSERT(m_IsValid); // Call Initialize() first // Check that both the cert and the key is valid: - if ((a_OwnCert.get() == NULL) || (a_OwnCertPrivKey.get() == NULL)) + if ((a_OwnCert.get() == nullptr) || (a_OwnCertPrivKey.get() == nullptr)) { LOGWARNING("SSL: Own certificate is not valid, skipping the set."); return; @@ -121,7 +121,7 @@ void cSslContext::SetOwnCert(const cX509CertPtr & a_OwnCert, const cCryptoKeyPtr ASSERT(m_IsValid); // Call Initialize() first // Check that both the cert and the key is valid: - if ((a_OwnCert.get() == NULL) || (a_OwnCertPrivKey.get() == NULL)) + if ((a_OwnCert.get() == nullptr) || (a_OwnCertPrivKey.get() == nullptr)) { LOGWARNING("SSL: Own certificate is not valid, skipping the set."); return; @@ -150,7 +150,7 @@ void cSslContext::SetCACerts(const cX509CertPtr & a_CACert, const AString & a_Ex // Set the trusted CA root cert store: ssl_set_authmode(&m_Ssl, SSL_VERIFY_REQUIRED); - ssl_set_ca_chain(&m_Ssl, m_CACerts->GetInternal(), NULL, m_ExpectedPeerName.empty() ? NULL : m_ExpectedPeerName.c_str()); + ssl_set_ca_chain(&m_Ssl, m_CACerts->GetInternal(), nullptr, m_ExpectedPeerName.empty() ? nullptr : m_ExpectedPeerName.c_str()); } diff --git a/src/Protocol/MojangAPI.cpp b/src/Protocol/MojangAPI.cpp index a4b4dbd3b..dd0d62af5 100644 --- a/src/Protocol/MojangAPI.cpp +++ b/src/Protocol/MojangAPI.cpp @@ -196,7 +196,7 @@ cMojangAPI::cMojangAPI(void) : m_NameToUUIDAddress(DEFAULT_NAME_TO_UUID_ADDRESS), m_UUIDToProfileServer(DEFAULT_UUID_TO_PROFILE_SERVER), m_UUIDToProfileAddress(DEFAULT_UUID_TO_PROFILE_ADDRESS), - m_RankMgr(NULL), + m_RankMgr(nullptr), m_UpdateThread(new cUpdateThread()) { } @@ -335,7 +335,7 @@ AStringVector cMojangAPI::GetUUIDsFromPlayerNames(const AStringVector & a_Player void cMojangAPI::AddPlayerNameToUUIDMapping(const AString & a_PlayerName, const AString & a_UUID) { AString UUID = MakeUUIDShort(a_UUID); - Int64 Now = time(NULL); + Int64 Now = time(nullptr); { cCSLock Lock(m_CSNameToUUID); m_NameToUUID[StrToLower(a_PlayerName)] = sProfile(a_PlayerName, UUID, "", "", Now); @@ -354,7 +354,7 @@ void cMojangAPI::AddPlayerNameToUUIDMapping(const AString & a_PlayerName, const void cMojangAPI::AddPlayerProfile(const AString & a_PlayerName, const AString & a_UUID, const Json::Value & a_Properties) { AString UUID = MakeUUIDShort(a_UUID); - Int64 Now = time(NULL); + Int64 Now = time(nullptr); { cCSLock Lock(m_CSNameToUUID); m_NameToUUID[StrToLower(a_PlayerName)] = sProfile(a_PlayerName, UUID, "", "", Now); @@ -558,7 +558,7 @@ void cMojangAPI::SaveCachesToDisk(void) db.exec("DELETE FROM UUIDToProfile"); // Save all cache entries - m_PlayerNameToUUID: - Int64 LimitDateTime = time(NULL) - MAX_AGE; + Int64 LimitDateTime = time(nullptr) - MAX_AGE; { SQLite::Statement stmt(db, "INSERT INTO PlayerNameToUUID(PlayerName, UUID, DateTime) VALUES (?, ?, ?)"); cCSLock Lock(m_CSNameToUUID); @@ -697,7 +697,7 @@ void cMojangAPI::QueryNamesToUUIDs(AStringVector & a_NamesToQuery) // Store the returned results into cache: Json::Value::UInt JsonCount = root.size(); - Int64 Now = time(NULL); + Int64 Now = time(nullptr); { cCSLock Lock(m_CSNameToUUID); for (Json::Value::UInt idx = 0; idx < JsonCount; ++idx) @@ -831,7 +831,7 @@ void cMojangAPI::QueryUUIDToProfile(const AString & a_UUID) return; } Json::Value Properties = root.get("properties", ""); - Int64 Now = time(NULL); + Int64 Now = time(nullptr); { cCSLock Lock(m_CSUUIDToProfile); m_UUIDToProfile[a_UUID] = sProfile(PlayerName, a_UUID, Properties, Now); @@ -855,7 +855,7 @@ void cMojangAPI::NotifyNameUUID(const AString & a_PlayerName, const AString & a_ { // Notify the rank manager: cCSLock Lock(m_CSRankMgr); - if (m_RankMgr != NULL) + if (m_RankMgr != nullptr) { m_RankMgr->NotifyNameUUID(a_PlayerName, a_UUID); } @@ -867,7 +867,7 @@ void cMojangAPI::NotifyNameUUID(const AString & a_PlayerName, const AString & a_ void cMojangAPI::Update(void) { - Int64 LimitDateTime = time(NULL) - MAX_AGE; + Int64 LimitDateTime = time(nullptr) - MAX_AGE; // Re-query all playernames that are stale: AStringVector PlayerNames; diff --git a/src/Protocol/MojangAPI.h b/src/Protocol/MojangAPI.h index 393fd4baa..0dc2617b6 100644 --- a/src/Protocol/MojangAPI.h +++ b/src/Protocol/MojangAPI.h @@ -89,7 +89,7 @@ public: the profile to the respective mapping caches and updtes their datetime stamp to now. */ void AddPlayerProfile(const AString & a_PlayerName, const AString & a_UUID, const Json::Value & a_Properties); - /** Sets the m_RankMgr that is used for name-uuid notifications. Accepts NULL to remove the binding. */ + /** Sets the m_RankMgr that is used for name-uuid notifications. Accepts nullptr to remove the binding. */ void SetRankManager(cRankManager * a_RankManager) { m_RankMgr = a_RankManager; } protected: @@ -112,7 +112,7 @@ protected: m_UUID(), m_Textures(), m_TexturesSignature(), - m_DateTime(time(NULL)) + m_DateTime(time(nullptr)) { } @@ -176,7 +176,7 @@ protected: /** Protects m_UUIDToProfile against simultaneous multi-threaded access. */ cCriticalSection m_CSUUIDToProfile; - /** The rank manager that is notified of the name-uuid pairings. May be NULL. Protected by m_CSRankMgr. */ + /** The rank manager that is notified of the name-uuid pairings. May be nullptr. Protected by m_CSRankMgr. */ cRankManager * m_RankMgr; /** Protects m_RankMgr agains simultaneous multi-threaded access. */ diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 204691ede..3baf684e9 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -120,7 +120,7 @@ cProtocol172::cProtocol172(cClientHandle * a_Client, const AString & a_ServerAdd { static int sCounter = 0; cFile::CreateFolder("CommLogs"); - AString FileName = Printf("CommLogs/%x_%d__%s.log", (unsigned)time(NULL), sCounter++, a_Client->GetIPString().c_str()); + AString FileName = Printf("CommLogs/%x_%d__%s.log", (unsigned)time(nullptr), sCounter++, a_Client->GetIPString().c_str()); m_CommLogFile.Open(FileName, cFile::fmWrite); } } @@ -159,7 +159,7 @@ void cProtocol172::SendAttachEntity(const cEntity & a_Entity, const cEntity * a_ cPacketizer Pkt(*this, 0x1b); // Attach Entity packet Pkt.WriteInt(a_Entity.GetUniqueID()); - Pkt.WriteInt((a_Vehicle != NULL) ? a_Vehicle->GetUniqueID() : 0); + Pkt.WriteInt((a_Vehicle != nullptr) ? a_Vehicle->GetUniqueID() : 0); Pkt.WriteBool(false); } @@ -254,7 +254,7 @@ void cProtocol172::SendChat(const cCompositeChat & a_Message) ASSERT(m_State == 3); // In game mode? cWorld * World = m_Client->GetPlayer()->GetWorld(); - bool ShouldUseChatPrefixes = (World == NULL) ? false : World->ShouldUseChatPrefixes(); + bool ShouldUseChatPrefixes = (World == nullptr) ? false : World->ShouldUseChatPrefixes(); // Send the message to the client: cPacketizer Pkt(*this, 0x02); diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index c9118c239..0ca9927db 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -107,7 +107,7 @@ cProtocol180::cProtocol180(cClientHandle * a_Client, const AString & a_ServerAdd { static int sCounter = 0; cFile::CreateFolder("CommLogs"); - AString FileName = Printf("CommLogs/%x_%d__%s.log", (unsigned)time(NULL), sCounter++, a_Client->GetIPString().c_str()); + AString FileName = Printf("CommLogs/%x_%d__%s.log", (unsigned)time(nullptr), sCounter++, a_Client->GetIPString().c_str()); m_CommLogFile.Open(FileName, cFile::fmWrite); } } @@ -146,7 +146,7 @@ void cProtocol180::SendAttachEntity(const cEntity & a_Entity, const cEntity * a_ cPacketizer Pkt(*this, 0x1b); // Attach Entity packet Pkt.WriteInt(a_Entity.GetUniqueID()); - Pkt.WriteInt((a_Vehicle != NULL) ? a_Vehicle->GetUniqueID() : 0); + Pkt.WriteInt((a_Vehicle != nullptr) ? a_Vehicle->GetUniqueID() : 0); Pkt.WriteBool(false); } @@ -234,7 +234,7 @@ void cProtocol180::SendChat(const cCompositeChat & a_Message) ASSERT(m_State == 3); // In game mode? cWorld * World = m_Client->GetPlayer()->GetWorld(); - bool ShouldUseChatPrefixes = (World == NULL) ? false : World->ShouldUseChatPrefixes(); + bool ShouldUseChatPrefixes = (World == nullptr) ? false : World->ShouldUseChatPrefixes(); // Send the message to the client: cPacketizer Pkt(*this, 0x02); diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index 0c1e83b67..af9e0d1bc 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -22,7 +22,7 @@ cProtocolRecognizer::cProtocolRecognizer(cClientHandle * a_Client) : super(a_Client), - m_Protocol(NULL), + m_Protocol(nullptr), m_Buffer(8192) // We need a larger buffer to support BungeeCord - it sends one huge packet at the start { } @@ -34,7 +34,7 @@ cProtocolRecognizer::cProtocolRecognizer(cClientHandle * a_Client) : cProtocolRecognizer::~cProtocolRecognizer() { delete m_Protocol; - m_Protocol = NULL; + m_Protocol = nullptr; } @@ -59,7 +59,7 @@ AString cProtocolRecognizer::GetVersionTextFromInt(int a_ProtocolVersion) void cProtocolRecognizer::DataReceived(const char * a_Data, size_t a_Size) { - if (m_Protocol == NULL) + if (m_Protocol == nullptr) { if (!m_Buffer.Write(a_Data, a_Size)) { @@ -90,7 +90,7 @@ void cProtocolRecognizer::DataReceived(const char * a_Data, size_t a_Size) void cProtocolRecognizer::SendAttachEntity(const cEntity & a_Entity, const cEntity * a_Vehicle) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendAttachEntity(a_Entity, a_Vehicle); } @@ -100,7 +100,7 @@ void cProtocolRecognizer::SendAttachEntity(const cEntity & a_Entity, const cEnti void cProtocolRecognizer::SendBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendBlockAction(a_BlockX, a_BlockY, a_BlockZ, a_Byte1, a_Byte2, a_BlockType); } @@ -110,7 +110,7 @@ void cProtocolRecognizer::SendBlockAction(int a_BlockX, int a_BlockY, int a_Bloc void cProtocolRecognizer::SendBlockBreakAnim(int a_entityID, int a_BlockX, int a_BlockY, int a_BlockZ, char stage) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendBlockBreakAnim(a_entityID, a_BlockX, a_BlockY, a_BlockZ, stage); } @@ -120,7 +120,7 @@ void cProtocolRecognizer::SendBlockBreakAnim(int a_entityID, int a_BlockX, int a void cProtocolRecognizer::SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendBlockChange(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); } @@ -130,7 +130,7 @@ void cProtocolRecognizer::SendBlockChange(int a_BlockX, int a_BlockY, int a_Bloc void cProtocolRecognizer::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendBlockChanges(a_ChunkX, a_ChunkZ, a_Changes); } @@ -140,7 +140,7 @@ void cProtocolRecognizer::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSe void cProtocolRecognizer::SendChat(const AString & a_Message) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendChat(a_Message); } @@ -150,7 +150,7 @@ void cProtocolRecognizer::SendChat(const AString & a_Message) void cProtocolRecognizer::SendChat(const cCompositeChat & a_Message) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendChat(a_Message); } @@ -160,7 +160,7 @@ void cProtocolRecognizer::SendChat(const cCompositeChat & a_Message) void cProtocolRecognizer::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendChunkData(a_ChunkX, a_ChunkZ, a_Serializer); } @@ -170,7 +170,7 @@ void cProtocolRecognizer::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSe void cProtocolRecognizer::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendCollectEntity(a_Entity, a_Player); } @@ -180,7 +180,7 @@ void cProtocolRecognizer::SendCollectEntity(const cEntity & a_Entity, const cPla void cProtocolRecognizer::SendDestroyEntity(const cEntity & a_Entity) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendDestroyEntity(a_Entity); } @@ -190,7 +190,7 @@ void cProtocolRecognizer::SendDestroyEntity(const cEntity & a_Entity) void cProtocolRecognizer::SendDisconnect(const AString & a_Reason) { - if (m_Protocol != NULL) + if (m_Protocol != nullptr) { m_Protocol->SendDisconnect(a_Reason); } @@ -212,7 +212,7 @@ void cProtocolRecognizer::SendDisconnect(const AString & a_Reason) void cProtocolRecognizer::SendEditSign(int a_BlockX, int a_BlockY, int a_BlockZ) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendEditSign(a_BlockX, a_BlockY, a_BlockZ); } @@ -222,7 +222,7 @@ void cProtocolRecognizer::SendEditSign(int a_BlockX, int a_BlockY, int a_BlockZ) void cProtocolRecognizer::SendEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendEntityEffect(a_Entity, a_EffectID, a_Amplifier, a_Duration); } @@ -232,7 +232,7 @@ void cProtocolRecognizer::SendEntityEffect(const cEntity & a_Entity, int a_Effec void cProtocolRecognizer::SendEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendEntityEquipment(a_Entity, a_SlotNum, a_Item); } @@ -242,7 +242,7 @@ void cProtocolRecognizer::SendEntityEquipment(const cEntity & a_Entity, short a_ void cProtocolRecognizer::SendEntityHeadLook(const cEntity & a_Entity) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendEntityHeadLook(a_Entity); } @@ -252,7 +252,7 @@ void cProtocolRecognizer::SendEntityHeadLook(const cEntity & a_Entity) void cProtocolRecognizer::SendEntityLook(const cEntity & a_Entity) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendEntityLook(a_Entity); } @@ -262,7 +262,7 @@ void cProtocolRecognizer::SendEntityLook(const cEntity & a_Entity) void cProtocolRecognizer::SendEntityMetadata(const cEntity & a_Entity) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendEntityMetadata(a_Entity); } @@ -272,7 +272,7 @@ void cProtocolRecognizer::SendEntityMetadata(const cEntity & a_Entity) void cProtocolRecognizer::SendEntityProperties(const cEntity & a_Entity) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendEntityProperties(a_Entity); } @@ -282,7 +282,7 @@ void cProtocolRecognizer::SendEntityProperties(const cEntity & a_Entity) void cProtocolRecognizer::SendEntityRelMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendEntityRelMove(a_Entity, a_RelX, a_RelY, a_RelZ); } @@ -292,7 +292,7 @@ void cProtocolRecognizer::SendEntityRelMove(const cEntity & a_Entity, char a_Rel void cProtocolRecognizer::SendEntityRelMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendEntityRelMoveLook(a_Entity, a_RelX, a_RelY, a_RelZ); } @@ -302,7 +302,7 @@ void cProtocolRecognizer::SendEntityRelMoveLook(const cEntity & a_Entity, char a void cProtocolRecognizer::SendEntityStatus(const cEntity & a_Entity, char a_Status) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendEntityStatus(a_Entity, a_Status); } @@ -312,7 +312,7 @@ void cProtocolRecognizer::SendEntityStatus(const cEntity & a_Entity, char a_Stat void cProtocolRecognizer::SendEntityVelocity(const cEntity & a_Entity) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendEntityVelocity(a_Entity); } @@ -322,7 +322,7 @@ void cProtocolRecognizer::SendEntityVelocity(const cEntity & a_Entity) void cProtocolRecognizer::SendExplosion(double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, const cVector3iArray & a_BlocksAffected, const Vector3d & a_PlayerMotion) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendExplosion(a_BlockX, a_BlockY, a_BlockZ, a_Radius, a_BlocksAffected, a_PlayerMotion); } @@ -332,7 +332,7 @@ void cProtocolRecognizer::SendExplosion(double a_BlockX, double a_BlockY, double void cProtocolRecognizer::SendGameMode(eGameMode a_GameMode) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendGameMode(a_GameMode); } @@ -342,7 +342,7 @@ void cProtocolRecognizer::SendGameMode(eGameMode a_GameMode) void cProtocolRecognizer::SendHealth(void) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendHealth(); } @@ -352,7 +352,7 @@ void cProtocolRecognizer::SendHealth(void) void cProtocolRecognizer::SendWindowProperty(const cWindow & a_Window, short a_Property, short a_Value) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendWindowProperty(a_Window, a_Property, a_Value); } @@ -362,7 +362,7 @@ void cProtocolRecognizer::SendWindowProperty(const cWindow & a_Window, short a_P void cProtocolRecognizer::SendInventorySlot(char a_WindowID, short a_SlotNum, const cItem & a_Item) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendInventorySlot(a_WindowID, a_SlotNum, a_Item); } @@ -372,7 +372,7 @@ void cProtocolRecognizer::SendInventorySlot(char a_WindowID, short a_SlotNum, co void cProtocolRecognizer::SendKeepAlive(int a_PingID) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendKeepAlive(a_PingID); } @@ -382,7 +382,7 @@ void cProtocolRecognizer::SendKeepAlive(int a_PingID) void cProtocolRecognizer::SendLogin(const cPlayer & a_Player, const cWorld & a_World) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendLogin(a_Player, a_World); } @@ -392,7 +392,7 @@ void cProtocolRecognizer::SendLogin(const cPlayer & a_Player, const cWorld & a_W void cProtocolRecognizer::SendLoginSuccess(void) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendLoginSuccess(); } @@ -402,7 +402,7 @@ void cProtocolRecognizer::SendLoginSuccess(void) void cProtocolRecognizer::SendMapColumn(int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length, unsigned int m_Scale) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendMapColumn(a_ID, a_X, a_Y, a_Colors, a_Length, m_Scale); } @@ -412,7 +412,7 @@ void cProtocolRecognizer::SendMapColumn(int a_ID, int a_X, int a_Y, const Byte * void cProtocolRecognizer::SendMapDecorators(int a_ID, const cMapDecoratorList & a_Decorators, unsigned int m_Scale) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendMapDecorators(a_ID, a_Decorators, m_Scale); } @@ -422,7 +422,7 @@ void cProtocolRecognizer::SendMapDecorators(int a_ID, const cMapDecoratorList & void cProtocolRecognizer::SendMapInfo(int a_ID, unsigned int a_Scale) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendMapInfo(a_ID, a_Scale); } @@ -432,7 +432,7 @@ void cProtocolRecognizer::SendMapInfo(int a_ID, unsigned int a_Scale) void cProtocolRecognizer::SendParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendParticleEffect(a_ParticleName, a_SrcX, a_SrcY, a_SrcZ, a_OffsetX, a_OffsetY, a_OffsetZ, a_ParticleData, a_ParticleAmount); } @@ -450,7 +450,7 @@ void cProtocolRecognizer::SendPaintingSpawn(const cPainting & a_Painting) void cProtocolRecognizer::SendPickupSpawn(const cPickup & a_Pickup) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendPickupSpawn(a_Pickup); } @@ -460,7 +460,7 @@ void cProtocolRecognizer::SendPickupSpawn(const cPickup & a_Pickup) void cProtocolRecognizer::SendPlayerAbilities(void) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendPlayerAbilities(); } @@ -470,7 +470,7 @@ void cProtocolRecognizer::SendPlayerAbilities(void) void cProtocolRecognizer::SendEntityAnimation(const cEntity & a_Entity, char a_Animation) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendEntityAnimation(a_Entity, a_Animation); } @@ -480,7 +480,7 @@ void cProtocolRecognizer::SendEntityAnimation(const cEntity & a_Entity, char a_A void cProtocolRecognizer::SendPlayerListAddPlayer(const cPlayer & a_Player) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendPlayerListAddPlayer(a_Player); } @@ -490,7 +490,7 @@ void cProtocolRecognizer::SendPlayerListAddPlayer(const cPlayer & a_Player) void cProtocolRecognizer::SendPlayerListRemovePlayer(const cPlayer & a_Player) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendPlayerListRemovePlayer(a_Player); } @@ -500,7 +500,7 @@ void cProtocolRecognizer::SendPlayerListRemovePlayer(const cPlayer & a_Player) void cProtocolRecognizer::SendPlayerListUpdateGameMode(const cPlayer & a_Player) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendPlayerListUpdateGameMode(a_Player); } @@ -510,7 +510,7 @@ void cProtocolRecognizer::SendPlayerListUpdateGameMode(const cPlayer & a_Player) void cProtocolRecognizer::SendPlayerListUpdatePing(const cPlayer & a_Player) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendPlayerListUpdatePing(a_Player); } @@ -520,7 +520,7 @@ void cProtocolRecognizer::SendPlayerListUpdatePing(const cPlayer & a_Player) void cProtocolRecognizer::SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendPlayerListUpdateDisplayName(a_Player, a_CustomName); } @@ -530,7 +530,7 @@ void cProtocolRecognizer::SendPlayerListUpdateDisplayName(const cPlayer & a_Play void cProtocolRecognizer::SendPlayerMaxSpeed(void) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendPlayerMaxSpeed(); } @@ -540,7 +540,7 @@ void cProtocolRecognizer::SendPlayerMaxSpeed(void) void cProtocolRecognizer::SendPlayerMoveLook(void) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendPlayerMoveLook(); } @@ -550,7 +550,7 @@ void cProtocolRecognizer::SendPlayerMoveLook(void) void cProtocolRecognizer::SendPlayerPosition(void) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendPlayerPosition(); } @@ -560,7 +560,7 @@ void cProtocolRecognizer::SendPlayerPosition(void) void cProtocolRecognizer::SendPlayerSpawn(const cPlayer & a_Player) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendPlayerSpawn(a_Player); } @@ -570,7 +570,7 @@ void cProtocolRecognizer::SendPlayerSpawn(const cPlayer & a_Player) void cProtocolRecognizer::SendPluginMessage(const AString & a_Channel, const AString & a_Message) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendPluginMessage(a_Channel, a_Message); } @@ -580,7 +580,7 @@ void cProtocolRecognizer::SendPluginMessage(const AString & a_Channel, const ASt void cProtocolRecognizer::SendRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendRemoveEntityEffect(a_Entity, a_EffectID); } @@ -590,7 +590,7 @@ void cProtocolRecognizer::SendRemoveEntityEffect(const cEntity & a_Entity, int a void cProtocolRecognizer::SendRespawn(eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendRespawn(a_Dimension, a_ShouldIgnoreDimensionChecks); } @@ -600,7 +600,7 @@ void cProtocolRecognizer::SendRespawn(eDimension a_Dimension, bool a_ShouldIgnor void cProtocolRecognizer::SendExperience(void) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendExperience(); } @@ -610,7 +610,7 @@ void cProtocolRecognizer::SendExperience(void) void cProtocolRecognizer::SendExperienceOrb(const cExpOrb & a_ExpOrb) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendExperienceOrb(a_ExpOrb); } @@ -620,7 +620,7 @@ void cProtocolRecognizer::SendExperienceOrb(const cExpOrb & a_ExpOrb) void cProtocolRecognizer::SendScoreboardObjective(const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendScoreboardObjective(a_Name, a_DisplayName, a_Mode); } @@ -630,7 +630,7 @@ void cProtocolRecognizer::SendScoreboardObjective(const AString & a_Name, const void cProtocolRecognizer::SendScoreUpdate(const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendScoreUpdate(a_Objective, a_Player, a_Score, a_Mode); } @@ -640,7 +640,7 @@ void cProtocolRecognizer::SendScoreUpdate(const AString & a_Objective, const ASt void cProtocolRecognizer::SendDisplayObjective(const AString & a_Objective, cScoreboard::eDisplaySlot a_Display) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendDisplayObjective(a_Objective, a_Display); } @@ -650,7 +650,7 @@ void cProtocolRecognizer::SendDisplayObjective(const AString & a_Objective, cSco void cProtocolRecognizer::SendSoundEffect(const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendSoundEffect(a_SoundName, a_X, a_Y, a_Z, a_Volume, a_Pitch); } @@ -660,7 +660,7 @@ void cProtocolRecognizer::SendSoundEffect(const AString & a_SoundName, double a_ void cProtocolRecognizer::SendSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendSoundParticleEffect(a_EffectID, a_SrcX, a_SrcY, a_SrcZ, a_Data); } @@ -670,7 +670,7 @@ void cProtocolRecognizer::SendSoundParticleEffect(int a_EffectID, int a_SrcX, in void cProtocolRecognizer::SendSpawnFallingBlock(const cFallingBlock & a_FallingBlock) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendSpawnFallingBlock(a_FallingBlock); } @@ -680,7 +680,7 @@ void cProtocolRecognizer::SendSpawnFallingBlock(const cFallingBlock & a_FallingB void cProtocolRecognizer::SendSpawnMob(const cMonster & a_Mob) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendSpawnMob(a_Mob); } @@ -690,7 +690,7 @@ void cProtocolRecognizer::SendSpawnMob(const cMonster & a_Mob) void cProtocolRecognizer::SendSpawnObject(const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, Byte a_Yaw, Byte a_Pitch) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendSpawnObject(a_Entity, a_ObjectType, a_ObjectData, a_Yaw, a_Pitch); } @@ -700,7 +700,7 @@ void cProtocolRecognizer::SendSpawnObject(const cEntity & a_Entity, char a_Objec void cProtocolRecognizer::SendSpawnVehicle(const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendSpawnVehicle(a_Vehicle, a_VehicleType, a_VehicleSubType); } @@ -710,7 +710,7 @@ void cProtocolRecognizer::SendSpawnVehicle(const cEntity & a_Vehicle, char a_Veh void cProtocolRecognizer::SendStatistics(const cStatManager & a_Manager) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendStatistics(a_Manager); } @@ -720,7 +720,7 @@ void cProtocolRecognizer::SendStatistics(const cStatManager & a_Manager) void cProtocolRecognizer::SendTabCompletionResults(const AStringVector & a_Results) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendTabCompletionResults(a_Results); } @@ -730,7 +730,7 @@ void cProtocolRecognizer::SendTabCompletionResults(const AStringVector & a_Resul void cProtocolRecognizer::SendTeleportEntity(const cEntity & a_Entity) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendTeleportEntity(a_Entity); } @@ -740,7 +740,7 @@ void cProtocolRecognizer::SendTeleportEntity(const cEntity & a_Entity) void cProtocolRecognizer::SendThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendThunderbolt(a_BlockX, a_BlockY, a_BlockZ); } @@ -750,7 +750,7 @@ void cProtocolRecognizer::SendThunderbolt(int a_BlockX, int a_BlockY, int a_Bloc void cProtocolRecognizer::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendTimeUpdate(a_WorldAge, a_TimeOfDay, a_DoDaylightCycle); } @@ -760,7 +760,7 @@ void cProtocolRecognizer::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bo void cProtocolRecognizer::SendUnloadChunk(int a_ChunkX, int a_ChunkZ) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendUnloadChunk(a_ChunkX, a_ChunkZ); } @@ -770,7 +770,7 @@ void cProtocolRecognizer::SendUnloadChunk(int a_ChunkX, int a_ChunkZ) void cProtocolRecognizer::SendUpdateBlockEntity(cBlockEntity & a_BlockEntity) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendUpdateBlockEntity(a_BlockEntity); } @@ -780,7 +780,7 @@ void cProtocolRecognizer::SendUpdateBlockEntity(cBlockEntity & a_BlockEntity) void cProtocolRecognizer::SendUpdateSign(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendUpdateSign(a_BlockX, a_BlockY, a_BlockZ, a_Line1, a_Line2, a_Line3, a_Line4); } @@ -790,7 +790,7 @@ void cProtocolRecognizer::SendUpdateSign(int a_BlockX, int a_BlockY, int a_Block void cProtocolRecognizer::SendUseBed(const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendUseBed(a_Entity, a_BlockX, a_BlockY, a_BlockZ); } @@ -800,7 +800,7 @@ void cProtocolRecognizer::SendUseBed(const cEntity & a_Entity, int a_BlockX, int void cProtocolRecognizer::SendWeather(eWeather a_Weather) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendWeather(a_Weather); } @@ -810,7 +810,7 @@ void cProtocolRecognizer::SendWeather(eWeather a_Weather) void cProtocolRecognizer::SendWholeInventory(const cWindow & a_Window) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendWholeInventory(a_Window); } @@ -820,7 +820,7 @@ void cProtocolRecognizer::SendWholeInventory(const cWindow & a_Window) void cProtocolRecognizer::SendWindowClose(const cWindow & a_Window) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendWindowClose(a_Window); } @@ -830,7 +830,7 @@ void cProtocolRecognizer::SendWindowClose(const cWindow & a_Window) void cProtocolRecognizer::SendWindowOpen(const cWindow & a_Window) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); m_Protocol->SendWindowOpen(a_Window); } @@ -840,7 +840,7 @@ void cProtocolRecognizer::SendWindowOpen(const cWindow & a_Window) AString cProtocolRecognizer::GetAuthServerID(void) { - ASSERT(m_Protocol != NULL); + ASSERT(m_Protocol != nullptr); return m_Protocol->GetAuthServerID(); } diff --git a/src/RCONServer.cpp b/src/RCONServer.cpp index 141c67d1b..df027c91f 100644 --- a/src/RCONServer.cpp +++ b/src/RCONServer.cpp @@ -242,7 +242,7 @@ bool cRCONServer::cConnection::ProcessPacket(int a_RequestID, int a_PacketType, if (strncmp(a_Payload, m_RCONServer.m_Password.c_str(), a_PayloadLength) != 0) { LOGINFO("RCON: Invalid password from client %s, dropping connection.", m_IPAddress.c_str()); - SendResponse(-1, RCON_PACKET_RESPONSE, 0, NULL); + SendResponse(-1, RCON_PACKET_RESPONSE, 0, nullptr); return false; } m_IsAuthenticated = true; @@ -250,7 +250,7 @@ bool cRCONServer::cConnection::ProcessPacket(int a_RequestID, int a_PacketType, LOGD("RCON: Client at %s has successfully authenticated", m_IPAddress.c_str()); // Send OK response: - SendResponse(a_RequestID, RCON_PACKET_RESPONSE, 0, NULL); + SendResponse(a_RequestID, RCON_PACKET_RESPONSE, 0, nullptr); return true; } @@ -268,7 +268,7 @@ bool cRCONServer::cConnection::ProcessPacket(int a_RequestID, int a_PacketType, cRoot::Get()->ExecuteConsoleCommand(cmd, *(new cRCONCommandOutput(*this, a_RequestID))); // Send an empty response: - SendResponse(a_RequestID, RCON_PACKET_RESPONSE, 0, NULL); + SendResponse(a_RequestID, RCON_PACKET_RESPONSE, 0, nullptr); return true; } } @@ -310,7 +310,7 @@ void cRCONServer::cConnection::IntToBuffer(int a_Value, char * a_Buffer) /// Sends a RCON packet back to the client void cRCONServer::cConnection::SendResponse(int a_RequestID, int a_PacketType, int a_PayloadLength, const char * a_Payload) { - ASSERT((a_PayloadLength == 0) || (a_Payload != NULL)); // Either zero data to send, or a valid payload ptr + ASSERT((a_PayloadLength == 0) || (a_Payload != nullptr)); // Either zero data to send, or a valid payload ptr char Buffer[4]; int Length = a_PayloadLength + 10; diff --git a/src/RankManager.cpp b/src/RankManager.cpp index f5342ed3d..3778f5d64 100644 --- a/src/RankManager.cpp +++ b/src/RankManager.cpp @@ -384,7 +384,7 @@ protected: cRankManager::cRankManager(void) : m_DB("Ranks.sqlite", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE), m_IsInitialized(false), - m_MojangAPI(NULL) + m_MojangAPI(nullptr) { } @@ -394,9 +394,9 @@ cRankManager::cRankManager(void) : cRankManager::~cRankManager() { - if (m_MojangAPI != NULL) + if (m_MojangAPI != nullptr) { - m_MojangAPI->SetRankManager(NULL); + m_MojangAPI->SetRankManager(nullptr); } } diff --git a/src/RankManager.h b/src/RankManager.h index 61c52fda6..5dff634b5 100644 --- a/src/RankManager.h +++ b/src/RankManager.h @@ -240,7 +240,7 @@ protected: bool m_IsInitialized; /** The MojangAPI instance that is used for translating playernames to UUIDs. - Set in Initialize(), may be NULL. */ + Set in Initialize(), may be nullptr. */ cMojangAPI * m_MojangAPI; diff --git a/src/Root.cpp b/src/Root.cpp index 1271e8648..c951cb891 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -34,20 +34,20 @@ -cRoot* cRoot::s_Root = NULL; +cRoot* cRoot::s_Root = nullptr; cRoot::cRoot(void) : - m_pDefaultWorld(NULL), - m_Server(NULL), - m_MonsterConfig(NULL), - m_CraftingRecipes(NULL), - m_FurnaceRecipe(NULL), - m_WebAdmin(NULL), - m_PluginManager(NULL), + m_pDefaultWorld(nullptr), + m_Server(nullptr), + m_MonsterConfig(nullptr), + m_CraftingRecipes(nullptr), + m_FurnaceRecipe(nullptr), + m_WebAdmin(nullptr), + m_PluginManager(nullptr), m_bStop(false), m_bRestart(false) { @@ -224,21 +224,21 @@ void cRoot::Start(void) m_Authenticator.Stop(); LOGD("Freeing MonsterConfig..."); - delete m_MonsterConfig; m_MonsterConfig = NULL; - delete m_WebAdmin; m_WebAdmin = NULL; + delete m_MonsterConfig; m_MonsterConfig = nullptr; + delete m_WebAdmin; m_WebAdmin = nullptr; LOGD("Unloading recipes..."); - delete m_FurnaceRecipe; m_FurnaceRecipe = NULL; - delete m_CraftingRecipes; m_CraftingRecipes = NULL; + delete m_FurnaceRecipe; m_FurnaceRecipe = nullptr; + delete m_CraftingRecipes; m_CraftingRecipes = nullptr; LOGD("Unloading worlds..."); UnloadWorlds(); LOGD("Stopping plugin manager..."); - delete m_PluginManager; m_PluginManager = NULL; + delete m_PluginManager; m_PluginManager = nullptr; cItemHandler::Deinit(); LOG("Cleaning up..."); - delete m_Server; m_Server = NULL; + delete m_Server; m_Server = nullptr; LOG("Shutdown successful!"); } @@ -313,7 +313,7 @@ void cRoot::LoadWorlds(cIniFile & IniFile) cWorld * cRoot::CreateAndInitializeWorld(const AString & a_WorldName, eDimension a_Dimension, const AString & a_OverworldName) { cWorld * World = m_WorldsByName[a_WorldName]; - if (World != NULL) + if (World != nullptr) { return World; } @@ -358,7 +358,7 @@ void cRoot::StopWorlds(void) void cRoot::UnloadWorlds(void) { - m_pDefaultWorld = NULL; + m_pDefaultWorld = nullptr; for (WorldMap::iterator itr = m_WorldsByName.begin(); itr != m_WorldsByName.end(); ++itr) { delete itr->second; @@ -391,7 +391,7 @@ cWorld * cRoot::GetWorld(const AString & a_WorldName, bool a_SearchForFolder) { return CreateAndInitializeWorld(a_WorldName); } - return NULL; + return nullptr; } @@ -403,7 +403,7 @@ bool cRoot::ForEachWorld(cWorldListCallback & a_Callback) for (WorldMap::iterator itr = m_WorldsByName.begin(), itr2 = itr; itr != m_WorldsByName.end(); itr = itr2) { ++itr2; - if (itr->second != NULL) + if (itr->second != nullptr) { if (a_Callback.Item(itr->second)) { @@ -538,7 +538,7 @@ void cRoot::BroadcastChat(const AString & a_Message, eMessageType a_ChatPrefix) { for (WorldMap::iterator itr = m_WorldsByName.begin(), end = m_WorldsByName.end(); itr != end; ++itr) { - itr->second->BroadcastChat(a_Message, NULL, a_ChatPrefix); + itr->second->BroadcastChat(a_Message, nullptr, a_ChatPrefix); } // for itr - m_WorldsByName[] } @@ -608,7 +608,7 @@ bool cRoot::FindAndDoWithPlayer(const AString & a_PlayerName, cPlayerListCallbac m_BestRating(0), m_NameLength(a_PlayerName.length()), m_PlayerName(a_PlayerName), - m_BestMatch(NULL), + m_BestMatch(nullptr), m_NumMatches(0) {} diff --git a/src/Scoreboard.cpp b/src/Scoreboard.cpp index def952029..adce8b549 100644 --- a/src/Scoreboard.cpp +++ b/src/Scoreboard.cpp @@ -278,7 +278,7 @@ cScoreboard::cScoreboard(cWorld * a_World) : m_World(a_World) { for (int i = 0; i < (int) dsCount; ++i) { - m_Display[i] = NULL; + m_Display[i] = nullptr; } } @@ -294,14 +294,14 @@ cObjective* cScoreboard::RegisterObjective(const AString & a_Name, const AString if (Status.second) { - ASSERT(m_World != NULL); + ASSERT(m_World != nullptr); m_World->BroadcastScoreboardObjective(a_Name, a_DisplayName, 0); return &Status.first->second; } else { - return NULL; + return nullptr; } } @@ -320,14 +320,14 @@ bool cScoreboard::RemoveObjective(const AString & a_Name) return false; } - ASSERT(m_World != NULL); + ASSERT(m_World != nullptr); m_World->BroadcastScoreboardObjective(it->second.GetName(), it->second.GetDisplayName(), 1); for (unsigned int i = 0; i < (unsigned int) dsCount; ++i) { if (m_Display[i] == &it->second) { - SetDisplay(NULL, (eDisplaySlot) i); + SetDisplay(nullptr, (eDisplaySlot) i); } } @@ -348,7 +348,7 @@ cObjective * cScoreboard::GetObjective(const AString & a_Name) if (it == m_Objectives.end()) { - return NULL; + return nullptr; } else { @@ -369,7 +369,7 @@ cTeam * cScoreboard::RegisterTeam( std::pair Status = m_Teams.insert(cNamedTeam(a_Name, Team)); - return Status.second ? &Status.first->second : NULL; + return Status.second ? &Status.first->second : nullptr; } @@ -404,7 +404,7 @@ cTeam * cScoreboard::GetTeam(const AString & a_Name) if (it == m_Teams.end()) { - return NULL; + return nullptr; } else { @@ -428,7 +428,7 @@ cTeam * cScoreboard::QueryPlayerTeam(const AString & a_Name) } } - return NULL; + return nullptr; } @@ -452,7 +452,7 @@ void cScoreboard::SetDisplay(cObjective * a_Objective, eDisplaySlot a_Slot) { m_Display[a_Slot] = a_Objective; - ASSERT(m_World != NULL); + ASSERT(m_World != nullptr); m_World->BroadcastDisplayObjective(a_Objective ? a_Objective->GetName() : "", a_Slot); } diff --git a/src/Scoreboard.h b/src/Scoreboard.h index f53b8c803..dd4073c89 100644 --- a/src/Scoreboard.h +++ b/src/Scoreboard.h @@ -226,22 +226,22 @@ public: // tolua_begin - /** Registers a new scoreboard objective, returns the cObjective instance, NULL on name collision */ + /** Registers a new scoreboard objective, returns the cObjective instance, nullptr on name collision */ cObjective * RegisterObjective(const AString & a_Name, const AString & a_DisplayName, cObjective::eType a_Type); /** Removes a registered objective, returns true if operation was successful */ bool RemoveObjective(const AString & a_Name); - /** Retrieves the objective with the specified name, NULL if not found */ + /** Retrieves the objective with the specified name, nullptr if not found */ cObjective * GetObjective(const AString & a_Name); - /** Registers a new team, returns the cTeam instance, NULL on name collision */ + /** Registers a new team, returns the cTeam instance, nullptr on name collision */ cTeam * RegisterTeam(const AString & a_Name, const AString & a_DisplayName, const AString & a_Prefix, const AString & a_Suffix); /** Removes a registered team, returns true if operation was successful */ bool RemoveTeam(const AString & a_Name); - /** Retrieves the team with the specified name, NULL if not found */ + /** Retrieves the team with the specified name, nullptr if not found */ cTeam * GetTeam(const AString & a_Name); void SetDisplay(const AString & a_Objective, eDisplaySlot a_Slot); diff --git a/src/Server.cpp b/src/Server.cpp index 38e5cebb3..11da36868 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -332,7 +332,7 @@ void cServer::OnConnectionAccepted(cSocket & a_Socket) LOGERROR("Client \"%s\" cannot be handled, server probably unstable", ClientIP.c_str()); a_Socket.CloseSocket(); delete NewHandle; - NewHandle = NULL; + NewHandle = nullptr; return; } @@ -631,17 +631,17 @@ void cServer::PrintHelp(const AStringVector & a_Split, cCommandOutputCallback & void cServer::BindBuiltInConsoleCommands(void) { cPluginManager * PlgMgr = cPluginManager::Get(); - PlgMgr->BindConsoleCommand("help", NULL, " - Shows the available commands"); - PlgMgr->BindConsoleCommand("reload", NULL, " - Reloads all plugins"); - PlgMgr->BindConsoleCommand("restart", NULL, " - Restarts the server cleanly"); - PlgMgr->BindConsoleCommand("stop", NULL, " - Stops the server cleanly"); - PlgMgr->BindConsoleCommand("chunkstats", NULL, " - Displays detailed chunk memory statistics"); - PlgMgr->BindConsoleCommand("load ", NULL, " - Adds and enables the specified plugin"); - PlgMgr->BindConsoleCommand("unload ", NULL, " - Disables the specified plugin"); - PlgMgr->BindConsoleCommand("destroyentities", NULL, " - Destroys all entities in all worlds"); + PlgMgr->BindConsoleCommand("help", nullptr, " - Shows the available commands"); + PlgMgr->BindConsoleCommand("reload", nullptr, " - Reloads all plugins"); + PlgMgr->BindConsoleCommand("restart", nullptr, " - Restarts the server cleanly"); + PlgMgr->BindConsoleCommand("stop", nullptr, " - Stops the server cleanly"); + PlgMgr->BindConsoleCommand("chunkstats", nullptr, " - Displays detailed chunk memory statistics"); + PlgMgr->BindConsoleCommand("load ", nullptr, " - Adds and enables the specified plugin"); + PlgMgr->BindConsoleCommand("unload ", nullptr, " - Disables the specified plugin"); + PlgMgr->BindConsoleCommand("destroyentities", nullptr, " - Destroys all entities in all worlds"); #if defined(_MSC_VER) && defined(_DEBUG) && defined(ENABLE_LEAK_FINDER) - PlgMgr->BindConsoleCommand("dumpmem", NULL, " - Dumps all used memory blocks together with their callstacks into memdump.xml"); + PlgMgr->BindConsoleCommand("dumpmem", nullptr, " - Dumps all used memory blocks together with their callstacks into memdump.xml"); #endif } @@ -710,7 +710,7 @@ void cServer::AuthenticateUser(int a_ClientID, const AString & a_Name, const ASt cServer::cNotifyWriteThread::cNotifyWriteThread(void) : super("ClientPacketThread"), - m_Server(NULL) + m_Server(nullptr) { } diff --git a/src/SetChunkData.cpp b/src/SetChunkData.cpp index 707dfb9e8..e335176a8 100644 --- a/src/SetChunkData.cpp +++ b/src/SetChunkData.cpp @@ -42,15 +42,15 @@ cSetChunkData::cSetChunkData( m_ShouldMarkDirty(a_ShouldMarkDirty) { // Check the params' validity: - ASSERT(a_BlockTypes != NULL); - ASSERT(a_BlockMetas != NULL); + ASSERT(a_BlockTypes != nullptr); + ASSERT(a_BlockMetas != nullptr); // Copy block types and metas: memcpy(m_BlockTypes, a_BlockTypes, sizeof(cChunkDef::BlockTypes)); memcpy(m_BlockMetas, a_BlockMetas, sizeof(cChunkDef::BlockNibbles)); // Copy lights, if both given: - if ((a_BlockLight != NULL) && (a_SkyLight != NULL)) + if ((a_BlockLight != nullptr) && (a_SkyLight != nullptr)) { memcpy(m_BlockLight, a_BlockLight, sizeof(m_BlockLight)); memcpy(m_SkyLight, a_SkyLight, sizeof(m_SkyLight)); @@ -62,7 +62,7 @@ cSetChunkData::cSetChunkData( } // Copy the heightmap, if available: - if (a_HeightMap != NULL) + if (a_HeightMap != nullptr) { memcpy(m_HeightMap, a_HeightMap, sizeof(m_HeightMap)); m_IsHeightMapValid = true; @@ -73,7 +73,7 @@ cSetChunkData::cSetChunkData( } // Copy biomes, if available: - if (a_Biomes != NULL) + if (a_Biomes != nullptr) { memcpy(m_Biomes, a_Biomes, sizeof(m_Biomes)); m_AreBiomesValid = true; diff --git a/src/SetChunkData.h b/src/SetChunkData.h index 03e9ef4d9..1eeb75ca9 100644 --- a/src/SetChunkData.h +++ b/src/SetChunkData.h @@ -27,7 +27,7 @@ public: Will move the entity and blockentity lists into the internal storage, and empty the a_Entities and a_BlockEntities lists. a_BlockTypes and a_BlockMetas must always be valid. - If either of the light arrays are NULL, the chunk data will be marked as not having any light at all and + If either of the light arrays are nullptr, the chunk data will be marked as not having any light at all and will be scheduled for re-lighting once it is set into the chunkmap. If a_Biomes is not valid, the internal flag is set and the world will calculate the biomes using the chunk generator when setting the chunk data. diff --git a/src/Simulator/DelayedFluidSimulator.cpp b/src/Simulator/DelayedFluidSimulator.cpp index 59ea51aa0..dc8dffe2d 100644 --- a/src/Simulator/DelayedFluidSimulator.cpp +++ b/src/Simulator/DelayedFluidSimulator.cpp @@ -55,7 +55,7 @@ cDelayedFluidSimulatorChunkData::cDelayedFluidSimulatorChunkData(int a_TickDelay cDelayedFluidSimulatorChunkData::~cDelayedFluidSimulatorChunkData() { delete[] m_Slots; - m_Slots = NULL; + m_Slots = nullptr; } @@ -86,7 +86,7 @@ void cDelayedFluidSimulator::AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, return; } - if ((a_Chunk == NULL) || !a_Chunk->IsValid()) + if ((a_Chunk == nullptr) || !a_Chunk->IsValid()) { return; } diff --git a/src/Simulator/FireSimulator.cpp b/src/Simulator/FireSimulator.cpp index d3deee74a..75ebefcf7 100644 --- a/src/Simulator/FireSimulator.cpp +++ b/src/Simulator/FireSimulator.cpp @@ -220,7 +220,7 @@ bool cFireSimulator::DoesBurnForever(BLOCKTYPE a_BlockType) void cFireSimulator::AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) { - if ((a_Chunk == NULL) || !a_Chunk->IsValid()) + if ((a_Chunk == nullptr) || !a_Chunk->IsValid()) { return; } @@ -359,7 +359,7 @@ void cFireSimulator::RemoveFuelNeighbors(cChunk * a_Chunk, int a_RelX, int a_Rel int Z = a_RelZ + gNeighborCoords[i].z; cChunkPtr Neighbour = a_Chunk->GetRelNeighborChunkAdjustCoords(X, Z); - if (Neighbour == NULL) + if (Neighbour == nullptr) { continue; } diff --git a/src/Simulator/FloodyFluidSimulator.cpp b/src/Simulator/FloodyFluidSimulator.cpp index b839aa746..e95ef216d 100644 --- a/src/Simulator/FloodyFluidSimulator.cpp +++ b/src/Simulator/FloodyFluidSimulator.cpp @@ -220,7 +220,7 @@ void cFloodyFluidSimulator::SpreadToNeighbor(cChunk * a_NearChunk, int a_RelX, i ASSERT(a_NewMeta > 0); // Source blocks aren't spread a_NearChunk = a_NearChunk->GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ); - if ((a_NearChunk == NULL) || (!a_NearChunk->IsValid())) + if ((a_NearChunk == nullptr) || (!a_NearChunk->IsValid())) { // Chunk not available return; @@ -297,7 +297,7 @@ void cFloodyFluidSimulator::SpreadToNeighbor(cChunk * a_NearChunk, int a_RelX, i ChunkInterface, m_World, PluginInterface, - NULL, + nullptr, BlockX, a_RelY, BlockZ diff --git a/src/Simulator/FluidSimulator.cpp b/src/Simulator/FluidSimulator.cpp index 58501326f..9c8453d04 100644 --- a/src/Simulator/FluidSimulator.cpp +++ b/src/Simulator/FluidSimulator.cpp @@ -178,7 +178,7 @@ Direction cFluidSimulator::GetFlowingDirection(int a_X, int a_Y, int a_Z, bool a } delete Pos; - Pos = NULL; + Pos = nullptr; } if (LowestPoint == m_World.GetBlockMeta(a_X, a_Y, a_Z)) diff --git a/src/Simulator/FluidSimulator.h b/src/Simulator/FluidSimulator.h index 0877a7bf1..d65a8e78b 100644 --- a/src/Simulator/FluidSimulator.h +++ b/src/Simulator/FluidSimulator.h @@ -51,7 +51,7 @@ public: virtual Direction GetFlowingDirection(int a_X, int a_Y, int a_Z, bool a_Over = true); /// Creates a ChunkData object for the simulator to use. The simulator returns the correct object type. - virtual cFluidSimulatorData * CreateChunkData(void) { return NULL; } + virtual cFluidSimulatorData * CreateChunkData(void) { return nullptr; } bool IsFluidBlock (BLOCKTYPE a_BlockType) const { return (a_BlockType == m_FluidBlock); } bool IsStationaryFluidBlock(BLOCKTYPE a_BlockType) const { return (a_BlockType == m_StationaryFluidBlock); } diff --git a/src/Simulator/NoopRedstoneSimulator.h b/src/Simulator/NoopRedstoneSimulator.h index 7c961f32b..832b26dfc 100644 --- a/src/Simulator/NoopRedstoneSimulator.h +++ b/src/Simulator/NoopRedstoneSimulator.h @@ -39,7 +39,7 @@ public: virtual cRedstoneSimulatorChunkData * CreateChunkData() override { - return NULL; + return nullptr; } } ; diff --git a/src/Simulator/SandSimulator.cpp b/src/Simulator/SandSimulator.cpp index aad41e463..073518b31 100644 --- a/src/Simulator/SandSimulator.cpp +++ b/src/Simulator/SandSimulator.cpp @@ -94,7 +94,7 @@ bool cSandSimulator::IsAllowedBlock(BLOCKTYPE a_BlockType) void cSandSimulator::AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) { - if ((a_Chunk == NULL) || !a_Chunk->IsValid()) + if ((a_Chunk == nullptr) || !a_Chunk->IsValid()) { return; } diff --git a/src/Simulator/VaporizeFluidSimulator.cpp b/src/Simulator/VaporizeFluidSimulator.cpp index 484cac334..119742346 100644 --- a/src/Simulator/VaporizeFluidSimulator.cpp +++ b/src/Simulator/VaporizeFluidSimulator.cpp @@ -22,7 +22,7 @@ cVaporizeFluidSimulator::cVaporizeFluidSimulator(cWorld & a_World, BLOCKTYPE a_F void cVaporizeFluidSimulator::AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) { - if (a_Chunk == NULL) + if (a_Chunk == nullptr) { return; } diff --git a/src/StackWalker.h b/src/StackWalker.h index bf47d3726..a609f6840 100644 --- a/src/StackWalker.h +++ b/src/StackWalker.h @@ -88,7 +88,7 @@ public: StackWalker( int options = OptionsAll, // 'int' is by design, to combine the enum-flags - LPCSTR szSymPath = NULL, + LPCSTR szSymPath = nullptr, DWORD dwProcessId = GetCurrentProcessId(), HANDLE hProcess = GetCurrentProcess() ); @@ -108,9 +108,9 @@ public: BOOL ShowCallstack( HANDLE hThread = GetCurrentThread(), - const CONTEXT *context = NULL, - PReadProcessMemoryRoutine readMemoryFunction = NULL, - LPVOID pUserData = NULL // optional to identify some data in the 'readMemoryFunction'-callback + const CONTEXT *context = nullptr, + PReadProcessMemoryRoutine readMemoryFunction = nullptr, + LPVOID pUserData = nullptr // optional to identify some data in the 'readMemoryFunction'-callback ); #if _MSC_VER >= 1300 @@ -180,11 +180,11 @@ protected: #define GET_CURRENT_CONTEXT(c, contextFlags) \ do { \ memset(&c, 0, sizeof(CONTEXT)); \ - EXCEPTION_POINTERS *pExp = NULL; \ + EXCEPTION_POINTERS *pExp = nullptr; \ __try { \ throw 0; \ } __except( ( (pExp = GetExceptionInformation()) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_EXECUTE_HANDLER)) {} \ - if (pExp != NULL) \ + if (pExp != nullptr) \ memcpy(&c, pExp->ContextRecord, sizeof(CONTEXT)); \ c.ContextFlags = contextFlags; \ } while(0); diff --git a/src/StringUtils.cpp b/src/StringUtils.cpp index 21962f832..34f2da682 100644 --- a/src/StringUtils.cpp +++ b/src/StringUtils.cpp @@ -20,7 +20,7 @@ AString & AppendVPrintf(AString & str, const char * format, va_list args) { - ASSERT(format != NULL); + ASSERT(format != nullptr); char buffer[2048]; size_t len; @@ -562,7 +562,7 @@ AString & CreateHexDump(AString & a_Out, const void * a_Data, size_t a_Size, siz #else int Count = sprintf(line, "%08x:", (unsigned)i); #endif - // Remove the terminating NULL / leftover garbage in line, after the sprintf-ed value + // Remove the terminating nullptr / leftover garbage in line, after the sprintf-ed value memset(line + Count, 32, sizeof(line) - Count); p = line + 10; q = p + 2 + a_BytesPerLine * 3 + 1; diff --git a/src/UI/SlotArea.cpp b/src/UI/SlotArea.cpp index 88d9f44fc..9113ec343 100644 --- a/src/UI/SlotArea.cpp +++ b/src/UI/SlotArea.cpp @@ -48,9 +48,9 @@ void cSlotArea::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickA ASSERT((a_SlotNum >= 0) && (a_SlotNum < GetNumSlots())); bool bAsync = false; - if (GetSlot(a_SlotNum, a_Player) == NULL) + if (GetSlot(a_SlotNum, a_Player) == nullptr) { - LOGWARNING("GetSlot(%d) returned NULL! Ignoring click", a_SlotNum); + LOGWARNING("GetSlot(%d) returned nullptr! Ignoring click", a_SlotNum); return; } @@ -791,9 +791,9 @@ void cSlotAreaAnvil::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_C } bool bAsync = false; - if (GetSlot(a_SlotNum, a_Player) == NULL) + if (GetSlot(a_SlotNum, a_Player) == nullptr) { - LOGWARNING("GetSlot(%d) returned NULL! Ignoring click", a_SlotNum); + LOGWARNING("GetSlot(%d) returned nullptr! Ignoring click", a_SlotNum); return; } @@ -980,7 +980,7 @@ void cSlotAreaAnvil::OnTakeResult(cPlayer & a_Player) m_ParentWindow.SetProperty(0, m_MaximumCost, a_Player); m_MaximumCost = 0; - ((cAnvilWindow*)&m_ParentWindow)->SetRepairedItemName("", NULL); + ((cAnvilWindow*)&m_ParentWindow)->SetRepairedItemName("", nullptr); int PosX, PosY, PosZ; ((cAnvilWindow*)&m_ParentWindow)->GetBlockPos(PosX, PosY, PosZ); @@ -1238,9 +1238,9 @@ void cSlotAreaBeacon::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ ASSERT((a_SlotNum >= 0) && (a_SlotNum < GetNumSlots())); bool bAsync = false; - if (GetSlot(a_SlotNum, a_Player) == NULL) + if (GetSlot(a_SlotNum, a_Player) == nullptr) { - LOGWARNING("GetSlot(%d) returned NULL! Ignoring click", a_SlotNum); + LOGWARNING("GetSlot(%d) returned nullptr! Ignoring click", a_SlotNum); return; } @@ -1408,9 +1408,9 @@ void cSlotAreaEnchanting::Clicked(cPlayer & a_Player, int a_SlotNum, eClickActio ASSERT((a_SlotNum >= 0) && (a_SlotNum < GetNumSlots())); bool bAsync = false; - if (GetSlot(a_SlotNum, a_Player) == NULL) + if (GetSlot(a_SlotNum, a_Player) == nullptr) { - LOGWARNING("GetSlot(%d) returned NULL! Ignoring click", a_SlotNum); + LOGWARNING("GetSlot(%d) returned nullptr! Ignoring click", a_SlotNum); return; } @@ -1709,19 +1709,19 @@ cSlotAreaFurnace::~cSlotAreaFurnace() void cSlotAreaFurnace::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem) { - if (m_Furnace == NULL) + if (m_Furnace == nullptr) { - LOGERROR("cSlotAreaFurnace::Clicked(): m_Furnace == NULL"); - ASSERT(!"cSlotAreaFurnace::Clicked(): m_Furnace == NULL"); + LOGERROR("cSlotAreaFurnace::Clicked(): m_Furnace == nullptr"); + ASSERT(!"cSlotAreaFurnace::Clicked(): m_Furnace == nullptr"); return; } if (a_SlotNum == 2) { bool bAsync = false; - if (GetSlot(a_SlotNum, a_Player) == NULL) + if (GetSlot(a_SlotNum, a_Player) == nullptr) { - LOGWARNING("GetSlot(%d) returned NULL! Ignoring click", a_SlotNum); + LOGWARNING("GetSlot(%d) returned nullptr! Ignoring click", a_SlotNum); return; } @@ -2071,9 +2071,9 @@ void cSlotAreaArmor::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_C } bool bAsync = false; - if (GetSlot(a_SlotNum, a_Player) == NULL) + if (GetSlot(a_SlotNum, a_Player) == nullptr) { - LOGWARNING("GetSlot(%d) returned NULL! Ignoring click", a_SlotNum); + LOGWARNING("GetSlot(%d) returned nullptr! Ignoring click", a_SlotNum); return; } @@ -2223,15 +2223,15 @@ const cItem * cSlotAreaTemporary::GetSlot(int a_SlotNum, cPlayer & a_Player) con LOGERROR("cSlotAreaTemporary: player \"%s\" not found for slot %d!", a_Player.GetName().c_str(), a_SlotNum); ASSERT(!"cSlotAreaTemporary: player not found!"); - // Player not found, this should not happen, ever! Return NULL, but things may break by this. - return NULL; + // Player not found, this should not happen, ever! Return nullptr, but things may break by this. + return nullptr; } if (a_SlotNum >= (int)(itr->second.size())) { LOGERROR("cSlotAreaTemporary: asking for more slots than actually stored!"); ASSERT(!"cSlotAreaTemporary: asking for more slots than actually stored!"); - return NULL; + return nullptr; } return &(itr->second[a_SlotNum]); @@ -2320,7 +2320,7 @@ cItem * cSlotAreaTemporary::GetPlayerSlots(cPlayer & a_Player) cItemMap::iterator itr = m_Items.find(a_Player.GetUniqueID()); if (itr == m_Items.end()) { - return NULL; + return nullptr; } return &(itr->second[0]); } diff --git a/src/UI/Window.cpp b/src/UI/Window.cpp index 802d0d219..1598dd3e7 100644 --- a/src/UI/Window.cpp +++ b/src/UI/Window.cpp @@ -33,7 +33,7 @@ cWindow::cWindow(WindowType a_WindowType, const AString & a_WindowTitle) : m_WindowTitle(a_WindowTitle), m_IsDestroyed(false), m_ShouldDistributeToHotbarFirst(true), - m_Owner(NULL) + m_Owner(nullptr) { if (a_WindowType == wtInventory) { @@ -105,10 +105,10 @@ const cItem * cWindow::GetSlot(cPlayer & a_Player, int a_SlotNum) const // Return the item at the specified slot for the specified player int LocalSlotNum = 0; const cSlotArea * Area = GetSlotArea(a_SlotNum, LocalSlotNum); - if (Area == NULL) + if (Area == nullptr) { - LOGWARNING("%s: requesting item from an invalid SlotArea (SlotNum %d), returning NULL.", __FUNCTION__, a_SlotNum); - return NULL; + LOGWARNING("%s: requesting item from an invalid SlotArea (SlotNum %d), returning nullptr.", __FUNCTION__, a_SlotNum); + return nullptr; } return Area->GetSlot(LocalSlotNum, a_Player); } @@ -122,7 +122,7 @@ void cWindow::SetSlot(cPlayer & a_Player, int a_SlotNum, const cItem & a_Item) // Set the item to the specified slot for the specified player int LocalSlotNum = 0; cSlotArea * Area = GetSlotArea(a_SlotNum, LocalSlotNum); - if (Area == NULL) + if (Area == nullptr) { LOGWARNING("%s: requesting write to an invalid SlotArea (SlotNum %d), ignoring.", __FUNCTION__, a_SlotNum); return; @@ -177,7 +177,7 @@ void cWindow::GetSlots(cPlayer & a_Player, cItems & a_Slots) const for (int i = 0; i < NumSlots; i++) { const cItem * Item = (*itr)->GetSlot(i, a_Player); - if (Item == NULL) + if (Item == nullptr) { a_Slots.push_back(cItem()); } @@ -311,7 +311,7 @@ bool cWindow::ClosedByPlayer(cPlayer & a_Player, bool a_CanRefuse) } cClientHandle * ClientHandle = a_Player.GetClientHandle(); - if (ClientHandle != NULL) + if (ClientHandle != nullptr) { ClientHandle->SendWindowClose(*this); } @@ -345,7 +345,7 @@ bool cWindow::ClosedByPlayer(cPlayer & a_Player, bool a_CanRefuse) void cWindow::OwnerDestroyed() { - m_Owner = NULL; + m_Owner = nullptr; // Close window for each player. Note that the last one needs special handling while (m_OpenedBy.size() > 1) { @@ -511,10 +511,10 @@ void cWindow::SendSlot(cPlayer & a_Player, cSlotArea * a_SlotArea, int a_Relativ void cWindow::Destroy(void) { - if (m_Owner != NULL) + if (m_Owner != nullptr) { m_Owner->CloseWindow(); - m_Owner = NULL; + m_Owner = nullptr; } m_IsDestroyed = true; } @@ -529,7 +529,7 @@ cSlotArea * cWindow::GetSlotArea(int a_GlobalSlotNum, int & a_LocalSlotNum) { LOGWARNING("%s: requesting an invalid SlotNum: %d out of %d slots", __FUNCTION__, a_GlobalSlotNum, GetNumSlots() - 1); ASSERT(!"Invalid SlotNum"); - return NULL; + return nullptr; } // Iterate through all the SlotAreas, find the correct one @@ -547,7 +547,7 @@ cSlotArea * cWindow::GetSlotArea(int a_GlobalSlotNum, int & a_LocalSlotNum) // We shouldn't be here - the check at the beginnning should prevent this. Log and assert LOGWARNING("%s: GetNumSlots() is out of sync: %d; LocalSlotNum = %d", __FUNCTION__, GetNumSlots(), LocalSlotNum); ASSERT(!"Invalid GetNumSlots"); - return NULL; + return nullptr; } @@ -560,7 +560,7 @@ const cSlotArea * cWindow::GetSlotArea(int a_GlobalSlotNum, int & a_LocalSlotNum { LOGWARNING("%s: requesting an invalid SlotNum: %d out of %d slots", __FUNCTION__, a_GlobalSlotNum, GetNumSlots() - 1); ASSERT(!"Invalid SlotNum"); - return NULL; + return nullptr; } // Iterate through all the SlotAreas, find the correct one @@ -578,7 +578,7 @@ const cSlotArea * cWindow::GetSlotArea(int a_GlobalSlotNum, int & a_LocalSlotNum // We shouldn't be here - the check at the beginnning should prevent this. Log and assert LOGWARNING("%s: GetNumSlots() is out of sync: %d; LocalSlotNum = %d", __FUNCTION__, GetNumSlots(), LocalSlotNum); ASSERT(!"Invalid GetNumSlots"); - return NULL; + return nullptr; } @@ -669,7 +669,7 @@ int cWindow::DistributeItemToSlots(cPlayer & a_Player, const cItem & a_Item, int { int LocalSlotNum = 0; cSlotArea * Area = GetSlotArea(*itr, LocalSlotNum); - if (Area == NULL) + if (Area == nullptr) { LOGWARNING("%s: Bad SlotArea for slot %d", __FUNCTION__, *itr); continue; @@ -836,7 +836,7 @@ void cAnvilWindow::SetRepairedItemName(const AString & a_Name, cPlayer * a_Playe { m_RepairedItemName = a_Name; - if (a_Player != NULL) + if (a_Player != nullptr) { m_AnvilSlotArea->UpdateResult(*a_Player); } @@ -963,7 +963,7 @@ cChestWindow::cChestWindow(cChestEntity * a_Chest) : m_BlockY(a_Chest->GetPosY()), m_BlockZ(a_Chest->GetPosZ()), m_PrimaryChest(a_Chest), - m_SecondaryChest(NULL) + m_SecondaryChest(nullptr) { m_SlotAreas.push_back(new cSlotAreaChest(a_Chest, *this)); m_SlotAreas.push_back(new cSlotAreaInventory(*this)); @@ -1014,7 +1014,7 @@ void cChestWindow::OpenedByPlayer(cPlayer & a_Player) cChunkDef::BlockToChunk(m_PrimaryChest->GetPosX(), m_PrimaryChest->GetPosZ(), ChunkX, ChunkZ); m_PrimaryChest->GetWorld()->MarkRedstoneDirty(ChunkX, ChunkZ); - if (m_SecondaryChest != NULL) + if (m_SecondaryChest != nullptr) { m_SecondaryChest->SetNumberOfPlayers(m_SecondaryChest->GetNumberOfPlayers() + 1); cChunkDef::BlockToChunk(m_SecondaryChest->GetPosX(), m_SecondaryChest->GetPosZ(), ChunkX, ChunkZ); @@ -1036,7 +1036,7 @@ bool cChestWindow::ClosedByPlayer(cPlayer & a_Player, bool a_CanRefuse) cChunkDef::BlockToChunk(m_PrimaryChest->GetPosX(), m_PrimaryChest->GetPosZ(), ChunkX, ChunkZ); m_PrimaryChest->GetWorld()->MarkRedstoneDirty(ChunkX, ChunkZ); - if (m_SecondaryChest != NULL) + if (m_SecondaryChest != nullptr) { m_SecondaryChest->SetNumberOfPlayers(m_SecondaryChest->GetNumberOfPlayers() - 1); cChunkDef::BlockToChunk(m_SecondaryChest->GetPosX(), m_SecondaryChest->GetPosZ(), ChunkX, ChunkZ); diff --git a/src/UI/Window.h b/src/UI/Window.h index 26dd7f125..e62176d50 100644 --- a/src/UI/Window.h +++ b/src/UI/Window.h @@ -90,7 +90,7 @@ public: // tolua_begin - /// Returns the item at the specified slot for the specified player. Returns NULL if invalid SlotNum requested + /// Returns the item at the specified slot for the specified player. Returns nullptr if invalid SlotNum requested const cItem * GetSlot(cPlayer & a_Player, int a_SlotNum) const; /// Sets the item to the specified slot for the specified player @@ -189,13 +189,13 @@ protected: /** Returns the correct slot area for the specified window-global SlotNum Also returns the area-local SlotNum corresponding to the GlobalSlotNum - If the global SlotNum is out of range, returns NULL + If the global SlotNum is out of range, returns nullptr */ cSlotArea * GetSlotArea(int a_GlobalSlotNum, int & a_LocalSlotNum); /** Returns the correct slot area for the specified window-global SlotNum Also returns the area-local SlotNum corresponding to the GlobalSlotNum - If the global SlotNum is out of range, returns NULL. + If the global SlotNum is out of range, returns nullptr. Const version. */ const cSlotArea * GetSlotArea(int a_GlobalSlotNum, int & a_LocalSlotNum) const; diff --git a/src/UI/WindowOwner.h b/src/UI/WindowOwner.h index 6845a161b..4dc3cf080 100644 --- a/src/UI/WindowOwner.h +++ b/src/UI/WindowOwner.h @@ -22,7 +22,7 @@ class cWindowOwner { public: cWindowOwner() : - m_Window(NULL) + m_Window(nullptr) { } @@ -32,7 +32,7 @@ public: void CloseWindow(void) { - m_Window = NULL; + m_Window = nullptr; } void OpenWindow(cWindow * a_Window) diff --git a/src/WebAdmin.cpp b/src/WebAdmin.cpp index db2ace386..dbf600c25 100644 --- a/src/WebAdmin.cpp +++ b/src/WebAdmin.cpp @@ -224,7 +224,7 @@ void cWebAdmin::HandleWebadminRequest(cHTTPConnection & a_Connection, cHTTPReque // Retrieve the request data: cWebadminRequestData * Data = (cWebadminRequestData *)(a_Request.GetUserData()); - if (Data == NULL) + if (Data == nullptr) { a_Connection.SendStatusAndReason(500, "Bad UserData"); return; @@ -483,7 +483,7 @@ AString cWebAdmin::GetDefaultPage(void) const cPluginManager::PluginMap & List = PM->GetAllPlugins(); for (cPluginManager::PluginMap::const_iterator itr = List.begin(); itr != List.end(); ++itr) { - if (itr->second == NULL) + if (itr->second == nullptr) { continue; } @@ -494,7 +494,7 @@ AString cWebAdmin::GetDefaultPage(void) cPlayerAccum PlayerAccum; cWorld * World = cRoot::Get()->GetDefaultWorld(); // TODO - Create a list of worlds and players - if (World != NULL) + if (World != nullptr) { World->ForEachPlayer(PlayerAccum); Content.append(PlayerAccum.m_Contents); @@ -625,7 +625,7 @@ void cWebAdmin::OnRequestBody(cHTTPConnection & a_Connection, cHTTPRequest & a_R { UNUSED(a_Connection); cRequestData * Data = (cRequestData *)(a_Request.GetUserData()); - if (Data == NULL) + if (Data == nullptr) { return; } @@ -659,7 +659,7 @@ void cWebAdmin::OnRequestFinished(cHTTPConnection & a_Connection, cHTTPRequest & // Delete any request data assigned to the request: cRequestData * Data = (cRequestData *)(a_Request.GetUserData()); delete Data; - Data = NULL; + Data = nullptr; } diff --git a/src/World.cpp b/src/World.cpp index 010fc0d87..c6168b572 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -252,10 +252,10 @@ cWorld::cWorld(const AString & a_WorldName, eDimension a_Dimension, const AStrin m_VillagersShouldHarvestCrops(true), m_SimulatorManager(), m_SandSimulator(), - m_WaterSimulator(NULL), + m_WaterSimulator(nullptr), m_LavaSimulator(nullptr), m_FireSimulator(), - m_RedstoneSimulator(NULL), + m_RedstoneSimulator(nullptr), m_MaxPlayers(10), m_ChunkMap(), m_bAnimals(true), @@ -297,9 +297,9 @@ cWorld::cWorld(const AString & a_WorldName, eDimension a_Dimension, const AStrin cWorld::~cWorld() { - delete m_WaterSimulator; m_WaterSimulator = NULL; - delete m_LavaSimulator; m_LavaSimulator = NULL; - delete m_RedstoneSimulator; m_RedstoneSimulator = NULL; + delete m_WaterSimulator; m_WaterSimulator = nullptr; + delete m_LavaSimulator; m_LavaSimulator = nullptr; + delete m_RedstoneSimulator; m_RedstoneSimulator = nullptr; UnloadUnusedChunks(); @@ -1255,7 +1255,7 @@ void cWorld::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_Blo for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { cClientHandle * ch = (*itr)->GetClientHandle(); - if (ch == NULL) + if (ch == nullptr) { continue; } @@ -2010,7 +2010,7 @@ void cWorld::BroadcastChat(const AString & a_Message, const cClientHandle * a_Ex for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { cClientHandle * ch = (*itr)->GetClientHandle(); - if ((ch == a_Exclude) || (ch == NULL) || !ch->IsLoggedIn() || ch->IsDestroyed()) + if ((ch == a_Exclude) || (ch == nullptr) || !ch->IsLoggedIn() || ch->IsDestroyed()) { continue; } @@ -2028,7 +2028,7 @@ void cWorld::BroadcastChat(const cCompositeChat & a_Message, const cClientHandle for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { cClientHandle * ch = (*itr)->GetClientHandle(); - if ((ch == a_Exclude) || (ch == NULL) || !ch->IsLoggedIn() || ch->IsDestroyed()) + if ((ch == a_Exclude) || (ch == nullptr) || !ch->IsLoggedIn() || ch->IsDestroyed()) { continue; } @@ -2171,7 +2171,7 @@ void cWorld::BroadcastPlayerListAddPlayer(const cPlayer & a_Player, const cClien for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { cClientHandle * ch = (*itr)->GetClientHandle(); - if ((ch == a_Exclude) || (ch == NULL) || !ch->IsLoggedIn() || ch->IsDestroyed()) + if ((ch == a_Exclude) || (ch == nullptr) || !ch->IsLoggedIn() || ch->IsDestroyed()) { continue; } @@ -2189,7 +2189,7 @@ void cWorld::BroadcastPlayerListRemovePlayer(const cPlayer & a_Player, const cCl for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { cClientHandle * ch = (*itr)->GetClientHandle(); - if ((ch == a_Exclude) || (ch == NULL) || !ch->IsLoggedIn() || ch->IsDestroyed()) + if ((ch == a_Exclude) || (ch == nullptr) || !ch->IsLoggedIn() || ch->IsDestroyed()) { continue; } @@ -2207,7 +2207,7 @@ void cWorld::BroadcastPlayerListUpdateGameMode(const cPlayer & a_Player, const c for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { cClientHandle * ch = (*itr)->GetClientHandle(); - if ((ch == a_Exclude) || (ch == NULL) || !ch->IsLoggedIn() || ch->IsDestroyed()) + if ((ch == a_Exclude) || (ch == nullptr) || !ch->IsLoggedIn() || ch->IsDestroyed()) { continue; } @@ -2225,7 +2225,7 @@ void cWorld::BroadcastPlayerListUpdatePing(const cPlayer & a_Player, const cClie for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { cClientHandle * ch = (*itr)->GetClientHandle(); - if ((ch == a_Exclude) || (ch == NULL) || !ch->IsLoggedIn() || ch->IsDestroyed()) + if ((ch == a_Exclude) || (ch == nullptr) || !ch->IsLoggedIn() || ch->IsDestroyed()) { continue; } @@ -2243,7 +2243,7 @@ void cWorld::BroadcastPlayerListUpdateDisplayName(const cPlayer & a_Player, cons for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { cClientHandle * ch = (*itr)->GetClientHandle(); - if ((ch == a_Exclude) || (ch == NULL) || !ch->IsLoggedIn() || ch->IsDestroyed()) + if ((ch == a_Exclude) || (ch == nullptr) || !ch->IsLoggedIn() || ch->IsDestroyed()) { continue; } @@ -2270,7 +2270,7 @@ void cWorld::BroadcastScoreboardObjective(const AString & a_Name, const AString for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { cClientHandle * ch = (*itr)->GetClientHandle(); - if ((ch == NULL) || !ch->IsLoggedIn() || ch->IsDestroyed()) + if ((ch == nullptr) || !ch->IsLoggedIn() || ch->IsDestroyed()) { continue; } @@ -2288,7 +2288,7 @@ void cWorld::BroadcastScoreUpdate(const AString & a_Objective, const AString & a for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { cClientHandle * ch = (*itr)->GetClientHandle(); - if ((ch == NULL) || !ch->IsLoggedIn() || ch->IsDestroyed()) + if ((ch == nullptr) || !ch->IsLoggedIn() || ch->IsDestroyed()) { continue; } @@ -2306,7 +2306,7 @@ void cWorld::BroadcastDisplayObjective(const AString & a_Objective, cScoreboard: for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { cClientHandle * ch = (*itr)->GetClientHandle(); - if ((ch == NULL) || !ch->IsLoggedIn() || ch->IsDestroyed()) + if ((ch == nullptr) || !ch->IsLoggedIn() || ch->IsDestroyed()) { continue; } @@ -2351,7 +2351,7 @@ void cWorld::BroadcastTeleportEntity(const cEntity & a_Entity, const cClientHand for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { cClientHandle * ch = (*itr)->GetClientHandle(); - if ((ch == a_Exclude) || (ch == NULL) || !ch->IsLoggedIn() || ch->IsDestroyed()) + if ((ch == a_Exclude) || (ch == nullptr) || !ch->IsLoggedIn() || ch->IsDestroyed()) { continue; } @@ -2378,7 +2378,7 @@ void cWorld::BroadcastTimeUpdate(const cClientHandle * a_Exclude) for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { cClientHandle * ch = (*itr)->GetClientHandle(); - if ((ch == a_Exclude) || (ch == NULL) || !ch->IsLoggedIn() || ch->IsDestroyed()) + if ((ch == a_Exclude) || (ch == nullptr) || !ch->IsLoggedIn() || ch->IsDestroyed()) { continue; } @@ -2405,7 +2405,7 @@ void cWorld::BroadcastWeather(eWeather a_Weather, const cClientHandle * a_Exclud for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { cClientHandle * ch = (*itr)->GetClientHandle(); - if ((ch == a_Exclude) || (ch == NULL) || !ch->IsLoggedIn() || ch->IsDestroyed()) + if ((ch == a_Exclude) || (ch == nullptr) || !ch->IsLoggedIn() || ch->IsDestroyed()) { continue; } @@ -2640,7 +2640,7 @@ void cWorld::RemovePlayer(cPlayer * a_Player, bool a_RemoveFromChunk) // Remove the player's client from the list of clients to be ticked: cClientHandle * Client = a_Player->GetClientHandle(); - if (Client != NULL) + if (Client != nullptr) { Client->RemoveFromWorld(); m_ChunkMap->RemoveClientFromChunks(Client); @@ -2693,7 +2693,7 @@ bool cWorld::DoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_ bool cWorld::FindAndDoWithPlayer(const AString & a_PlayerNameHint, cPlayerListCallback & a_Callback) { - cPlayer * BestMatch = NULL; + cPlayer * BestMatch = nullptr; size_t BestRating = 0; size_t NameLength = a_PlayerNameHint.length(); @@ -2712,7 +2712,7 @@ bool cWorld::FindAndDoWithPlayer(const AString & a_PlayerNameHint, cPlayerListCa } } // for itr - m_Players[] - if (BestMatch != NULL) + if (BestMatch != nullptr) { return a_Callback.Item (BestMatch); } @@ -2729,7 +2729,7 @@ cPlayer * cWorld::FindClosestPlayer(const Vector3d & a_Pos, float a_SightLimit, cTracer LineOfSight(this); double ClosestDistance = a_SightLimit; - cPlayer * ClosestPlayer = NULL; + cPlayer * ClosestPlayer = nullptr; cCSLock Lock(m_CSPlayers); for (cPlayerList::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) @@ -2768,7 +2768,7 @@ void cWorld::SendPlayerList(cPlayer * a_DestPlayer) for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { cClientHandle * ch = (*itr)->GetClientHandle(); - if ((ch != NULL) && !ch->IsDestroyed()) + if ((ch != nullptr) && !ch->IsDestroyed()) { a_DestPlayer->GetClientHandle()->SendPlayerListAddPlayer(*(*itr)); } @@ -3212,10 +3212,10 @@ bool cWorld::IsBlockDirectlyWatered(int a_BlockX, int a_BlockY, int a_BlockZ) int cWorld::SpawnMob(double a_PosX, double a_PosY, double a_PosZ, eMonsterType a_MonsterType) { - cMonster * Monster = NULL; + cMonster * Monster = nullptr; Monster = cMonster::NewMonsterFromType(a_MonsterType); - if (Monster != NULL) + if (Monster != nullptr) { Monster->SetPosition(a_PosX, a_PosY, a_PosZ); } @@ -3241,7 +3241,7 @@ int cWorld::SpawnMobFinalize(cMonster * a_Monster) if (cPluginManager::Get()->CallHookSpawningMonster(*this, *a_Monster)) { delete a_Monster; - a_Monster = NULL; + a_Monster = nullptr; return -1; } @@ -3249,7 +3249,7 @@ int cWorld::SpawnMobFinalize(cMonster * a_Monster) if (!a_Monster->Initialize(*this)) { delete a_Monster; - a_Monster = NULL; + a_Monster = nullptr; return -1; } @@ -3266,14 +3266,14 @@ int cWorld::SpawnMobFinalize(cMonster * a_Monster) int cWorld::CreateProjectile(double a_PosX, double a_PosY, double a_PosZ, cProjectileEntity::eKind a_Kind, cEntity * a_Creator, const cItem * a_Item, const Vector3d * a_Speed) { cProjectileEntity * Projectile = cProjectileEntity::Create(a_Kind, a_Creator, a_PosX, a_PosY, a_PosZ, a_Item, a_Speed); - if (Projectile == NULL) + if (Projectile == nullptr) { return -1; } if (!Projectile->Initialize(*this)) { delete Projectile; - Projectile = NULL; + Projectile = nullptr; return -1; } return Projectile->GetUniqueID(); @@ -3356,7 +3356,7 @@ cRedstoneSimulator * cWorld::InitializeRedstoneSimulator(cIniFil SimulatorName = "Incremental"; } - cRedstoneSimulator * res = NULL; + cRedstoneSimulator * res = nullptr; if (NoCaseCompare(SimulatorName, "Incremental") == 0) { @@ -3389,7 +3389,7 @@ cFluidSimulator * cWorld::InitializeFluidSimulator(cIniFile & a_IniFile, const c SimulatorName = "Vanilla"; } - cFluidSimulator * res = NULL; + cFluidSimulator * res = nullptr; bool IsWater = (strcmp(a_FluidName, "Water") == 0); // Used for defaults int Rate = 1; if ( @@ -3479,7 +3479,7 @@ void cWorld::AddQueuedPlayers(void) for (cPlayerList::iterator itr = PlayersToAdd.begin(), end = PlayersToAdd.end(); itr != end; ++itr) { cClientHandle * Client = (*itr)->GetClientHandle(); - if (Client != NULL) + if (Client != nullptr) { m_Clients.push_back(Client); } @@ -3490,7 +3490,7 @@ void cWorld::AddQueuedPlayers(void) for (cPlayerList::iterator itr = PlayersToAdd.begin(), end = PlayersToAdd.end(); itr != end; ++itr) { cClientHandle * Client = (*itr)->GetClientHandle(); - if (Client != NULL) + if (Client != nullptr) { Client->StreamChunks(); Client->SendPlayerMoveLook(); @@ -3591,7 +3591,7 @@ void cWorld::cChunkGeneratorCallbacks::OnChunkGenerated(cChunkDesc & a_ChunkDesc cSetChunkDataPtr SetChunkData(new cSetChunkData( a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ(), a_ChunkDesc.GetBlockTypes(), BlockMetas, - NULL, NULL, // We don't have lighting, chunk will be lighted when needed + nullptr, nullptr, // We don't have lighting, chunk will be lighted when needed &a_ChunkDesc.GetHeightMap(), &a_ChunkDesc.GetBiomeMap(), a_ChunkDesc.GetEntities(), a_ChunkDesc.GetBlockEntities(), true diff --git a/src/World.h b/src/World.h index 338721553..b1b80ffb2 100644 --- a/src/World.h +++ b/src/World.h @@ -212,52 +212,52 @@ public: // Broadcast respective packets to all clients of the chunk where the event is taking place // (Please keep these alpha-sorted) void BroadcastAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle); - void BroadcastBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType, const cClientHandle * a_Exclude = NULL); // tolua_export - void BroadcastBlockBreakAnimation(int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage, const cClientHandle * a_Exclude = NULL); - void BroadcastBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = NULL); ///< If there is a block entity at the specified coods, sends it to all clients except a_Exclude + void BroadcastBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType, const cClientHandle * a_Exclude = nullptr); // tolua_export + void BroadcastBlockBreakAnimation(int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage, const cClientHandle * a_Exclude = nullptr); + void BroadcastBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = nullptr); ///< If there is a block entity at the specified coods, sends it to all clients except a_Exclude // tolua_begin - void BroadcastChat (const AString & a_Message, const cClientHandle * a_Exclude = NULL, eMessageType a_ChatPrefix = mtCustom); - void BroadcastChatInfo (const AString & a_Message, const cClientHandle * a_Exclude = NULL) { BroadcastChat(a_Message, a_Exclude, mtInformation); } - void BroadcastChatFailure(const AString & a_Message, const cClientHandle * a_Exclude = NULL) { BroadcastChat(a_Message, a_Exclude, mtFailure); } - void BroadcastChatSuccess(const AString & a_Message, const cClientHandle * a_Exclude = NULL) { BroadcastChat(a_Message, a_Exclude, mtSuccess); } - void BroadcastChatWarning(const AString & a_Message, const cClientHandle * a_Exclude = NULL) { BroadcastChat(a_Message, a_Exclude, mtWarning); } - void BroadcastChatFatal (const AString & a_Message, const cClientHandle * a_Exclude = NULL) { BroadcastChat(a_Message, a_Exclude, mtFailure); } - void BroadcastChatDeath (const AString & a_Message, const cClientHandle * a_Exclude = NULL) { BroadcastChat(a_Message, a_Exclude, mtDeath); } - void BroadcastChat (const cCompositeChat & a_Message, const cClientHandle * a_Exclude = NULL); + void BroadcastChat (const AString & a_Message, const cClientHandle * a_Exclude = nullptr, eMessageType a_ChatPrefix = mtCustom); + void BroadcastChatInfo (const AString & a_Message, const cClientHandle * a_Exclude = nullptr) { BroadcastChat(a_Message, a_Exclude, mtInformation); } + void BroadcastChatFailure(const AString & a_Message, const cClientHandle * a_Exclude = nullptr) { BroadcastChat(a_Message, a_Exclude, mtFailure); } + void BroadcastChatSuccess(const AString & a_Message, const cClientHandle * a_Exclude = nullptr) { BroadcastChat(a_Message, a_Exclude, mtSuccess); } + void BroadcastChatWarning(const AString & a_Message, const cClientHandle * a_Exclude = nullptr) { BroadcastChat(a_Message, a_Exclude, mtWarning); } + void BroadcastChatFatal (const AString & a_Message, const cClientHandle * a_Exclude = nullptr) { BroadcastChat(a_Message, a_Exclude, mtFailure); } + void BroadcastChatDeath (const AString & a_Message, const cClientHandle * a_Exclude = nullptr) { BroadcastChat(a_Message, a_Exclude, mtDeath); } + void BroadcastChat (const cCompositeChat & a_Message, const cClientHandle * a_Exclude = nullptr); // tolua_end - void BroadcastChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = NULL); - void BroadcastCollectEntity (const cEntity & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL); - void BroadcastDestroyEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityHeadLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityMetadata (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityStatus (const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityVelocity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); - virtual void BroadcastEntityAnimation (const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = NULL) override; // tolua_export - void BroadcastParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount, cClientHandle * a_Exclude = NULL); // tolua_export - void BroadcastPlayerListAddPlayer (const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL); - void BroadcastPlayerListRemovePlayer (const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL); - void BroadcastPlayerListUpdateGameMode (const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL); - void BroadcastPlayerListUpdatePing (const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL); - void BroadcastPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName, const cClientHandle * a_Exclude = NULL); - void BroadcastRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude = NULL); + void BroadcastChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = nullptr); + void BroadcastCollectEntity (const cEntity & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude = nullptr); + void BroadcastDestroyEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr); + void BroadcastEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude = nullptr); + void BroadcastEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude = nullptr); + void BroadcastEntityHeadLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr); + void BroadcastEntityLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr); + void BroadcastEntityMetadata (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr); + void BroadcastEntityRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = nullptr); + void BroadcastEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = nullptr); + void BroadcastEntityStatus (const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude = nullptr); + void BroadcastEntityVelocity (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr); + virtual void BroadcastEntityAnimation (const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = nullptr) override; // tolua_export + void BroadcastParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount, cClientHandle * a_Exclude = nullptr); // tolua_export + void BroadcastPlayerListAddPlayer (const cPlayer & a_Player, const cClientHandle * a_Exclude = nullptr); + void BroadcastPlayerListRemovePlayer (const cPlayer & a_Player, const cClientHandle * a_Exclude = nullptr); + void BroadcastPlayerListUpdateGameMode (const cPlayer & a_Player, const cClientHandle * a_Exclude = nullptr); + void BroadcastPlayerListUpdatePing (const cPlayer & a_Player, const cClientHandle * a_Exclude = nullptr); + void BroadcastPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName, const cClientHandle * a_Exclude = nullptr); + void BroadcastRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude = nullptr); void BroadcastScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode); void BroadcastScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode); void BroadcastDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display); - void BroadcastSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = NULL); // tolua_export - void BroadcastSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data, const cClientHandle * a_Exclude = NULL); // tolua_export - void BroadcastSpawnEntity (cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); - void BroadcastTeleportEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); - void BroadcastThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = NULL); - void BroadcastTimeUpdate (const cClientHandle * a_Exclude = NULL); + void BroadcastSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = nullptr); // tolua_export + void BroadcastSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data, const cClientHandle * a_Exclude = nullptr); // tolua_export + void BroadcastSpawnEntity (cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr); + void BroadcastTeleportEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr); + void BroadcastThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = nullptr); + void BroadcastTimeUpdate (const cClientHandle * a_Exclude = nullptr); virtual void BroadcastUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) override; - void BroadcastWeather (eWeather a_Weather, const cClientHandle * a_Exclude = NULL); + void BroadcastWeather (eWeather a_Weather, const cClientHandle * a_Exclude = nullptr); virtual cBroadcastInterface & GetBroadcastManager(void) override { @@ -374,11 +374,11 @@ public: /** Marks the chunk as failed-to-load: */ void ChunkLoadFailed(int a_ChunkX, int a_ChunkZ); - /** Sets the sign text, asking plugins for permission first. a_Player is the player who this change belongs to, may be NULL. Returns true if sign text changed. Same as UpdateSign() */ - bool SetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player = NULL); // Exported in ManualBindings.cpp + /** Sets the sign text, asking plugins for permission first. a_Player is the player who this change belongs to, may be nullptr. Returns true if sign text changed. Same as UpdateSign() */ + bool SetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player = nullptr); // Exported in ManualBindings.cpp - /** Sets the sign text, asking plugins for permission first. a_Player is the player who this change belongs to, may be NULL. Returns true if sign text changed. Same as SetSignLines() */ - bool UpdateSign(int a_X, int a_Y, int a_Z, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player = NULL); // Exported in ManualBindings.cpp + /** Sets the sign text, asking plugins for permission first. a_Player is the player who this change belongs to, may be nullptr. Returns true if sign text changed. Same as SetSignLines() */ + bool UpdateSign(int a_X, int a_Y, int a_Z, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player = nullptr); // Exported in ManualBindings.cpp /** Sets the command block command. Returns true if command changed. */ bool SetCommandBlockCommand(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Command); // tolua_export @@ -396,7 +396,7 @@ public: void GenerateChunk(int a_ChunkX, int a_ChunkZ); // tolua_export /** Queues a chunk for lighting; a_Callback is called after the chunk is lighted */ - void QueueLightChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_Callback = NULL); + void QueueLightChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_Callback = nullptr); bool IsChunkLighted(int a_ChunkX, int a_ChunkZ); @@ -781,7 +781,7 @@ public: /** Creates a projectile of the specified type. Returns the projectile's EntityID if successful, <0 otherwise Item parameter used currently for Fireworks to correctly set entity metadata based on item metadata */ - int CreateProjectile(double a_PosX, double a_PosY, double a_PosZ, cProjectileEntity::eKind a_Kind, cEntity * a_Creator, const cItem * a_Item, const Vector3d * a_Speed = NULL); // tolua_export + int CreateProjectile(double a_PosX, double a_PosY, double a_PosZ, cProjectileEntity::eKind a_Kind, cEntity * a_Creator, const cItem * a_Item, const Vector3d * a_Speed = nullptr); // tolua_export /** Returns a random number from the m_TickRand in range [0 .. a_Range]. To be used only in the tick thread! */ int GetTickRandomNumber(unsigned a_Range) { return (int)(m_TickRand.randInt(a_Range)); } @@ -857,7 +857,7 @@ private: virtual ~cScheduledTask() { delete m_Task; - m_Task = NULL; + m_Task = nullptr; } }; diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index 28b9dd042..c4862bdb4 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -467,7 +467,7 @@ void cNBTChunkSerializer::AddMinecartEntity(cMinecart * a_Minecart) void cNBTChunkSerializer::AddMonsterEntity(cMonster * a_Monster) { - const char * EntityClass = NULL; + const char * EntityClass = nullptr; switch (a_Monster->GetMobType()) { case mtBat: EntityClass = "Bat"; break; diff --git a/src/WorldStorage/ScoreboardSerializer.cpp b/src/WorldStorage/ScoreboardSerializer.cpp index e30eecf67..404604382 100644 --- a/src/WorldStorage/ScoreboardSerializer.cpp +++ b/src/WorldStorage/ScoreboardSerializer.cpp @@ -174,13 +174,13 @@ void cScoreboardSerializer::SaveScoreboardToNBT(cFastNBTWriter & a_Writer) a_Writer.BeginCompound("DisplaySlots"); cObjective * Objective = m_ScoreBoard->GetObjectiveIn(cScoreboard::dsList); - a_Writer.AddString("slot_0", (Objective == NULL) ? "" : Objective->GetName()); + a_Writer.AddString("slot_0", (Objective == nullptr) ? "" : Objective->GetName()); Objective = m_ScoreBoard->GetObjectiveIn(cScoreboard::dsSidebar); - a_Writer.AddString("slot_1", (Objective == NULL) ? "" : Objective->GetName()); + a_Writer.AddString("slot_1", (Objective == nullptr) ? "" : Objective->GetName()); Objective = m_ScoreBoard->GetObjectiveIn(cScoreboard::dsName); - a_Writer.AddString("slot_2", (Objective == NULL) ? "" : Objective->GetName()); + a_Writer.AddString("slot_2", (Objective == nullptr) ? "" : Objective->GetName()); a_Writer.EndCompound(); // DisplaySlots diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 092b9514c..d0483ab70 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -126,7 +126,7 @@ cWSSAnvil::cWSSAnvil(cWorld * a_World, int a_CompressionFactor) : #endif // _DEBUG gzFile gz = gzopen((FILE_IO_PREFIX + fnam).c_str(), "wb"); - if (gz != NULL) + if (gz != nullptr) { gzwrite(gz, Writer.GetResult().data(), (unsigned)Writer.GetResult().size()); } @@ -193,7 +193,7 @@ bool cWSSAnvil::GetChunkData(const cChunkCoords & a_Chunk, AString & a_Data) { cCSLock Lock(m_CS); cMCAFile * File = LoadMCAFile(a_Chunk); - if (File == NULL) + if (File == nullptr) { return false; } @@ -208,7 +208,7 @@ bool cWSSAnvil::SetChunkData(const cChunkCoords & a_Chunk, const AString & a_Dat { cCSLock Lock(m_CS); cMCAFile * File = LoadMCAFile(a_Chunk); - if (File == NULL) + if (File == nullptr) { return false; } @@ -234,7 +234,7 @@ cWSSAnvil::cMCAFile * cWSSAnvil::LoadMCAFile(const cChunkCoords & a_Chunk) // Is it already cached? for (cMCAFiles::iterator itr = m_Files.begin(); itr != m_Files.end(); ++itr) { - if (((*itr) != NULL) && ((*itr)->GetRegionX() == RegionX) && ((*itr)->GetRegionZ() == RegionZ)) + if (((*itr) != nullptr) && ((*itr)->GetRegionX() == RegionX) && ((*itr)->GetRegionZ() == RegionZ)) { // Move the file to front and return it: cMCAFile * f = *itr; @@ -253,9 +253,9 @@ cWSSAnvil::cMCAFile * cWSSAnvil::LoadMCAFile(const cChunkCoords & a_Chunk) cFile::CreateFolder(FILE_IO_PREFIX + FileName); AppendPrintf(FileName, "/r.%d.%d.mca", RegionX, RegionZ); cMCAFile * f = new cMCAFile(FileName, RegionX, RegionZ); - if (f == NULL) + if (f == nullptr) { - return NULL; + return nullptr; } m_Files.push_front(f); @@ -373,7 +373,7 @@ bool cWSSAnvil::LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT // Load the biomes from NBT, if present and valid. First try MCS-style, then Vanilla-style: cChunkDef::BiomeMap BiomeMap; cChunkDef::BiomeMap * Biomes = LoadBiomeMapFromNBT(&BiomeMap, a_NBT, a_NBT.FindChildByName(Level, "MCSBiomes")); - if (Biomes == NULL) + if (Biomes == nullptr) { // MCS-style biomes not available, load vanilla-style: Biomes = LoadVanillaBiomeMapFromNBT(&BiomeMap, a_NBT, a_NBT.FindChildByName(Level, "Biomes")); @@ -426,9 +426,9 @@ bool cWSSAnvil::LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT cSetChunkDataPtr SetChunkData(new cSetChunkData( a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, BlockTypes, MetaData, - IsLightValid ? BlockLight : NULL, - IsLightValid ? SkyLight : NULL, - NULL, Biomes, + IsLightValid ? BlockLight : nullptr, + IsLightValid ? SkyLight : nullptr, + nullptr, Biomes, Entities, BlockEntities, false )); @@ -525,12 +525,12 @@ cChunkDef::BiomeMap * cWSSAnvil::LoadVanillaBiomeMapFromNBT(cChunkDef::BiomeMap { if ((a_TagIdx < 0) || (a_NBT.GetType(a_TagIdx) != TAG_ByteArray)) { - return NULL; + return nullptr; } if (a_NBT.GetDataLength(a_TagIdx) != 16 * 16) { // The biomes stored don't match in size - return NULL; + return nullptr; } const unsigned char * VanillaBiomeData = (const unsigned char *)(a_NBT.GetData(a_TagIdx)); for (size_t i = 0; i < ARRAYCOUNT(*a_BiomeMap); i++) @@ -538,7 +538,7 @@ cChunkDef::BiomeMap * cWSSAnvil::LoadVanillaBiomeMapFromNBT(cChunkDef::BiomeMap if ((VanillaBiomeData)[i] == 0xff) { // Unassigned biomes - return NULL; + return nullptr; } (*a_BiomeMap)[i] = (EMCSBiome)(VanillaBiomeData[i]); } @@ -553,12 +553,12 @@ cChunkDef::BiomeMap * cWSSAnvil::LoadBiomeMapFromNBT(cChunkDef::BiomeMap * a_Bio { if ((a_TagIdx < 0) || (a_NBT.GetType(a_TagIdx) != TAG_IntArray)) { - return NULL; + return nullptr; } if (a_NBT.GetDataLength(a_TagIdx) != sizeof(*a_BiomeMap)) { // The biomes stored don't match in size - return NULL; + return nullptr; } const char * BiomeData = (a_NBT.GetData(a_TagIdx)); for (size_t i = 0; i < ARRAYCOUNT(*a_BiomeMap); i++) @@ -567,7 +567,7 @@ cChunkDef::BiomeMap * cWSSAnvil::LoadBiomeMapFromNBT(cChunkDef::BiomeMap * a_Bio if ((*a_BiomeMap)[i] == 0xff) { // Unassigned biomes - return NULL; + return nullptr; } } return a_BiomeMap; @@ -631,7 +631,7 @@ void cWSSAnvil::LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntities, con BLOCKTYPE BlockType = cChunkDef::GetBlock(a_BlockTypes, RelX, RelY, RelZ); NIBBLETYPE BlockMeta = cChunkDef::GetNibble(a_BlockMetas, RelX, RelY, RelZ); std::auto_ptr be(LoadBlockEntityFromNBT(a_NBT, Child, x, y, z, BlockType, BlockMeta)); - if (be.get() == NULL) + if (be.get() == nullptr) { continue; } @@ -670,7 +670,7 @@ cBlockEntity * cWSSAnvil::LoadBlockEntityFromNBT(const cParsedNBT & a_NBT, int a case E_BLOCK_WALLSIGN: return LoadSignFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_WALLSIGN); // Blocktypes that have block entities but don't load their contents from disk: - case E_BLOCK_ENDER_CHEST: return NULL; + case E_BLOCK_ENDER_CHEST: return nullptr; } // All the other blocktypes should have no entities assigned to them. Report an error: @@ -686,7 +686,7 @@ cBlockEntity * cWSSAnvil::LoadBlockEntityFromNBT(const cParsedNBT & a_NBT, int a ItemTypeToString(a_BlockType).c_str(), a_BlockType, TypeName.c_str(), a_BlockX, a_BlockY, a_BlockZ ); - return NULL; + return nullptr; } @@ -836,7 +836,7 @@ cBlockEntity * cWSSAnvil::LoadBeaconFromNBT(const cParsedNBT & a_NBT, int a_TagI // Check if the data has a proper type: if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Beacon")) { - return NULL; + return nullptr; } std::auto_ptr Beacon(new cBeaconEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); @@ -881,13 +881,13 @@ cBlockEntity * cWSSAnvil::LoadChestFromNBT(const cParsedNBT & a_NBT, int a_TagId // https://github.com/mc-server/MCServer/blob/d0551e2e0a98a28f31a88d489d17b408e4a7d38d/src/WorldStorage/WSSAnvil.cpp#L637 if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Chest") && !CheckBlockEntityType(a_NBT, a_TagIdx, "TrappedChest")) { - return NULL; + return nullptr; } int Items = a_NBT.FindChildByName(a_TagIdx, "Items"); if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List)) { - return NULL; // Make it an empty chest - the chunk loader will provide an empty cChestEntity for this + return nullptr; // Make it an empty chest - the chunk loader will provide an empty cChestEntity for this } std::auto_ptr Chest(new cChestEntity(a_BlockX, a_BlockY, a_BlockZ, m_World, a_ChestBlockType)); LoadItemGridFromNBT(Chest->GetContents(), a_NBT, Items); @@ -903,7 +903,7 @@ cBlockEntity * cWSSAnvil::LoadCommandBlockFromNBT(const cParsedNBT & a_NBT, int // Check if the data has a proper type: if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Control")) { - return NULL; + return nullptr; } std::auto_ptr CmdBlock(new cCommandBlockEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); @@ -940,13 +940,13 @@ cBlockEntity * cWSSAnvil::LoadDispenserFromNBT(const cParsedNBT & a_NBT, int a_T // Check if the data has a proper type: if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Trap")) { - return NULL; + return nullptr; } int Items = a_NBT.FindChildByName(a_TagIdx, "Items"); if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List)) { - return NULL; // Make it an empty dispenser - the chunk loader will provide an empty cDispenserEntity for this + return nullptr; // Make it an empty dispenser - the chunk loader will provide an empty cDispenserEntity for this } std::auto_ptr Dispenser(new cDispenserEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); LoadItemGridFromNBT(Dispenser->GetContents(), a_NBT, Items); @@ -962,13 +962,13 @@ cBlockEntity * cWSSAnvil::LoadDropperFromNBT(const cParsedNBT & a_NBT, int a_Tag // Check if the data has a proper type: if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Dropper")) { - return NULL; + return nullptr; } int Items = a_NBT.FindChildByName(a_TagIdx, "Items"); if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List)) { - return NULL; // Make it an empty dropper - the chunk loader will provide an empty cDropperEntity for this + return nullptr; // Make it an empty dropper - the chunk loader will provide an empty cDropperEntity for this } std::auto_ptr Dropper(new cDropperEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); LoadItemGridFromNBT(Dropper->GetContents(), a_NBT, Items); @@ -984,7 +984,7 @@ cBlockEntity * cWSSAnvil::LoadFlowerPotFromNBT(const cParsedNBT & a_NBT, int a_T // Check if the data has a proper type: if (!CheckBlockEntityType(a_NBT, a_TagIdx, "FlowerPot")) { - return NULL; + return nullptr; } std::auto_ptr FlowerPot(new cFlowerPotEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); @@ -1015,13 +1015,13 @@ cBlockEntity * cWSSAnvil::LoadFurnaceFromNBT(const cParsedNBT & a_NBT, int a_Tag // Check if the data has a proper type: if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Furnace")) { - return NULL; + return nullptr; } int Items = a_NBT.FindChildByName(a_TagIdx, "Items"); if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List)) { - return NULL; // Make it an empty furnace - the chunk loader will provide an empty cFurnaceEntity for this + return nullptr; // Make it an empty furnace - the chunk loader will provide an empty cFurnaceEntity for this } std::auto_ptr Furnace(new cFurnaceEntity(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, m_World)); @@ -1073,13 +1073,13 @@ cBlockEntity * cWSSAnvil::LoadHopperFromNBT(const cParsedNBT & a_NBT, int a_TagI // Check if the data has a proper type: if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Hopper")) { - return NULL; + return nullptr; } int Items = a_NBT.FindChildByName(a_TagIdx, "Items"); if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List)) { - return NULL; // Make it an empty hopper - the chunk loader will provide an empty cHopperEntity for this + return nullptr; // Make it an empty hopper - the chunk loader will provide an empty cHopperEntity for this } std::auto_ptr Hopper(new cHopperEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); LoadItemGridFromNBT(Hopper->GetContents(), a_NBT, Items); @@ -1095,7 +1095,7 @@ cBlockEntity * cWSSAnvil::LoadJukeboxFromNBT(const cParsedNBT & a_NBT, int a_Tag // Check if the data has a proper type: if (!CheckBlockEntityType(a_NBT, a_TagIdx, "RecordPlayer")) { - return NULL; + return nullptr; } std::auto_ptr Jukebox(new cJukeboxEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); @@ -1116,7 +1116,7 @@ cBlockEntity * cWSSAnvil::LoadMobHeadFromNBT(const cParsedNBT & a_NBT, int a_Tag // Check if the data has a proper type: if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Skull")) { - return NULL; + return nullptr; } std::auto_ptr MobHead(new cMobHeadEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); @@ -1151,7 +1151,7 @@ cBlockEntity * cWSSAnvil::LoadNoteBlockFromNBT(const cParsedNBT & a_NBT, int a_T // Check if the data has a proper type: if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Music")) { - return NULL; + return nullptr; } std::auto_ptr NoteBlock(new cNoteEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); @@ -1172,7 +1172,7 @@ cBlockEntity * cWSSAnvil::LoadSignFromNBT(const cParsedNBT & a_NBT, int a_TagIdx // Check if the data has a proper type: if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Sign")) { - return NULL; + return nullptr; } std::auto_ptr Sign(new cSignEntity(a_BlockType, a_BlockX, a_BlockY, a_BlockZ, m_World)); @@ -1744,7 +1744,7 @@ void cWSSAnvil::LoadItemFrameFromNBT(cEntityList & a_Entities, const cParsedNBT void cWSSAnvil::LoadArrowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr Arrow(new cArrowEntity(NULL, 0, 0, 0, Vector3d(0, 0, 0))); + std::auto_ptr Arrow(new cArrowEntity(nullptr, 0, 0, 0, Vector3d(0, 0, 0))); if (!LoadProjectileBaseFromNBT(*Arrow.get(), a_NBT, a_TagIdx)) { return; @@ -1808,7 +1808,7 @@ void cWSSAnvil::LoadArrowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ void cWSSAnvil::LoadSplashPotionFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr SplashPotion(new cSplashPotionEntity(NULL, 0, 0, 0, Vector3d(0, 0, 0), cItem())); + std::auto_ptr SplashPotion(new cSplashPotionEntity(nullptr, 0, 0, 0, Vector3d(0, 0, 0), cItem())); if (!LoadProjectileBaseFromNBT(*SplashPotion.get(), a_NBT, a_TagIdx)) { return; @@ -1832,7 +1832,7 @@ void cWSSAnvil::LoadSplashPotionFromNBT(cEntityList & a_Entities, const cParsedN void cWSSAnvil::LoadSnowballFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr Snowball(new cThrownSnowballEntity(NULL, 0, 0, 0, Vector3d(0, 0, 0))); + std::auto_ptr Snowball(new cThrownSnowballEntity(nullptr, 0, 0, 0, Vector3d(0, 0, 0))); if (!LoadProjectileBaseFromNBT(*Snowball.get(), a_NBT, a_TagIdx)) { return; @@ -1848,7 +1848,7 @@ void cWSSAnvil::LoadSnowballFromNBT(cEntityList & a_Entities, const cParsedNBT & void cWSSAnvil::LoadEggFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr Egg(new cThrownEggEntity(NULL, 0, 0, 0, Vector3d(0, 0, 0))); + std::auto_ptr Egg(new cThrownEggEntity(nullptr, 0, 0, 0, Vector3d(0, 0, 0))); if (!LoadProjectileBaseFromNBT(*Egg.get(), a_NBT, a_TagIdx)) { return; @@ -1864,7 +1864,7 @@ void cWSSAnvil::LoadEggFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NB void cWSSAnvil::LoadFireballFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr Fireball(new cGhastFireballEntity(NULL, 0, 0, 0, Vector3d(0, 0, 0))); + std::auto_ptr Fireball(new cGhastFireballEntity(nullptr, 0, 0, 0, Vector3d(0, 0, 0))); if (!LoadProjectileBaseFromNBT(*Fireball.get(), a_NBT, a_TagIdx)) { return; @@ -1880,7 +1880,7 @@ void cWSSAnvil::LoadFireballFromNBT(cEntityList & a_Entities, const cParsedNBT & void cWSSAnvil::LoadFireChargeFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr FireCharge(new cFireChargeEntity(NULL, 0, 0, 0, Vector3d(0, 0, 0))); + std::auto_ptr FireCharge(new cFireChargeEntity(nullptr, 0, 0, 0, Vector3d(0, 0, 0))); if (!LoadProjectileBaseFromNBT(*FireCharge.get(), a_NBT, a_TagIdx)) { return; @@ -1896,7 +1896,7 @@ void cWSSAnvil::LoadFireChargeFromNBT(cEntityList & a_Entities, const cParsedNBT void cWSSAnvil::LoadThrownEnderpearlFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr Enderpearl(new cThrownEnderPearlEntity(NULL, 0, 0, 0, Vector3d(0, 0, 0))); + std::auto_ptr Enderpearl(new cThrownEnderPearlEntity(nullptr, 0, 0, 0, Vector3d(0, 0, 0))); if (!LoadProjectileBaseFromNBT(*Enderpearl.get(), a_NBT, a_TagIdx)) { return; @@ -2853,7 +2853,7 @@ bool cWSSAnvil::cMCAFile::OpenFile(bool a_IsForReading) if (m_File.Read(m_Header, sizeof(m_Header)) != sizeof(m_Header)) { // Cannot read the header - perhaps the file has just been created? - // Try writing a NULL header (both chunk offsets and timestamps): + // Try writing a nullptr header (both chunk offsets and timestamps): memset(m_Header, 0, sizeof(m_Header)); if ( (m_File.Write(m_Header, sizeof(m_Header)) != sizeof(m_Header)) || // Real header - chunk offsets diff --git a/src/WorldStorage/WSSAnvil.h b/src/WorldStorage/WSSAnvil.h index 591ec6757..9c579a617 100644 --- a/src/WorldStorage/WSSAnvil.h +++ b/src/WorldStorage/WSSAnvil.h @@ -113,10 +113,10 @@ protected: /// Saves the chunk into NBT data using a_Writer; returns true on success bool SaveChunkToNBT(const cChunkCoords & a_Chunk, cFastNBTWriter & a_Writer); - /// Loads the chunk's biome map from vanilla-format; returns a_BiomeMap if biomes present and valid, NULL otherwise + /// Loads the chunk's biome map from vanilla-format; returns a_BiomeMap if biomes present and valid, nullptr otherwise cChunkDef::BiomeMap * LoadVanillaBiomeMapFromNBT(cChunkDef::BiomeMap * a_BiomeMap, const cParsedNBT & a_NBT, int a_TagIdx); - /// Loads the chunk's biome map from MCS format; returns a_BiomeMap if biomes present and valid, NULL otherwise + /// Loads the chunk's biome map from MCS format; returns a_BiomeMap if biomes present and valid, nullptr otherwise cChunkDef::BiomeMap * LoadBiomeMapFromNBT(cChunkDef::BiomeMap * a_BiomeMap, const cParsedNBT & a_NBT, int a_TagIdx); /// Loads the chunk's entities from NBT data (a_Tag is the Level\\Entities list tag; may be -1) @@ -126,7 +126,7 @@ protected: void LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntitites, const cParsedNBT & a_NBT, int a_Tag, BLOCKTYPE * a_BlockTypes, NIBBLETYPE * a_BlockMetas); /** Loads the data for a block entity from the specified NBT tag. - Returns the loaded block entity, or NULL upon failure. */ + Returns the loaded block entity, or nullptr upon failure. */ cBlockEntity * LoadBlockEntityFromNBT(const cParsedNBT & a_NBT, int a_Tag, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); /// Loads a cItem contents from the specified NBT tag; returns true if successful. Doesn't load the Slot tag diff --git a/src/WorldStorage/WorldStorage.cpp b/src/WorldStorage/WorldStorage.cpp index c611bfd90..31318ee67 100644 --- a/src/WorldStorage/WorldStorage.cpp +++ b/src/WorldStorage/WorldStorage.cpp @@ -39,8 +39,8 @@ protected: cWorldStorage::cWorldStorage(void) : super("cWorldStorage"), - m_World(NULL), - m_SaveSchema(NULL) + m_World(nullptr), + m_SaveSchema(nullptr) { } diff --git a/src/XMLParser.h b/src/XMLParser.h index e39405529..5b53e55cf 100644 --- a/src/XMLParser.h +++ b/src/XMLParser.h @@ -68,7 +68,7 @@ protected: 3, Create an instance of your class: CMyParser Parser; 4, Call Create(): - Parser.Create(NULL, NULL); + Parser.Create(nullptr, nullptr); 4, Call Parse(), repeatedly: Parser.Parse(Buffer, Length); */ @@ -84,7 +84,7 @@ public: CExpatImpl () { - m_p = NULL; + m_p = nullptr; } // @cmember Destructor @@ -99,24 +99,24 @@ public: // @cmember Create a parser - bool Create (const XML_Char * pszEncoding = NULL, const XML_Char * pszSep = NULL) + bool Create (const XML_Char * pszEncoding = nullptr, const XML_Char * pszSep = nullptr) { // Destroy the old parser Destroy (); - // If the encoding or seperator are empty, then NULL - if (pszEncoding != NULL && pszEncoding [0] == 0) + // If the encoding or seperator are empty, then nullptr + if (pszEncoding != nullptr && pszEncoding [0] == 0) { - pszEncoding = NULL; + pszEncoding = nullptr; } - if (pszSep != NULL && pszSep [0] == 0) + if (pszSep != nullptr && pszSep [0] == 0) { - pszSep = NULL; + pszSep = nullptr; } // Create the new parser - m_p = XML_ParserCreate_MM (pszEncoding, NULL, pszSep); - if (m_p == NULL) + m_p = XML_ParserCreate_MM (pszEncoding, nullptr, pszSep); + if (m_p == nullptr) { return false; } @@ -134,11 +134,11 @@ public: void Destroy (void) { - if (m_p != NULL) + if (m_p != nullptr) { XML_ParserFree (m_p); } - m_p = NULL; + m_p = nullptr; } @@ -146,7 +146,7 @@ public: bool Parse (const char *pszBuffer, int nLength, bool fIsFinal = true) { - assert (m_p != NULL); + assert (m_p != nullptr); return XML_Parse (m_p, pszBuffer, nLength, fIsFinal) != 0; } @@ -154,7 +154,7 @@ public: bool ParseBuffer (int nLength, bool fIsFinal = true) { - assert (m_p != NULL); + assert (m_p != nullptr); return XML_ParseBuffer (m_p, nLength, fIsFinal) != 0; } @@ -162,7 +162,7 @@ public: void *GetBuffer (int nLength) { - assert (m_p != NULL); + assert (m_p != nullptr); return XML_GetBuffer (m_p, nLength); } @@ -174,23 +174,23 @@ protected: void EnableStartElementHandler (bool fEnable = true) { - assert (m_p != NULL); - XML_SetStartElementHandler (m_p, fEnable ? StartElementHandler : NULL); + assert (m_p != nullptr); + XML_SetStartElementHandler (m_p, fEnable ? StartElementHandler : nullptr); } // @cmember Enable/Disable the end element handler void EnableEndElementHandler (bool fEnable = true) { - assert (m_p != NULL); - XML_SetEndElementHandler (m_p, fEnable ? EndElementHandler : NULL); + assert (m_p != nullptr); + XML_SetEndElementHandler (m_p, fEnable ? EndElementHandler : nullptr); } // @cmember Enable/Disable the element handlers void EnableElementHandler (bool fEnable = true) { - assert (m_p != NULL); + assert (m_p != nullptr); EnableStartElementHandler (fEnable); EnableEndElementHandler (fEnable); } @@ -199,47 +199,47 @@ protected: void EnableCharacterDataHandler (bool fEnable = true) { - assert (m_p != NULL); - XML_SetCharacterDataHandler (m_p, fEnable ? CharacterDataHandler : NULL); + assert (m_p != nullptr); + XML_SetCharacterDataHandler (m_p, fEnable ? CharacterDataHandler : nullptr); } // @cmember Enable/Disable the processing instruction handler void EnableProcessingInstructionHandler (bool fEnable = true) { - assert (m_p != NULL); - XML_SetProcessingInstructionHandler (m_p, fEnable ? ProcessingInstructionHandler : NULL); + assert (m_p != nullptr); + XML_SetProcessingInstructionHandler (m_p, fEnable ? ProcessingInstructionHandler : nullptr); } // @cmember Enable/Disable the comment handler void EnableCommentHandler (bool fEnable = true) { - assert (m_p != NULL); - XML_SetCommentHandler (m_p, fEnable ? CommentHandler : NULL); + assert (m_p != nullptr); + XML_SetCommentHandler (m_p, fEnable ? CommentHandler : nullptr); } // @cmember Enable/Disable the start CDATA section handler void EnableStartCdataSectionHandler (bool fEnable = true) { - assert (m_p != NULL); - XML_SetStartCdataSectionHandler (m_p, fEnable ? StartCdataSectionHandler : NULL); + assert (m_p != nullptr); + XML_SetStartCdataSectionHandler (m_p, fEnable ? StartCdataSectionHandler : nullptr); } // @cmember Enable/Disable the end CDATA section handler void EnableEndCdataSectionHandler (bool fEnable = true) { - assert (m_p != NULL); - XML_SetEndCdataSectionHandler (m_p, fEnable ? EndCdataSectionHandler : NULL); + assert (m_p != nullptr); + XML_SetEndCdataSectionHandler (m_p, fEnable ? EndCdataSectionHandler : nullptr); } // @cmember Enable/Disable the CDATA section handlers void EnableCdataSectionHandler (bool fEnable = true) { - assert (m_p != NULL); + assert (m_p != nullptr); EnableStartCdataSectionHandler (fEnable); EnableEndCdataSectionHandler (fEnable); } @@ -248,45 +248,45 @@ protected: void EnableDefaultHandler (bool fEnable = true, bool fExpand = true) { - assert (m_p != NULL); + assert (m_p != nullptr); if (fExpand) { - XML_SetDefaultHandlerExpand (m_p, fEnable ? DefaultHandler : NULL); + XML_SetDefaultHandlerExpand (m_p, fEnable ? DefaultHandler : nullptr); } else - XML_SetDefaultHandler (m_p, fEnable ? DefaultHandler : NULL); + XML_SetDefaultHandler (m_p, fEnable ? DefaultHandler : nullptr); } // @cmember Enable/Disable external entity ref handler void EnableExternalEntityRefHandler (bool fEnable = true) { - assert (m_p != NULL); - XML_SetExternalEntityRefHandler (m_p, fEnable ? ExternalEntityRefHandler : NULL); + assert (m_p != nullptr); + XML_SetExternalEntityRefHandler (m_p, fEnable ? ExternalEntityRefHandler : nullptr); } // @cmember Enable/Disable unknown encoding handler void EnableUnknownEncodingHandler (bool fEnable = true) { - assert (m_p != NULL); - XML_SetUnknownEncodingHandler (m_p, fEnable ? UnknownEncodingHandler : NULL); + assert (m_p != nullptr); + XML_SetUnknownEncodingHandler (m_p, fEnable ? UnknownEncodingHandler : nullptr); } // @cmember Enable/Disable start namespace handler void EnableStartNamespaceDeclHandler (bool fEnable = true) { - assert (m_p != NULL); - XML_SetStartNamespaceDeclHandler (m_p, fEnable ? StartNamespaceDeclHandler : NULL); + assert (m_p != nullptr); + XML_SetStartNamespaceDeclHandler (m_p, fEnable ? StartNamespaceDeclHandler : nullptr); } // @cmember Enable/Disable end namespace handler void EnableEndNamespaceDeclHandler (bool fEnable = true) { - assert (m_p != NULL); - XML_SetEndNamespaceDeclHandler (m_p, fEnable ? EndNamespaceDeclHandler : NULL); + assert (m_p != nullptr); + XML_SetEndNamespaceDeclHandler (m_p, fEnable ? EndNamespaceDeclHandler : nullptr); } // @cmember Enable/Disable namespace handlers @@ -301,32 +301,32 @@ protected: void EnableXmlDeclHandler (bool fEnable = true) { - assert (m_p != NULL); - XML_SetXmlDeclHandler (m_p, fEnable ? XmlDeclHandler : NULL); + assert (m_p != nullptr); + XML_SetXmlDeclHandler (m_p, fEnable ? XmlDeclHandler : nullptr); } // @cmember Enable/Disable the start DOCTYPE declaration handler void EnableStartDoctypeDeclHandler (bool fEnable = true) { - assert (m_p != NULL); - XML_SetStartDoctypeDeclHandler (m_p, fEnable ? StartDoctypeDeclHandler : NULL); + assert (m_p != nullptr); + XML_SetStartDoctypeDeclHandler (m_p, fEnable ? StartDoctypeDeclHandler : nullptr); } // @cmember Enable/Disable the end DOCTYPE declaration handler void EnableEndDoctypeDeclHandler (bool fEnable = true) { - assert (m_p != NULL); + assert (m_p != nullptr); XML_SetEndDoctypeDeclHandler (m_p, - fEnable ? EndDoctypeDeclHandler : NULL); + fEnable ? EndDoctypeDeclHandler : nullptr); } // @cmember Enable/Disable the DOCTYPE declaration handler void EnableDoctypeDeclHandler (bool fEnable = true) { - assert (m_p != NULL); + assert (m_p != nullptr); EnableStartDoctypeDeclHandler (fEnable); EnableEndDoctypeDeclHandler (fEnable); } @@ -338,7 +338,7 @@ public: enum XML_Error GetErrorCode () { - assert (m_p != NULL); + assert (m_p != nullptr); return XML_GetErrorCode (m_p); } @@ -346,7 +346,7 @@ public: long GetCurrentByteIndex () { - assert (m_p != NULL); + assert (m_p != nullptr); return XML_GetCurrentByteIndex (m_p); } @@ -354,7 +354,7 @@ public: int GetCurrentLineNumber () { - assert (m_p != NULL); + assert (m_p != nullptr); return XML_GetCurrentLineNumber (m_p); } @@ -362,7 +362,7 @@ public: int GetCurrentColumnNumber () { - assert (m_p != NULL); + assert (m_p != nullptr); return XML_GetCurrentColumnNumber (m_p); } @@ -370,7 +370,7 @@ public: int GetCurrentByteCount () { - assert (m_p != NULL); + assert (m_p != nullptr); return XML_GetCurrentByteCount (m_p); } @@ -378,7 +378,7 @@ public: const char *GetInputContext (int *pnOffset, int *pnSize) { - assert (m_p != NULL); + assert (m_p != nullptr); return XML_GetInputContext (m_p, pnOffset, pnSize); } @@ -682,17 +682,17 @@ protected: XML_Parser m_p; - /// Returns the value of the specified attribute, if found; NULL otherwise + /// Returns the value of the specified attribute, if found; nullptr otherwise static const XML_Char * FindAttr(const XML_Char ** iAttrs, const XML_Char * iAttrToFind) { - for (const XML_Char ** Attr = iAttrs; *Attr != NULL; Attr += 2) + for (const XML_Char ** Attr = iAttrs; *Attr != nullptr; Attr += 2) { if (strcmp(*Attr, iAttrToFind) == 0) { return *(Attr + 1); } } // for Attr - iAttrs[] - return NULL; + return nullptr; } } ; diff --git a/src/main.cpp b/src/main.cpp index b1cfd6976..5391fa9c9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -133,8 +133,8 @@ LONG WINAPI LastChanceExceptionFilter(__in struct _EXCEPTION_POINTERS * a_Except ExcInformation.ClientPointers = 0; // Write the dump file: - HANDLE dumpFile = CreateFile(g_DumpFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - g_WriteMiniDump(GetCurrentProcess(), GetCurrentProcessId(), dumpFile, g_DumpFlags, (a_ExceptionInfo) ? &ExcInformation : NULL, NULL, NULL); + HANDLE dumpFile = CreateFile(g_DumpFileName, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); + g_WriteMiniDump(GetCurrentProcess(), GetCurrentProcessId(), dumpFile, g_DumpFlags, (a_ExceptionInfo) ? &ExcInformation : nullptr, nullptr, nullptr); CloseHandle(dumpFile); // Revert to old stack: @@ -190,7 +190,7 @@ int main( int argc, char **argv) #if defined(_WIN32) && !defined(_WIN64) && defined(_MSC_VER) HINSTANCE hDbgHelp = LoadLibrary("DBGHELP.DLL"); g_WriteMiniDump = (pMiniDumpWriteDump)GetProcAddress(hDbgHelp, "MiniDumpWriteDump"); - if (g_WriteMiniDump != NULL) + if (g_WriteMiniDump != nullptr) { _snprintf_s(g_DumpFileName, ARRAYCOUNT(g_DumpFileName), _TRUNCATE, "crash_mcs_%x.dmp", GetCurrentProcessId()); SetUnhandledExceptionFilter(LastChanceExceptionFilter); @@ -272,7 +272,7 @@ int main( int argc, char **argv) } else if (NoCaseCompare(Arg, "nooutbuf") == 0) { - setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stdout, nullptr, _IONBF, 0); } } // for i - argv[] -- cgit v1.2.3 From 5089f04cf67dfc3598ff8b714b452a66093625b0 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 21 Oct 2014 13:20:06 +0100 Subject: Replace &*[0] accesses with .data() --- src/UI/SlotArea.cpp | 4 ++-- src/WorldStorage/FireworksSerializer.cpp | 8 ++++---- src/WorldStorage/MapSerializer.cpp | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/UI/SlotArea.cpp b/src/UI/SlotArea.cpp index 9113ec343..f5c409e6c 100644 --- a/src/UI/SlotArea.cpp +++ b/src/UI/SlotArea.cpp @@ -2321,8 +2321,8 @@ cItem * cSlotAreaTemporary::GetPlayerSlots(cPlayer & a_Player) if (itr == m_Items.end()) { return nullptr; - } - return &(itr->second[0]); + } + return itr->second.data(); } diff --git a/src/WorldStorage/FireworksSerializer.cpp b/src/WorldStorage/FireworksSerializer.cpp index ecb600483..91a5b8b63 100644 --- a/src/WorldStorage/FireworksSerializer.cpp +++ b/src/WorldStorage/FireworksSerializer.cpp @@ -22,11 +22,11 @@ void cFireworkItem::WriteToNBTCompound(const cFireworkItem & a_FireworkItem, cFa a_Writer.AddByte("Type", a_FireworkItem.m_Type); if (!a_FireworkItem.m_Colours.empty()) { - a_Writer.AddIntArray("Colors", &(a_FireworkItem.m_Colours[0]), a_FireworkItem.m_Colours.size()); + a_Writer.AddIntArray("Colors", a_FireworkItem.m_Colours.data(), a_FireworkItem.m_Colours.size()); } if (!a_FireworkItem.m_FadeColours.empty()) { - a_Writer.AddIntArray("FadeColors", &(a_FireworkItem.m_FadeColours[0]), a_FireworkItem.m_FadeColours.size()); + a_Writer.AddIntArray("FadeColors", a_FireworkItem.m_FadeColours.data(), a_FireworkItem.m_FadeColours.size()); } a_Writer.EndCompound(); a_Writer.EndList(); @@ -41,11 +41,11 @@ void cFireworkItem::WriteToNBTCompound(const cFireworkItem & a_FireworkItem, cFa a_Writer.AddByte("Type", a_FireworkItem.m_Type); if (!a_FireworkItem.m_Colours.empty()) { - a_Writer.AddIntArray("Colors", &(a_FireworkItem.m_Colours[0]), a_FireworkItem.m_Colours.size()); + a_Writer.AddIntArray("Colors", a_FireworkItem.m_Colours.data(), a_FireworkItem.m_Colours.size()); } if (!a_FireworkItem.m_FadeColours.empty()) { - a_Writer.AddIntArray("FadeColors", &(a_FireworkItem.m_FadeColours[0]), a_FireworkItem.m_FadeColours.size()); + a_Writer.AddIntArray("FadeColors", a_FireworkItem.m_FadeColours.data(), a_FireworkItem.m_FadeColours.size()); } a_Writer.EndCompound(); break; diff --git a/src/WorldStorage/MapSerializer.cpp b/src/WorldStorage/MapSerializer.cpp index 4a913c81a..f2d35b318 100644 --- a/src/WorldStorage/MapSerializer.cpp +++ b/src/WorldStorage/MapSerializer.cpp @@ -112,7 +112,7 @@ void cMapSerializer::SaveMapToNBT(cFastNBTWriter & a_Writer) a_Writer.AddInt("zCenter", m_Map->GetCenterZ()); const cMap::cColorList & Data = m_Map->GetData(); - a_Writer.AddByteArray("colors", (char *) &Data[0], Data.size()); + a_Writer.AddByteArray("colors", (char *)Data.data(), Data.size()); a_Writer.EndCompound(); } @@ -190,7 +190,7 @@ bool cMapSerializer::LoadMapFromNBT(const cParsedNBT & a_NBT) CurrLine = a_NBT.FindChildByName(Data, "colors"); if ((CurrLine >= 0) && (a_NBT.GetType(CurrLine) == TAG_ByteArray)) { - memcpy(&m_Map->m_Data[0], a_NBT.GetData(CurrLine), NumPixels); + memcpy(m_Map->m_Data.data(), a_NBT.GetData(CurrLine), NumPixels); } return true; -- cgit v1.2.3 From 014ebb7fe641d14fd5f2d9d65ec336f5bf98b7f5 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 21 Oct 2014 13:41:08 +0100 Subject: Windows close handlers handles more closes --- src/main.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 5391fa9c9..b6ee8c0a7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -158,12 +158,9 @@ BOOL CtrlHandler(DWORD fdwCtrlType) cRoot::m_TerminateEventRaised = true; LOGD("Terminate event raised from the Windows CtrlHandler"); - if (fdwCtrlType == CTRL_CLOSE_EVENT) // Console window closed via 'x' button, Windows will try to close immediately, therefore... + while (!g_ServerTerminated) { - while (!g_ServerTerminated) - { - std::this_thread::sleep_for(std::chrono::milliseconds(50)); // Delay as much as possible to try to get the server to shut down cleanly - } + std::this_thread::sleep_for(std::chrono::milliseconds(50)); // Delay as much as possible to try to get the server to shut down cleanly } return TRUE; -- cgit v1.2.3 From 2b920f9e2154f48e3838a073d79713716bce748d Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 21 Oct 2014 13:49:53 +0100 Subject: Compile fix? --- src/CMakeLists.txt | 2 -- src/OSSupport/CMakeLists.txt | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e322b842b..31e3bb362 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -31,7 +31,6 @@ SET (SRCS Cuboid.cpp DeadlockDetect.cpp Enchantments.cpp - FastRandom.cpp FurnaceRecipe.cpp Globals.cpp Inventory.cpp @@ -94,7 +93,6 @@ SET (HDRS Defines.h Enchantments.h Endianness.h - FastRandom.h ForEachChunkProvider.h FurnaceRecipe.h Globals.h diff --git a/src/OSSupport/CMakeLists.txt b/src/OSSupport/CMakeLists.txt index 45df0c1a3..29cf440ca 100644 --- a/src/OSSupport/CMakeLists.txt +++ b/src/OSSupport/CMakeLists.txt @@ -15,7 +15,7 @@ SET (SRCS Semaphore.cpp Socket.cpp SocketThreads.cpp - Timer.cpp) +) SET (HDRS CriticalSection.h @@ -29,7 +29,7 @@ SET (HDRS Semaphore.h Socket.h SocketThreads.h - Timer.h) +) if(NOT MSVC) add_library(OSSupport ${SRCS} ${HDRS}) -- cgit v1.2.3 From 8ddc40e44baa382f3601537418a96b06a84ffe6d Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Tue, 21 Oct 2014 14:17:04 +0100 Subject: Missing space fix. --- src/World.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/World.cpp b/src/World.cpp index c6168b572..65f607ee0 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -212,7 +212,7 @@ void cWorld::cTickThread::Execute(void) if (TickTime < msPerTick) { // Stretch tick time until it's at least msPerTick - std::this_thread::sleep_for(msPerTick -TickTime); + std::this_thread::sleep_for(msPerTick - TickTime); } LastTime = NowTime; -- cgit v1.2.3 From 3e0f7c2b1c9b371307a570e445d0178599abd92d Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Tue, 21 Oct 2014 14:17:36 +0100 Subject: Missing space. --- src/Server.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Server.cpp b/src/Server.cpp index 11da36868..6f7d494be 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -84,7 +84,7 @@ void cServer::cTickThread::Execute(void) if (TickTime < msPerTick) { // Stretch tick time until it's at least msPerTick - std::this_thread::sleep_for(msPerTick -TickTime); + std::this_thread::sleep_for(msPerTick - TickTime); } LastTime = NowTime; -- cgit v1.2.3 From 8299b0920f6b73145faf849fea9f2e6927e63b77 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Tue, 21 Oct 2014 14:19:58 +0100 Subject: Alignment. --- src/Noise.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Noise.h b/src/Noise.h index b7a90d5b7..9a3f24556 100644 --- a/src/Noise.h +++ b/src/Noise.h @@ -155,7 +155,7 @@ public: NOISE_DATATYPE * a_Array, ///< Array to generate into int a_SizeX, ///< Count of the array NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array - NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash + NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash ) const; @@ -164,7 +164,7 @@ public: int a_SizeX, int a_SizeY, ///< Count of the array, in each direction NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction - NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash + NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash ) const; @@ -174,7 +174,7 @@ public: NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction NOISE_DATATYPE a_StartZ, NOISE_DATATYPE a_EndZ, ///< Noise-space coords of the array in the Z direction - NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash + NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash ) const; protected: @@ -219,7 +219,7 @@ public: NOISE_DATATYPE * a_Array, ///< Array to generate into int a_SizeX, ///< Count of the array NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array - NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash + NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash ) const; @@ -228,7 +228,7 @@ public: int a_SizeX, int a_SizeY, ///< Count of the array, in each direction NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction - NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash + NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash ) const; @@ -238,7 +238,7 @@ public: NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction NOISE_DATATYPE a_StartZ, NOISE_DATATYPE a_EndZ, ///< Noise-space coords of the array in the Z direction - NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash + NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash ) const; protected: -- cgit v1.2.3 From d0766fcea800db94941f46b3ef7449d91e50f554 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Tue, 21 Oct 2014 14:21:08 +0100 Subject: Missing EOL. --- src/FastRandom.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FastRandom.h b/src/FastRandom.h index 37d7f6eef..7eecc698a 100644 --- a/src/FastRandom.h +++ b/src/FastRandom.h @@ -80,4 +80,4 @@ private: std::mt19937 m_MersenneRand; std::uniform_int_distribution<> m_IntDistribution; std::uniform_real_distribution<> m_DoubleDistribution; -}; \ No newline at end of file +}; -- cgit v1.2.3 From 6a9f8a7615ab27d9619ba606c1fce5e2a3a6253d Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 21 Oct 2014 14:40:00 +0100 Subject: Compile fix? --- Tools/AnvilStats/CMakeLists.txt | 2 -- Tools/MCADefrag/CMakeLists.txt | 2 -- Tools/ProtoProxy/CMakeLists.txt | 2 -- 3 files changed, 6 deletions(-) diff --git a/Tools/AnvilStats/CMakeLists.txt b/Tools/AnvilStats/CMakeLists.txt index 557a4c17a..688fbe493 100644 --- a/Tools/AnvilStats/CMakeLists.txt +++ b/Tools/AnvilStats/CMakeLists.txt @@ -53,7 +53,6 @@ set(SHARED_OSS_SRC ../../src/OSSupport/File.cpp ../../src/OSSupport/GZipFile.cpp ../../src/OSSupport/IsThread.cpp - ../../src/OSSupport/Timer.cpp ) set(SHARED_OSS_HDR @@ -62,7 +61,6 @@ set(SHARED_OSS_HDR ../../src/OSSupport/File.h ../../src/OSSupport/GZipFile.h ../../src/OSSupport/IsThread.h - ../../src/OSSupport/Timer.h ) flatten_files(SHARED_SRC) diff --git a/Tools/MCADefrag/CMakeLists.txt b/Tools/MCADefrag/CMakeLists.txt index 42b42018b..ea345d87c 100644 --- a/Tools/MCADefrag/CMakeLists.txt +++ b/Tools/MCADefrag/CMakeLists.txt @@ -54,13 +54,11 @@ set(SHARED_OSS_SRC ../../src/OSSupport/CriticalSection.cpp ../../src/OSSupport/File.cpp ../../src/OSSupport/IsThread.cpp - ../../src/OSSupport/Timer.cpp ) set(SHARED_OSS_HDR ../../src/OSSupport/CriticalSection.h ../../src/OSSupport/File.h ../../src/OSSupport/IsThread.h - ../../src/OSSupport/Timer.h ) flatten_files(SHARED_OSS_SRC) diff --git a/Tools/ProtoProxy/CMakeLists.txt b/Tools/ProtoProxy/CMakeLists.txt index bc3923d90..b136a10ba 100644 --- a/Tools/ProtoProxy/CMakeLists.txt +++ b/Tools/ProtoProxy/CMakeLists.txt @@ -57,13 +57,11 @@ set(SHARED_OSS_SRC ../../src/OSSupport/CriticalSection.cpp ../../src/OSSupport/File.cpp ../../src/OSSupport/IsThread.cpp - ../../src/OSSupport/Timer.cpp ) set(SHARED_OSS_HDR ../../src/OSSupport/CriticalSection.h ../../src/OSSupport/File.h ../../src/OSSupport/IsThread.h - ../../src/OSSupport/Timer.h ) flatten_files(SHARED_SRC) flatten_files(SHARED_HDR) -- cgit v1.2.3 From 27687cfcd47289c9d9d2e7fdebc6e72db695f4d4 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 23 Oct 2014 08:41:57 +0200 Subject: Added FastRandom.* back to CMakeLists.txt. --- src/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 31e3bb362..e322b842b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -31,6 +31,7 @@ SET (SRCS Cuboid.cpp DeadlockDetect.cpp Enchantments.cpp + FastRandom.cpp FurnaceRecipe.cpp Globals.cpp Inventory.cpp @@ -93,6 +94,7 @@ SET (HDRS Defines.h Enchantments.h Endianness.h + FastRandom.h ForEachChunkProvider.h FurnaceRecipe.h Globals.h -- cgit v1.2.3 From 51fa6b4090ee930d03592550613592b1087fb788 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Thu, 23 Oct 2014 23:58:01 +0100 Subject: Suggestions --- src/DeadlockDetect.cpp | 2 +- src/Globals.h | 3 +-- src/OSSupport/CriticalSection.h | 1 + src/OSSupport/IsThread.cpp | 46 +++++++++++++++++++++++++++++++++++++++-- src/OSSupport/IsThread.h | 5 +---- src/Root.cpp | 2 +- src/Root.h | 1 + 7 files changed, 50 insertions(+), 10 deletions(-) diff --git a/src/DeadlockDetect.cpp b/src/DeadlockDetect.cpp index 81a328af8..3bb897221 100644 --- a/src/DeadlockDetect.cpp +++ b/src/DeadlockDetect.cpp @@ -14,7 +14,7 @@ /** Number of milliseconds per cycle */ -#define CYCLE_MILLISECONDS 100 +const int CYCLE_MILLISECONDS = 100; diff --git a/src/Globals.h b/src/Globals.h index 8658b49c4..15f5336d8 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -184,7 +184,7 @@ template class SizeChecker; #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN - #define _WIN32_WINNT 0x501 // We want to target WinXP and higher + #define _WIN32_WINNT_WS03 // We want to target Windows XP with Service Pack 2 & Windows Server 2003 with Service Pack 1 and higher #include #include @@ -239,7 +239,6 @@ template class SizeChecker; // STL stuff: -#include #include #include #include diff --git a/src/OSSupport/CriticalSection.h b/src/OSSupport/CriticalSection.h index 19e4f78af..17fcdfc12 100644 --- a/src/OSSupport/CriticalSection.h +++ b/src/OSSupport/CriticalSection.h @@ -1,6 +1,7 @@ #pragma once #include +#include diff --git a/src/OSSupport/IsThread.cpp b/src/OSSupport/IsThread.cpp index 94c867d19..02d8a77c7 100644 --- a/src/OSSupport/IsThread.cpp +++ b/src/OSSupport/IsThread.cpp @@ -11,6 +11,40 @@ +#if defined(_MSC_VER) && defined(_DEBUG) + // Code adapted from MSDN: http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx + + const DWORD MS_VC_EXCEPTION = 0x406D1388; + #pragma pack(push, 8) + struct THREADNAME_INFO + { + DWORD dwType; // Must be 0x1000. + LPCSTR szName; // Pointer to name (in user addr space). + DWORD dwThreadID; // Thread ID (-1 = caller thread). + DWORD dwFlags; // Reserved for future use, must be zero. + }; + #pragma pack(pop) + + /** Sets the name of a thread with the specified ID + (When in MSVC, the debugger provides "thread naming" by catching special exceptions) + */ + static void SetThreadName(std::thread * a_Thread, const char * a_ThreadName) + { + THREADNAME_INFO info { 0x1000, a_ThreadName, GetThreadId(a_Thread->native_handle()), 0 }; + __try + { + RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR *)&info); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + } + } +#endif // _MSC_VER && _DEBUG + + + + + //////////////////////////////////////////////////////////////////////////////// // cIsThread: @@ -39,11 +73,19 @@ bool cIsThread::Start(void) try { m_Thread = std::thread(&cIsThread::Execute, this); + + #if defined (_MSC_VER) && defined(_DEBUG) + if (!m_ThreadName.empty()) + { + SetThreadName(&m_Thread, m_ThreadName.c_str()); + } + #endif + return true; } catch (std::system_error & a_Exception) { - LOGERROR("ERROR: Could not create thread \"%s\", error = %s!", m_ThreadName.c_str(), a_Exception.code(), a_Exception.what()); + LOGERROR("cIsThread::Wait (std::thread) error %i: could not construct thread %s; %s", m_ThreadName.c_str(), a_Exception.code().value(), a_Exception.what()); return false; } } @@ -77,7 +119,7 @@ bool cIsThread::Wait(void) } catch (std::system_error & a_Exception) { - LOGERROR("ERROR: Could wait for thread \"%s\" to finish, error = %s!", m_ThreadName.c_str(), a_Exception.code(), a_Exception.what()); + LOGERROR("cIsThread::Wait (std::thread) error %i: could not join thread %s; %s", m_ThreadName.c_str(), a_Exception.code().value(), a_Exception.what()); return false; } } diff --git a/src/OSSupport/IsThread.h b/src/OSSupport/IsThread.h index 6aadaf447..131c6950e 100644 --- a/src/OSSupport/IsThread.h +++ b/src/OSSupport/IsThread.h @@ -16,8 +16,7 @@ In the descending class' constructor call the Start() method to start the thread #pragma once -#ifndef CISTHREAD_H_INCLUDED -#define CISTHREAD_H_INCLUDED +#include @@ -56,5 +55,3 @@ protected: - -#endif // CISTHREAD_H_INCLUDED diff --git a/src/Root.cpp b/src/Root.cpp index c951cb891..2a56a70be 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -193,7 +193,7 @@ void cRoot::Start(void) } catch (std::system_error & a_Exception) { - LOGERROR("ERROR: Could not create input thread, error = %s!", a_Exception.code(), a_Exception.what()); + LOGERROR("cRoot::Start (std::thread) error %i: could not construct input thread; %s", a_Exception.code().value(), a_Exception.what()); } #endif diff --git a/src/Root.h b/src/Root.h index c6bea4902..2860c1ce2 100644 --- a/src/Root.h +++ b/src/Root.h @@ -6,6 +6,7 @@ #include "HTTPServer/HTTPServer.h" #include "Defines.h" #include "RankManager.h" +#include -- cgit v1.2.3 From 9c7661f50f82fe265836f3279bf20b15aebba5b3 Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 30 Oct 2014 21:24:10 +0100 Subject: Added a MaxViewDistance option. --- src/ClientHandle.cpp | 4 +++- src/World.cpp | 3 +++ src/World.h | 10 ++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index faee05450..9b3bd9545 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -2847,7 +2847,9 @@ void cClientHandle::SetUsername( const AString & a_Username) void cClientHandle::SetViewDistance(int a_ViewDistance) { - m_ViewDistance = Clamp(a_ViewDistance, MIN_VIEW_DISTANCE, MAX_VIEW_DISTANCE); + ASSERT(m_Player->GetWorld() == NULL); + + m_ViewDistance = Clamp(a_ViewDistance, cClientHandle::MIN_VIEW_DISTANCE, m_Player->GetWorld()->GetMaxViewDistance()); LOGD("Setted %s's view distance to %i", GetUsername().c_str(), m_ViewDistance); } diff --git a/src/World.cpp b/src/World.cpp index 2e079d447..4e6ca264f 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -283,6 +283,7 @@ cWorld::cWorld(const AString & a_WorldName, eDimension a_Dimension, const AStrin m_bCommandBlocksEnabled(true), m_bUseChatPrefixes(false), m_TNTShrapnelLevel(slNone), + m_MaxViewDistance(12), m_Scoreboard(this), m_MapManager(this), m_GeneratorCallbacks(*this), @@ -561,6 +562,8 @@ void cWorld::Start(void) m_BroadcastDeathMessages = IniFile.GetValueSetB("Broadcasting", "BroadcastDeathMessages", true); m_BroadcastAchievementMessages = IniFile.GetValueSetB("Broadcasting", "BroadcastAchievementMessages", true); + SetMaxViewDistance(IniFile.GetValueSetI("SpawnPosition", "MaxViewDistance", 12)); + // Try to find the "SpawnPosition" key and coord values in the world configuration, set the flag if found int KeyNum = IniFile.FindKey("SpawnPosition"); m_IsSpawnExplicitlySet = diff --git a/src/World.h b/src/World.h index ec6dcadde..cc8906d95 100644 --- a/src/World.h +++ b/src/World.h @@ -26,6 +26,7 @@ #include "MapManager.h" #include "Blocks/WorldInterface.h" #include "Blocks/BroadcastInterface.h" +#include "ClientHandle.h" @@ -646,6 +647,12 @@ public: eShrapnelLevel GetTNTShrapnelLevel(void) const { return m_TNTShrapnelLevel; } void SetTNTShrapnelLevel(eShrapnelLevel a_Flag) { m_TNTShrapnelLevel = a_Flag; } + int GetMaxViewDistance(void) const { return m_MaxViewDistance; } + void SetMaxViewDistance(int a_MaxViewDistance) + { + m_MaxViewDistance = Clamp(a_MaxViewDistance, cClientHandle::MIN_VIEW_DISTANCE, cClientHandle::MAX_VIEW_DISTANCE); + } + bool ShouldUseChatPrefixes(void) const { return m_bUseChatPrefixes; } void SetShouldUseChatPrefixes(bool a_Flag) { m_bUseChatPrefixes = a_Flag; } @@ -961,6 +968,9 @@ private: */ eShrapnelLevel m_TNTShrapnelLevel; + /** The maximum view distance that a player can have. */ + int m_MaxViewDistance; + /** Name of the nether world */ AString m_NetherWorldName; -- cgit v1.2.3 From 415c0e128e0a333f69e1785c4d49a6161e1c6f34 Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 30 Oct 2014 21:38:32 +0100 Subject: ... in this world --- src/World.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/World.h b/src/World.h index cc8906d95..a782bb5ec 100644 --- a/src/World.h +++ b/src/World.h @@ -968,7 +968,7 @@ private: */ eShrapnelLevel m_TNTShrapnelLevel; - /** The maximum view distance that a player can have. */ + /** The maximum view distance that a player can have in this world. */ int m_MaxViewDistance; /** Name of the nether world */ -- cgit v1.2.3 From 9f71a4e7aec04c4c7fa57ac4b82f27a21044f798 Mon Sep 17 00:00:00 2001 From: Lukas Pioch Date: Sun, 2 Nov 2014 21:01:23 +0100 Subject: Added FindAndDoWithUUID --- src/Bindings/ManualBindings.cpp | 2 ++ src/Root.cpp | 16 ++++++++++++++++ src/Root.h | 3 +++ src/World.cpp | 22 ++++++++++++++++++++++ src/World.h | 3 +++ 5 files changed, 46 insertions(+) diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index a4a5d79b4..5343090d9 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -3368,6 +3368,7 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_beginmodule(tolua_S, "cRoot"); tolua_function(tolua_S, "FindAndDoWithPlayer", tolua_DoWith ); + tolua_function(tolua_S, "FindAndDoWithUUID", tolua_DoWith ); tolua_function(tolua_S, "ForEachPlayer", tolua_ForEach); tolua_function(tolua_S, "ForEachWorld", tolua_ForEach); tolua_function(tolua_S, "GetFurnaceRecipe", tolua_cRoot_GetFurnaceRecipe); @@ -3389,6 +3390,7 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_function(tolua_S, "DoWithFlowerPotAt", tolua_DoWithXYZ); tolua_function(tolua_S, "DoWithPlayer", tolua_DoWith< cWorld, cPlayer, &cWorld::DoWithPlayer>); tolua_function(tolua_S, "FindAndDoWithPlayer", tolua_DoWith< cWorld, cPlayer, &cWorld::FindAndDoWithPlayer>); + tolua_function(tolua_S, "FindAndDoWithUUID", tolua_DoWith< cWorld, cPlayer, &cWorld::FindAndDoWithUUID>); tolua_function(tolua_S, "ForEachBlockEntityInChunk", tolua_ForEachInChunk); tolua_function(tolua_S, "ForEachChestInChunk", tolua_ForEachInChunk); tolua_function(tolua_S, "ForEachEntity", tolua_ForEach< cWorld, cEntity, &cWorld::ForEachEntity>); diff --git a/src/Root.cpp b/src/Root.cpp index 24c1a4cc8..539284665 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -633,6 +633,22 @@ bool cRoot::FindAndDoWithPlayer(const AString & a_PlayerName, cPlayerListCallbac +bool cRoot::FindAndDoWithUUID(const AString & a_PlayerUUID, cPlayerListCallback & a_Callback) +{ + for (WorldMap::iterator itr = m_WorldsByName.begin(); itr != m_WorldsByName.end();itr++) + { + if (itr->second->FindAndDoWithUUID(a_PlayerUUID, a_Callback)) + { + return true; + } + } + return false; +} + + + + + AString cRoot::GetProtocolVersionTextFromInt(int a_ProtocolVersion) { return cProtocolRecognizer::GetVersionTextFromInt(a_ProtocolVersion); diff --git a/src/Root.h b/src/Root.h index 020a6cff0..456217140 100644 --- a/src/Root.h +++ b/src/Root.h @@ -125,6 +125,9 @@ public: /// Finds a player from a partial or complete player name and calls the callback - case-insensitive bool FindAndDoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS << + + /// Finds a player with the same uuid and call the callback */ + bool FindAndDoWithUUID(const AString & a_PlayerUUID, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS << // tolua_begin diff --git a/src/World.cpp b/src/World.cpp index 2e079d447..212566194 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -2729,6 +2729,28 @@ bool cWorld::FindAndDoWithPlayer(const AString & a_PlayerNameHint, cPlayerListCa +bool cWorld::FindAndDoWithUUID(const AString & a_PlayerUUID, cPlayerListCallback & a_Callback) +{ + cPlayer * FoundPlayer = nullptr; + cCSLock Lock(m_CSPlayers); + for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) + { + if ((*itr)->GetUUID() == a_PlayerUUID) { // Match found and exit + FoundPlayer = *itr; + break; + } + } + if (FoundPlayer != nullptr) + { + return a_Callback.Item (FoundPlayer); + } + return false; +} + + + + + // TODO: This interface is dangerous! cPlayer * cWorld::FindClosestPlayer(const Vector3d & a_Pos, float a_SightLimit, bool a_CheckLineOfSight) { diff --git a/src/World.h b/src/World.h index ec6dcadde..aeb8abf81 100644 --- a/src/World.h +++ b/src/World.h @@ -323,6 +323,9 @@ public: // TODO: This interface is dangerous - rewrite to DoWithClosestPlayer(pos, sight, action) cPlayer * FindClosestPlayer(const Vector3d & a_Pos, float a_SightLimit, bool a_CheckLineOfSight = true); + /** Finds a player with the same uuid and call the callback */ + bool FindAndDoWithUUID(const AString & a_PlayerUUID, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS << + void SendPlayerList(cPlayer * a_DestPlayer); // Sends playerlist to the player /** Adds the entity into its appropriate chunk; takes ownership of the entity ptr. -- cgit v1.2.3 From 269d76a208fcfc58c3c79d6e6a887b823d4f8f00 Mon Sep 17 00:00:00 2001 From: Lukas Pioch Date: Sun, 2 Nov 2014 21:38:17 +0100 Subject: Simplified FindAndDoWithUUID, formatted line --- src/Root.h | 2 +- src/World.cpp | 8 +------- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/Root.h b/src/Root.h index 456217140..f0cdf14d1 100644 --- a/src/Root.h +++ b/src/Root.h @@ -126,7 +126,7 @@ public: /// Finds a player from a partial or complete player name and calls the callback - case-insensitive bool FindAndDoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS << - /// Finds a player with the same uuid and call the callback */ + /// Finds a player with the same uuid and call the callback bool FindAndDoWithUUID(const AString & a_PlayerUUID, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS << // tolua_begin diff --git a/src/World.cpp b/src/World.cpp index 212566194..1b4f4f171 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -2731,19 +2731,13 @@ bool cWorld::FindAndDoWithPlayer(const AString & a_PlayerNameHint, cPlayerListCa bool cWorld::FindAndDoWithUUID(const AString & a_PlayerUUID, cPlayerListCallback & a_Callback) { - cPlayer * FoundPlayer = nullptr; cCSLock Lock(m_CSPlayers); for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { if ((*itr)->GetUUID() == a_PlayerUUID) { // Match found and exit - FoundPlayer = *itr; - break; + return a_Callback.Item (*itr); } } - if (FoundPlayer != nullptr) - { - return a_Callback.Item (FoundPlayer); - } return false; } -- cgit v1.2.3 From eab829ee37b0bf23568cc15e13db72a2abfd35ed Mon Sep 17 00:00:00 2001 From: Ambushed91 Date: Wed, 5 Nov 2014 13:45:15 +0100 Subject: Update V1.0.3 WebAdmin Fixes --- MCServer/webadmin/login_template.html | 4 ++-- MCServer/webadmin/temp.html | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) delete mode 100644 MCServer/webadmin/temp.html diff --git a/MCServer/webadmin/login_template.html b/MCServer/webadmin/login_template.html index a6a8dea44..a4522b015 100644 --- a/MCServer/webadmin/login_template.html +++ b/MCServer/webadmin/login_template.html @@ -1,4 +1,4 @@ -/* Copyright Justin S and MCServer Team, licensed under CC-BY-SA 3.0 */ + MCServer WebAdmin - Login @@ -61,7 +61,7 @@
- Current time: + Current time: Copyright © MCServer Team 2014.
diff --git a/MCServer/webadmin/temp.html b/MCServer/webadmin/temp.html deleted file mode 100644 index 8b1378917..000000000 --- a/MCServer/webadmin/temp.html +++ /dev/null @@ -1 +0,0 @@ - -- cgit v1.2.3 From 0fa8c881a6967ea0c97da4852854102da5cd94c0 Mon Sep 17 00:00:00 2001 From: Ambushed91 Date: Wed, 5 Nov 2014 14:20:03 +0100 Subject: Update V1.0.9 Removed Time, Scroll-Able Header, Resized contention --- MCServer/webadmin/files/style.css | 28 ++++++++------------ MCServer/webadmin/login_template.html | 3 +-- MCServer/webadmin/template.lua | 49 +++++++++++++++++------------------ 3 files changed, 36 insertions(+), 44 deletions(-) diff --git a/MCServer/webadmin/files/style.css b/MCServer/webadmin/files/style.css index 541cd389a..7c0671970 100644 --- a/MCServer/webadmin/files/style.css +++ b/MCServer/webadmin/files/style.css @@ -9,6 +9,8 @@ body { background: #fff; width: 100%; min-width: 100%; + height:100%; + min-height:100%; overflow-y: scroll; overflow-x: hidden; } @@ -48,7 +50,8 @@ h1 { margin: 0 auto; text-align: center; vertical-align: middle; - margin-top: 125px; + margin-top: 25px; + margin-bottom: 25px; } .contention { @@ -58,10 +61,10 @@ h1 { margin: 0; font-family: Tahoma,Verdana,Arial,Sans-Serif; font-size: 13px; + margin-bottom:75px; } -.push10 { - padding-bottom: 75px; +.push25 { } #panel ul.menu { @@ -93,10 +96,6 @@ h1 { padding: 7px; } -#footer { - z-index: 99999; -} - #footer ul.menu { margin: 0; padding: 0; @@ -154,13 +153,14 @@ h1 { } #footer { - position: fixed; - left: 0; - bottom: 0; - height: 60px; + position: fixed; + left:0; + bottom:0; + height: 61px; width: 100%; background: #999; border-top: 1px #000 solid; + border-bottom: 1px #000 solid; } * html #footer { @@ -234,10 +234,6 @@ table { -moz-box-sizing: border-box; } -.padtopp { - padding-top: 25px; -} - table { color: #000; font-size: 13px; @@ -319,8 +315,6 @@ select { } .pagehead { - position: fixed; - z-index: 99999; top: 0; left: 0; width: 100%; diff --git a/MCServer/webadmin/login_template.html b/MCServer/webadmin/login_template.html index a4522b015..7a8601065 100644 --- a/MCServer/webadmin/login_template.html +++ b/MCServer/webadmin/login_template.html @@ -17,7 +17,7 @@
-
+ @@ -61,7 +61,6 @@
- Current time: Copyright © MCServer Team 2014.
diff --git a/MCServer/webadmin/template.lua b/MCServer/webadmin/template.lua index 2811d16f8..4d3934da8 100644 --- a/MCServer/webadmin/template.lua +++ b/MCServer/webadmin/template.lua @@ -81,7 +81,7 @@ function ShowPage(WebAdmin, TemplateRequest) end Output([[ -/* Copyright Justin S and MCServer Team, licensed under CC-BY-SA 3.0 */ + ]] .. Title .. [[ @@ -90,7 +90,7 @@ function ShowPage(WebAdmin, TemplateRequest) -
+
@@ -110,27 +110,27 @@ function ShowPage(WebAdmin, TemplateRequest)
-
-
- - - -
- - - - - - - - - - - - - - -
Menu
Home
Server Management
+
+
+ + + +
+ + + + + + + + + + + + + + +
Menu
Home
Server Management
]]) @@ -173,7 +173,6 @@ function ShowPage(WebAdmin, TemplateRequest)
- ]]) -- cgit v1.2.3 From 13b20d6fe29ebccc60b6be0d3baa17e0353f4a06 Mon Sep 17 00:00:00 2001 From: Lukas Pioch Date: Wed, 5 Nov 2014 21:57:38 +0100 Subject: renamed FindAndDoWithUUID to DoWithPlayerByUUID, fixed style and comments, added description to APIDump --- MCServer/Plugins/APIDump/APIDesc.lua | 2 ++ src/Bindings/ManualBindings.cpp | 4 ++-- src/Root.cpp | 4 ++-- src/Root.h | 4 ++-- src/World.cpp | 5 +++-- src/World.h | 4 ++-- 6 files changed, 13 insertions(+), 10 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 6a151b5ef..01e945e73 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -2137,6 +2137,7 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage); BroadcastChatWarning = { Params = "MessageText", Return = "", Notes = "Broadcasts the specified message to all players, with its message type set to mtWarning. Use for concerning events, such as plugin reload etc." }, CreateAndInitializeWorld = { Params = "WorldName", Return = "{{cWorld|cWorld}}", Notes = "Creates a new world and initializes it. If there is a world whith the same name it returns nil.

NOTEThis function is currently unsafe, do not use!" }, FindAndDoWithPlayer = { Params = "PlayerName, CallbackFunction", Return = "", Notes = "Calls the given callback function for all players with names partially (or fully) matching the name string provided." }, + DoWithPlayerByUUID = { Params = "PlayerUUID, CallbackFunction, [CallbackData]", Return = "bool", Notes = "If there is the player with the uuid, calls the CallbackFunction with the {{cPlayer}} parameter representing the player. The CallbackFunction has the following signature:
function Callback({{cPlayer|Player}}, [CallbackData])
The function returns false if the player was not found, or whatever bool value the callback returned if the player was found." }, ForEachPlayer = { Params = "CallbackFunction", Return = "", Notes = "Calls the given callback function for each player. The callback function has the following signature:
function Callback({{cPlayer|cPlayer}})
" }, ForEachWorld = { Params = "CallbackFunction", Return = "", Notes = "Calls the given callback function for each world. The callback function has the following signature:
function Callback({{cWorld|cWorld}})
" }, Get = { Params = "", Return = "Root object", Notes = "(STATIC)This function returns the cRoot object." }, @@ -2406,6 +2407,7 @@ end { Params = "{{Vector3i|BlockCoords}}, BlockType, BlockMeta", Return = "", Notes = "Sets the block at the specified coords, without waking up the simulators or replacing the block entities for the previous block type. Do not use if the block being replaced has a block entity tied to it!" }, }, FindAndDoWithPlayer = { Params = "PlayerNameHint, CallbackFunction, [CallbackData]", Return = "bool", Notes = "If there is a player of a name similar to the specified name (weighted-match), calls the CallbackFunction with the {{cPlayer}} parameter representing the player. The CallbackFunction has the following signature:
function Callback({{cPlayer|Player}}, [CallbackData])
The function returns false if the player was not found, or whatever bool value the callback returned if the player was found. Note that the name matching is very loose, so it is a good idea to check the player name in the callback function." }, + DoWithPlayerByUUID = { Params = "PlayerUUID, CallbackFunction, [CallbackData]", Return = "bool", Notes = "If there is the player with the uuid, calls the CallbackFunction with the {{cPlayer}} parameter representing the player. The CallbackFunction has the following signature:
function Callback({{cPlayer|Player}}, [CallbackData])
The function returns false if the player was not found, or whatever bool value the callback returned if the player was found." }, ForEachBlockEntityInChunk = { Params = "ChunkX, ChunkZ, CallbackFunction, [CallbackData]", Return = "bool", Notes = "Calls the specified callback for each block entity in the chunk. Returns true if all block entities in the chunk have been processed (including when there are zero block entities), or false if the callback has aborted the enumeration by returning true. The CallbackFunction has the following signature:
function Callback({{cBlockEntity|BlockEntity}}, [CallbackData])
The callback should return false or no value to continue with the next block entity, or true to abort the enumeration. Use {{tolua}}.cast() to cast the Callback's BlockEntity parameter to the correct {{cBlockEntity}} descendant." }, ForEachChestInChunk = { Params = "ChunkX, ChunkZ, CallbackFunction, [CallbackData]", Return = "bool", Notes = "Calls the specified callback for each chest in the chunk. Returns true if all chests in the chunk have been processed (including when there are zero chests), or false if the callback has aborted the enumeration by returning true. The CallbackFunction has the following signature:
function Callback({{cChestEntity|ChestEntity}}, [CallbackData])
The callback should return false or no value to continue with the next chest, or true to abort the enumeration." }, ForEachEntity = { Params = "CallbackFunction, [CallbackData]", Return = "bool", Notes = "Calls the specified callback for each entity in the loaded world. Returns true if all the entities have been processed (including when there are zero entities), or false if the callback function has aborted the enumeration by returning true. The callback function has the following signature:
function Callback({{cEntity|Entity}}, [CallbackData])
The callback should return false or no value to continue with the next entity, or true to abort the enumeration." }, diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 5343090d9..3d10e2abb 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -3368,7 +3368,7 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_beginmodule(tolua_S, "cRoot"); tolua_function(tolua_S, "FindAndDoWithPlayer", tolua_DoWith ); - tolua_function(tolua_S, "FindAndDoWithUUID", tolua_DoWith ); + tolua_function(tolua_S, "DoWithPlayerByUUID", tolua_DoWith ); tolua_function(tolua_S, "ForEachPlayer", tolua_ForEach); tolua_function(tolua_S, "ForEachWorld", tolua_ForEach); tolua_function(tolua_S, "GetFurnaceRecipe", tolua_cRoot_GetFurnaceRecipe); @@ -3390,7 +3390,7 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_function(tolua_S, "DoWithFlowerPotAt", tolua_DoWithXYZ); tolua_function(tolua_S, "DoWithPlayer", tolua_DoWith< cWorld, cPlayer, &cWorld::DoWithPlayer>); tolua_function(tolua_S, "FindAndDoWithPlayer", tolua_DoWith< cWorld, cPlayer, &cWorld::FindAndDoWithPlayer>); - tolua_function(tolua_S, "FindAndDoWithUUID", tolua_DoWith< cWorld, cPlayer, &cWorld::FindAndDoWithUUID>); + tolua_function(tolua_S, "DoWithPlayerByUUID", tolua_DoWith< cWorld, cPlayer, &cWorld::DoWithPlayerByUUID>); tolua_function(tolua_S, "ForEachBlockEntityInChunk", tolua_ForEachInChunk); tolua_function(tolua_S, "ForEachChestInChunk", tolua_ForEachInChunk); tolua_function(tolua_S, "ForEachEntity", tolua_ForEach< cWorld, cEntity, &cWorld::ForEachEntity>); diff --git a/src/Root.cpp b/src/Root.cpp index 539284665..49d6117eb 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -633,11 +633,11 @@ bool cRoot::FindAndDoWithPlayer(const AString & a_PlayerName, cPlayerListCallbac -bool cRoot::FindAndDoWithUUID(const AString & a_PlayerUUID, cPlayerListCallback & a_Callback) +bool cRoot::DoWithPlayerByUUID(const AString & a_PlayerUUID, cPlayerListCallback & a_Callback) { for (WorldMap::iterator itr = m_WorldsByName.begin(); itr != m_WorldsByName.end();itr++) { - if (itr->second->FindAndDoWithUUID(a_PlayerUUID, a_Callback)) + if (itr->second->DoWithPlayerByUUID(a_PlayerUUID, a_Callback)) { return true; } diff --git a/src/Root.h b/src/Root.h index f0cdf14d1..618f70fb8 100644 --- a/src/Root.h +++ b/src/Root.h @@ -126,8 +126,8 @@ public: /// Finds a player from a partial or complete player name and calls the callback - case-insensitive bool FindAndDoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS << - /// Finds a player with the same uuid and call the callback - bool FindAndDoWithUUID(const AString & a_PlayerUUID, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS << + /** Finds the player over his uuid and calls the callback */ + bool DoWithPlayerByUUID(const AString & a_PlayerUUID, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS << // tolua_begin diff --git a/src/World.cpp b/src/World.cpp index 1b4f4f171..1954854f3 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -2729,12 +2729,13 @@ bool cWorld::FindAndDoWithPlayer(const AString & a_PlayerNameHint, cPlayerListCa -bool cWorld::FindAndDoWithUUID(const AString & a_PlayerUUID, cPlayerListCallback & a_Callback) +bool cWorld::DoWithPlayerByUUID(const AString & a_PlayerUUID, cPlayerListCallback & a_Callback) { cCSLock Lock(m_CSPlayers); for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { - if ((*itr)->GetUUID() == a_PlayerUUID) { // Match found and exit + if ((*itr)->GetUUID() == a_PlayerUUID) + { return a_Callback.Item (*itr); } } diff --git a/src/World.h b/src/World.h index aeb8abf81..f1bf9371a 100644 --- a/src/World.h +++ b/src/World.h @@ -323,8 +323,8 @@ public: // TODO: This interface is dangerous - rewrite to DoWithClosestPlayer(pos, sight, action) cPlayer * FindClosestPlayer(const Vector3d & a_Pos, float a_SightLimit, bool a_CheckLineOfSight = true); - /** Finds a player with the same uuid and call the callback */ - bool FindAndDoWithUUID(const AString & a_PlayerUUID, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS << + /** Finds the player over his uuid and calls the callback */ + bool DoWithPlayerByUUID(const AString & a_PlayerUUID, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS << void SendPlayerList(cPlayer * a_DestPlayer); // Sends playerlist to the player -- cgit v1.2.3 From 479c151edab86eb3c495bf3d1c35a42520be676d Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 6 Nov 2014 08:57:11 +0100 Subject: Fixed an extra space. --- src/World.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/World.cpp b/src/World.cpp index 1954854f3..68855e617 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -2736,7 +2736,7 @@ bool cWorld::DoWithPlayerByUUID(const AString & a_PlayerUUID, cPlayerListCallbac { if ((*itr)->GetUUID() == a_PlayerUUID) { - return a_Callback.Item (*itr); + return a_Callback.Item(*itr); } } return false; -- cgit v1.2.3 From 136d6b5c3080df039a5be047c27911c2d03c9fc5 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 6 Nov 2014 19:25:42 +0100 Subject: Noise3D CompoGen: Fixed missing initialization. --- src/Generating/Noise3DGenerator.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Generating/Noise3DGenerator.h b/src/Generating/Noise3DGenerator.h index 42f61a854..c59b3f933 100644 --- a/src/Generating/Noise3DGenerator.h +++ b/src/Generating/Noise3DGenerator.h @@ -96,9 +96,11 @@ protected: // cTerrainHeightGen overrides: virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; + virtual void InitializeHeightGen(cIniFile & a_IniFile) override { Initialize(a_IniFile); } // cTerrainCompositionGen overrides: virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc) override; + virtual void InitializeCompoGen(cIniFile & a_IniFile) override { Initialize(a_IniFile); } } ; -- cgit v1.2.3 From f90f721bb0c06f708909cc7e1986f6eb1538a1d8 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Sat, 8 Nov 2014 09:14:52 +0000 Subject: Added gratipay badge. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bcc7c118f..1f3b06676 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -MCServer [![Build Status](http://img.shields.io/travis/mc-server/MCServer.svg)](https://travis-ci.org/mc-server/MCServer) [![Coverity Scan Build Status](https://scan.coverity.com/projects/1930/badge.svg)](https://scan.coverity.com/projects/1930) [![tip for next commit](http://tip4commit.com/projects/74.svg)](http://tip4commit.com/projects/74) +MCServer [![Build Status](http://img.shields.io/travis/mc-server/MCServer.svg?style=flat)](https://travis-ci.org/mc-server/MCServer) [![Coverity Scan Build Status](https://scan.coverity.com/projects/1930/badge.svg)](https://scan.coverity.com/projects/1930) [![weekly tips](http://img.shields.io/gratipay/cuberite_team.svg?style=flat)](http://gratipay.com/cuberite_team) [![tip for next commit](http://tip4commit.com/projects/74.svg)](http://tip4commit.com/projects/74) ======== MCServer is a Minecraft server that is written in C++ and designed to be efficient with memory and CPU, as well as having a flexible Lua Plugin API. -- cgit v1.2.3 From 378aa20e26377f749bcd40268ff7b2fdad4f9764 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Sat, 8 Nov 2014 09:15:47 +0000 Subject: Travis badge uses master branch. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1f3b06676..88080a52f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -MCServer [![Build Status](http://img.shields.io/travis/mc-server/MCServer.svg?style=flat)](https://travis-ci.org/mc-server/MCServer) [![Coverity Scan Build Status](https://scan.coverity.com/projects/1930/badge.svg)](https://scan.coverity.com/projects/1930) [![weekly tips](http://img.shields.io/gratipay/cuberite_team.svg?style=flat)](http://gratipay.com/cuberite_team) [![tip for next commit](http://tip4commit.com/projects/74.svg)](http://tip4commit.com/projects/74) +MCServer [![Build Status](http://img.shields.io/travis/mc-server/MCServer/master.svg?style=flat)](https://travis-ci.org/mc-server/MCServer) [![Coverity Scan Build Status](https://scan.coverity.com/projects/1930/badge.svg)](https://scan.coverity.com/projects/1930) [![weekly tips](http://img.shields.io/gratipay/cuberite_team.svg?style=flat)](http://gratipay.com/cuberite_team) [![tip for next commit](http://tip4commit.com/projects/74.svg)](http://tip4commit.com/projects/74) ======== MCServer is a Minecraft server that is written in C++ and designed to be efficient with memory and CPU, as well as having a flexible Lua Plugin API. -- cgit v1.2.3 From c43391fd8cfb50746493c103e504d38359c366b2 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 9 Nov 2014 14:33:37 +0100 Subject: Noise3D generator: rewritten from scratch. Now it uses three 3D and one 2D perlin noises to generate the terrain, and is highly parametrizable. --- src/Generating/Noise3DGenerator.cpp | 177 +++++++++++++++++++++--------------- src/Generating/Noise3DGenerator.h | 46 ++++++++-- 2 files changed, 145 insertions(+), 78 deletions(-) diff --git a/src/Generating/Noise3DGenerator.cpp b/src/Generating/Noise3DGenerator.cpp index 5a4cb44cf..4292c66e5 100644 --- a/src/Generating/Noise3DGenerator.cpp +++ b/src/Generating/Noise3DGenerator.cpp @@ -61,6 +61,35 @@ public: +/** Linearly interpolates between two values. +Assumes that a_Ratio is in range [0, 1]. */ +inline static NOISE_DATATYPE Lerp(NOISE_DATATYPE a_Val1, NOISE_DATATYPE a_Val2, NOISE_DATATYPE a_Ratio) +{ + return a_Val1 + (a_Val2 - a_Val1) * a_Ratio; +} + + + + + +/** Linearly interpolates between two values, clamping the ratio to [0, 1] first. */ +inline static NOISE_DATATYPE ClampedLerp(NOISE_DATATYPE a_Val1, NOISE_DATATYPE a_Val2, NOISE_DATATYPE a_Ratio) +{ + if (a_Ratio < 0) + { + return a_Val1; + } + if (a_Ratio > 1) + { + return a_Val2; + } + return a_Val1 + (a_Val2 - a_Val1) * a_Ratio; +} + + + + + //////////////////////////////////////////////////////////////////////////////// // cNoise3DGenerator: @@ -346,9 +375,10 @@ void cNoise3DGenerator::ComposeTerrain(cChunkDesc & a_ChunkDesc) // cNoise3DComposable: cNoise3DComposable::cNoise3DComposable(int a_Seed) : - m_Noise1(a_Seed + 1000), - m_Noise2(a_Seed + 2000), - m_Noise3(a_Seed + 3000) + m_ChoiceNoise(a_Seed), + m_DensityNoiseA(a_Seed + 1), + m_DensityNoiseB(a_Seed + 2), + m_BaseNoise(a_Seed + 3) { } @@ -359,13 +389,51 @@ cNoise3DComposable::cNoise3DComposable(int a_Seed) : void cNoise3DComposable::Initialize(cIniFile & a_IniFile) { // Params: + // The defaults generate extreme hills terrain m_SeaLevel = a_IniFile.GetValueSetI("Generator", "Noise3DSeaLevel", 62); - m_HeightAmplification = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DHeightAmplification", 0); + m_HeightAmplification = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DHeightAmplification", 0.045); m_MidPoint = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DMidPoint", 75); - m_FrequencyX = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DFrequencyX", 10); - m_FrequencyY = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DFrequencyY", 10); - m_FrequencyZ = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DFrequencyZ", 10); - m_AirThreshold = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DAirThreshold", 0.5); + m_FrequencyX = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DFrequencyX", 40); + m_FrequencyY = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DFrequencyY", 40); + m_FrequencyZ = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DFrequencyZ", 40); + m_BaseFrequencyX = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DBaseFrequencyX", 40); + m_BaseFrequencyZ = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DBaseFrequencyZ", 40); + m_ChoiceFrequencyX = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DChoiceFrequencyX", 40); + m_ChoiceFrequencyY = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DChoiceFrequencyY", 80); + m_ChoiceFrequencyZ = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DChoiceFrequencyZ", 40); + m_AirThreshold = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DAirThreshold", 0); + int NumChoiceOctaves = a_IniFile.GetValueSetI("Generator", "Noise3DNumChoiceOctaves", 4); + int NumDensityOctaves = a_IniFile.GetValueSetI("Generator", "Noise3DNumDensityOctaves", 6); + int NumBaseOctaves = a_IniFile.GetValueSetI("Generator", "Noise3DNumBaseOctaves", 6); + NOISE_DATATYPE BaseNoiseAmplitude = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DBaseAmplitude", 1); + + // Add octaves for the choice noise: + NOISE_DATATYPE wavlen = 1, ampl = 0.5; + for (int i = 0; i < NumChoiceOctaves; i++) + { + m_ChoiceNoise.AddOctave(wavlen, ampl); + wavlen = wavlen * 2; + ampl = ampl / 2; + } + + // Add octaves for the density noises: + wavlen = 1, ampl = 1; + for (int i = 0; i < NumDensityOctaves; i++) + { + m_DensityNoiseA.AddOctave(wavlen, ampl); + m_DensityNoiseB.AddOctave(wavlen, ampl); + wavlen = wavlen * 2; + ampl = ampl / 2; + } + + // Add octaves for the base noise: + wavlen = 1, ampl = BaseNoiseAmplitude; + for (int i = 0; i < NumBaseOctaves; i++) + { + m_BaseNoise.AddOctave(wavlen, ampl); + wavlen = wavlen * 2; + ampl = ampl / 2; + } } @@ -382,77 +450,44 @@ void cNoise3DComposable::GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_ChunkZ) m_LastChunkX = a_ChunkX; m_LastChunkZ = a_ChunkZ; - // Upscaling parameters: - const int UPSCALE_X = 8; - const int UPSCALE_Y = 4; - const int UPSCALE_Z = 8; - - // Precalculate a "height" array: - NOISE_DATATYPE Height[17 * 17]; // x + 17 * z - for (int z = 0; z < 17; z += UPSCALE_Z) + // Generate all the noises: + NOISE_DATATYPE ChoiceNoise[5 * 5 * 33]; + NOISE_DATATYPE Workspace[5 * 5 * 33]; + NOISE_DATATYPE DensityNoiseA[5 * 5 * 33]; + NOISE_DATATYPE DensityNoiseB[5 * 5 * 33]; + NOISE_DATATYPE BaseNoise[5 * 5]; + NOISE_DATATYPE BlockX = static_cast(a_ChunkX * cChunkDef::Width); + NOISE_DATATYPE BlockZ = static_cast(a_ChunkZ * cChunkDef::Width); + // Note that we have to swap the coords, because noise generator uses [x + SizeX * y + SizeX * SizeY * z] ordering and we want "BlockY" to be "z": + m_ChoiceNoise.Generate3D (ChoiceNoise, 5, 5, 33, BlockX / m_ChoiceFrequencyX, (BlockX + 17) / m_ChoiceFrequencyX, BlockZ / m_ChoiceFrequencyZ, (BlockZ + 17) / m_ChoiceFrequencyZ, 0, 257 / m_ChoiceFrequencyY, Workspace); + m_DensityNoiseA.Generate3D(DensityNoiseA, 5, 5, 33, BlockX / m_FrequencyX, (BlockX + 17) / m_FrequencyX, BlockZ / m_FrequencyZ, (BlockZ + 17) / m_FrequencyZ, 0, 257 / m_FrequencyY, Workspace); + m_DensityNoiseB.Generate3D(DensityNoiseB, 5, 5, 33, BlockX / m_FrequencyX, (BlockX + 17) / m_FrequencyX, BlockZ / m_FrequencyZ, (BlockZ + 17) / m_FrequencyZ, 0, 257 / m_FrequencyY, Workspace); + m_BaseNoise.Generate2D (BaseNoise, 5, 5, BlockX / m_BaseFrequencyX, (BlockX + 17) / m_BaseFrequencyX, BlockZ / m_FrequencyZ, (BlockZ + 17) / m_FrequencyZ, Workspace); + + // Calculate the final noise based on the partial noises: + for (int y = 0; y < 33; y++) { - NOISE_DATATYPE NoiseZ = ((NOISE_DATATYPE)(a_ChunkZ * cChunkDef::Width + z)) / m_FrequencyZ; - for (int x = 0; x < 17; x += UPSCALE_X) - { - NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(a_ChunkX * cChunkDef::Width + x)) / m_FrequencyX; - NOISE_DATATYPE val = std::abs(m_Noise1.CubicNoise2D(NoiseX / 5, NoiseZ / 5)) * m_HeightAmplification + 1; - Height[x + 17 * z] = val * val * val; - } - } + NOISE_DATATYPE AddHeight = (static_cast(y * 8) - m_MidPoint) * m_HeightAmplification; - for (int y = 0; y < 257; y += UPSCALE_Y) - { - NOISE_DATATYPE NoiseY = ((NOISE_DATATYPE)y) / m_FrequencyY; - NOISE_DATATYPE AddHeight = (y - m_MidPoint) / 20; - AddHeight *= AddHeight * AddHeight; - NOISE_DATATYPE * CurFloor = &(m_NoiseArray[y * 17 * 17]); - for (int z = 0; z < 17; z += UPSCALE_Z) + // If "underground", make the terrain smoother by forcing the vertical linear gradient into steeper slope: + if (AddHeight < 0) { - NOISE_DATATYPE NoiseZ = ((NOISE_DATATYPE)(a_ChunkZ * cChunkDef::Width + z)) / m_FrequencyZ; - for (int x = 0; x < 17; x += UPSCALE_X) - { - NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(a_ChunkX * cChunkDef::Width + x)) / m_FrequencyX; - CurFloor[x + 17 * z] = ( - m_Noise1.CubicNoise3D(NoiseX, NoiseY, NoiseZ) * (NOISE_DATATYPE)0.5 + - m_Noise2.CubicNoise3D(NoiseX / 2, NoiseY / 2, NoiseZ / 2) + - m_Noise3.CubicNoise3D(NoiseX / 4, NoiseY / 4, NoiseZ / 4) * 2 + - AddHeight / Height[x + 17 * z] - ); - } + AddHeight *= 4; } - // Linear-interpolate this XZ floor: - LinearUpscale2DArrayInPlace<17, 17, UPSCALE_X, UPSCALE_Z>(CurFloor); - } - // Finish the 3D linear interpolation by interpolating between each XZ-floors on the Y axis - for (int y = 1; y < cChunkDef::Height; y++) - { - if ((y % UPSCALE_Y) == 0) + for (int z = 0; z < 5; z++) { - // This is the interpolation source floor, already calculated - continue; - } - int LoFloorY = (y / UPSCALE_Y) * UPSCALE_Y; - int HiFloorY = LoFloorY + UPSCALE_Y; - NOISE_DATATYPE * LoFloor = &(m_NoiseArray[LoFloorY * 17 * 17]); - NOISE_DATATYPE * HiFloor = &(m_NoiseArray[HiFloorY * 17 * 17]); - NOISE_DATATYPE * CurFloor = &(m_NoiseArray[y * 17 * 17]); - NOISE_DATATYPE Ratio = ((NOISE_DATATYPE)(y % UPSCALE_Y)) / UPSCALE_Y; - int idx = 0; - for (int z = 0; z < cChunkDef::Width; z++) - { - for (int x = 0; x < cChunkDef::Width; x++) + for (int x = 0; x < 5; x++) { - CurFloor[idx] = LoFloor[idx] + (HiFloor[idx] - LoFloor[idx]) * Ratio; - idx += 1; + int idx = x + 5 * z + 5 * 5 * y; + Workspace[idx] = ClampedLerp(DensityNoiseA[idx], DensityNoiseB[idx], 8 * (ChoiceNoise[idx] + 0.5f)) + AddHeight + BaseNoise[x + 5 * z]; } - idx += 1; // Skipping one X column } } + LinearUpscale3DArray(Workspace, 5, 5, 33, m_NoiseArray, 4, 4, 8); - // The noise array is now fully interpolated - /* - // DEBUG: Output two images of the array, sliced by XY and XZ: + #if 0 + // DEBUG: Output two images of m_NoiseArray, sliced by XY and XZ, into grayscale files, to be inspected by Grabber: cFile f1; if (f1.Open(Printf("Chunk_%d_%d_XY.raw", a_ChunkX, a_ChunkZ), cFile::fmWrite)) { @@ -464,7 +499,7 @@ void cNoise3DComposable::GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_ChunkZ) unsigned char buf[16]; for (int x = 0; x < cChunkDef::Width; x++) { - buf[x] = (unsigned char)(std::min(256, std::max(0, (int)(128 + 128 * m_Noise[idx++])))); + buf[x] = (unsigned char)(std::min(256, std::max(0, (int)(128 + 32 * m_NoiseArray[idx++])))); } f1.Write(buf, 16); } // for y @@ -482,13 +517,13 @@ void cNoise3DComposable::GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_ChunkZ) unsigned char buf[16]; for (int x = 0; x < cChunkDef::Width; x++) { - buf[x] = (unsigned char)(std::min(256, std::max(0, (int)(128 + 128 * m_Noise[idx++])))); + buf[x] = (unsigned char)(std::min(256, std::max(0, (int)(128 + 32 * m_NoiseArray[idx++])))); } f2.Write(buf, 16); } // for z } // for y } // if (XZ file open) - */ + #endif } diff --git a/src/Generating/Noise3DGenerator.h b/src/Generating/Noise3DGenerator.h index c59b3f933..207aeab97 100644 --- a/src/Generating/Noise3DGenerator.h +++ b/src/Generating/Noise3DGenerator.h @@ -1,7 +1,11 @@ // Noise3DGenerator.h -// Generates terrain using 3D noise, rather than composing. Is a test. +// Declares cNoise3DGenerator and cNoise3DComposable classes, representing 3D-noise-based generators. +// They generate terrain shape by combining a lerp of two 3D noises with a vertical linear gradient +// cNoise3DGenerator is obsolete and unmaintained. +// cNoise3DComposable is used to test parameter combinations for single-biome worlds. + @@ -74,24 +78,52 @@ public: void Initialize(cIniFile & a_IniFile); protected: - cNoise m_Noise1; - cNoise m_Noise2; - cNoise m_Noise3; + /** The noise that is used to choose between density noise A and B. */ + cPerlinNoise m_ChoiceNoise; + + /** Density 3D noise, variant A. */ + cPerlinNoise m_DensityNoiseA; + + /** Density 3D noise, variant B. */ + cPerlinNoise m_DensityNoiseB; + + /** Heightmap-like noise used to provide variance for low-amplitude biomes. */ + cPerlinNoise m_BaseNoise; - int m_SeaLevel; + /** Block height of the sealevel, used for composing the terrain. */ + int m_SeaLevel; + + /** The main parameter of the generator, specifies the slope of the vertical linear gradient. + A higher value means a steeper slope and a smaller total amplitude of the generated terrain. */ NOISE_DATATYPE m_HeightAmplification; - NOISE_DATATYPE m_MidPoint; // Where the vertical "center" of the noise should be + + /** Where the vertical "center" of the noise should be, as block height. */ + NOISE_DATATYPE m_MidPoint; + + // Frequency of the 3D noise's first octave: NOISE_DATATYPE m_FrequencyX; NOISE_DATATYPE m_FrequencyY; NOISE_DATATYPE m_FrequencyZ; + + // Frequency of the base terrain noise: + NOISE_DATATYPE m_BaseFrequencyX; + NOISE_DATATYPE m_BaseFrequencyZ; + + // Frequency of the choice noise: + NOISE_DATATYPE m_ChoiceFrequencyX; + NOISE_DATATYPE m_ChoiceFrequencyY; + NOISE_DATATYPE m_ChoiceFrequencyZ; + + // Threshold for when the values are considered air: NOISE_DATATYPE m_AirThreshold; + // Cache for the last calculated chunk (reused between heightmap and composition queries): int m_LastChunkX; int m_LastChunkZ; NOISE_DATATYPE m_NoiseArray[17 * 17 * 257]; // x + 17 * z + 17 * 17 * y - /// Generates the 3D noise array used for terrain generation, unless the LastChunk coords are equal to coords given + /** Generates the 3D noise array used for terrain generation (m_NoiseArray), unless the LastChunk coords are equal to coords given */ void GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_ChunkZ); // cTerrainHeightGen overrides: -- cgit v1.2.3 From 5993c06bd7ab5f02aabb4790570c86699189e219 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 9 Nov 2014 15:33:01 +0100 Subject: Noise3d Generator: Fixed unused function error. --- src/Generating/Noise3DGenerator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Generating/Noise3DGenerator.cpp b/src/Generating/Noise3DGenerator.cpp index 4292c66e5..885a9bab3 100644 --- a/src/Generating/Noise3DGenerator.cpp +++ b/src/Generating/Noise3DGenerator.cpp @@ -83,7 +83,7 @@ inline static NOISE_DATATYPE ClampedLerp(NOISE_DATATYPE a_Val1, NOISE_DATATYPE a { return a_Val2; } - return a_Val1 + (a_Val2 - a_Val1) * a_Ratio; + return Lerp(a_Val1, a_Val2, a_Ratio); } -- cgit v1.2.3 From 4b95f7c69a1b3a3aac8855d5e026238ed0f61fa7 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Mon, 10 Nov 2014 17:00:14 +0100 Subject: Added BiomalNoise3D shape generator. --- src/Generating/ComposableGenerator.cpp | 4 + src/Generating/HeiGen.cpp | 4 + src/Generating/Noise3DGenerator.cpp | 304 +++++++++++++++++++++++++++++---- src/Generating/Noise3DGenerator.h | 86 ++++++++++ 4 files changed, 369 insertions(+), 29 deletions(-) diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index 169821050..5f46574c7 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -73,6 +73,10 @@ cTerrainCompositionGenPtr cTerrainCompositionGen::CreateCompositionGen(cIniFile { res = new cCompoGenNether(a_Seed); } + else if (NoCaseCompare(CompoGenName, "BiomalNoise3D") == 0) + { + res = new cBiomalNoise3DComposable(a_Seed, a_BiomeGen); + } else if (NoCaseCompare(CompoGenName, "Noise3D") == 0) { res = new cNoise3DComposable(a_Seed); diff --git a/src/Generating/HeiGen.cpp b/src/Generating/HeiGen.cpp index 28a5698e4..1d9f1e3aa 100644 --- a/src/Generating/HeiGen.cpp +++ b/src/Generating/HeiGen.cpp @@ -776,6 +776,10 @@ cTerrainHeightGenPtr cTerrainHeightGen::CreateHeightGen(cIniFile & a_IniFile, cB { res = new cHeiGenMountains(a_Seed); } + else if (NoCaseCompare(HeightGenName, "BiomalNoise3D") == 0) + { + res = new cBiomalNoise3DComposable(a_Seed, a_BiomeGen); + } else if (NoCaseCompare(HeightGenName, "Noise3D") == 0) { res = new cNoise3DComposable(a_Seed); diff --git a/src/Generating/Noise3DGenerator.cpp b/src/Generating/Noise3DGenerator.cpp index 885a9bab3..3f50ea0e9 100644 --- a/src/Generating/Noise3DGenerator.cpp +++ b/src/Generating/Noise3DGenerator.cpp @@ -444,7 +444,7 @@ void cNoise3DComposable::GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_ChunkZ) { if ((a_ChunkX == m_LastChunkX) && (a_ChunkZ == m_LastChunkZ)) { - // The noise for this chunk is already generated in m_Noise + // The noise for this chunk is already generated in m_NoiseArray return; } m_LastChunkX = a_ChunkX; @@ -485,52 +485,298 @@ void cNoise3DComposable::GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_ChunkZ) } } LinearUpscale3DArray(Workspace, 5, 5, 33, m_NoiseArray, 4, 4, 8); +} - #if 0 - // DEBUG: Output two images of m_NoiseArray, sliced by XY and XZ, into grayscale files, to be inspected by Grabber: - cFile f1; - if (f1.Open(Printf("Chunk_%d_%d_XY.raw", a_ChunkX, a_ChunkZ), cFile::fmWrite)) + + + + +void cNoise3DComposable::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) +{ + GenerateNoiseArrayIfNeeded(a_ChunkX, a_ChunkZ); + + for (int z = 0; z < cChunkDef::Width; z++) { - for (int z = 0; z < cChunkDef::Width; z++) + for (int x = 0; x < cChunkDef::Width; x++) { - for (int y = 0; y < cChunkDef::Height; y++) + cChunkDef::SetHeight(a_HeightMap, x, z, m_SeaLevel); + for (int y = cChunkDef::Height - 1; y > m_SeaLevel; y--) { - int idx = y * 17 * 17 + z * 17; - unsigned char buf[16]; - for (int x = 0; x < cChunkDef::Width; x++) + if (m_NoiseArray[y * 17 * 17 + z * 17 + x] <= m_AirThreshold) { - buf[x] = (unsigned char)(std::min(256, std::max(0, (int)(128 + 32 * m_NoiseArray[idx++])))); + cChunkDef::SetHeight(a_HeightMap, x, z, y); + break; } - f1.Write(buf, 16); } // for y - } // for z - } // if (XY file open) + } // for x + } // for z +} - cFile f2; - if (f2.Open(Printf("Chunk_%d_%d_XZ.raw", a_ChunkX, a_ChunkZ), cFile::fmWrite)) + + + + +void cNoise3DComposable::ComposeTerrain(cChunkDesc & a_ChunkDesc) +{ + GenerateNoiseArrayIfNeeded(a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ()); + + a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0); + + // Make basic terrain composition: + for (int z = 0; z < cChunkDef::Width; z++) { - for (int y = 0; y < cChunkDef::Height; y++) + for (int x = 0; x < cChunkDef::Width; x++) { - for (int z = 0; z < cChunkDef::Width; z++) + int LastAir = a_ChunkDesc.GetHeight(x, z) + 1; + bool HasHadWater = false; + for (int y = LastAir; y < m_SeaLevel; y++) { - int idx = y * 17 * 17 + z * 17; - unsigned char buf[16]; - for (int x = 0; x < cChunkDef::Width; x++) + a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_STATIONARY_WATER); + } + for (int y = LastAir - 1; y > 0; y--) + { + if (m_NoiseArray[x + 17 * z + 17 * 17 * y] > m_AirThreshold) { - buf[x] = (unsigned char)(std::min(256, std::max(0, (int)(128 + 32 * m_NoiseArray[idx++])))); + // "air" part + LastAir = y; + if (y < m_SeaLevel) + { + a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_STATIONARY_WATER); + HasHadWater = true; + } + continue; } - f2.Write(buf, 16); - } // for z - } // for y - } // if (XZ file open) - #endif + // "ground" part: + if (LastAir - y > 4) + { + a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_STONE); + continue; + } + if (HasHadWater) + { + a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_SAND); + } + else + { + a_ChunkDesc.SetBlockType(x, y, z, (LastAir == y + 1) ? E_BLOCK_GRASS : E_BLOCK_DIRT); + } + } // for y + a_ChunkDesc.SetBlockType(x, 0, z, E_BLOCK_BEDROCK); + } // for x + } // for z } -void cNoise3DComposable::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) +//////////////////////////////////////////////////////////////////////////////// +// cBiomalNoise3DComposable: + +cBiomalNoise3DComposable::cBiomalNoise3DComposable(int a_Seed, cBiomeGenPtr a_BiomeGen) : + m_ChoiceNoise(a_Seed), + m_DensityNoiseA(a_Seed + 1), + m_DensityNoiseB(a_Seed + 2), + m_BaseNoise(a_Seed + 3), + m_BiomeGen(a_BiomeGen) +{ + // Generate the weight distribution for summing up neighboring biomes: + m_WeightSum = 0; + for (int z = 0; z <= AVERAGING_SIZE * 2; z++) + { + for (int x = 0; x <= AVERAGING_SIZE * 2; x++) + { + m_Weight[z][x] = static_cast((5 - std::abs(5 - x)) + (5 - std::abs(5 - z))); + m_WeightSum += m_Weight[z][x]; + } + } +} + + + + + +void cBiomalNoise3DComposable::Initialize(cIniFile & a_IniFile) +{ + // Params: + // The defaults generate extreme hills terrain + m_SeaLevel = a_IniFile.GetValueSetI("Generator", "BiomalNoise3DSeaLevel", 62); + m_FrequencyX = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "BiomalNoise3DFrequencyX", 40); + m_FrequencyY = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "BiomalNoise3DFrequencyY", 40); + m_FrequencyZ = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "BiomalNoise3DFrequencyZ", 40); + m_BaseFrequencyX = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "BiomalNoise3DBaseFrequencyX", 40); + m_BaseFrequencyZ = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "BiomalNoise3DBaseFrequencyZ", 40); + m_ChoiceFrequencyX = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "BiomalNoise3DChoiceFrequencyX", 40); + m_ChoiceFrequencyY = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "BiomalNoise3DChoiceFrequencyY", 80); + m_ChoiceFrequencyZ = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "BiomalNoise3DChoiceFrequencyZ", 40); + m_AirThreshold = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "BiomalNoise3DAirThreshold", 0); + int NumChoiceOctaves = a_IniFile.GetValueSetI("Generator", "BiomalNoise3DNumChoiceOctaves", 4); + int NumDensityOctaves = a_IniFile.GetValueSetI("Generator", "BiomalNoise3DNumDensityOctaves", 6); + int NumBaseOctaves = a_IniFile.GetValueSetI("Generator", "BiomalNoise3DNumBaseOctaves", 6); + NOISE_DATATYPE BaseNoiseAmplitude = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "BiomalNoise3DBaseAmplitude", 1); + + // Add octaves for the choice noise: + NOISE_DATATYPE wavlen = 1, ampl = 0.5; + for (int i = 0; i < NumChoiceOctaves; i++) + { + m_ChoiceNoise.AddOctave(wavlen, ampl); + wavlen = wavlen * 2; + ampl = ampl / 2; + } + + // Add octaves for the density noises: + wavlen = 1, ampl = 1; + for (int i = 0; i < NumDensityOctaves; i++) + { + m_DensityNoiseA.AddOctave(wavlen, ampl); + m_DensityNoiseB.AddOctave(wavlen, ampl); + wavlen = wavlen * 2; + ampl = ampl / 2; + } + + // Add octaves for the base noise: + wavlen = 1, ampl = BaseNoiseAmplitude; + for (int i = 0; i < NumBaseOctaves; i++) + { + m_BaseNoise.AddOctave(wavlen, ampl); + wavlen = wavlen * 2; + ampl = ampl / 2; + } +} + + + + + +void cBiomalNoise3DComposable::GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_ChunkZ) +{ + if ((a_ChunkX == m_LastChunkX) && (a_ChunkZ == m_LastChunkZ)) + { + // The noise for this chunk is already generated in m_NoiseArray + return; + } + m_LastChunkX = a_ChunkX; + m_LastChunkZ = a_ChunkZ; + + // Calculate the parameters for the biomes: + ChunkParam MidPoint; + ChunkParam HeightAmp; + CalcBiomeParamArrays(a_ChunkX, a_ChunkZ, HeightAmp, MidPoint); + + // Generate all the noises: + NOISE_DATATYPE ChoiceNoise[5 * 5 * 33]; + NOISE_DATATYPE Workspace[5 * 5 * 33]; + NOISE_DATATYPE DensityNoiseA[5 * 5 * 33]; + NOISE_DATATYPE DensityNoiseB[5 * 5 * 33]; + NOISE_DATATYPE BaseNoise[5 * 5]; + NOISE_DATATYPE BlockX = static_cast(a_ChunkX * cChunkDef::Width); + NOISE_DATATYPE BlockZ = static_cast(a_ChunkZ * cChunkDef::Width); + // Note that we have to swap the coords, because noise generator uses [x + SizeX * y + SizeX * SizeY * z] ordering and we want "BlockY" to be "z": + m_ChoiceNoise.Generate3D (ChoiceNoise, 5, 5, 33, BlockX / m_ChoiceFrequencyX, (BlockX + 17) / m_ChoiceFrequencyX, BlockZ / m_ChoiceFrequencyZ, (BlockZ + 17) / m_ChoiceFrequencyZ, 0, 257 / m_ChoiceFrequencyY, Workspace); + m_DensityNoiseA.Generate3D(DensityNoiseA, 5, 5, 33, BlockX / m_FrequencyX, (BlockX + 17) / m_FrequencyX, BlockZ / m_FrequencyZ, (BlockZ + 17) / m_FrequencyZ, 0, 257 / m_FrequencyY, Workspace); + m_DensityNoiseB.Generate3D(DensityNoiseB, 5, 5, 33, BlockX / m_FrequencyX, (BlockX + 17) / m_FrequencyX, BlockZ / m_FrequencyZ, (BlockZ + 17) / m_FrequencyZ, 0, 257 / m_FrequencyY, Workspace); + m_BaseNoise.Generate2D (BaseNoise, 5, 5, BlockX / m_BaseFrequencyX, (BlockX + 17) / m_BaseFrequencyX, BlockZ / m_FrequencyZ, (BlockZ + 17) / m_FrequencyZ, Workspace); + + // Calculate the final noise based on the partial noises: + for (int y = 0; y < 33; y++) + { + NOISE_DATATYPE BlockHeight = static_cast(y * 8); + for (int z = 0; z < 5; z++) + { + for (int x = 0; x < 5; x++) + { + NOISE_DATATYPE AddHeight = (BlockHeight - MidPoint[x + 5 * z]) * HeightAmp[x + 5 * z]; + + // If "underground", make the terrain smoother by forcing the vertical linear gradient into steeper slope: + if (AddHeight < 0) + { + AddHeight *= 4; + } + + int idx = x + 5 * z + 5 * 5 * y; + Workspace[idx] = ClampedLerp(DensityNoiseA[idx], DensityNoiseB[idx], 8 * (ChoiceNoise[idx] + 0.5f)) + AddHeight + BaseNoise[x + 5 * z]; + } + } + } + LinearUpscale3DArray(Workspace, 5, 5, 33, m_NoiseArray, 4, 4, 8); +} + + + + + +void cBiomalNoise3DComposable::CalcBiomeParamArrays(int a_ChunkX, int a_ChunkZ, ChunkParam & a_HeightAmp, ChunkParam & a_MidPoint) +{ + // Generate the 3*3 chunks of biomes around this chunk: + cChunkDef::BiomeMap neighborBiomes[3 * 3]; + for (int z = 0; z < 3; z++) + { + for (int x = 0; x < 3; x++) + { + m_BiomeGen->GenBiomes(a_ChunkX + x - 1, a_ChunkZ + z - 1, neighborBiomes[x + 3 * z]); + } + } + + // Sum up the biome values: + for (int z = 0; z < 5; z++) + { + for (int x = 0; x < 5; x++) + { + NOISE_DATATYPE totalHeightAmp = 0; + NOISE_DATATYPE totalMidPoint = 0; + // Add up the biomes around this point: + for (int relz = 0; relz <= AVERAGING_SIZE * 2; ++relz) + { + int colz = 16 + z * 4 + relz - AVERAGING_SIZE; // Biome Z coord relative to the neighborBiomes start + int neicellz = colz / 16; // Chunk Z coord relative to the neighborBiomes start + int neirelz = colz % 16; // Biome Z coord relative to cz in neighborBiomes + for (int relx = 0; relx <= AVERAGING_SIZE * 2; ++relx) + { + int colx = 16 + x * 4 + relx - AVERAGING_SIZE; // Biome X coord relative to the neighborBiomes start + int neicellx = colx / 16; // Chunk X coord relative to the neighborBiomes start + int neirelx = colx % 16; // Biome X coord relative to cz in neighborBiomes + EMCSBiome biome = cChunkDef::GetBiome(neighborBiomes[neicellx + neicellz * 3], neirelx, neirelz); + NOISE_DATATYPE heightAmp, midPoint; + GetBiomeParams(biome, heightAmp, midPoint); + totalHeightAmp += heightAmp * m_Weight[relz][relx]; + totalMidPoint += midPoint * m_Weight[relz][relx]; + } // for relx + } // for relz + a_HeightAmp[x + 5 * z] = totalHeightAmp / m_WeightSum; + a_MidPoint[x + 5 * z] = totalMidPoint / m_WeightSum; + } // for x + } // for z +} + + + + + +void cBiomalNoise3DComposable::GetBiomeParams(EMCSBiome a_Biome, NOISE_DATATYPE & a_HeightAmp, NOISE_DATATYPE & a_MidPoint) +{ + switch (a_Biome) + { + case biDesert: a_HeightAmp = 0.29f; a_MidPoint = 62; break; // Needs verification + case biExtremeHills: a_HeightAmp = 0.045f; a_MidPoint = 75; break; + case biPlains: a_HeightAmp = 0.3f; a_MidPoint = 62; break; // Needs verification + case biSwampland: a_HeightAmp = 0.25f; a_MidPoint = 59; break; + case biSwamplandM: a_HeightAmp = 0.11f; a_MidPoint = 59; break; + + default: + { + // Make a crazy terrain so that it stands out + a_HeightAmp = 0.001f; + a_MidPoint = 90; + break; + } + } +} + + + + + +void cBiomalNoise3DComposable::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) { GenerateNoiseArrayIfNeeded(a_ChunkX, a_ChunkZ); @@ -555,7 +801,7 @@ void cNoise3DComposable::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::Hei -void cNoise3DComposable::ComposeTerrain(cChunkDesc & a_ChunkDesc) +void cBiomalNoise3DComposable::ComposeTerrain(cChunkDesc & a_ChunkDesc) { GenerateNoiseArrayIfNeeded(a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ()); diff --git a/src/Generating/Noise3DGenerator.h b/src/Generating/Noise3DGenerator.h index 207aeab97..ba541fbcc 100644 --- a/src/Generating/Noise3DGenerator.h +++ b/src/Generating/Noise3DGenerator.h @@ -138,3 +138,89 @@ protected: + +class cBiomalNoise3DComposable : + public cTerrainHeightGen, + public cTerrainCompositionGen +{ +public: + cBiomalNoise3DComposable(int a_Seed, cBiomeGenPtr a_BiomeGen); + + void Initialize(cIniFile & a_IniFile); + +protected: + /** Number of columns around the pixel to query for biomes for averaging. */ + static const int AVERAGING_SIZE = 5; + + /** Type used for a single parameter across the entire (downscaled) chunk. */ + typedef NOISE_DATATYPE ChunkParam[5 * 5]; + + + /** The noise that is used to choose between density noise A and B. */ + cPerlinNoise m_ChoiceNoise; + + /** Density 3D noise, variant A. */ + cPerlinNoise m_DensityNoiseA; + + /** Density 3D noise, variant B. */ + cPerlinNoise m_DensityNoiseB; + + /** Heightmap-like noise used to provide variance for low-amplitude biomes. */ + cPerlinNoise m_BaseNoise; + + /** The underlying biome generator. */ + cBiomeGenPtr m_BiomeGen; + + /** Block height of the sealevel, used for composing the terrain. */ + int m_SeaLevel; + + // Frequency of the 3D noise's first octave: + NOISE_DATATYPE m_FrequencyX; + NOISE_DATATYPE m_FrequencyY; + NOISE_DATATYPE m_FrequencyZ; + + // Frequency of the base terrain noise: + NOISE_DATATYPE m_BaseFrequencyX; + NOISE_DATATYPE m_BaseFrequencyZ; + + // Frequency of the choice noise: + NOISE_DATATYPE m_ChoiceFrequencyX; + NOISE_DATATYPE m_ChoiceFrequencyY; + NOISE_DATATYPE m_ChoiceFrequencyZ; + + // Threshold for when the values are considered air: + NOISE_DATATYPE m_AirThreshold; + + // Cache for the last calculated chunk (reused between heightmap and composition queries): + int m_LastChunkX; + int m_LastChunkZ; + NOISE_DATATYPE m_NoiseArray[17 * 17 * 257]; // x + 17 * z + 17 * 17 * y + + /** Weights for summing up neighboring biomes. */ + NOISE_DATATYPE m_Weight[AVERAGING_SIZE * 2 + 1][AVERAGING_SIZE * 2 + 1]; + + /** The sum of m_Weight[]. */ + NOISE_DATATYPE m_WeightSum; + + + /** Generates the 3D noise array used for terrain generation (m_NoiseArray), unless the LastChunk coords are equal to coords given */ + void GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_ChunkZ); + + /** Calculates the biome-related parameters for the chunk. */ + void CalcBiomeParamArrays(int a_ChunkX, int a_ChunkZ, ChunkParam & a_HeightAmp, ChunkParam & a_MidPoint); + + /** Returns the parameters for the specified biome. */ + void GetBiomeParams(EMCSBiome a_Biome, NOISE_DATATYPE & a_HeightAmp, NOISE_DATATYPE & a_MidPoint); + + // cTerrainHeightGen overrides: + virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; + virtual void InitializeHeightGen(cIniFile & a_IniFile) override { Initialize(a_IniFile); } + + // cTerrainCompositionGen overrides: + virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc) override; + virtual void InitializeCompoGen(cIniFile & a_IniFile) override { Initialize(a_IniFile); } +} ; + + + + -- cgit v1.2.3 From 9a50a1fe0cc641a4ec931d733702b775292a6ab6 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 10 Nov 2014 21:55:13 +0100 Subject: TallGrassGenerator: Fixed crash when too high --- src/Generating/FinishGen.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index 18f8ee2bc..b8afac09a 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -199,6 +199,11 @@ void cFinishGenTallGrass::GenFinish(cChunkDesc & a_ChunkDesc) // Get the top block + 1. This is the place where the grass would finaly be placed: int y = a_ChunkDesc.GetHeight(x, z) + 1; + + if (y >= 255) + { + continue; + } // Check if long grass can be placed: if ( -- cgit v1.2.3 From b525eee8e001676d54cf43cb6c74794a60038a5c Mon Sep 17 00:00:00 2001 From: Mattes D Date: Mon, 10 Nov 2014 22:08:07 +0100 Subject: BiomalNoise3D: Added a few biomes. --- src/Generating/Noise3DGenerator.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Generating/Noise3DGenerator.cpp b/src/Generating/Noise3DGenerator.cpp index 3f50ea0e9..4e45aa18b 100644 --- a/src/Generating/Noise3DGenerator.cpp +++ b/src/Generating/Noise3DGenerator.cpp @@ -756,11 +756,14 @@ void cBiomalNoise3DComposable::GetBiomeParams(EMCSBiome a_Biome, NOISE_DATATYPE { switch (a_Biome) { - case biDesert: a_HeightAmp = 0.29f; a_MidPoint = 62; break; // Needs verification - case biExtremeHills: a_HeightAmp = 0.045f; a_MidPoint = 75; break; - case biPlains: a_HeightAmp = 0.3f; a_MidPoint = 62; break; // Needs verification - case biSwampland: a_HeightAmp = 0.25f; a_MidPoint = 59; break; - case biSwamplandM: a_HeightAmp = 0.11f; a_MidPoint = 59; break; + case biDesert: a_HeightAmp = 0.29f; a_MidPoint = 62; break; // Needs verification + case biExtremeHills: a_HeightAmp = 0.045f; a_MidPoint = 75; break; + case biExtremeHillsPlus: a_HeightAmp = 0.04f; a_MidPoint = 80; break; + case biFrozenRiver: a_HeightAmp = 0.4f; a_MidPoint = 53; break; + case biPlains: a_HeightAmp = 0.3f; a_MidPoint = 62; break; // Needs verification + case biRiver: a_HeightAmp = 0.4f; a_MidPoint = 53; break; + case biSwampland: a_HeightAmp = 0.25f; a_MidPoint = 59; break; + case biSwamplandM: a_HeightAmp = 0.11f; a_MidPoint = 59; break; default: { -- cgit v1.2.3 From 5fb2526e0739fa27d925a686669f2c3aef56e825 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 12 Nov 2014 21:24:26 +0100 Subject: Generator: Shape initial refactoring. The code compiles, but several structure generators are broken, crash on start. --- src/Generating/CMakeLists.txt | 3 + src/Generating/ChunkDesc.cpp | 63 +++ src/Generating/ChunkDesc.h | 25 +- src/Generating/CompoGen.cpp | 332 +------------ src/Generating/CompoGen.h | 44 +- src/Generating/CompoGenBiomal.cpp | 799 ++++++++++++++++++++++++++++++++ src/Generating/CompoGenBiomal.h | 21 + src/Generating/ComposableGenerator.cpp | 99 ++-- src/Generating/ComposableGenerator.h | 95 ++-- src/Generating/DistortedHeightmap.cpp | 565 +--------------------- src/Generating/DistortedHeightmap.h | 60 +-- src/Generating/DungeonRoomsFinisher.cpp | 8 +- src/Generating/DungeonRoomsFinisher.h | 8 +- src/Generating/EndGen.cpp | 44 +- src/Generating/EndGen.h | 8 +- src/Generating/HeiGen.cpp | 47 +- src/Generating/HeiGen.h | 53 +-- src/Generating/Noise3DGenerator.cpp | 197 ++------ src/Generating/Noise3DGenerator.h | 26 +- src/Generating/ShapeGen.cpp | 140 ++++++ src/Generating/StructGen.cpp | 26 +- src/Generating/StructGen.h | 33 +- src/Generating/VillageGen.cpp | 6 +- 23 files changed, 1356 insertions(+), 1346 deletions(-) create mode 100644 src/Generating/CompoGenBiomal.cpp create mode 100644 src/Generating/CompoGenBiomal.h create mode 100644 src/Generating/ShapeGen.cpp diff --git a/src/Generating/CMakeLists.txt b/src/Generating/CMakeLists.txt index 1a26bd0d5..047452bbb 100644 --- a/src/Generating/CMakeLists.txt +++ b/src/Generating/CMakeLists.txt @@ -10,6 +10,7 @@ SET (SRCS ChunkDesc.cpp ChunkGenerator.cpp CompoGen.cpp + CompoGenBiomal.cpp ComposableGenerator.cpp DistortedHeightmap.cpp DungeonRoomsFinisher.cpp @@ -39,6 +40,7 @@ SET (HDRS ChunkDesc.h ChunkGenerator.h CompoGen.h + CompoGenBiomal.h ComposableGenerator.h DistortedHeightmap.h DungeonRoomsFinisher.h @@ -58,6 +60,7 @@ SET (HDRS RainbowRoadsGen.h Ravines.h RoughRavines.h + ShapeGen.cpp StructGen.h TestRailsGen.h Trees.h diff --git a/src/Generating/ChunkDesc.cpp b/src/Generating/ChunkDesc.cpp index 020d3bd0f..3fe81c7e4 100644 --- a/src/Generating/ChunkDesc.cpp +++ b/src/Generating/ChunkDesc.cpp @@ -152,6 +152,52 @@ int cChunkDesc::GetHeight(int a_RelX, int a_RelZ) +void cChunkDesc::SetHeightFromShape(const Shape & a_Shape) +{ + for (int z = 0; z < cChunkDef::Width; z++) + { + for (int x = 0; x < cChunkDef::Width; x++) + { + for (int y = cChunkDef::Height - 1; y > 0; y--) + { + if (a_Shape[y + x * 256 + z * 16 * 256] != 0) + { + cChunkDef::SetHeight(m_HeightMap, x, z, y); + break; + } + } // for y + } // for x + } // for z +} + + + + + +void cChunkDesc::GetShapeFromHeight(Shape & a_Shape) const +{ + for (int z = 0; z < cChunkDef::Width; z++) + { + for (int x = 0; x < cChunkDef::Width; x++) + { + int height = cChunkDef::GetHeight(m_HeightMap, x, z); + for (int y = 0; y <= height; y++) + { + a_Shape[y + x * 256 + z * 16 * 256] = 1; + } + + for (int y = height + 1; y < cChunkDef::Height; y++) + { + a_Shape[y + x * 256 + z * 16 * 256] = 0; + } // for y + } // for x + } // for z +} + + + + + void cChunkDesc::SetUseDefaultBiomes(bool a_bUseDefaultBiomes) { m_bUseDefaultBiomes = a_bUseDefaultBiomes; @@ -366,6 +412,23 @@ HEIGHTTYPE cChunkDesc::GetMaxHeight(void) const +HEIGHTTYPE cChunkDesc::GetMinHeight(void) const +{ + HEIGHTTYPE MinHeight = m_HeightMap[0]; + for (size_t i = 1; i < ARRAYCOUNT(m_HeightMap); i++) + { + if (m_HeightMap[i] < MinHeight) + { + MinHeight = m_HeightMap[i]; + } + } + return MinHeight; +} + + + + + void cChunkDesc::FillRelCuboid( int a_MinX, int a_MaxX, int a_MinY, int a_MaxY, diff --git a/src/Generating/ChunkDesc.h b/src/Generating/ChunkDesc.h index 570132790..b86041a7d 100644 --- a/src/Generating/ChunkDesc.h +++ b/src/Generating/ChunkDesc.h @@ -29,10 +29,17 @@ class cChunkDesc { public: // tolua_end + + /** The datatype used to represent the entire chunk worth of shape. + 0 = air + 1 = solid + Indexed as [y + 256 * z + 256 * 16 * x]. */ + typedef Byte Shape[256 * 16 * 16]; /** Uncompressed block metas, 1 meta per byte */ typedef NIBBLETYPE BlockNibbleBytes[cChunkDef::NumBlocks]; + cChunkDesc(int a_ChunkX, int a_ChunkZ); ~cChunkDesc(); @@ -57,10 +64,21 @@ public: EMCSBiome GetBiome(int a_RelX, int a_RelZ); // These operate on the heightmap, so they could get out of sync with the data - // Use UpdateHeightmap() to re-sync + // Use UpdateHeightmap() to re-calculate heightmap from the block data void SetHeight(int a_RelX, int a_RelZ, int a_Height); int GetHeight(int a_RelX, int a_RelZ); + // tolua_end + + /** Sets the heightmap to match the given shape data. + Note that this ignores overhangs; the method is mostly used by old composition generators. */ + void SetHeightFromShape(const Shape & a_Shape); + + /** Sets the shape in a_Shape to match the heightmap stored currently in m_HeightMap. */ + void GetShapeFromHeight(Shape & a_Shape) const; + + // tolua_begin + // Default generation: void SetUseDefaultBiomes(bool a_bUseDefaultBiomes); bool IsUsingDefaultBiomes(void) const; @@ -77,8 +95,11 @@ public: /** Reads an area from the chunk into a cBlockArea, blocktypes and blockmetas */ void ReadBlockArea(cBlockArea & a_Dest, int a_MinRelX, int a_MaxRelX, int a_MinRelY, int a_MaxRelY, int a_MinRelZ, int a_MaxRelZ); - /** Returns the maximum height value in the heightmap */ + /** Returns the maximum height value in the heightmap. */ HEIGHTTYPE GetMaxHeight(void) const; + + /** Returns the minimum height value in the heightmap. */ + HEIGHTTYPE GetMinHeight(void) const; /** Fills the relative cuboid with specified block; allows cuboid out of range of this chunk */ void FillRelCuboid( diff --git a/src/Generating/CompoGen.cpp b/src/Generating/CompoGen.cpp index 29b831dfd..ef13b7c6b 100644 --- a/src/Generating/CompoGen.cpp +++ b/src/Generating/CompoGen.cpp @@ -21,8 +21,9 @@ //////////////////////////////////////////////////////////////////////////////// // cCompoGenSameBlock: -void cCompoGenSameBlock::ComposeTerrain(cChunkDesc & a_ChunkDesc) +void cCompoGenSameBlock::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) { + a_ChunkDesc.SetHeightFromShape(a_Shape); a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0); for (int z = 0; z < cChunkDef::Width; z++) { @@ -63,7 +64,7 @@ void cCompoGenSameBlock::InitializeCompoGen(cIniFile & a_IniFile) //////////////////////////////////////////////////////////////////////////////// // cCompoGenDebugBiomes: -void cCompoGenDebugBiomes::ComposeTerrain(cChunkDesc & a_ChunkDesc) +void cCompoGenDebugBiomes::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) { static BLOCKTYPE Blocks[] = { @@ -92,6 +93,7 @@ void cCompoGenDebugBiomes::ComposeTerrain(cChunkDesc & a_ChunkDesc) E_BLOCK_BEDROCK, } ; + a_ChunkDesc.SetHeightFromShape(a_Shape); a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0); for (int z = 0; z < cChunkDef::Width; z++) @@ -131,7 +133,7 @@ cCompoGenClassic::cCompoGenClassic(void) : -void cCompoGenClassic::ComposeTerrain(cChunkDesc & a_ChunkDesc) +void cCompoGenClassic::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) { /* The classic composition means: - 1 layer of grass, 3 of dirt and the rest stone, if the height > sealevel + beachheight @@ -142,6 +144,7 @@ void cCompoGenClassic::ComposeTerrain(cChunkDesc & a_ChunkDesc) */ a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0); + a_ChunkDesc.SetHeightFromShape(a_Shape); // The patterns to use for different situations, must be same length! const BLOCKTYPE PatternGround[] = {m_BlockTop, m_BlockMiddle, m_BlockMiddle, m_BlockMiddle} ; @@ -209,323 +212,6 @@ void cCompoGenClassic::InitializeCompoGen(cIniFile & a_IniFile) -//////////////////////////////////////////////////////////////////////////////// -// cCompoGenBiomal: - -void cCompoGenBiomal::ComposeTerrain(cChunkDesc & a_ChunkDesc) -{ - a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0); - - int ChunkX = a_ChunkDesc.GetChunkX(); - int ChunkZ = a_ChunkDesc.GetChunkZ(); - - /* - _X 2013_04_22: - There's no point in generating the whole cubic noise at once, because the noise values are used in - only about 20 % of the cases, so the speed gained by precalculating is lost by precalculating too much data - */ - - for (int z = 0; z < cChunkDef::Width; z++) - { - for (int x = 0; x < cChunkDef::Width; x++) - { - int Height = a_ChunkDesc.GetHeight(x, z); - if (Height > m_SeaLevel) - { - switch (a_ChunkDesc.GetBiome(x, z)) - { - case biOcean: - case biPlains: - case biExtremeHills: - case biForest: - case biTaiga: - case biSwampland: - case biRiver: - case biFrozenOcean: - case biFrozenRiver: - case biIcePlains: - case biIceMountains: - case biForestHills: - case biTaigaHills: - case biExtremeHillsEdge: - case biJungle: - case biJungleHills: - case biJungleEdge: - case biDeepOcean: - case biStoneBeach: - case biColdBeach: - case biBirchForest: - case biBirchForestHills: - case biRoofedForest: - case biColdTaiga: - case biColdTaigaHills: - case biExtremeHillsPlus: - case biSavanna: - case biSavannaPlateau: - case biSunflowerPlains: - case biExtremeHillsM: - case biFlowerForest: - case biTaigaM: - case biSwamplandM: - case biIcePlainsSpikes: - case biJungleM: - case biJungleEdgeM: - case biBirchForestM: - case biBirchForestHillsM: - case biRoofedForestM: - case biColdTaigaM: - case biExtremeHillsPlusM: - case biSavannaM: - case biSavannaPlateauM: - { - FillColumnGrass(x, z, Height, a_ChunkDesc.GetBlockTypes()); - break; - } - - case biMesa: - case biMesaPlateauF: - case biMesaPlateau: - case biMesaBryce: - case biMesaPlateauFM: - case biMesaPlateauM: - { - FillColumnClay(x, z, Height, a_ChunkDesc.GetBlockTypes()); - break; - } - - case biMegaTaiga: - case biMegaTaigaHills: - case biMegaSpruceTaiga: - case biMegaSpruceTaigaHills: - { - FillColumnDirt(x, z, Height, a_ChunkDesc.GetBlockTypes()); - break; - } - - case biDesertHills: - case biDesert: - case biDesertM: - case biBeach: - { - FillColumnSand(x, z, Height, a_ChunkDesc.GetBlockTypes()); - break; - } - case biMushroomIsland: - case biMushroomShore: - { - FillColumnMycelium(x, z, Height, a_ChunkDesc.GetBlockTypes()); - break; - } - default: - { - // TODO - ASSERT(!"CompoGenBiomal: Biome not implemented yet!"); - break; - } - } - } - else - { - switch (a_ChunkDesc.GetBiome(x, z)) - { - case biDesert: - case biBeach: - { - // Fill with water, sand, sandstone and stone - FillColumnWaterSand(x, z, Height, a_ChunkDesc.GetBlockTypes()); - break; - } - default: - { - // Fill with water, sand/dirt/clay mix and stone - if (m_Noise.CubicNoise2D(0.3f * (cChunkDef::Width * ChunkX + x), 0.3f * (cChunkDef::Width * ChunkZ + z)) < 0) - { - FillColumnWaterSand(x, z, Height, a_ChunkDesc.GetBlockTypes()); - } - else - { - FillColumnWaterDirt(x, z, Height, a_ChunkDesc.GetBlockTypes()); - } - break; - } - } // switch (biome) - a_ChunkDesc.SetHeight(x, z, m_SeaLevel + 1); - } // else (under water) - a_ChunkDesc.SetBlockType(x, 0, z, E_BLOCK_BEDROCK); - } // for x - } // for z -} - - - - - -void cCompoGenBiomal::InitializeCompoGen(cIniFile & a_IniFile) -{ - m_SeaLevel = a_IniFile.GetValueSetI("Generator", "BiomalSeaLevel", m_SeaLevel) - 1; -} - - - - - -void cCompoGenBiomal::FillColumnGrass(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes) -{ - BLOCKTYPE Pattern[] = - { - E_BLOCK_GRASS, - E_BLOCK_DIRT, - E_BLOCK_DIRT, - E_BLOCK_DIRT, - } ; - FillColumnPattern(a_RelX, a_RelZ, a_Height, a_BlockTypes, Pattern, ARRAYCOUNT(Pattern)); - - for (int y = a_Height - ARRAYCOUNT(Pattern); y > 0; y--) - { - cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STONE); - } -} - - - - - -void cCompoGenBiomal::FillColumnClay(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes) -{ - BLOCKTYPE Pattern[] = - { - E_BLOCK_HARDENED_CLAY, - E_BLOCK_HARDENED_CLAY, - E_BLOCK_HARDENED_CLAY, - E_BLOCK_HARDENED_CLAY, - } ; - FillColumnPattern(a_RelX, a_RelZ, a_Height, a_BlockTypes, Pattern, ARRAYCOUNT(Pattern)); - - for (int y = a_Height - ARRAYCOUNT(Pattern); y > 0; y--) - { - cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STONE); - } -} - - - - - -void cCompoGenBiomal::FillColumnDirt(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes) -{ - for (int y = 0; y < 4; y++) - { - if (a_Height - y < 0) - { - return; - } - cChunkDef::SetBlock(a_BlockTypes, a_RelX, a_Height - y, a_RelZ, E_BLOCK_DIRT); - } - for (int y = a_Height - 4; y > 0; y--) - { - cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STONE); - } -} - - - - - -void cCompoGenBiomal::FillColumnSand(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes) -{ - BLOCKTYPE Pattern[] = - { - E_BLOCK_SAND, - E_BLOCK_SAND, - E_BLOCK_SAND, - E_BLOCK_SANDSTONE, - } ; - FillColumnPattern(a_RelX, a_RelZ, a_Height, a_BlockTypes, Pattern, ARRAYCOUNT(Pattern)); - - for (int y = a_Height - ARRAYCOUNT(Pattern); y > 0; y--) - { - cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STONE); - } -} - - - - - - -void cCompoGenBiomal::FillColumnMycelium (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes) -{ - BLOCKTYPE Pattern[] = - { - E_BLOCK_MYCELIUM, - E_BLOCK_DIRT, - E_BLOCK_DIRT, - E_BLOCK_DIRT, - } ; - FillColumnPattern(a_RelX, a_RelZ, a_Height, a_BlockTypes, Pattern, ARRAYCOUNT(Pattern)); - - for (int y = a_Height - ARRAYCOUNT(Pattern); y > 0; y--) - { - cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STONE); - } -} - - - - - -void cCompoGenBiomal::FillColumnWaterSand(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes) -{ - FillColumnSand(a_RelX, a_RelZ, a_Height, a_BlockTypes); - for (int y = a_Height + 1; y <= m_SeaLevel + 1; y++) - { - cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STATIONARY_WATER); - } -} - - - - - -void cCompoGenBiomal::FillColumnWaterDirt(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes) -{ - // Dirt - BLOCKTYPE Pattern[] = - { - E_BLOCK_DIRT, - E_BLOCK_DIRT, - E_BLOCK_DIRT, - E_BLOCK_DIRT, - } ; - FillColumnPattern(a_RelX, a_RelZ, a_Height, a_BlockTypes, Pattern, ARRAYCOUNT(Pattern)); - - for (int y = a_Height - ARRAYCOUNT(Pattern); y > 0; y--) - { - cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STONE); - } - for (int y = a_Height + 1; y <= m_SeaLevel + 1; y++) - { - cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STATIONARY_WATER); - } -} - - - - - - -void cCompoGenBiomal::FillColumnPattern(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes, const BLOCKTYPE * a_Pattern, int a_PatternSize) -{ - for (int y = a_Height, idx = 0; (y >= 0) && (idx < a_PatternSize); y--, idx++) - { - cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, a_Pattern[idx]); - } -} - - - - - //////////////////////////////////////////////////////////////////////////////// // cCompoGenNether: @@ -540,7 +226,7 @@ cCompoGenNether::cCompoGenNether(int a_Seed) : -void cCompoGenNether::ComposeTerrain(cChunkDesc & a_ChunkDesc) +void cCompoGenNether::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) { HEIGHTTYPE MaxHeight = a_ChunkDesc.GetMaxHeight(); @@ -696,7 +382,7 @@ cCompoGenCache::~cCompoGenCache() -void cCompoGenCache::ComposeTerrain(cChunkDesc & a_ChunkDesc) +void cCompoGenCache::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) { #ifdef _DEBUG if (((m_NumHits + m_NumMisses) % 1024) == 10) @@ -739,7 +425,7 @@ void cCompoGenCache::ComposeTerrain(cChunkDesc & a_ChunkDesc) // Not in the cache: m_NumMisses++; - m_Underlying->ComposeTerrain(a_ChunkDesc); + m_Underlying->ComposeTerrain(a_ChunkDesc, a_Shape); // Insert it as the first item in the MRU order: int Idx = m_CacheOrder[m_CacheSize - 1]; diff --git a/src/Generating/CompoGen.h b/src/Generating/CompoGen.h index b145b6ba3..16c00c13d 100644 --- a/src/Generating/CompoGen.h +++ b/src/Generating/CompoGen.h @@ -38,7 +38,7 @@ protected: bool m_IsBedrocked; // cTerrainCompositionGen overrides: - virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc) override; + virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) override; virtual void InitializeCompoGen(cIniFile & a_IniFile) override; } ; @@ -55,7 +55,7 @@ public: protected: // cTerrainCompositionGen overrides: - virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc) override; + virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) override; } ; @@ -81,7 +81,7 @@ protected: BLOCKTYPE m_BlockSea; // cTerrainCompositionGen overrides: - virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc) override; + virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) override; virtual void InitializeCompoGen(cIniFile & a_IniFile) override; } ; @@ -89,40 +89,6 @@ protected: -class cCompoGenBiomal : - public cTerrainCompositionGen -{ -public: - cCompoGenBiomal(int a_Seed) : - m_Noise(a_Seed + 1000), - m_SeaLevel(62) - { - } - -protected: - - cNoise m_Noise; - int m_SeaLevel; - - // cTerrainCompositionGen overrides: - virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc) override; - virtual void InitializeCompoGen(cIniFile & a_IniFile) override; - - void FillColumnGrass (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes); - void FillColumnClay (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes); - void FillColumnDirt (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes); - void FillColumnSand (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes); - void FillColumnMycelium (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes); - void FillColumnWaterSand(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes); - void FillColumnWaterDirt(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes); - - void FillColumnPattern (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes, const BLOCKTYPE * a_Pattern, int a_PatternSize); -} ; - - - - - class cCompoGenNether : public cTerrainCompositionGen { @@ -136,7 +102,7 @@ protected: int m_Threshold; // cTerrainCompositionGen overrides: - virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc) override; + virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) override; virtual void InitializeCompoGen(cIniFile & a_IniFile) override; } ; @@ -153,7 +119,7 @@ public: ~cCompoGenCache(); // cTerrainCompositionGen override: - virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc) override; + virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) override; virtual void InitializeCompoGen(cIniFile & a_IniFile) override; protected: diff --git a/src/Generating/CompoGenBiomal.cpp b/src/Generating/CompoGenBiomal.cpp new file mode 100644 index 000000000..1e3363606 --- /dev/null +++ b/src/Generating/CompoGenBiomal.cpp @@ -0,0 +1,799 @@ + +// CompoGenBiomal.cpp + +// Implements the cCompoGenBiomal class representing the biome-aware composition generator + +#include "Globals.h" +#include "ComposableGenerator.h" +#include "../IniFile.h" +#include "../Noise.h" +#include "../LinearUpscale.h" + + + + + +//////////////////////////////////////////////////////////////////////////////// +// cPattern: + +/** This class is used to store a column pattern initialized at runtime, +so that the program doesn't need to explicitly set 256 values for each pattern +Each pattern has 256 blocks so that there's no need to check pattern bounds when assigning the +pattern - there will always be enough pattern left, even for the whole-chunk-height columns. */ +class cPattern +{ +public: + struct BlockInfo + { + BLOCKTYPE m_BlockType; + NIBBLETYPE m_BlockMeta; + }; + + cPattern(BlockInfo * a_TopBlocks, size_t a_Count) + { + // Copy the pattern into the top: + for (size_t i = 0; i < a_Count; i++) + { + m_Pattern[i] = a_TopBlocks[i]; + } + + // Fill the rest with stone: + static BlockInfo Stone = {E_BLOCK_STONE, 0}; + for (size_t i = a_Count; i < cChunkDef::Height; i++) + { + m_Pattern[i] = Stone; + } + } + + const BlockInfo * Get(void) const { return m_Pattern; } + +protected: + BlockInfo m_Pattern[cChunkDef::Height]; +} ; + + + + + +//////////////////////////////////////////////////////////////////////////////// +// The arrays to use for the top block pattern definitions: + +static cPattern::BlockInfo tbGrass[] = +{ + {E_BLOCK_GRASS, 0}, + {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, + {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, + {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, +} ; + +static cPattern::BlockInfo tbSand[] = +{ + { E_BLOCK_SAND, 0}, + { E_BLOCK_SAND, 0}, + { E_BLOCK_SAND, 0}, + { E_BLOCK_SANDSTONE, 0}, +} ; + +static cPattern::BlockInfo tbDirt[] = +{ + {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, + {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, + {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, + {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, +} ; + +static cPattern::BlockInfo tbPodzol[] = +{ + {E_BLOCK_DIRT, E_META_DIRT_PODZOL}, + {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, + {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, + {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, +} ; + +static cPattern::BlockInfo tbGrassLess[] = +{ + {E_BLOCK_DIRT, E_META_DIRT_GRASSLESS}, + {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, + {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, + {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, +} ; + +static cPattern::BlockInfo tbMycelium[] = +{ + {E_BLOCK_MYCELIUM, 0}, + {E_BLOCK_DIRT, 0}, + {E_BLOCK_DIRT, 0}, + {E_BLOCK_DIRT, 0}, +} ; + +static cPattern::BlockInfo tbGravel[] = +{ + {E_BLOCK_GRAVEL, 0}, + {E_BLOCK_GRAVEL, 0}, + {E_BLOCK_GRAVEL, 0}, + {E_BLOCK_STONE, 0}, +} ; + +static cPattern::BlockInfo tbStone[] = +{ + {E_BLOCK_STONE, 0}, + {E_BLOCK_STONE, 0}, + {E_BLOCK_STONE, 0}, + {E_BLOCK_STONE, 0}, +} ; + + + +//////////////////////////////////////////////////////////////////////////////// +// Ocean floor pattern top-block definitions: + +static cPattern::BlockInfo tbOFSand[] = +{ + {E_BLOCK_SAND, 0}, + {E_BLOCK_SAND, 0}, + {E_BLOCK_SAND, 0}, + {E_BLOCK_SANDSTONE, 0} +} ; + +static cPattern::BlockInfo tbOFClay[] = +{ + { E_BLOCK_CLAY, 0}, + { E_BLOCK_CLAY, 0}, + { E_BLOCK_SAND, 0}, + { E_BLOCK_SAND, 0}, +} ; + +static cPattern::BlockInfo tbOFOrangeClay[] = +{ + { E_BLOCK_STAINED_CLAY, E_META_STAINED_GLASS_ORANGE}, + { E_BLOCK_STAINED_CLAY, E_META_STAINED_GLASS_ORANGE}, + { E_BLOCK_STAINED_CLAY, E_META_STAINED_GLASS_ORANGE}, +} ; + + + + + + +//////////////////////////////////////////////////////////////////////////////// +// Individual patterns to use: + +static cPattern patGrass (tbGrass, ARRAYCOUNT(tbGrass)); +static cPattern patSand (tbSand, ARRAYCOUNT(tbSand)); +static cPattern patDirt (tbDirt, ARRAYCOUNT(tbDirt)); +static cPattern patPodzol (tbPodzol, ARRAYCOUNT(tbPodzol)); +static cPattern patGrassLess(tbGrassLess, ARRAYCOUNT(tbGrassLess)); +static cPattern patMycelium (tbMycelium, ARRAYCOUNT(tbMycelium)); +static cPattern patGravel (tbGravel, ARRAYCOUNT(tbGravel)); +static cPattern patStone (tbStone, ARRAYCOUNT(tbStone)); + +static cPattern patOFSand (tbOFSand, ARRAYCOUNT(tbOFSand)); +static cPattern patOFClay (tbOFClay, ARRAYCOUNT(tbOFClay)); +static cPattern patOFOrangeClay(tbOFOrangeClay, ARRAYCOUNT(tbOFOrangeClay)); + + + + + +//////////////////////////////////////////////////////////////////////////////// +// cCompoGenBiomal: + +class cCompoGenBiomal : + public cTerrainCompositionGen +{ +public: + cCompoGenBiomal(int a_Seed) : + m_SeaLevel(62), + m_OceanFloorSelect(a_Seed + 1), + m_MesaFloor(a_Seed + 2) + { + initMesaPattern(a_Seed); + } + +protected: + /** The block height at which water is generated instead of air. */ + int m_SeaLevel; + + /** The pattern used for mesa biomes. Initialized by seed on generator creation. */ + cPattern::BlockInfo m_MesaPattern[2 * cChunkDef::Height]; + + /** Noise used for selecting between dirt and sand on the ocean floor. */ + cNoise m_OceanFloorSelect; + + /** Noise used for the floor of the clay blocks in mesa biomes. */ + cNoise m_MesaFloor; + + + // cTerrainCompositionGen overrides: + virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) override + { + a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0); + for (int z = 0; z < cChunkDef::Width; z++) + { + for (int x = 0; x < cChunkDef::Width; x++) + { + ComposeColumn(a_ChunkDesc, x, z, &(a_Shape[x * 256 + z * 16 * 256])); + } // for x + } // for z + } + + + + virtual void InitializeCompoGen(cIniFile & a_IniFile) override + { + m_SeaLevel = a_IniFile.GetValueSetI("Generator", "SeaLevel", m_SeaLevel) - 1; + } + + + + /** Initializes the m_MesaPattern with a pattern based on the generator's seed. */ + void initMesaPattern(int a_Seed) + { + // In a loop, choose whether to use one, two or three layers of stained clay, then choose a color and width for each layer + // Separate each group with another layer of hardened clay + cNoise patternNoise((unsigned)a_Seed); + static NIBBLETYPE allowedColors[] = + { + E_META_STAINED_CLAY_YELLOW, + E_META_STAINED_CLAY_YELLOW, + E_META_STAINED_CLAY_RED, + E_META_STAINED_CLAY_RED, + E_META_STAINED_CLAY_WHITE, + E_META_STAINED_CLAY_BROWN, + E_META_STAINED_CLAY_BROWN, + E_META_STAINED_CLAY_BROWN, + E_META_STAINED_CLAY_ORANGE, + E_META_STAINED_CLAY_ORANGE, + E_META_STAINED_CLAY_ORANGE, + E_META_STAINED_CLAY_ORANGE, + E_META_STAINED_CLAY_ORANGE, + E_META_STAINED_CLAY_ORANGE, + E_META_STAINED_CLAY_LIGHTGRAY, + } ; + static int layerSizes[] = // Adjust the chance so that thinner layers occur more commonly + { + 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, + 3, 3, + } ; + int idx = ARRAYCOUNT(m_MesaPattern) - 1; + while (idx >= 0) + { + // A layer group of 1 - 2 color stained clay: + int rnd = patternNoise.IntNoise1DInt(idx) / 7; + int numLayers = (rnd % 2) + 1; + rnd /= 2; + for (int lay = 0; lay < numLayers; lay++) + { + int numBlocks = layerSizes[(rnd % ARRAYCOUNT(layerSizes))]; + NIBBLETYPE Color = allowedColors[(rnd / 4) % ARRAYCOUNT(allowedColors)]; + if ( + ((numBlocks == 3) && (numLayers == 2)) || // In two-layer mode disallow the 3-high layers: + (Color == E_META_STAINED_CLAY_WHITE)) // White stained clay can ever be only 1 block high + { + numBlocks = 1; + } + numBlocks = std::min(idx + 1, numBlocks); // Limit by idx so that we don't have to check inside the loop + rnd /= 32; + for (int block = 0; block < numBlocks; block++, idx--) + { + m_MesaPattern[idx].m_BlockMeta = Color; + m_MesaPattern[idx].m_BlockType = E_BLOCK_STAINED_CLAY; + } // for block + } // for lay + + // A layer of hardened clay in between the layer group: + int numBlocks = (rnd % 4) + 1; // All heights the same probability + if ((numLayers == 2) && (numBlocks < 4)) + { + // For two layers of stained clay, add an extra block of hardened clay: + numBlocks++; + } + numBlocks = std::min(idx + 1, numBlocks); // Limit by idx so that we don't have to check inside the loop + for (int block = 0; block < numBlocks; block++, idx--) + { + m_MesaPattern[idx].m_BlockMeta = 0; + m_MesaPattern[idx].m_BlockType = E_BLOCK_HARDENED_CLAY; + } // for block + } // while (idx >= 0) + } + + + + /** Composes a single column in a_ChunkDesc. Chooses what to do based on the biome in that column. */ + void ComposeColumn(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelZ, const Byte * a_ShapeColumn) + { + // Frequencies for the podzol floor selecting noise: + const NOISE_DATATYPE FrequencyX = 8; + const NOISE_DATATYPE FrequencyZ = 8; + + EMCSBiome Biome = a_ChunkDesc.GetBiome(a_RelX, a_RelZ); + switch (Biome) + { + case biOcean: + case biPlains: + case biForest: + case biTaiga: + case biSwampland: + case biRiver: + case biFrozenOcean: + case biFrozenRiver: + case biIcePlains: + case biIceMountains: + case biForestHills: + case biTaigaHills: + case biExtremeHillsEdge: + case biExtremeHillsPlus: + case biExtremeHills: + case biJungle: + case biJungleHills: + case biJungleEdge: + case biDeepOcean: + case biStoneBeach: + case biColdBeach: + case biBirchForest: + case biBirchForestHills: + case biRoofedForest: + case biColdTaiga: + case biColdTaigaHills: + case biSavanna: + case biSavannaPlateau: + case biSunflowerPlains: + case biFlowerForest: + case biTaigaM: + case biSwamplandM: + case biIcePlainsSpikes: + case biJungleM: + case biJungleEdgeM: + case biBirchForestM: + case biBirchForestHillsM: + case biRoofedForestM: + case biColdTaigaM: + case biSavannaM: + case biSavannaPlateauM: + { + FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, patGrass.Get(), a_ShapeColumn); + return; + } + + case biMegaTaiga: + case biMegaTaigaHills: + case biMegaSpruceTaiga: + case biMegaSpruceTaigaHills: + { + // Select the pattern to use - podzol, grass or grassless dirt: + NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(a_ChunkDesc.GetChunkX() * cChunkDef::Width + a_RelX)) / FrequencyX; + NOISE_DATATYPE NoiseY = ((NOISE_DATATYPE)(a_ChunkDesc.GetChunkZ() * cChunkDef::Width + a_RelZ)) / FrequencyZ; + NOISE_DATATYPE Val = m_OceanFloorSelect.CubicNoise2D(NoiseX, NoiseY); + const cPattern::BlockInfo * Pattern = (Val < -0.9) ? patGrassLess.Get() : ((Val > 0) ? patPodzol.Get() : patGrass.Get()); + FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, Pattern, a_ShapeColumn); + return; + } + + case biDesertHills: + case biDesert: + case biDesertM: + case biBeach: + { + FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, patSand.Get(), a_ShapeColumn); + return; + } + + case biMushroomIsland: + case biMushroomShore: + { + FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, patMycelium.Get(), a_ShapeColumn); + return; + } + + case biMesa: + case biMesaPlateauF: + case biMesaPlateau: + case biMesaBryce: + case biMesaPlateauFM: + case biMesaPlateauM: + { + // Mesa biomes need special handling, because they don't follow the usual "4 blocks from top pattern", + // instead, they provide a "from bottom" pattern with varying base height, + // usually 4 blocks below the ocean level + FillColumnMesa(a_ChunkDesc, a_RelX, a_RelZ, a_ShapeColumn); + return; + } + + case biExtremeHillsPlusM: + case biExtremeHillsM: + { + // Select the pattern to use - gravel, stone or grass: + NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(a_ChunkDesc.GetChunkX() * cChunkDef::Width + a_RelX)) / FrequencyX; + NOISE_DATATYPE NoiseY = ((NOISE_DATATYPE)(a_ChunkDesc.GetChunkZ() * cChunkDef::Width + a_RelZ)) / FrequencyZ; + NOISE_DATATYPE Val = m_OceanFloorSelect.CubicNoise2D(NoiseX, NoiseY); + const cPattern::BlockInfo * Pattern = (Val < 0.0) ? patStone.Get() : patGrass.Get(); + FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, Pattern, a_ShapeColumn); + return; + } + default: + { + ASSERT(!"Unhandled biome"); + return; + } + } // switch (Biome) + } + + + + /** Fills the specified column with the specified pattern; restarts the pattern when air is reached, + switches to ocean floor pattern if ocean is reached. Always adds bedrock at the very bottom. */ + void FillColumnPattern(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelZ, const cPattern::BlockInfo * a_Pattern, const Byte * a_ShapeColumn) + { + bool HasHadWater = false; + int PatternIdx = 0; + for (int y = a_ChunkDesc.GetHeight(a_RelX, a_RelZ); y > 0; y--) + { + if (a_ShapeColumn[y] > 0) + { + // "ground" part, use the pattern: + a_ChunkDesc.SetBlockTypeMeta(a_RelX, y, a_RelZ, a_Pattern[PatternIdx].m_BlockType, a_Pattern[PatternIdx].m_BlockMeta); + PatternIdx++; + continue; + } + + // "air" or "water" part: + // Reset the pattern index to zero, so that the pattern is repeated from the top again: + PatternIdx = 0; + + if (y >= m_SeaLevel) + { + // "air" part, do nothing + continue; + } + + a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_STATIONARY_WATER); + if (HasHadWater) + { + continue; + } + + // Select the ocean-floor pattern to use: + if (a_ChunkDesc.GetBiome(a_RelX, a_RelZ) == biDeepOcean) + { + a_Pattern = patGravel.Get(); + } + else + { + a_Pattern = ChooseOceanFloorPattern(a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ(), a_RelX, a_RelZ); + } + HasHadWater = true; + } // for y + a_ChunkDesc.SetBlockType(a_RelX, 0, a_RelZ, E_BLOCK_BEDROCK); + } + + + + /** Fills the specified column with mesa pattern, based on the column height */ + void FillColumnMesa(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelZ, const Byte * a_ShapeColumn) + { + // Frequencies for the clay floor noise: + const NOISE_DATATYPE FrequencyX = 50; + const NOISE_DATATYPE FrequencyZ = 50; + + int Top = a_ChunkDesc.GetHeight(a_RelX, a_RelZ); + if (Top < m_SeaLevel) + { + // The terrain is below sealevel, handle as regular ocean with red sand floor: + FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, patOFOrangeClay.Get(), a_ShapeColumn); + return; + } + + NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(a_ChunkDesc.GetChunkX() * cChunkDef::Width + a_RelX)) / FrequencyX; + NOISE_DATATYPE NoiseY = ((NOISE_DATATYPE)(a_ChunkDesc.GetChunkZ() * cChunkDef::Width + a_RelZ)) / FrequencyZ; + int ClayFloor = m_SeaLevel - 6 + (int)(4.f * m_MesaFloor.CubicNoise2D(NoiseX, NoiseY)); + if (ClayFloor >= Top) + { + ClayFloor = Top - 1; + } + + if (Top - m_SeaLevel < 5) + { + // Simple case: top is red sand, then hardened clay down to ClayFloor, then stone: + a_ChunkDesc.SetBlockTypeMeta(a_RelX, Top, a_RelZ, E_BLOCK_SAND, E_META_SAND_RED); + for (int y = Top - 1; y >= ClayFloor; y--) + { + a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_HARDENED_CLAY); + } + for (int y = ClayFloor - 1; y > 0; y--) + { + a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_STONE); + } + a_ChunkDesc.SetBlockType(a_RelX, 0, a_RelZ, E_BLOCK_BEDROCK); + return; + } + + // Difficult case: use the mesa pattern and watch for overhangs: + int PatternIdx = cChunkDef::Height - (Top - ClayFloor); // We want the block at index ClayFloor to be pattern's 256th block (first stone) + const cPattern::BlockInfo * Pattern = m_MesaPattern; + bool HasHadWater = false; + for (int y = Top; y > 0; y--) + { + if (a_ShapeColumn[y] > 0) + { + // "ground" part, use the pattern: + a_ChunkDesc.SetBlockTypeMeta(a_RelX, y, a_RelZ, Pattern[PatternIdx].m_BlockType, Pattern[PatternIdx].m_BlockMeta); + PatternIdx++; + continue; + } + + if (y >= m_SeaLevel) + { + // "air" part, do nothing + continue; + } + + // "water" part, fill with water and choose new pattern for ocean floor, if not chosen already: + PatternIdx = 0; + a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_STATIONARY_WATER); + if (HasHadWater) + { + continue; + } + + // Select the ocean-floor pattern to use: + Pattern = ChooseOceanFloorPattern(a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ(), a_RelX, a_RelZ); + HasHadWater = true; + } // for y + a_ChunkDesc.SetBlockType(a_RelX, 0, a_RelZ, E_BLOCK_BEDROCK); + } + + + + /** Returns the pattern to use for an ocean floor in the specified column. + The returned pattern is guaranteed to be 256 blocks long. */ + const cPattern::BlockInfo * ChooseOceanFloorPattern(int a_ChunkX, int a_ChunkZ, int a_RelX, int a_RelZ) + { + // Frequencies for the ocean floor selecting noise: + const NOISE_DATATYPE FrequencyX = 3; + const NOISE_DATATYPE FrequencyZ = 3; + + // Select the ocean-floor pattern to use: + NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(a_ChunkX * cChunkDef::Width + a_RelX)) / FrequencyX; + NOISE_DATATYPE NoiseY = ((NOISE_DATATYPE)(a_ChunkZ * cChunkDef::Width + a_RelZ)) / FrequencyZ; + NOISE_DATATYPE Val = m_OceanFloorSelect.CubicNoise2D(NoiseX, NoiseY); + if (Val < -0.95) + { + return patOFClay.Get(); + } + else if (Val < 0) + { + return patOFSand.Get(); + } + else + { + return patDirt.Get(); + } + } + + + + #if 0 + /** Fills a single column with grass-based terrain (grass or water, dirt, stone). */ + void FillColumnGrass(int a_RelX, int a_RelZ, const Byte * a_ShapeColumn, cChunkDesc & a_ChunkDesc) + { + static const PatternItem pattern[] = + { + { E_BLOCK_GRASS, 0}, + { E_BLOCK_DIRT, 0}, + { E_BLOCK_DIRT, 0}, + { E_BLOCK_DIRT, 0}, + } ; + FillColumnPattern(a_RelX, a_RelZ, a_ShapeColumn, a_ChunkDesc, pattern, ARRAYCOUNT(pattern)); + } + + + + /** Fills a single column with grass-based terrain (grass or water, dirt, stone). */ + void FillColumnStone(int a_RelX, int a_RelZ, const Byte * a_ShapeColumn, cChunkDesc & a_ChunkDesc) + { + static const PatternItem pattern[] = + { + { E_BLOCK_STONE, 0}, + } ; + FillColumnPattern(a_RelX, a_RelZ, a_ShapeColumn, a_ChunkDesc, pattern, ARRAYCOUNT(pattern)); + } + + + + /** Fills a single column with Mesa-like terrain (variations of clay). */ + void FillColumnMesa(int a_RelX, int a_RelZ, const Byte * a_ShapeColumn, cChunkDesc & a_ChunkDesc) + { + // Fill with grass and dirt on the very top of mesa plateaus: + size_t curIdx = 0; + for (int y = 255; y > m_MesaDirtLevel; y--) + { + if (a_ShapeColumn[y] > 0) + { + a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, (curIdx > 0) ? E_BLOCK_DIRT : E_BLOCK_GRASS); + curIdx += 1; + } + else + { + curIdx = 0; + } + } // for y + + // Fill with clays from the DirtLevel down to SandLevel: + for (int y = m_MesaDirtLevel; y > m_MesaSandLevel; y--) + { + if (a_ShapeColumn[y] > 0) + { + a_ChunkDesc.SetBlockTypeMeta(a_RelX, y, a_RelZ, m_MesaPattern[y].m_BlockType, m_MesaPattern[y].m_BlockMeta); + } + else + { + curIdx = 0; + } + } // for y + + // If currently air, switch to red sand pattern: + static const PatternItem redSandPattern[] = + { + { E_BLOCK_SAND, E_META_SAND_RED}, + { E_BLOCK_STAINED_CLAY, E_META_STAINED_CLAY_ORANGE}, + { E_BLOCK_STAINED_CLAY, E_META_STAINED_CLAY_ORANGE}, + { E_BLOCK_STAINED_CLAY, E_META_STAINED_CLAY_ORANGE}, + }; + Pattern pattern; + size_t patternSize; + if (curIdx == 0) + { + pattern = redSandPattern; + patternSize = ARRAYCOUNT(redSandPattern); + } + else + { + pattern = m_MesaPattern + m_MesaSandLevel; + patternSize = static_cast(m_MesaSandLevel); + } + + // Fill with current pattern (MesaPattern or RedSand) until sealevel: + for (int y = m_MesaSandLevel; y > m_SeaLevel; y--) + { + if (a_ShapeColumn[y] > 0) + { + if (curIdx >= patternSize) + { + a_ChunkDesc.SetBlockTypeMeta(a_RelX, y, a_RelZ, E_BLOCK_STAINED_CLAY, E_META_STAINED_CLAY_ORANGE); + } + else + { + a_ChunkDesc.SetBlockTypeMeta(a_RelX, y, a_RelZ, pattern[curIdx].m_BlockType, pattern[curIdx].m_BlockMeta); + } + curIdx += 1; + } + else + { + // Air resets the pattern to red sand: + curIdx = 0; + pattern = redSandPattern; + patternSize = ARRAYCOUNT(redSandPattern); + } + } // for y + + // If there is an ocean, fill it with water and then redsand: + int y = m_SeaLevel; + for (; y > 0; y--) + { + if ((a_ShapeColumn[y] == 0) || (curIdx >= ARRAYCOUNT(redSandPattern))) + { + // water pocket or out of red sand pattern, use stone from now on + break; + } + a_ChunkDesc.SetBlockTypeMeta(a_RelX, y, a_RelZ, E_BLOCK_STAINED_CLAY, E_META_STAINED_CLAY_ORANGE); + curIdx = curIdx + 1; + } // for y + + // The rest should be filled with stone: + for (; y > 0; y--) + { + if (a_ShapeColumn[y] > 0) + { + a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_STONE); + } + } // for y + } + + + + /** Fills a single column with megataiga-based terrain (grass or podzol on top). */ + void FillColumnMegaTaiga(int a_RelX, int a_RelZ, const Byte * a_ShapeColumn, cChunkDesc & a_ChunkDesc) + { + // TODO + } + + + + /** Fills a single column with sand-based terrain (such as desert or beach). */ + void FillColumnSand(int a_RelX, int a_RelZ, const Byte * a_ShapeColumn, cChunkDesc & a_ChunkDesc) + { + static const PatternItem pattern[] = + { + { E_BLOCK_SAND, 0}, + { E_BLOCK_SAND, 0}, + { E_BLOCK_SAND, 0}, + { E_BLOCK_SANDSTONE, 0}, + } ; + FillColumnPattern(a_RelX, a_RelZ, a_ShapeColumn, a_ChunkDesc, pattern, ARRAYCOUNT(pattern)); + } + + + + void FillColumnMycelium(int a_RelX, int a_RelZ, const Byte * a_ShapeColumn, cChunkDesc & a_ChunkDesc) + { + static const PatternItem pattern[] = + { + { E_BLOCK_MYCELIUM, 0}, + { E_BLOCK_DIRT, 0}, + { E_BLOCK_DIRT, 0}, + { E_BLOCK_DIRT, 0}, + } ; + FillColumnPattern(a_RelX, a_RelZ, a_ShapeColumn, a_ChunkDesc, pattern, ARRAYCOUNT(pattern)); + } + + + + /** Fills the column with the specified pattern, repeating it if there's an air pocket in between. */ + void FillColumnPattern(int a_RelX, int a_RelZ, const Byte * a_ShapeColumn, cChunkDesc & a_ChunkDesc, Pattern a_Pattern, size_t a_PatternSize) + { + // Fill with pattern until sealevel: + size_t curIdx = 0; + for (int y = 255; y > m_SeaLevel; y--) + { + if (a_ShapeColumn[y] > 0) + { + // Continue with the pattern: + if (curIdx >= a_PatternSize) + { + a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_STONE); + } + else + { + a_ChunkDesc.SetBlockTypeMeta(a_RelX, y, a_RelZ, a_Pattern[curIdx].m_BlockType, a_Pattern[curIdx].m_BlockMeta); + } + curIdx += 1; + } + else + { + // Air pocket, restart the pattern: + curIdx = 0; + } + } // for y + + // From sealevel downward use the ocean floor pattern: + FillOceanFloor(a_RelX, a_RelZ, a_ShapeColumn, a_ChunkDesc, a_Pattern, a_PatternSize, curIdx); + } + + + /** Fills the blocks from sealevel down to bottom with ocean-floor pattern. + a_PatternStartOffset specifies the offset at which to start the pattern, in case there was air just above. */ + void FillOceanFloor(int a_RelX, int a_RelZ, const Byte * a_ShapeColumn, cChunkDesc & a_ChunkDesc, Pattern a_Pattern, size_t a_PatternSize, size_t a_PatternStartOffset) + { + for (int y = m_SeaLevel; y > 0; y--) + { + if (a_ShapeColumn[y] > 0) + { + // TODO + } + } // for y + } + #endif +} ; + + + + + +cTerrainCompositionGenPtr CreateCompoGenBiomal(int a_Seed) +{ + return std::make_shared(a_Seed); +} + + + diff --git a/src/Generating/CompoGenBiomal.h b/src/Generating/CompoGenBiomal.h new file mode 100644 index 000000000..a3a65d3dc --- /dev/null +++ b/src/Generating/CompoGenBiomal.h @@ -0,0 +1,21 @@ + +// CompoGenBiomal.h + + + + + +#pragma once + +#include "ComposableGenerator.h" + + + + + +/** Returns a new instance of the Biomal composition generator. */ +cTerrainCompositionGenPtr CreateCompoGenBiomal(int a_Seed); + + + + diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index 5f46574c7..5420e12ac 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -17,6 +17,8 @@ #include "StructGen.h" #include "FinishGen.h" +#include "CompoGenBiomal.h" + #include "Caves.h" #include "DistortedHeightmap.h" #include "DungeonRoomsFinisher.h" @@ -39,7 +41,7 @@ //////////////////////////////////////////////////////////////////////////////// // cTerrainCompositionGen: -cTerrainCompositionGenPtr cTerrainCompositionGen::CreateCompositionGen(cIniFile & a_IniFile, cBiomeGenPtr a_BiomeGen, cTerrainHeightGen & a_HeightGen, int a_Seed) +cTerrainCompositionGenPtr cTerrainCompositionGen::CreateCompositionGen(cIniFile & a_IniFile, cBiomeGenPtr a_BiomeGen, cTerrainShapeGenPtr a_ShapeGen, int a_Seed) { AString CompoGenName = a_IniFile.GetValueSet("Generator", "CompositionGen", ""); if (CompoGenName.empty()) @@ -48,63 +50,52 @@ cTerrainCompositionGenPtr cTerrainCompositionGen::CreateCompositionGen(cIniFile CompoGenName = "Biomal"; } - cTerrainCompositionGen * res = nullptr; - if (NoCaseCompare(CompoGenName, "sameblock") == 0) + // Compositor list is alpha-sorted + cTerrainCompositionGenPtr res; + if (NoCaseCompare(CompoGenName, "Biomal") == 0) { - res = new cCompoGenSameBlock; + res = CreateCompoGenBiomal(a_Seed); } - else if (NoCaseCompare(CompoGenName, "debugbiomes") == 0) + else if (NoCaseCompare(CompoGenName, "BiomalNoise3D") == 0) { - res = new cCompoGenDebugBiomes; + // The composition that used to be provided with BiomalNoise3D is now provided by the Biomal compositor: + res = CreateCompoGenBiomal(a_Seed); } - else if (NoCaseCompare(CompoGenName, "classic") == 0) + else if (NoCaseCompare(CompoGenName, "Classic") == 0) { - res = new cCompoGenClassic; + res = std::make_shared(); } - else if (NoCaseCompare(CompoGenName, "DistortedHeightmap") == 0) + else if (NoCaseCompare(CompoGenName, "DebugBiomes") == 0) { - res = new cDistortedHeightmap(a_Seed, a_BiomeGen); + res = std::make_shared(); } - else if (NoCaseCompare(CompoGenName, "end") == 0) + else if (NoCaseCompare(CompoGenName, "DistortedHeightmap") == 0) { - res = new cEndGen(a_Seed); + // The composition that used to be provided with DistortedHeightmap is now provided by the Biomal compositor: + res = CreateCompoGenBiomal(a_Seed); } - else if (NoCaseCompare(CompoGenName, "nether") == 0) + else if (NoCaseCompare(CompoGenName, "End") == 0) { - res = new cCompoGenNether(a_Seed); + res = std::make_shared(a_Seed); } - else if (NoCaseCompare(CompoGenName, "BiomalNoise3D") == 0) + else if (NoCaseCompare(CompoGenName, "Nether") == 0) { - res = new cBiomalNoise3DComposable(a_Seed, a_BiomeGen); + res = std::make_shared(a_Seed); } else if (NoCaseCompare(CompoGenName, "Noise3D") == 0) { - res = new cNoise3DComposable(a_Seed); + // The composition that used to be provided with Noise3D is now provided by the Biomal compositor: + res = CreateCompoGenBiomal(a_Seed); } - else if (NoCaseCompare(CompoGenName, "biomal") == 0) + else if (NoCaseCompare(CompoGenName, "SameBlock") == 0) { - res = new cCompoGenBiomal(a_Seed); - - /* - // Performance-testing: - LOGINFO("Measuring performance of cCompoGenBiomal..."); - clock_t BeginTick = clock(); - for (int x = 0; x < 500; x++) - { - cChunkDesc Desc(200 + x * 8, 200 + x * 8); - a_BiomeGen->GenBiomes(Desc.GetChunkX(), Desc.GetChunkZ(), Desc.GetBiomeMap()); - a_HeightGen->GenHeightMap(Desc.GetChunkX(), Desc.GetChunkZ(), Desc.GetHeightMap()); - res->ComposeTerrain(Desc); - } - clock_t Duration = clock() - BeginTick; - LOGINFO("CompositionGen for 500 chunks took %d ticks (%.02f sec)", Duration, (double)Duration / CLOCKS_PER_SEC); - //*/ + res = std::make_shared(); } else { LOGWARN("Unknown CompositionGen \"%s\", using \"Biomal\" instead.", CompoGenName.c_str()); a_IniFile.SetValue("Generator", "CompositionGen", "Biomal"); - return CreateCompositionGen(a_IniFile, a_BiomeGen, a_HeightGen, a_Seed); + return CreateCompositionGen(a_IniFile, a_BiomeGen, a_ShapeGen, a_Seed); } ASSERT(res != nullptr); @@ -124,7 +115,7 @@ cTerrainCompositionGenPtr cTerrainCompositionGen::CreateCompositionGen(cIniFile cComposableGenerator::cComposableGenerator(cChunkGenerator & a_ChunkGenerator) : super(a_ChunkGenerator), m_BiomeGen(), - m_HeightGen(), + m_ShapeGen(), m_CompositionGen() { } @@ -138,7 +129,7 @@ void cComposableGenerator::Initialize(cIniFile & a_IniFile) super::Initialize(a_IniFile); InitBiomeGen(a_IniFile); - InitHeightGen(a_IniFile); + InitShapeGen(a_IniFile); InitCompositionGen(a_IniFile); InitFinishGens(a_IniFile); } @@ -166,15 +157,22 @@ void cComposableGenerator::DoGenerate(int a_ChunkX, int a_ChunkZ, cChunkDesc & a m_BiomeGen->GenBiomes(a_ChunkX, a_ChunkZ, a_ChunkDesc.GetBiomeMap()); } + cChunkDesc::Shape shape; if (a_ChunkDesc.IsUsingDefaultHeight()) { - m_HeightGen->GenHeightMap(a_ChunkX, a_ChunkZ, a_ChunkDesc.GetHeightMap()); + m_ShapeGen->GenShape(a_ChunkX, a_ChunkZ, shape); + a_ChunkDesc.SetHeightFromShape(shape); + } + else + { + // Convert the heightmap in a_ChunkDesc into shape: + a_ChunkDesc.GetShapeFromHeight(shape); } bool ShouldUpdateHeightmap = false; if (a_ChunkDesc.IsUsingDefaultComposition()) { - m_CompositionGen->ComposeTerrain(a_ChunkDesc); + m_CompositionGen->ComposeTerrain(a_ChunkDesc, shape); ShouldUpdateHeightmap = true; } @@ -234,13 +232,15 @@ void cComposableGenerator::InitBiomeGen(cIniFile & a_IniFile) -void cComposableGenerator::InitHeightGen(cIniFile & a_IniFile) +void cComposableGenerator::InitShapeGen(cIniFile & a_IniFile) { bool CacheOffByDefault = false; - m_HeightGen = cTerrainHeightGen::CreateHeightGen(a_IniFile, m_BiomeGen, m_ChunkGenerator.GetSeed(), CacheOffByDefault); + m_ShapeGen = cTerrainShapeGen::CreateShapeGen(a_IniFile, m_BiomeGen, m_ChunkGenerator.GetSeed(), CacheOffByDefault); + /* + // TODO // Add a cache, if requested: - int CacheSize = a_IniFile.GetValueSetI("Generator", "HeightGenCacheSize", CacheOffByDefault ? 0 : 64); + int CacheSize = a_IniFile.GetValueSetI("Generator", "ShapeGenCacheSize", CacheOffByDefault ? 0 : 64); if (CacheSize > 0) { if (CacheSize < 4) @@ -253,6 +253,7 @@ void cComposableGenerator::InitHeightGen(cIniFile & a_IniFile) LOGD("Using a cache for Heightgen of size %d.", CacheSize); m_HeightGen = cTerrainHeightGenPtr(new cHeiGenCache(m_HeightGen, CacheSize)); } + */ } @@ -261,7 +262,7 @@ void cComposableGenerator::InitHeightGen(cIniFile & a_IniFile) void cComposableGenerator::InitCompositionGen(cIniFile & a_IniFile) { - m_CompositionGen = cTerrainCompositionGen::CreateCompositionGen(a_IniFile, m_BiomeGen, *m_HeightGen, m_ChunkGenerator.GetSeed()); + m_CompositionGen = cTerrainCompositionGen::CreateCompositionGen(a_IniFile, m_BiomeGen, m_ShapeGen, m_ChunkGenerator.GetSeed()); int CompoGenCacheSize = a_IniFile.GetValueSetI("Generator", "CompositionGenCacheSize", 64); if (CompoGenCacheSize > 1) @@ -333,7 +334,7 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) int MaxSize = a_IniFile.GetValueSetI("Generator", "DungeonRoomsMaxSize", 7); int MinSize = a_IniFile.GetValueSetI("Generator", "DungeonRoomsMinSize", 5); AString HeightDistrib = a_IniFile.GetValueSet ("Generator", "DungeonRoomsHeightDistrib", "0, 0; 10, 10; 11, 500; 40, 500; 60, 40; 90, 1"); - m_FinishGens.push_back(cFinishGenPtr(new cDungeonRoomsFinisher(m_HeightGen, Seed, GridSize, MaxSize, MinSize, HeightDistrib))); + m_FinishGens.push_back(cFinishGenPtr(new cDungeonRoomsFinisher(m_ShapeGen, Seed, GridSize, MaxSize, MinSize, HeightDistrib))); } else if (NoCaseCompare(*itr, "Ice") == 0) { @@ -342,7 +343,7 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) else if (NoCaseCompare(*itr, "LavaLakes") == 0) { int Probability = a_IniFile.GetValueSetI("Generator", "LavaLakesProbability", 10); - m_FinishGens.push_back(cFinishGenPtr(new cStructGenLakes(Seed * 5 + 16873, E_BLOCK_STATIONARY_LAVA, m_HeightGen, Probability))); + m_FinishGens.push_back(cFinishGenPtr(new cStructGenLakes(Seed * 5 + 16873, E_BLOCK_STATIONARY_LAVA, m_ShapeGen, Probability))); } else if (NoCaseCompare(*itr, "LavaSprings") == 0) { @@ -580,7 +581,7 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) } else if (NoCaseCompare(*itr, "Trees") == 0) { - m_FinishGens.push_back(cFinishGenPtr(new cStructGenTrees(Seed, m_BiomeGen, m_HeightGen, m_CompositionGen))); + m_FinishGens.push_back(cFinishGenPtr(new cStructGenTrees(Seed, m_BiomeGen, m_ShapeGen, m_CompositionGen))); } else if (NoCaseCompare(*itr, "UnderwaterBases") == 0) { @@ -588,7 +589,7 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) int MaxOffset = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxOffset", 128); int MaxDepth = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxDepth", 7); int MaxSize = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxSize", 128); - m_FinishGens.push_back(cFinishGenPtr(new cUnderwaterBaseGen(Seed, GridSize, MaxOffset, MaxDepth, MaxSize, m_BiomeGen))); + m_FinishGens.push_back(std::make_shared(Seed, GridSize, MaxOffset, MaxDepth, MaxSize, m_BiomeGen)); } else if (NoCaseCompare(*itr, "Villages") == 0) { @@ -598,12 +599,12 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) int MaxSize = a_IniFile.GetValueSetI("Generator", "VillageMaxSize", 128); int MinDensity = a_IniFile.GetValueSetI("Generator", "VillageMinDensity", 50); int MaxDensity = a_IniFile.GetValueSetI("Generator", "VillageMaxDensity", 80); - m_FinishGens.push_back(cFinishGenPtr(new cVillageGen(Seed, GridSize, MaxOffset, MaxDepth, MaxSize, MinDensity, MaxDensity, m_BiomeGen, m_HeightGen))); + m_FinishGens.push_back(std::make_shared(Seed, GridSize, MaxOffset, MaxDepth, MaxSize, MinDensity, MaxDensity, m_BiomeGen, m_CompositedHeightCache)); } else if (NoCaseCompare(*itr, "WaterLakes") == 0) { int Probability = a_IniFile.GetValueSetI("Generator", "WaterLakesProbability", 25); - m_FinishGens.push_back(cFinishGenPtr(new cStructGenLakes(Seed * 3 + 652, E_BLOCK_STATIONARY_WATER, m_HeightGen, Probability))); + m_FinishGens.push_back(cFinishGenPtr(new cStructGenLakes(Seed * 3 + 652, E_BLOCK_STATIONARY_WATER, m_ShapeGen, Probability))); } else if (NoCaseCompare(*itr, "WaterSprings") == 0) { diff --git a/src/Generating/ComposableGenerator.h b/src/Generating/ComposableGenerator.h index a091f8d53..86c30e090 100644 --- a/src/Generating/ComposableGenerator.h +++ b/src/Generating/ComposableGenerator.h @@ -26,20 +26,16 @@ See http://forum.mc-server.org/showthread.php?tid=409 for details. // Forward-declare the shared pointers to subgenerator classes: class cBiomeGen; +class cTerrainShapeGen; class cTerrainHeightGen; class cTerrainCompositionGen; class cFinishGen; typedef SharedPtr cBiomeGenPtr; +typedef SharedPtr cTerrainShapeGenPtr; typedef SharedPtr cTerrainHeightGenPtr; typedef SharedPtr cTerrainCompositionGenPtr; typedef SharedPtr cFinishGenPtr; -// fwd: Noise3DGenerator.h -class cNoise3DComposable; - -// fwd: DistortedHeightmap.h -class cDistortedHeightmap; - @@ -70,28 +66,54 @@ public: -/** The interface that a terrain height generator must implement -A terrain height generator takes chunk coords on input and outputs an array of terrain heights for that chunk. -The output array is sequenced in the same way as the BiomeGen's biome data. +/** The interface that a terrain shape generator must implement +A terrain shape generator takes chunk coords on input and outputs a 3D array of "shape" for that chunk. The shape here +represents the distinction between air and solid; there's no representation of Water since that is added by the +composition geenrator. +The output array is indexed [y + 256 * z + 16 * 256 * x], so that it's fast to later compose a single column of the terrain, +which is the dominant operation following the shape generation. The generator may request biome information from the underlying BiomeGen, it may even request information for -other chunks than the one it's currently generating (possibly neighbors - for averaging) +other chunks than the one it's currently generating (neighbors - for averaging) */ -class cTerrainHeightGen +class cTerrainShapeGen { public: - virtual ~cTerrainHeightGen() {} // Force a virtual destructor in descendants + virtual ~cTerrainShapeGen() {} // Force a virtual destructor in descendants - /** Generates heightmap for the given chunk */ - virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) = 0; + /** Generates the shape for the given chunk */ + virtual void GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape) = 0; /** Reads parameters from the ini file, prepares generator for use. */ - virtual void InitializeHeightGen(cIniFile & a_IniFile) {} + virtual void InitializeShapeGen(cIniFile & a_IniFile) {} - /** Creates the correct TerrainHeightGen descendant based on the ini file settings and the seed provided. - a_BiomeGen is the underlying biome generator, some height generators may depend on it to generate more biomes + /** Creates the correct TerrainShapeGen descendant based on the ini file settings and the seed provided. + a_BiomeGen is the underlying biome generator, some shape generators may depend on it providing additional biomes data around the chunk a_CacheOffByDefault gets set to whether the cache should be disabled by default - Implemented in HeiGen.cpp! + Implemented in ShapeGen.cpp! */ + static cTerrainShapeGenPtr CreateShapeGen(cIniFile & a_IniFile, cBiomeGenPtr a_BiomeGen, int a_Seed, bool & a_CacheOffByDefault); +} ; + + + + + +/** The interface that is used to query terrain height from the shape generator. +Usually the structure generators require only the final heightmap, and generating the whole shape only to +consume the heightmap is wasteful, so this interface is used instead; it has a cache implemented over it so +that data is retained. */ +class cTerrainHeightGen +{ +public: + virtual ~cTerrainHeightGen() {} // Force a virtual destructor in descendants + + /** Retrieves the heightmap for the specified chunk. */ + virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) = 0; + + /** Initializes the generator, reading its parameters from the INI file. */ + virtual void InitializeHeightGen(cIniFile & a_IniFile) {} + + /** Creates a cTerrainHeightGen descendant based on the INI file settings. */ static cTerrainHeightGenPtr CreateHeightGen(cIniFile & a_IniFile, cBiomeGenPtr a_BiomeGen, int a_Seed, bool & a_CacheOffByDefault); } ; @@ -109,16 +131,18 @@ class cTerrainCompositionGen public: virtual ~cTerrainCompositionGen() {} // Force a virtual destructor in descendants - virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc) = 0; + /** Generates the chunk's composition into a_ChunkDesc, using the terrain shape provided in a_Shape. + Is expected to fill a_ChunkDesc's heightmap with the data from a_Shape. */ + virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) = 0; /** Reads parameters from the ini file, prepares generator for use. */ virtual void InitializeCompoGen(cIniFile & a_IniFile) {} /** Creates the correct TerrainCompositionGen descendant based on the ini file settings and the seed provided. - a_BiomeGen is the underlying biome generator, some composition generators may depend on it to generate more biomes - a_HeightGen is the underlying height generator, some composition generators may depend on it providing additional values + a_BiomeGen is the underlying biome generator, some composition generators may depend on it providing additional biomes around the chunk + a_ShapeGen is the underlying shape generator, some composition generators may depend on it providing additional shape around the chunk */ - static cTerrainCompositionGenPtr CreateCompositionGen(cIniFile & a_IniFile, cBiomeGenPtr a_BiomeGen, cTerrainHeightGen & a_HeightGen, int a_Seed); + static cTerrainCompositionGenPtr CreateCompositionGen(cIniFile & a_IniFile, cBiomeGenPtr a_BiomeGen, cTerrainShapeGenPtr a_ShapeGen, int a_Seed); } ; @@ -128,7 +152,7 @@ public: /** The interface that a finisher must implement Finisher implements changes to the chunk after the rough terrain has been generated. Examples of finishers are trees, snow, ore, lilypads and others. -Note that a worldgenerator may contain multiple finishers. +Note that a worldgenerator may contain multiple finishers, chained one after another. Also note that previously we used to distinguish between a structuregen and a finisher; this distinction is no longer relevant, all structure generators are considered finishers now (#398) */ @@ -154,23 +178,34 @@ class cComposableGenerator : public: cComposableGenerator(cChunkGenerator & a_ChunkGenerator); + // cChunkGenerator::cGenerator overrides: virtual void Initialize(cIniFile & a_IniFile) override; virtual void GenerateBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; virtual void DoGenerate(int a_ChunkX, int a_ChunkZ, cChunkDesc & a_ChunkDesc) override; protected: - // The generation composition: - cBiomeGenPtr m_BiomeGen; - cTerrainHeightGenPtr m_HeightGen; + // The generator's composition: + /** The biome generator. */ + cBiomeGenPtr m_BiomeGen; + + /** The terrain shape generator. */ + cTerrainShapeGenPtr m_ShapeGen; + + /** The terrain composition generator. */ cTerrainCompositionGenPtr m_CompositionGen; - cFinishGenList m_FinishGens; + + /** The cache for the heights of the composited terrain. */ + cTerrainHeightGenPtr m_CompositedHeightCache; + + /** The finisher generators, in the order in which they are applied. */ + cFinishGenList m_FinishGens; - /** Reads the biome gen settings from the ini and initializes m_BiomeGen accordingly */ + /** Reads the BiomeGen settings from the ini and initializes m_BiomeGen accordingly */ void InitBiomeGen(cIniFile & a_IniFile); - /** Reads the HeightGen settings from the ini and initializes m_HeightGen accordingly */ - void InitHeightGen(cIniFile & a_IniFile); + /** Reads the ShapeGen settings from the ini and initializes m_ShapeGen accordingly */ + void InitShapeGen(cIniFile & a_IniFile); /** Reads the CompositionGen settings from the ini and initializes m_CompositionGen accordingly */ void InitCompositionGen(cIniFile & a_IniFile); diff --git a/src/Generating/DistortedHeightmap.cpp b/src/Generating/DistortedHeightmap.cpp index d5bc6ab55..e1ed9b450 100644 --- a/src/Generating/DistortedHeightmap.cpp +++ b/src/Generating/DistortedHeightmap.cpp @@ -14,163 +14,6 @@ -//////////////////////////////////////////////////////////////////////////////// -// cPattern: - -/// This class is used to store a column pattern initialized at runtime, -/// so that the program doesn't need to explicitly set 256 values for each pattern -/// Each pattern has 256 blocks so that there's no need to check pattern bounds when assigning the -/// pattern - there will always be enough pattern left, even for the whole chunk height -class cPattern -{ -public: - cPattern(cDistortedHeightmap::sBlockInfo * a_TopBlocks, size_t a_Count) - { - // Copy the pattern into the top: - for (size_t i = 0; i < a_Count; i++) - { - m_Pattern[i] = a_TopBlocks[i]; - } - - // Fill the rest with stone: - static cDistortedHeightmap::sBlockInfo Stone = {E_BLOCK_STONE, 0}; - for (size_t i = a_Count; i < cChunkDef::Height; i++) - { - m_Pattern[i] = Stone; - } - } - - const cDistortedHeightmap::sBlockInfo * Get(void) const { return m_Pattern; } - -protected: - cDistortedHeightmap::sBlockInfo m_Pattern[cChunkDef::Height]; -} ; - - - - - -//////////////////////////////////////////////////////////////////////////////// -// The arrays to use for the top block pattern definitions: - -static cDistortedHeightmap::sBlockInfo tbGrass[] = -{ - {E_BLOCK_GRASS, 0}, - {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, - {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, - {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, -} ; - -static cDistortedHeightmap::sBlockInfo tbSand[] = -{ - { E_BLOCK_SAND, 0}, - { E_BLOCK_SAND, 0}, - { E_BLOCK_SAND, 0}, - { E_BLOCK_SANDSTONE, 0}, -} ; - -static cDistortedHeightmap::sBlockInfo tbDirt[] = -{ - {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, - {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, - {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, - {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, -} ; - -static cDistortedHeightmap::sBlockInfo tbPodzol[] = -{ - {E_BLOCK_DIRT, E_META_DIRT_PODZOL}, - {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, - {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, - {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, -} ; - -static cDistortedHeightmap::sBlockInfo tbGrassLess[] = -{ - {E_BLOCK_DIRT, E_META_DIRT_GRASSLESS}, - {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, - {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, - {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, -} ; - -static cDistortedHeightmap::sBlockInfo tbMycelium[] = -{ - {E_BLOCK_MYCELIUM, 0}, - {E_BLOCK_DIRT, 0}, - {E_BLOCK_DIRT, 0}, - {E_BLOCK_DIRT, 0}, -} ; - -static cDistortedHeightmap::sBlockInfo tbGravel[] = -{ - {E_BLOCK_GRAVEL, 0}, - {E_BLOCK_GRAVEL, 0}, - {E_BLOCK_GRAVEL, 0}, - {E_BLOCK_STONE, 0}, -} ; - -static cDistortedHeightmap::sBlockInfo tbStone[] = -{ - {E_BLOCK_STONE, 0}, - {E_BLOCK_STONE, 0}, - {E_BLOCK_STONE, 0}, - {E_BLOCK_STONE, 0}, -} ; - - - -//////////////////////////////////////////////////////////////////////////////// -// Ocean floor pattern top-block definitions: - -static cDistortedHeightmap::sBlockInfo tbOFSand[] = -{ - {E_BLOCK_SAND, 0}, - {E_BLOCK_SAND, 0}, - {E_BLOCK_SAND, 0}, - {E_BLOCK_SANDSTONE, 0} -} ; - -static cDistortedHeightmap::sBlockInfo tbOFClay[] = -{ - { E_BLOCK_CLAY, 0}, - { E_BLOCK_CLAY, 0}, - { E_BLOCK_SAND, 0}, - { E_BLOCK_SAND, 0}, -} ; - -static cDistortedHeightmap::sBlockInfo tbOFRedSand[] = -{ - { E_BLOCK_SAND, E_META_SAND_RED}, - { E_BLOCK_SAND, E_META_SAND_RED}, - { E_BLOCK_SAND, E_META_SAND_RED}, - { E_BLOCK_SANDSTONE, 0}, -} ; - - - - - - -//////////////////////////////////////////////////////////////////////////////// -// Individual patterns to use: - -static cPattern patGrass (tbGrass, ARRAYCOUNT(tbGrass)); -static cPattern patSand (tbSand, ARRAYCOUNT(tbSand)); -static cPattern patDirt (tbDirt, ARRAYCOUNT(tbDirt)); -static cPattern patPodzol (tbPodzol, ARRAYCOUNT(tbPodzol)); -static cPattern patGrassLess(tbGrassLess, ARRAYCOUNT(tbGrassLess)); -static cPattern patMycelium (tbMycelium, ARRAYCOUNT(tbMycelium)); -static cPattern patGravel (tbGravel, ARRAYCOUNT(tbGravel)); -static cPattern patStone (tbStone, ARRAYCOUNT(tbStone)); - -static cPattern patOFSand (tbOFSand, ARRAYCOUNT(tbOFSand)); -static cPattern patOFClay (tbOFClay, ARRAYCOUNT(tbOFClay)); -static cPattern patOFRedSand(tbOFRedSand, ARRAYCOUNT(tbOFRedSand)); - - - - - //////////////////////////////////////////////////////////////////////////////// // cDistortedHeightmap: @@ -237,7 +80,7 @@ const cDistortedHeightmap::sGenParam cDistortedHeightmap::m_GenParam[256] = {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, // 110 .. 119 {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, // 120 .. 128 - // Release 1.7 /* biome variants: + // Release 1.7 biome variants: /* biSunflowerPlains */ { 1.0f, 1.0f}, // 129 /* biDesertM */ { 1.0f, 1.0f}, // 130 /* biExtremeHillsM */ {16.0f, 16.0f}, // 131 @@ -279,8 +122,6 @@ const cDistortedHeightmap::sGenParam cDistortedHeightmap::m_GenParam[256] = cDistortedHeightmap::cDistortedHeightmap(int a_Seed, cBiomeGenPtr a_BiomeGen) : m_NoiseDistortX(a_Seed + 1000), m_NoiseDistortZ(a_Seed + 2000), - m_OceanFloorSelect(a_Seed + 3000), - m_MesaFloor(a_Seed + 4000), m_BiomeGen(a_BiomeGen), m_UnderlyingHeiGen(new cHeiGenBiomal(a_Seed, a_BiomeGen)), m_HeightGen(m_UnderlyingHeiGen, 64), @@ -293,8 +134,6 @@ cDistortedHeightmap::cDistortedHeightmap(int a_Seed, cBiomeGenPtr a_BiomeGen) : m_NoiseDistortZ.AddOctave((NOISE_DATATYPE)1, (NOISE_DATATYPE)0.5); m_NoiseDistortZ.AddOctave((NOISE_DATATYPE)0.5, (NOISE_DATATYPE)1); m_NoiseDistortZ.AddOctave((NOISE_DATATYPE)0.25, (NOISE_DATATYPE)2); - - InitMesaPattern(a_Seed); } @@ -309,7 +148,7 @@ void cDistortedHeightmap::Initialize(cIniFile & a_IniFile) } // Read the params from the INI file: - m_SeaLevel = a_IniFile.GetValueSetI("Generator", "DistortedHeightmapSeaLevel", 62); + m_SeaLevel = a_IniFile.GetValueSetI("Generator", "SeaLevel", 62); m_FrequencyX = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "DistortedHeightmapFrequencyX", 10); m_FrequencyY = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "DistortedHeightmapFrequencyY", 10); m_FrequencyZ = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "DistortedHeightmapFrequencyZ", 10); @@ -321,89 +160,6 @@ void cDistortedHeightmap::Initialize(cIniFile & a_IniFile) -void cDistortedHeightmap::InitMesaPattern(int a_Seed) -{ - // Stone in the bottom half of the pattern: - for (int i = cChunkDef::Height; i < 2 * cChunkDef::Height; i++) - { - m_MesaPattern[i].BlockMeta = 0; - m_MesaPattern[i].BlockType = E_BLOCK_STONE; - } - - // Stained and hardened clay in the top half of the pattern - // In a loop, choose whether to use one or two layers of stained clay, then choose a color and width for each layer - // Separate each group with another layer of hardened clay - cNoise PatternNoise((unsigned)a_Seed); - static NIBBLETYPE AllowedColors[] = - { - E_META_STAINED_CLAY_YELLOW, - E_META_STAINED_CLAY_YELLOW, - E_META_STAINED_CLAY_RED, - E_META_STAINED_CLAY_RED, - E_META_STAINED_CLAY_WHITE, - E_META_STAINED_CLAY_BROWN, - E_META_STAINED_CLAY_BROWN, - E_META_STAINED_CLAY_BROWN, - E_META_STAINED_CLAY_ORANGE, - E_META_STAINED_CLAY_ORANGE, - E_META_STAINED_CLAY_ORANGE, - E_META_STAINED_CLAY_ORANGE, - E_META_STAINED_CLAY_ORANGE, - E_META_STAINED_CLAY_ORANGE, - E_META_STAINED_CLAY_LIGHTGRAY, - } ; - static int LayerSizes[] = // Adjust the chance so that thinner layers occur more commonly - { - 1, 1, 1, 1, 1, 1, - 2, 2, 2, 2, - 3, 3, - } ; - int Idx = cChunkDef::Height - 1; - while (Idx >= 0) - { - // A layer group of 1 - 2 color stained clay: - int Random = PatternNoise.IntNoise1DInt(Idx) / 7; - int NumLayers = (Random % 2) + 1; - Random /= 2; - for (int Lay = 0; Lay < NumLayers; Lay++) - { - int NumBlocks = LayerSizes[(Random % ARRAYCOUNT(LayerSizes))]; - NIBBLETYPE Color = AllowedColors[(Random / 4) % ARRAYCOUNT(AllowedColors)]; - if ( - ((NumBlocks == 3) && (NumLayers == 2)) || // In two-layer mode disallow the 3-high layers: - (Color == E_META_STAINED_CLAY_WHITE)) // White stained clay can ever be only 1 block high - { - NumBlocks = 1; - } - NumBlocks = std::min(Idx + 1, NumBlocks); // Limit by Idx so that we don't have to check inside the loop - Random /= 32; - for (int Block = 0; Block < NumBlocks; Block++, Idx--) - { - m_MesaPattern[Idx].BlockMeta = Color; - m_MesaPattern[Idx].BlockType = E_BLOCK_STAINED_CLAY; - } // for Block - } // for Lay - - // A layer of hardened clay in between the layer group: - int NumBlocks = (Random % 4) + 1; // All heights the same probability - if ((NumLayers == 2) && (NumBlocks < 4)) - { - // For two layers of stained clay, add an extra block of hardened clay: - NumBlocks++; - } - NumBlocks = std::min(Idx + 1, NumBlocks); // Limit by Idx so that we don't have to check inside the loop - for (int Block = 0; Block < NumBlocks; Block++, Idx--) - { - m_MesaPattern[Idx].BlockMeta = 0; - m_MesaPattern[Idx].BlockType = E_BLOCK_HARDENED_CLAY; - } // for Block - } // while (Idx >= 0) -} - - - - - void cDistortedHeightmap::PrepareState(int a_ChunkX, int a_ChunkZ) { if ((m_CurChunkX == a_ChunkX) && (m_CurChunkZ == a_ChunkZ)) @@ -474,23 +230,17 @@ void cDistortedHeightmap::GenerateHeightArray(void) -void cDistortedHeightmap::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) +void cDistortedHeightmap::GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape) { PrepareState(a_ChunkX, a_ChunkZ); for (int z = 0; z < cChunkDef::Width; z++) { for (int x = 0; x < cChunkDef::Width; x++) { - int NoiseArrayIdx = x + 17 * 257 * z; - cChunkDef::SetHeight(a_HeightMap, x, z, m_SeaLevel - 1); - for (int y = cChunkDef::Height - 1; y > m_SeaLevel - 1; y--) + int idx = x + 17 * 257 * z; + for (int y = 0; y < cChunkDef::Height; y++) { - int HeightMapHeight = (int)m_DistortedHeightmap[NoiseArrayIdx + 17 * y]; - if (y < HeightMapHeight) - { - cChunkDef::SetHeight(a_HeightMap, x, z, y); - break; - } + a_Shape[y + x * 256 + z * 16 * 256] = (y < m_DistortedHeightmap[idx + y * 17]) ? 1 : 0; } // for y } // for x } // for z @@ -500,36 +250,7 @@ void cDistortedHeightmap::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::He -void cDistortedHeightmap::InitializeHeightGen(cIniFile & a_IniFile) -{ - Initialize(a_IniFile); -} - - - - - -void cDistortedHeightmap::ComposeTerrain(cChunkDesc & a_ChunkDesc) -{ - // Prepare the internal state for generating this chunk: - PrepareState(a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ()); - - // Compose: - a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0); - for (int z = 0; z < cChunkDef::Width; z++) - { - for (int x = 0; x < cChunkDef::Width; x++) - { - ComposeColumn(a_ChunkDesc, x, z); - } // for x - } // for z -} - - - - - -void cDistortedHeightmap::InitializeCompoGen(cIniFile & a_IniFile) +void cDistortedHeightmap::InitializeShapeGen(cIniFile & a_IniFile) { Initialize(a_IniFile); } @@ -654,275 +375,3 @@ void cDistortedHeightmap::GetDistortAmpsAt(BiomeNeighbors & a_Neighbors, int a_R -void cDistortedHeightmap::ComposeColumn(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelZ) -{ - // Frequencies for the podzol floor selecting noise: - const NOISE_DATATYPE FrequencyX = 8; - const NOISE_DATATYPE FrequencyZ = 8; - - EMCSBiome Biome = a_ChunkDesc.GetBiome(a_RelX, a_RelZ); - switch (Biome) - { - case biOcean: - case biPlains: - case biForest: - case biTaiga: - case biSwampland: - case biRiver: - case biFrozenOcean: - case biFrozenRiver: - case biIcePlains: - case biIceMountains: - case biForestHills: - case biTaigaHills: - case biExtremeHillsEdge: - case biExtremeHillsPlus: - case biExtremeHills: - case biJungle: - case biJungleHills: - case biJungleEdge: - case biDeepOcean: - case biStoneBeach: - case biColdBeach: - case biBirchForest: - case biBirchForestHills: - case biRoofedForest: - case biColdTaiga: - case biColdTaigaHills: - case biSavanna: - case biSavannaPlateau: - case biSunflowerPlains: - case biFlowerForest: - case biTaigaM: - case biSwamplandM: - case biIcePlainsSpikes: - case biJungleM: - case biJungleEdgeM: - case biBirchForestM: - case biBirchForestHillsM: - case biRoofedForestM: - case biColdTaigaM: - case biSavannaM: - case biSavannaPlateauM: - { - FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, patGrass.Get()); - return; - } - - case biMegaTaiga: - case biMegaTaigaHills: - case biMegaSpruceTaiga: - case biMegaSpruceTaigaHills: - { - // Select the pattern to use - podzol, grass or grassless dirt: - NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(m_CurChunkX * cChunkDef::Width + a_RelX)) / FrequencyX; - NOISE_DATATYPE NoiseY = ((NOISE_DATATYPE)(m_CurChunkZ * cChunkDef::Width + a_RelZ)) / FrequencyZ; - NOISE_DATATYPE Val = m_OceanFloorSelect.CubicNoise2D(NoiseX, NoiseY); - const sBlockInfo * Pattern = (Val < -0.9) ? patGrassLess.Get() : ((Val > 0) ? patPodzol.Get() : patGrass.Get()); - FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, Pattern); - return; - } - - case biDesertHills: - case biDesert: - case biDesertM: - case biBeach: - { - FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, patSand.Get()); - return; - } - - case biMushroomIsland: - case biMushroomShore: - { - FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, patMycelium.Get()); - return; - } - - case biMesa: - case biMesaPlateauF: - case biMesaPlateau: - case biMesaBryce: - case biMesaPlateauFM: - case biMesaPlateauM: - { - // Mesa biomes need special handling, because they don't follow the usual "4 blocks from top pattern", - // instead, they provide a "from bottom" pattern with varying base height, - // usually 4 blocks below the ocean level - FillColumnMesa(a_ChunkDesc, a_RelX, a_RelZ); - return; - } - - case biExtremeHillsPlusM: - case biExtremeHillsM: - { - // Select the pattern to use - gravel, stone or grass: - NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(m_CurChunkX * cChunkDef::Width + a_RelX)) / FrequencyX; - NOISE_DATATYPE NoiseY = ((NOISE_DATATYPE)(m_CurChunkZ * cChunkDef::Width + a_RelZ)) / FrequencyZ; - NOISE_DATATYPE Val = m_OceanFloorSelect.CubicNoise2D(NoiseX, NoiseY); - const sBlockInfo * Pattern = (Val < 0.0) ? patStone.Get() : patGrass.Get(); - FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, Pattern); - return; - } - default: - { - ASSERT(!"Unhandled biome"); - return; - } - } // switch (Biome) -} - - - - - -void cDistortedHeightmap::FillColumnPattern(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelZ, const sBlockInfo * a_Pattern) -{ - int NoiseArrayIdx = a_RelX + 17 * 257 * a_RelZ; - bool HasHadWater = false; - int PatternIdx = 0; - for (int y = a_ChunkDesc.GetHeight(a_RelX, a_RelZ); y > 0; y--) - { - int HeightMapHeight = (int)m_DistortedHeightmap[NoiseArrayIdx + 17 * y]; - - if (y < HeightMapHeight) - { - // "ground" part, use the pattern: - a_ChunkDesc.SetBlockTypeMeta(a_RelX, y, a_RelZ, a_Pattern[PatternIdx].BlockType, a_Pattern[PatternIdx].BlockMeta); - PatternIdx++; - continue; - } - - // "air" or "water" part: - // Reset the pattern index to zero, so that the pattern is repeated from the top again: - PatternIdx = 0; - - if (y >= m_SeaLevel) - { - // "air" part, do nothing - continue; - } - - a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_STATIONARY_WATER); - if (HasHadWater) - { - continue; - } - - // Select the ocean-floor pattern to use: - a_Pattern = a_ChunkDesc.GetBiome(a_RelX, a_RelZ) == biDeepOcean ? patGravel.Get() : ChooseOceanFloorPattern(a_RelX, a_RelZ); - HasHadWater = true; - } // for y - a_ChunkDesc.SetBlockType(a_RelX, 0, a_RelZ, E_BLOCK_BEDROCK); -} - - - - - -void cDistortedHeightmap::FillColumnMesa(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelZ) -{ - // Frequencies for the clay floor noise: - const NOISE_DATATYPE FrequencyX = 50; - const NOISE_DATATYPE FrequencyZ = 50; - - int Top = a_ChunkDesc.GetHeight(a_RelX, a_RelZ); - if (Top < m_SeaLevel) - { - // The terrain is below sealevel, handle as regular ocean: - FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, patOFRedSand.Get()); - return; - } - - NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(m_CurChunkX * cChunkDef::Width + a_RelX)) / FrequencyX; - NOISE_DATATYPE NoiseY = ((NOISE_DATATYPE)(m_CurChunkZ * cChunkDef::Width + a_RelZ)) / FrequencyZ; - int ClayFloor = m_SeaLevel - 6 + (int)(4.f * m_MesaFloor.CubicNoise2D(NoiseX, NoiseY)); - if (ClayFloor >= Top) - { - ClayFloor = Top - 1; - } - - if (Top - m_SeaLevel < 5) - { - // Simple case: top is red sand, then hardened clay down to ClayFloor, then stone: - a_ChunkDesc.SetBlockTypeMeta(a_RelX, Top, a_RelZ, E_BLOCK_SAND, E_META_SAND_RED); - for (int y = Top - 1; y >= ClayFloor; y--) - { - a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_HARDENED_CLAY); - } - for (int y = ClayFloor - 1; y > 0; y--) - { - a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_STONE); - } - a_ChunkDesc.SetBlockType(a_RelX, 0, a_RelZ, E_BLOCK_BEDROCK); - return; - } - - // Difficult case: use the mesa pattern and watch for overhangs: - int NoiseArrayIdx = a_RelX + 17 * 257 * a_RelZ; - int PatternIdx = cChunkDef::Height - (Top - ClayFloor); // We want the block at index ClayFloor to be pattern's 256th block (first stone) - const sBlockInfo * Pattern = m_MesaPattern; - bool HasHadWater = false; - for (int y = Top; y > 0; y--) - { - int HeightMapHeight = (int)m_DistortedHeightmap[NoiseArrayIdx + 17 * y]; - if (y < HeightMapHeight) - { - // "ground" part, use the pattern: - a_ChunkDesc.SetBlockTypeMeta(a_RelX, y, a_RelZ, Pattern[PatternIdx].BlockType, Pattern[PatternIdx].BlockMeta); - PatternIdx++; - continue; - } - - if (y >= m_SeaLevel) - { - // "air" part, do nothing - continue; - } - - // "water" part, fill with water and choose new pattern for ocean floor, if not chosen already: - PatternIdx = 0; - a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_STATIONARY_WATER); - if (HasHadWater) - { - continue; - } - - // Select the ocean-floor pattern to use: - Pattern = ChooseOceanFloorPattern(a_RelX, a_RelZ); - HasHadWater = true; - } // for y - a_ChunkDesc.SetBlockType(a_RelX, 0, a_RelZ, E_BLOCK_BEDROCK); -} - - - - - -const cDistortedHeightmap::sBlockInfo * cDistortedHeightmap::ChooseOceanFloorPattern(int a_RelX, int a_RelZ) -{ - // Frequencies for the ocean floor selecting noise: - const NOISE_DATATYPE FrequencyX = 3; - const NOISE_DATATYPE FrequencyZ = 3; - - // Select the ocean-floor pattern to use: - NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(m_CurChunkX * cChunkDef::Width + a_RelX)) / FrequencyX; - NOISE_DATATYPE NoiseY = ((NOISE_DATATYPE)(m_CurChunkZ * cChunkDef::Width + a_RelZ)) / FrequencyZ; - NOISE_DATATYPE Val = m_OceanFloorSelect.CubicNoise2D(NoiseX, NoiseY); - if (Val < -0.95) - { - return patOFClay.Get(); - } - else if (Val < 0) - { - return patOFSand.Get(); - } - else - { - return patDirt.Get(); - } -} - - - - diff --git a/src/Generating/DistortedHeightmap.h b/src/Generating/DistortedHeightmap.h index d073f29e4..4027a94ca 100644 --- a/src/Generating/DistortedHeightmap.h +++ b/src/Generating/DistortedHeightmap.h @@ -24,17 +24,9 @@ class cDistortedHeightmap : - public cTerrainHeightGen, - public cTerrainCompositionGen + public cTerrainShapeGen { public: - /// Structure used for storing block patterns for columns - struct sBlockInfo - { - BLOCKTYPE BlockType; - NIBBLETYPE BlockMeta; - } ; - cDistortedHeightmap(int a_Seed, cBiomeGenPtr a_BiomeGen); protected: @@ -52,8 +44,6 @@ protected: cPerlinNoise m_NoiseDistortX; cPerlinNoise m_NoiseDistortZ; - cNoise m_OceanFloorSelect; ///< Used for selecting between dirt and sand on the ocean floor - cNoise m_MesaFloor; ///< Used for the floor of the clay blocks in mesa biomes int m_SeaLevel; NOISE_DATATYPE m_FrequencyX; @@ -71,9 +61,9 @@ protected: cTerrainHeightGenPtr m_UnderlyingHeiGen; /** Cache for m_UnderlyingHeiGen. */ - cHeiGenCache m_HeightGen; + cHeiGenCache m_HeightGen; - /// Heightmap for the current chunk, before distortion (from m_HeightGen). Used for optimization. + /** Heightmap for the current chunk, before distortion (from m_HeightGen). Used for optimization. */ cChunkDef::HeightMap m_CurChunkHeights; // Per-biome terrain generator parameters: @@ -88,54 +78,30 @@ protected: NOISE_DATATYPE m_DistortAmpX[DIM_X * DIM_Z]; NOISE_DATATYPE m_DistortAmpZ[DIM_X * DIM_Z]; - /// True if Initialize() has been called. Used to initialize-once even with multiple init entrypoints (HeiGen / CompoGen) + /** True if Initialize() has been called. Used to initialize-once even with multiple init entrypoints (HeiGen / CompoGen). */ bool m_IsInitialized; - /// The vertical pattern to be used for mesa biomes. Seed-dependant. - /// One Height of pattern and one Height of stone to avoid checking pattern dimensions - sBlockInfo m_MesaPattern[2 * cChunkDef::Height]; - - /// Initializes m_MesaPattern with a reasonable pattern of stained clay / hardened clay, based on the seed - void InitMesaPattern(int a_Seed); - - /// Unless the LastChunk coords are equal to coords given, prepares the internal state (noise arrays, heightmap) + /** Unless the LastChunk coords are equal to coords given, prepares the internal state (noise arrays, heightmap). */ void PrepareState(int a_ChunkX, int a_ChunkZ); - /// Generates the m_DistortedHeightmap array for the current chunk + /** Generates the m_DistortedHeightmap array for the current chunk. */ void GenerateHeightArray(void); - /// Calculates the heightmap value (before distortion) at the specified (floating-point) coords + /** Calculates the heightmap value (before distortion) at the specified (floating-point) coords. */ int GetHeightmapAt(NOISE_DATATYPE a_X, NOISE_DATATYPE a_Z); - /// Updates m_DistortAmpX/Z[] based on m_CurChunkX and m_CurChunkZ + /** Updates m_DistortAmpX/Z[] based on m_CurChunkX and m_CurChunkZ. */ void UpdateDistortAmps(void); - /// Calculates the X and Z distortion amplitudes based on the neighbors' biomes + /** Calculates the X and Z distortion amplitudes based on the neighbors' biomes. */ void GetDistortAmpsAt(BiomeNeighbors & a_Neighbors, int a_RelX, int a_RelZ, NOISE_DATATYPE & a_DistortAmpX, NOISE_DATATYPE & a_DistortAmpZ); - /// Reads the settings from the ini file. Skips reading if already initialized + /** Reads the settings from the ini file. Skips reading if already initialized. */ void Initialize(cIniFile & a_IniFile); - /// Composes a single column in a_ChunkDesc. Chooses what to do based on the biome in that column - void ComposeColumn(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelZ); - /// Fills the specified column with the specified pattern; restarts the pattern when air is reached, - /// switches to ocean floor pattern if ocean is reached. Always adds bedrock at the very bottom. - void FillColumnPattern(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelZ, const sBlockInfo * a_Pattern); - - /// Fills the specified column with mesa pattern, based on the column height - void FillColumnMesa(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelZ); - - /// Returns the pattern to use for an ocean floor in the specified column - const sBlockInfo * ChooseOceanFloorPattern(int a_RelX, int a_RelZ); - - - // cTerrainHeightGen overrides: - virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; - virtual void InitializeHeightGen(cIniFile & a_IniFile) override; - - // cTerrainCompositionGen overrides: - virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc) override; - virtual void InitializeCompoGen(cIniFile & a_IniFile) override; + // cTerrainShapeGen overrides: + virtual void GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape) override; + virtual void InitializeShapeGen(cIniFile & a_IniFile) override; } ; diff --git a/src/Generating/DungeonRoomsFinisher.cpp b/src/Generating/DungeonRoomsFinisher.cpp index 3f328868d..bd45cb2a4 100644 --- a/src/Generating/DungeonRoomsFinisher.cpp +++ b/src/Generating/DungeonRoomsFinisher.cpp @@ -258,9 +258,9 @@ protected: //////////////////////////////////////////////////////////////////////////////// // cDungeonRoomsFinisher: -cDungeonRoomsFinisher::cDungeonRoomsFinisher(cTerrainHeightGenPtr a_HeightGen, int a_Seed, int a_GridSize, int a_MaxSize, int a_MinSize, const AString & a_HeightDistrib) : +cDungeonRoomsFinisher::cDungeonRoomsFinisher(cTerrainShapeGenPtr a_ShapeGen, int a_Seed, int a_GridSize, int a_MaxSize, int a_MinSize, const AString & a_HeightDistrib) : super(a_Seed + 100, a_GridSize, a_GridSize, a_GridSize, a_GridSize, a_MaxSize, a_MaxSize, 1024), - m_HeightGen(a_HeightGen), + m_ShapeGen(a_ShapeGen), m_MaxHalfSize((a_MaxSize + 1) / 2), m_MinHalfSize((a_MinSize + 1) / 2), m_HeightProbability(cChunkDef::Height) @@ -293,10 +293,14 @@ cDungeonRoomsFinisher::cStructurePtr cDungeonRoomsFinisher::CreateStructure(int int ChunkX, ChunkZ; int RelX = a_OriginX, RelY = 0, RelZ = a_OriginZ; cChunkDef::AbsoluteToRelative(RelX, RelY, RelZ, ChunkX, ChunkZ); + /* + // TODO cChunkDef::HeightMap HeightMap; m_HeightGen->GenHeightMap(ChunkX, ChunkZ, HeightMap); int Height = cChunkDef::GetHeight(HeightMap, RelX, RelZ); // Max room height at {a_OriginX, a_OriginZ} Height = Clamp(m_HeightProbability.MapValue(rnd % m_HeightProbability.GetSum()), 10, Height - 5); + */ + int Height = 62; // Create the dungeon room descriptor: return cStructurePtr(new cDungeonRoom(a_GridX, a_GridZ, a_OriginX, a_OriginZ, HalfSizeX, HalfSizeZ, Height, m_Noise)); diff --git a/src/Generating/DungeonRoomsFinisher.h b/src/Generating/DungeonRoomsFinisher.h index 09dd0448a..e5828f989 100644 --- a/src/Generating/DungeonRoomsFinisher.h +++ b/src/Generating/DungeonRoomsFinisher.h @@ -23,15 +23,15 @@ class cDungeonRoomsFinisher : public: /** Creates a new dungeon room finisher. - a_HeightGen is the underlying height generator, so that the rooms can always be placed under the terrain. + a_ShapeGen is the underlying terrain shape generator, so that the rooms can always be placed under the terrain. a_MaxSize and a_MinSize are the maximum and minimum sizes of the room's internal (air) area, in blocks across. a_HeightDistrib is the string defining the height distribution for the rooms (cProbabDistrib format). */ - cDungeonRoomsFinisher(cTerrainHeightGenPtr a_HeightGen, int a_Seed, int a_GridSize, int a_MaxSize, int a_MinSize, const AString & a_HeightDistrib); + cDungeonRoomsFinisher(cTerrainShapeGenPtr a_ShapeGen, int a_Seed, int a_GridSize, int a_MaxSize, int a_MinSize, const AString & a_HeightDistrib); protected: - /** The height gen that is used for limiting the rooms' Y coords */ - cTerrainHeightGenPtr m_HeightGen; + /** The shape gen that is used for limiting the rooms' Y coords */ + cTerrainShapeGenPtr m_ShapeGen; /** Maximum half-size (from center to wall) of the dungeon room's inner (air) area. Default is 3 (vanilla). */ int m_MaxHalfSize; diff --git a/src/Generating/EndGen.cpp b/src/Generating/EndGen.cpp index 0111d2fa3..89d6117bb 100644 --- a/src/Generating/EndGen.cpp +++ b/src/Generating/EndGen.cpp @@ -147,13 +147,14 @@ bool cEndGen::IsChunkOutsideRange(int a_ChunkX, int a_ChunkZ) -void cEndGen::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) +void cEndGen::GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape) { + // If the chunk is outside out range, fill the shape with zeroes: if (IsChunkOutsideRange(a_ChunkX, a_ChunkZ)) { - for (size_t i = 0; i < ARRAYCOUNT(a_HeightMap); i++) + for (size_t i = 0; i < ARRAYCOUNT(a_Shape); i++) { - a_HeightMap[i] = 0; + a_Shape[i] = 0; } return; } @@ -165,15 +166,14 @@ void cEndGen::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_ { for (int x = 0; x < cChunkDef::Width; x++) { - cChunkDef::SetHeight(a_HeightMap, x, z, MaxY); - for (int y = MaxY; y > 0; y--) + for (int y = 0; y < MaxY; y++) { - if (m_NoiseArray[y * 17 * 17 + z * 17 + x] <= 0) - { - cChunkDef::SetHeight(a_HeightMap, x, z, y); - break; - } - } // for y + a_Shape[(x + 16 * z) * 256 + y] = (m_NoiseArray[y * 17 * 17 + z * 17 + z] > 0) ? 1 : 0; + } + for (int y = MaxY; y < cChunkDef::Height; y++) + { + a_Shape[(x + 16 * z) * 256 + y] = 0; + } } // for x } // for z } @@ -182,30 +182,18 @@ void cEndGen::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_ -void cEndGen::ComposeTerrain(cChunkDesc & a_ChunkDesc) +void cEndGen::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) { - if (IsChunkOutsideRange(a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ())) - { - a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0); - return; - } - - PrepareState(a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ()); - - int MaxY = std::min((int)(1.75 * m_IslandSizeY + 1), cChunkDef::Height - 1); + a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0); for (int z = 0; z < cChunkDef::Width; z++) { for (int x = 0; x < cChunkDef::Width; x++) { - for (int y = MaxY; y > 0; y--) + for (int y = 0; y < cChunkDef::Height; y++) { - if (m_NoiseArray[y * 17 * 17 + z * 17 + x] <= 0) - { - a_ChunkDesc.SetBlockTypeMeta(x, y, z, E_BLOCK_END_STONE, 0); - } - else + if (a_Shape[(x + 16 * z) * 256 + y] != 0) { - a_ChunkDesc.SetBlockTypeMeta(x, y, z, E_BLOCK_AIR, 0); + a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_END_STONE); } } // for y } // for x diff --git a/src/Generating/EndGen.h b/src/Generating/EndGen.h index 322061810..e4c874014 100644 --- a/src/Generating/EndGen.h +++ b/src/Generating/EndGen.h @@ -17,7 +17,7 @@ class cEndGen : - public cTerrainHeightGen, + public cTerrainShapeGen, public cTerrainCompositionGen { public: @@ -59,10 +59,10 @@ protected: /// Returns true if the chunk is outside of the island's dimensions bool IsChunkOutsideRange(int a_ChunkX, int a_ChunkZ); - // cTerrainHeightGen overrides: - virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; + // cTerrainShapeGen overrides: + virtual void GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape) override; // cTerrainCompositionGen overrides: - virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc) override; + virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) override; virtual void InitializeCompoGen(cIniFile & a_IniFile) override; } ; diff --git a/src/Generating/HeiGen.cpp b/src/Generating/HeiGen.cpp index 1d9f1e3aa..86f934c16 100644 --- a/src/Generating/HeiGen.cpp +++ b/src/Generating/HeiGen.cpp @@ -15,7 +15,6 @@ - //////////////////////////////////////////////////////////////////////////////// // cHeiGenFlat: @@ -133,15 +132,6 @@ void cHeiGenCache::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap -void cHeiGenCache::InitializeHeightGen(cIniFile & a_IniFile) -{ - m_HeiGenToCache->InitializeHeightGen(a_IniFile); -} - - - - - bool cHeiGenCache::GetHeightAt(int a_ChunkX, int a_ChunkZ, int a_RelX, int a_RelZ, HEIGHTTYPE & a_Height) { for (int i = 0; i < m_CacheSize; i++) @@ -750,43 +740,51 @@ cTerrainHeightGenPtr cTerrainHeightGen::CreateHeightGen(cIniFile & a_IniFile, cB } a_CacheOffByDefault = false; - cTerrainHeightGen * res = nullptr; - if (NoCaseCompare(HeightGenName, "flat") == 0) + cTerrainHeightGenPtr res; + if (NoCaseCompare(HeightGenName, "Flat") == 0) { - res = new cHeiGenFlat; + res = std::make_shared(); a_CacheOffByDefault = true; // We're generating faster than a cache would retrieve data } else if (NoCaseCompare(HeightGenName, "classic") == 0) { - res = new cHeiGenClassic(a_Seed); + res = std::make_shared(a_Seed); } else if (NoCaseCompare(HeightGenName, "DistortedHeightmap") == 0) { - res = new cDistortedHeightmap(a_Seed, a_BiomeGen); + // Not a heightmap-based generator, but it used to be accessible via HeightGen, so we need to skip making the default out of it + // Return an empty pointer, the caller will create the proper generator: + return cTerrainHeightGenPtr(); } else if (NoCaseCompare(HeightGenName, "End") == 0) { - res = new cEndGen(a_Seed); + // Not a heightmap-based generator, but it used to be accessible via HeightGen, so we need to skip making the default out of it + // Return an empty pointer, the caller will create the proper generator: + return cTerrainHeightGenPtr(); } else if (NoCaseCompare(HeightGenName, "MinMax") == 0) { - res = new cHeiGenMinMax(a_Seed, a_BiomeGen); + res = std::make_shared(a_Seed, a_BiomeGen); } else if (NoCaseCompare(HeightGenName, "Mountains") == 0) { - res = new cHeiGenMountains(a_Seed); + res = std::make_shared(a_Seed); } else if (NoCaseCompare(HeightGenName, "BiomalNoise3D") == 0) { - res = new cBiomalNoise3DComposable(a_Seed, a_BiomeGen); + // Not a heightmap-based generator, but it used to be accessible via HeightGen, so we need to skip making the default out of it + // Return an empty pointer, the caller will create the proper generator: + return cTerrainHeightGenPtr(); } else if (NoCaseCompare(HeightGenName, "Noise3D") == 0) { - res = new cNoise3DComposable(a_Seed); + // Not a heightmap-based generator, but it used to be accessible via HeightGen, so we need to skip making the default out of it + // Return an empty pointer, the caller will create the proper generator: + return cTerrainHeightGenPtr(); } - else if (NoCaseCompare(HeightGenName, "biomal") == 0) + else if (NoCaseCompare(HeightGenName, "Biomal") == 0) { - res = new cHeiGenBiomal(a_Seed, a_BiomeGen); + res = std::make_shared(a_Seed, a_BiomeGen); /* // Performance-testing: @@ -805,15 +803,14 @@ cTerrainHeightGenPtr cTerrainHeightGen::CreateHeightGen(cIniFile & a_IniFile, cB { // No match found, force-set the default and retry LOGWARN("Unknown HeightGen \"%s\", using \"Biomal\" instead.", HeightGenName.c_str()); - a_IniFile.DeleteValue("Generator", "HeightGen"); a_IniFile.SetValue("Generator", "HeightGen", "Biomal"); return CreateHeightGen(a_IniFile, a_BiomeGen, a_Seed, a_CacheOffByDefault); } // Read the settings: res->InitializeHeightGen(a_IniFile); - - return cTerrainHeightGenPtr(res); + + return res; } diff --git a/src/Generating/HeiGen.h b/src/Generating/HeiGen.h index 6ae5ba362..d91ace3bd 100644 --- a/src/Generating/HeiGen.h +++ b/src/Generating/HeiGen.h @@ -2,10 +2,12 @@ // HeiGen.h /* -Interfaces to the various height generators: +Interfaces to the various height-based terrain shape generators: - cHeiGenFlat - cHeiGenClassic - cHeiGenBiomal + +Also implements the heightmap cache */ @@ -21,26 +23,7 @@ Interfaces to the various height generators: -class cHeiGenFlat : - public cTerrainHeightGen -{ -public: - cHeiGenFlat(void) : m_Height(5) {} - -protected: - - int m_Height; - - // cTerrainHeightGen overrides: - virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; - virtual void InitializeHeightGen(cIniFile & a_IniFile) override; -} ; - - - - - -/// A simple cache that stores N most recently generated chunks' heightmaps; N being settable upon creation +/** A simple cache that stores N most recently generated chunks' heightmaps; N being settable upon creation */ class cHeiGenCache : public cTerrainHeightGen { @@ -50,15 +33,11 @@ public: // cTerrainHeightGen overrides: virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; - virtual void InitializeHeightGen(cIniFile & a_IniFile) override; - /// Retrieves height at the specified point in the cache, returns true if found, false if not found + /** Retrieves height at the specified point in the cache, returns true if found, false if not found */ bool GetHeightAt(int a_ChunkX, int a_ChunkZ, int a_RelX, int a_RelZ, HEIGHTTYPE & a_Height); protected: - - cTerrainHeightGenPtr m_HeiGenToCache; - struct sCacheData { int m_ChunkX; @@ -66,6 +45,9 @@ protected: cChunkDef::HeightMap m_HeightMap; } ; + /** The terrain height generator that is being cached. */ + cTerrainHeightGenPtr m_HeiGenToCache; + // To avoid moving large amounts of data for the MRU behavior, we MRU-ize indices to an array of the actual data int m_CacheSize; int * m_CacheOrder; // MRU-ized order, indices into m_CacheData array @@ -81,6 +63,25 @@ protected: +class cHeiGenFlat : + public cTerrainHeightGen +{ +public: + cHeiGenFlat(void) : m_Height(5) {} + +protected: + + int m_Height; + + // cTerrainHeightGen overrides: + virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; + virtual void InitializeHeightGen(cIniFile & a_IniFile) override; +} ; + + + + + class cHeiGenClassic : public cTerrainHeightGen { diff --git a/src/Generating/Noise3DGenerator.cpp b/src/Generating/Noise3DGenerator.cpp index 4e45aa18b..da4632de4 100644 --- a/src/Generating/Noise3DGenerator.cpp +++ b/src/Generating/Noise3DGenerator.cpp @@ -458,110 +458,53 @@ void cNoise3DComposable::GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_ChunkZ) NOISE_DATATYPE BaseNoise[5 * 5]; NOISE_DATATYPE BlockX = static_cast(a_ChunkX * cChunkDef::Width); NOISE_DATATYPE BlockZ = static_cast(a_ChunkZ * cChunkDef::Width); - // Note that we have to swap the coords, because noise generator uses [x + SizeX * y + SizeX * SizeY * z] ordering and we want "BlockY" to be "z": - m_ChoiceNoise.Generate3D (ChoiceNoise, 5, 5, 33, BlockX / m_ChoiceFrequencyX, (BlockX + 17) / m_ChoiceFrequencyX, BlockZ / m_ChoiceFrequencyZ, (BlockZ + 17) / m_ChoiceFrequencyZ, 0, 257 / m_ChoiceFrequencyY, Workspace); - m_DensityNoiseA.Generate3D(DensityNoiseA, 5, 5, 33, BlockX / m_FrequencyX, (BlockX + 17) / m_FrequencyX, BlockZ / m_FrequencyZ, (BlockZ + 17) / m_FrequencyZ, 0, 257 / m_FrequencyY, Workspace); - m_DensityNoiseB.Generate3D(DensityNoiseB, 5, 5, 33, BlockX / m_FrequencyX, (BlockX + 17) / m_FrequencyX, BlockZ / m_FrequencyZ, (BlockZ + 17) / m_FrequencyZ, 0, 257 / m_FrequencyY, Workspace); + // Note that we have to swap the X and Y coords, because noise generator uses [x + SizeX * y + SizeX * SizeY * z] ordering and we want "BlockY" to be "x": + m_ChoiceNoise.Generate3D (ChoiceNoise, 33, 5, 5, 0, 257 / m_ChoiceFrequencyY, BlockX / m_ChoiceFrequencyX, (BlockX + 17) / m_ChoiceFrequencyX, BlockZ / m_ChoiceFrequencyZ, (BlockZ + 17) / m_ChoiceFrequencyZ, Workspace); + m_DensityNoiseA.Generate3D(DensityNoiseA, 33, 5, 5, 0, 257 / m_FrequencyY, BlockX / m_FrequencyX, (BlockX + 17) / m_FrequencyX, BlockZ / m_FrequencyZ, (BlockZ + 17) / m_FrequencyZ, Workspace); + m_DensityNoiseB.Generate3D(DensityNoiseB, 33, 5, 5, 0, 257 / m_FrequencyY, BlockX / m_FrequencyX, (BlockX + 17) / m_FrequencyX, BlockZ / m_FrequencyZ, (BlockZ + 17) / m_FrequencyZ, Workspace); m_BaseNoise.Generate2D (BaseNoise, 5, 5, BlockX / m_BaseFrequencyX, (BlockX + 17) / m_BaseFrequencyX, BlockZ / m_FrequencyZ, (BlockZ + 17) / m_FrequencyZ, Workspace); // Calculate the final noise based on the partial noises: - for (int y = 0; y < 33; y++) + for (int z = 0; z < 5; z++) { - NOISE_DATATYPE AddHeight = (static_cast(y * 8) - m_MidPoint) * m_HeightAmplification; - - // If "underground", make the terrain smoother by forcing the vertical linear gradient into steeper slope: - if (AddHeight < 0) - { - AddHeight *= 4; - } - - for (int z = 0; z < 5; z++) + for (int x = 0; x < 5; x++) { - for (int x = 0; x < 5; x++) + NOISE_DATATYPE curBaseNoise = BaseNoise[x + 5 * z]; + for (int y = 0; y < 33; y++) { - int idx = x + 5 * z + 5 * 5 * y; - Workspace[idx] = ClampedLerp(DensityNoiseA[idx], DensityNoiseB[idx], 8 * (ChoiceNoise[idx] + 0.5f)) + AddHeight + BaseNoise[x + 5 * z]; + NOISE_DATATYPE AddHeight = (static_cast(y * 8) - m_MidPoint) * m_HeightAmplification; + + // If "underground", make the terrain smoother by forcing the vertical linear gradient into steeper slope: + if (AddHeight < 0) + { + AddHeight *= 4; + } + + int idx = 33 * x + 33 * 5 * z + y; + Workspace[idx] = ClampedLerp(DensityNoiseA[idx], DensityNoiseB[idx], 8 * (ChoiceNoise[idx] + 0.5f)) + AddHeight + curBaseNoise; } } } - LinearUpscale3DArray(Workspace, 5, 5, 33, m_NoiseArray, 4, 4, 8); + LinearUpscale3DArray(Workspace, 33, 5, 5, m_NoiseArray, 8, 4, 4); } -void cNoise3DComposable::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) +void cNoise3DComposable::GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape) { GenerateNoiseArrayIfNeeded(a_ChunkX, a_ChunkZ); + // Translate the noise array into Shape: for (int z = 0; z < cChunkDef::Width; z++) { for (int x = 0; x < cChunkDef::Width; x++) { - cChunkDef::SetHeight(a_HeightMap, x, z, m_SeaLevel); - for (int y = cChunkDef::Height - 1; y > m_SeaLevel; y--) - { - if (m_NoiseArray[y * 17 * 17 + z * 17 + x] <= m_AirThreshold) - { - cChunkDef::SetHeight(a_HeightMap, x, z, y); - break; - } - } // for y - } // for x - } // for z -} - - - - - -void cNoise3DComposable::ComposeTerrain(cChunkDesc & a_ChunkDesc) -{ - GenerateNoiseArrayIfNeeded(a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ()); - - a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0); - - // Make basic terrain composition: - for (int z = 0; z < cChunkDef::Width; z++) - { - for (int x = 0; x < cChunkDef::Width; x++) - { - int LastAir = a_ChunkDesc.GetHeight(x, z) + 1; - bool HasHadWater = false; - for (int y = LastAir; y < m_SeaLevel; y++) + for (int y = 0; y < cChunkDef::Height; y++) { - a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_STATIONARY_WATER); + a_Shape[y + x * 256 + z * 256 * 16] = (m_NoiseArray[y + 257 * x + 257 * 17 * z] > m_AirThreshold) ? 0 : 1; } - for (int y = LastAir - 1; y > 0; y--) - { - if (m_NoiseArray[x + 17 * z + 17 * 17 * y] > m_AirThreshold) - { - // "air" part - LastAir = y; - if (y < m_SeaLevel) - { - a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_STATIONARY_WATER); - HasHadWater = true; - } - continue; - } - // "ground" part: - if (LastAir - y > 4) - { - a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_STONE); - continue; - } - if (HasHadWater) - { - a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_SAND); - } - else - { - a_ChunkDesc.SetBlockType(x, y, z, (LastAir == y + 1) ? E_BLOCK_GRASS : E_BLOCK_DIRT); - } - } // for y - a_ChunkDesc.SetBlockType(x, 0, z, E_BLOCK_BEDROCK); } // for x } // for z } @@ -671,21 +614,23 @@ void cBiomalNoise3DComposable::GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_Ch NOISE_DATATYPE BaseNoise[5 * 5]; NOISE_DATATYPE BlockX = static_cast(a_ChunkX * cChunkDef::Width); NOISE_DATATYPE BlockZ = static_cast(a_ChunkZ * cChunkDef::Width); - // Note that we have to swap the coords, because noise generator uses [x + SizeX * y + SizeX * SizeY * z] ordering and we want "BlockY" to be "z": - m_ChoiceNoise.Generate3D (ChoiceNoise, 5, 5, 33, BlockX / m_ChoiceFrequencyX, (BlockX + 17) / m_ChoiceFrequencyX, BlockZ / m_ChoiceFrequencyZ, (BlockZ + 17) / m_ChoiceFrequencyZ, 0, 257 / m_ChoiceFrequencyY, Workspace); - m_DensityNoiseA.Generate3D(DensityNoiseA, 5, 5, 33, BlockX / m_FrequencyX, (BlockX + 17) / m_FrequencyX, BlockZ / m_FrequencyZ, (BlockZ + 17) / m_FrequencyZ, 0, 257 / m_FrequencyY, Workspace); - m_DensityNoiseB.Generate3D(DensityNoiseB, 5, 5, 33, BlockX / m_FrequencyX, (BlockX + 17) / m_FrequencyX, BlockZ / m_FrequencyZ, (BlockZ + 17) / m_FrequencyZ, 0, 257 / m_FrequencyY, Workspace); + // Note that we have to swap the X and Y coords, because noise generator uses [x + SizeX * y + SizeX * SizeY * z] ordering and we want "BlockY" to be "x": + m_ChoiceNoise.Generate3D (ChoiceNoise, 33, 5, 5, 0, 257 / m_ChoiceFrequencyY, BlockX / m_ChoiceFrequencyX, (BlockX + 17) / m_ChoiceFrequencyX, BlockZ / m_ChoiceFrequencyZ, (BlockZ + 17) / m_ChoiceFrequencyZ, Workspace); + m_DensityNoiseA.Generate3D(DensityNoiseA, 33, 5, 5, 0, 257 / m_FrequencyY, BlockX / m_FrequencyX, (BlockX + 17) / m_FrequencyX, BlockZ / m_FrequencyZ, (BlockZ + 17) / m_FrequencyZ, Workspace); + m_DensityNoiseB.Generate3D(DensityNoiseB, 33, 5, 5, 0, 257 / m_FrequencyY, BlockX / m_FrequencyX, (BlockX + 17) / m_FrequencyX, BlockZ / m_FrequencyZ, (BlockZ + 17) / m_FrequencyZ, Workspace); m_BaseNoise.Generate2D (BaseNoise, 5, 5, BlockX / m_BaseFrequencyX, (BlockX + 17) / m_BaseFrequencyX, BlockZ / m_FrequencyZ, (BlockZ + 17) / m_FrequencyZ, Workspace); // Calculate the final noise based on the partial noises: - for (int y = 0; y < 33; y++) + for (int z = 0; z < 5; z++) { - NOISE_DATATYPE BlockHeight = static_cast(y * 8); - for (int z = 0; z < 5; z++) + for (int x = 0; x < 5; x++) { - for (int x = 0; x < 5; x++) + NOISE_DATATYPE curMidPoint = MidPoint[x + 5 * z]; + NOISE_DATATYPE curHeightAmp = HeightAmp[x + 5 * z]; + NOISE_DATATYPE curBaseNoise = BaseNoise[x + 5 * z]; + for (int y = 0; y < 33; y++) { - NOISE_DATATYPE AddHeight = (BlockHeight - MidPoint[x + 5 * z]) * HeightAmp[x + 5 * z]; + NOISE_DATATYPE AddHeight = (static_cast(y * 8) - curMidPoint) * curHeightAmp; // If "underground", make the terrain smoother by forcing the vertical linear gradient into steeper slope: if (AddHeight < 0) @@ -693,12 +638,12 @@ void cBiomalNoise3DComposable::GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_Ch AddHeight *= 4; } - int idx = x + 5 * z + 5 * 5 * y; - Workspace[idx] = ClampedLerp(DensityNoiseA[idx], DensityNoiseB[idx], 8 * (ChoiceNoise[idx] + 0.5f)) + AddHeight + BaseNoise[x + 5 * z]; + int idx = 33 * x + y + 33 * 5 * z; + Workspace[idx] = ClampedLerp(DensityNoiseA[idx], DensityNoiseB[idx], 8 * (ChoiceNoise[idx] + 0.5f)) + AddHeight + curBaseNoise; } } } - LinearUpscale3DArray(Workspace, 5, 5, 33, m_NoiseArray, 4, 4, 8); + LinearUpscale3DArray(Workspace, 33, 5, 5, m_NoiseArray, 8, 4, 4); } @@ -778,78 +723,19 @@ void cBiomalNoise3DComposable::GetBiomeParams(EMCSBiome a_Biome, NOISE_DATATYPE - -void cBiomalNoise3DComposable::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) +void cBiomalNoise3DComposable::GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape) { GenerateNoiseArrayIfNeeded(a_ChunkX, a_ChunkZ); + // Translate the noise array into Shape: for (int z = 0; z < cChunkDef::Width; z++) { for (int x = 0; x < cChunkDef::Width; x++) { - cChunkDef::SetHeight(a_HeightMap, x, z, m_SeaLevel); - for (int y = cChunkDef::Height - 1; y > m_SeaLevel; y--) - { - if (m_NoiseArray[y * 17 * 17 + z * 17 + x] <= m_AirThreshold) - { - cChunkDef::SetHeight(a_HeightMap, x, z, y); - break; - } - } // for y - } // for x - } // for z -} - - - - - -void cBiomalNoise3DComposable::ComposeTerrain(cChunkDesc & a_ChunkDesc) -{ - GenerateNoiseArrayIfNeeded(a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ()); - - a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0); - - // Make basic terrain composition: - for (int z = 0; z < cChunkDef::Width; z++) - { - for (int x = 0; x < cChunkDef::Width; x++) - { - int LastAir = a_ChunkDesc.GetHeight(x, z) + 1; - bool HasHadWater = false; - for (int y = LastAir; y < m_SeaLevel; y++) + for (int y = 0; y < cChunkDef::Height; y++) { - a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_STATIONARY_WATER); + a_Shape[y + x * 256 + z * 256 * 16] = (m_NoiseArray[y + 257 * x + 257 * 17 * z] > m_AirThreshold) ? 0 : 1; } - for (int y = LastAir - 1; y > 0; y--) - { - if (m_NoiseArray[x + 17 * z + 17 * 17 * y] > m_AirThreshold) - { - // "air" part - LastAir = y; - if (y < m_SeaLevel) - { - a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_STATIONARY_WATER); - HasHadWater = true; - } - continue; - } - // "ground" part: - if (LastAir - y > 4) - { - a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_STONE); - continue; - } - if (HasHadWater) - { - a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_SAND); - } - else - { - a_ChunkDesc.SetBlockType(x, y, z, (LastAir == y + 1) ? E_BLOCK_GRASS : E_BLOCK_DIRT); - } - } // for y - a_ChunkDesc.SetBlockType(x, 0, z, E_BLOCK_BEDROCK); } // for x } // for z } @@ -857,3 +743,4 @@ void cBiomalNoise3DComposable::ComposeTerrain(cChunkDesc & a_ChunkDesc) + diff --git a/src/Generating/Noise3DGenerator.h b/src/Generating/Noise3DGenerator.h index ba541fbcc..eaac182ba 100644 --- a/src/Generating/Noise3DGenerator.h +++ b/src/Generating/Noise3DGenerator.h @@ -69,8 +69,7 @@ protected: class cNoise3DComposable : - public cTerrainHeightGen, - public cTerrainCompositionGen + public cTerrainShapeGen { public: cNoise3DComposable(int a_Seed); @@ -127,12 +126,8 @@ protected: void GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_ChunkZ); // cTerrainHeightGen overrides: - virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; - virtual void InitializeHeightGen(cIniFile & a_IniFile) override { Initialize(a_IniFile); } - - // cTerrainCompositionGen overrides: - virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc) override; - virtual void InitializeCompoGen(cIniFile & a_IniFile) override { Initialize(a_IniFile); } + virtual void GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape) override; + virtual void InitializeShapeGen(cIniFile & a_IniFile) override { Initialize(a_IniFile); } } ; @@ -140,8 +135,7 @@ protected: class cBiomalNoise3DComposable : - public cTerrainHeightGen, - public cTerrainCompositionGen + public cTerrainShapeGen { public: cBiomalNoise3DComposable(int a_Seed, cBiomeGenPtr a_BiomeGen); @@ -194,7 +188,7 @@ protected: // Cache for the last calculated chunk (reused between heightmap and composition queries): int m_LastChunkX; int m_LastChunkZ; - NOISE_DATATYPE m_NoiseArray[17 * 17 * 257]; // x + 17 * z + 17 * 17 * y + NOISE_DATATYPE m_NoiseArray[17 * 17 * 257]; // 257 * x + y + 257 * 17 * z /** Weights for summing up neighboring biomes. */ NOISE_DATATYPE m_Weight[AVERAGING_SIZE * 2 + 1][AVERAGING_SIZE * 2 + 1]; @@ -212,13 +206,9 @@ protected: /** Returns the parameters for the specified biome. */ void GetBiomeParams(EMCSBiome a_Biome, NOISE_DATATYPE & a_HeightAmp, NOISE_DATATYPE & a_MidPoint); - // cTerrainHeightGen overrides: - virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; - virtual void InitializeHeightGen(cIniFile & a_IniFile) override { Initialize(a_IniFile); } - - // cTerrainCompositionGen overrides: - virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc) override; - virtual void InitializeCompoGen(cIniFile & a_IniFile) override { Initialize(a_IniFile); } + // cTerrainShapeGen overrides: + virtual void GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape) override; + virtual void InitializeShapeGen(cIniFile & a_IniFile) override { Initialize(a_IniFile); } } ; diff --git a/src/Generating/ShapeGen.cpp b/src/Generating/ShapeGen.cpp new file mode 100644 index 000000000..750b34e10 --- /dev/null +++ b/src/Generating/ShapeGen.cpp @@ -0,0 +1,140 @@ + +// ShapeGen.cpp + +// Implements the function to create a cTerrainShapeGen descendant based on INI file settings + +#include "Globals.h" +#include "HeiGen.h" +#include "../IniFile.h" +#include "DistortedHeightmap.h" +#include "EndGen.h" +#include "Noise3DGenerator.h" + + + + + +//////////////////////////////////////////////////////////////////////////////// +// cTerrainHeightToShapeGen: + +/** Converts old-style height-generators into new-style shape-generators. */ +class cTerrainHeightToShapeGen: + public cTerrainShapeGen +{ +public: + cTerrainHeightToShapeGen(cTerrainHeightGenPtr a_HeightGen): + m_HeightGen(a_HeightGen) + { + } + + + // cTerrainShapeGen overrides: + virtual void GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape) override + { + // Generate the heightmap: + cChunkDef::HeightMap heightMap; + m_HeightGen->GenHeightMap(a_ChunkX, a_ChunkZ, heightMap); + + // Convert from heightmap to shape: + for (int z = 0; z < cChunkDef::Width; z++) + { + for (int x = 0; x < cChunkDef::Width; x++) + { + HEIGHTTYPE height = cChunkDef::GetHeight(heightMap, x, z) + 1; + Byte * shapeColumn = &(a_Shape[(x + 16 * z) * 256]); + for (int y = 0; y < height; y++) + { + shapeColumn[y] = 1; + } + for (int y = height; y < cChunkDef::Height; y++) + { + shapeColumn[y] = 0; + } + } // for x + } // for z + } + + + virtual void InitializeShapeGen(cIniFile & a_IniFile) override + { + m_HeightGen->InitializeHeightGen(a_IniFile); + } + +protected: + /** The height generator being converted. */ + cTerrainHeightGenPtr m_HeightGen; +}; + +typedef SharedPtr cTerrainHeightToShapeGenPtr; + + + + + +//////////////////////////////////////////////////////////////////////////////// +// cTerrainShapeGen: + +cTerrainShapeGenPtr cTerrainShapeGen::CreateShapeGen(cIniFile & a_IniFile, cBiomeGenPtr a_BiomeGen, int a_Seed, bool & a_CacheOffByDefault) +{ + AString shapeGenName = a_IniFile.GetValueSet("Generator", "ShapeGen", ""); + if (shapeGenName.empty()) + { + LOGWARN("[Generator] ShapeGen value not set in world.ini, using \"BiomalNoise3D\"."); + shapeGenName = "BiomalNoise3D"; + } + + // If the shapegen is HeightMap, redirect to older HeightMap-based generators: + if (NoCaseCompare(shapeGenName, "HeightMap") == 0) + { + cTerrainHeightGenPtr heightGen = cTerrainHeightGen::CreateHeightGen(a_IniFile, a_BiomeGen, a_Seed, a_CacheOffByDefault); + if (heightGen != nullptr) + { + return std::make_shared(heightGen); + } + + // The height gen was not recognized; several heightgens were promoted to shape gens, so let's try them instead: + shapeGenName = a_IniFile.GetValue("Generator", "HeightGen", ""); + if (shapeGenName.empty()) + { + LOGWARNING("[Generator] ShapeGen set to HeightMap, but HeightGen not set. Reverting to \"BiomalNoise3D\"."); + shapeGenName = "BiomalNoise3D"; + a_IniFile.SetValue("Generator", "ShapeGen", shapeGenName); + } + } + + // Choose the shape generator based on the name: + a_CacheOffByDefault = false; + cTerrainShapeGenPtr res; + if (NoCaseCompare(shapeGenName, "DistortedHeightmap") == 0) + { + res = std::make_shared(a_Seed, a_BiomeGen); + } + else if (NoCaseCompare(shapeGenName, "End") == 0) + { + res = std::make_shared(a_Seed); + } + else if (NoCaseCompare(shapeGenName, "BiomalNoise3D") == 0) + { + res = std::make_shared(a_Seed, a_BiomeGen); + } + else if (NoCaseCompare(shapeGenName, "Noise3D") == 0) + { + res = std::make_shared(a_Seed); + } + else + { + // No match found, force-set the default and retry + LOGWARN("Unknown ShapeGen \"%s\", using \"BiomalNoise3D\" instead.", shapeGenName.c_str()); + a_IniFile.SetValue("Generator", "ShapeGen", "BiomalNoise3D"); + return CreateShapeGen(a_IniFile, a_BiomeGen, a_Seed, a_CacheOffByDefault); + } + + // Read the settings: + res->InitializeShapeGen(a_IniFile); + + return res; +} + + + + diff --git a/src/Generating/StructGen.cpp b/src/Generating/StructGen.cpp index bdefcd8c1..1c83cf78f 100644 --- a/src/Generating/StructGen.cpp +++ b/src/Generating/StructGen.cpp @@ -37,10 +37,12 @@ void cStructGenTrees::GenFinish(cChunkDesc & a_ChunkDesc) Dest = &WorkerDesc; WorkerDesc.SetChunkCoords(BaseX, BaseZ); + // TODO: This may cause a lot of wasted calculations, instead of pulling data out of a single (cChunkDesc) cache + + cChunkDesc::Shape workerShape; m_BiomeGen->GenBiomes (BaseX, BaseZ, WorkerDesc.GetBiomeMap()); - m_HeightGen->GenHeightMap (BaseX, BaseZ, WorkerDesc.GetHeightMap()); - m_CompositionGen->ComposeTerrain(WorkerDesc); - // TODO: Free the entity lists + m_ShapeGen->GenShape (BaseX, BaseZ, workerShape); + m_CompositionGen->ComposeTerrain(WorkerDesc, workerShape); } else { @@ -390,7 +392,7 @@ void cStructGenLakes::GenFinish(cChunkDesc & a_ChunkDesc) } cBlockArea Lake; - CreateLakeImage(ChunkX + x, ChunkZ + z, Lake); + CreateLakeImage(ChunkX + x, ChunkZ + z, a_ChunkDesc.GetMinHeight(), Lake); int OfsX = Lake.GetOriginX() + x * cChunkDef::Width; int OfsZ = Lake.GetOriginZ() + z * cChunkDef::Width; @@ -404,25 +406,13 @@ void cStructGenLakes::GenFinish(cChunkDesc & a_ChunkDesc) -void cStructGenLakes::CreateLakeImage(int a_ChunkX, int a_ChunkZ, cBlockArea & a_Lake) +void cStructGenLakes::CreateLakeImage(int a_ChunkX, int a_ChunkZ, int a_MaxLakeHeight, cBlockArea & a_Lake) { a_Lake.Create(16, 8, 16); a_Lake.Fill(cBlockArea::baTypes, E_BLOCK_SPONGE); // Sponge is the NOP blocktype for lake merging strategy - // Find the minimum height in this chunk: - cChunkDef::HeightMap HeightMap; - m_HeiGen->GenHeightMap(a_ChunkX, a_ChunkZ, HeightMap); - HEIGHTTYPE MinHeight = HeightMap[0]; - for (size_t i = 1; i < ARRAYCOUNT(HeightMap); i++) - { - if (HeightMap[i] < MinHeight) - { - MinHeight = HeightMap[i]; - } - } - // Make a random position in the chunk by using a random 16 block XZ offset and random height up to chunk's max height minus 6 - MinHeight = std::max(MinHeight - 6, 2); + int MinHeight = std::max(a_MaxLakeHeight - 6, 2); int Rnd = m_Noise.IntNoise3DInt(a_ChunkX, 128, a_ChunkZ) / 11; // Random offset [-8 .. 8], with higher probability around 0; add up four three-bit-wide randoms [0 .. 28], divide and subtract to get range int OffsetX = 4 * ((Rnd & 0x07) + ((Rnd & 0x38) >> 3) + ((Rnd & 0x1c0) >> 6) + ((Rnd & 0xe00) >> 9)) / 7 - 8; diff --git a/src/Generating/StructGen.h b/src/Generating/StructGen.h index 906fdd722..0c5efe622 100644 --- a/src/Generating/StructGen.h +++ b/src/Generating/StructGen.h @@ -24,11 +24,11 @@ class cStructGenTrees : public cFinishGen { public: - cStructGenTrees(int a_Seed, cBiomeGenPtr a_BiomeGen, cTerrainHeightGenPtr a_HeightGen, cTerrainCompositionGenPtr a_CompositionGen) : + cStructGenTrees(int a_Seed, cBiomeGenPtr a_BiomeGen, cTerrainShapeGenPtr a_ShapeGen, cTerrainCompositionGenPtr a_CompositionGen) : m_Seed(a_Seed), m_Noise(a_Seed), m_BiomeGen(a_BiomeGen), - m_HeightGen(a_HeightGen), + m_ShapeGen(a_ShapeGen), m_CompositionGen(a_CompositionGen) {} @@ -37,12 +37,12 @@ protected: int m_Seed; cNoise m_Noise; cBiomeGenPtr m_BiomeGen; - cTerrainHeightGenPtr m_HeightGen; + cTerrainShapeGenPtr m_ShapeGen; cTerrainCompositionGenPtr m_CompositionGen; /** Generates and applies an image of a single tree. - Parts of the tree inside the chunk are applied to a_BlockX. - Parts of the tree outside the chunk are stored in a_OutsideX + Parts of the tree inside the chunk are applied to a_ChunkDesc. + Parts of the tree outside the chunk are stored in a_OutsideXYZ */ void GenerateSingleTree( int a_ChunkX, int a_ChunkZ, int a_Seq, @@ -51,7 +51,7 @@ protected: sSetBlockVector & a_OutsideOther ) ; - /// Applies an image into chunk blockdata; all blocks outside the chunk will be appended to a_Overflow + /** Applies an image into chunk blockdata; all blocks outside the chunk will be appended to a_Overflow. */ void ApplyTreeImage( int a_ChunkX, int a_ChunkZ, cChunkDesc & a_ChunkDesc, @@ -124,27 +124,30 @@ class cStructGenLakes : public cFinishGen { public: - cStructGenLakes(int a_Seed, BLOCKTYPE a_Fluid, cTerrainHeightGenPtr a_HeiGen, int a_Probability) : + cStructGenLakes(int a_Seed, BLOCKTYPE a_Fluid, cTerrainShapeGenPtr a_ShapeGen, int a_Probability) : m_Noise(a_Seed), m_Seed(a_Seed), m_Fluid(a_Fluid), - m_HeiGen(a_HeiGen), + m_ShapeGen(a_ShapeGen), m_Probability(a_Probability) { } protected: - cNoise m_Noise; - int m_Seed; - BLOCKTYPE m_Fluid; - cTerrainHeightGenPtr m_HeiGen; - int m_Probability; ///< Chance, 0 .. 100, of a chunk having the lake + cNoise m_Noise; + int m_Seed; + BLOCKTYPE m_Fluid; + cTerrainShapeGenPtr m_ShapeGen; + + /** Chance, [0 .. 100], of a chunk having the lake. */ + int m_Probability; + // cFinishGen override: virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; - /// Creates a lake image for the specified chunk into a_Lake - void CreateLakeImage(int a_ChunkX, int a_ChunkZ, cBlockArea & a_Lake); + /** Creates a lake image for the specified chunk into a_Lake. */ + void CreateLakeImage(int a_ChunkX, int a_ChunkZ, int a_MaxLakeHeight, cBlockArea & a_Lake); } ; diff --git a/src/Generating/VillageGen.cpp b/src/Generating/VillageGen.cpp index a9b359b6a..f7d9a8316 100644 --- a/src/Generating/VillageGen.cpp +++ b/src/Generating/VillageGen.cpp @@ -18,8 +18,8 @@ /* How village generating works: -By descending from a cGridStructGen, a semi-random grid is generated. A village may be generated for each of -the grid's cells. Each cell checks the biomes in an entire chunk around it, only generating a village if all +By descending from a cGridStructGen, a semi-random (jitter) grid is generated. A village may be generated for each +of the grid's cells. Each cell checks the biomes in an entire chunk around it, only generating a village if all biomes are village-friendly. If yes, the entire village structure is built for that cell. If not, the cell is left village-less. @@ -125,7 +125,7 @@ public: m_Noise(a_Seed), m_MaxSize(a_MaxSize), m_Density(a_Density), - m_Borders(a_OriginX - a_MaxSize, 0, a_OriginZ - a_MaxSize, a_OriginX + a_MaxSize, 255, a_OriginZ + a_MaxSize), + m_Borders(a_OriginX - a_MaxSize, 0, a_OriginZ - a_MaxSize, a_OriginX + a_MaxSize, cChunkDef::Height - 1, a_OriginZ + a_MaxSize), m_Prefabs(a_Prefabs), m_HeightGen(a_HeightGen), m_RoadBlock(a_RoadBlock), -- cgit v1.2.3 From c9a3cb4d3f9fa9262b5adf775a8af0cc39234f5e Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 12 Nov 2014 21:59:42 +0100 Subject: Fixed trailing whitespace. --- src/Root.cpp | 2 +- src/Root.h | 2 +- src/World.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Root.cpp b/src/Root.cpp index 49d6117eb..55e1c1156 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -634,7 +634,7 @@ bool cRoot::FindAndDoWithPlayer(const AString & a_PlayerName, cPlayerListCallbac bool cRoot::DoWithPlayerByUUID(const AString & a_PlayerUUID, cPlayerListCallback & a_Callback) -{ +{ for (WorldMap::iterator itr = m_WorldsByName.begin(); itr != m_WorldsByName.end();itr++) { if (itr->second->DoWithPlayerByUUID(a_PlayerUUID, a_Callback)) diff --git a/src/Root.h b/src/Root.h index 618f70fb8..ec6b83fcc 100644 --- a/src/Root.h +++ b/src/Root.h @@ -125,7 +125,7 @@ public: /// Finds a player from a partial or complete player name and calls the callback - case-insensitive bool FindAndDoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS << - + /** Finds the player over his uuid and calls the callback */ bool DoWithPlayerByUUID(const AString & a_PlayerUUID, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS << diff --git a/src/World.h b/src/World.h index f1bf9371a..1a9f60a5c 100644 --- a/src/World.h +++ b/src/World.h @@ -325,7 +325,7 @@ public: /** Finds the player over his uuid and calls the callback */ bool DoWithPlayerByUUID(const AString & a_PlayerUUID, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS << - + void SendPlayerList(cPlayer * a_DestPlayer); // Sends playerlist to the player /** Adds the entity into its appropriate chunk; takes ownership of the entity ptr. -- cgit v1.2.3 From 5584144be2f0747d35f0828413d5441af4a277ee Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Thu, 13 Nov 2014 10:44:36 +0100 Subject: First implementation for the LargeOakTree --- src/Generating/Trees.cpp | 106 ++++++++++++++++++++++++++++++++++++++++++++++- src/Generating/Trees.h | 6 +++ src/Vector3.h | 15 +++++++ 3 files changed, 125 insertions(+), 2 deletions(-) diff --git a/src/Generating/Trees.cpp b/src/Generating/Trees.cpp index 7fd6d6f07..3c695ad20 100644 --- a/src/Generating/Trees.cpp +++ b/src/Generating/Trees.cpp @@ -61,7 +61,7 @@ static const sCoords BigO3[] = static const sCoords BigO4[] = // Part of Big Jungle tree { - /* -4 */ {-2, -4}, {-1, -4}, {0, -4}, {1, -4}, {2, -4}, + /* -4 */ {-2, -4}, {-1, -4}, {0, -4}, {1, -4}, {2, -4}, /* -3 */ {-3, -3}, {-2, -3}, {-1, -3}, {0, -3}, {1, -3}, {2, -3}, {3, -3}, /* -2 */ {-4, -2}, {-3, -2}, {-2, -2}, {-1, -2}, {0, -2}, {1, -2}, {2, -2}, {3, -2}, {4, -2}, /* -1 */ {-4, -1}, {-3, -1}, {-2, -1}, {-1, -1}, {0, -1}, {1, -1}, {2, -1}, {3, -1}, {4, -1}, @@ -361,7 +361,109 @@ void GetSmallAppleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a void GetLargeAppleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks) { - // TODO + int Height = 7 + a_Noise.IntNoise3DInt(a_BlockX, a_BlockY, a_BlockZ) % 4; + + // Array with possible directions for a branch to go to. + const Vector3d AvailableDirections[] = + { + { -1, 0, 0 }, { 0, 0, -1 }, + { -1, 0, 1 }, { -1, 0, -1 }, + { 1, 0, 1 }, { 1, 0, -1 }, + { 1, 0, 0 }, { 0, 0, 1 }, + + { -0.5, 0, 0 }, { 0, 0, -0.5 }, + { -0.5, 0, 0.5 }, { -0.5, 0, -0.5 }, + { 0.5, 0, 0.5 }, { 0.5, 0, -0.5 }, + { 0.5, 0, 0 }, { 0, 0, 0.5 }, + + { -1, 0.5, 0 }, { 0, 0.5, -1 }, + { -1, 0.5, 1 }, { -1, 0.5, -1 }, + { 1, 0.5, 1 }, { 1, 0.5, -1 }, + { 1, 0.5, 0 }, { 0, 0.5, 1 }, + + { -0.5, 0.5, 0 }, { 0, 0.5, -0.5 }, + { -0.5, 0.5, 0.5 }, { -0.5, 0.5, -0.5 }, + { 0.5, 0.5, 0.5 }, { 0.5, 0.5, -0.5 }, + { 0.5, 0.5, 0 }, { 0, 0.5, 0.5 }, + + }; + + // Create branches + for (int i = 4; i < Height; i++) + { + // Get a direction for the trunk to go to. + Vector3d BranchStartDirection = AvailableDirections[a_Noise.IntNoise3DInt(a_BlockX, a_BlockY + i, a_BlockZ) % ARRAYCOUNT(AvailableDirections)]; + Vector3d BranchDirection = AvailableDirections[a_Noise.IntNoise3DInt(a_BlockX, a_BlockY / i, a_BlockZ) % ARRAYCOUNT(AvailableDirections)] / 3; + + int BranchLength = 2 + a_Noise.IntNoise3DInt(a_BlockX * a_Seq, a_BlockY * a_Seq, a_BlockZ * a_Seq) % 3; + GetLargeAppleTreeBranch(a_BlockX, a_BlockY + i, a_BlockZ, BranchLength, BranchStartDirection, BranchDirection, a_BlockY + Height, a_Noise, a_LogBlocks); + } + + // Place leaves + for (auto itr : a_LogBlocks) + { + // Get the log's X and Z coordinates + int X = itr.ChunkX * 16 + itr.x; + int Z = itr.ChunkZ * 16 + itr.z; + + a_OtherBlocks.push_back(sSetBlock(X, itr.y - 2, Z, E_BLOCK_LEAVES, E_META_LEAVES_APPLE)); + PushCoordBlocks(X, itr.y - 2, Z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_APPLE); + for (int y = -1; y <= 1; y++) + { + PushCoordBlocks (X, itr.y + y, Z, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_APPLE); + } + PushCoordBlocks(X, itr.y + 2, Z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_APPLE); + a_OtherBlocks.push_back(sSetBlock(X, itr.y + 2, Z, E_BLOCK_LEAVES, E_META_LEAVES_APPLE)); + } + + // Trunk: + for (int i = 0; i < Height; i++) + { + a_LogBlocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_APPLE)); + } +} + + + + + +void GetLargeAppleTreeBranch(int a_BlockX, int a_BlockY, int a_BlockZ, int a_BranchLength, Vector3d a_StartDirection, Vector3d a_Direction, int a_TreeHeight, cNoise & a_Noise, sSetBlockVector & a_LogBlocks) +{ + Vector3d CurrentPos = Vector3d(a_BlockX, a_BlockY, a_BlockZ); + Vector3d Direction = a_StartDirection; + for (int i = 0; i < a_BranchLength; i++) + { + CurrentPos += Direction; + if (CurrentPos.y >= a_TreeHeight) + { + return; + } + Direction -= a_Direction; + Direction.clamp(-1.0, 1.0); + a_LogBlocks.push_back(sSetBlock(FloorC(CurrentPos.x), FloorC(CurrentPos.y), FloorC(CurrentPos.z), E_BLOCK_LOG, GetLogMetaFromDirection(E_META_LOG_APPLE, Direction))); + } +} + + + + + +NIBBLETYPE GetLogMetaFromDirection(NIBBLETYPE a_BlockMeta, Vector3d a_Direction) +{ + a_Direction.abs(); + + if ((a_Direction.y > a_Direction.x) && (a_Direction.y > a_Direction.z)) + { + return a_BlockMeta; + } + else if (a_Direction.x > a_Direction.z) + { + return a_BlockMeta + 4; + } + else + { + return a_BlockMeta + 8; + } } diff --git a/src/Generating/Trees.h b/src/Generating/Trees.h index c9eb7de80..b6b61fe7b 100644 --- a/src/Generating/Trees.h +++ b/src/Generating/Trees.h @@ -62,6 +62,12 @@ void GetSmallAppleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a /// Generates an image of a large (branching) apple tree void GetLargeAppleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks); +/// Generates a branch for a large apple tree +void GetLargeAppleTreeBranch(int a_BlockX, int a_BlockY, int a_BlockZ, int a_BranchLength, Vector3d a_StartDirection, Vector3d a_Direction, int a_TreeHeight, cNoise & a_Noise, sSetBlockVector & a_LogBlocks); + +/// Returns the meta for a log from the given direction +NIBBLETYPE GetLogMetaFromDirection(NIBBLETYPE a_BlockMeta, Vector3d a_Direction); + /// Generates an image of a random birch tree void GetBirchTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks); diff --git a/src/Vector3.h b/src/Vector3.h index 1854e42e3..1e4a1f5d9 100644 --- a/src/Vector3.h +++ b/src/Vector3.h @@ -93,6 +93,21 @@ public: return x * a_Rhs.x + y * a_Rhs.y + z * a_Rhs.z; } + inline void abs() + { + x = (x < 0) ? -x : x; + y = (y < 0) ? -y : y; + z = (z < 0) ? -z : z; + } + + // We can't use a capital letter, because we wouldn't be able to call the normal Clamp function. + inline void clamp(T a_Min, T a_Max) + { + x = Clamp(x, a_Min, a_Max); + y = Clamp(y, a_Min, a_Max); + z = Clamp(z, a_Min, a_Max); + } + inline Vector3 Cross(const Vector3 & a_Rhs) const { return Vector3( -- cgit v1.2.3 From 7a3b3aeb3c28b7ba899d6dff2b5e160a95529f40 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 13 Nov 2014 21:28:50 +0100 Subject: Gen refactor: Implemented CompositedHeiGen. This fixes crashes in the Village generator due to the missing generator. --- src/Generating/CMakeLists.txt | 1 + src/Generating/CompoGen.cpp | 2 + src/Generating/CompoGen.h | 1 + src/Generating/CompoGenBiomal.cpp | 214 --------------------------------- src/Generating/ComposableGenerator.cpp | 13 +- src/Generating/CompositedHeiGen.h | 49 ++++++++ src/Generating/HeiGen.cpp | 45 +++++++ src/Generating/HeiGen.h | 32 +++++ src/Generating/StructGen.cpp | 1 + 9 files changed, 141 insertions(+), 217 deletions(-) create mode 100644 src/Generating/CompositedHeiGen.h diff --git a/src/Generating/CMakeLists.txt b/src/Generating/CMakeLists.txt index 047452bbb..dcb4bb3a7 100644 --- a/src/Generating/CMakeLists.txt +++ b/src/Generating/CMakeLists.txt @@ -42,6 +42,7 @@ SET (HDRS CompoGen.h CompoGenBiomal.h ComposableGenerator.h + CompositedHeiGen.h DistortedHeightmap.h DungeonRoomsFinisher.h EndGen.h diff --git a/src/Generating/CompoGen.cpp b/src/Generating/CompoGen.cpp index ef13b7c6b..db43e34b6 100644 --- a/src/Generating/CompoGen.cpp +++ b/src/Generating/CompoGen.cpp @@ -417,6 +417,7 @@ void cCompoGenCache::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc:: // Use the cached data: memcpy(a_ChunkDesc.GetBlockTypes(), m_CacheData[Idx].m_BlockTypes, sizeof(a_ChunkDesc.GetBlockTypes())); memcpy(a_ChunkDesc.GetBlockMetasUncompressed(), m_CacheData[Idx].m_BlockMetas, sizeof(a_ChunkDesc.GetBlockMetasUncompressed())); + memcpy(a_ChunkDesc.GetHeightMap(), m_CacheData[Idx].m_HeightMap, sizeof(a_ChunkDesc.GetHeightMap())); m_NumHits++; m_TotalChain += i; @@ -436,6 +437,7 @@ void cCompoGenCache::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc:: m_CacheOrder[0] = Idx; memcpy(m_CacheData[Idx].m_BlockTypes, a_ChunkDesc.GetBlockTypes(), sizeof(a_ChunkDesc.GetBlockTypes())); memcpy(m_CacheData[Idx].m_BlockMetas, a_ChunkDesc.GetBlockMetasUncompressed(), sizeof(a_ChunkDesc.GetBlockMetasUncompressed())); + memcpy(m_CacheData[Idx].m_HeightMap, a_ChunkDesc.GetHeightMap(), sizeof(a_ChunkDesc.GetHeightMap())); m_CacheData[Idx].m_ChunkX = ChunkX; m_CacheData[Idx].m_ChunkZ = ChunkZ; } diff --git a/src/Generating/CompoGen.h b/src/Generating/CompoGen.h index 16c00c13d..03df0cf25 100644 --- a/src/Generating/CompoGen.h +++ b/src/Generating/CompoGen.h @@ -132,6 +132,7 @@ protected: int m_ChunkZ; cChunkDef::BlockTypes m_BlockTypes; cChunkDesc::BlockNibbleBytes m_BlockMetas; // The metas are uncompressed, 1 meta per byte + cChunkDef::HeightMap m_HeightMap; } ; // To avoid moving large amounts of data for the MRU behavior, we MRU-ize indices to an array of the actual data diff --git a/src/Generating/CompoGenBiomal.cpp b/src/Generating/CompoGenBiomal.cpp index 1e3363606..0bb7f4802 100644 --- a/src/Generating/CompoGenBiomal.cpp +++ b/src/Generating/CompoGenBiomal.cpp @@ -570,220 +570,6 @@ protected: return patDirt.Get(); } } - - - - #if 0 - /** Fills a single column with grass-based terrain (grass or water, dirt, stone). */ - void FillColumnGrass(int a_RelX, int a_RelZ, const Byte * a_ShapeColumn, cChunkDesc & a_ChunkDesc) - { - static const PatternItem pattern[] = - { - { E_BLOCK_GRASS, 0}, - { E_BLOCK_DIRT, 0}, - { E_BLOCK_DIRT, 0}, - { E_BLOCK_DIRT, 0}, - } ; - FillColumnPattern(a_RelX, a_RelZ, a_ShapeColumn, a_ChunkDesc, pattern, ARRAYCOUNT(pattern)); - } - - - - /** Fills a single column with grass-based terrain (grass or water, dirt, stone). */ - void FillColumnStone(int a_RelX, int a_RelZ, const Byte * a_ShapeColumn, cChunkDesc & a_ChunkDesc) - { - static const PatternItem pattern[] = - { - { E_BLOCK_STONE, 0}, - } ; - FillColumnPattern(a_RelX, a_RelZ, a_ShapeColumn, a_ChunkDesc, pattern, ARRAYCOUNT(pattern)); - } - - - - /** Fills a single column with Mesa-like terrain (variations of clay). */ - void FillColumnMesa(int a_RelX, int a_RelZ, const Byte * a_ShapeColumn, cChunkDesc & a_ChunkDesc) - { - // Fill with grass and dirt on the very top of mesa plateaus: - size_t curIdx = 0; - for (int y = 255; y > m_MesaDirtLevel; y--) - { - if (a_ShapeColumn[y] > 0) - { - a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, (curIdx > 0) ? E_BLOCK_DIRT : E_BLOCK_GRASS); - curIdx += 1; - } - else - { - curIdx = 0; - } - } // for y - - // Fill with clays from the DirtLevel down to SandLevel: - for (int y = m_MesaDirtLevel; y > m_MesaSandLevel; y--) - { - if (a_ShapeColumn[y] > 0) - { - a_ChunkDesc.SetBlockTypeMeta(a_RelX, y, a_RelZ, m_MesaPattern[y].m_BlockType, m_MesaPattern[y].m_BlockMeta); - } - else - { - curIdx = 0; - } - } // for y - - // If currently air, switch to red sand pattern: - static const PatternItem redSandPattern[] = - { - { E_BLOCK_SAND, E_META_SAND_RED}, - { E_BLOCK_STAINED_CLAY, E_META_STAINED_CLAY_ORANGE}, - { E_BLOCK_STAINED_CLAY, E_META_STAINED_CLAY_ORANGE}, - { E_BLOCK_STAINED_CLAY, E_META_STAINED_CLAY_ORANGE}, - }; - Pattern pattern; - size_t patternSize; - if (curIdx == 0) - { - pattern = redSandPattern; - patternSize = ARRAYCOUNT(redSandPattern); - } - else - { - pattern = m_MesaPattern + m_MesaSandLevel; - patternSize = static_cast(m_MesaSandLevel); - } - - // Fill with current pattern (MesaPattern or RedSand) until sealevel: - for (int y = m_MesaSandLevel; y > m_SeaLevel; y--) - { - if (a_ShapeColumn[y] > 0) - { - if (curIdx >= patternSize) - { - a_ChunkDesc.SetBlockTypeMeta(a_RelX, y, a_RelZ, E_BLOCK_STAINED_CLAY, E_META_STAINED_CLAY_ORANGE); - } - else - { - a_ChunkDesc.SetBlockTypeMeta(a_RelX, y, a_RelZ, pattern[curIdx].m_BlockType, pattern[curIdx].m_BlockMeta); - } - curIdx += 1; - } - else - { - // Air resets the pattern to red sand: - curIdx = 0; - pattern = redSandPattern; - patternSize = ARRAYCOUNT(redSandPattern); - } - } // for y - - // If there is an ocean, fill it with water and then redsand: - int y = m_SeaLevel; - for (; y > 0; y--) - { - if ((a_ShapeColumn[y] == 0) || (curIdx >= ARRAYCOUNT(redSandPattern))) - { - // water pocket or out of red sand pattern, use stone from now on - break; - } - a_ChunkDesc.SetBlockTypeMeta(a_RelX, y, a_RelZ, E_BLOCK_STAINED_CLAY, E_META_STAINED_CLAY_ORANGE); - curIdx = curIdx + 1; - } // for y - - // The rest should be filled with stone: - for (; y > 0; y--) - { - if (a_ShapeColumn[y] > 0) - { - a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_STONE); - } - } // for y - } - - - - /** Fills a single column with megataiga-based terrain (grass or podzol on top). */ - void FillColumnMegaTaiga(int a_RelX, int a_RelZ, const Byte * a_ShapeColumn, cChunkDesc & a_ChunkDesc) - { - // TODO - } - - - - /** Fills a single column with sand-based terrain (such as desert or beach). */ - void FillColumnSand(int a_RelX, int a_RelZ, const Byte * a_ShapeColumn, cChunkDesc & a_ChunkDesc) - { - static const PatternItem pattern[] = - { - { E_BLOCK_SAND, 0}, - { E_BLOCK_SAND, 0}, - { E_BLOCK_SAND, 0}, - { E_BLOCK_SANDSTONE, 0}, - } ; - FillColumnPattern(a_RelX, a_RelZ, a_ShapeColumn, a_ChunkDesc, pattern, ARRAYCOUNT(pattern)); - } - - - - void FillColumnMycelium(int a_RelX, int a_RelZ, const Byte * a_ShapeColumn, cChunkDesc & a_ChunkDesc) - { - static const PatternItem pattern[] = - { - { E_BLOCK_MYCELIUM, 0}, - { E_BLOCK_DIRT, 0}, - { E_BLOCK_DIRT, 0}, - { E_BLOCK_DIRT, 0}, - } ; - FillColumnPattern(a_RelX, a_RelZ, a_ShapeColumn, a_ChunkDesc, pattern, ARRAYCOUNT(pattern)); - } - - - - /** Fills the column with the specified pattern, repeating it if there's an air pocket in between. */ - void FillColumnPattern(int a_RelX, int a_RelZ, const Byte * a_ShapeColumn, cChunkDesc & a_ChunkDesc, Pattern a_Pattern, size_t a_PatternSize) - { - // Fill with pattern until sealevel: - size_t curIdx = 0; - for (int y = 255; y > m_SeaLevel; y--) - { - if (a_ShapeColumn[y] > 0) - { - // Continue with the pattern: - if (curIdx >= a_PatternSize) - { - a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_STONE); - } - else - { - a_ChunkDesc.SetBlockTypeMeta(a_RelX, y, a_RelZ, a_Pattern[curIdx].m_BlockType, a_Pattern[curIdx].m_BlockMeta); - } - curIdx += 1; - } - else - { - // Air pocket, restart the pattern: - curIdx = 0; - } - } // for y - - // From sealevel downward use the ocean floor pattern: - FillOceanFloor(a_RelX, a_RelZ, a_ShapeColumn, a_ChunkDesc, a_Pattern, a_PatternSize, curIdx); - } - - - /** Fills the blocks from sealevel down to bottom with ocean-floor pattern. - a_PatternStartOffset specifies the offset at which to start the pattern, in case there was air just above. */ - void FillOceanFloor(int a_RelX, int a_RelZ, const Byte * a_ShapeColumn, cChunkDesc & a_ChunkDesc, Pattern a_Pattern, size_t a_PatternSize, size_t a_PatternStartOffset) - { - for (int y = m_SeaLevel; y > 0; y--) - { - if (a_ShapeColumn[y] > 0) - { - // TODO - } - } // for y - } - #endif } ; diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index 5420e12ac..4192dfa72 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -19,6 +19,8 @@ #include "CompoGenBiomal.h" +#include "CompositedHeiGen.h" + #include "Caves.h" #include "DistortedHeightmap.h" #include "DungeonRoomsFinisher.h" @@ -173,7 +175,6 @@ void cComposableGenerator::DoGenerate(int a_ChunkX, int a_ChunkZ, cChunkDesc & a if (a_ChunkDesc.IsUsingDefaultComposition()) { m_CompositionGen->ComposeTerrain(a_ChunkDesc, shape); - ShouldUpdateHeightmap = true; } if (a_ChunkDesc.IsUsingDefaultFinish()) @@ -264,11 +265,17 @@ void cComposableGenerator::InitCompositionGen(cIniFile & a_IniFile) { m_CompositionGen = cTerrainCompositionGen::CreateCompositionGen(a_IniFile, m_BiomeGen, m_ShapeGen, m_ChunkGenerator.GetSeed()); + // Add a cache over the composition generator: + // Even a cache of size 1 is useful due to the CompositedHeiGen cache after us doing re-composition on its misses int CompoGenCacheSize = a_IniFile.GetValueSetI("Generator", "CompositionGenCacheSize", 64); - if (CompoGenCacheSize > 1) + if (CompoGenCacheSize > 0) { - m_CompositionGen = cTerrainCompositionGenPtr(new cCompoGenCache(m_CompositionGen, 32)); + m_CompositionGen = std::make_shared(m_CompositionGen, CompoGenCacheSize); } + + // Create a cache of the composited heightmaps, so that finishers may use it: + m_CompositedHeightCache = std::make_shared(std::make_shared(m_ShapeGen, m_CompositionGen), 16, 24); + // 24 subcaches of depth 16 each = 96 KiB of RAM. Acceptable, for the amount of work this saves. } diff --git a/src/Generating/CompositedHeiGen.h b/src/Generating/CompositedHeiGen.h new file mode 100644 index 000000000..fa33a7861 --- /dev/null +++ b/src/Generating/CompositedHeiGen.h @@ -0,0 +1,49 @@ + +// CompositedHeiGen.h + +// Declares the cCompositedHeiGen class representing a cTerrainHeightGen descendant that calculates heightmap of the composited terrain +// This is used to further cache heightmaps for chunks already generated for finishers that require only heightmap information + + + + + +#pragma once + +#include "ComposableGenerator.h" + + + + + +class cCompositedHeiGen: + public cTerrainHeightGen +{ +public: + cCompositedHeiGen(cTerrainShapeGenPtr a_ShapeGen, cTerrainCompositionGenPtr a_CompositionGen): + m_ShapeGen(a_ShapeGen), + m_CompositionGen(a_CompositionGen) + { + } + + + + // cTerrainheightGen overrides: + virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override + { + cChunkDesc::Shape shape; + m_ShapeGen->GenShape(a_ChunkX, a_ChunkZ, shape); + cChunkDesc desc(a_ChunkX, a_ChunkZ); + desc.SetHeightFromShape(shape); + m_CompositionGen->ComposeTerrain(desc, shape); + memcpy(a_HeightMap, desc.GetHeightMap(), sizeof(a_HeightMap)); + } + +protected: + cTerrainShapeGenPtr m_ShapeGen; + cTerrainCompositionGenPtr m_CompositionGen; +}; + + + + diff --git a/src/Generating/HeiGen.cpp b/src/Generating/HeiGen.cpp index 86f934c16..61d087c17 100644 --- a/src/Generating/HeiGen.cpp +++ b/src/Generating/HeiGen.cpp @@ -149,6 +149,51 @@ bool cHeiGenCache::GetHeightAt(int a_ChunkX, int a_ChunkZ, int a_RelX, int a_Rel +//////////////////////////////////////////////////////////////////////////////// +// cHeiGenMultiCache: + +cHeiGenMultiCache::cHeiGenMultiCache(cTerrainHeightGenPtr a_HeiGenToCache, size_t a_SubCacheSize, size_t a_NumSubCaches): + m_NumSubCaches(a_NumSubCaches) +{ + // Create the individual sub-caches: + m_SubCaches.reserve(a_NumSubCaches); + for (size_t i = 0; i < a_NumSubCaches; i++) + { + m_SubCaches.push_back(std::make_shared(a_HeiGenToCache, a_SubCacheSize)); + } +} + + + + + +void cHeiGenMultiCache::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) +{ + // Get the subcache responsible for this chunk: + const size_t cacheIdx = ((size_t)a_ChunkX + m_CoeffZ * (size_t)a_ChunkZ) % m_NumSubCaches; + + // Ask the subcache: + m_SubCaches[cacheIdx]->GenHeightMap(a_ChunkX, a_ChunkZ, a_HeightMap); +} + + + + + +bool cHeiGenMultiCache::GetHeightAt(int a_ChunkX, int a_ChunkZ, int a_RelX, int a_RelZ, HEIGHTTYPE & a_Height) +{ + // Get the subcache responsible for this chunk: + const size_t cacheIdx = ((size_t)a_ChunkX + m_CoeffZ * (size_t)a_ChunkZ) % m_NumSubCaches; + + // Ask the subcache: + return m_SubCaches[cacheIdx]->GetHeightAt(a_ChunkX, a_ChunkZ, a_RelX, a_RelZ, a_Height); +} + + + + + + //////////////////////////////////////////////////////////////////////////////// // cHeiGenClassic: diff --git a/src/Generating/HeiGen.h b/src/Generating/HeiGen.h index d91ace3bd..fe0a023e4 100644 --- a/src/Generating/HeiGen.h +++ b/src/Generating/HeiGen.h @@ -63,6 +63,38 @@ protected: +/** Caches heightmaps in multiple underlying caches to improve the distribution and lower the chain length. */ +class cHeiGenMultiCache: + public cTerrainHeightGen +{ +public: + cHeiGenMultiCache(cTerrainHeightGenPtr a_HeightGenToCache, size_t a_SubCacheSize, size_t a_NumSubCaches); + + // cTerrainHeightGen overrides: + virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; + + /** Retrieves height at the specified point in the cache, returns true if found, false if not found */ + bool GetHeightAt(int a_ChunkX, int a_ChunkZ, int a_RelX, int a_RelZ, HEIGHTTYPE & a_Height); + +protected: + typedef SharedPtr cHeiGenCachePtr; + typedef std::vector cHeiGenCachePtrs; + + + /** The coefficient used to turn Z coords into index (x + Coeff * z). */ + static const size_t m_CoeffZ = 5; + + /** Number of sub-caches, pulled out of m_SubCaches.size() for performance reasons. */ + size_t m_NumSubCaches; + + /** The individual sub-caches. */ + cHeiGenCachePtrs m_SubCaches; +}; + + + + + class cHeiGenFlat : public cTerrainHeightGen { diff --git a/src/Generating/StructGen.cpp b/src/Generating/StructGen.cpp index 1c83cf78f..ca8f0411f 100644 --- a/src/Generating/StructGen.cpp +++ b/src/Generating/StructGen.cpp @@ -42,6 +42,7 @@ void cStructGenTrees::GenFinish(cChunkDesc & a_ChunkDesc) cChunkDesc::Shape workerShape; m_BiomeGen->GenBiomes (BaseX, BaseZ, WorkerDesc.GetBiomeMap()); m_ShapeGen->GenShape (BaseX, BaseZ, workerShape); + WorkerDesc.SetHeightFromShape (workerShape); m_CompositionGen->ComposeTerrain(WorkerDesc, workerShape); } else -- cgit v1.2.3 From 2789fafeb7445a69ccd31e7867e5c9f27654725f Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 13 Nov 2014 21:47:39 +0100 Subject: Noise3D: Added oceans. --- src/Generating/Noise3DGenerator.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Generating/Noise3DGenerator.cpp b/src/Generating/Noise3DGenerator.cpp index 4e45aa18b..d516b612c 100644 --- a/src/Generating/Noise3DGenerator.cpp +++ b/src/Generating/Noise3DGenerator.cpp @@ -756,10 +756,13 @@ void cBiomalNoise3DComposable::GetBiomeParams(EMCSBiome a_Biome, NOISE_DATATYPE { switch (a_Biome) { + case biDeepOcean: a_HeightAmp = 0.17f; a_MidPoint = 35; break; case biDesert: a_HeightAmp = 0.29f; a_MidPoint = 62; break; // Needs verification case biExtremeHills: a_HeightAmp = 0.045f; a_MidPoint = 75; break; case biExtremeHillsPlus: a_HeightAmp = 0.04f; a_MidPoint = 80; break; case biFrozenRiver: a_HeightAmp = 0.4f; a_MidPoint = 53; break; + case biFrozenOcean: a_HeightAmp = 0.17f; a_MidPoint = 47; break; + case biOcean: a_HeightAmp = 0.17f; a_MidPoint = 47; break; case biPlains: a_HeightAmp = 0.3f; a_MidPoint = 62; break; // Needs verification case biRiver: a_HeightAmp = 0.4f; a_MidPoint = 53; break; case biSwampland: a_HeightAmp = 0.25f; a_MidPoint = 59; break; -- cgit v1.2.3 From 644240a0e5b03889fb202ff173337cdf389d197b Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 14 Nov 2014 22:17:11 +0100 Subject: Noise3D: Added jungles. --- src/Generating/Noise3DGenerator.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Generating/Noise3DGenerator.cpp b/src/Generating/Noise3DGenerator.cpp index d516b612c..91bdce458 100644 --- a/src/Generating/Noise3DGenerator.cpp +++ b/src/Generating/Noise3DGenerator.cpp @@ -762,6 +762,8 @@ void cBiomalNoise3DComposable::GetBiomeParams(EMCSBiome a_Biome, NOISE_DATATYPE case biExtremeHillsPlus: a_HeightAmp = 0.04f; a_MidPoint = 80; break; case biFrozenRiver: a_HeightAmp = 0.4f; a_MidPoint = 53; break; case biFrozenOcean: a_HeightAmp = 0.17f; a_MidPoint = 47; break; + case biJungle: a_HeightAmp = 0.1f; a_MidPoint = 63; break; + case biJungleM: a_HeightAmp = 0.1f; a_MidPoint = 63; break; case biOcean: a_HeightAmp = 0.17f; a_MidPoint = 47; break; case biPlains: a_HeightAmp = 0.3f; a_MidPoint = 62; break; // Needs verification case biRiver: a_HeightAmp = 0.4f; a_MidPoint = 53; break; -- cgit v1.2.3 From 83d3f3347b5c812b06be87804b7582a92d0294d3 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 14 Nov 2014 22:53:12 +0100 Subject: Use m_UsedViewDistance and m_SetViewDistance. --- src/ClientHandle.cpp | 18 ++++++++++-------- src/ClientHandle.h | 20 +++++++++++++------- src/Entities/Player.cpp | 3 +++ 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index d7d97c6c4..d5882da06 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -65,7 +65,8 @@ int cClientHandle::s_ClientCount = 0; // cClientHandle: cClientHandle::cClientHandle(const cSocket * a_Socket, int a_ViewDistance) : - m_ViewDistance(a_ViewDistance), + m_UsedViewDistance(a_ViewDistance), + m_SetViewDistance(a_ViewDistance), m_IPString(a_Socket->GetIPString()), m_OutgoingData(64 KiB), m_Player(nullptr), @@ -430,7 +431,7 @@ bool cClientHandle::StreamNextChunk(void) cCSLock Lock(m_CSChunkLists); // High priority: Load the chunks that are in the view-direction of the player (with a radius of 3) - for (int Range = 0; Range < m_ViewDistance; Range++) + for (int Range = 0; Range < m_UsedViewDistance; Range++) { Vector3d Vector = Position + LookVector * cChunkDef::Width * Range; @@ -447,7 +448,7 @@ bool cClientHandle::StreamNextChunk(void) cChunkCoords Coords(ChunkX, ChunkZ); // Checks if the chunk is in distance - if ((Diff(ChunkX, ChunkPosX) > m_ViewDistance) || (Diff(ChunkZ, ChunkPosZ) > m_ViewDistance)) + if ((Diff(ChunkX, ChunkPosX) > m_UsedViewDistance) || (Diff(ChunkZ, ChunkPosZ) > m_UsedViewDistance)) { continue; } @@ -470,7 +471,7 @@ bool cClientHandle::StreamNextChunk(void) } // Low priority: Add all chunks that are in range. (From the center out to the edge) - for (int d = 0; d <= m_ViewDistance; ++d) // cycle through (square) distance, from nearest to furthest + for (int d = 0; d <= m_UsedViewDistance; ++d) // cycle through (square) distance, from nearest to furthest { // For each distance add chunks in a hollow square centered around current position: cChunkCoordsList CurcleChunks; @@ -528,7 +529,7 @@ void cClientHandle::UnloadOutOfRangeChunks(void) { int DiffX = Diff((*itr).m_ChunkX, ChunkPosX); int DiffZ = Diff((*itr).m_ChunkZ, ChunkPosZ); - if ((DiffX > m_ViewDistance) || (DiffZ > m_ViewDistance)) + if ((DiffX > m_UsedViewDistance) || (DiffZ > m_UsedViewDistance)) { ChunksToRemove.push_back(*itr); itr = m_LoadedChunks.erase(itr); @@ -543,7 +544,7 @@ void cClientHandle::UnloadOutOfRangeChunks(void) { int DiffX = Diff((*itr).m_ChunkX, ChunkPosX); int DiffZ = Diff((*itr).m_ChunkZ, ChunkPosZ); - if ((DiffX > m_ViewDistance) || (DiffZ > m_ViewDistance)) + if ((DiffX > m_UsedViewDistance) || (DiffZ > m_UsedViewDistance)) { itr = m_ChunksToSend.erase(itr); } @@ -2849,8 +2850,9 @@ void cClientHandle::SetViewDistance(int a_ViewDistance) { ASSERT(m_Player->GetWorld() == NULL); - m_ViewDistance = Clamp(a_ViewDistance, cClientHandle::MIN_VIEW_DISTANCE, m_Player->GetWorld()->GetMaxViewDistance()); - LOGD("Setted %s's view distance to %i", GetUsername().c_str(), m_ViewDistance); + m_SetViewDistance = a_ViewDistance; + m_UsedViewDistance = Clamp(m_SetViewDistance, cClientHandle::MIN_VIEW_DISTANCE, m_Player->GetWorld()->GetMaxViewDistance()); + LOGD("Setted view distance from %s to %i!", GetUsername().c_str(), m_UsedViewDistance); } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 082ed2fcc..20789621d 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -217,9 +217,15 @@ public: inline short GetPing(void) const { return m_Ping; } + /** Sets the maximal view distance. */ void SetViewDistance(int a_ViewDistance); - int GetViewDistance(void) const { return m_ViewDistance; } - + + /** Returns the view distance that the player currently have. */ + int GetViewDistance(void) const { return m_UsedViewDistance; } + + /** Returns the view distance that the player set, not the used view distance. */ + int GetSettedViewDistance(void) const { return m_SetViewDistance; } + void SetLocale(AString & a_Locale) { m_Locale = a_Locale; } AString GetLocale(void) const { return m_Locale; } @@ -334,11 +340,11 @@ private: typedef std::set cChannels; /** Number of chunks the player can see in each direction */ - int m_ViewDistance; - - /** Server generates this many chunks AHEAD of player sight. */ - static const int GENERATEDISTANCE = 2; - + int m_UsedViewDistance; + + /** The original view distance from the player. It isn't clamped with 1 and the max view distance of the world. */ + int m_SetViewDistance; + AString m_IPString; AString m_Username; diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 5c18d8f96..1fe14ff65 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1602,6 +1602,9 @@ bool cPlayer::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn) a_World->AddPlayer(this); SetWorld(a_World); // Chunks may be streamed before cWorld::AddPlayer() sets the world to the new value + // Update the view distance. + m_ClientHandle->SetViewDistance(m_ClientHandle->GetSettedViewDistance()); + return true; } -- cgit v1.2.3 From 66c4117856dccfd768b0607541c06ad7d1601f18 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 14 Nov 2014 22:55:09 +0100 Subject: Updated APIDump --- MCServer/Plugins/APIDump/APIDesc.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 01e945e73..97abab4a0 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -534,6 +534,7 @@ end GetUUID = { Params = "", Return = "string", Notes = "Returns the authentication-based UUID of the client. This UUID should be used to identify the player when persisting any player-related data. Returns a 32-char UUID (no dashes)" }, GetUsername = { Params = "", Return = "string", Notes = "Returns the username that the client has provided" }, GetViewDistance = { Params = "", Return = "number", Notes = "Returns the viewdistance (number of chunks loaded for the player in each direction)" }, + GetSettedViewDistance = { Params = "", Return = "number", Notes = "Returns the view distance that the player set, not the used view distance." }, HasPluginChannel = { Params = "ChannelName", Return = "bool", Notes = "Returns true if the client has registered to receive messages on the specified plugin channel." }, IsUUIDOnline = { Params = "UUID", Return = "bool", Notes = "(STATIC) Returns true if the UUID is generated by online auth, false if it is an offline-generated UUID. We use Version-3 UUIDs for offline UUIDs, online UUIDs are Version-4, thus we can tell them apart. Accepts both 32-char and 36-char UUIDs (with and without dashes). If the string given is not a valid UUID, returns false."}, Kick = { Params = "Reason", Return = "", Notes = "Kicks the user with the specified reason" }, -- cgit v1.2.3 From 7120b1a7691771450b792dd2e821d94e07079a29 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 14 Nov 2014 22:56:55 +0100 Subject: APIDump: Fixed example cCompositeChat URL --- MCServer/Plugins/APIDump/APIDesc.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 01e945e73..740168501 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -614,7 +614,7 @@ function OnPlayerJoined(a_Player) -- Send an example composite chat message to the player: a_Player:SendMessage(cCompositeChat() :AddTextPart("Hello, ") - :AddUrlPart(a_Player:GetName(), "www.mc-server.org", "u@2") -- Colored underlined link + :AddUrlPart(a_Player:GetName(), "http://www.mc-server.org", "u@2") -- Colored underlined link :AddSuggestCommandPart(", and welcome.", "/help", "u") -- Underlined suggest-command :AddRunCommandPart(" SetDay", "/time set 0") -- Regular text that will execute command when clicked :SetMessageType(mtJoin) -- It is a join-message -- cgit v1.2.3 From 30fa6a642c309b054e017aa5e07f62ed7c219dc7 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sat, 15 Nov 2014 11:17:05 +0100 Subject: DungeonRooms: Changed to work with the new shape generators. --- src/Generating/DungeonRoomsFinisher.cpp | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/Generating/DungeonRoomsFinisher.cpp b/src/Generating/DungeonRoomsFinisher.cpp index bd45cb2a4..7ab22c2c5 100644 --- a/src/Generating/DungeonRoomsFinisher.cpp +++ b/src/Generating/DungeonRoomsFinisher.cpp @@ -78,7 +78,8 @@ protected: - /** Decodes the position index along the room walls into a proper 2D position for a chest. */ + /** Decodes the position index along the room walls into a proper 2D position for a chest. + The Y coord of the returned vector specifies the chest's meta value*/ Vector3i DecodeChestCoords(int a_PosIdx, int a_SizeX, int a_SizeZ) { if (a_PosIdx < a_SizeX) @@ -293,17 +294,21 @@ cDungeonRoomsFinisher::cStructurePtr cDungeonRoomsFinisher::CreateStructure(int int ChunkX, ChunkZ; int RelX = a_OriginX, RelY = 0, RelZ = a_OriginZ; cChunkDef::AbsoluteToRelative(RelX, RelY, RelZ, ChunkX, ChunkZ); - /* - // TODO - cChunkDef::HeightMap HeightMap; - m_HeightGen->GenHeightMap(ChunkX, ChunkZ, HeightMap); - int Height = cChunkDef::GetHeight(HeightMap, RelX, RelZ); // Max room height at {a_OriginX, a_OriginZ} - Height = Clamp(m_HeightProbability.MapValue(rnd % m_HeightProbability.GetSum()), 10, Height - 5); - */ - int Height = 62; + cChunkDesc::Shape shape; + m_ShapeGen->GenShape(ChunkX, ChunkZ, shape); + int height = 0; + int idx = RelX * 256 + RelZ * 16 * 256; + for (int y = 6; y < cChunkDef::Height; y++) + { + if (shape[idx + y] != 0) + { + continue; + } + height = Clamp(m_HeightProbability.MapValue(rnd % m_HeightProbability.GetSum()), 10, y - 5); + } // Create the dungeon room descriptor: - return cStructurePtr(new cDungeonRoom(a_GridX, a_GridZ, a_OriginX, a_OriginZ, HalfSizeX, HalfSizeZ, Height, m_Noise)); + return cStructurePtr(new cDungeonRoom(a_GridX, a_GridZ, a_OriginX, a_OriginZ, HalfSizeX, HalfSizeZ, height, m_Noise)); } -- cgit v1.2.3 From 8c3c11d6b33c8ff71ad3f4e2c6ca67fc835dea33 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 15 Nov 2014 14:27:50 +0100 Subject: Renamed GetSettedViewDistance() to GetRequestedViewDistance() --- MCServer/Plugins/APIDump/APIDesc.lua | 2 +- src/ClientHandle.h | 4 ++-- src/Entities/Player.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 97abab4a0..8491047d0 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -534,7 +534,7 @@ end GetUUID = { Params = "", Return = "string", Notes = "Returns the authentication-based UUID of the client. This UUID should be used to identify the player when persisting any player-related data. Returns a 32-char UUID (no dashes)" }, GetUsername = { Params = "", Return = "string", Notes = "Returns the username that the client has provided" }, GetViewDistance = { Params = "", Return = "number", Notes = "Returns the viewdistance (number of chunks loaded for the player in each direction)" }, - GetSettedViewDistance = { Params = "", Return = "number", Notes = "Returns the view distance that the player set, not the used view distance." }, + GetRequestedViewDistance = { Params = "", Return = "number", Notes = "Returns the view distance that the player request, not the used view distance." }, HasPluginChannel = { Params = "ChannelName", Return = "bool", Notes = "Returns true if the client has registered to receive messages on the specified plugin channel." }, IsUUIDOnline = { Params = "UUID", Return = "bool", Notes = "(STATIC) Returns true if the UUID is generated by online auth, false if it is an offline-generated UUID. We use Version-3 UUIDs for offline UUIDs, online UUIDs are Version-4, thus we can tell them apart. Accepts both 32-char and 36-char UUIDs (with and without dashes). If the string given is not a valid UUID, returns false."}, Kick = { Params = "Reason", Return = "", Notes = "Kicks the user with the specified reason" }, diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 20789621d..db386d8a3 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -223,8 +223,8 @@ public: /** Returns the view distance that the player currently have. */ int GetViewDistance(void) const { return m_UsedViewDistance; } - /** Returns the view distance that the player set, not the used view distance. */ - int GetSettedViewDistance(void) const { return m_SetViewDistance; } + /** Returns the view distance that the player request, not the used view distance. */ + int GetRequestedViewDistance(void) const { return m_SetViewDistance; } void SetLocale(AString & a_Locale) { m_Locale = a_Locale; } AString GetLocale(void) const { return m_Locale; } diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 1fe14ff65..edcdb4799 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1603,7 +1603,7 @@ bool cPlayer::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn) SetWorld(a_World); // Chunks may be streamed before cWorld::AddPlayer() sets the world to the new value // Update the view distance. - m_ClientHandle->SetViewDistance(m_ClientHandle->GetSettedViewDistance()); + m_ClientHandle->SetViewDistance(m_ClientHandle->GetRequestedViewDistance()); return true; } -- cgit v1.2.3 From 78fb7896313f2074fa814309901e30d4a4f218e2 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 15 Nov 2014 15:16:52 +0100 Subject: Fixed a security problem with signs. --- src/Bindings/ManualBindings.cpp | 2 +- src/ClientHandle.cpp | 9 +++++++-- src/ClientHandle.h | 6 ++++++ src/World.cpp | 12 +++--------- src/World.h | 5 +---- 5 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 3d10e2abb..e259e2e91 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -1038,7 +1038,7 @@ static int tolua_cWorld_SetSignLines(lua_State * tolua_S) } #endif { - bool res = self->UpdateSign(BlockX, BlockY, BlockZ, Line1, Line2, Line3, Line4, Player); + bool res = self->SetSignLines(BlockX, BlockY, BlockZ, Line1, Line2, Line3, Line4, Player); tolua_pushboolean(tolua_S, res ? 1 : 0); } } diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 94bace43a..9bf4875e2 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -93,6 +93,7 @@ cClientHandle::cClientHandle(const cSocket * a_Socket, int a_ViewDistance) : m_UniqueID(0), m_HasSentPlayerChunk(false), m_Locale("en_GB"), + m_LastPlacedBlock(0, -1, 0), m_ProtocolVersion(0) { m_Protocol = new cProtocolRecognizer(this); @@ -1500,6 +1501,8 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e { m_Player->GetInventory().RemoveOneEquippedItem(); } + m_LastPlacedBlock.Set(a_BlockX, a_BlockY, a_BlockZ); + cChunkInterface ChunkInterface(World->GetChunkMap()); NewBlock->OnPlacedByPlayer(ChunkInterface, *World, m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta); @@ -1677,8 +1680,10 @@ void cClientHandle::HandleUpdateSign( const AString & a_Line3, const AString & a_Line4 ) { - cWorld * World = m_Player->GetWorld(); - World->UpdateSign(a_BlockX, a_BlockY, a_BlockZ, a_Line1, a_Line2, a_Line3, a_Line4, m_Player); + if (m_LastPlacedBlock.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) + { + m_Player->GetWorld()->SetSignLines(a_BlockX, a_BlockY, a_BlockZ, a_Line1, a_Line2, a_Line3, a_Line4, m_Player); + } } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 082ed2fcc..a0dd4ff7a 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -125,6 +125,9 @@ public: inline bool IsLoggedIn(void) const { return (m_State >= csAuthenticating); } + /** Returns the positions from the last block that the player placed. */ + const Vector3i & GetLastPlacedBlock(void) const { return m_LastPlacedBlock; } // tolua_export + /** Called while the client is being ticked from the world via its cPlayer object */ void Tick(float a_Dt); @@ -432,6 +435,9 @@ private: /** Client Settings */ AString m_Locale; + + /** The positions from the last block that the player placed. It's needed to verify the sign text change. */ + Vector3i m_LastPlacedBlock; /** The plugin channels that the client has registered. */ cChannels m_PluginChannels; diff --git a/src/World.cpp b/src/World.cpp index 68855e617..3178d41a6 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -2926,25 +2926,19 @@ bool cWorld::SetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, const AStrin AString Line2(a_Line2); AString Line3(a_Line3); AString Line4(a_Line4); + if (cRoot::Get()->GetPluginManager()->CallHookUpdatingSign(*this, a_BlockX, a_BlockY, a_BlockZ, Line1, Line2, Line3, Line4, a_Player)) { return false; } + if (m_ChunkMap->SetSignLines(a_BlockX, a_BlockY, a_BlockZ, Line1, Line2, Line3, Line4)) { cRoot::Get()->GetPluginManager()->CallHookUpdatedSign(*this, a_BlockX, a_BlockY, a_BlockZ, Line1, Line2, Line3, Line4, a_Player); return true; } - return false; -} - - - - -bool cWorld::UpdateSign(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player) -{ - return SetSignLines(a_BlockX, a_BlockY, a_BlockZ, a_Line1, a_Line2, a_Line3, a_Line4, a_Player); + return false; } diff --git a/src/World.h b/src/World.h index 1a9f60a5c..b209f71a7 100644 --- a/src/World.h +++ b/src/World.h @@ -377,11 +377,8 @@ public: /** Marks the chunk as failed-to-load: */ void ChunkLoadFailed(int a_ChunkX, int a_ChunkZ); - /** Sets the sign text, asking plugins for permission first. a_Player is the player who this change belongs to, may be nullptr. Returns true if sign text changed. Same as UpdateSign() */ + /** Sets the sign text, asking plugins for permission first. a_Player is the player who this change belongs to, may be nullptr. Returns true if sign text changed. */ bool SetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player = nullptr); // Exported in ManualBindings.cpp - - /** Sets the sign text, asking plugins for permission first. a_Player is the player who this change belongs to, may be nullptr. Returns true if sign text changed. Same as SetSignLines() */ - bool UpdateSign(int a_X, int a_Y, int a_Z, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player = nullptr); // Exported in ManualBindings.cpp /** Sets the command block command. Returns true if command changed. */ bool SetCommandBlockCommand(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Command); // tolua_export -- cgit v1.2.3 From fe9750136c465baa8690a3edf9a8fadfe305bc28 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 15 Nov 2014 15:27:41 +0100 Subject: Updated APIDump --- MCServer/Plugins/APIDump/APIDesc.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 740168501..9ebc689a1 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -536,6 +536,7 @@ end GetViewDistance = { Params = "", Return = "number", Notes = "Returns the viewdistance (number of chunks loaded for the player in each direction)" }, HasPluginChannel = { Params = "ChannelName", Return = "bool", Notes = "Returns true if the client has registered to receive messages on the specified plugin channel." }, IsUUIDOnline = { Params = "UUID", Return = "bool", Notes = "(STATIC) Returns true if the UUID is generated by online auth, false if it is an offline-generated UUID. We use Version-3 UUIDs for offline UUIDs, online UUIDs are Version-4, thus we can tell them apart. Accepts both 32-char and 36-char UUIDs (with and without dashes). If the string given is not a valid UUID, returns false."}, + GetLastPlacedBlock = { Params = "", Return = "{{Vector3i}}", Notes = "Returns the positions from the last block that the player placed." }, Kick = { Params = "Reason", Return = "", Notes = "Kicks the user with the specified reason" }, SendPluginMessage = { Params = "Channel, Message", Return = "", Notes = "Sends the plugin message on the specified channel." }, SetClientBrand = { Params = "ClientBrand", Return = "", Notes = "Sets the value of the client's brand. Normally this value is received from the client by a MC|Brand plugin message, this function lets plugins overwrite the value." }, @@ -2499,7 +2500,7 @@ end SetCommandBlocksEnabled = { Params = "IsEnabled (bool)", Return = "", Notes = "Sets whether command blocks should be enabled on the (entire) server." }, SetShouldUseChatPrefixes = { Params = "", Return = "ShouldUse (bool)", Notes = "Sets whether coloured chat prefixes such as [INFO] is used with the SendMessageXXX() or BroadcastChatXXX(), or simply the entire message is coloured in the respective colour." }, ShouldUseChatPrefixes = { Params = "", Return = "bool", Notes = "Returns whether coloured chat prefixes are prepended to chat messages or the entire message is simply coloured." }, - SetSignLines = { Params = "X, Y, Z, Line1, Line2, Line3, Line4, [{{cPlayer|Player}}]", Return = "", Notes = "Sets the sign text at the specified coords. The sign-updating hooks are called for the change. The Player parameter is used to indicate the player from whom the change has come, it may be nil. Same as UpdateSign()." }, + SetSignLines = { Params = "X, Y, Z, Line1, Line2, Line3, Line4, [{{cPlayer|Player}}]", Return = "", Notes = "Sets the sign text at the specified coords. The sign-updating hooks are called for the change. The Player parameter is used to indicate the player from whom the change has come, it may be nil." }, SetTicksUntilWeatherChange = { Params = "NumTicks", Return = "", Notes = "Sets the number of ticks after which the weather will be changed." }, SetTimeOfDay = { Params = "TimeOfDayTicks", Return = "", Notes = "Sets the time of day, expressed as number of ticks past sunrise, in the range 0 .. 24000." }, SetWeather = { Params = "Weather", Return = "", Notes = "Sets the current weather (wSunny, wRain, wStorm) and resets the TicksUntilWeatherChange to the default value for the new weather. The normal weather-changing hooks are called for the change." }, @@ -2514,7 +2515,7 @@ end SpawnExperienceOrb = { Params = "X, Y, Z, Reward", Return = "EntityID", Notes = "Spawns an {{cExpOrb|experience orb}} at the specified coords, with the given reward" }, SpawnPrimedTNT = { Params = "X, Y, Z, FuseTicks, InitialVelocityCoeff", Return = "", Notes = "Spawns a {{cTNTEntity|primed TNT entity}} at the specified coords, with the given fuse ticks. The entity gets a random speed multiplied by the InitialVelocityCoeff, 1 being the default value." }, TryGetHeight = { Params = "BlockX, BlockZ", Return = "IsValid, Height", Notes = "Returns true and height of the highest non-air block if the chunk is loaded, or false otherwise." }, - UpdateSign = { Params = "X, Y, Z, Line1, Line2, Line3, Line4, [{{cPlayer|Player}}]", Return = "", Notes = "Sets the sign text at the specified coords. The sign-updating hooks are called for the change. The Player parameter is used to indicate the player from whom the change has come, it may be nil. Same as SetSignLiens()" }, + UpdateSign = { Params = "X, Y, Z, Line1, Line2, Line3, Line4, [{{cPlayer|Player}}]", Return = "", Notes = "(DEPRECATED) Please use SetSignLines()." }, UseBlockEntity = { Params = "{{cPlayer|Player}}, BlockX, BlockY, BlockZ", Return = "", Notes = "Makes the specified Player use the block entity at the specified coords (open chest UI, etc.) If the cords are in an unloaded chunk or there's no block entity, ignores the call." }, WakeUpSimulators = { Params = "BlockX, BlockY, BlockZ", Return = "", Notes = "Wakes up the simulators for the specified block." }, WakeUpSimulatorsInArea = { Params = "MinBlockX, MaxBlockX, MinBlockY, MaxBlockY, MinBlockZ, MaxBlockZ", Return = "", Notes = "Wakes up the simulators for all the blocks in the specified area (edges inclusive)." }, -- cgit v1.2.3 From 927d8d7702b71baa64dc70593ea71e1081c33a9c Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 15 Nov 2014 15:33:42 +0100 Subject: Renamed m_SetViewDistance to m_RequestedViewDistance --- src/ClientHandle.cpp | 8 ++++---- src/ClientHandle.h | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index d5882da06..3feb4c596 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -66,7 +66,7 @@ int cClientHandle::s_ClientCount = 0; cClientHandle::cClientHandle(const cSocket * a_Socket, int a_ViewDistance) : m_UsedViewDistance(a_ViewDistance), - m_SetViewDistance(a_ViewDistance), + m_RequestedViewDistance(a_ViewDistance), m_IPString(a_Socket->GetIPString()), m_OutgoingData(64 KiB), m_Player(nullptr), @@ -2850,9 +2850,9 @@ void cClientHandle::SetViewDistance(int a_ViewDistance) { ASSERT(m_Player->GetWorld() == NULL); - m_SetViewDistance = a_ViewDistance; - m_UsedViewDistance = Clamp(m_SetViewDistance, cClientHandle::MIN_VIEW_DISTANCE, m_Player->GetWorld()->GetMaxViewDistance()); - LOGD("Setted view distance from %s to %i!", GetUsername().c_str(), m_UsedViewDistance); + m_RequestedViewDistance = a_ViewDistance; + m_UsedViewDistance = Clamp(a_ViewDistance, cClientHandle::MIN_VIEW_DISTANCE, m_Player->GetWorld()->GetMaxViewDistance()); + LOGD("Setted view distance from %s to %d!", GetUsername().c_str(), m_UsedViewDistance); } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index db386d8a3..c0826d7c4 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -224,7 +224,7 @@ public: int GetViewDistance(void) const { return m_UsedViewDistance; } /** Returns the view distance that the player request, not the used view distance. */ - int GetRequestedViewDistance(void) const { return m_SetViewDistance; } + int GetRequestedViewDistance(void) const { return m_RequestedViewDistance; } void SetLocale(AString & a_Locale) { m_Locale = a_Locale; } AString GetLocale(void) const { return m_Locale; } @@ -342,8 +342,8 @@ private: /** Number of chunks the player can see in each direction */ int m_UsedViewDistance; - /** The original view distance from the player. It isn't clamped with 1 and the max view distance of the world. */ - int m_SetViewDistance; + /** The requested view distance from the player. It isn't clamped with 1 and the max view distance of the world. */ + int m_RequestedViewDistance; AString m_IPString; -- cgit v1.2.3 From 889aa7404dd37b862d8874c9d5545f51be19e17d Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sat, 15 Nov 2014 20:23:47 +0100 Subject: ChunkDesc: Fixed comment about indexing. --- src/Generating/ChunkDesc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Generating/ChunkDesc.h b/src/Generating/ChunkDesc.h index b86041a7d..480106fb5 100644 --- a/src/Generating/ChunkDesc.h +++ b/src/Generating/ChunkDesc.h @@ -33,7 +33,7 @@ public: /** The datatype used to represent the entire chunk worth of shape. 0 = air 1 = solid - Indexed as [y + 256 * z + 256 * 16 * x]. */ + Indexed as [y + 256 * x + 256 * 16 * z]. */ typedef Byte Shape[256 * 16 * 16]; /** Uncompressed block metas, 1 meta per byte */ -- cgit v1.2.3 From b0bcd75732bef60409ac1390cf3fbe5cd89c6634 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sat, 15 Nov 2014 20:24:15 +0100 Subject: Snow generator: Fixed failure at top of the world. --- src/Generating/FinishGen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index b8afac09a..f67d59998 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -412,7 +412,7 @@ void cFinishGenSnow::GenFinish(cChunkDesc & a_ChunkDesc) case biFrozenOcean: { int Height = a_ChunkDesc.GetHeight(x, z); - if (cBlockInfo::IsSnowable(a_ChunkDesc.GetBlockType(x, Height, z))) + if (cBlockInfo::IsSnowable(a_ChunkDesc.GetBlockType(x, Height, z)) && (Height < cChunkDef::Height - 1)) { a_ChunkDesc.SetBlockType(x, Height + 1, z, E_BLOCK_SNOW); a_ChunkDesc.SetHeight(x, z, Height + 1); -- cgit v1.2.3 From 564b9ad33711b45c59d3c001df1b9206c7cbf60e Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sat, 15 Nov 2014 21:45:24 +0100 Subject: Generator: Fixed crash with trees too high. --- src/Generating/StructGen.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Generating/StructGen.cpp b/src/Generating/StructGen.cpp index ca8f0411f..2f685c808 100644 --- a/src/Generating/StructGen.cpp +++ b/src/Generating/StructGen.cpp @@ -100,7 +100,7 @@ void cStructGenTrees::GenerateSingleTree( int Height = a_ChunkDesc.GetHeight(x, z); - if ((Height <= 0) || (Height > 240)) + if ((Height <= 0) || (Height >= 230)) { return; } @@ -128,6 +128,11 @@ void cStructGenTrees::GenerateSingleTree( // Outside the chunk continue; } + if (itr->y >= cChunkDef::Height) + { + // Above the chunk, cut off (this shouldn't happen too often, we're limiting trees to y < 230) + continue; + } BLOCKTYPE Block = a_ChunkDesc.GetBlockType(itr->x, itr->y, itr->z); switch (Block) @@ -162,7 +167,7 @@ void cStructGenTrees::ApplyTreeImage( // Put the generated image into a_BlockTypes, push things outside this chunk into a_Blocks for (sSetBlockVector::const_iterator itr = a_Image.begin(), end = a_Image.end(); itr != end; ++itr) { - if ((itr->ChunkX == a_ChunkX) && (itr->ChunkZ == a_ChunkZ)) + if ((itr->ChunkX == a_ChunkX) && (itr->ChunkZ == a_ChunkZ) && (itr->y < cChunkDef::Height)) { // Inside this chunk, integrate into a_ChunkDesc: switch (a_ChunkDesc.GetBlockType(itr->x, itr->y, itr->z)) -- cgit v1.2.3 From 1240e583d27c2189e50fda3f7ab63d736889abda Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sat, 15 Nov 2014 21:45:57 +0100 Subject: Mobs: Fixed crash with terrain too high. --- src/Mobs/Monster.cpp | 4 ++-- src/Mobs/Monster.h | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 23b4d9f45..5319bdf91 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -160,7 +160,7 @@ void cMonster::TickPathFinding() BLOCKTYPE BlockAtYP = m_World->GetBlock(gCrossCoords[i].x + PosX, PosY + 1, gCrossCoords[i].z + PosZ); BLOCKTYPE BlockAtYPP = m_World->GetBlock(gCrossCoords[i].x + PosX, PosY + 2, gCrossCoords[i].z + PosZ); int LowestY = FindFirstNonAirBlockPosition(gCrossCoords[i].x + PosX, gCrossCoords[i].z + PosZ); - BLOCKTYPE BlockAtLowestY = m_World->GetBlock(gCrossCoords[i].x + PosX, LowestY, gCrossCoords[i].z + PosZ); + BLOCKTYPE BlockAtLowestY = (LowestY >= cChunkDef::Height) ? E_BLOCK_AIR : m_World->GetBlock(gCrossCoords[i].x + PosX, LowestY, gCrossCoords[i].z + PosZ); if ( (!cBlockInfo::IsSolid(BlockAtY)) && @@ -453,7 +453,7 @@ int cMonster::FindFirstNonAirBlockPosition(double a_PosX, double a_PosZ) } else { - while (cBlockInfo::IsSolid(m_World->GetBlock((int)floor(a_PosX), PosY, (int)floor(a_PosZ))) && (PosY < cChunkDef::Height)) + while ((PosY < cChunkDef::Height) && cBlockInfo::IsSolid(m_World->GetBlock((int)floor(a_PosX), PosY, (int)floor(a_PosZ)))) { PosY++; } diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h index f5ae2cb4d..e5dcb0309 100644 --- a/src/Mobs/Monster.h +++ b/src/Mobs/Monster.h @@ -169,10 +169,12 @@ protected: /** Stores if mobile is currently moving towards the ultimate, final destination */ bool m_bMovingToDestination; - /** Finds the first non-air block position (not the highest, as cWorld::GetHeight does) - If current Y is nonsolid, goes down to try to find a solid block, then returns that + 1 - If current Y is solid, goes up to find first nonsolid block, and returns that */ + /** Finds the lowest non-air block position (not the highest, as cWorld::GetHeight does) + If current Y is nonsolid, goes down to try to find a solid block, then returns that + 1 + If current Y is solid, goes up to find first nonsolid block, and returns that. + If no suitable position is found, returns cChunkDef::Height. */ int FindFirstNonAirBlockPosition(double a_PosX, double a_PosZ); + /** Returns if a monster can actually reach a given height by jumping or walking */ inline bool IsNextYPosReachable(int a_PosY) { -- cgit v1.2.3 From 09cea625fcf2d1eb1fb37a57c5712d992c96e4fd Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 15 Nov 2014 22:26:54 +0100 Subject: Renamed m_UsedViewDistance to m_CurrentViewDistance --- src/ClientHandle.cpp | 16 ++++++++-------- src/ClientHandle.h | 6 +++--- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 3feb4c596..0b9d84bf7 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -65,7 +65,7 @@ int cClientHandle::s_ClientCount = 0; // cClientHandle: cClientHandle::cClientHandle(const cSocket * a_Socket, int a_ViewDistance) : - m_UsedViewDistance(a_ViewDistance), + m_CurrentViewDistance(a_ViewDistance), m_RequestedViewDistance(a_ViewDistance), m_IPString(a_Socket->GetIPString()), m_OutgoingData(64 KiB), @@ -431,7 +431,7 @@ bool cClientHandle::StreamNextChunk(void) cCSLock Lock(m_CSChunkLists); // High priority: Load the chunks that are in the view-direction of the player (with a radius of 3) - for (int Range = 0; Range < m_UsedViewDistance; Range++) + for (int Range = 0; Range < m_CurrentViewDistance; Range++) { Vector3d Vector = Position + LookVector * cChunkDef::Width * Range; @@ -448,7 +448,7 @@ bool cClientHandle::StreamNextChunk(void) cChunkCoords Coords(ChunkX, ChunkZ); // Checks if the chunk is in distance - if ((Diff(ChunkX, ChunkPosX) > m_UsedViewDistance) || (Diff(ChunkZ, ChunkPosZ) > m_UsedViewDistance)) + if ((Diff(ChunkX, ChunkPosX) > m_CurrentViewDistance) || (Diff(ChunkZ, ChunkPosZ) > m_CurrentViewDistance)) { continue; } @@ -471,7 +471,7 @@ bool cClientHandle::StreamNextChunk(void) } // Low priority: Add all chunks that are in range. (From the center out to the edge) - for (int d = 0; d <= m_UsedViewDistance; ++d) // cycle through (square) distance, from nearest to furthest + for (int d = 0; d <= m_CurrentViewDistance; ++d) // cycle through (square) distance, from nearest to furthest { // For each distance add chunks in a hollow square centered around current position: cChunkCoordsList CurcleChunks; @@ -529,7 +529,7 @@ void cClientHandle::UnloadOutOfRangeChunks(void) { int DiffX = Diff((*itr).m_ChunkX, ChunkPosX); int DiffZ = Diff((*itr).m_ChunkZ, ChunkPosZ); - if ((DiffX > m_UsedViewDistance) || (DiffZ > m_UsedViewDistance)) + if ((DiffX > m_CurrentViewDistance) || (DiffZ > m_CurrentViewDistance)) { ChunksToRemove.push_back(*itr); itr = m_LoadedChunks.erase(itr); @@ -544,7 +544,7 @@ void cClientHandle::UnloadOutOfRangeChunks(void) { int DiffX = Diff((*itr).m_ChunkX, ChunkPosX); int DiffZ = Diff((*itr).m_ChunkZ, ChunkPosZ); - if ((DiffX > m_UsedViewDistance) || (DiffZ > m_UsedViewDistance)) + if ((DiffX > m_CurrentViewDistance) || (DiffZ > m_CurrentViewDistance)) { itr = m_ChunksToSend.erase(itr); } @@ -2851,8 +2851,8 @@ void cClientHandle::SetViewDistance(int a_ViewDistance) ASSERT(m_Player->GetWorld() == NULL); m_RequestedViewDistance = a_ViewDistance; - m_UsedViewDistance = Clamp(a_ViewDistance, cClientHandle::MIN_VIEW_DISTANCE, m_Player->GetWorld()->GetMaxViewDistance()); - LOGD("Setted view distance from %s to %d!", GetUsername().c_str(), m_UsedViewDistance); + m_CurrentViewDistance = Clamp(a_ViewDistance, cClientHandle::MIN_VIEW_DISTANCE, m_Player->GetWorld()->GetMaxViewDistance()); + LOGD("Setted view distance from %s to %d!", GetUsername().c_str(), m_CurrentViewDistance); } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index c0826d7c4..8d241c1e7 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -221,7 +221,7 @@ public: void SetViewDistance(int a_ViewDistance); /** Returns the view distance that the player currently have. */ - int GetViewDistance(void) const { return m_UsedViewDistance; } + int GetViewDistance(void) const { return m_CurrentViewDistance; } /** Returns the view distance that the player request, not the used view distance. */ int GetRequestedViewDistance(void) const { return m_RequestedViewDistance; } @@ -339,8 +339,8 @@ private: /** The type used for storing the names of registered plugin channels. */ typedef std::set cChannels; - /** Number of chunks the player can see in each direction */ - int m_UsedViewDistance; + /** The actual view distance used, the minimum of client's requested view distance and world's max view distance. */ + int m_CurrentViewDistance; /** The requested view distance from the player. It isn't clamped with 1 and the max view distance of the world. */ int m_RequestedViewDistance; -- cgit v1.2.3 From 277151582fbb0652dcf4e15f67d41f90e08bdeeb Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 15 Nov 2014 22:36:31 +0100 Subject: Use LastPlacedSign instead of LastPlacedBlock. --- MCServer/Plugins/APIDump/APIDesc.lua | 1 - src/ClientHandle.cpp | 7 ++++--- src/ClientHandle.h | 7 ++----- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 9ebc689a1..925f80252 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -536,7 +536,6 @@ end GetViewDistance = { Params = "", Return = "number", Notes = "Returns the viewdistance (number of chunks loaded for the player in each direction)" }, HasPluginChannel = { Params = "ChannelName", Return = "bool", Notes = "Returns true if the client has registered to receive messages on the specified plugin channel." }, IsUUIDOnline = { Params = "UUID", Return = "bool", Notes = "(STATIC) Returns true if the UUID is generated by online auth, false if it is an offline-generated UUID. We use Version-3 UUIDs for offline UUIDs, online UUIDs are Version-4, thus we can tell them apart. Accepts both 32-char and 36-char UUIDs (with and without dashes). If the string given is not a valid UUID, returns false."}, - GetLastPlacedBlock = { Params = "", Return = "{{Vector3i}}", Notes = "Returns the positions from the last block that the player placed." }, Kick = { Params = "Reason", Return = "", Notes = "Kicks the user with the specified reason" }, SendPluginMessage = { Params = "Channel, Message", Return = "", Notes = "Sends the plugin message on the specified channel." }, SetClientBrand = { Params = "ClientBrand", Return = "", Notes = "Sets the value of the client's brand. Normally this value is received from the client by a MC|Brand plugin message, this function lets plugins overwrite the value." }, diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 9bf4875e2..83fb283b6 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -93,7 +93,7 @@ cClientHandle::cClientHandle(const cSocket * a_Socket, int a_ViewDistance) : m_UniqueID(0), m_HasSentPlayerChunk(false), m_Locale("en_GB"), - m_LastPlacedBlock(0, -1, 0), + m_LastPlacedSign(0, -1, 0), m_ProtocolVersion(0) { m_Protocol = new cProtocolRecognizer(this); @@ -1501,7 +1501,6 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e { m_Player->GetInventory().RemoveOneEquippedItem(); } - m_LastPlacedBlock.Set(a_BlockX, a_BlockY, a_BlockZ); cChunkInterface ChunkInterface(World->GetChunkMap()); NewBlock->OnPlacedByPlayer(ChunkInterface, *World, m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta); @@ -1680,8 +1679,9 @@ void cClientHandle::HandleUpdateSign( const AString & a_Line3, const AString & a_Line4 ) { - if (m_LastPlacedBlock.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) + if (m_LastPlacedSign.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { + m_LastPlacedSign.Set(0, -1, 0); m_Player->GetWorld()->SetSignLines(a_BlockX, a_BlockY, a_BlockZ, a_Line1, a_Line2, a_Line3, a_Line4, m_Player); } } @@ -2262,6 +2262,7 @@ void cClientHandle::SendDisconnect(const AString & a_Reason) void cClientHandle::SendEditSign(int a_BlockX, int a_BlockY, int a_BlockZ) { + m_LastPlacedSign.Set(a_BlockX, a_BlockY, a_BlockZ); m_Protocol->SendEditSign(a_BlockX, a_BlockY, a_BlockZ); } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index a0dd4ff7a..d8cc3c643 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -125,9 +125,6 @@ public: inline bool IsLoggedIn(void) const { return (m_State >= csAuthenticating); } - /** Returns the positions from the last block that the player placed. */ - const Vector3i & GetLastPlacedBlock(void) const { return m_LastPlacedBlock; } // tolua_export - /** Called while the client is being ticked from the world via its cPlayer object */ void Tick(float a_Dt); @@ -436,8 +433,8 @@ private: /** Client Settings */ AString m_Locale; - /** The positions from the last block that the player placed. It's needed to verify the sign text change. */ - Vector3i m_LastPlacedBlock; + /** The positions from the last sign that the player placed. It's needed to verify the sign text change. */ + Vector3i m_LastPlacedSign; /** The plugin channels that the client has registered. */ cChannels m_PluginChannels; -- cgit v1.2.3 From 95e59056a187fe51091b5ee4b3870fa94b7df12f Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 16 Nov 2014 19:02:37 +0100 Subject: BiomalNoise3D: Added more biomes. --- src/Generating/Noise3DGenerator.cpp | 78 ++++++++++++++++++++++++++++++------- 1 file changed, 65 insertions(+), 13 deletions(-) diff --git a/src/Generating/Noise3DGenerator.cpp b/src/Generating/Noise3DGenerator.cpp index 91bdce458..f2af75999 100644 --- a/src/Generating/Noise3DGenerator.cpp +++ b/src/Generating/Noise3DGenerator.cpp @@ -756,19 +756,71 @@ void cBiomalNoise3DComposable::GetBiomeParams(EMCSBiome a_Biome, NOISE_DATATYPE { switch (a_Biome) { - case biDeepOcean: a_HeightAmp = 0.17f; a_MidPoint = 35; break; - case biDesert: a_HeightAmp = 0.29f; a_MidPoint = 62; break; // Needs verification - case biExtremeHills: a_HeightAmp = 0.045f; a_MidPoint = 75; break; - case biExtremeHillsPlus: a_HeightAmp = 0.04f; a_MidPoint = 80; break; - case biFrozenRiver: a_HeightAmp = 0.4f; a_MidPoint = 53; break; - case biFrozenOcean: a_HeightAmp = 0.17f; a_MidPoint = 47; break; - case biJungle: a_HeightAmp = 0.1f; a_MidPoint = 63; break; - case biJungleM: a_HeightAmp = 0.1f; a_MidPoint = 63; break; - case biOcean: a_HeightAmp = 0.17f; a_MidPoint = 47; break; - case biPlains: a_HeightAmp = 0.3f; a_MidPoint = 62; break; // Needs verification - case biRiver: a_HeightAmp = 0.4f; a_MidPoint = 53; break; - case biSwampland: a_HeightAmp = 0.25f; a_MidPoint = 59; break; - case biSwamplandM: a_HeightAmp = 0.11f; a_MidPoint = 59; break; + case biBeach: a_HeightAmp = 0.3f; a_MidPoint = 62; break; + case biBirchForest: a_HeightAmp = 0.1f; a_MidPoint = 64; break; + case biBirchForestHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; + case biBirchForestHillsM: a_HeightAmp = 0.075f; a_MidPoint = 68; break; + case biBirchForestM: a_HeightAmp = 0.1f; a_MidPoint = 64; break; + case biColdBeach: a_HeightAmp = 0.3f; a_MidPoint = 62; break; + case biDesertHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; + case biDeepOcean: a_HeightAmp = 0.17f; a_MidPoint = 35; break; + case biDesert: a_HeightAmp = 0.29f; a_MidPoint = 62; break; + case biEnd: a_HeightAmp = 0.15f; a_MidPoint = 64; break; + case biExtremeHills: a_HeightAmp = 0.045f; a_MidPoint = 75; break; + case biExtremeHillsPlus: a_HeightAmp = 0.04f; a_MidPoint = 80; break; + case biFlowerForest: a_HeightAmp = 0.1f; a_MidPoint = 64; break; + case biForest: a_HeightAmp = 0.1f; a_MidPoint = 64; break; + case biForestHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; + case biFrozenRiver: a_HeightAmp = 0.4f; a_MidPoint = 53; break; + case biFrozenOcean: a_HeightAmp = 0.17f; a_MidPoint = 47; break; + case biIceMountains: a_HeightAmp = 0.075f; a_MidPoint = 68; break; + case biIcePlains: a_HeightAmp = 0.3f; a_MidPoint = 62; break; + case biIcePlainsSpikes: a_HeightAmp = 0.3f; a_MidPoint = 62; break; + case biJungle: a_HeightAmp = 0.1f; a_MidPoint = 63; break; + case biJungleHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; + case biJungleM: a_HeightAmp = 0.1f; a_MidPoint = 63; break; + case biMegaSpruceTaigaHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; + case biMegaTaigaHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; + case biMushroomShore: a_HeightAmp = 0.15f; a_MidPoint = 15; break; + case biOcean: a_HeightAmp = 0.3f; a_MidPoint = 62; break; + case biPlains: a_HeightAmp = 0.3f; a_MidPoint = 62; break; + case biRiver: a_HeightAmp = 0.4f; a_MidPoint = 53; break; + case biSwampland: a_HeightAmp = 0.25f; a_MidPoint = 59; break; + case biSwamplandM: a_HeightAmp = 0.11f; a_MidPoint = 59; break; + case biTaigaHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; + + /* + // Still missing: + case biColdTaiga: a_HeightAmp = 0.15f; a_MidPoint = 30; break; + case biColdTaigaHills: a_HeightAmp = 0.15f; a_MidPoint = 31; break; + case biColdTaigaM: a_HeightAmp = 0.15f; a_MidPoint = 70; break; + case biDesertM: a_HeightAmp = 0.15f; a_MidPoint = 70; break; + case biExtremeHillsEdge: a_HeightAmp = 0.15f; a_MidPoint = 20; break; + case biExtremeHillsM: a_HeightAmp = 0.15f; a_MidPoint = 70; break; + case biExtremeHillsPlusM: a_HeightAmp = 0.15f; a_MidPoint = 70; break; + case biJungleEdge: a_HeightAmp = 0.15f; a_MidPoint = 23; break; + case biJungleEdgeM: a_HeightAmp = 0.15f; a_MidPoint = 70; break; + case biMegaSpruceTaiga: a_HeightAmp = 0.15f; a_MidPoint = 70; break; + case biMegaTaiga: a_HeightAmp = 0.15f; a_MidPoint = 32; break; + case biMesa: a_HeightAmp = 0.15f; a_MidPoint = 37; break; + case biMesaBryce: a_HeightAmp = 0.15f; a_MidPoint = 70; break; + case biMesaPlateau: a_HeightAmp = 0.15f; a_MidPoint = 39; break; + case biMesaPlateauF: a_HeightAmp = 0.15f; a_MidPoint = 38; break; + case biMesaPlateauFM: a_HeightAmp = 0.15f; a_MidPoint = 70; break; + case biMesaPlateauM: a_HeightAmp = 0.15f; a_MidPoint = 70; break; + case biMushroomIsland: a_HeightAmp = 0.15f; a_MidPoint = 14; break; + case biNether: a_HeightAmp = 0.15f; a_MidPoint = 68; break; + case biRoofedForest: a_HeightAmp = 0.15f; a_MidPoint = 29; break; + case biRoofedForestM: a_HeightAmp = 0.15f; a_MidPoint = 70; break; + case biSavanna: a_HeightAmp = 0.15f; a_MidPoint = 35; break; + case biSavannaM: a_HeightAmp = 0.15f; a_MidPoint = 70; break; + case biSavannaPlateau: a_HeightAmp = 0.15f; a_MidPoint = 36; break; + case biSavannaPlateauM: a_HeightAmp = 0.15f; a_MidPoint = 70; break; + case biStoneBeach: a_HeightAmp = 0.15f; a_MidPoint = 25; break; + case biSunflowerPlains: a_HeightAmp = 0.15f; a_MidPoint = 70; break; + case biTaiga: a_HeightAmp = 0.15f; a_MidPoint = 65; break; + case biTaigaM: a_HeightAmp = 0.15f; a_MidPoint = 70; break; + */ default: { -- cgit v1.2.3 From ff036c9cef7ba04cfbd96196570b2251874eac7a Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 16 Nov 2014 19:50:57 +0100 Subject: Changed comment Suggestion by xoft --- src/Generating/Trees.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Generating/Trees.cpp b/src/Generating/Trees.cpp index 3c695ad20..be8b0cd6b 100644 --- a/src/Generating/Trees.cpp +++ b/src/Generating/Trees.cpp @@ -399,7 +399,7 @@ void GetLargeAppleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a GetLargeAppleTreeBranch(a_BlockX, a_BlockY + i, a_BlockZ, BranchLength, BranchStartDirection, BranchDirection, a_BlockY + Height, a_Noise, a_LogBlocks); } - // Place leaves + // Place leaves around each log block for (auto itr : a_LogBlocks) { // Get the log's X and Z coordinates -- cgit v1.2.3 From ae15c2f78e85c8a6ee192d48d8befc5ee4b478b6 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Mon, 17 Nov 2014 12:34:14 +0100 Subject: Fixed a wrong assert in cClientHandle::SetViewDistance(). --- src/ClientHandle.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 0b9d84bf7..8b4d6d0cc 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -2848,11 +2848,15 @@ void cClientHandle::SetUsername( const AString & a_Username) void cClientHandle::SetViewDistance(int a_ViewDistance) { - ASSERT(m_Player->GetWorld() == NULL); - m_RequestedViewDistance = a_ViewDistance; - m_CurrentViewDistance = Clamp(a_ViewDistance, cClientHandle::MIN_VIEW_DISTANCE, m_Player->GetWorld()->GetMaxViewDistance()); - LOGD("Setted view distance from %s to %d!", GetUsername().c_str(), m_CurrentViewDistance); + LOGD("%s is requesting ViewDistance of %d!", GetUsername().c_str(), m_RequestedViewDistance); + + // Set the current view distance based on the requested VD and world max VD: + cWorld * world = m_Player->GetWorld(); + if (world != nullptr) + { + m_CurrentViewDistance = Clamp(a_ViewDistance, cClientHandle::MIN_VIEW_DISTANCE, world->GetMaxViewDistance()); + } } -- cgit v1.2.3 From 0e491273c1e942b73adc78db03a71d76d529b009 Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 17 Nov 2014 14:57:24 +0100 Subject: Added UpdateSign() method to DeprecatedBindings.cpp --- src/Bindings/DeprecatedBindings.cpp | 86 +++++++++++++++++++++++++++++++++++++ src/Bindings/ManualBindings.cpp | 5 +-- 2 files changed, 88 insertions(+), 3 deletions(-) diff --git a/src/Bindings/DeprecatedBindings.cpp b/src/Bindings/DeprecatedBindings.cpp index ded7a0142..442d9add5 100644 --- a/src/Bindings/DeprecatedBindings.cpp +++ b/src/Bindings/DeprecatedBindings.cpp @@ -7,6 +7,33 @@ #include "../BlockInfo.h" +#include "../World.h" +#include "../Entities/Player.h" + + + + + +static void lua_do_warning(lua_State* L, const char * a_pFormat, ...) +{ + // Retrieve current function name + lua_Debug entry; + VERIFY(lua_getstack(L, 0, &entry)); + VERIFY(lua_getinfo(L, "n", &entry)); + + // Insert function name into error msg + AString msg(a_pFormat); + ReplaceString(msg, "#funcname#", entry.name?entry.name:"?"); + + // Copied from luaL_error and modified + va_list argp; + va_start(argp, a_pFormat); + luaL_where(L, 1); + lua_pushvfstring(L, msg.c_str(), argp); + va_end(argp); + lua_concat(L, 2); + lua_error(L); +} @@ -222,6 +249,61 @@ static int tolua_get_AllToLua_g_BlockFullyOccupiesVoxel(lua_State* tolua_S) +/** function: cWorld:SetSignLines */ +static int tolua_cWorld_SetSignLines(lua_State * tolua_S) +{ + #ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype (tolua_S, 1, "cWorld", 0, &tolua_err) || + !tolua_isnumber (tolua_S, 2, 0, &tolua_err) || + !tolua_isnumber (tolua_S, 3, 0, &tolua_err) || + !tolua_isnumber (tolua_S, 4, 0, &tolua_err) || + !tolua_iscppstring(tolua_S, 5, 0, &tolua_err) || + !tolua_iscppstring(tolua_S, 6, 0, &tolua_err) || + !tolua_iscppstring(tolua_S, 7, 0, &tolua_err) || + !tolua_iscppstring(tolua_S, 8, 0, &tolua_err) || + !tolua_isusertype (tolua_S, 9, "cPlayer", 1, &tolua_err) || + !tolua_isnoobj (tolua_S, 10, &tolua_err) + ) + goto tolua_lerror; + else + #endif + { + cWorld * self = (cWorld *) tolua_tousertype (tolua_S, 1, nullptr); + int BlockX = (int) tolua_tonumber (tolua_S, 2, 0); + int BlockY = (int) tolua_tonumber (tolua_S, 3, 0); + int BlockZ = (int) tolua_tonumber (tolua_S, 4, 0); + const AString Line1 = tolua_tocppstring(tolua_S, 5, 0); + const AString Line2 = tolua_tocppstring(tolua_S, 6, 0); + const AString Line3 = tolua_tocppstring(tolua_S, 7, 0); + const AString Line4 = tolua_tocppstring(tolua_S, 8, 0); + cPlayer * Player = (cPlayer *)tolua_tousertype (tolua_S, 9, nullptr); + #ifndef TOLUA_RELEASE + if (self == nullptr) + { + tolua_error(tolua_S, "invalid 'self' in function 'UpdateSign'", nullptr); + } + #endif + { + bool res = self->SetSignLines(BlockX, BlockY, BlockZ, Line1, Line2, Line3, Line4, Player); + tolua_pushboolean(tolua_S, res ? 1 : 0); + } + } + lua_do_warning(tolua_S, "Warning in function call '#funcname#': UpdateSign() is deprecated. Please use SetSignLines()"); + return 1; + + #ifndef TOLUA_RELEASE +tolua_lerror: + tolua_error(tolua_S, "#ferror in function 'UpdateSign'.", &tolua_err); + return 0; + #endif +} + + + + + void DeprecatedBindings::Bind(lua_State * tolua_S) { tolua_beginmodule(tolua_S, nullptr); @@ -235,6 +317,10 @@ void DeprecatedBindings::Bind(lua_State * tolua_S) tolua_array(tolua_S, "g_BlockIsSolid", tolua_get_AllToLua_g_BlockIsSolid, nullptr); tolua_array(tolua_S, "g_BlockFullyOccupiesVoxel", tolua_get_AllToLua_g_BlockFullyOccupiesVoxel, nullptr); + tolua_beginmodule(tolua_S, "cWorld"); + tolua_function(tolua_S, "UpdateSign", tolua_cWorld_SetSignLines); + tolua_endmodule(tolua_S); + tolua_endmodule(tolua_S); } diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index e259e2e91..750f7c65a 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -1034,7 +1034,7 @@ static int tolua_cWorld_SetSignLines(lua_State * tolua_S) #ifndef TOLUA_RELEASE if (self == nullptr) { - tolua_error(tolua_S, "invalid 'self' in function 'SetSignLines' / 'UpdateSign'", nullptr); + tolua_error(tolua_S, "invalid 'self' in function 'SetSignLines'", nullptr); } #endif { @@ -1046,7 +1046,7 @@ static int tolua_cWorld_SetSignLines(lua_State * tolua_S) #ifndef TOLUA_RELEASE tolua_lerror: - tolua_error(tolua_S, "#ferror in function 'SetSignLines' / 'UpdateSign'.", &tolua_err); + tolua_error(tolua_S, "#ferror in function 'SetSignLines'.", &tolua_err); return 0; #endif } @@ -3405,7 +3405,6 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_function(tolua_S, "ScheduleTask", tolua_cWorld_ScheduleTask); tolua_function(tolua_S, "SetSignLines", tolua_cWorld_SetSignLines); tolua_function(tolua_S, "TryGetHeight", tolua_cWorld_TryGetHeight); - tolua_function(tolua_S, "UpdateSign", tolua_cWorld_SetSignLines); tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "cMapManager"); -- cgit v1.2.3 From f9cfc36643b7cc0a2b8f46455d452beb6e444e0d Mon Sep 17 00:00:00 2001 From: Mattes D Date: Mon, 17 Nov 2014 16:50:28 +0100 Subject: Added cImprovedNoise implementation. --- src/Generating/Noise3DGenerator.cpp | 37 +---- src/Generating/Noise3DGenerator.h | 6 +- src/Noise.cpp | 274 +++++++++++++++++++++++++++++++++++- src/Noise.h | 105 +++++++++++++- 4 files changed, 376 insertions(+), 46 deletions(-) diff --git a/src/Generating/Noise3DGenerator.cpp b/src/Generating/Noise3DGenerator.cpp index f2af75999..654e9d01f 100644 --- a/src/Generating/Noise3DGenerator.cpp +++ b/src/Generating/Noise3DGenerator.cpp @@ -61,35 +61,6 @@ public: -/** Linearly interpolates between two values. -Assumes that a_Ratio is in range [0, 1]. */ -inline static NOISE_DATATYPE Lerp(NOISE_DATATYPE a_Val1, NOISE_DATATYPE a_Val2, NOISE_DATATYPE a_Ratio) -{ - return a_Val1 + (a_Val2 - a_Val1) * a_Ratio; -} - - - - - -/** Linearly interpolates between two values, clamping the ratio to [0, 1] first. */ -inline static NOISE_DATATYPE ClampedLerp(NOISE_DATATYPE a_Val1, NOISE_DATATYPE a_Val2, NOISE_DATATYPE a_Ratio) -{ - if (a_Ratio < 0) - { - return a_Val1; - } - if (a_Ratio > 1) - { - return a_Val2; - } - return Lerp(a_Val1, a_Val2, a_Ratio); -} - - - - - //////////////////////////////////////////////////////////////////////////////// // cNoise3DGenerator: @@ -249,10 +220,10 @@ void cNoise3DGenerator::GenerateNoiseArray(int a_ChunkX, int a_ChunkZ, NOISE_DAT NOISE_DATATYPE NoiseW[DIM_X * DIM_Y * DIM_Z]; // Workspace that the noise calculation can use and trash // Our noise array has different layout, XZY, instead of regular chunk's XYZ, that's why the coords are "renamed" - NOISE_DATATYPE StartX = ((NOISE_DATATYPE)(a_ChunkX * cChunkDef::Width)) / m_FrequencyX; - NOISE_DATATYPE EndX = ((NOISE_DATATYPE)((a_ChunkX + 1) * cChunkDef::Width) - 1) / m_FrequencyX; - NOISE_DATATYPE StartZ = ((NOISE_DATATYPE)(a_ChunkZ * cChunkDef::Width)) / m_FrequencyZ; - NOISE_DATATYPE EndZ = ((NOISE_DATATYPE)((a_ChunkZ + 1) * cChunkDef::Width) - 1) / m_FrequencyZ; + NOISE_DATATYPE StartX = ((NOISE_DATATYPE)(a_ChunkX * cChunkDef::Width)) / m_FrequencyX; + NOISE_DATATYPE EndX = ((NOISE_DATATYPE)((a_ChunkX + 1) * cChunkDef::Width)) / m_FrequencyX; + NOISE_DATATYPE StartZ = ((NOISE_DATATYPE)(a_ChunkZ * cChunkDef::Width)) / m_FrequencyZ; + NOISE_DATATYPE EndZ = ((NOISE_DATATYPE)((a_ChunkZ + 1) * cChunkDef::Width)) / m_FrequencyZ; NOISE_DATATYPE StartY = 0; NOISE_DATATYPE EndY = ((NOISE_DATATYPE)256) / m_FrequencyY; diff --git a/src/Generating/Noise3DGenerator.h b/src/Generating/Noise3DGenerator.h index ba541fbcc..92cfc32b7 100644 --- a/src/Generating/Noise3DGenerator.h +++ b/src/Generating/Noise3DGenerator.h @@ -34,9 +34,9 @@ public: protected: // Linear interpolation step sizes, must be divisors of cChunkDef::Width and cChunkDef::Height, respectively: - static const int UPSCALE_X = 8; - static const int UPSCALE_Y = 4; - static const int UPSCALE_Z = 8; + static const int UPSCALE_X = 4; + static const int UPSCALE_Y = 8; + static const int UPSCALE_Z = 4; // Linear interpolation buffer dimensions, calculated from the step sizes: static const int DIM_X = 1 + cChunkDef::Width / UPSCALE_X; diff --git a/src/Noise.cpp b/src/Noise.cpp index 8fcfe2920..56d39395d 100644 --- a/src/Noise.cpp +++ b/src/Noise.cpp @@ -2,6 +2,7 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "Noise.h" +#include "OSSupport\Timer.h" #define FAST_FLOOR(x) (((x) < 0) ? (((int)x) - 1) : ((int)x)) @@ -9,10 +10,110 @@ +#if 0 +/** cImprovedPerlin noise test suite: +- Generate a rather large 2D and 3D noise array and output it to a file +- Compare performance of cCubicNoise and cImprovedNoise, both in single-value and 3D-array usages */ +static class cImprovedPerlinNoiseTest +{ +public: + cImprovedPerlinNoiseTest(void) + { + printf("Performing Improved Perlin Noise tests...\n"); + TestImage(); + TestSpeed(); + TestSpeedArr(); + printf("Improved Perlin Noise tests complete.\n"); + } + + + /** Tests the noise by generating 2D and 3D images and dumping them to files. */ + void TestImage(void) + { + static const int SIZE_X = 256; + static const int SIZE_Y = 256; + static const int SIZE_Z = 16; + + cImprovedNoise noise(1); + std::unique_ptr arr(new NOISE_DATATYPE[SIZE_X * SIZE_Y * SIZE_Z]); + noise.Generate3D(arr.get(), SIZE_X, SIZE_Y, SIZE_Z, 0, 14, 0, 14, 0, 14); + Debug3DNoise(arr.get(), SIZE_X, SIZE_Y, SIZE_Z, "ImprovedPerlinNoiseTest3D", 128); + noise.Generate2D(arr.get(), SIZE_X, SIZE_Y, 0, 14, 15, 28); + Debug2DNoise(arr.get(), SIZE_X, SIZE_Y, "ImprovedPerlinNoiseTest2D", 128); + } + + + /** Tests the speeds of cImprovedPerlin and cCubicNoise when generating individual values. */ + void TestSpeed(void) + { + cImprovedNoise improvedNoise(1); + cNoise noise(1); + cTimer timer; + + // Measure the improvedNoise: + NOISE_DATATYPE sum = 0; + long long start = timer.GetNowTime(); + for (int i = 0; i < 100000000; i++) + { + sum += improvedNoise.GetValueAt(i, 0, -i); + } + long long finish = timer.GetNowTime(); + printf("cImprovedNoise took %.2f seconds; total is %f.\n", static_cast(finish - start) / 1000.0f, sum); + + // Measure the cubicNoise: + sum = 0; + start = timer.GetNowTime(); + for (int i = 0; i < 100000000; i++) + { + sum += noise.IntNoise3D(i, 0, -i); + } + finish = timer.GetNowTime(); + printf("cCubicNoise took %.2f seconds; total is %f.\n", static_cast(finish - start) / 1000.0f, sum); + } + + + /** Tests the speeds of cImprovedPerlin and cCubicNoise when generating arrays. */ + void TestSpeedArr(void) + { + static const int SIZE_X = 256; + static const int SIZE_Y = 256; + static const int SIZE_Z = 16; + + std::unique_ptr arr(new NOISE_DATATYPE[SIZE_X * SIZE_Y * SIZE_Z]); + cTimer timer; + cImprovedNoise improvedNoise(1); + cCubicNoise cubicNoise(1); + + // Measure the improvedNoise: + long long start = timer.GetNowTime(); + for (int i = 0; i < 40; i++) + { + improvedNoise.Generate3D(arr.get(), SIZE_X, SIZE_Y, SIZE_Z, 0, 14, 0, 14, 0, 14); + } + long long finish = timer.GetNowTime(); + printf("cImprovedNoise(arr) took %.2f seconds.\n", static_cast(finish - start) / 1000.0f); + + // Measure the cubicNoise: + start = timer.GetNowTime(); + for (int i = 0; i < 40; i++) + { + cubicNoise.Generate3D(arr.get(), SIZE_X, SIZE_Y, SIZE_Z, 0, 14, 0, 14, 0, 14); + } + finish = timer.GetNowTime(); + printf("cCubicNoise(arr) took %.2f seconds.\n", static_cast(finish - start) / 1000.0f); + } +} g_Test; + +#endif + + + + + //////////////////////////////////////////////////////////////////////////////// // Globals: -void Debug3DNoise(const NOISE_DATATYPE * a_Noise, int a_SizeX, int a_SizeY, int a_SizeZ, const AString & a_FileNameBase) +void Debug3DNoise(const NOISE_DATATYPE * a_Noise, int a_SizeX, int a_SizeY, int a_SizeZ, const AString & a_FileNameBase, NOISE_DATATYPE a_Coeff) { const int BUF_SIZE = 512; ASSERT(a_SizeX <= BUF_SIZE); // Just stretch it, if needed @@ -29,7 +130,7 @@ void Debug3DNoise(const NOISE_DATATYPE * a_Noise, int a_SizeX, int a_SizeY, int unsigned char buf[BUF_SIZE]; for (int x = 0; x < a_SizeX; x++) { - buf[x] = (unsigned char)(std::min(255, std::max(0, (int)(128 + 32 * a_Noise[idx++])))); + buf[x] = static_cast(Clamp((int)(128 + a_Coeff * a_Noise[idx++]), 0, 255)); } f1.Write(buf, a_SizeX); } // for y @@ -50,7 +151,7 @@ void Debug3DNoise(const NOISE_DATATYPE * a_Noise, int a_SizeX, int a_SizeY, int unsigned char buf[BUF_SIZE]; for (int x = 0; x < a_SizeX; x++) { - buf[x] = (unsigned char)(std::min(255, std::max(0, (int)(128 + 32 * a_Noise[idx++])))); + buf[x] = static_cast(Clamp((int)(128 + a_Coeff * a_Noise[idx++]), 0, 255)); } f2.Write(buf, a_SizeX); } // for z @@ -65,7 +166,7 @@ void Debug3DNoise(const NOISE_DATATYPE * a_Noise, int a_SizeX, int a_SizeY, int -void Debug2DNoise(const NOISE_DATATYPE * a_Noise, int a_SizeX, int a_SizeY, const AString & a_FileNameBase) +void Debug2DNoise(const NOISE_DATATYPE * a_Noise, int a_SizeX, int a_SizeY, const AString & a_FileNameBase, NOISE_DATATYPE a_Coeff) { const int BUF_SIZE = 512; ASSERT(a_SizeX <= BUF_SIZE); // Just stretch it, if needed @@ -79,7 +180,7 @@ void Debug2DNoise(const NOISE_DATATYPE * a_Noise, int a_SizeX, int a_SizeY, cons unsigned char buf[BUF_SIZE]; for (int x = 0; x < a_SizeX; x++) { - buf[x] = (unsigned char)(std::min(255, std::max(0, (int)(128 + 32 * a_Noise[idx++])))); + buf[x] = static_cast(Clamp((int)(128 + a_Coeff * a_Noise[idx++]), 0, 255)); } f1.Write(buf, a_SizeX); } // for y @@ -791,6 +892,169 @@ void cCubicNoise::CalcFloorFrac( +//////////////////////////////////////////////////////////////////////////////// +// cImprovedNoise: + +cImprovedNoise::cImprovedNoise(int a_Seed) +{ + // Initialize the permutations with identity: + for (int i = 0; i < 256; i++) + { + m_Perm[i] = i; + } + + // Randomize the permutation table - swap each element with a random other element: + cNoise noise(a_Seed); + for (int i = 0; i < 256; i++) + { + int rnd = (noise.IntNoise1DInt(i) / 7) % 256; + std::swap(m_Perm[i], m_Perm[rnd]); + } + + // Copy the lower 256 entries into upper 256 entries: + for (int i = 0; i < 256; i++) + { + m_Perm[i + 256] = m_Perm[i]; + } +} + + + + + +void cImprovedNoise::Generate2D( + NOISE_DATATYPE * a_Array, + int a_SizeX, int a_SizeY, + NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, + NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY +) const +{ + size_t idx = 0; + for (int y = 0; y < a_SizeY; y++) + { + NOISE_DATATYPE ratioY = static_cast(y) / (a_SizeY - 1); + NOISE_DATATYPE noiseY = Lerp(a_StartY, a_EndY, ratioY); + int noiseYInt = FAST_FLOOR(noiseY); + int yCoord = noiseYInt & 255; + NOISE_DATATYPE noiseYFrac = noiseY - noiseYInt; + NOISE_DATATYPE fadeY = Fade(noiseYFrac); + for (int x = 0; x < a_SizeX; x++) + { + NOISE_DATATYPE ratioX = static_cast(x) / (a_SizeX - 1); + NOISE_DATATYPE noiseX = Lerp(a_StartX, a_EndX, ratioX); + int noiseXInt = FAST_FLOOR(noiseX); + int xCoord = noiseXInt & 255; + NOISE_DATATYPE noiseXFrac = noiseX - noiseXInt; + NOISE_DATATYPE fadeX = Fade(noiseXFrac); + + // Hash the coordinates: + int A = m_Perm[xCoord] + yCoord; + int AA = m_Perm[A]; + int AB = m_Perm[A + 1]; + int B = m_Perm[xCoord + 1] + yCoord; + int BA = m_Perm[B]; + int BB = m_Perm[B + 1]; + + // Lerp the gradients: + a_Array[idx++] = Lerp( + Lerp(Grad(m_Perm[AA], noiseXFrac, noiseYFrac, 0), Grad(m_Perm[BA], noiseXFrac - 1, noiseYFrac, 0), fadeX), + Lerp(Grad(m_Perm[AB], noiseXFrac, noiseYFrac - 1, 0), Grad(m_Perm[BB], noiseXFrac - 1, noiseYFrac - 1, 0), fadeX), + fadeY + ); + } // for x + } // for y +} + + + + + +void cImprovedNoise::Generate3D( + NOISE_DATATYPE * a_Array, + int a_SizeX, int a_SizeY, int a_SizeZ, + NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, + NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, + NOISE_DATATYPE a_StartZ, NOISE_DATATYPE a_EndZ +) const +{ + size_t idx = 0; + for (int z = 0; z < a_SizeZ; z++) + { + NOISE_DATATYPE ratioZ = static_cast(z) / (a_SizeZ - 1); + NOISE_DATATYPE noiseZ = Lerp(a_StartZ, a_EndZ, ratioZ); + int noiseZInt = FAST_FLOOR(noiseZ); + int zCoord = noiseZInt & 255; + NOISE_DATATYPE noiseZFrac = noiseZ - noiseZInt; + NOISE_DATATYPE fadeZ = Fade(noiseZFrac); + for (int y = 0; y < a_SizeY; y++) + { + NOISE_DATATYPE ratioY = static_cast(y) / (a_SizeY - 1); + NOISE_DATATYPE noiseY = Lerp(a_StartY, a_EndY, ratioY); + int noiseYInt = FAST_FLOOR(noiseY); + int yCoord = noiseYInt & 255; + NOISE_DATATYPE noiseYFrac = noiseY - noiseYInt; + NOISE_DATATYPE fadeY = Fade(noiseYFrac); + for (int x = 0; x < a_SizeX; x++) + { + NOISE_DATATYPE ratioX = static_cast(x) / (a_SizeX - 1); + NOISE_DATATYPE noiseX = Lerp(a_StartX, a_EndX, ratioX); + int noiseXInt = FAST_FLOOR(noiseX); + int xCoord = noiseXInt & 255; + NOISE_DATATYPE noiseXFrac = noiseX - noiseXInt; + NOISE_DATATYPE fadeX = Fade(noiseXFrac); + + // Hash the coordinates: + int A = m_Perm[xCoord] + yCoord; + int AA = m_Perm[A] + zCoord; + int AB = m_Perm[A + 1] + zCoord; + int B = m_Perm[xCoord + 1] + yCoord; + int BA = m_Perm[B] + zCoord; + int BB = m_Perm[B + 1] + zCoord; + + // Lerp the gradients: + // TODO: This may be optimized by swapping the coords and recalculating most lerps only "once every x" + a_Array[idx++] = Lerp( + Lerp( + Lerp(Grad(m_Perm[AA], noiseXFrac, noiseYFrac, noiseZFrac), Grad(m_Perm[BA], noiseXFrac - 1, noiseYFrac, noiseZFrac), fadeX), + Lerp(Grad(m_Perm[AB], noiseXFrac, noiseYFrac - 1, noiseZFrac), Grad(m_Perm[BB], noiseXFrac - 1, noiseYFrac - 1, noiseZFrac), fadeX), + fadeY + ), + Lerp( + Lerp(Grad(m_Perm[AA + 1], noiseXFrac, noiseYFrac, noiseZFrac - 1), Grad(m_Perm[BA + 1], noiseXFrac - 1, noiseYFrac, noiseZFrac - 1), fadeX), + Lerp(Grad(m_Perm[AB + 1], noiseXFrac, noiseYFrac - 1, noiseZFrac - 1), Grad(m_Perm[BB + 1], noiseXFrac - 1, noiseYFrac - 1, noiseZFrac - 1), fadeX), + fadeY + ), + fadeZ + ); + } // for x + } // for y + } // for z +} + + + + + +NOISE_DATATYPE cImprovedNoise::GetValueAt(int a_X, int a_Y, int a_Z) +{ + // Hash the coordinates: + a_X = a_X & 255; + a_Y = a_Y & 255; + a_Z = a_Z & 255; + int A = m_Perm[a_X] + a_Y; + int AA = m_Perm[A] + a_Z; + int AB = m_Perm[A + 1] + a_Z; + int B = m_Perm[a_X + 1] + a_Y; + int BA = m_Perm[B] + a_Z; + int BB = m_Perm[B + 1] + a_Z; + + return Grad(m_Perm[AA], 0, 0, 0); +} + + + + + //////////////////////////////////////////////////////////////////////////////// // cPerlinNoise: diff --git a/src/Noise.h b/src/Noise.h index b7a90d5b7..3c5caded7 100644 --- a/src/Noise.h +++ b/src/Noise.h @@ -140,6 +140,63 @@ protected: +/** Improved noise, as described by Ken Perlin: http://mrl.nyu.edu/~perlin/paper445.pdf +Implementation adapted from Perlin's Java implementation: http://mrl.nyu.edu/~perlin/noise/ */ +class cImprovedNoise +{ +public: + /** Constructs a new instance of the noise obbject. + Note that this operation is quite expensive (the permutation array being constructed). */ + cImprovedNoise(int a_Seed); + + + /** Fills a 2D array with the values of the noise. */ + void Generate2D( + NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y] + int a_SizeX, int a_SizeY, ///< Count of the array, in each direction + NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction + NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY ///< Noise-space coords of the array in the Y direction + ) const; + + + /** Fills a 3D array with the values of the noise. */ + void Generate3D( + NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y + a_SizeX * a_SizeY * z] + int a_SizeX, int a_SizeY, int a_SizeZ, ///< Count of the array, in each direction + NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction + NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction + NOISE_DATATYPE a_StartZ, NOISE_DATATYPE a_EndZ ///< Noise-space coords of the array in the Z direction + ) const; + + /** Returns the value at the specified integral coords. Used for raw speed measurement. */ + NOISE_DATATYPE GetValueAt(int a_X, int a_Y, int a_Z); + +protected: + + /** The permutation table used by the noise function. Initialized using seed. */ + int m_Perm[512]; + + + /** Calculates the fade curve, 6 * t^5 - 15 * t^4 + 10 * t^3. */ + inline static NOISE_DATATYPE Fade(NOISE_DATATYPE a_T) + { + return a_T * a_T * a_T * (a_T * (a_T * 6 - 15) + 10); + } + + /** Returns the gradient value based on the hash. */ + inline static NOISE_DATATYPE Grad(int a_Hash, NOISE_DATATYPE a_X, NOISE_DATATYPE a_Y, NOISE_DATATYPE a_Z) + { + int hash = a_Hash % 16; + NOISE_DATATYPE u = (hash < 8) ? a_X : a_Y; + NOISE_DATATYPE v = (hash < 4) ? a_Y : (((hash == 12) || (hash == 14)) ? a_X : a_Z); + return (((hash & 1) == 0) ? u : -u) + (((hash & 2) == 0) ? v : -v); + } +}; + + + + + class cPerlinNoise { public: @@ -155,7 +212,7 @@ public: NOISE_DATATYPE * a_Array, ///< Array to generate into int a_SizeX, ///< Count of the array NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array - NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash + NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash ) const; @@ -164,7 +221,7 @@ public: int a_SizeX, int a_SizeY, ///< Count of the array, in each direction NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction - NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash + NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash ) const; @@ -174,7 +231,7 @@ public: NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction NOISE_DATATYPE a_StartZ, NOISE_DATATYPE a_EndZ, ///< Noise-space coords of the array in the Z direction - NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash + NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash ) const; protected: @@ -376,8 +433,46 @@ NOISE_DATATYPE cNoise::LinearInterpolate(NOISE_DATATYPE a_A, NOISE_DATATYPE a_B, //////////////////////////////////////////////////////////////////////////////// // Global functions: -extern void Debug2DNoise(const NOISE_DATATYPE * a_Noise, int a_SizeX, int a_SizeY, const AString & a_FileNameBase); -extern void Debug3DNoise(const NOISE_DATATYPE * a_Noise, int a_SizeX, int a_SizeY, int a_SizeZ, const AString & a_FileNameBase); +/** Exports the noise array into a file. +a_Coeff specifies the value that each array value is multiplied by before being converted into a byte. */ +extern void Debug2DNoise(const NOISE_DATATYPE * a_Array, int a_SizeX, int a_SizeY, const AString & a_FileNameBase, NOISE_DATATYPE a_Coeff = 32); + +/** Exports the noise array into a set of files, ordered by XY and XZ. +a_Coeff specifies the value that each array value is multiplied by before being converted into a byte. */ +extern void Debug3DNoise(const NOISE_DATATYPE * a_Array, int a_SizeX, int a_SizeY, int a_SizeZ, const AString & a_FileNameBase, NOISE_DATATYPE a_Coeff = 32); + + + + +/** Linearly interpolates between two values. +Assumes that a_Ratio is in range [0, 1]. */ +inline NOISE_DATATYPE Lerp(NOISE_DATATYPE a_Val1, NOISE_DATATYPE a_Val2, NOISE_DATATYPE a_Ratio) +{ + return a_Val1 + (a_Val2 - a_Val1) * a_Ratio; +} + + + + + +/** Linearly interpolates between two values, clamping the ratio to [0, 1] first. */ +inline NOISE_DATATYPE ClampedLerp(NOISE_DATATYPE a_Val1, NOISE_DATATYPE a_Val2, NOISE_DATATYPE a_Ratio) +{ + if (a_Ratio < 0) + { + return a_Val1; + } + if (a_Ratio > 1) + { + return a_Val2; + } + return Lerp(a_Val1, a_Val2, a_Ratio); +} + + + + + -- cgit v1.2.3 From faf0ce3d7f001d6725f3fdaa7c69a56ed40955f1 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Mon, 17 Nov 2014 17:13:42 +0100 Subject: Fixed include path. --- src/Noise.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Noise.cpp b/src/Noise.cpp index 56d39395d..d3098c295 100644 --- a/src/Noise.cpp +++ b/src/Noise.cpp @@ -2,7 +2,7 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "Noise.h" -#include "OSSupport\Timer.h" +#include "OSSupport/Timer.h" #define FAST_FLOOR(x) (((x) < 0) ? (((int)x) - 1) : ((int)x)) -- cgit v1.2.3 From d7efece5f2efcbaa93c36f26c325fea66f3700f1 Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 17 Nov 2014 18:01:56 +0100 Subject: Use cLuaState's stack trace. --- src/Bindings/DeprecatedBindings.cpp | 75 +++++++++++++------------------------ 1 file changed, 27 insertions(+), 48 deletions(-) diff --git a/src/Bindings/DeprecatedBindings.cpp b/src/Bindings/DeprecatedBindings.cpp index 442d9add5..345ab2a07 100644 --- a/src/Bindings/DeprecatedBindings.cpp +++ b/src/Bindings/DeprecatedBindings.cpp @@ -9,31 +9,7 @@ #include "../BlockInfo.h" #include "../World.h" #include "../Entities/Player.h" - - - - - -static void lua_do_warning(lua_State* L, const char * a_pFormat, ...) -{ - // Retrieve current function name - lua_Debug entry; - VERIFY(lua_getstack(L, 0, &entry)); - VERIFY(lua_getinfo(L, "n", &entry)); - - // Insert function name into error msg - AString msg(a_pFormat); - ReplaceString(msg, "#funcname#", entry.name?entry.name:"?"); - - // Copied from luaL_error and modified - va_list argp; - va_start(argp, a_pFormat); - luaL_where(L, 1); - lua_pushvfstring(L, msg.c_str(), argp); - va_end(argp); - lua_concat(L, 2); - lua_error(L); -} +#include "LuaState.h" @@ -252,50 +228,53 @@ static int tolua_get_AllToLua_g_BlockFullyOccupiesVoxel(lua_State* tolua_S) /** function: cWorld:SetSignLines */ static int tolua_cWorld_SetSignLines(lua_State * tolua_S) { + cLuaState LuaState(tolua_S); + #ifndef TOLUA_RELEASE tolua_Error tolua_err; if ( - !tolua_isusertype (tolua_S, 1, "cWorld", 0, &tolua_err) || - !tolua_isnumber (tolua_S, 2, 0, &tolua_err) || - !tolua_isnumber (tolua_S, 3, 0, &tolua_err) || - !tolua_isnumber (tolua_S, 4, 0, &tolua_err) || - !tolua_iscppstring(tolua_S, 5, 0, &tolua_err) || - !tolua_iscppstring(tolua_S, 6, 0, &tolua_err) || - !tolua_iscppstring(tolua_S, 7, 0, &tolua_err) || - !tolua_iscppstring(tolua_S, 8, 0, &tolua_err) || - !tolua_isusertype (tolua_S, 9, "cPlayer", 1, &tolua_err) || - !tolua_isnoobj (tolua_S, 10, &tolua_err) + !tolua_isusertype (LuaState, 1, "cWorld", 0, &tolua_err) || + !tolua_isnumber (LuaState, 2, 0, &tolua_err) || + !tolua_isnumber (LuaState, 3, 0, &tolua_err) || + !tolua_isnumber (LuaState, 4, 0, &tolua_err) || + !tolua_iscppstring(LuaState, 5, 0, &tolua_err) || + !tolua_iscppstring(LuaState, 6, 0, &tolua_err) || + !tolua_iscppstring(LuaState, 7, 0, &tolua_err) || + !tolua_iscppstring(LuaState, 8, 0, &tolua_err) || + !tolua_isusertype (LuaState, 9, "cPlayer", 1, &tolua_err) || + !tolua_isnoobj (LuaState, 10, &tolua_err) ) goto tolua_lerror; else #endif { - cWorld * self = (cWorld *) tolua_tousertype (tolua_S, 1, nullptr); - int BlockX = (int) tolua_tonumber (tolua_S, 2, 0); - int BlockY = (int) tolua_tonumber (tolua_S, 3, 0); - int BlockZ = (int) tolua_tonumber (tolua_S, 4, 0); - const AString Line1 = tolua_tocppstring(tolua_S, 5, 0); - const AString Line2 = tolua_tocppstring(tolua_S, 6, 0); - const AString Line3 = tolua_tocppstring(tolua_S, 7, 0); - const AString Line4 = tolua_tocppstring(tolua_S, 8, 0); - cPlayer * Player = (cPlayer *)tolua_tousertype (tolua_S, 9, nullptr); + cWorld * self = (cWorld *) tolua_tousertype (LuaState, 1, nullptr); + int BlockX = (int) tolua_tonumber (LuaState, 2, 0); + int BlockY = (int) tolua_tonumber (LuaState, 3, 0); + int BlockZ = (int) tolua_tonumber (LuaState, 4, 0); + const AString Line1 = tolua_tocppstring(LuaState, 5, 0); + const AString Line2 = tolua_tocppstring(LuaState, 6, 0); + const AString Line3 = tolua_tocppstring(LuaState, 7, 0); + const AString Line4 = tolua_tocppstring(LuaState, 8, 0); + cPlayer * Player = (cPlayer *)tolua_tousertype (LuaState, 9, nullptr); #ifndef TOLUA_RELEASE if (self == nullptr) { - tolua_error(tolua_S, "invalid 'self' in function 'UpdateSign'", nullptr); + tolua_error(LuaState, "invalid 'self' in function 'UpdateSign'", nullptr); } #endif { bool res = self->SetSignLines(BlockX, BlockY, BlockZ, Line1, Line2, Line3, Line4, Player); - tolua_pushboolean(tolua_S, res ? 1 : 0); + tolua_pushboolean(LuaState, res ? 1 : 0); } } - lua_do_warning(tolua_S, "Warning in function call '#funcname#': UpdateSign() is deprecated. Please use SetSignLines()"); + LOGWARNING("Warning in function call 'UpdateSign': UpdateSign() is deprecated. Please use SetSignLines()"); + LuaState.LogStackTrace(0); return 1; #ifndef TOLUA_RELEASE tolua_lerror: - tolua_error(tolua_S, "#ferror in function 'UpdateSign'.", &tolua_err); + tolua_error(LuaState, "#ferror in function 'UpdateSign'.", &tolua_err); return 0; #endif } -- cgit v1.2.3 From e9082263c92549aebd3cb136935db28784adcf01 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Mon, 17 Nov 2014 23:02:53 +0100 Subject: Added cOctavedNoise template. This allows us to use any noise generator in the combination of octaves. --- src/Noise.cpp | 174 ------------------------------------------------ src/Noise.h | 98 ++++----------------------- src/OctavedNoise.h | 192 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 206 insertions(+), 258 deletions(-) create mode 100644 src/OctavedNoise.h diff --git a/src/Noise.cpp b/src/Noise.cpp index d3098c295..d16c0849c 100644 --- a/src/Noise.cpp +++ b/src/Noise.cpp @@ -1043,10 +1043,6 @@ NOISE_DATATYPE cImprovedNoise::GetValueAt(int a_X, int a_Y, int a_Z) a_Z = a_Z & 255; int A = m_Perm[a_X] + a_Y; int AA = m_Perm[A] + a_Z; - int AB = m_Perm[A + 1] + a_Z; - int B = m_Perm[a_X + 1] + a_Y; - int BA = m_Perm[B] + a_Z; - int BB = m_Perm[B + 1] + a_Z; return Grad(m_Perm[AA], 0, 0, 0); } @@ -1055,176 +1051,6 @@ NOISE_DATATYPE cImprovedNoise::GetValueAt(int a_X, int a_Y, int a_Z) -//////////////////////////////////////////////////////////////////////////////// -// cPerlinNoise: - -cPerlinNoise::cPerlinNoise(void) : - m_Seed(0) -{ -} - - - - - -cPerlinNoise::cPerlinNoise(int a_Seed) : - m_Seed(a_Seed) -{ -} - - - - - -void cPerlinNoise::SetSeed(int a_Seed) -{ - m_Seed = a_Seed; -} - - - - - -void cPerlinNoise::AddOctave(float a_Frequency, float a_Amplitude) -{ - m_Octaves.push_back(cOctave(m_Seed * ((int)m_Octaves.size() + 4) * 4 + 1024, a_Frequency, a_Amplitude)); -} - - - - - -void cPerlinNoise::Generate2D( - NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y] - int a_SizeX, int a_SizeY, ///< Count of the array, in each direction - NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction - NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction - NOISE_DATATYPE * a_Workspace ///< Workspace that this function can use and trash -) const -{ - if (m_Octaves.empty()) - { - // No work to be done - ASSERT(!"Perlin: No octaves to generate!"); - return; - } - - bool ShouldFreeWorkspace = (a_Workspace == nullptr); - int ArrayCount = a_SizeX * a_SizeY; - if (ShouldFreeWorkspace) - { - a_Workspace = new NOISE_DATATYPE[ArrayCount]; - } - - // Generate the first octave directly into array: - const cOctave & FirstOctave = m_Octaves.front(); - - FirstOctave.m_Noise.Generate2D( - a_Workspace, a_SizeX, a_SizeY, - a_StartX * FirstOctave.m_Frequency, a_EndX * FirstOctave.m_Frequency, - a_StartY * FirstOctave.m_Frequency, a_EndY * FirstOctave.m_Frequency - ); - NOISE_DATATYPE Amplitude = FirstOctave.m_Amplitude; - for (int i = 0; i < ArrayCount; i++) - { - a_Array[i] = a_Workspace[i] * Amplitude; - } - - // Add each octave: - for (cOctaves::const_iterator itr = m_Octaves.begin() + 1, end = m_Octaves.end(); itr != end; ++itr) - { - // Generate cubic noise for the octave: - itr->m_Noise.Generate2D( - a_Workspace, a_SizeX, a_SizeY, - a_StartX * itr->m_Frequency, a_EndX * itr->m_Frequency, - a_StartY * itr->m_Frequency, a_EndY * itr->m_Frequency - ); - // Add the cubic noise into the output: - NOISE_DATATYPE Amplitude = itr->m_Amplitude; - for (int i = 0; i < ArrayCount; i++) - { - a_Array[i] += a_Workspace[i] * Amplitude; - } - } - - if (ShouldFreeWorkspace) - { - delete[] a_Workspace; - a_Workspace = nullptr; - } -} - - - - - -void cPerlinNoise::Generate3D( - NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y + a_SizeX * a_SizeY * z] - int a_SizeX, int a_SizeY, int a_SizeZ, ///< Count of the array, in each direction - NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction - NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction - NOISE_DATATYPE a_StartZ, NOISE_DATATYPE a_EndZ, ///< Noise-space coords of the array in the Z direction - NOISE_DATATYPE * a_Workspace ///< Workspace that this function can use and trash -) const -{ - if (m_Octaves.empty()) - { - // No work to be done - ASSERT(!"Perlin: No octaves to generate!"); - return; - } - - bool ShouldFreeWorkspace = (a_Workspace == nullptr); - int ArrayCount = a_SizeX * a_SizeY * a_SizeZ; - if (ShouldFreeWorkspace) - { - a_Workspace = new NOISE_DATATYPE[ArrayCount]; - } - - // Generate the first octave directly into array: - const cOctave & FirstOctave = m_Octaves.front(); - - FirstOctave.m_Noise.Generate3D( - a_Workspace, a_SizeX, a_SizeY, a_SizeZ, - a_StartX * FirstOctave.m_Frequency, a_EndX * FirstOctave.m_Frequency, - a_StartY * FirstOctave.m_Frequency, a_EndY * FirstOctave.m_Frequency, - a_StartZ * FirstOctave.m_Frequency, a_EndZ * FirstOctave.m_Frequency - ); - NOISE_DATATYPE Amplitude = FirstOctave.m_Amplitude; - for (int i = 0; i < ArrayCount; i++) - { - a_Array[i] = a_Workspace[i] * Amplitude; - } - - // Add each octave: - for (cOctaves::const_iterator itr = m_Octaves.begin() + 1, end = m_Octaves.end(); itr != end; ++itr) - { - // Generate cubic noise for the octave: - itr->m_Noise.Generate3D( - a_Workspace, a_SizeX, a_SizeY, a_SizeZ, - a_StartX * itr->m_Frequency, a_EndX * itr->m_Frequency, - a_StartY * itr->m_Frequency, a_EndY * itr->m_Frequency, - a_StartZ * itr->m_Frequency, a_EndZ * itr->m_Frequency - ); - // Add the cubic noise into the output: - NOISE_DATATYPE Amplitude = itr->m_Amplitude; - for (int i = 0; i < ArrayCount; i++) - { - a_Array[i] += a_Workspace[i] * Amplitude; - } - } - - if (ShouldFreeWorkspace) - { - delete[] a_Workspace; - a_Workspace = nullptr; - } -} - - - - - //////////////////////////////////////////////////////////////////////////////// // cRidgedMultiNoise: diff --git a/src/Noise.h b/src/Noise.h index 3c5caded7..8b9ee2f3b 100644 --- a/src/Noise.h +++ b/src/Noise.h @@ -7,22 +7,10 @@ #include +/** The datatype used by all the noise generators. */ +typedef float NOISE_DATATYPE; - - - -// Some settings -#define NOISE_DATATYPE float - - - - - -#ifdef _MSC_VER - #define INLINE __forceinline -#else - #define INLINE inline -#endif +#include "OctavedNoise.h" @@ -35,20 +23,20 @@ public: cNoise(const cNoise & a_Noise); // The following functions, if not marked INLINE, are about 20 % slower - INLINE NOISE_DATATYPE IntNoise1D(int a_X) const; - INLINE NOISE_DATATYPE IntNoise2D(int a_X, int a_Y) const; - INLINE NOISE_DATATYPE IntNoise3D(int a_X, int a_Y, int a_Z) const; + inline NOISE_DATATYPE IntNoise1D(int a_X) const; + inline NOISE_DATATYPE IntNoise2D(int a_X, int a_Y) const; + inline NOISE_DATATYPE IntNoise3D(int a_X, int a_Y, int a_Z) const; // Return a float number in the specified range: - INLINE NOISE_DATATYPE IntNoise2DInRange(int a_X, int a_Y, float a_Min, float a_Max) const + inline NOISE_DATATYPE IntNoise2DInRange(int a_X, int a_Y, float a_Min, float a_Max) const { return a_Min + std::abs(IntNoise2D(a_X, a_Y)) * (a_Max - a_Min); } // Note: These functions have a mod8-irregular chance - each of the mod8 remainders has different chance of occurrence. Divide by 8 to rectify. - INLINE int IntNoise1DInt(int a_X) const; - INLINE int IntNoise2DInt(int a_X, int a_Y) const; - INLINE int IntNoise3DInt(int a_X, int a_Y, int a_Z) const; + inline int IntNoise1DInt(int a_X) const; + inline int IntNoise2DInt(int a_X, int a_Y) const; + inline int IntNoise3DInt(int a_X, int a_Y, int a_Z) const; NOISE_DATATYPE LinearNoise1D(NOISE_DATATYPE a_X) const; NOISE_DATATYPE CosineNoise1D(NOISE_DATATYPE a_X) const; @@ -61,9 +49,9 @@ public: void SetSeed(int a_Seed) { m_Seed = a_Seed; } - INLINE static NOISE_DATATYPE CubicInterpolate (NOISE_DATATYPE a_A, NOISE_DATATYPE a_B, NOISE_DATATYPE a_C, NOISE_DATATYPE a_D, NOISE_DATATYPE a_Pct); - INLINE static NOISE_DATATYPE CosineInterpolate(NOISE_DATATYPE a_A, NOISE_DATATYPE a_B, NOISE_DATATYPE a_Pct); - INLINE static NOISE_DATATYPE LinearInterpolate(NOISE_DATATYPE a_A, NOISE_DATATYPE a_B, NOISE_DATATYPE a_Pct); + inline static NOISE_DATATYPE CubicInterpolate (NOISE_DATATYPE a_A, NOISE_DATATYPE a_B, NOISE_DATATYPE a_C, NOISE_DATATYPE a_D, NOISE_DATATYPE a_Pct); + inline static NOISE_DATATYPE CosineInterpolate(NOISE_DATATYPE a_A, NOISE_DATATYPE a_B, NOISE_DATATYPE a_Pct); + inline static NOISE_DATATYPE LinearInterpolate(NOISE_DATATYPE a_A, NOISE_DATATYPE a_B, NOISE_DATATYPE a_Pct); private: int m_Seed; @@ -197,65 +185,7 @@ protected: -class cPerlinNoise -{ -public: - cPerlinNoise(void); - cPerlinNoise(int a_Seed); - - - void SetSeed(int a_Seed); - - void AddOctave(NOISE_DATATYPE a_Frequency, NOISE_DATATYPE a_Amplitude); - - void Generate1D( - NOISE_DATATYPE * a_Array, ///< Array to generate into - int a_SizeX, ///< Count of the array - NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array - NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash - ) const; - - - void Generate2D( - NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y] - int a_SizeX, int a_SizeY, ///< Count of the array, in each direction - NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction - NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction - NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash - ) const; - - - void Generate3D( - NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y + a_SizeX * a_SizeY * z] - int a_SizeX, int a_SizeY, int a_SizeZ, ///< Count of the array, in each direction - NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction - NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction - NOISE_DATATYPE a_StartZ, NOISE_DATATYPE a_EndZ, ///< Noise-space coords of the array in the Z direction - NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash - ) const; - -protected: - class cOctave - { - public: - cCubicNoise m_Noise; - - NOISE_DATATYPE m_Frequency; // Coord multiplier - NOISE_DATATYPE m_Amplitude; // Value multiplier - - cOctave(int a_Seed, NOISE_DATATYPE a_Frequency, NOISE_DATATYPE a_Amplitude) : - m_Noise(a_Seed), - m_Frequency(a_Frequency), - m_Amplitude(a_Amplitude) - { - } - } ; - - typedef std::vector cOctaves; - - int m_Seed; - cOctaves m_Octaves; -} ; +typedef cOctavedNoise cPerlinNoise; diff --git a/src/OctavedNoise.h b/src/OctavedNoise.h new file mode 100644 index 000000000..86fb0ddb0 --- /dev/null +++ b/src/OctavedNoise.h @@ -0,0 +1,192 @@ + +// OctavedNoise.h + +// Implements the cOctavedNoise class template representing a noise generator that layers several octaves of another noise + + + + + +#pragma once + + + + + +template +class cOctavedNoise +{ +public: + cOctavedNoise(int a_Seed = 0): + m_Seed(a_Seed) + { + } + + + /** Sets a new seed for the generators. Relays the seed to all underlying octaves. */ + void SetSeed(int a_Seed) + { + m_Seed = a_Seed; + for (auto oct: m_Octaves) + { + oct->SetSeed(a_Seed); + } + } + + + /** */ + void AddOctave(NOISE_DATATYPE a_Frequency, NOISE_DATATYPE a_Amplitude) + { + m_Octaves.emplace_back(m_Seed, a_Frequency, a_Amplitude); + } + + + /** Fills a 2D array with the values of the noise. */ + void Generate2D( + NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y] + int a_SizeX, int a_SizeY, ///< Count of the array, in each direction + NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction + NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction + NOISE_DATATYPE * a_Workspace ///< Workspace that this function can use and trash. Must be valid. + ) const + { + // Check that state is alright: + if (m_Octaves.empty()) + { + ASSERT(!"Perlin: No octaves to generate!"); + return; + } + + // Allocate the workspace on the heap, if it wasn't given: + std::unique_ptr workspaceHeap; + if (a_Workspace == nullptr) + { + workspaceHeap.reset(new NOISE_DATATYPE[a_SizeX * a_SizeY]); + a_Workspace = workspaceHeap.get(); + } + + // Generate the first octave directly into array: + const cOctave & FirstOctave = m_Octaves.front(); + int ArrayCount = a_SizeX * a_SizeY; + FirstOctave.m_Noise.Generate2D( + a_Workspace, a_SizeX, a_SizeY, + a_StartX * FirstOctave.m_Frequency, a_EndX * FirstOctave.m_Frequency, + a_StartY * FirstOctave.m_Frequency, a_EndY * FirstOctave.m_Frequency + ); + NOISE_DATATYPE Amplitude = FirstOctave.m_Amplitude; + for (int i = 0; i < ArrayCount; i++) + { + a_Array[i] = a_Workspace[i] * Amplitude; + } + + // Add each octave: + for (cOctaves::const_iterator itr = m_Octaves.begin() + 1, end = m_Octaves.end(); itr != end; ++itr) + { + // Generate the noise for the octave: + itr->m_Noise.Generate2D( + a_Workspace, a_SizeX, a_SizeY, + a_StartX * itr->m_Frequency, a_EndX * itr->m_Frequency, + a_StartY * itr->m_Frequency, a_EndY * itr->m_Frequency + ); + // Add it into the output: + NOISE_DATATYPE Amplitude = itr->m_Amplitude; + for (int i = 0; i < ArrayCount; i++) + { + a_Array[i] += a_Workspace[i] * Amplitude; + } + } // for itr - m_Octaves[] + } + + + /** Fills a 3D array with the values of the noise. */ + void Generate3D( + NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y + a_SizeX * a_SizeY * z] + int a_SizeX, int a_SizeY, int a_SizeZ, ///< Count of the array, in each direction + NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction + NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction + NOISE_DATATYPE a_StartZ, NOISE_DATATYPE a_EndZ, ///< Noise-space coords of the array in the Z direction + NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash, same size as a_Array + ) const + { + // Check that state is alright: + if (m_Octaves.empty()) + { + ASSERT(!"Perlin: No octaves to generate!"); + return; + } + + // Allocate the workspace on the heap, if it wasn't given: + std::unique_ptr workspaceHeap; + if (a_Workspace == nullptr) + { + workspaceHeap.reset(new NOISE_DATATYPE[a_SizeX * a_SizeY * a_SizeZ]); + a_Workspace = workspaceHeap.get(); + } + + // Generate the first octave directly into array: + const cOctave & FirstOctave = m_Octaves.front(); + int ArrayCount = a_SizeX * a_SizeY * a_SizeZ; + FirstOctave.m_Noise.Generate3D( + a_Workspace, a_SizeX, a_SizeY, a_SizeZ, + a_StartX * FirstOctave.m_Frequency, a_EndX * FirstOctave.m_Frequency, + a_StartY * FirstOctave.m_Frequency, a_EndY * FirstOctave.m_Frequency, + a_StartZ * FirstOctave.m_Frequency, a_EndZ * FirstOctave.m_Frequency + ); + NOISE_DATATYPE Amplitude = FirstOctave.m_Amplitude; + for (int i = 0; i < ArrayCount; i++) + { + a_Array[i] = a_Workspace[i] * Amplitude; + } + + // Add each octave: + for (cOctaves::const_iterator itr = m_Octaves.begin() + 1, end = m_Octaves.end(); itr != end; ++itr) + { + // Generate the noise for the octave: + itr->m_Noise.Generate3D( + a_Workspace, a_SizeX, a_SizeY, a_SizeZ, + a_StartX * itr->m_Frequency, a_EndX * itr->m_Frequency, + a_StartY * itr->m_Frequency, a_EndY * itr->m_Frequency, + a_StartZ * itr->m_Frequency, a_EndZ * itr->m_Frequency + ); + // Add it into the output: + NOISE_DATATYPE Amplitude = itr->m_Amplitude; + for (int i = 0; i < ArrayCount; i++) + { + a_Array[i] += a_Workspace[i] * Amplitude; + } + } // for itr - m_Octaves[] + } + +protected: + /** Stores information and state for one octave of the noise. */ + class cOctave + { + public: + N m_Noise; + + /** Coord multiplier. */ + NOISE_DATATYPE m_Frequency; + + /** Value multiplier. */ + NOISE_DATATYPE m_Amplitude; + + cOctave(int a_Seed, NOISE_DATATYPE a_Frequency, NOISE_DATATYPE a_Amplitude) : + m_Noise(a_Seed), + m_Frequency(a_Frequency), + m_Amplitude(a_Amplitude) + { + } + } ; + typedef std::vector cOctaves; + + + /** The seed used by the underlying generators. */ + int m_Seed; + + /** The octaves that compose this noise. */ + cOctaves m_Octaves; +}; + + + + -- cgit v1.2.3 From 8c54fc0f7d92af1fbb774fdc36d32f4640769333 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Tue, 18 Nov 2014 09:23:45 +0100 Subject: OctavedNoise: linux compilation fixes. --- src/CMakeLists.txt | 1 + src/OctavedNoise.h | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 096fa824d..83d19eca2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -121,6 +121,7 @@ SET (HDRS MobSpawner.h MonsterConfig.h Noise.h + OctavedNoise.h ProbabDistrib.h RankManager.h RCONServer.h diff --git a/src/OctavedNoise.h b/src/OctavedNoise.h index 86fb0ddb0..272a1051e 100644 --- a/src/OctavedNoise.h +++ b/src/OctavedNoise.h @@ -80,7 +80,7 @@ public: } // Add each octave: - for (cOctaves::const_iterator itr = m_Octaves.begin() + 1, end = m_Octaves.end(); itr != end; ++itr) + for (auto itr = m_Octaves.cbegin() + 1, end = m_Octaves.cend(); itr != end; ++itr) { // Generate the noise for the octave: itr->m_Noise.Generate2D( @@ -139,7 +139,7 @@ public: } // Add each octave: - for (cOctaves::const_iterator itr = m_Octaves.begin() + 1, end = m_Octaves.end(); itr != end; ++itr) + for (auto itr = m_Octaves.cbegin() + 1, end = m_Octaves.cend(); itr != end; ++itr) { // Generate the noise for the octave: itr->m_Noise.Generate3D( -- cgit v1.2.3 From f683872f5423c184d56bc229c7de44b2384c4787 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Tue, 18 Nov 2014 09:49:53 +0100 Subject: Refactored cRidgedNoise into a separate template. This allows us to make the ridges out of any noise and to combine the cRidgedNoise with cOctavedNoise. --- src/CMakeLists.txt | 1 + src/Noise.cpp | 171 +---------------------------------------------------- src/Noise.h | 66 +-------------------- src/OctavedNoise.h | 18 +++--- src/RidgedNoise.h | 91 ++++++++++++++++++++++++++++ 5 files changed, 104 insertions(+), 243 deletions(-) create mode 100644 src/RidgedNoise.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 83d19eca2..a8dfc394c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -124,6 +124,7 @@ SET (HDRS OctavedNoise.h ProbabDistrib.h RankManager.h + RidgedNoise.h RCONServer.h Root.h Scoreboard.h diff --git a/src/Noise.cpp b/src/Noise.cpp index d16c0849c..c4a7e2d5f 100644 --- a/src/Noise.cpp +++ b/src/Noise.cpp @@ -1044,179 +1044,10 @@ NOISE_DATATYPE cImprovedNoise::GetValueAt(int a_X, int a_Y, int a_Z) int A = m_Perm[a_X] + a_Y; int AA = m_Perm[A] + a_Z; - return Grad(m_Perm[AA], 0, 0, 0); + return Grad(m_Perm[AA], 1, 1, 1); } -//////////////////////////////////////////////////////////////////////////////// -// cRidgedMultiNoise: - -cRidgedMultiNoise::cRidgedMultiNoise(void) : - m_Seed(0) -{ -} - - - - - -cRidgedMultiNoise::cRidgedMultiNoise(int a_Seed) : - m_Seed(a_Seed) -{ -} - - - - - -void cRidgedMultiNoise::SetSeed(int a_Seed) -{ - m_Seed = a_Seed; -} - - - - - -void cRidgedMultiNoise::AddOctave(float a_Frequency, float a_Amplitude) -{ - m_Octaves.push_back(cOctave(m_Seed * ((int)m_Octaves.size() + 4) * 4 + 1024, a_Frequency, a_Amplitude)); -} - - - - - -void cRidgedMultiNoise::Generate2D( - NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y] - int a_SizeX, int a_SizeY, ///< Count of the array, in each direction - NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction - NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction - NOISE_DATATYPE * a_Workspace ///< Workspace that this function can use and trash -) const -{ - if (m_Octaves.empty()) - { - // No work to be done - ASSERT(!"RidgedMulti: No octaves to generate!"); - return; - } - - bool ShouldFreeWorkspace = (a_Workspace == nullptr); - int ArrayCount = a_SizeX * a_SizeY; - if (ShouldFreeWorkspace) - { - a_Workspace = new NOISE_DATATYPE[ArrayCount]; - } - - // Generate the first octave directly into array: - const cOctave & FirstOctave = m_Octaves.front(); - - FirstOctave.m_Noise.Generate2D( - a_Workspace, a_SizeX, a_SizeY, - a_StartX * FirstOctave.m_Frequency, a_EndX * FirstOctave.m_Frequency, - a_StartY * FirstOctave.m_Frequency, a_EndY * FirstOctave.m_Frequency - ); - NOISE_DATATYPE Amplitude = FirstOctave.m_Amplitude; - for (int i = 0; i < ArrayCount; i++) - { - a_Array[i] = fabs(a_Workspace[i] * Amplitude); - } - - // Add each octave: - for (cOctaves::const_iterator itr = m_Octaves.begin() + 1, end = m_Octaves.end(); itr != end; ++itr) - { - // Generate cubic noise for the octave: - itr->m_Noise.Generate2D( - a_Workspace, a_SizeX, a_SizeY, - a_StartX * itr->m_Frequency, a_EndX * itr->m_Frequency, - a_StartY * itr->m_Frequency, a_EndY * itr->m_Frequency - ); - // Add the cubic noise into the output: - NOISE_DATATYPE Amplitude = itr->m_Amplitude; - for (int i = 0; i < ArrayCount; i++) - { - a_Array[i] += fabs(a_Workspace[i] * Amplitude); - } - } - - if (ShouldFreeWorkspace) - { - delete[] a_Workspace; - a_Workspace = nullptr; - } -} - - - - - -void cRidgedMultiNoise::Generate3D( - NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y + a_SizeX * a_SizeY * z] - int a_SizeX, int a_SizeY, int a_SizeZ, ///< Count of the array, in each direction - NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction - NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction - NOISE_DATATYPE a_StartZ, NOISE_DATATYPE a_EndZ, ///< Noise-space coords of the array in the Z direction - NOISE_DATATYPE * a_Workspace ///< Workspace that this function can use and trash -) const -{ - if (m_Octaves.empty()) - { - // No work to be done - ASSERT(!"RidgedMulti: No octaves to generate!"); - return; - } - - bool ShouldFreeWorkspace = (a_Workspace == nullptr); - int ArrayCount = a_SizeX * a_SizeY * a_SizeZ; - if (ShouldFreeWorkspace) - { - a_Workspace = new NOISE_DATATYPE[ArrayCount]; - } - - // Generate the first octave directly into array: - const cOctave & FirstOctave = m_Octaves.front(); - - FirstOctave.m_Noise.Generate3D( - a_Workspace, a_SizeX, a_SizeY, a_SizeZ, - a_StartX * FirstOctave.m_Frequency, a_EndX * FirstOctave.m_Frequency, - a_StartY * FirstOctave.m_Frequency, a_EndY * FirstOctave.m_Frequency, - a_StartZ * FirstOctave.m_Frequency, a_EndZ * FirstOctave.m_Frequency - ); - NOISE_DATATYPE Amplitude = FirstOctave.m_Amplitude; - for (int i = 0; i < ArrayCount; i++) - { - a_Array[i] = a_Workspace[i] * Amplitude; - } - - // Add each octave: - for (cOctaves::const_iterator itr = m_Octaves.begin() + 1, end = m_Octaves.end(); itr != end; ++itr) - { - // Generate cubic noise for the octave: - itr->m_Noise.Generate3D( - a_Workspace, a_SizeX, a_SizeY, a_SizeZ, - a_StartX * itr->m_Frequency, a_EndX * itr->m_Frequency, - a_StartY * itr->m_Frequency, a_EndY * itr->m_Frequency, - a_StartZ * itr->m_Frequency, a_EndZ * itr->m_Frequency - ); - // Add the cubic noise into the output: - NOISE_DATATYPE Amplitude = itr->m_Amplitude; - for (int i = 0; i < ArrayCount; i++) - { - a_Array[i] += a_Workspace[i] * Amplitude; - } - } - - if (ShouldFreeWorkspace) - { - delete[] a_Workspace; - a_Workspace = nullptr; - } -} - - - - diff --git a/src/Noise.h b/src/Noise.h index 8b9ee2f3b..e616155d5 100644 --- a/src/Noise.h +++ b/src/Noise.h @@ -11,6 +11,7 @@ typedef float NOISE_DATATYPE; #include "OctavedNoise.h" +#include "RidgedNoise.h" @@ -186,70 +187,7 @@ protected: typedef cOctavedNoise cPerlinNoise; - - - - - -class cRidgedMultiNoise -{ -public: - cRidgedMultiNoise(void); - cRidgedMultiNoise(int a_Seed); - - - void SetSeed(int a_Seed); - - void AddOctave(NOISE_DATATYPE a_Frequency, NOISE_DATATYPE a_Amplitude); - - void Generate1D( - NOISE_DATATYPE * a_Array, ///< Array to generate into - int a_SizeX, ///< Count of the array - NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array - NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash - ) const; - - - void Generate2D( - NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y] - int a_SizeX, int a_SizeY, ///< Count of the array, in each direction - NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction - NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction - NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash - ) const; - - - void Generate3D( - NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y + a_SizeX * a_SizeY * z] - int a_SizeX, int a_SizeY, int a_SizeZ, ///< Count of the array, in each direction - NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction - NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction - NOISE_DATATYPE a_StartZ, NOISE_DATATYPE a_EndZ, ///< Noise-space coords of the array in the Z direction - NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash - ) const; - -protected: - class cOctave - { - public: - cCubicNoise m_Noise; - - NOISE_DATATYPE m_Frequency; // Coord multiplier - NOISE_DATATYPE m_Amplitude; // Value multiplier - - cOctave(int a_Seed, NOISE_DATATYPE a_Frequency, NOISE_DATATYPE a_Amplitude) : - m_Noise(a_Seed), - m_Frequency(a_Frequency), - m_Amplitude(a_Amplitude) - { - } - } ; - - typedef std::vector cOctaves; - - int m_Seed; - cOctaves m_Octaves; -} ; +typedef cOctavedNoise> cRidgedMultiNoise; diff --git a/src/OctavedNoise.h b/src/OctavedNoise.h index 272a1051e..166d2c205 100644 --- a/src/OctavedNoise.h +++ b/src/OctavedNoise.h @@ -32,7 +32,7 @@ public: oct->SetSeed(a_Seed); } } - + /** */ void AddOctave(NOISE_DATATYPE a_Frequency, NOISE_DATATYPE a_Amplitude) @@ -56,7 +56,7 @@ public: ASSERT(!"Perlin: No octaves to generate!"); return; } - + // Allocate the workspace on the heap, if it wasn't given: std::unique_ptr workspaceHeap; if (a_Workspace == nullptr) @@ -78,7 +78,7 @@ public: { a_Array[i] = a_Workspace[i] * Amplitude; } - + // Add each octave: for (auto itr = m_Octaves.cbegin() + 1, end = m_Octaves.cend(); itr != end; ++itr) { @@ -96,8 +96,8 @@ public: } } // for itr - m_Octaves[] } - - + + /** Fills a 3D array with the values of the noise. */ void Generate3D( NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y + a_SizeX * a_SizeY * z] @@ -114,7 +114,7 @@ public: ASSERT(!"Perlin: No octaves to generate!"); return; } - + // Allocate the workspace on the heap, if it wasn't given: std::unique_ptr workspaceHeap; if (a_Workspace == nullptr) @@ -137,7 +137,7 @@ public: { a_Array[i] = a_Workspace[i] * Amplitude; } - + // Add each octave: for (auto itr = m_Octaves.cbegin() + 1, end = m_Octaves.cend(); itr != end; ++itr) { @@ -169,7 +169,7 @@ protected: /** Value multiplier. */ NOISE_DATATYPE m_Amplitude; - + cOctave(int a_Seed, NOISE_DATATYPE a_Frequency, NOISE_DATATYPE a_Amplitude) : m_Noise(a_Seed), m_Frequency(a_Frequency), @@ -181,7 +181,7 @@ protected: /** The seed used by the underlying generators. */ - int m_Seed; + int m_Seed; /** The octaves that compose this noise. */ cOctaves m_Octaves; diff --git a/src/RidgedNoise.h b/src/RidgedNoise.h new file mode 100644 index 000000000..69b480f60 --- /dev/null +++ b/src/RidgedNoise.h @@ -0,0 +1,91 @@ + +// RidgedNoise.h + +// Implements the cRidgedNoise template class that generates ridged noise based on another noise provider. + + + + + +#pragma once + + + + + +template +class cRidgedNoise +{ +public: + /** Creates a new instance with the seed set to 0. */ + cRidgedNoise(void): + m_Noise(0) + { + } + + + /** Creates a new instance with the specified seed. */ + cRidgedNoise(int a_Seed): + m_Noise(a_Seed) + { + } + + + /** Sets the seed for the underlying noise. */ + void SetSeed(int a_Seed) + { + m_Noise.SetSeed(a_Seed); + } + + + /** Fills a 2D array with the values of the noise. */ + void Generate2D( + NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y] + int a_SizeX, int a_SizeY, ///< Count of the array, in each direction + NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction + NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY ///< Noise-space coords of the array in the Y direction + ) const + { + int ArrayCount = a_SizeX * a_SizeY; + m_Noise.Generate2D( + a_Array, a_SizeX, a_SizeY, + a_StartX, a_EndX, + a_StartY, a_EndY + ); + for (int i = 0; i < ArrayCount; i++) + { + a_Array[i] = fabs(a_Array[i]); + } + } + + + /** Fills a 3D array with the values of the noise. */ + void Generate3D( + NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y + a_SizeX * a_SizeY * z] + int a_SizeX, int a_SizeY, int a_SizeZ, ///< Count of the array, in each direction + NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction + NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction + NOISE_DATATYPE a_StartZ, NOISE_DATATYPE a_EndZ ///< Noise-space coords of the array in the Z direction + ) const + { + int ArrayCount = a_SizeX * a_SizeY * a_SizeZ; + m_Noise.Generate2D( + a_Array, a_SizeX, a_SizeY, a_SizeZ, + a_StartX, a_EndX, + a_StartY, a_EndY, + a_StartZ, a_EndZ + ); + for (int i = 0; i < ArrayCount; i++) + { + a_Array[i] = fabs(a_Array[i]); + } + } + +protected: + N m_Noise; +} ; + + + + + -- cgit v1.2.3 From 2467d29a4ec63936d0af20ae4d5cfb8e897e75be Mon Sep 17 00:00:00 2001 From: Mattes D Date: Tue, 18 Nov 2014 12:07:08 +0100 Subject: Moved all Noise-related files into a separate folder. --- src/CMakeLists.txt | 13 +- src/Chunk.cpp | 2 +- src/Enchantments.cpp | 2 +- src/Generating/BioGen.h | 2 +- src/Generating/Caves.h | 1 - src/Generating/ChunkDesc.cpp | 2 +- src/Generating/CompoGen.h | 2 +- src/Generating/DistortedHeightmap.h | 1 - src/Generating/EndGen.h | 2 +- src/Generating/FinishGen.cpp | 1 - src/Generating/FinishGen.h | 2 +- src/Generating/GridStructGen.h | 2 +- src/Generating/HeiGen.h | 2 +- src/Generating/MineShafts.h | 1 - src/Generating/Noise3DGenerator.h | 2 +- src/Generating/PieceGenerator.h | 2 +- src/Generating/Ravines.h | 1 - src/Generating/StructGen.h | 2 +- src/Generating/Trees.h | 2 +- src/ItemGrid.cpp | 2 +- src/Noise.cpp | 1053 ----------------------------------- src/Noise.h | 347 ------------ src/Noise/CMakeLists.txt | 21 + src/Noise/Noise.cpp | 1029 ++++++++++++++++++++++++++++++++++ src/Noise/Noise.h | 332 +++++++++++ src/Noise/OctavedNoise.h | 192 +++++++ src/Noise/RidgedNoise.h | 91 +++ src/OctavedNoise.h | 192 ------- src/RidgedNoise.h | 91 --- src/VoronoiMap.h | 2 +- 30 files changed, 1686 insertions(+), 1710 deletions(-) delete mode 100644 src/Noise.cpp delete mode 100644 src/Noise.h create mode 100644 src/Noise/CMakeLists.txt create mode 100644 src/Noise/Noise.cpp create mode 100644 src/Noise/Noise.h create mode 100644 src/Noise/OctavedNoise.h create mode 100644 src/Noise/RidgedNoise.h delete mode 100644 src/OctavedNoise.h delete mode 100644 src/RidgedNoise.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a8dfc394c..9720c9941 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,6 +9,7 @@ include_directories (SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/../lib/polarssl/include set(FOLDERS OSSupport HTTPServer Items Blocks Protocol Generating PolarSSL++ Bindings WorldStorage Mobs Entities Simulator UI BlockEntities Generating/Prefabs + Noise ) SET (SRCS @@ -50,7 +51,6 @@ SET (SRCS MobProximityCounter.cpp MobSpawner.cpp MonsterConfig.cpp - Noise.cpp ProbabDistrib.cpp RankManager.cpp RCONServer.cpp @@ -65,7 +65,8 @@ SET (SRCS VoronoiMap.cpp WebAdmin.cpp World.cpp - main.cpp) + main.cpp +) SET (HDRS AllocationPool.h @@ -120,11 +121,8 @@ SET (HDRS MobProximityCounter.h MobSpawner.h MonsterConfig.h - Noise.h - OctavedNoise.h ProbabDistrib.h RankManager.h - RidgedNoise.h RCONServer.h Root.h Scoreboard.h @@ -139,7 +137,8 @@ SET (HDRS VoronoiMap.h WebAdmin.h World.h - XMLParser.h) + XMLParser.h +) include_directories(".") include_directories ("${CMAKE_CURRENT_SOURCE_DIR}/../lib/sqlite") @@ -316,7 +315,7 @@ endif () if (NOT MSVC) target_link_libraries(${EXECUTABLE} - OSSupport HTTPServer Bindings Items Blocks + OSSupport HTTPServer Bindings Items Blocks Noise Protocol Generating Generating_Prefabs WorldStorage Mobs Entities Simulator UI BlockEntities PolarSSL++ ) diff --git a/src/Chunk.cpp b/src/Chunk.cpp index a0224322a..d9333afc7 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -25,7 +25,7 @@ #include "BlockEntities/FlowerPotEntity.h" #include "Entities/Pickup.h" #include "Item.h" -#include "Noise.h" +#include "Noise/Noise.h" #include "Root.h" #include "MersenneTwister.h" #include "Entities/Player.h" diff --git a/src/Enchantments.cpp b/src/Enchantments.cpp index 80a9810b6..36c451b81 100644 --- a/src/Enchantments.cpp +++ b/src/Enchantments.cpp @@ -6,7 +6,7 @@ #include "Enchantments.h" #include "WorldStorage/FastNBT.h" #include "FastRandom.h" -#include "Noise.h" +#include "Noise/Noise.h" diff --git a/src/Generating/BioGen.h b/src/Generating/BioGen.h index 5fd0844d9..13fb40c5f 100644 --- a/src/Generating/BioGen.h +++ b/src/Generating/BioGen.h @@ -15,7 +15,7 @@ Interfaces to the various biome generators: #pragma once #include "ComposableGenerator.h" -#include "../Noise.h" +#include "../Noise/Noise.h" #include "../VoronoiMap.h" diff --git a/src/Generating/Caves.h b/src/Generating/Caves.h index 0e17acf9e..691ef3e62 100644 --- a/src/Generating/Caves.h +++ b/src/Generating/Caves.h @@ -13,7 +13,6 @@ #pragma once #include "GridStructGen.h" -#include "../Noise.h" diff --git a/src/Generating/ChunkDesc.cpp b/src/Generating/ChunkDesc.cpp index 020d3bd0f..042b688b7 100644 --- a/src/Generating/ChunkDesc.cpp +++ b/src/Generating/ChunkDesc.cpp @@ -7,7 +7,7 @@ #include "ChunkDesc.h" #include "../BlockArea.h" #include "../Cuboid.h" -#include "../Noise.h" +#include "../Noise/Noise.h" #include "../BlockEntities/BlockEntity.h" diff --git a/src/Generating/CompoGen.h b/src/Generating/CompoGen.h index b145b6ba3..c65a07fe8 100644 --- a/src/Generating/CompoGen.h +++ b/src/Generating/CompoGen.h @@ -17,7 +17,7 @@ #pragma once #include "ComposableGenerator.h" -#include "../Noise.h" +#include "../Noise/Noise.h" diff --git a/src/Generating/DistortedHeightmap.h b/src/Generating/DistortedHeightmap.h index d073f29e4..955e57a1e 100644 --- a/src/Generating/DistortedHeightmap.h +++ b/src/Generating/DistortedHeightmap.h @@ -11,7 +11,6 @@ #include "ComposableGenerator.h" #include "HeiGen.h" -#include "../Noise.h" diff --git a/src/Generating/EndGen.h b/src/Generating/EndGen.h index 322061810..c2278c1e1 100644 --- a/src/Generating/EndGen.h +++ b/src/Generating/EndGen.h @@ -10,7 +10,7 @@ #pragma once #include "ComposableGenerator.h" -#include "../Noise.h" +#include "../Noise/Noise.h" diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index b8afac09a..42ecdf8a8 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -10,7 +10,6 @@ #include "Globals.h" #include "FinishGen.h" -#include "../Noise.h" #include "../BlockID.h" #include "../Simulator/FluidSimulator.h" // for cFluidSimulator::CanWashAway() #include "../Simulator/FireSimulator.h" diff --git a/src/Generating/FinishGen.h b/src/Generating/FinishGen.h index 4a08d70c8..991a85787 100644 --- a/src/Generating/FinishGen.h +++ b/src/Generating/FinishGen.h @@ -16,7 +16,7 @@ #include "ComposableGenerator.h" -#include "../Noise.h" +#include "../Noise/Noise.h" #include "../ProbabDistrib.h" diff --git a/src/Generating/GridStructGen.h b/src/Generating/GridStructGen.h index 03131fce9..b92fb2e9d 100644 --- a/src/Generating/GridStructGen.h +++ b/src/Generating/GridStructGen.h @@ -10,7 +10,7 @@ #pragma once #include "ComposableGenerator.h" -#include "../Noise.h" +#include "../Noise/Noise.h" diff --git a/src/Generating/HeiGen.h b/src/Generating/HeiGen.h index 6ae5ba362..b3c9483fb 100644 --- a/src/Generating/HeiGen.h +++ b/src/Generating/HeiGen.h @@ -15,7 +15,7 @@ Interfaces to the various height generators: #pragma once #include "ComposableGenerator.h" -#include "../Noise.h" +#include "../Noise/Noise.h" diff --git a/src/Generating/MineShafts.h b/src/Generating/MineShafts.h index 2850db571..efb11cfee 100644 --- a/src/Generating/MineShafts.h +++ b/src/Generating/MineShafts.h @@ -10,7 +10,6 @@ #pragma once #include "GridStructGen.h" -#include "../Noise.h" diff --git a/src/Generating/Noise3DGenerator.h b/src/Generating/Noise3DGenerator.h index 92cfc32b7..8a6e97e1c 100644 --- a/src/Generating/Noise3DGenerator.h +++ b/src/Generating/Noise3DGenerator.h @@ -13,7 +13,7 @@ #pragma once #include "ComposableGenerator.h" -#include "../Noise.h" +#include "../Noise/Noise.h" diff --git a/src/Generating/PieceGenerator.h b/src/Generating/PieceGenerator.h index f06029280..43ffed7a2 100644 --- a/src/Generating/PieceGenerator.h +++ b/src/Generating/PieceGenerator.h @@ -20,7 +20,7 @@ Each uses a slightly different approach to generating: #include "../Defines.h" #include "../Cuboid.h" -#include "../Noise.h" +#include "../Noise/Noise.h" diff --git a/src/Generating/Ravines.h b/src/Generating/Ravines.h index 3e41c5ce6..b11037433 100644 --- a/src/Generating/Ravines.h +++ b/src/Generating/Ravines.h @@ -10,7 +10,6 @@ #pragma once #include "GridStructGen.h" -#include "../Noise.h" diff --git a/src/Generating/StructGen.h b/src/Generating/StructGen.h index 906fdd722..d3b0b5544 100644 --- a/src/Generating/StructGen.h +++ b/src/Generating/StructGen.h @@ -14,7 +14,7 @@ #pragma once #include "ComposableGenerator.h" -#include "../Noise.h" +#include "../Noise/Noise.h" diff --git a/src/Generating/Trees.h b/src/Generating/Trees.h index c9eb7de80..cc0fa87d9 100644 --- a/src/Generating/Trees.h +++ b/src/Generating/Trees.h @@ -18,7 +18,7 @@ logs can overwrite others(leaves), but others shouldn't overwrite logs. This is #pragma once #include "../ChunkDef.h" -#include "../Noise.h" +#include "../Noise/Noise.h" diff --git a/src/ItemGrid.cpp b/src/ItemGrid.cpp index 55fb36a17..d49ea9df1 100644 --- a/src/ItemGrid.cpp +++ b/src/ItemGrid.cpp @@ -6,7 +6,7 @@ #include "Globals.h" #include "ItemGrid.h" #include "Items/ItemHandler.h" -#include "Noise.h" +#include "Noise/Noise.h" diff --git a/src/Noise.cpp b/src/Noise.cpp deleted file mode 100644 index c4a7e2d5f..000000000 --- a/src/Noise.cpp +++ /dev/null @@ -1,1053 +0,0 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "Noise.h" -#include "OSSupport/Timer.h" - -#define FAST_FLOOR(x) (((x) < 0) ? (((int)x) - 1) : ((int)x)) - - - - - -#if 0 -/** cImprovedPerlin noise test suite: -- Generate a rather large 2D and 3D noise array and output it to a file -- Compare performance of cCubicNoise and cImprovedNoise, both in single-value and 3D-array usages */ -static class cImprovedPerlinNoiseTest -{ -public: - cImprovedPerlinNoiseTest(void) - { - printf("Performing Improved Perlin Noise tests...\n"); - TestImage(); - TestSpeed(); - TestSpeedArr(); - printf("Improved Perlin Noise tests complete.\n"); - } - - - /** Tests the noise by generating 2D and 3D images and dumping them to files. */ - void TestImage(void) - { - static const int SIZE_X = 256; - static const int SIZE_Y = 256; - static const int SIZE_Z = 16; - - cImprovedNoise noise(1); - std::unique_ptr arr(new NOISE_DATATYPE[SIZE_X * SIZE_Y * SIZE_Z]); - noise.Generate3D(arr.get(), SIZE_X, SIZE_Y, SIZE_Z, 0, 14, 0, 14, 0, 14); - Debug3DNoise(arr.get(), SIZE_X, SIZE_Y, SIZE_Z, "ImprovedPerlinNoiseTest3D", 128); - noise.Generate2D(arr.get(), SIZE_X, SIZE_Y, 0, 14, 15, 28); - Debug2DNoise(arr.get(), SIZE_X, SIZE_Y, "ImprovedPerlinNoiseTest2D", 128); - } - - - /** Tests the speeds of cImprovedPerlin and cCubicNoise when generating individual values. */ - void TestSpeed(void) - { - cImprovedNoise improvedNoise(1); - cNoise noise(1); - cTimer timer; - - // Measure the improvedNoise: - NOISE_DATATYPE sum = 0; - long long start = timer.GetNowTime(); - for (int i = 0; i < 100000000; i++) - { - sum += improvedNoise.GetValueAt(i, 0, -i); - } - long long finish = timer.GetNowTime(); - printf("cImprovedNoise took %.2f seconds; total is %f.\n", static_cast(finish - start) / 1000.0f, sum); - - // Measure the cubicNoise: - sum = 0; - start = timer.GetNowTime(); - for (int i = 0; i < 100000000; i++) - { - sum += noise.IntNoise3D(i, 0, -i); - } - finish = timer.GetNowTime(); - printf("cCubicNoise took %.2f seconds; total is %f.\n", static_cast(finish - start) / 1000.0f, sum); - } - - - /** Tests the speeds of cImprovedPerlin and cCubicNoise when generating arrays. */ - void TestSpeedArr(void) - { - static const int SIZE_X = 256; - static const int SIZE_Y = 256; - static const int SIZE_Z = 16; - - std::unique_ptr arr(new NOISE_DATATYPE[SIZE_X * SIZE_Y * SIZE_Z]); - cTimer timer; - cImprovedNoise improvedNoise(1); - cCubicNoise cubicNoise(1); - - // Measure the improvedNoise: - long long start = timer.GetNowTime(); - for (int i = 0; i < 40; i++) - { - improvedNoise.Generate3D(arr.get(), SIZE_X, SIZE_Y, SIZE_Z, 0, 14, 0, 14, 0, 14); - } - long long finish = timer.GetNowTime(); - printf("cImprovedNoise(arr) took %.2f seconds.\n", static_cast(finish - start) / 1000.0f); - - // Measure the cubicNoise: - start = timer.GetNowTime(); - for (int i = 0; i < 40; i++) - { - cubicNoise.Generate3D(arr.get(), SIZE_X, SIZE_Y, SIZE_Z, 0, 14, 0, 14, 0, 14); - } - finish = timer.GetNowTime(); - printf("cCubicNoise(arr) took %.2f seconds.\n", static_cast(finish - start) / 1000.0f); - } -} g_Test; - -#endif - - - - - -//////////////////////////////////////////////////////////////////////////////// -// Globals: - -void Debug3DNoise(const NOISE_DATATYPE * a_Noise, int a_SizeX, int a_SizeY, int a_SizeZ, const AString & a_FileNameBase, NOISE_DATATYPE a_Coeff) -{ - const int BUF_SIZE = 512; - ASSERT(a_SizeX <= BUF_SIZE); // Just stretch it, if needed - - // Save in XY cuts: - cFile f1; - if (f1.Open(Printf("%s_XY (%d).grab", a_FileNameBase.c_str(), a_SizeX), cFile::fmWrite)) - { - for (int z = 0; z < a_SizeZ; z++) - { - for (int y = 0; y < a_SizeY; y++) - { - int idx = y * a_SizeX + z * a_SizeX * a_SizeY; - unsigned char buf[BUF_SIZE]; - for (int x = 0; x < a_SizeX; x++) - { - buf[x] = static_cast(Clamp((int)(128 + a_Coeff * a_Noise[idx++]), 0, 255)); - } - f1.Write(buf, a_SizeX); - } // for y - unsigned char buf[BUF_SIZE]; - memset(buf, 0, a_SizeX); - f1.Write(buf, a_SizeX); - } // for z - } // if (XY file open) - - cFile f2; - if (f2.Open(Printf("%s_XZ (%d).grab", a_FileNameBase.c_str(), a_SizeX), cFile::fmWrite)) - { - for (int y = 0; y < a_SizeY; y++) - { - for (int z = 0; z < a_SizeZ; z++) - { - int idx = y * a_SizeX + z * a_SizeX * a_SizeY; - unsigned char buf[BUF_SIZE]; - for (int x = 0; x < a_SizeX; x++) - { - buf[x] = static_cast(Clamp((int)(128 + a_Coeff * a_Noise[idx++]), 0, 255)); - } - f2.Write(buf, a_SizeX); - } // for z - unsigned char buf[BUF_SIZE]; - memset(buf, 0, a_SizeX); - f2.Write(buf, a_SizeX); - } // for y - } // if (XZ file open) -} - - - - - -void Debug2DNoise(const NOISE_DATATYPE * a_Noise, int a_SizeX, int a_SizeY, const AString & a_FileNameBase, NOISE_DATATYPE a_Coeff) -{ - const int BUF_SIZE = 512; - ASSERT(a_SizeX <= BUF_SIZE); // Just stretch it, if needed - - cFile f1; - if (f1.Open(Printf("%s (%d).grab", a_FileNameBase.c_str(), a_SizeX), cFile::fmWrite)) - { - for (int y = 0; y < a_SizeY; y++) - { - int idx = y * a_SizeX; - unsigned char buf[BUF_SIZE]; - for (int x = 0; x < a_SizeX; x++) - { - buf[x] = static_cast(Clamp((int)(128 + a_Coeff * a_Noise[idx++]), 0, 255)); - } - f1.Write(buf, a_SizeX); - } // for y - } // if (file open) -} - - - - - -//////////////////////////////////////////////////////////////////////////////// -// cCubicCell2D: - -class cCubicCell2D -{ -public: - cCubicCell2D( - const cNoise & a_Noise, ///< Noise to use for generating the random values - NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y] - int a_SizeX, int a_SizeY, ///< Count of the array, in each direction - const NOISE_DATATYPE * a_FracX, ///< Pointer to the array that stores the X fractional values - const NOISE_DATATYPE * a_FracY ///< Pointer to the attay that stores the Y fractional values - ); - - /// Uses current m_WorkRnds[] to generate part of the array - void Generate( - int a_FromX, int a_ToX, - int a_FromY, int a_ToY - ); - - /// Initializes m_WorkRnds[] with the specified Floor values - void InitWorkRnds(int a_FloorX, int a_FloorY); - - /// Updates m_WorkRnds[] for the new Floor values. - void Move(int a_NewFloorX, int a_NewFloorY); - -protected: - typedef NOISE_DATATYPE Workspace[4][4]; - - const cNoise & m_Noise; - - Workspace * m_WorkRnds; ///< The current random values; points to either m_Workspace1 or m_Workspace2 (doublebuffering) - Workspace m_Workspace1; ///< Buffer 1 for workspace doublebuffering, used in Move() - Workspace m_Workspace2; ///< Buffer 2 for workspace doublebuffering, used in Move() - int m_CurFloorX; - int m_CurFloorY; - - NOISE_DATATYPE * m_Array; - int m_SizeX, m_SizeY; - const NOISE_DATATYPE * m_FracX; - const NOISE_DATATYPE * m_FracY; -} ; - - - - - -cCubicCell2D::cCubicCell2D( - const cNoise & a_Noise, ///< Noise to use for generating the random values - NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y] - int a_SizeX, int a_SizeY, ///< Count of the array, in each direction - const NOISE_DATATYPE * a_FracX, ///< Pointer to the array that stores the X fractional values - const NOISE_DATATYPE * a_FracY ///< Pointer to the attay that stores the Y fractional values -) : - m_Noise(a_Noise), - m_WorkRnds(&m_Workspace1), - m_CurFloorX(0), - m_CurFloorY(0), - m_Array(a_Array), - m_SizeX(a_SizeX), - m_SizeY(a_SizeY), - m_FracX(a_FracX), - m_FracY(a_FracY) -{ -} - - - - - -void cCubicCell2D::Generate( - int a_FromX, int a_ToX, - int a_FromY, int a_ToY -) -{ - for (int y = a_FromY; y < a_ToY; y++) - { - NOISE_DATATYPE Interp[4]; - NOISE_DATATYPE FracY = m_FracY[y]; - Interp[0] = cNoise::CubicInterpolate((*m_WorkRnds)[0][0], (*m_WorkRnds)[0][1], (*m_WorkRnds)[0][2], (*m_WorkRnds)[0][3], FracY); - Interp[1] = cNoise::CubicInterpolate((*m_WorkRnds)[1][0], (*m_WorkRnds)[1][1], (*m_WorkRnds)[1][2], (*m_WorkRnds)[1][3], FracY); - Interp[2] = cNoise::CubicInterpolate((*m_WorkRnds)[2][0], (*m_WorkRnds)[2][1], (*m_WorkRnds)[2][2], (*m_WorkRnds)[2][3], FracY); - Interp[3] = cNoise::CubicInterpolate((*m_WorkRnds)[3][0], (*m_WorkRnds)[3][1], (*m_WorkRnds)[3][2], (*m_WorkRnds)[3][3], FracY); - int idx = y * m_SizeX + a_FromX; - for (int x = a_FromX; x < a_ToX; x++) - { - m_Array[idx++] = cNoise::CubicInterpolate(Interp[0], Interp[1], Interp[2], Interp[3], m_FracX[x]); - } // for x - } // for y -} - - - - - -void cCubicCell2D::InitWorkRnds(int a_FloorX, int a_FloorY) -{ - m_CurFloorX = a_FloorX; - m_CurFloorY = a_FloorY; - for (int x = 0; x < 4; x++) - { - int cx = a_FloorX + x - 1; - for (int y = 0; y < 4; y++) - { - int cy = a_FloorY + y - 1; - (*m_WorkRnds)[x][y] = (NOISE_DATATYPE)m_Noise.IntNoise2D(cx, cy); - } - } -} - - - - - -void cCubicCell2D::Move(int a_NewFloorX, int a_NewFloorY) -{ - // Swap the doublebuffer: - int OldFloorX = m_CurFloorX; - int OldFloorY = m_CurFloorY; - Workspace * OldWorkRnds = m_WorkRnds; - m_WorkRnds = (m_WorkRnds == &m_Workspace1) ? &m_Workspace2 : &m_Workspace1; - - // Reuse as much of the old workspace as possible: - int DiffX = OldFloorX - a_NewFloorX; - int DiffY = OldFloorY - a_NewFloorY; - for (int x = 0; x < 4; x++) - { - int cx = a_NewFloorX + x - 1; - int OldX = x - DiffX; // Where would this X be in the old grid? - for (int y = 0; y < 4; y++) - { - int cy = a_NewFloorY + y - 1; - int OldY = y - DiffY; // Where would this Y be in the old grid? - if ((OldX >= 0) && (OldX < 4) && (OldY >= 0) && (OldY < 4)) - { - (*m_WorkRnds)[x][y] = (*OldWorkRnds)[OldX][OldY]; - } - else - { - (*m_WorkRnds)[x][y] = (NOISE_DATATYPE)m_Noise.IntNoise2D(cx, cy); - } - } - } - m_CurFloorX = a_NewFloorX; - m_CurFloorY = a_NewFloorY; -} - - - - - -//////////////////////////////////////////////////////////////////////////////// -// cCubicCell3D: - -class cCubicCell3D -{ -public: - cCubicCell3D( - const cNoise & a_Noise, ///< Noise to use for generating the random values - NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y] - int a_SizeX, int a_SizeY, int a_SizeZ, ///< Count of the array, in each direction - const NOISE_DATATYPE * a_FracX, ///< Pointer to the array that stores the X fractional values - const NOISE_DATATYPE * a_FracY, ///< Pointer to the attay that stores the Y fractional values - const NOISE_DATATYPE * a_FracZ ///< Pointer to the array that stores the Z fractional values - ); - - /// Uses current m_WorkRnds[] to generate part of the array - void Generate( - int a_FromX, int a_ToX, - int a_FromY, int a_ToY, - int a_FromZ, int a_ToZ - ); - - /// Initializes m_WorkRnds[] with the specified Floor values - void InitWorkRnds(int a_FloorX, int a_FloorY, int a_FloorZ); - - /// Updates m_WorkRnds[] for the new Floor values. - void Move(int a_NewFloorX, int a_NewFloorY, int a_NewFloorZ); - -protected: - typedef NOISE_DATATYPE Workspace[4][4][4]; - - const cNoise & m_Noise; - - Workspace * m_WorkRnds; ///< The current random values; points to either m_Workspace1 or m_Workspace2 (doublebuffering) - Workspace m_Workspace1; ///< Buffer 1 for workspace doublebuffering, used in Move() - Workspace m_Workspace2; ///< Buffer 2 for workspace doublebuffering, used in Move() - int m_CurFloorX; - int m_CurFloorY; - int m_CurFloorZ; - - NOISE_DATATYPE * m_Array; - int m_SizeX, m_SizeY, m_SizeZ; - const NOISE_DATATYPE * m_FracX; - const NOISE_DATATYPE * m_FracY; - const NOISE_DATATYPE * m_FracZ; -} ; - - - - - -cCubicCell3D::cCubicCell3D( - const cNoise & a_Noise, ///< Noise to use for generating the random values - NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y] - int a_SizeX, int a_SizeY, int a_SizeZ, ///< Count of the array, in each direction - const NOISE_DATATYPE * a_FracX, ///< Pointer to the array that stores the X fractional values - const NOISE_DATATYPE * a_FracY, ///< Pointer to the attay that stores the Y fractional values - const NOISE_DATATYPE * a_FracZ ///< Pointer to the array that stores the Z fractional values -) : - m_Noise(a_Noise), - m_WorkRnds(&m_Workspace1), - m_CurFloorX(0), - m_CurFloorY(0), - m_CurFloorZ(0), - m_Array(a_Array), - m_SizeX(a_SizeX), - m_SizeY(a_SizeY), - m_SizeZ(a_SizeZ), - m_FracX(a_FracX), - m_FracY(a_FracY), - m_FracZ(a_FracZ) -{ -} - - - - - -void cCubicCell3D::Generate( - int a_FromX, int a_ToX, - int a_FromY, int a_ToY, - int a_FromZ, int a_ToZ -) -{ - for (int z = a_FromZ; z < a_ToZ; z++) - { - int idxZ = z * m_SizeX * m_SizeY; - NOISE_DATATYPE Interp2[4][4]; - NOISE_DATATYPE FracZ = m_FracZ[z]; - for (int x = 0; x < 4; x++) - { - for (int y = 0; y < 4; y++) - { - Interp2[x][y] = cNoise::CubicInterpolate((*m_WorkRnds)[x][y][0], (*m_WorkRnds)[x][y][1], (*m_WorkRnds)[x][y][2], (*m_WorkRnds)[x][y][3], FracZ); - } - } - for (int y = a_FromY; y < a_ToY; y++) - { - NOISE_DATATYPE Interp[4]; - NOISE_DATATYPE FracY = m_FracY[y]; - Interp[0] = cNoise::CubicInterpolate(Interp2[0][0], Interp2[0][1], Interp2[0][2], Interp2[0][3], FracY); - Interp[1] = cNoise::CubicInterpolate(Interp2[1][0], Interp2[1][1], Interp2[1][2], Interp2[1][3], FracY); - Interp[2] = cNoise::CubicInterpolate(Interp2[2][0], Interp2[2][1], Interp2[2][2], Interp2[2][3], FracY); - Interp[3] = cNoise::CubicInterpolate(Interp2[3][0], Interp2[3][1], Interp2[3][2], Interp2[3][3], FracY); - int idx = idxZ + y * m_SizeX + a_FromX; - for (int x = a_FromX; x < a_ToX; x++) - { - m_Array[idx++] = cNoise::CubicInterpolate(Interp[0], Interp[1], Interp[2], Interp[3], m_FracX[x]); - } // for x - } // for y - } // for z -} - - - - - -void cCubicCell3D::InitWorkRnds(int a_FloorX, int a_FloorY, int a_FloorZ) -{ - m_CurFloorX = a_FloorX; - m_CurFloorY = a_FloorY; - m_CurFloorZ = a_FloorZ; - for (int x = 0; x < 4; x++) - { - int cx = a_FloorX + x - 1; - for (int y = 0; y < 4; y++) - { - int cy = a_FloorY + y - 1; - for (int z = 0; z < 4; z++) - { - int cz = a_FloorZ + z - 1; - (*m_WorkRnds)[x][y][z] = (NOISE_DATATYPE)m_Noise.IntNoise3D(cx, cy, cz); - } - } - } -} - - - - - -void cCubicCell3D::Move(int a_NewFloorX, int a_NewFloorY, int a_NewFloorZ) -{ - // Swap the doublebuffer: - int OldFloorX = m_CurFloorX; - int OldFloorY = m_CurFloorY; - int OldFloorZ = m_CurFloorZ; - Workspace * OldWorkRnds = m_WorkRnds; - m_WorkRnds = (m_WorkRnds == &m_Workspace1) ? &m_Workspace2 : &m_Workspace1; - - // Reuse as much of the old workspace as possible: - int DiffX = OldFloorX - a_NewFloorX; - int DiffY = OldFloorY - a_NewFloorY; - int DiffZ = OldFloorZ - a_NewFloorZ; - for (int x = 0; x < 4; x++) - { - int cx = a_NewFloorX + x - 1; - int OldX = x - DiffX; // Where would this X be in the old grid? - for (int y = 0; y < 4; y++) - { - int cy = a_NewFloorY + y - 1; - int OldY = y - DiffY; // Where would this Y be in the old grid? - for (int z = 0; z < 4; z++) - { - int cz = a_NewFloorZ + z - 1; - int OldZ = z - DiffZ; - if ((OldX >= 0) && (OldX < 4) && (OldY >= 0) && (OldY < 4) && (OldZ >= 0) && (OldZ < 4)) - { - (*m_WorkRnds)[x][y][z] = (*OldWorkRnds)[OldX][OldY][OldZ]; - } - else - { - (*m_WorkRnds)[x][y][z] = (NOISE_DATATYPE)m_Noise.IntNoise3D(cx, cy, cz); - } - } // for z - } // for y - } // for x - m_CurFloorX = a_NewFloorX; - m_CurFloorY = a_NewFloorY; - m_CurFloorZ = a_NewFloorZ; -} - - - - - -//////////////////////////////////////////////////////////////////////////////// -// cNoise: - -cNoise::cNoise(int a_Seed) : - m_Seed(a_Seed) -{ -} - - - - - -cNoise::cNoise(const cNoise & a_Noise) : - m_Seed(a_Noise.m_Seed) -{ -} - - - - - -NOISE_DATATYPE cNoise::LinearNoise1D(NOISE_DATATYPE a_X) const -{ - int BaseX = FAST_FLOOR(a_X); - NOISE_DATATYPE FracX = a_X - BaseX; - return LinearInterpolate(IntNoise1D(BaseX), IntNoise1D(BaseX + 1), FracX); -} - - - - - -NOISE_DATATYPE cNoise::CosineNoise1D(NOISE_DATATYPE a_X) const -{ - int BaseX = FAST_FLOOR(a_X); - NOISE_DATATYPE FracX = a_X - BaseX; - return CosineInterpolate(IntNoise1D(BaseX), IntNoise1D(BaseX + 1), FracX); -} - - - - - -NOISE_DATATYPE cNoise::CubicNoise1D(NOISE_DATATYPE a_X) const -{ - int BaseX = FAST_FLOOR(a_X); - NOISE_DATATYPE FracX = a_X - BaseX; - return CubicInterpolate(IntNoise1D(BaseX - 1), IntNoise1D(BaseX), IntNoise1D(BaseX + 1), IntNoise1D(BaseX + 2), FracX); -} - - - - - -NOISE_DATATYPE cNoise::SmoothNoise1D(int a_X) const -{ - return IntNoise1D(a_X) / 2 + IntNoise1D(a_X - 1) / 4 + IntNoise1D(a_X + 1) / 4; -} - - - - - -NOISE_DATATYPE cNoise::CubicNoise2D(NOISE_DATATYPE a_X, NOISE_DATATYPE a_Y) const -{ - const int BaseX = FAST_FLOOR(a_X); - const int BaseY = FAST_FLOOR(a_Y); - - const NOISE_DATATYPE points[4][4] = - { - { IntNoise2D(BaseX - 1, BaseY - 1), IntNoise2D(BaseX, BaseY - 1), IntNoise2D(BaseX + 1, BaseY - 1), IntNoise2D(BaseX + 2, BaseY - 1), }, - { IntNoise2D(BaseX - 1, BaseY), IntNoise2D(BaseX, BaseY), IntNoise2D(BaseX + 1, BaseY), IntNoise2D(BaseX + 2, BaseY), }, - { IntNoise2D(BaseX - 1, BaseY + 1), IntNoise2D(BaseX, BaseY + 1), IntNoise2D(BaseX + 1, BaseY + 1), IntNoise2D(BaseX + 2, BaseY + 1), }, - { IntNoise2D(BaseX - 1, BaseY + 2), IntNoise2D(BaseX, BaseY + 2), IntNoise2D(BaseX + 1, BaseY + 2), IntNoise2D(BaseX + 2, BaseY + 2), }, - }; - - const NOISE_DATATYPE FracX = a_X - BaseX; - const NOISE_DATATYPE interp1 = CubicInterpolate(points[0][0], points[0][1], points[0][2], points[0][3], FracX); - const NOISE_DATATYPE interp2 = CubicInterpolate(points[1][0], points[1][1], points[1][2], points[1][3], FracX); - const NOISE_DATATYPE interp3 = CubicInterpolate(points[2][0], points[2][1], points[2][2], points[2][3], FracX); - const NOISE_DATATYPE interp4 = CubicInterpolate(points[3][0], points[3][1], points[3][2], points[3][3], FracX); - - - const NOISE_DATATYPE FracY = a_Y - BaseY; - return CubicInterpolate(interp1, interp2, interp3, interp4, FracY); -} - - - - - -NOISE_DATATYPE cNoise::CubicNoise3D(NOISE_DATATYPE a_X, NOISE_DATATYPE a_Y, NOISE_DATATYPE a_Z) const -{ - const int BaseX = FAST_FLOOR(a_X); - const int BaseY = FAST_FLOOR(a_Y); - const int BaseZ = FAST_FLOOR(a_Z); - - const NOISE_DATATYPE points1[4][4] = - { - { IntNoise3D(BaseX - 1, BaseY - 1, BaseZ - 1), IntNoise3D(BaseX, BaseY - 1, BaseZ - 1), IntNoise3D(BaseX + 1, BaseY - 1, BaseZ - 1), IntNoise3D(BaseX + 2, BaseY - 1, BaseZ - 1), }, - { IntNoise3D(BaseX - 1, BaseY, BaseZ - 1), IntNoise3D(BaseX, BaseY, BaseZ - 1), IntNoise3D(BaseX + 1, BaseY, BaseZ - 1), IntNoise3D(BaseX + 2, BaseY, BaseZ - 1), }, - { IntNoise3D(BaseX - 1, BaseY + 1, BaseZ - 1), IntNoise3D(BaseX, BaseY + 1, BaseZ - 1), IntNoise3D(BaseX + 1, BaseY + 1, BaseZ - 1), IntNoise3D(BaseX + 2, BaseY + 1, BaseZ - 1), }, - { IntNoise3D(BaseX - 1, BaseY + 2, BaseZ - 1), IntNoise3D(BaseX, BaseY + 2, BaseZ - 1), IntNoise3D(BaseX + 1, BaseY + 2, BaseZ - 1), IntNoise3D(BaseX + 2, BaseY + 2, BaseZ - 1), }, - }; - - const NOISE_DATATYPE FracX = (a_X) - BaseX; - const NOISE_DATATYPE x1interp1 = CubicInterpolate( points1[0][0], points1[0][1], points1[0][2], points1[0][3], FracX); - const NOISE_DATATYPE x1interp2 = CubicInterpolate( points1[1][0], points1[1][1], points1[1][2], points1[1][3], FracX); - const NOISE_DATATYPE x1interp3 = CubicInterpolate( points1[2][0], points1[2][1], points1[2][2], points1[2][3], FracX); - const NOISE_DATATYPE x1interp4 = CubicInterpolate( points1[3][0], points1[3][1], points1[3][2], points1[3][3], FracX); - - const NOISE_DATATYPE points2[4][4] = - { - { IntNoise3D(BaseX - 1, BaseY - 1, BaseZ), IntNoise3D(BaseX, BaseY - 1, BaseZ), IntNoise3D(BaseX + 1, BaseY - 1, BaseZ), IntNoise3D(BaseX + 2, BaseY - 1, BaseZ), }, - { IntNoise3D(BaseX - 1, BaseY, BaseZ), IntNoise3D(BaseX, BaseY, BaseZ), IntNoise3D(BaseX + 1, BaseY, BaseZ), IntNoise3D(BaseX + 2, BaseY, BaseZ), }, - { IntNoise3D(BaseX - 1, BaseY + 1, BaseZ), IntNoise3D(BaseX, BaseY + 1, BaseZ), IntNoise3D(BaseX + 1, BaseY + 1, BaseZ), IntNoise3D(BaseX + 2, BaseY + 1, BaseZ), }, - { IntNoise3D(BaseX - 1, BaseY + 2, BaseZ), IntNoise3D(BaseX, BaseY + 2, BaseZ), IntNoise3D(BaseX + 1, BaseY + 2, BaseZ), IntNoise3D(BaseX + 2, BaseY + 2, BaseZ), }, - }; - - const NOISE_DATATYPE x2interp1 = CubicInterpolate( points2[0][0], points2[0][1], points2[0][2], points2[0][3], FracX); - const NOISE_DATATYPE x2interp2 = CubicInterpolate( points2[1][0], points2[1][1], points2[1][2], points2[1][3], FracX); - const NOISE_DATATYPE x2interp3 = CubicInterpolate( points2[2][0], points2[2][1], points2[2][2], points2[2][3], FracX); - const NOISE_DATATYPE x2interp4 = CubicInterpolate( points2[3][0], points2[3][1], points2[3][2], points2[3][3], FracX); - - const NOISE_DATATYPE points3[4][4] = - { - { IntNoise3D( BaseX-1, BaseY-1, BaseZ+1), IntNoise3D( BaseX, BaseY-1, BaseZ+1), IntNoise3D( BaseX+1, BaseY-1, BaseZ+1), IntNoise3D( BaseX+2, BaseY-1, BaseZ + 1), }, - { IntNoise3D( BaseX-1, BaseY, BaseZ+1), IntNoise3D( BaseX, BaseY, BaseZ+1), IntNoise3D( BaseX+1, BaseY, BaseZ+1), IntNoise3D( BaseX+2, BaseY, BaseZ + 1), }, - { IntNoise3D( BaseX-1, BaseY+1, BaseZ+1), IntNoise3D( BaseX, BaseY+1, BaseZ+1), IntNoise3D( BaseX+1, BaseY+1, BaseZ+1), IntNoise3D( BaseX+2, BaseY+1, BaseZ + 1), }, - { IntNoise3D( BaseX-1, BaseY+2, BaseZ+1), IntNoise3D( BaseX, BaseY+2, BaseZ+1), IntNoise3D( BaseX+1, BaseY+2, BaseZ+1), IntNoise3D( BaseX+2, BaseY+2, BaseZ + 1), }, - }; - - const NOISE_DATATYPE x3interp1 = CubicInterpolate( points3[0][0], points3[0][1], points3[0][2], points3[0][3], FracX); - const NOISE_DATATYPE x3interp2 = CubicInterpolate( points3[1][0], points3[1][1], points3[1][2], points3[1][3], FracX); - const NOISE_DATATYPE x3interp3 = CubicInterpolate( points3[2][0], points3[2][1], points3[2][2], points3[2][3], FracX); - const NOISE_DATATYPE x3interp4 = CubicInterpolate( points3[3][0], points3[3][1], points3[3][2], points3[3][3], FracX); - - const NOISE_DATATYPE points4[4][4] = - { - { IntNoise3D( BaseX-1, BaseY-1, BaseZ+2), IntNoise3D( BaseX, BaseY-1, BaseZ+2), IntNoise3D( BaseX+1, BaseY-1, BaseZ+2), IntNoise3D( BaseX+2, BaseY-1, BaseZ+2), }, - { IntNoise3D( BaseX-1, BaseY, BaseZ+2), IntNoise3D( BaseX, BaseY, BaseZ+2), IntNoise3D( BaseX+1, BaseY, BaseZ+2), IntNoise3D( BaseX+2, BaseY, BaseZ+2), }, - { IntNoise3D( BaseX-1, BaseY+1, BaseZ+2), IntNoise3D( BaseX, BaseY+1, BaseZ+2), IntNoise3D( BaseX+1, BaseY+1, BaseZ+2), IntNoise3D( BaseX+2, BaseY+1, BaseZ+2), }, - { IntNoise3D( BaseX-1, BaseY+2, BaseZ+2), IntNoise3D( BaseX, BaseY+2, BaseZ+2), IntNoise3D( BaseX+1, BaseY+2, BaseZ+2), IntNoise3D( BaseX+2, BaseY+2, BaseZ+2), }, - }; - - const NOISE_DATATYPE x4interp1 = CubicInterpolate( points4[0][0], points4[0][1], points4[0][2], points4[0][3], FracX); - const NOISE_DATATYPE x4interp2 = CubicInterpolate( points4[1][0], points4[1][1], points4[1][2], points4[1][3], FracX); - const NOISE_DATATYPE x4interp3 = CubicInterpolate( points4[2][0], points4[2][1], points4[2][2], points4[2][3], FracX); - const NOISE_DATATYPE x4interp4 = CubicInterpolate( points4[3][0], points4[3][1], points4[3][2], points4[3][3], FracX); - - const NOISE_DATATYPE FracY = (a_Y) - BaseY; - const NOISE_DATATYPE yinterp1 = CubicInterpolate( x1interp1, x1interp2, x1interp3, x1interp4, FracY); - const NOISE_DATATYPE yinterp2 = CubicInterpolate( x2interp1, x2interp2, x2interp3, x2interp4, FracY); - const NOISE_DATATYPE yinterp3 = CubicInterpolate( x3interp1, x3interp2, x3interp3, x3interp4, FracY); - const NOISE_DATATYPE yinterp4 = CubicInterpolate( x4interp1, x4interp2, x4interp3, x4interp4, FracY); - - const NOISE_DATATYPE FracZ = (a_Z) - BaseZ; - return CubicInterpolate( yinterp1, yinterp2, yinterp3, yinterp4, FracZ); -} - - - - - -//////////////////////////////////////////////////////////////////////////////// -// cCubicNoise: - -#ifdef _DEBUG - int cCubicNoise::m_NumSingleX = 0; - int cCubicNoise::m_NumSingleXY = 0; - int cCubicNoise::m_NumSingleY = 0; - int cCubicNoise::m_NumCalls = 0; -#endif // _DEBUG - -cCubicNoise::cCubicNoise(int a_Seed) : - m_Noise(a_Seed) -{ -} - - - - - -void cCubicNoise::Generate2D( - NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y] - int a_SizeX, int a_SizeY, ///< Size of the array (num doubles), in each direction - NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction - NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY ///< Noise-space coords of the array in the Y direction -) const -{ - ASSERT(a_SizeX > 0); - ASSERT(a_SizeY > 0); - ASSERT(a_SizeX < MAX_SIZE); - ASSERT(a_SizeY < MAX_SIZE); - ASSERT(a_StartX < a_EndX); - ASSERT(a_StartY < a_EndY); - - // Calculate the integral and fractional parts of each coord: - int FloorX[MAX_SIZE]; - int FloorY[MAX_SIZE]; - NOISE_DATATYPE FracX[MAX_SIZE]; - NOISE_DATATYPE FracY[MAX_SIZE]; - int SameX[MAX_SIZE]; - int SameY[MAX_SIZE]; - int NumSameX, NumSameY; - CalcFloorFrac(a_SizeX, a_StartX, a_EndX, FloorX, FracX, SameX, NumSameX); - CalcFloorFrac(a_SizeY, a_StartY, a_EndY, FloorY, FracY, SameY, NumSameY); - - cCubicCell2D Cell(m_Noise, a_Array, a_SizeX, a_SizeY, FracX, FracY); - - Cell.InitWorkRnds(FloorX[0], FloorY[0]); - - #ifdef _DEBUG - // Statistics on the noise-space coords: - if (NumSameX == 1) - { - m_NumSingleX++; - if (NumSameY == 1) - { - m_NumSingleXY++; - } - } - if (NumSameY == 1) - { - m_NumSingleY++; - } - m_NumCalls++; - #endif // _DEBUG - - // Calculate query values using Cell: - int FromY = 0; - for (int y = 0; y < NumSameY; y++) - { - int ToY = FromY + SameY[y]; - int FromX = 0; - int CurFloorY = FloorY[FromY]; - for (int x = 0; x < NumSameX; x++) - { - int ToX = FromX + SameX[x]; - Cell.Generate(FromX, ToX, FromY, ToY); - Cell.Move(FloorX[ToX], CurFloorY); - FromX = ToX; - } - Cell.Move(FloorX[0], FloorY[ToY]); - FromY = ToY; - } -} - - - - - -void cCubicNoise::Generate3D( - NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y] - int a_SizeX, int a_SizeY, int a_SizeZ, ///< Size of the array (num doubles), in each direction - NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction - NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction - NOISE_DATATYPE a_StartZ, NOISE_DATATYPE a_EndZ ///< Noise-space coords of the array in the Y direction -) const -{ - ASSERT(a_SizeX < MAX_SIZE); - ASSERT(a_SizeY < MAX_SIZE); - ASSERT(a_SizeZ < MAX_SIZE); - ASSERT(a_StartX < a_EndX); - ASSERT(a_StartY < a_EndY); - ASSERT(a_StartZ < a_EndZ); - - // Calculate the integral and fractional parts of each coord: - int FloorX[MAX_SIZE]; - int FloorY[MAX_SIZE]; - int FloorZ[MAX_SIZE]; - NOISE_DATATYPE FracX[MAX_SIZE]; - NOISE_DATATYPE FracY[MAX_SIZE]; - NOISE_DATATYPE FracZ[MAX_SIZE]; - int SameX[MAX_SIZE]; - int SameY[MAX_SIZE]; - int SameZ[MAX_SIZE]; - int NumSameX, NumSameY, NumSameZ; - CalcFloorFrac(a_SizeX, a_StartX, a_EndX, FloorX, FracX, SameX, NumSameX); - CalcFloorFrac(a_SizeY, a_StartY, a_EndY, FloorY, FracY, SameY, NumSameY); - CalcFloorFrac(a_SizeZ, a_StartZ, a_EndZ, FloorZ, FracZ, SameZ, NumSameZ); - - cCubicCell3D Cell( - m_Noise, a_Array, - a_SizeX, a_SizeY, a_SizeZ, - FracX, FracY, FracZ - ); - - Cell.InitWorkRnds(FloorX[0], FloorY[0], FloorZ[0]); - - // Calculate query values using Cell: - int FromZ = 0; - for (int z = 0; z < NumSameZ; z++) - { - int ToZ = FromZ + SameZ[z]; - int CurFloorZ = FloorZ[FromZ]; - int FromY = 0; - for (int y = 0; y < NumSameY; y++) - { - int ToY = FromY + SameY[y]; - int CurFloorY = FloorY[FromY]; - int FromX = 0; - for (int x = 0; x < NumSameX; x++) - { - int ToX = FromX + SameX[x]; - Cell.Generate(FromX, ToX, FromY, ToY, FromZ, ToZ); - Cell.Move(FloorX[ToX], CurFloorY, CurFloorZ); - FromX = ToX; - } - Cell.Move(FloorX[0], FloorY[ToY], CurFloorZ); - FromY = ToY; - } // for y - Cell.Move(FloorX[0], FloorY[0], FloorZ[ToZ]); - FromZ = ToZ; - } // for z -} - - - - - -void cCubicNoise::CalcFloorFrac( - int a_Size, - NOISE_DATATYPE a_Start, NOISE_DATATYPE a_End, - int * a_Floor, NOISE_DATATYPE * a_Frac, - int * a_Same, int & a_NumSame -) const -{ - ASSERT(a_Size > 0); - - NOISE_DATATYPE val = a_Start; - NOISE_DATATYPE dif = (a_End - a_Start) / (a_Size - 1); - for (int i = 0; i < a_Size; i++) - { - a_Floor[i] = FAST_FLOOR(val); - a_Frac[i] = val - a_Floor[i]; - val += dif; - } - - // Mark up the same floor values into a_Same / a_NumSame: - int CurFloor = a_Floor[0]; - int LastSame = 0; - a_NumSame = 0; - for (int i = 1; i < a_Size; i++) - { - if (a_Floor[i] != CurFloor) - { - a_Same[a_NumSame] = i - LastSame; - LastSame = i; - a_NumSame += 1; - CurFloor = a_Floor[i]; - } - } // for i - a_Floor[] - if (LastSame < a_Size) - { - a_Same[a_NumSame] = a_Size - LastSame; - a_NumSame += 1; - } -} - - - - - -//////////////////////////////////////////////////////////////////////////////// -// cImprovedNoise: - -cImprovedNoise::cImprovedNoise(int a_Seed) -{ - // Initialize the permutations with identity: - for (int i = 0; i < 256; i++) - { - m_Perm[i] = i; - } - - // Randomize the permutation table - swap each element with a random other element: - cNoise noise(a_Seed); - for (int i = 0; i < 256; i++) - { - int rnd = (noise.IntNoise1DInt(i) / 7) % 256; - std::swap(m_Perm[i], m_Perm[rnd]); - } - - // Copy the lower 256 entries into upper 256 entries: - for (int i = 0; i < 256; i++) - { - m_Perm[i + 256] = m_Perm[i]; - } -} - - - - - -void cImprovedNoise::Generate2D( - NOISE_DATATYPE * a_Array, - int a_SizeX, int a_SizeY, - NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, - NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY -) const -{ - size_t idx = 0; - for (int y = 0; y < a_SizeY; y++) - { - NOISE_DATATYPE ratioY = static_cast(y) / (a_SizeY - 1); - NOISE_DATATYPE noiseY = Lerp(a_StartY, a_EndY, ratioY); - int noiseYInt = FAST_FLOOR(noiseY); - int yCoord = noiseYInt & 255; - NOISE_DATATYPE noiseYFrac = noiseY - noiseYInt; - NOISE_DATATYPE fadeY = Fade(noiseYFrac); - for (int x = 0; x < a_SizeX; x++) - { - NOISE_DATATYPE ratioX = static_cast(x) / (a_SizeX - 1); - NOISE_DATATYPE noiseX = Lerp(a_StartX, a_EndX, ratioX); - int noiseXInt = FAST_FLOOR(noiseX); - int xCoord = noiseXInt & 255; - NOISE_DATATYPE noiseXFrac = noiseX - noiseXInt; - NOISE_DATATYPE fadeX = Fade(noiseXFrac); - - // Hash the coordinates: - int A = m_Perm[xCoord] + yCoord; - int AA = m_Perm[A]; - int AB = m_Perm[A + 1]; - int B = m_Perm[xCoord + 1] + yCoord; - int BA = m_Perm[B]; - int BB = m_Perm[B + 1]; - - // Lerp the gradients: - a_Array[idx++] = Lerp( - Lerp(Grad(m_Perm[AA], noiseXFrac, noiseYFrac, 0), Grad(m_Perm[BA], noiseXFrac - 1, noiseYFrac, 0), fadeX), - Lerp(Grad(m_Perm[AB], noiseXFrac, noiseYFrac - 1, 0), Grad(m_Perm[BB], noiseXFrac - 1, noiseYFrac - 1, 0), fadeX), - fadeY - ); - } // for x - } // for y -} - - - - - -void cImprovedNoise::Generate3D( - NOISE_DATATYPE * a_Array, - int a_SizeX, int a_SizeY, int a_SizeZ, - NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, - NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, - NOISE_DATATYPE a_StartZ, NOISE_DATATYPE a_EndZ -) const -{ - size_t idx = 0; - for (int z = 0; z < a_SizeZ; z++) - { - NOISE_DATATYPE ratioZ = static_cast(z) / (a_SizeZ - 1); - NOISE_DATATYPE noiseZ = Lerp(a_StartZ, a_EndZ, ratioZ); - int noiseZInt = FAST_FLOOR(noiseZ); - int zCoord = noiseZInt & 255; - NOISE_DATATYPE noiseZFrac = noiseZ - noiseZInt; - NOISE_DATATYPE fadeZ = Fade(noiseZFrac); - for (int y = 0; y < a_SizeY; y++) - { - NOISE_DATATYPE ratioY = static_cast(y) / (a_SizeY - 1); - NOISE_DATATYPE noiseY = Lerp(a_StartY, a_EndY, ratioY); - int noiseYInt = FAST_FLOOR(noiseY); - int yCoord = noiseYInt & 255; - NOISE_DATATYPE noiseYFrac = noiseY - noiseYInt; - NOISE_DATATYPE fadeY = Fade(noiseYFrac); - for (int x = 0; x < a_SizeX; x++) - { - NOISE_DATATYPE ratioX = static_cast(x) / (a_SizeX - 1); - NOISE_DATATYPE noiseX = Lerp(a_StartX, a_EndX, ratioX); - int noiseXInt = FAST_FLOOR(noiseX); - int xCoord = noiseXInt & 255; - NOISE_DATATYPE noiseXFrac = noiseX - noiseXInt; - NOISE_DATATYPE fadeX = Fade(noiseXFrac); - - // Hash the coordinates: - int A = m_Perm[xCoord] + yCoord; - int AA = m_Perm[A] + zCoord; - int AB = m_Perm[A + 1] + zCoord; - int B = m_Perm[xCoord + 1] + yCoord; - int BA = m_Perm[B] + zCoord; - int BB = m_Perm[B + 1] + zCoord; - - // Lerp the gradients: - // TODO: This may be optimized by swapping the coords and recalculating most lerps only "once every x" - a_Array[idx++] = Lerp( - Lerp( - Lerp(Grad(m_Perm[AA], noiseXFrac, noiseYFrac, noiseZFrac), Grad(m_Perm[BA], noiseXFrac - 1, noiseYFrac, noiseZFrac), fadeX), - Lerp(Grad(m_Perm[AB], noiseXFrac, noiseYFrac - 1, noiseZFrac), Grad(m_Perm[BB], noiseXFrac - 1, noiseYFrac - 1, noiseZFrac), fadeX), - fadeY - ), - Lerp( - Lerp(Grad(m_Perm[AA + 1], noiseXFrac, noiseYFrac, noiseZFrac - 1), Grad(m_Perm[BA + 1], noiseXFrac - 1, noiseYFrac, noiseZFrac - 1), fadeX), - Lerp(Grad(m_Perm[AB + 1], noiseXFrac, noiseYFrac - 1, noiseZFrac - 1), Grad(m_Perm[BB + 1], noiseXFrac - 1, noiseYFrac - 1, noiseZFrac - 1), fadeX), - fadeY - ), - fadeZ - ); - } // for x - } // for y - } // for z -} - - - - - -NOISE_DATATYPE cImprovedNoise::GetValueAt(int a_X, int a_Y, int a_Z) -{ - // Hash the coordinates: - a_X = a_X & 255; - a_Y = a_Y & 255; - a_Z = a_Z & 255; - int A = m_Perm[a_X] + a_Y; - int AA = m_Perm[A] + a_Z; - - return Grad(m_Perm[AA], 1, 1, 1); -} - - - - - diff --git a/src/Noise.h b/src/Noise.h deleted file mode 100644 index e616155d5..000000000 --- a/src/Noise.h +++ /dev/null @@ -1,347 +0,0 @@ - -// Noise.h - -// Declares the cNoise, cCubicNoise and cPerlinNoise classes for generating noise - -#pragma once - -#include - -/** The datatype used by all the noise generators. */ -typedef float NOISE_DATATYPE; - -#include "OctavedNoise.h" -#include "RidgedNoise.h" - - - - - -class cNoise -{ -public: - cNoise(int a_Seed); - cNoise(const cNoise & a_Noise); - - // The following functions, if not marked INLINE, are about 20 % slower - inline NOISE_DATATYPE IntNoise1D(int a_X) const; - inline NOISE_DATATYPE IntNoise2D(int a_X, int a_Y) const; - inline NOISE_DATATYPE IntNoise3D(int a_X, int a_Y, int a_Z) const; - - // Return a float number in the specified range: - inline NOISE_DATATYPE IntNoise2DInRange(int a_X, int a_Y, float a_Min, float a_Max) const - { - return a_Min + std::abs(IntNoise2D(a_X, a_Y)) * (a_Max - a_Min); - } - - // Note: These functions have a mod8-irregular chance - each of the mod8 remainders has different chance of occurrence. Divide by 8 to rectify. - inline int IntNoise1DInt(int a_X) const; - inline int IntNoise2DInt(int a_X, int a_Y) const; - inline int IntNoise3DInt(int a_X, int a_Y, int a_Z) const; - - NOISE_DATATYPE LinearNoise1D(NOISE_DATATYPE a_X) const; - NOISE_DATATYPE CosineNoise1D(NOISE_DATATYPE a_X) const; - NOISE_DATATYPE CubicNoise1D (NOISE_DATATYPE a_X) const; - NOISE_DATATYPE SmoothNoise1D(int a_X) const; - - NOISE_DATATYPE CubicNoise2D (NOISE_DATATYPE a_X, NOISE_DATATYPE a_Y) const; - - NOISE_DATATYPE CubicNoise3D (NOISE_DATATYPE a_X, NOISE_DATATYPE a_Y, NOISE_DATATYPE a_Z) const; - - void SetSeed(int a_Seed) { m_Seed = a_Seed; } - - inline static NOISE_DATATYPE CubicInterpolate (NOISE_DATATYPE a_A, NOISE_DATATYPE a_B, NOISE_DATATYPE a_C, NOISE_DATATYPE a_D, NOISE_DATATYPE a_Pct); - inline static NOISE_DATATYPE CosineInterpolate(NOISE_DATATYPE a_A, NOISE_DATATYPE a_B, NOISE_DATATYPE a_Pct); - inline static NOISE_DATATYPE LinearInterpolate(NOISE_DATATYPE a_A, NOISE_DATATYPE a_B, NOISE_DATATYPE a_Pct); - -private: - int m_Seed; -} ; - - - - - -class cCubicNoise -{ -public: - static const int MAX_SIZE = 512; ///< Maximum size of each dimension of the query arrays. - - - cCubicNoise(int a_Seed); - - - void Generate1D( - NOISE_DATATYPE * a_Array, ///< Array to generate into - int a_SizeX, ///< Count of the array - NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX ///< Noise-space coords of the array - ) const; - - - void Generate2D( - NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y] - int a_SizeX, int a_SizeY, ///< Count of the array, in each direction - NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction - NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY ///< Noise-space coords of the array in the Y direction - ) const; - - - void Generate3D( - NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y + a_SizeX * a_SizeY * z] - int a_SizeX, int a_SizeY, int a_SizeZ, ///< Count of the array, in each direction - NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction - NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction - NOISE_DATATYPE a_StartZ, NOISE_DATATYPE a_EndZ ///< Noise-space coords of the array in the Z direction - ) const; - -protected: - typedef NOISE_DATATYPE Workspace1D[4]; - typedef NOISE_DATATYPE Workspace2D[4][4]; - - cNoise m_Noise; // Used for integral rnd values - - #ifdef _DEBUG - // Statistics on the noise-space coords: - static int m_NumSingleX; - static int m_NumSingleXY; - static int m_NumSingleY; - static int m_NumCalls; - #endif // _DEBUG - - /// Calculates the integral and fractional parts along one axis. - void CalcFloorFrac( - int a_Size, - NOISE_DATATYPE a_Start, NOISE_DATATYPE a_End, - int * a_Floor, NOISE_DATATYPE * a_Frac, - int * a_Same, int & a_NumSame - ) const; - - void UpdateWorkRnds2DX( - Workspace2D & a_WorkRnds, - Workspace1D & a_Interps, - int a_LastFloorX, int a_NewFloorX, - int a_FloorY, - NOISE_DATATYPE a_FractionY - ) const; -} ; - - - - - -/** Improved noise, as described by Ken Perlin: http://mrl.nyu.edu/~perlin/paper445.pdf -Implementation adapted from Perlin's Java implementation: http://mrl.nyu.edu/~perlin/noise/ */ -class cImprovedNoise -{ -public: - /** Constructs a new instance of the noise obbject. - Note that this operation is quite expensive (the permutation array being constructed). */ - cImprovedNoise(int a_Seed); - - - /** Fills a 2D array with the values of the noise. */ - void Generate2D( - NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y] - int a_SizeX, int a_SizeY, ///< Count of the array, in each direction - NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction - NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY ///< Noise-space coords of the array in the Y direction - ) const; - - - /** Fills a 3D array with the values of the noise. */ - void Generate3D( - NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y + a_SizeX * a_SizeY * z] - int a_SizeX, int a_SizeY, int a_SizeZ, ///< Count of the array, in each direction - NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction - NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction - NOISE_DATATYPE a_StartZ, NOISE_DATATYPE a_EndZ ///< Noise-space coords of the array in the Z direction - ) const; - - /** Returns the value at the specified integral coords. Used for raw speed measurement. */ - NOISE_DATATYPE GetValueAt(int a_X, int a_Y, int a_Z); - -protected: - - /** The permutation table used by the noise function. Initialized using seed. */ - int m_Perm[512]; - - - /** Calculates the fade curve, 6 * t^5 - 15 * t^4 + 10 * t^3. */ - inline static NOISE_DATATYPE Fade(NOISE_DATATYPE a_T) - { - return a_T * a_T * a_T * (a_T * (a_T * 6 - 15) + 10); - } - - /** Returns the gradient value based on the hash. */ - inline static NOISE_DATATYPE Grad(int a_Hash, NOISE_DATATYPE a_X, NOISE_DATATYPE a_Y, NOISE_DATATYPE a_Z) - { - int hash = a_Hash % 16; - NOISE_DATATYPE u = (hash < 8) ? a_X : a_Y; - NOISE_DATATYPE v = (hash < 4) ? a_Y : (((hash == 12) || (hash == 14)) ? a_X : a_Z); - return (((hash & 1) == 0) ? u : -u) + (((hash & 2) == 0) ? v : -v); - } -}; - - - - - -typedef cOctavedNoise cPerlinNoise; -typedef cOctavedNoise> cRidgedMultiNoise; - - - - - -//////////////////////////////////////////////////////////////////////////////// -// Inline function definitions: -// These need to be in the header, otherwise linker error occur in MSVC - -NOISE_DATATYPE cNoise::IntNoise1D(int a_X) const -{ - int x = ((a_X * m_Seed) << 13) ^ a_X; - return (1 - (NOISE_DATATYPE)((x * (x * x * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824); - // returns a float number in the range of [-1, 1] -} - - - - - -NOISE_DATATYPE cNoise::IntNoise2D(int a_X, int a_Y) const -{ - int n = a_X + a_Y * 57 + m_Seed * 57 * 57; - n = (n << 13) ^ n; - return (1 - (NOISE_DATATYPE)((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824); - // returns a float number in the range of [-1, 1] -} - - - - - -NOISE_DATATYPE cNoise::IntNoise3D(int a_X, int a_Y, int a_Z) const -{ - int n = a_X + a_Y * 57 + a_Z * 57 * 57 + m_Seed * 57 * 57 * 57; - n = (n << 13) ^ n; - return ((NOISE_DATATYPE)1 - (NOISE_DATATYPE)((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0f); - // returns a float number in the range of [-1, 1] -} - - - - - -int cNoise::IntNoise1DInt(int a_X) const -{ - int x = ((a_X * m_Seed) << 13) ^ a_X; - return ((x * (x * x * 15731 + 789221) + 1376312589) & 0x7fffffff); -} - - - - - -int cNoise::IntNoise2DInt(int a_X, int a_Y) const -{ - int n = a_X + a_Y * 57 + m_Seed * 57 * 57; - n = (n << 13) ^ n; - return ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff); -} - - - - - -int cNoise::IntNoise3DInt(int a_X, int a_Y, int a_Z) const -{ - int n = a_X + a_Y * 57 + a_Z * 57 * 57 + m_Seed * 57 * 57 * 57; - n = (n << 13) ^ n; - return ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff); -} - - - - - -NOISE_DATATYPE cNoise::CubicInterpolate(NOISE_DATATYPE a_A, NOISE_DATATYPE a_B, NOISE_DATATYPE a_C, NOISE_DATATYPE a_D, NOISE_DATATYPE a_Pct) -{ - NOISE_DATATYPE P = (a_D - a_C) - (a_A - a_B); - NOISE_DATATYPE Q = (a_A - a_B) - P; - NOISE_DATATYPE R = a_C - a_A; - NOISE_DATATYPE S = a_B; - - return ((P * a_Pct + Q) * a_Pct + R) * a_Pct + S; -} - - - - - -NOISE_DATATYPE cNoise::CosineInterpolate(NOISE_DATATYPE a_A, NOISE_DATATYPE a_B, NOISE_DATATYPE a_Pct) -{ - const NOISE_DATATYPE ft = a_Pct * (NOISE_DATATYPE)3.1415927; - const NOISE_DATATYPE f = (NOISE_DATATYPE)((NOISE_DATATYPE)(1 - cos(ft)) * (NOISE_DATATYPE)0.5); - return a_A * (1 - f) + a_B * f; -} - - - - - -NOISE_DATATYPE cNoise::LinearInterpolate(NOISE_DATATYPE a_A, NOISE_DATATYPE a_B, NOISE_DATATYPE a_Pct) -{ - return a_A * (1 - a_Pct) + a_B * a_Pct; -} - - - - - -//////////////////////////////////////////////////////////////////////////////// -// Global functions: - -/** Exports the noise array into a file. -a_Coeff specifies the value that each array value is multiplied by before being converted into a byte. */ -extern void Debug2DNoise(const NOISE_DATATYPE * a_Array, int a_SizeX, int a_SizeY, const AString & a_FileNameBase, NOISE_DATATYPE a_Coeff = 32); - -/** Exports the noise array into a set of files, ordered by XY and XZ. -a_Coeff specifies the value that each array value is multiplied by before being converted into a byte. */ -extern void Debug3DNoise(const NOISE_DATATYPE * a_Array, int a_SizeX, int a_SizeY, int a_SizeZ, const AString & a_FileNameBase, NOISE_DATATYPE a_Coeff = 32); - - - - -/** Linearly interpolates between two values. -Assumes that a_Ratio is in range [0, 1]. */ -inline NOISE_DATATYPE Lerp(NOISE_DATATYPE a_Val1, NOISE_DATATYPE a_Val2, NOISE_DATATYPE a_Ratio) -{ - return a_Val1 + (a_Val2 - a_Val1) * a_Ratio; -} - - - - - -/** Linearly interpolates between two values, clamping the ratio to [0, 1] first. */ -inline NOISE_DATATYPE ClampedLerp(NOISE_DATATYPE a_Val1, NOISE_DATATYPE a_Val2, NOISE_DATATYPE a_Ratio) -{ - if (a_Ratio < 0) - { - return a_Val1; - } - if (a_Ratio > 1) - { - return a_Val2; - } - return Lerp(a_Val1, a_Val2, a_Ratio); -} - - - - - - - - - diff --git a/src/Noise/CMakeLists.txt b/src/Noise/CMakeLists.txt new file mode 100644 index 000000000..e1837500f --- /dev/null +++ b/src/Noise/CMakeLists.txt @@ -0,0 +1,21 @@ + +cmake_minimum_required (VERSION 2.6) +project (MCServer) + +include_directories ("${PROJECT_SOURCE_DIR}/../") + +SET (SRCS + Noise.cpp +) + +SET (HDRS + Noise.h + OctavedNoise.h + RidgedNoise.h +) + +if(NOT MSVC) + add_library(Noise ${SRCS} ${HDRS}) + + target_link_libraries(Noise OSSupport) +endif() diff --git a/src/Noise/Noise.cpp b/src/Noise/Noise.cpp new file mode 100644 index 000000000..509be7d6c --- /dev/null +++ b/src/Noise/Noise.cpp @@ -0,0 +1,1029 @@ + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "Noise.h" +#include "OSSupport/Timer.h" + +#define FAST_FLOOR(x) (((x) < 0) ? (((int)x) - 1) : ((int)x)) + + + + + +#if 0 +/** cImprovedPerlin noise test suite: +- Generate a rather large 2D and 3D noise array and output it to a file +- Compare performance of cCubicNoise and cImprovedNoise, both in single-value and 3D-array usages */ +static class cImprovedPerlinNoiseTest +{ +public: + cImprovedPerlinNoiseTest(void) + { + printf("Performing Improved Perlin Noise tests...\n"); + TestImage(); + TestSpeed(); + TestSpeedArr(); + printf("Improved Perlin Noise tests complete.\n"); + } + + + /** Tests the noise by generating 2D and 3D images and dumping them to files. */ + void TestImage(void) + { + static const int SIZE_X = 256; + static const int SIZE_Y = 256; + static const int SIZE_Z = 16; + + cImprovedNoise noise(1); + std::unique_ptr arr(new NOISE_DATATYPE[SIZE_X * SIZE_Y * SIZE_Z]); + noise.Generate3D(arr.get(), SIZE_X, SIZE_Y, SIZE_Z, 0, 14, 0, 14, 0, 14); + Debug3DNoise(arr.get(), SIZE_X, SIZE_Y, SIZE_Z, "ImprovedPerlinNoiseTest3D", 128); + noise.Generate2D(arr.get(), SIZE_X, SIZE_Y, 0, 14, 15, 28); + Debug2DNoise(arr.get(), SIZE_X, SIZE_Y, "ImprovedPerlinNoiseTest2D", 128); + } + + + /** Tests the speeds of cImprovedPerlin and cCubicNoise when generating individual values. */ + void TestSpeed(void) + { + cImprovedNoise improvedNoise(1); + cNoise noise(1); + cTimer timer; + + // Measure the improvedNoise: + NOISE_DATATYPE sum = 0; + long long start = timer.GetNowTime(); + for (int i = 0; i < 100000000; i++) + { + sum += improvedNoise.GetValueAt(i, 0, -i); + } + long long finish = timer.GetNowTime(); + printf("cImprovedNoise took %.2f seconds; total is %f.\n", static_cast(finish - start) / 1000.0f, sum); + + // Measure the cubicNoise: + sum = 0; + start = timer.GetNowTime(); + for (int i = 0; i < 100000000; i++) + { + sum += noise.IntNoise3D(i, 0, -i); + } + finish = timer.GetNowTime(); + printf("cCubicNoise took %.2f seconds; total is %f.\n", static_cast(finish - start) / 1000.0f, sum); + } + + + /** Tests the speeds of cImprovedPerlin and cCubicNoise when generating arrays. */ + void TestSpeedArr(void) + { + static const int SIZE_X = 256; + static const int SIZE_Y = 256; + static const int SIZE_Z = 16; + + std::unique_ptr arr(new NOISE_DATATYPE[SIZE_X * SIZE_Y * SIZE_Z]); + cTimer timer; + cImprovedNoise improvedNoise(1); + cCubicNoise cubicNoise(1); + + // Measure the improvedNoise: + long long start = timer.GetNowTime(); + for (int i = 0; i < 40; i++) + { + improvedNoise.Generate3D(arr.get(), SIZE_X, SIZE_Y, SIZE_Z, 0, 14, 0, 14, 0, 14); + } + long long finish = timer.GetNowTime(); + printf("cImprovedNoise(arr) took %.2f seconds.\n", static_cast(finish - start) / 1000.0f); + + // Measure the cubicNoise: + start = timer.GetNowTime(); + for (int i = 0; i < 40; i++) + { + cubicNoise.Generate3D(arr.get(), SIZE_X, SIZE_Y, SIZE_Z, 0, 14, 0, 14, 0, 14); + } + finish = timer.GetNowTime(); + printf("cCubicNoise(arr) took %.2f seconds.\n", static_cast(finish - start) / 1000.0f); + } +} g_Test; + +#endif + + + + + +//////////////////////////////////////////////////////////////////////////////// +// Globals: + +void Debug3DNoise(const NOISE_DATATYPE * a_Noise, int a_SizeX, int a_SizeY, int a_SizeZ, const AString & a_FileNameBase, NOISE_DATATYPE a_Coeff) +{ + const int BUF_SIZE = 512; + ASSERT(a_SizeX <= BUF_SIZE); // Just stretch it, if needed + + // Save in XY cuts: + cFile f1; + if (f1.Open(Printf("%s_XY (%d).grab", a_FileNameBase.c_str(), a_SizeX), cFile::fmWrite)) + { + for (int z = 0; z < a_SizeZ; z++) + { + for (int y = 0; y < a_SizeY; y++) + { + int idx = y * a_SizeX + z * a_SizeX * a_SizeY; + unsigned char buf[BUF_SIZE]; + for (int x = 0; x < a_SizeX; x++) + { + buf[x] = static_cast(Clamp((int)(128 + a_Coeff * a_Noise[idx++]), 0, 255)); + } + f1.Write(buf, a_SizeX); + } // for y + unsigned char buf[BUF_SIZE]; + memset(buf, 0, a_SizeX); + f1.Write(buf, a_SizeX); + } // for z + } // if (XY file open) + + cFile f2; + if (f2.Open(Printf("%s_XZ (%d).grab", a_FileNameBase.c_str(), a_SizeX), cFile::fmWrite)) + { + for (int y = 0; y < a_SizeY; y++) + { + for (int z = 0; z < a_SizeZ; z++) + { + int idx = y * a_SizeX + z * a_SizeX * a_SizeY; + unsigned char buf[BUF_SIZE]; + for (int x = 0; x < a_SizeX; x++) + { + buf[x] = static_cast(Clamp((int)(128 + a_Coeff * a_Noise[idx++]), 0, 255)); + } + f2.Write(buf, a_SizeX); + } // for z + unsigned char buf[BUF_SIZE]; + memset(buf, 0, a_SizeX); + f2.Write(buf, a_SizeX); + } // for y + } // if (XZ file open) +} + + + + + +void Debug2DNoise(const NOISE_DATATYPE * a_Noise, int a_SizeX, int a_SizeY, const AString & a_FileNameBase, NOISE_DATATYPE a_Coeff) +{ + const int BUF_SIZE = 512; + ASSERT(a_SizeX <= BUF_SIZE); // Just stretch it, if needed + + cFile f1; + if (f1.Open(Printf("%s (%d).grab", a_FileNameBase.c_str(), a_SizeX), cFile::fmWrite)) + { + for (int y = 0; y < a_SizeY; y++) + { + int idx = y * a_SizeX; + unsigned char buf[BUF_SIZE]; + for (int x = 0; x < a_SizeX; x++) + { + buf[x] = static_cast(Clamp((int)(128 + a_Coeff * a_Noise[idx++]), 0, 255)); + } + f1.Write(buf, a_SizeX); + } // for y + } // if (file open) +} + + + + + +//////////////////////////////////////////////////////////////////////////////// +// cCubicCell2D: + +class cCubicCell2D +{ +public: + cCubicCell2D( + const cNoise & a_Noise, ///< Noise to use for generating the random values + NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y] + int a_SizeX, int a_SizeY, ///< Count of the array, in each direction + const NOISE_DATATYPE * a_FracX, ///< Pointer to the array that stores the X fractional values + const NOISE_DATATYPE * a_FracY ///< Pointer to the attay that stores the Y fractional values + ); + + /// Uses current m_WorkRnds[] to generate part of the array + void Generate( + int a_FromX, int a_ToX, + int a_FromY, int a_ToY + ); + + /// Initializes m_WorkRnds[] with the specified Floor values + void InitWorkRnds(int a_FloorX, int a_FloorY); + + /// Updates m_WorkRnds[] for the new Floor values. + void Move(int a_NewFloorX, int a_NewFloorY); + +protected: + typedef NOISE_DATATYPE Workspace[4][4]; + + const cNoise & m_Noise; + + Workspace * m_WorkRnds; ///< The current random values; points to either m_Workspace1 or m_Workspace2 (doublebuffering) + Workspace m_Workspace1; ///< Buffer 1 for workspace doublebuffering, used in Move() + Workspace m_Workspace2; ///< Buffer 2 for workspace doublebuffering, used in Move() + int m_CurFloorX; + int m_CurFloorY; + + NOISE_DATATYPE * m_Array; + int m_SizeX, m_SizeY; + const NOISE_DATATYPE * m_FracX; + const NOISE_DATATYPE * m_FracY; +} ; + + + + + +cCubicCell2D::cCubicCell2D( + const cNoise & a_Noise, ///< Noise to use for generating the random values + NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y] + int a_SizeX, int a_SizeY, ///< Count of the array, in each direction + const NOISE_DATATYPE * a_FracX, ///< Pointer to the array that stores the X fractional values + const NOISE_DATATYPE * a_FracY ///< Pointer to the attay that stores the Y fractional values +) : + m_Noise(a_Noise), + m_WorkRnds(&m_Workspace1), + m_CurFloorX(0), + m_CurFloorY(0), + m_Array(a_Array), + m_SizeX(a_SizeX), + m_SizeY(a_SizeY), + m_FracX(a_FracX), + m_FracY(a_FracY) +{ +} + + + + + +void cCubicCell2D::Generate( + int a_FromX, int a_ToX, + int a_FromY, int a_ToY +) +{ + for (int y = a_FromY; y < a_ToY; y++) + { + NOISE_DATATYPE Interp[4]; + NOISE_DATATYPE FracY = m_FracY[y]; + Interp[0] = cNoise::CubicInterpolate((*m_WorkRnds)[0][0], (*m_WorkRnds)[0][1], (*m_WorkRnds)[0][2], (*m_WorkRnds)[0][3], FracY); + Interp[1] = cNoise::CubicInterpolate((*m_WorkRnds)[1][0], (*m_WorkRnds)[1][1], (*m_WorkRnds)[1][2], (*m_WorkRnds)[1][3], FracY); + Interp[2] = cNoise::CubicInterpolate((*m_WorkRnds)[2][0], (*m_WorkRnds)[2][1], (*m_WorkRnds)[2][2], (*m_WorkRnds)[2][3], FracY); + Interp[3] = cNoise::CubicInterpolate((*m_WorkRnds)[3][0], (*m_WorkRnds)[3][1], (*m_WorkRnds)[3][2], (*m_WorkRnds)[3][3], FracY); + int idx = y * m_SizeX + a_FromX; + for (int x = a_FromX; x < a_ToX; x++) + { + m_Array[idx++] = cNoise::CubicInterpolate(Interp[0], Interp[1], Interp[2], Interp[3], m_FracX[x]); + } // for x + } // for y +} + + + + + +void cCubicCell2D::InitWorkRnds(int a_FloorX, int a_FloorY) +{ + m_CurFloorX = a_FloorX; + m_CurFloorY = a_FloorY; + for (int x = 0; x < 4; x++) + { + int cx = a_FloorX + x - 1; + for (int y = 0; y < 4; y++) + { + int cy = a_FloorY + y - 1; + (*m_WorkRnds)[x][y] = (NOISE_DATATYPE)m_Noise.IntNoise2D(cx, cy); + } + } +} + + + + + +void cCubicCell2D::Move(int a_NewFloorX, int a_NewFloorY) +{ + // Swap the doublebuffer: + int OldFloorX = m_CurFloorX; + int OldFloorY = m_CurFloorY; + Workspace * OldWorkRnds = m_WorkRnds; + m_WorkRnds = (m_WorkRnds == &m_Workspace1) ? &m_Workspace2 : &m_Workspace1; + + // Reuse as much of the old workspace as possible: + int DiffX = OldFloorX - a_NewFloorX; + int DiffY = OldFloorY - a_NewFloorY; + for (int x = 0; x < 4; x++) + { + int cx = a_NewFloorX + x - 1; + int OldX = x - DiffX; // Where would this X be in the old grid? + for (int y = 0; y < 4; y++) + { + int cy = a_NewFloorY + y - 1; + int OldY = y - DiffY; // Where would this Y be in the old grid? + if ((OldX >= 0) && (OldX < 4) && (OldY >= 0) && (OldY < 4)) + { + (*m_WorkRnds)[x][y] = (*OldWorkRnds)[OldX][OldY]; + } + else + { + (*m_WorkRnds)[x][y] = (NOISE_DATATYPE)m_Noise.IntNoise2D(cx, cy); + } + } + } + m_CurFloorX = a_NewFloorX; + m_CurFloorY = a_NewFloorY; +} + + + + + +//////////////////////////////////////////////////////////////////////////////// +// cCubicCell3D: + +class cCubicCell3D +{ +public: + cCubicCell3D( + const cNoise & a_Noise, ///< Noise to use for generating the random values + NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y] + int a_SizeX, int a_SizeY, int a_SizeZ, ///< Count of the array, in each direction + const NOISE_DATATYPE * a_FracX, ///< Pointer to the array that stores the X fractional values + const NOISE_DATATYPE * a_FracY, ///< Pointer to the attay that stores the Y fractional values + const NOISE_DATATYPE * a_FracZ ///< Pointer to the array that stores the Z fractional values + ); + + /// Uses current m_WorkRnds[] to generate part of the array + void Generate( + int a_FromX, int a_ToX, + int a_FromY, int a_ToY, + int a_FromZ, int a_ToZ + ); + + /// Initializes m_WorkRnds[] with the specified Floor values + void InitWorkRnds(int a_FloorX, int a_FloorY, int a_FloorZ); + + /// Updates m_WorkRnds[] for the new Floor values. + void Move(int a_NewFloorX, int a_NewFloorY, int a_NewFloorZ); + +protected: + typedef NOISE_DATATYPE Workspace[4][4][4]; + + const cNoise & m_Noise; + + Workspace * m_WorkRnds; ///< The current random values; points to either m_Workspace1 or m_Workspace2 (doublebuffering) + Workspace m_Workspace1; ///< Buffer 1 for workspace doublebuffering, used in Move() + Workspace m_Workspace2; ///< Buffer 2 for workspace doublebuffering, used in Move() + int m_CurFloorX; + int m_CurFloorY; + int m_CurFloorZ; + + NOISE_DATATYPE * m_Array; + int m_SizeX, m_SizeY, m_SizeZ; + const NOISE_DATATYPE * m_FracX; + const NOISE_DATATYPE * m_FracY; + const NOISE_DATATYPE * m_FracZ; +} ; + + + + + +cCubicCell3D::cCubicCell3D( + const cNoise & a_Noise, ///< Noise to use for generating the random values + NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y] + int a_SizeX, int a_SizeY, int a_SizeZ, ///< Count of the array, in each direction + const NOISE_DATATYPE * a_FracX, ///< Pointer to the array that stores the X fractional values + const NOISE_DATATYPE * a_FracY, ///< Pointer to the attay that stores the Y fractional values + const NOISE_DATATYPE * a_FracZ ///< Pointer to the array that stores the Z fractional values +) : + m_Noise(a_Noise), + m_WorkRnds(&m_Workspace1), + m_CurFloorX(0), + m_CurFloorY(0), + m_CurFloorZ(0), + m_Array(a_Array), + m_SizeX(a_SizeX), + m_SizeY(a_SizeY), + m_SizeZ(a_SizeZ), + m_FracX(a_FracX), + m_FracY(a_FracY), + m_FracZ(a_FracZ) +{ +} + + + + + +void cCubicCell3D::Generate( + int a_FromX, int a_ToX, + int a_FromY, int a_ToY, + int a_FromZ, int a_ToZ +) +{ + for (int z = a_FromZ; z < a_ToZ; z++) + { + int idxZ = z * m_SizeX * m_SizeY; + NOISE_DATATYPE Interp2[4][4]; + NOISE_DATATYPE FracZ = m_FracZ[z]; + for (int x = 0; x < 4; x++) + { + for (int y = 0; y < 4; y++) + { + Interp2[x][y] = cNoise::CubicInterpolate((*m_WorkRnds)[x][y][0], (*m_WorkRnds)[x][y][1], (*m_WorkRnds)[x][y][2], (*m_WorkRnds)[x][y][3], FracZ); + } + } + for (int y = a_FromY; y < a_ToY; y++) + { + NOISE_DATATYPE Interp[4]; + NOISE_DATATYPE FracY = m_FracY[y]; + Interp[0] = cNoise::CubicInterpolate(Interp2[0][0], Interp2[0][1], Interp2[0][2], Interp2[0][3], FracY); + Interp[1] = cNoise::CubicInterpolate(Interp2[1][0], Interp2[1][1], Interp2[1][2], Interp2[1][3], FracY); + Interp[2] = cNoise::CubicInterpolate(Interp2[2][0], Interp2[2][1], Interp2[2][2], Interp2[2][3], FracY); + Interp[3] = cNoise::CubicInterpolate(Interp2[3][0], Interp2[3][1], Interp2[3][2], Interp2[3][3], FracY); + int idx = idxZ + y * m_SizeX + a_FromX; + for (int x = a_FromX; x < a_ToX; x++) + { + m_Array[idx++] = cNoise::CubicInterpolate(Interp[0], Interp[1], Interp[2], Interp[3], m_FracX[x]); + } // for x + } // for y + } // for z +} + + + + + +void cCubicCell3D::InitWorkRnds(int a_FloorX, int a_FloorY, int a_FloorZ) +{ + m_CurFloorX = a_FloorX; + m_CurFloorY = a_FloorY; + m_CurFloorZ = a_FloorZ; + for (int x = 0; x < 4; x++) + { + int cx = a_FloorX + x - 1; + for (int y = 0; y < 4; y++) + { + int cy = a_FloorY + y - 1; + for (int z = 0; z < 4; z++) + { + int cz = a_FloorZ + z - 1; + (*m_WorkRnds)[x][y][z] = (NOISE_DATATYPE)m_Noise.IntNoise3D(cx, cy, cz); + } + } + } +} + + + + + +void cCubicCell3D::Move(int a_NewFloorX, int a_NewFloorY, int a_NewFloorZ) +{ + // Swap the doublebuffer: + int OldFloorX = m_CurFloorX; + int OldFloorY = m_CurFloorY; + int OldFloorZ = m_CurFloorZ; + Workspace * OldWorkRnds = m_WorkRnds; + m_WorkRnds = (m_WorkRnds == &m_Workspace1) ? &m_Workspace2 : &m_Workspace1; + + // Reuse as much of the old workspace as possible: + int DiffX = OldFloorX - a_NewFloorX; + int DiffY = OldFloorY - a_NewFloorY; + int DiffZ = OldFloorZ - a_NewFloorZ; + for (int x = 0; x < 4; x++) + { + int cx = a_NewFloorX + x - 1; + int OldX = x - DiffX; // Where would this X be in the old grid? + for (int y = 0; y < 4; y++) + { + int cy = a_NewFloorY + y - 1; + int OldY = y - DiffY; // Where would this Y be in the old grid? + for (int z = 0; z < 4; z++) + { + int cz = a_NewFloorZ + z - 1; + int OldZ = z - DiffZ; + if ((OldX >= 0) && (OldX < 4) && (OldY >= 0) && (OldY < 4) && (OldZ >= 0) && (OldZ < 4)) + { + (*m_WorkRnds)[x][y][z] = (*OldWorkRnds)[OldX][OldY][OldZ]; + } + else + { + (*m_WorkRnds)[x][y][z] = (NOISE_DATATYPE)m_Noise.IntNoise3D(cx, cy, cz); + } + } // for z + } // for y + } // for x + m_CurFloorX = a_NewFloorX; + m_CurFloorY = a_NewFloorY; + m_CurFloorZ = a_NewFloorZ; +} + + + + + +//////////////////////////////////////////////////////////////////////////////// +// cNoise: + +cNoise::cNoise(int a_Seed) : + m_Seed(a_Seed) +{ +} + + + + + +cNoise::cNoise(const cNoise & a_Noise) : + m_Seed(a_Noise.m_Seed) +{ +} + + + + + +NOISE_DATATYPE cNoise::LinearNoise1D(NOISE_DATATYPE a_X) const +{ + int BaseX = FAST_FLOOR(a_X); + NOISE_DATATYPE FracX = a_X - BaseX; + return LinearInterpolate(IntNoise1D(BaseX), IntNoise1D(BaseX + 1), FracX); +} + + + + + +NOISE_DATATYPE cNoise::CosineNoise1D(NOISE_DATATYPE a_X) const +{ + int BaseX = FAST_FLOOR(a_X); + NOISE_DATATYPE FracX = a_X - BaseX; + return CosineInterpolate(IntNoise1D(BaseX), IntNoise1D(BaseX + 1), FracX); +} + + + + + +NOISE_DATATYPE cNoise::CubicNoise1D(NOISE_DATATYPE a_X) const +{ + int BaseX = FAST_FLOOR(a_X); + NOISE_DATATYPE FracX = a_X - BaseX; + return CubicInterpolate(IntNoise1D(BaseX - 1), IntNoise1D(BaseX), IntNoise1D(BaseX + 1), IntNoise1D(BaseX + 2), FracX); +} + + + + + +NOISE_DATATYPE cNoise::SmoothNoise1D(int a_X) const +{ + return IntNoise1D(a_X) / 2 + IntNoise1D(a_X - 1) / 4 + IntNoise1D(a_X + 1) / 4; +} + + + + + +NOISE_DATATYPE cNoise::CubicNoise2D(NOISE_DATATYPE a_X, NOISE_DATATYPE a_Y) const +{ + const int BaseX = FAST_FLOOR(a_X); + const int BaseY = FAST_FLOOR(a_Y); + + const NOISE_DATATYPE points[4][4] = + { + { IntNoise2D(BaseX - 1, BaseY - 1), IntNoise2D(BaseX, BaseY - 1), IntNoise2D(BaseX + 1, BaseY - 1), IntNoise2D(BaseX + 2, BaseY - 1), }, + { IntNoise2D(BaseX - 1, BaseY), IntNoise2D(BaseX, BaseY), IntNoise2D(BaseX + 1, BaseY), IntNoise2D(BaseX + 2, BaseY), }, + { IntNoise2D(BaseX - 1, BaseY + 1), IntNoise2D(BaseX, BaseY + 1), IntNoise2D(BaseX + 1, BaseY + 1), IntNoise2D(BaseX + 2, BaseY + 1), }, + { IntNoise2D(BaseX - 1, BaseY + 2), IntNoise2D(BaseX, BaseY + 2), IntNoise2D(BaseX + 1, BaseY + 2), IntNoise2D(BaseX + 2, BaseY + 2), }, + }; + + const NOISE_DATATYPE FracX = a_X - BaseX; + const NOISE_DATATYPE interp1 = CubicInterpolate(points[0][0], points[0][1], points[0][2], points[0][3], FracX); + const NOISE_DATATYPE interp2 = CubicInterpolate(points[1][0], points[1][1], points[1][2], points[1][3], FracX); + const NOISE_DATATYPE interp3 = CubicInterpolate(points[2][0], points[2][1], points[2][2], points[2][3], FracX); + const NOISE_DATATYPE interp4 = CubicInterpolate(points[3][0], points[3][1], points[3][2], points[3][3], FracX); + + + const NOISE_DATATYPE FracY = a_Y - BaseY; + return CubicInterpolate(interp1, interp2, interp3, interp4, FracY); +} + + + + + +NOISE_DATATYPE cNoise::CubicNoise3D(NOISE_DATATYPE a_X, NOISE_DATATYPE a_Y, NOISE_DATATYPE a_Z) const +{ + const int BaseX = FAST_FLOOR(a_X); + const int BaseY = FAST_FLOOR(a_Y); + const int BaseZ = FAST_FLOOR(a_Z); + + const NOISE_DATATYPE points1[4][4] = + { + { IntNoise3D(BaseX - 1, BaseY - 1, BaseZ - 1), IntNoise3D(BaseX, BaseY - 1, BaseZ - 1), IntNoise3D(BaseX + 1, BaseY - 1, BaseZ - 1), IntNoise3D(BaseX + 2, BaseY - 1, BaseZ - 1), }, + { IntNoise3D(BaseX - 1, BaseY, BaseZ - 1), IntNoise3D(BaseX, BaseY, BaseZ - 1), IntNoise3D(BaseX + 1, BaseY, BaseZ - 1), IntNoise3D(BaseX + 2, BaseY, BaseZ - 1), }, + { IntNoise3D(BaseX - 1, BaseY + 1, BaseZ - 1), IntNoise3D(BaseX, BaseY + 1, BaseZ - 1), IntNoise3D(BaseX + 1, BaseY + 1, BaseZ - 1), IntNoise3D(BaseX + 2, BaseY + 1, BaseZ - 1), }, + { IntNoise3D(BaseX - 1, BaseY + 2, BaseZ - 1), IntNoise3D(BaseX, BaseY + 2, BaseZ - 1), IntNoise3D(BaseX + 1, BaseY + 2, BaseZ - 1), IntNoise3D(BaseX + 2, BaseY + 2, BaseZ - 1), }, + }; + + const NOISE_DATATYPE FracX = (a_X) - BaseX; + const NOISE_DATATYPE x1interp1 = CubicInterpolate( points1[0][0], points1[0][1], points1[0][2], points1[0][3], FracX); + const NOISE_DATATYPE x1interp2 = CubicInterpolate( points1[1][0], points1[1][1], points1[1][2], points1[1][3], FracX); + const NOISE_DATATYPE x1interp3 = CubicInterpolate( points1[2][0], points1[2][1], points1[2][2], points1[2][3], FracX); + const NOISE_DATATYPE x1interp4 = CubicInterpolate( points1[3][0], points1[3][1], points1[3][2], points1[3][3], FracX); + + const NOISE_DATATYPE points2[4][4] = + { + { IntNoise3D(BaseX - 1, BaseY - 1, BaseZ), IntNoise3D(BaseX, BaseY - 1, BaseZ), IntNoise3D(BaseX + 1, BaseY - 1, BaseZ), IntNoise3D(BaseX + 2, BaseY - 1, BaseZ), }, + { IntNoise3D(BaseX - 1, BaseY, BaseZ), IntNoise3D(BaseX, BaseY, BaseZ), IntNoise3D(BaseX + 1, BaseY, BaseZ), IntNoise3D(BaseX + 2, BaseY, BaseZ), }, + { IntNoise3D(BaseX - 1, BaseY + 1, BaseZ), IntNoise3D(BaseX, BaseY + 1, BaseZ), IntNoise3D(BaseX + 1, BaseY + 1, BaseZ), IntNoise3D(BaseX + 2, BaseY + 1, BaseZ), }, + { IntNoise3D(BaseX - 1, BaseY + 2, BaseZ), IntNoise3D(BaseX, BaseY + 2, BaseZ), IntNoise3D(BaseX + 1, BaseY + 2, BaseZ), IntNoise3D(BaseX + 2, BaseY + 2, BaseZ), }, + }; + + const NOISE_DATATYPE x2interp1 = CubicInterpolate( points2[0][0], points2[0][1], points2[0][2], points2[0][3], FracX); + const NOISE_DATATYPE x2interp2 = CubicInterpolate( points2[1][0], points2[1][1], points2[1][2], points2[1][3], FracX); + const NOISE_DATATYPE x2interp3 = CubicInterpolate( points2[2][0], points2[2][1], points2[2][2], points2[2][3], FracX); + const NOISE_DATATYPE x2interp4 = CubicInterpolate( points2[3][0], points2[3][1], points2[3][2], points2[3][3], FracX); + + const NOISE_DATATYPE points3[4][4] = + { + { IntNoise3D( BaseX-1, BaseY-1, BaseZ+1), IntNoise3D( BaseX, BaseY-1, BaseZ+1), IntNoise3D( BaseX+1, BaseY-1, BaseZ+1), IntNoise3D( BaseX+2, BaseY-1, BaseZ + 1), }, + { IntNoise3D( BaseX-1, BaseY, BaseZ+1), IntNoise3D( BaseX, BaseY, BaseZ+1), IntNoise3D( BaseX+1, BaseY, BaseZ+1), IntNoise3D( BaseX+2, BaseY, BaseZ + 1), }, + { IntNoise3D( BaseX-1, BaseY+1, BaseZ+1), IntNoise3D( BaseX, BaseY+1, BaseZ+1), IntNoise3D( BaseX+1, BaseY+1, BaseZ+1), IntNoise3D( BaseX+2, BaseY+1, BaseZ + 1), }, + { IntNoise3D( BaseX-1, BaseY+2, BaseZ+1), IntNoise3D( BaseX, BaseY+2, BaseZ+1), IntNoise3D( BaseX+1, BaseY+2, BaseZ+1), IntNoise3D( BaseX+2, BaseY+2, BaseZ + 1), }, + }; + + const NOISE_DATATYPE x3interp1 = CubicInterpolate( points3[0][0], points3[0][1], points3[0][2], points3[0][3], FracX); + const NOISE_DATATYPE x3interp2 = CubicInterpolate( points3[1][0], points3[1][1], points3[1][2], points3[1][3], FracX); + const NOISE_DATATYPE x3interp3 = CubicInterpolate( points3[2][0], points3[2][1], points3[2][2], points3[2][3], FracX); + const NOISE_DATATYPE x3interp4 = CubicInterpolate( points3[3][0], points3[3][1], points3[3][2], points3[3][3], FracX); + + const NOISE_DATATYPE points4[4][4] = + { + { IntNoise3D( BaseX-1, BaseY-1, BaseZ+2), IntNoise3D( BaseX, BaseY-1, BaseZ+2), IntNoise3D( BaseX+1, BaseY-1, BaseZ+2), IntNoise3D( BaseX+2, BaseY-1, BaseZ+2), }, + { IntNoise3D( BaseX-1, BaseY, BaseZ+2), IntNoise3D( BaseX, BaseY, BaseZ+2), IntNoise3D( BaseX+1, BaseY, BaseZ+2), IntNoise3D( BaseX+2, BaseY, BaseZ+2), }, + { IntNoise3D( BaseX-1, BaseY+1, BaseZ+2), IntNoise3D( BaseX, BaseY+1, BaseZ+2), IntNoise3D( BaseX+1, BaseY+1, BaseZ+2), IntNoise3D( BaseX+2, BaseY+1, BaseZ+2), }, + { IntNoise3D( BaseX-1, BaseY+2, BaseZ+2), IntNoise3D( BaseX, BaseY+2, BaseZ+2), IntNoise3D( BaseX+1, BaseY+2, BaseZ+2), IntNoise3D( BaseX+2, BaseY+2, BaseZ+2), }, + }; + + const NOISE_DATATYPE x4interp1 = CubicInterpolate( points4[0][0], points4[0][1], points4[0][2], points4[0][3], FracX); + const NOISE_DATATYPE x4interp2 = CubicInterpolate( points4[1][0], points4[1][1], points4[1][2], points4[1][3], FracX); + const NOISE_DATATYPE x4interp3 = CubicInterpolate( points4[2][0], points4[2][1], points4[2][2], points4[2][3], FracX); + const NOISE_DATATYPE x4interp4 = CubicInterpolate( points4[3][0], points4[3][1], points4[3][2], points4[3][3], FracX); + + const NOISE_DATATYPE FracY = (a_Y) - BaseY; + const NOISE_DATATYPE yinterp1 = CubicInterpolate( x1interp1, x1interp2, x1interp3, x1interp4, FracY); + const NOISE_DATATYPE yinterp2 = CubicInterpolate( x2interp1, x2interp2, x2interp3, x2interp4, FracY); + const NOISE_DATATYPE yinterp3 = CubicInterpolate( x3interp1, x3interp2, x3interp3, x3interp4, FracY); + const NOISE_DATATYPE yinterp4 = CubicInterpolate( x4interp1, x4interp2, x4interp3, x4interp4, FracY); + + const NOISE_DATATYPE FracZ = (a_Z) - BaseZ; + return CubicInterpolate( yinterp1, yinterp2, yinterp3, yinterp4, FracZ); +} + + + + + +//////////////////////////////////////////////////////////////////////////////// +// cCubicNoise: + +cCubicNoise::cCubicNoise(int a_Seed) : + m_Noise(a_Seed) +{ +} + + + + + +void cCubicNoise::Generate2D( + NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y] + int a_SizeX, int a_SizeY, ///< Size of the array (num doubles), in each direction + NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction + NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY ///< Noise-space coords of the array in the Y direction +) const +{ + ASSERT(a_SizeX > 0); + ASSERT(a_SizeY > 0); + ASSERT(a_SizeX < MAX_SIZE); + ASSERT(a_SizeY < MAX_SIZE); + ASSERT(a_StartX < a_EndX); + ASSERT(a_StartY < a_EndY); + + // Calculate the integral and fractional parts of each coord: + int FloorX[MAX_SIZE]; + int FloorY[MAX_SIZE]; + NOISE_DATATYPE FracX[MAX_SIZE]; + NOISE_DATATYPE FracY[MAX_SIZE]; + int SameX[MAX_SIZE]; + int SameY[MAX_SIZE]; + int NumSameX, NumSameY; + CalcFloorFrac(a_SizeX, a_StartX, a_EndX, FloorX, FracX, SameX, NumSameX); + CalcFloorFrac(a_SizeY, a_StartY, a_EndY, FloorY, FracY, SameY, NumSameY); + + cCubicCell2D Cell(m_Noise, a_Array, a_SizeX, a_SizeY, FracX, FracY); + + Cell.InitWorkRnds(FloorX[0], FloorY[0]); + + // Calculate query values using Cell: + int FromY = 0; + for (int y = 0; y < NumSameY; y++) + { + int ToY = FromY + SameY[y]; + int FromX = 0; + int CurFloorY = FloorY[FromY]; + for (int x = 0; x < NumSameX; x++) + { + int ToX = FromX + SameX[x]; + Cell.Generate(FromX, ToX, FromY, ToY); + Cell.Move(FloorX[ToX], CurFloorY); + FromX = ToX; + } + Cell.Move(FloorX[0], FloorY[ToY]); + FromY = ToY; + } +} + + + + + +void cCubicNoise::Generate3D( + NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y] + int a_SizeX, int a_SizeY, int a_SizeZ, ///< Size of the array (num doubles), in each direction + NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction + NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction + NOISE_DATATYPE a_StartZ, NOISE_DATATYPE a_EndZ ///< Noise-space coords of the array in the Y direction +) const +{ + ASSERT(a_SizeX < MAX_SIZE); + ASSERT(a_SizeY < MAX_SIZE); + ASSERT(a_SizeZ < MAX_SIZE); + ASSERT(a_StartX < a_EndX); + ASSERT(a_StartY < a_EndY); + ASSERT(a_StartZ < a_EndZ); + + // Calculate the integral and fractional parts of each coord: + int FloorX[MAX_SIZE]; + int FloorY[MAX_SIZE]; + int FloorZ[MAX_SIZE]; + NOISE_DATATYPE FracX[MAX_SIZE]; + NOISE_DATATYPE FracY[MAX_SIZE]; + NOISE_DATATYPE FracZ[MAX_SIZE]; + int SameX[MAX_SIZE]; + int SameY[MAX_SIZE]; + int SameZ[MAX_SIZE]; + int NumSameX, NumSameY, NumSameZ; + CalcFloorFrac(a_SizeX, a_StartX, a_EndX, FloorX, FracX, SameX, NumSameX); + CalcFloorFrac(a_SizeY, a_StartY, a_EndY, FloorY, FracY, SameY, NumSameY); + CalcFloorFrac(a_SizeZ, a_StartZ, a_EndZ, FloorZ, FracZ, SameZ, NumSameZ); + + cCubicCell3D Cell( + m_Noise, a_Array, + a_SizeX, a_SizeY, a_SizeZ, + FracX, FracY, FracZ + ); + + Cell.InitWorkRnds(FloorX[0], FloorY[0], FloorZ[0]); + + // Calculate query values using Cell: + int FromZ = 0; + for (int z = 0; z < NumSameZ; z++) + { + int ToZ = FromZ + SameZ[z]; + int CurFloorZ = FloorZ[FromZ]; + int FromY = 0; + for (int y = 0; y < NumSameY; y++) + { + int ToY = FromY + SameY[y]; + int CurFloorY = FloorY[FromY]; + int FromX = 0; + for (int x = 0; x < NumSameX; x++) + { + int ToX = FromX + SameX[x]; + Cell.Generate(FromX, ToX, FromY, ToY, FromZ, ToZ); + Cell.Move(FloorX[ToX], CurFloorY, CurFloorZ); + FromX = ToX; + } + Cell.Move(FloorX[0], FloorY[ToY], CurFloorZ); + FromY = ToY; + } // for y + Cell.Move(FloorX[0], FloorY[0], FloorZ[ToZ]); + FromZ = ToZ; + } // for z +} + + + + + +void cCubicNoise::CalcFloorFrac( + int a_Size, + NOISE_DATATYPE a_Start, NOISE_DATATYPE a_End, + int * a_Floor, NOISE_DATATYPE * a_Frac, + int * a_Same, int & a_NumSame +) const +{ + ASSERT(a_Size > 0); + + NOISE_DATATYPE val = a_Start; + NOISE_DATATYPE dif = (a_End - a_Start) / (a_Size - 1); + for (int i = 0; i < a_Size; i++) + { + a_Floor[i] = FAST_FLOOR(val); + a_Frac[i] = val - a_Floor[i]; + val += dif; + } + + // Mark up the same floor values into a_Same / a_NumSame: + int CurFloor = a_Floor[0]; + int LastSame = 0; + a_NumSame = 0; + for (int i = 1; i < a_Size; i++) + { + if (a_Floor[i] != CurFloor) + { + a_Same[a_NumSame] = i - LastSame; + LastSame = i; + a_NumSame += 1; + CurFloor = a_Floor[i]; + } + } // for i - a_Floor[] + if (LastSame < a_Size) + { + a_Same[a_NumSame] = a_Size - LastSame; + a_NumSame += 1; + } +} + + + + + +//////////////////////////////////////////////////////////////////////////////// +// cImprovedNoise: + +cImprovedNoise::cImprovedNoise(int a_Seed) +{ + // Initialize the permutations with identity: + for (int i = 0; i < 256; i++) + { + m_Perm[i] = i; + } + + // Randomize the permutation table - swap each element with a random other element: + cNoise noise(a_Seed); + for (int i = 0; i < 256; i++) + { + int rnd = (noise.IntNoise1DInt(i) / 7) % 256; + std::swap(m_Perm[i], m_Perm[rnd]); + } + + // Copy the lower 256 entries into upper 256 entries: + for (int i = 0; i < 256; i++) + { + m_Perm[i + 256] = m_Perm[i]; + } +} + + + + + +void cImprovedNoise::Generate2D( + NOISE_DATATYPE * a_Array, + int a_SizeX, int a_SizeY, + NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, + NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY +) const +{ + size_t idx = 0; + for (int y = 0; y < a_SizeY; y++) + { + NOISE_DATATYPE ratioY = static_cast(y) / (a_SizeY - 1); + NOISE_DATATYPE noiseY = Lerp(a_StartY, a_EndY, ratioY); + int noiseYInt = FAST_FLOOR(noiseY); + int yCoord = noiseYInt & 255; + NOISE_DATATYPE noiseYFrac = noiseY - noiseYInt; + NOISE_DATATYPE fadeY = Fade(noiseYFrac); + for (int x = 0; x < a_SizeX; x++) + { + NOISE_DATATYPE ratioX = static_cast(x) / (a_SizeX - 1); + NOISE_DATATYPE noiseX = Lerp(a_StartX, a_EndX, ratioX); + int noiseXInt = FAST_FLOOR(noiseX); + int xCoord = noiseXInt & 255; + NOISE_DATATYPE noiseXFrac = noiseX - noiseXInt; + NOISE_DATATYPE fadeX = Fade(noiseXFrac); + + // Hash the coordinates: + int A = m_Perm[xCoord] + yCoord; + int AA = m_Perm[A]; + int AB = m_Perm[A + 1]; + int B = m_Perm[xCoord + 1] + yCoord; + int BA = m_Perm[B]; + int BB = m_Perm[B + 1]; + + // Lerp the gradients: + a_Array[idx++] = Lerp( + Lerp(Grad(m_Perm[AA], noiseXFrac, noiseYFrac, 0), Grad(m_Perm[BA], noiseXFrac - 1, noiseYFrac, 0), fadeX), + Lerp(Grad(m_Perm[AB], noiseXFrac, noiseYFrac - 1, 0), Grad(m_Perm[BB], noiseXFrac - 1, noiseYFrac - 1, 0), fadeX), + fadeY + ); + } // for x + } // for y +} + + + + + +void cImprovedNoise::Generate3D( + NOISE_DATATYPE * a_Array, + int a_SizeX, int a_SizeY, int a_SizeZ, + NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, + NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, + NOISE_DATATYPE a_StartZ, NOISE_DATATYPE a_EndZ +) const +{ + size_t idx = 0; + for (int z = 0; z < a_SizeZ; z++) + { + NOISE_DATATYPE ratioZ = static_cast(z) / (a_SizeZ - 1); + NOISE_DATATYPE noiseZ = Lerp(a_StartZ, a_EndZ, ratioZ); + int noiseZInt = FAST_FLOOR(noiseZ); + int zCoord = noiseZInt & 255; + NOISE_DATATYPE noiseZFrac = noiseZ - noiseZInt; + NOISE_DATATYPE fadeZ = Fade(noiseZFrac); + for (int y = 0; y < a_SizeY; y++) + { + NOISE_DATATYPE ratioY = static_cast(y) / (a_SizeY - 1); + NOISE_DATATYPE noiseY = Lerp(a_StartY, a_EndY, ratioY); + int noiseYInt = FAST_FLOOR(noiseY); + int yCoord = noiseYInt & 255; + NOISE_DATATYPE noiseYFrac = noiseY - noiseYInt; + NOISE_DATATYPE fadeY = Fade(noiseYFrac); + for (int x = 0; x < a_SizeX; x++) + { + NOISE_DATATYPE ratioX = static_cast(x) / (a_SizeX - 1); + NOISE_DATATYPE noiseX = Lerp(a_StartX, a_EndX, ratioX); + int noiseXInt = FAST_FLOOR(noiseX); + int xCoord = noiseXInt & 255; + NOISE_DATATYPE noiseXFrac = noiseX - noiseXInt; + NOISE_DATATYPE fadeX = Fade(noiseXFrac); + + // Hash the coordinates: + int A = m_Perm[xCoord] + yCoord; + int AA = m_Perm[A] + zCoord; + int AB = m_Perm[A + 1] + zCoord; + int B = m_Perm[xCoord + 1] + yCoord; + int BA = m_Perm[B] + zCoord; + int BB = m_Perm[B + 1] + zCoord; + + // Lerp the gradients: + // TODO: This may be optimized by swapping the coords and recalculating most lerps only "once every x" + a_Array[idx++] = Lerp( + Lerp( + Lerp(Grad(m_Perm[AA], noiseXFrac, noiseYFrac, noiseZFrac), Grad(m_Perm[BA], noiseXFrac - 1, noiseYFrac, noiseZFrac), fadeX), + Lerp(Grad(m_Perm[AB], noiseXFrac, noiseYFrac - 1, noiseZFrac), Grad(m_Perm[BB], noiseXFrac - 1, noiseYFrac - 1, noiseZFrac), fadeX), + fadeY + ), + Lerp( + Lerp(Grad(m_Perm[AA + 1], noiseXFrac, noiseYFrac, noiseZFrac - 1), Grad(m_Perm[BA + 1], noiseXFrac - 1, noiseYFrac, noiseZFrac - 1), fadeX), + Lerp(Grad(m_Perm[AB + 1], noiseXFrac, noiseYFrac - 1, noiseZFrac - 1), Grad(m_Perm[BB + 1], noiseXFrac - 1, noiseYFrac - 1, noiseZFrac - 1), fadeX), + fadeY + ), + fadeZ + ); + } // for x + } // for y + } // for z +} + + + + + +NOISE_DATATYPE cImprovedNoise::GetValueAt(int a_X, int a_Y, int a_Z) +{ + // Hash the coordinates: + a_X = a_X & 255; + a_Y = a_Y & 255; + a_Z = a_Z & 255; + int A = m_Perm[a_X] + a_Y; + int AA = m_Perm[A] + a_Z; + + return Grad(m_Perm[AA], 1, 1, 1); +} + + + + + diff --git a/src/Noise/Noise.h b/src/Noise/Noise.h new file mode 100644 index 000000000..323194bfd --- /dev/null +++ b/src/Noise/Noise.h @@ -0,0 +1,332 @@ + +// Noise.h + +// Declares the cNoise, cCubicNoise and cPerlinNoise classes for generating noise + +#pragma once + +#include + +/** The datatype used by all the noise generators. */ +typedef float NOISE_DATATYPE; + +#include "OctavedNoise.h" +#include "RidgedNoise.h" + + + + + +class cNoise +{ +public: + cNoise(int a_Seed); + cNoise(const cNoise & a_Noise); + + // The following functions, if not marked INLINE, are about 20 % slower + inline NOISE_DATATYPE IntNoise1D(int a_X) const; + inline NOISE_DATATYPE IntNoise2D(int a_X, int a_Y) const; + inline NOISE_DATATYPE IntNoise3D(int a_X, int a_Y, int a_Z) const; + + // Return a float number in the specified range: + inline NOISE_DATATYPE IntNoise2DInRange(int a_X, int a_Y, float a_Min, float a_Max) const + { + return a_Min + std::abs(IntNoise2D(a_X, a_Y)) * (a_Max - a_Min); + } + + // Note: These functions have a mod8-irregular chance - each of the mod8 remainders has different chance of occurrence. Divide by 8 to rectify. + inline int IntNoise1DInt(int a_X) const; + inline int IntNoise2DInt(int a_X, int a_Y) const; + inline int IntNoise3DInt(int a_X, int a_Y, int a_Z) const; + + NOISE_DATATYPE LinearNoise1D(NOISE_DATATYPE a_X) const; + NOISE_DATATYPE CosineNoise1D(NOISE_DATATYPE a_X) const; + NOISE_DATATYPE CubicNoise1D (NOISE_DATATYPE a_X) const; + NOISE_DATATYPE SmoothNoise1D(int a_X) const; + + NOISE_DATATYPE CubicNoise2D (NOISE_DATATYPE a_X, NOISE_DATATYPE a_Y) const; + + NOISE_DATATYPE CubicNoise3D (NOISE_DATATYPE a_X, NOISE_DATATYPE a_Y, NOISE_DATATYPE a_Z) const; + + void SetSeed(int a_Seed) { m_Seed = a_Seed; } + + inline static NOISE_DATATYPE CubicInterpolate (NOISE_DATATYPE a_A, NOISE_DATATYPE a_B, NOISE_DATATYPE a_C, NOISE_DATATYPE a_D, NOISE_DATATYPE a_Pct); + inline static NOISE_DATATYPE CosineInterpolate(NOISE_DATATYPE a_A, NOISE_DATATYPE a_B, NOISE_DATATYPE a_Pct); + inline static NOISE_DATATYPE LinearInterpolate(NOISE_DATATYPE a_A, NOISE_DATATYPE a_B, NOISE_DATATYPE a_Pct); + +private: + int m_Seed; +} ; + + + + + +class cCubicNoise +{ +public: + /** Maximum size of each dimension of the query arrays. */ + static const int MAX_SIZE = 512; + + + /** Creates a new instance with the specified seed. */ + cCubicNoise(int a_Seed); + + + /** Fills a 2D array with the values of the noise. */ + void Generate2D( + NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y] + int a_SizeX, int a_SizeY, ///< Count of the array, in each direction + NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction + NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY ///< Noise-space coords of the array in the Y direction + ) const; + + + /** Fills a 3D array with the values of the noise. */ + void Generate3D( + NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y + a_SizeX * a_SizeY * z] + int a_SizeX, int a_SizeY, int a_SizeZ, ///< Count of the array, in each direction + NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction + NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction + NOISE_DATATYPE a_StartZ, NOISE_DATATYPE a_EndZ ///< Noise-space coords of the array in the Z direction + ) const; + +protected: + + /** Noise used for integral random values. */ + cNoise m_Noise; + + + /** Calculates the integral and fractional parts along one axis. + a_Floor will receive the integral parts (array of a_Size ints). + a_Frac will receive the fractional parts (array of a_Size floats). + a_Same will receive the counts of items that have the same integral parts (array of up to a_Size ints). + a_NumSame will receive the count of a_Same elements (total count of different integral parts). */ + void CalcFloorFrac( + int a_Size, + NOISE_DATATYPE a_Start, NOISE_DATATYPE a_End, + int * a_Floor, NOISE_DATATYPE * a_Frac, + int * a_Same, int & a_NumSame + ) const; +} ; + + + + + +/** Improved noise, as described by Ken Perlin: http://mrl.nyu.edu/~perlin/paper445.pdf +Implementation adapted from Perlin's Java implementation: http://mrl.nyu.edu/~perlin/noise/ */ +class cImprovedNoise +{ +public: + /** Constructs a new instance of the noise obbject. + Note that this operation is quite expensive (the permutation array being constructed). */ + cImprovedNoise(int a_Seed); + + + /** Fills a 2D array with the values of the noise. */ + void Generate2D( + NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y] + int a_SizeX, int a_SizeY, ///< Count of the array, in each direction + NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction + NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY ///< Noise-space coords of the array in the Y direction + ) const; + + + /** Fills a 3D array with the values of the noise. */ + void Generate3D( + NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y + a_SizeX * a_SizeY * z] + int a_SizeX, int a_SizeY, int a_SizeZ, ///< Count of the array, in each direction + NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction + NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction + NOISE_DATATYPE a_StartZ, NOISE_DATATYPE a_EndZ ///< Noise-space coords of the array in the Z direction + ) const; + + /** Returns the value at the specified integral coords. Used for raw speed measurement. */ + NOISE_DATATYPE GetValueAt(int a_X, int a_Y, int a_Z); + +protected: + + /** The permutation table used by the noise function. Initialized using seed. */ + int m_Perm[512]; + + + /** Calculates the fade curve, 6 * t^5 - 15 * t^4 + 10 * t^3. */ + inline static NOISE_DATATYPE Fade(NOISE_DATATYPE a_T) + { + return a_T * a_T * a_T * (a_T * (a_T * 6 - 15) + 10); + } + + /** Returns the gradient value based on the hash. */ + inline static NOISE_DATATYPE Grad(int a_Hash, NOISE_DATATYPE a_X, NOISE_DATATYPE a_Y, NOISE_DATATYPE a_Z) + { + int hash = a_Hash % 16; + NOISE_DATATYPE u = (hash < 8) ? a_X : a_Y; + NOISE_DATATYPE v = (hash < 4) ? a_Y : (((hash == 12) || (hash == 14)) ? a_X : a_Z); + return (((hash & 1) == 0) ? u : -u) + (((hash & 2) == 0) ? v : -v); + } +}; + + + + + +typedef cOctavedNoise cPerlinNoise; +typedef cOctavedNoise> cRidgedMultiNoise; + + + + + +//////////////////////////////////////////////////////////////////////////////// +// Inline function definitions: +// These need to be in the header, otherwise linker error occur in MSVC + +NOISE_DATATYPE cNoise::IntNoise1D(int a_X) const +{ + int x = ((a_X * m_Seed) << 13) ^ a_X; + return (1 - (NOISE_DATATYPE)((x * (x * x * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824); + // returns a float number in the range of [-1, 1] +} + + + + + +NOISE_DATATYPE cNoise::IntNoise2D(int a_X, int a_Y) const +{ + int n = a_X + a_Y * 57 + m_Seed * 57 * 57; + n = (n << 13) ^ n; + return (1 - (NOISE_DATATYPE)((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824); + // returns a float number in the range of [-1, 1] +} + + + + + +NOISE_DATATYPE cNoise::IntNoise3D(int a_X, int a_Y, int a_Z) const +{ + int n = a_X + a_Y * 57 + a_Z * 57 * 57 + m_Seed * 57 * 57 * 57; + n = (n << 13) ^ n; + return ((NOISE_DATATYPE)1 - (NOISE_DATATYPE)((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0f); + // returns a float number in the range of [-1, 1] +} + + + + + +int cNoise::IntNoise1DInt(int a_X) const +{ + int x = ((a_X * m_Seed) << 13) ^ a_X; + return ((x * (x * x * 15731 + 789221) + 1376312589) & 0x7fffffff); +} + + + + + +int cNoise::IntNoise2DInt(int a_X, int a_Y) const +{ + int n = a_X + a_Y * 57 + m_Seed * 57 * 57; + n = (n << 13) ^ n; + return ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff); +} + + + + + +int cNoise::IntNoise3DInt(int a_X, int a_Y, int a_Z) const +{ + int n = a_X + a_Y * 57 + a_Z * 57 * 57 + m_Seed * 57 * 57 * 57; + n = (n << 13) ^ n; + return ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff); +} + + + + + +NOISE_DATATYPE cNoise::CubicInterpolate(NOISE_DATATYPE a_A, NOISE_DATATYPE a_B, NOISE_DATATYPE a_C, NOISE_DATATYPE a_D, NOISE_DATATYPE a_Pct) +{ + NOISE_DATATYPE P = (a_D - a_C) - (a_A - a_B); + NOISE_DATATYPE Q = (a_A - a_B) - P; + NOISE_DATATYPE R = a_C - a_A; + NOISE_DATATYPE S = a_B; + + return ((P * a_Pct + Q) * a_Pct + R) * a_Pct + S; +} + + + + + +NOISE_DATATYPE cNoise::CosineInterpolate(NOISE_DATATYPE a_A, NOISE_DATATYPE a_B, NOISE_DATATYPE a_Pct) +{ + const NOISE_DATATYPE ft = a_Pct * (NOISE_DATATYPE)3.1415927; + const NOISE_DATATYPE f = (NOISE_DATATYPE)((NOISE_DATATYPE)(1 - cos(ft)) * (NOISE_DATATYPE)0.5); + return a_A * (1 - f) + a_B * f; +} + + + + + +NOISE_DATATYPE cNoise::LinearInterpolate(NOISE_DATATYPE a_A, NOISE_DATATYPE a_B, NOISE_DATATYPE a_Pct) +{ + return a_A * (1 - a_Pct) + a_B * a_Pct; +} + + + + + +//////////////////////////////////////////////////////////////////////////////// +// Global functions: + +/** Exports the noise array into a file. +a_Coeff specifies the value that each array value is multiplied by before being converted into a byte. */ +extern void Debug2DNoise(const NOISE_DATATYPE * a_Array, int a_SizeX, int a_SizeY, const AString & a_FileNameBase, NOISE_DATATYPE a_Coeff = 32); + +/** Exports the noise array into a set of files, ordered by XY and XZ. +a_Coeff specifies the value that each array value is multiplied by before being converted into a byte. */ +extern void Debug3DNoise(const NOISE_DATATYPE * a_Array, int a_SizeX, int a_SizeY, int a_SizeZ, const AString & a_FileNameBase, NOISE_DATATYPE a_Coeff = 32); + + + + +/** Linearly interpolates between two values. +Assumes that a_Ratio is in range [0, 1]. */ +inline NOISE_DATATYPE Lerp(NOISE_DATATYPE a_Val1, NOISE_DATATYPE a_Val2, NOISE_DATATYPE a_Ratio) +{ + return a_Val1 + (a_Val2 - a_Val1) * a_Ratio; +} + + + + + +/** Linearly interpolates between two values, clamping the ratio to [0, 1] first. */ +inline NOISE_DATATYPE ClampedLerp(NOISE_DATATYPE a_Val1, NOISE_DATATYPE a_Val2, NOISE_DATATYPE a_Ratio) +{ + if (a_Ratio < 0) + { + return a_Val1; + } + if (a_Ratio > 1) + { + return a_Val2; + } + return Lerp(a_Val1, a_Val2, a_Ratio); +} + + + + + + + + + diff --git a/src/Noise/OctavedNoise.h b/src/Noise/OctavedNoise.h new file mode 100644 index 000000000..166d2c205 --- /dev/null +++ b/src/Noise/OctavedNoise.h @@ -0,0 +1,192 @@ + +// OctavedNoise.h + +// Implements the cOctavedNoise class template representing a noise generator that layers several octaves of another noise + + + + + +#pragma once + + + + + +template +class cOctavedNoise +{ +public: + cOctavedNoise(int a_Seed = 0): + m_Seed(a_Seed) + { + } + + + /** Sets a new seed for the generators. Relays the seed to all underlying octaves. */ + void SetSeed(int a_Seed) + { + m_Seed = a_Seed; + for (auto oct: m_Octaves) + { + oct->SetSeed(a_Seed); + } + } + + + /** */ + void AddOctave(NOISE_DATATYPE a_Frequency, NOISE_DATATYPE a_Amplitude) + { + m_Octaves.emplace_back(m_Seed, a_Frequency, a_Amplitude); + } + + + /** Fills a 2D array with the values of the noise. */ + void Generate2D( + NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y] + int a_SizeX, int a_SizeY, ///< Count of the array, in each direction + NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction + NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction + NOISE_DATATYPE * a_Workspace ///< Workspace that this function can use and trash. Must be valid. + ) const + { + // Check that state is alright: + if (m_Octaves.empty()) + { + ASSERT(!"Perlin: No octaves to generate!"); + return; + } + + // Allocate the workspace on the heap, if it wasn't given: + std::unique_ptr workspaceHeap; + if (a_Workspace == nullptr) + { + workspaceHeap.reset(new NOISE_DATATYPE[a_SizeX * a_SizeY]); + a_Workspace = workspaceHeap.get(); + } + + // Generate the first octave directly into array: + const cOctave & FirstOctave = m_Octaves.front(); + int ArrayCount = a_SizeX * a_SizeY; + FirstOctave.m_Noise.Generate2D( + a_Workspace, a_SizeX, a_SizeY, + a_StartX * FirstOctave.m_Frequency, a_EndX * FirstOctave.m_Frequency, + a_StartY * FirstOctave.m_Frequency, a_EndY * FirstOctave.m_Frequency + ); + NOISE_DATATYPE Amplitude = FirstOctave.m_Amplitude; + for (int i = 0; i < ArrayCount; i++) + { + a_Array[i] = a_Workspace[i] * Amplitude; + } + + // Add each octave: + for (auto itr = m_Octaves.cbegin() + 1, end = m_Octaves.cend(); itr != end; ++itr) + { + // Generate the noise for the octave: + itr->m_Noise.Generate2D( + a_Workspace, a_SizeX, a_SizeY, + a_StartX * itr->m_Frequency, a_EndX * itr->m_Frequency, + a_StartY * itr->m_Frequency, a_EndY * itr->m_Frequency + ); + // Add it into the output: + NOISE_DATATYPE Amplitude = itr->m_Amplitude; + for (int i = 0; i < ArrayCount; i++) + { + a_Array[i] += a_Workspace[i] * Amplitude; + } + } // for itr - m_Octaves[] + } + + + /** Fills a 3D array with the values of the noise. */ + void Generate3D( + NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y + a_SizeX * a_SizeY * z] + int a_SizeX, int a_SizeY, int a_SizeZ, ///< Count of the array, in each direction + NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction + NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction + NOISE_DATATYPE a_StartZ, NOISE_DATATYPE a_EndZ, ///< Noise-space coords of the array in the Z direction + NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash, same size as a_Array + ) const + { + // Check that state is alright: + if (m_Octaves.empty()) + { + ASSERT(!"Perlin: No octaves to generate!"); + return; + } + + // Allocate the workspace on the heap, if it wasn't given: + std::unique_ptr workspaceHeap; + if (a_Workspace == nullptr) + { + workspaceHeap.reset(new NOISE_DATATYPE[a_SizeX * a_SizeY * a_SizeZ]); + a_Workspace = workspaceHeap.get(); + } + + // Generate the first octave directly into array: + const cOctave & FirstOctave = m_Octaves.front(); + int ArrayCount = a_SizeX * a_SizeY * a_SizeZ; + FirstOctave.m_Noise.Generate3D( + a_Workspace, a_SizeX, a_SizeY, a_SizeZ, + a_StartX * FirstOctave.m_Frequency, a_EndX * FirstOctave.m_Frequency, + a_StartY * FirstOctave.m_Frequency, a_EndY * FirstOctave.m_Frequency, + a_StartZ * FirstOctave.m_Frequency, a_EndZ * FirstOctave.m_Frequency + ); + NOISE_DATATYPE Amplitude = FirstOctave.m_Amplitude; + for (int i = 0; i < ArrayCount; i++) + { + a_Array[i] = a_Workspace[i] * Amplitude; + } + + // Add each octave: + for (auto itr = m_Octaves.cbegin() + 1, end = m_Octaves.cend(); itr != end; ++itr) + { + // Generate the noise for the octave: + itr->m_Noise.Generate3D( + a_Workspace, a_SizeX, a_SizeY, a_SizeZ, + a_StartX * itr->m_Frequency, a_EndX * itr->m_Frequency, + a_StartY * itr->m_Frequency, a_EndY * itr->m_Frequency, + a_StartZ * itr->m_Frequency, a_EndZ * itr->m_Frequency + ); + // Add it into the output: + NOISE_DATATYPE Amplitude = itr->m_Amplitude; + for (int i = 0; i < ArrayCount; i++) + { + a_Array[i] += a_Workspace[i] * Amplitude; + } + } // for itr - m_Octaves[] + } + +protected: + /** Stores information and state for one octave of the noise. */ + class cOctave + { + public: + N m_Noise; + + /** Coord multiplier. */ + NOISE_DATATYPE m_Frequency; + + /** Value multiplier. */ + NOISE_DATATYPE m_Amplitude; + + cOctave(int a_Seed, NOISE_DATATYPE a_Frequency, NOISE_DATATYPE a_Amplitude) : + m_Noise(a_Seed), + m_Frequency(a_Frequency), + m_Amplitude(a_Amplitude) + { + } + } ; + typedef std::vector cOctaves; + + + /** The seed used by the underlying generators. */ + int m_Seed; + + /** The octaves that compose this noise. */ + cOctaves m_Octaves; +}; + + + + diff --git a/src/Noise/RidgedNoise.h b/src/Noise/RidgedNoise.h new file mode 100644 index 000000000..69b480f60 --- /dev/null +++ b/src/Noise/RidgedNoise.h @@ -0,0 +1,91 @@ + +// RidgedNoise.h + +// Implements the cRidgedNoise template class that generates ridged noise based on another noise provider. + + + + + +#pragma once + + + + + +template +class cRidgedNoise +{ +public: + /** Creates a new instance with the seed set to 0. */ + cRidgedNoise(void): + m_Noise(0) + { + } + + + /** Creates a new instance with the specified seed. */ + cRidgedNoise(int a_Seed): + m_Noise(a_Seed) + { + } + + + /** Sets the seed for the underlying noise. */ + void SetSeed(int a_Seed) + { + m_Noise.SetSeed(a_Seed); + } + + + /** Fills a 2D array with the values of the noise. */ + void Generate2D( + NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y] + int a_SizeX, int a_SizeY, ///< Count of the array, in each direction + NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction + NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY ///< Noise-space coords of the array in the Y direction + ) const + { + int ArrayCount = a_SizeX * a_SizeY; + m_Noise.Generate2D( + a_Array, a_SizeX, a_SizeY, + a_StartX, a_EndX, + a_StartY, a_EndY + ); + for (int i = 0; i < ArrayCount; i++) + { + a_Array[i] = fabs(a_Array[i]); + } + } + + + /** Fills a 3D array with the values of the noise. */ + void Generate3D( + NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y + a_SizeX * a_SizeY * z] + int a_SizeX, int a_SizeY, int a_SizeZ, ///< Count of the array, in each direction + NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction + NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction + NOISE_DATATYPE a_StartZ, NOISE_DATATYPE a_EndZ ///< Noise-space coords of the array in the Z direction + ) const + { + int ArrayCount = a_SizeX * a_SizeY * a_SizeZ; + m_Noise.Generate2D( + a_Array, a_SizeX, a_SizeY, a_SizeZ, + a_StartX, a_EndX, + a_StartY, a_EndY, + a_StartZ, a_EndZ + ); + for (int i = 0; i < ArrayCount; i++) + { + a_Array[i] = fabs(a_Array[i]); + } + } + +protected: + N m_Noise; +} ; + + + + + diff --git a/src/OctavedNoise.h b/src/OctavedNoise.h deleted file mode 100644 index 166d2c205..000000000 --- a/src/OctavedNoise.h +++ /dev/null @@ -1,192 +0,0 @@ - -// OctavedNoise.h - -// Implements the cOctavedNoise class template representing a noise generator that layers several octaves of another noise - - - - - -#pragma once - - - - - -template -class cOctavedNoise -{ -public: - cOctavedNoise(int a_Seed = 0): - m_Seed(a_Seed) - { - } - - - /** Sets a new seed for the generators. Relays the seed to all underlying octaves. */ - void SetSeed(int a_Seed) - { - m_Seed = a_Seed; - for (auto oct: m_Octaves) - { - oct->SetSeed(a_Seed); - } - } - - - /** */ - void AddOctave(NOISE_DATATYPE a_Frequency, NOISE_DATATYPE a_Amplitude) - { - m_Octaves.emplace_back(m_Seed, a_Frequency, a_Amplitude); - } - - - /** Fills a 2D array with the values of the noise. */ - void Generate2D( - NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y] - int a_SizeX, int a_SizeY, ///< Count of the array, in each direction - NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction - NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction - NOISE_DATATYPE * a_Workspace ///< Workspace that this function can use and trash. Must be valid. - ) const - { - // Check that state is alright: - if (m_Octaves.empty()) - { - ASSERT(!"Perlin: No octaves to generate!"); - return; - } - - // Allocate the workspace on the heap, if it wasn't given: - std::unique_ptr workspaceHeap; - if (a_Workspace == nullptr) - { - workspaceHeap.reset(new NOISE_DATATYPE[a_SizeX * a_SizeY]); - a_Workspace = workspaceHeap.get(); - } - - // Generate the first octave directly into array: - const cOctave & FirstOctave = m_Octaves.front(); - int ArrayCount = a_SizeX * a_SizeY; - FirstOctave.m_Noise.Generate2D( - a_Workspace, a_SizeX, a_SizeY, - a_StartX * FirstOctave.m_Frequency, a_EndX * FirstOctave.m_Frequency, - a_StartY * FirstOctave.m_Frequency, a_EndY * FirstOctave.m_Frequency - ); - NOISE_DATATYPE Amplitude = FirstOctave.m_Amplitude; - for (int i = 0; i < ArrayCount; i++) - { - a_Array[i] = a_Workspace[i] * Amplitude; - } - - // Add each octave: - for (auto itr = m_Octaves.cbegin() + 1, end = m_Octaves.cend(); itr != end; ++itr) - { - // Generate the noise for the octave: - itr->m_Noise.Generate2D( - a_Workspace, a_SizeX, a_SizeY, - a_StartX * itr->m_Frequency, a_EndX * itr->m_Frequency, - a_StartY * itr->m_Frequency, a_EndY * itr->m_Frequency - ); - // Add it into the output: - NOISE_DATATYPE Amplitude = itr->m_Amplitude; - for (int i = 0; i < ArrayCount; i++) - { - a_Array[i] += a_Workspace[i] * Amplitude; - } - } // for itr - m_Octaves[] - } - - - /** Fills a 3D array with the values of the noise. */ - void Generate3D( - NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y + a_SizeX * a_SizeY * z] - int a_SizeX, int a_SizeY, int a_SizeZ, ///< Count of the array, in each direction - NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction - NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction - NOISE_DATATYPE a_StartZ, NOISE_DATATYPE a_EndZ, ///< Noise-space coords of the array in the Z direction - NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash, same size as a_Array - ) const - { - // Check that state is alright: - if (m_Octaves.empty()) - { - ASSERT(!"Perlin: No octaves to generate!"); - return; - } - - // Allocate the workspace on the heap, if it wasn't given: - std::unique_ptr workspaceHeap; - if (a_Workspace == nullptr) - { - workspaceHeap.reset(new NOISE_DATATYPE[a_SizeX * a_SizeY * a_SizeZ]); - a_Workspace = workspaceHeap.get(); - } - - // Generate the first octave directly into array: - const cOctave & FirstOctave = m_Octaves.front(); - int ArrayCount = a_SizeX * a_SizeY * a_SizeZ; - FirstOctave.m_Noise.Generate3D( - a_Workspace, a_SizeX, a_SizeY, a_SizeZ, - a_StartX * FirstOctave.m_Frequency, a_EndX * FirstOctave.m_Frequency, - a_StartY * FirstOctave.m_Frequency, a_EndY * FirstOctave.m_Frequency, - a_StartZ * FirstOctave.m_Frequency, a_EndZ * FirstOctave.m_Frequency - ); - NOISE_DATATYPE Amplitude = FirstOctave.m_Amplitude; - for (int i = 0; i < ArrayCount; i++) - { - a_Array[i] = a_Workspace[i] * Amplitude; - } - - // Add each octave: - for (auto itr = m_Octaves.cbegin() + 1, end = m_Octaves.cend(); itr != end; ++itr) - { - // Generate the noise for the octave: - itr->m_Noise.Generate3D( - a_Workspace, a_SizeX, a_SizeY, a_SizeZ, - a_StartX * itr->m_Frequency, a_EndX * itr->m_Frequency, - a_StartY * itr->m_Frequency, a_EndY * itr->m_Frequency, - a_StartZ * itr->m_Frequency, a_EndZ * itr->m_Frequency - ); - // Add it into the output: - NOISE_DATATYPE Amplitude = itr->m_Amplitude; - for (int i = 0; i < ArrayCount; i++) - { - a_Array[i] += a_Workspace[i] * Amplitude; - } - } // for itr - m_Octaves[] - } - -protected: - /** Stores information and state for one octave of the noise. */ - class cOctave - { - public: - N m_Noise; - - /** Coord multiplier. */ - NOISE_DATATYPE m_Frequency; - - /** Value multiplier. */ - NOISE_DATATYPE m_Amplitude; - - cOctave(int a_Seed, NOISE_DATATYPE a_Frequency, NOISE_DATATYPE a_Amplitude) : - m_Noise(a_Seed), - m_Frequency(a_Frequency), - m_Amplitude(a_Amplitude) - { - } - } ; - typedef std::vector cOctaves; - - - /** The seed used by the underlying generators. */ - int m_Seed; - - /** The octaves that compose this noise. */ - cOctaves m_Octaves; -}; - - - - diff --git a/src/RidgedNoise.h b/src/RidgedNoise.h deleted file mode 100644 index 69b480f60..000000000 --- a/src/RidgedNoise.h +++ /dev/null @@ -1,91 +0,0 @@ - -// RidgedNoise.h - -// Implements the cRidgedNoise template class that generates ridged noise based on another noise provider. - - - - - -#pragma once - - - - - -template -class cRidgedNoise -{ -public: - /** Creates a new instance with the seed set to 0. */ - cRidgedNoise(void): - m_Noise(0) - { - } - - - /** Creates a new instance with the specified seed. */ - cRidgedNoise(int a_Seed): - m_Noise(a_Seed) - { - } - - - /** Sets the seed for the underlying noise. */ - void SetSeed(int a_Seed) - { - m_Noise.SetSeed(a_Seed); - } - - - /** Fills a 2D array with the values of the noise. */ - void Generate2D( - NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y] - int a_SizeX, int a_SizeY, ///< Count of the array, in each direction - NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction - NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY ///< Noise-space coords of the array in the Y direction - ) const - { - int ArrayCount = a_SizeX * a_SizeY; - m_Noise.Generate2D( - a_Array, a_SizeX, a_SizeY, - a_StartX, a_EndX, - a_StartY, a_EndY - ); - for (int i = 0; i < ArrayCount; i++) - { - a_Array[i] = fabs(a_Array[i]); - } - } - - - /** Fills a 3D array with the values of the noise. */ - void Generate3D( - NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y + a_SizeX * a_SizeY * z] - int a_SizeX, int a_SizeY, int a_SizeZ, ///< Count of the array, in each direction - NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction - NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction - NOISE_DATATYPE a_StartZ, NOISE_DATATYPE a_EndZ ///< Noise-space coords of the array in the Z direction - ) const - { - int ArrayCount = a_SizeX * a_SizeY * a_SizeZ; - m_Noise.Generate2D( - a_Array, a_SizeX, a_SizeY, a_SizeZ, - a_StartX, a_EndX, - a_StartY, a_EndY, - a_StartZ, a_EndZ - ); - for (int i = 0; i < ArrayCount; i++) - { - a_Array[i] = fabs(a_Array[i]); - } - } - -protected: - N m_Noise; -} ; - - - - - diff --git a/src/VoronoiMap.h b/src/VoronoiMap.h index dfb11e9ce..56022849e 100644 --- a/src/VoronoiMap.h +++ b/src/VoronoiMap.h @@ -9,7 +9,7 @@ #pragma once -#include "Noise.h" +#include "Noise/Noise.h" -- cgit v1.2.3 From 8b028c5c78e53c149dfa8b3e7ec878f7f0428f1d Mon Sep 17 00:00:00 2001 From: Howaner Date: Tue, 18 Nov 2014 15:33:41 +0100 Subject: Finished mob spawner implementation. --- src/BlockEntities/BeaconEntity.h | 10 +------ src/BlockEntities/BlockEntity.h | 5 ---- src/BlockEntities/ChestEntity.h | 5 ---- src/BlockEntities/CommandBlockEntity.h | 8 ------ src/BlockEntities/DropSpenserEntity.h | 4 --- src/BlockEntities/FlowerPotEntity.h | 10 ------- src/BlockEntities/FurnaceEntity.h | 5 ---- src/BlockEntities/JukeboxEntity.h | 9 ------ src/BlockEntities/MobHeadEntity.h | 8 ------ src/BlockEntities/MobSpawnerEntity.cpp | 33 +++------------------- src/BlockEntities/MobSpawnerEntity.h | 19 ++++--------- src/BlockEntities/NoteEntity.h | 6 ---- src/BlockEntities/SignEntity.h | 9 ------ src/MobSpawner.h | 2 +- src/Protocol/Protocol18x.cpp | 13 +++++++++ src/WorldStorage/NBTChunkSerializer.cpp | 5 ++-- src/WorldStorage/WSSAnvil.cpp | 50 +++++++++++++++++++++++++++++++++ src/WorldStorage/WSSAnvil.h | 1 + 18 files changed, 78 insertions(+), 124 deletions(-) diff --git a/src/BlockEntities/BeaconEntity.h b/src/BlockEntities/BeaconEntity.h index d1db3a68f..783e04fe2 100644 --- a/src/BlockEntities/BeaconEntity.h +++ b/src/BlockEntities/BeaconEntity.h @@ -1,3 +1,4 @@ + // BeaconEntity.h // Declares the cBeaconEntity class representing a single beacon in the world @@ -14,15 +15,6 @@ -namespace Json -{ - class Value; -} - - - - - // tolua_begin class cBeaconEntity : public cBlockEntityWithItems diff --git a/src/BlockEntities/BlockEntity.h b/src/BlockEntities/BlockEntity.h index c778e97bc..056a88721 100644 --- a/src/BlockEntities/BlockEntity.h +++ b/src/BlockEntities/BlockEntity.h @@ -28,11 +28,6 @@ -namespace Json -{ - class Value; -}; - class cChunk; class cPlayer; class cWorld; diff --git a/src/BlockEntities/ChestEntity.h b/src/BlockEntities/ChestEntity.h index 09fffb923..a8a765430 100644 --- a/src/BlockEntities/ChestEntity.h +++ b/src/BlockEntities/ChestEntity.h @@ -7,11 +7,6 @@ -namespace Json -{ - class Value; -}; - class cClientHandle; diff --git a/src/BlockEntities/CommandBlockEntity.h b/src/BlockEntities/CommandBlockEntity.h index 217390293..8b5a2b87f 100644 --- a/src/BlockEntities/CommandBlockEntity.h +++ b/src/BlockEntities/CommandBlockEntity.h @@ -15,14 +15,6 @@ -namespace Json -{ - class Value; -} - - - - // tolua_begin diff --git a/src/BlockEntities/DropSpenserEntity.h b/src/BlockEntities/DropSpenserEntity.h index f77a28c28..8ce7f8bb8 100644 --- a/src/BlockEntities/DropSpenserEntity.h +++ b/src/BlockEntities/DropSpenserEntity.h @@ -16,10 +16,6 @@ -namespace Json -{ - class Value; -} class cClientHandle; diff --git a/src/BlockEntities/FlowerPotEntity.h b/src/BlockEntities/FlowerPotEntity.h index fc886c51f..e98d0a395 100644 --- a/src/BlockEntities/FlowerPotEntity.h +++ b/src/BlockEntities/FlowerPotEntity.h @@ -15,16 +15,6 @@ - -namespace Json -{ - class Value; -} - - - - - // tolua_begin class cFlowerPotEntity : diff --git a/src/BlockEntities/FurnaceEntity.h b/src/BlockEntities/FurnaceEntity.h index 71c2fe127..0a66c60e3 100644 --- a/src/BlockEntities/FurnaceEntity.h +++ b/src/BlockEntities/FurnaceEntity.h @@ -8,11 +8,6 @@ -namespace Json -{ - class Value; -} - class cClientHandle; diff --git a/src/BlockEntities/JukeboxEntity.h b/src/BlockEntities/JukeboxEntity.h index 7a69d6499..67a8aa62a 100644 --- a/src/BlockEntities/JukeboxEntity.h +++ b/src/BlockEntities/JukeboxEntity.h @@ -7,15 +7,6 @@ -namespace Json -{ - class Value; -} - - - - - // tolua_begin class cJukeboxEntity : diff --git a/src/BlockEntities/MobHeadEntity.h b/src/BlockEntities/MobHeadEntity.h index 7132ef558..55e45f0a6 100644 --- a/src/BlockEntities/MobHeadEntity.h +++ b/src/BlockEntities/MobHeadEntity.h @@ -14,14 +14,6 @@ -namespace Json -{ - class Value; -} - - - - // tolua_begin diff --git a/src/BlockEntities/MobSpawnerEntity.cpp b/src/BlockEntities/MobSpawnerEntity.cpp index 0d14ad647..696a109d1 100644 --- a/src/BlockEntities/MobSpawnerEntity.cpp +++ b/src/BlockEntities/MobSpawnerEntity.cpp @@ -2,7 +2,6 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "MobSpawnerEntity.h" -#include "json/json.h" #include "../World.h" #include "../FastRandom.h" @@ -38,8 +37,8 @@ void cMobSpawnerEntity::UsedBy(cPlayer * a_Player) { if (a_Player->GetEquippedItem().m_ItemType == E_ITEM_SPAWN_EGG) { - cMonster::eType MonsterType = cItemSpawnEggHandler::ItemDamageToMonsterType(a_Player->GetEquippedItem().m_ItemDamage); - if (MonsterType == mtInvalidType) + eMonsterType MonsterType = cItemSpawnEggHandler::ItemDamageToMonsterType(a_Player->GetEquippedItem().m_ItemDamage); + if (MonsterType == eMonsterType::mtInvalidType) { return; } @@ -50,7 +49,7 @@ void cMobSpawnerEntity::UsedBy(cPlayer * a_Player) { a_Player->GetInventory().RemoveOneEquippedItem(); } - LOGD("Changed monster spawner entity to %s!", GetEntityName().c_str()); + LOGD("Changed monster spawner at {%d, %d, %d} to type %s.", GetPosX(), GetPosY(), GetPosZ(), GetEntityName().c_str()); } } @@ -105,7 +104,7 @@ bool cMobSpawnerEntity::Tick(float a_Dt, cChunk & a_Chunk) void cMobSpawnerEntity::ResetTimer(void) { - m_SpawnDelay = 200 + m_World->GetTickRandomNumber(600); + m_SpawnDelay = (short) (200 + m_World->GetTickRandomNumber(600)); m_World->BroadcastBlockEntity(m_PosX, m_PosY, m_PosZ); } @@ -196,30 +195,6 @@ void cMobSpawnerEntity::SpawnEntity(void) -bool cMobSpawnerEntity::LoadFromJson(const Json::Value & a_Value) -{ - m_PosX = a_Value.get("x", 0).asInt(); - m_PosY = a_Value.get("y", 0).asInt(); - m_PosZ = a_Value.get("z", 0).asInt(); - - return true; -} - - - - - -void cMobSpawnerEntity::SaveToJson(Json::Value & a_Value) -{ - a_Value["x"] = m_PosX; - a_Value["y"] = m_PosY; - a_Value["z"] = m_PosZ; -} - - - - - AString cMobSpawnerEntity::GetEntityName() const { switch (m_Entity) diff --git a/src/BlockEntities/MobSpawnerEntity.h b/src/BlockEntities/MobSpawnerEntity.h index 7fec2699c..073eb03ab 100644 --- a/src/BlockEntities/MobSpawnerEntity.h +++ b/src/BlockEntities/MobSpawnerEntity.h @@ -8,15 +8,6 @@ -namespace Json -{ - class Value; -} - - - - - // tolua_begin class cMobSpawnerEntity : @@ -54,23 +45,23 @@ public: AString GetEntityName(void) const; /** Returns the spawn delay. */ - int GetSpawnDelay(void) const { return m_SpawnDelay; } + short GetSpawnDelay(void) const { return m_SpawnDelay; } + + /** Sets the spawn delay. */ + void SetSpawnDelay(short a_Delay) { m_SpawnDelay = a_Delay; } int GetNearbyPlayersNum(void); int GetNearbyMonsterNum(eMonsterType a_EntityType); // tolua_end - bool LoadFromJson(const Json::Value & a_Value); - virtual void SaveToJson(Json::Value & a_Value) override; - static const char * GetClassStatic(void) { return "cMobSpawnerEntity"; } private: /** The entity to spawn. */ eMonsterType m_Entity; - int m_SpawnDelay; + short m_SpawnDelay; bool m_IsActive; } ; // tolua_end diff --git a/src/BlockEntities/NoteEntity.h b/src/BlockEntities/NoteEntity.h index fc5f27d07..b33edba4e 100644 --- a/src/BlockEntities/NoteEntity.h +++ b/src/BlockEntities/NoteEntity.h @@ -5,12 +5,6 @@ #include "RedstonePoweredEntity.h" -namespace Json -{ - class Value; -} - - diff --git a/src/BlockEntities/SignEntity.h b/src/BlockEntities/SignEntity.h index 52baa486d..09ab46f0b 100644 --- a/src/BlockEntities/SignEntity.h +++ b/src/BlockEntities/SignEntity.h @@ -14,15 +14,6 @@ -namespace Json -{ - class Value; -} - - - - - // tolua_begin class cSignEntity : diff --git a/src/MobSpawner.h b/src/MobSpawner.h index 3d2d4a6ce..e8b8f191b 100644 --- a/src/MobSpawner.h +++ b/src/MobSpawner.h @@ -52,7 +52,7 @@ public : tSpawnedContainer & getSpawned(void); /** Returns true if specified type of mob can spawn on specified block */ - static bool CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, cMonster::eType a_MobType, EMCSBiome a_Biome); + static bool CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, eMonsterType a_MobType, EMCSBiome a_Biome); protected : // return a random type that can spawn on specified biome. diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index 8170a494f..42f365e80 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -41,6 +41,7 @@ Implements the 1.8.x protocol classes: #include "../BlockEntities/BeaconEntity.h" #include "../BlockEntities/CommandBlockEntity.h" #include "../BlockEntities/MobHeadEntity.h" +#include "../BlockEntities/MobSpawnerEntity.h" #include "../BlockEntities/FlowerPotEntity.h" #include "Bindings/PluginManager.h" @@ -2972,6 +2973,18 @@ void cProtocol180::cPacketizer::WriteBlockEntity(const cBlockEntity & a_BlockEnt Writer.AddString("id", "FlowerPot"); // "Tile Entity ID" - MC wiki; vanilla server always seems to send this though break; } + case E_BLOCK_MOB_SPAWNER: + { + cMobSpawnerEntity & MobSpawnerEntity = (cMobSpawnerEntity &)a_BlockEntity; + + Writer.AddInt("x", MobSpawnerEntity.GetPosX()); + Writer.AddInt("y", MobSpawnerEntity.GetPosY()); + Writer.AddInt("z", MobSpawnerEntity.GetPosZ()); + Writer.AddString("EntityId", MobSpawnerEntity.GetEntityName()); + Writer.AddShort("Delay", MobSpawnerEntity.GetSpawnDelay()); + Writer.AddString("id", "MobSpawner"); + break; + } default: break; } diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index 05d5709db..228df2686 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -294,9 +294,10 @@ void cNBTChunkSerializer::AddJukeboxEntity(cJukeboxEntity * a_Jukebox) void cNBTChunkSerializer::AddMobSpawnerEntity(cMobSpawnerEntity * a_MobSpawner) { m_Writer.BeginCompound(""); - AddBasicTileEntity(a_MobSpawner, "MobSpawner"); + AddBasicTileEntity(a_MobSpawner, "MobSpawner"); + m_Writer.AddShort("Entity", static_cast(a_MobSpawner->GetEntity())); m_Writer.AddString("EntityId", a_MobSpawner->GetEntityName()); - m_Writer.AddShort("Delay", (Int16)a_MobSpawner->GetSpawnDelay()); + m_Writer.AddShort("Delay", a_MobSpawner->GetSpawnDelay()); m_Writer.EndCompound(); } diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 0c77b4d67..451f20ca5 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -28,6 +28,7 @@ #include "../BlockEntities/NoteEntity.h" #include "../BlockEntities/SignEntity.h" #include "../BlockEntities/MobHeadEntity.h" +#include "../BlockEntities/MobSpawnerEntity.h" #include "../BlockEntities/FlowerPotEntity.h" #include "../Mobs/Monster.h" @@ -664,6 +665,7 @@ cBlockEntity * cWSSAnvil::LoadBlockEntityFromNBT(const cParsedNBT & a_NBT, int a case E_BLOCK_HOPPER: return LoadHopperFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ); case E_BLOCK_JUKEBOX: return LoadJukeboxFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ); case E_BLOCK_LIT_FURNACE: return LoadFurnaceFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_LIT_FURNACE, a_BlockMeta); + case E_BLOCK_MOB_SPAWNER: return LoadMobSpawnerFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ); case E_BLOCK_NOTE_BLOCK: return LoadNoteBlockFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ); case E_BLOCK_SIGN_POST: return LoadSignFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_SIGN_POST); case E_BLOCK_TRAPPED_CHEST: return LoadChestFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_TRAPPED_CHEST); @@ -1085,6 +1087,54 @@ cBlockEntity * cWSSAnvil::LoadFurnaceFromNBT(const cParsedNBT & a_NBT, int a_Tag +cBlockEntity * cWSSAnvil::LoadMobSpawnerFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ) +{ + // Check if the data has a proper type: + if (!CheckBlockEntityType(a_NBT, a_TagIdx, "MobSpawner")) + { + return nullptr; + } + + std::auto_ptr MobSpawner(new cMobSpawnerEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); + + // Load entity (MCServer worlds): + int Type = a_NBT.FindChildByName(a_TagIdx, "Entity"); + if ((Type >= 0) && (a_NBT.GetType(Type) == TAG_Short)) + { + short MonsterType = a_NBT.GetShort(Type); + if ((MonsterType >= 50) && (MonsterType <= 120)) + { + MobSpawner->SetEntity(static_cast(MonsterType)); + } + } + else + { + // Load entity (vanilla worlds): + Type = a_NBT.FindChildByName(a_TagIdx, "EntityId"); + if ((Type >= 0) && (a_NBT.GetType(Type) == TAG_String)) + { + eMonsterType MonsterType = cMonster::StringToMobType(a_NBT.GetString(Type)); + if (MonsterType != eMonsterType::mtInvalidType) + { + MobSpawner->SetEntity(MonsterType); + } + } + } + + // Load delay: + int Delay = a_NBT.FindChildByName(a_TagIdx, "Delay"); + if ((Delay >= 0) && (a_NBT.GetType(Delay) == TAG_Short)) + { + MobSpawner->SetSpawnDelay(a_NBT.GetShort(Delay)); + } + + return MobSpawner.release(); +} + + + + + cBlockEntity * cWSSAnvil::LoadHopperFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ) { // Check if the data has a proper type: diff --git a/src/WorldStorage/WSSAnvil.h b/src/WorldStorage/WSSAnvil.h index 9c579a617..7a98a9a04 100644 --- a/src/WorldStorage/WSSAnvil.h +++ b/src/WorldStorage/WSSAnvil.h @@ -148,6 +148,7 @@ protected: cBlockEntity * LoadDropperFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ); cBlockEntity * LoadFlowerPotFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ); cBlockEntity * LoadFurnaceFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); + cBlockEntity * LoadMobSpawnerFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ); cBlockEntity * LoadHopperFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ); cBlockEntity * LoadJukeboxFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ); cBlockEntity * LoadMobHeadFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ); -- cgit v1.2.3 From c048f2bd95bd74c54f32e37978da47d450ac567b Mon Sep 17 00:00:00 2001 From: Mattes D Date: Tue, 18 Nov 2014 23:21:57 +0100 Subject: Added a cInterpolNoise template for faster noise generator. Used an instance of it in the Noise3D generator. --- src/Generating/Noise3DGenerator.cpp | 53 ++++- src/Generating/Noise3DGenerator.h | 5 +- src/Noise/InterpolNoise.h | 385 ++++++++++++++++++++++++++++++++++++ 3 files changed, 439 insertions(+), 4 deletions(-) create mode 100644 src/Noise/InterpolNoise.h diff --git a/src/Generating/Noise3DGenerator.cpp b/src/Generating/Noise3DGenerator.cpp index 654e9d01f..d051948c4 100644 --- a/src/Generating/Noise3DGenerator.cpp +++ b/src/Generating/Noise3DGenerator.cpp @@ -6,6 +6,7 @@ #include "Globals.h" #include "Noise3DGenerator.h" #include "../OSSupport/File.h" +#include "../OSSupport/Timer.h" #include "../IniFile.h" #include "../LinearInterpolation.h" #include "../LinearUpscale.h" @@ -61,6 +62,50 @@ public: +#if 0 +// Perform speed test of the cInterpolNoise class +static class cInterpolNoiseSpeedTest +{ +public: + cInterpolNoiseSpeedTest(void) + { + printf("Evaluating 3D noise performance...\n"); + static const int SIZE_X = 128; + static const int SIZE_Y = 128; + static const int SIZE_Z = 128; + static const NOISE_DATATYPE MUL = 80; + std::unique_ptr arr(new NOISE_DATATYPE[SIZE_X * SIZE_Y * SIZE_Z]); + cTimer timer; + + // Test the cInterpolNoise: + cInterpolNoise interpNoise(1); + long long start = timer.GetNowTime(); + for (int i = 0; i < 30; i++) + { + interpNoise.Generate3D(arr.get(), SIZE_X, SIZE_Y, SIZE_Z, MUL * i, MUL * i + MUL, 0, MUL, 0, MUL); + } + long long end = timer.GetNowTime(); + printf("InterpolNoise took %.02f sec\n", static_cast(end - start) / 1000); + + // Test the cCubicNoise: + cCubicNoise cubicNoise(1); + start = timer.GetNowTime(); + for (int i = 0; i < 30; i++) + { + cubicNoise.Generate3D(arr.get(), SIZE_X, SIZE_Y, SIZE_Z, MUL * i, MUL * i + MUL, 0, MUL, 0, MUL); + } + end = timer.GetNowTime(); + printf("CubicNoise took %.02f sec\n", static_cast(end - start) / 1000); + printf("3D noise performance comparison finished.\n"); + } + +} g_InterpolNoiseSpeedTest; +#endif + + + + + //////////////////////////////////////////////////////////////////////////////// // cNoise3DGenerator: @@ -69,9 +114,11 @@ cNoise3DGenerator::cNoise3DGenerator(cChunkGenerator & a_ChunkGenerator) : m_Perlin(1000), m_Cubic(1000) { - m_Perlin.AddOctave(1, (NOISE_DATATYPE)0.5); - m_Perlin.AddOctave((NOISE_DATATYPE)0.5, 1); - m_Perlin.AddOctave((NOISE_DATATYPE)0.5, 2); + m_Perlin.AddOctave(1, 1); + m_Perlin.AddOctave(2, 0.5); + m_Perlin.AddOctave(4, 0.25); + m_Perlin.AddOctave(8, 0.125); + m_Perlin.AddOctave(16, 0.0625); #if 0 // DEBUG: Test the noise generation: diff --git a/src/Generating/Noise3DGenerator.h b/src/Generating/Noise3DGenerator.h index 8a6e97e1c..d198c5498 100644 --- a/src/Generating/Noise3DGenerator.h +++ b/src/Generating/Noise3DGenerator.h @@ -14,6 +14,7 @@ #include "ComposableGenerator.h" #include "../Noise/Noise.h" +#include "../Noise/InterpolNoise.h" @@ -43,7 +44,9 @@ protected: static const int DIM_Y = 1 + cChunkDef::Height / UPSCALE_Y; static const int DIM_Z = 1 + cChunkDef::Width / UPSCALE_Z; - cPerlinNoise m_Perlin; // The base 3D noise source for the actual composition + /** The base 3D noise source for the actual composition */ + cOctavedNoise m_Perlin; + cCubicNoise m_Cubic; // The noise used for heightmap directing int m_SeaLevel; diff --git a/src/Noise/InterpolNoise.h b/src/Noise/InterpolNoise.h new file mode 100644 index 000000000..69e7194c9 --- /dev/null +++ b/src/Noise/InterpolNoise.h @@ -0,0 +1,385 @@ + +// InterpolNoise.h + +// Implements the cInterpolNoise class template representing a noise that interpolates the values between integer coords from a single set of neighbors + + + + + +#pragma once + +#include "Noise.h" + +#define FAST_FLOOR(x) (((x) < 0) ? (((int)x) - 1) : ((int)x)) + + + + + +//////////////////////////////////////////////////////////////////////////////// +// cInterpolCell3D: + +/** Holds a cache of the last calculated integral noise values and interpolates between them en masse. +Provides a massive optimization for cInterpolNoise. +Works by calculating multiple noise values (that have the same integral noise coords) at once. The underlying noise values +needn't be recalculated for these values, only the interpolation is done within the unit cube. */ +template +class cInterpolCell3D +{ +public: + cInterpolCell3D( + const cNoise & a_Noise, ///< Noise to use for generating the random values + NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y] + int a_SizeX, int a_SizeY, int a_SizeZ, ///< Count of the array, in each direction + const NOISE_DATATYPE * a_FracX, ///< Pointer to the array that stores the X fractional values + const NOISE_DATATYPE * a_FracY, ///< Pointer to the attay that stores the Y fractional values + const NOISE_DATATYPE * a_FracZ ///< Pointer to the array that stores the Z fractional values + ): + m_Noise(a_Noise), + m_WorkRnds(&m_Workspace1), + m_CurFloorX(0), + m_CurFloorY(0), + m_CurFloorZ(0), + m_Array(a_Array), + m_SizeX(a_SizeX), + m_SizeY(a_SizeY), + m_SizeZ(a_SizeZ), + m_FracX(a_FracX), + m_FracY(a_FracY), + m_FracZ(a_FracZ) + { + } + + + /** Generates part of the output array using current m_WorkRnds[]. */ + void Generate( + int a_FromX, int a_ToX, + int a_FromY, int a_ToY, + int a_FromZ, int a_ToZ + ) + { + for (int z = a_FromZ; z < a_ToZ; z++) + { + int idxZ = z * m_SizeX * m_SizeY; + NOISE_DATATYPE Interp2[2][2]; + NOISE_DATATYPE FracZ = T::coeff(m_FracZ[z]); + for (int x = 0; x < 2; x++) + { + for (int y = 0; y < 2; y++) + { + Interp2[x][y] = Lerp((*m_WorkRnds)[x][y][0], (*m_WorkRnds)[x][y][1], FracZ); + } + } + for (int y = a_FromY; y < a_ToY; y++) + { + NOISE_DATATYPE Interp[2]; + NOISE_DATATYPE FracY = T::coeff(m_FracY[y]); + Interp[0] = Lerp(Interp2[0][0], Interp2[0][1], FracY); + Interp[1] = Lerp(Interp2[1][0], Interp2[1][1], FracY); + int idx = idxZ + y * m_SizeX + a_FromX; + for (int x = a_FromX; x < a_ToX; x++) + { + m_Array[idx++] = Lerp(Interp[0], Interp[1], T::coeff(m_FracX[x])); + } // for x + } // for y + } // for z + } + + + /** Initializes m_WorkRnds[] with the specified Floor values. */ + void InitWorkRnds(int a_FloorX, int a_FloorY, int a_FloorZ) + { + m_CurFloorX = a_FloorX; + m_CurFloorY = a_FloorY; + m_CurFloorZ = a_FloorZ; + (*m_WorkRnds)[0][0][0] = (NOISE_DATATYPE)m_Noise.IntNoise3D(m_CurFloorX, m_CurFloorY, m_CurFloorZ); + (*m_WorkRnds)[0][0][1] = (NOISE_DATATYPE)m_Noise.IntNoise3D(m_CurFloorX, m_CurFloorY, m_CurFloorZ + 1); + (*m_WorkRnds)[0][1][0] = (NOISE_DATATYPE)m_Noise.IntNoise3D(m_CurFloorX, m_CurFloorY + 1, m_CurFloorZ); + (*m_WorkRnds)[0][1][1] = (NOISE_DATATYPE)m_Noise.IntNoise3D(m_CurFloorX, m_CurFloorY + 1, m_CurFloorZ + 1); + (*m_WorkRnds)[1][0][0] = (NOISE_DATATYPE)m_Noise.IntNoise3D(m_CurFloorX + 1, m_CurFloorY, m_CurFloorZ); + (*m_WorkRnds)[1][0][1] = (NOISE_DATATYPE)m_Noise.IntNoise3D(m_CurFloorX + 1, m_CurFloorY, m_CurFloorZ + 1); + (*m_WorkRnds)[1][1][0] = (NOISE_DATATYPE)m_Noise.IntNoise3D(m_CurFloorX + 1, m_CurFloorY + 1, m_CurFloorZ); + (*m_WorkRnds)[1][1][1] = (NOISE_DATATYPE)m_Noise.IntNoise3D(m_CurFloorX + 1, m_CurFloorY + 1, m_CurFloorZ + 1); + } + + + /** Updates m_WorkRnds[] for the new Floor values. */ + void Move(int a_NewFloorX, int a_NewFloorY, int a_NewFloorZ) + { + // Swap the doublebuffer: + int OldFloorX = m_CurFloorX; + int OldFloorY = m_CurFloorY; + int OldFloorZ = m_CurFloorZ; + Workspace * OldWorkRnds = m_WorkRnds; + m_WorkRnds = (m_WorkRnds == &m_Workspace1) ? &m_Workspace2 : &m_Workspace1; + + // Reuse as much of the old workspace as possible: + // TODO: Try out if simply calculating all 8 elements each time is faster than this monster loop + int DiffX = OldFloorX - a_NewFloorX; + int DiffY = OldFloorY - a_NewFloorY; + int DiffZ = OldFloorZ - a_NewFloorZ; + for (int x = 0; x < 2; x++) + { + int cx = a_NewFloorX + x; + int OldX = x - DiffX; // Where would this X be in the old grid? + for (int y = 0; y < 2; y++) + { + int cy = a_NewFloorY + y; + int OldY = y - DiffY; // Where would this Y be in the old grid? + for (int z = 0; z < 2; z++) + { + int cz = a_NewFloorZ + z; + int OldZ = z - DiffZ; + if ((OldX >= 0) && (OldX < 2) && (OldY >= 0) && (OldY < 2) && (OldZ >= 0) && (OldZ < 2)) + { + (*m_WorkRnds)[x][y][z] = (*OldWorkRnds)[OldX][OldY][OldZ]; + } + else + { + (*m_WorkRnds)[x][y][z] = (NOISE_DATATYPE)m_Noise.IntNoise3D(cx, cy, cz); + } + } // for z + } // for y + } // for x + m_CurFloorX = a_NewFloorX; + m_CurFloorY = a_NewFloorY; + m_CurFloorZ = a_NewFloorZ; + } + +protected: + typedef NOISE_DATATYPE Workspace[2][2][2]; + + /** The noise used for generating the values at integral coords. */ + const cNoise & m_Noise; + + /** The current random values; points to either m_Workspace1 or m_Workspace2 (doublebuffering) */ + Workspace * m_WorkRnds; + + /** Buffer 1 for workspace doublebuffering, used in Move() */ + Workspace m_Workspace1; + + /** Buffer 2 for workspace doublebuffering, used in Move() */ + Workspace m_Workspace2; + + /** The integral coords of the currently calculated WorkRnds[] */ + int m_CurFloorX, m_CurFloorY, m_CurFloorZ; + + /** The output array where the noise is calculated. */ + NOISE_DATATYPE * m_Array; + + /** Dimensions of the output array. */ + int m_SizeX, m_SizeY, m_SizeZ; + + /** Arrays holding the fractional values of the coords in each direction. */ + const NOISE_DATATYPE * m_FracX; + const NOISE_DATATYPE * m_FracY; + const NOISE_DATATYPE * m_FracZ; +} ; + + + + + +//////////////////////////////////////////////////////////////////////////////// +// cInterpolNoise: + +template +class cInterpolNoise +{ + /** Maximum size, for each direction, of the generated array. */ + static const int MAX_SIZE = 256; + +public: + cInterpolNoise(int a_Seed): + m_Noise(a_Seed) + { + } + + + /** Sets a new seed for the generators. Relays the seed to the underlying noise. */ + void SetSeed(int a_Seed) + { + m_Noise.SetSeed(a_Seed); + } + + + /** Fills a 2D array with the values of the noise. */ + void Generate2D( + NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y] + int a_SizeX, int a_SizeY, ///< Count of the array, in each direction + NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction + NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY ///< Noise-space coords of the array in the Y direction + ) const + { + // Check params: + ASSERT(a_SizeX > 1); + ASSERT(a_SizeY > 1); + + // Generate the noise: + size_t idx = 0; + for (int y = 0; y < a_SizeY; y++) + { + NOISE_DATATYPE ratioY = static_cast(y) / (a_SizeY - 1); + NOISE_DATATYPE noiseY = Lerp(a_StartY, a_EndY, ratioY); + int noiseYInt = FAST_FLOOR(noiseY); + NOISE_DATATYPE ratioY = typename T(noiseY - static_cast(noiseYInt)); + for (int x = 0; x < a_SizeX; x++) + { + NOISE_DATATYPE ratioX = static_cast(x) / (a_SizeX - 1); + NOISE_DATATYPE noiseX = Lerp(a_StartX, a_EndX, ratioX); + int noiseXInt = FAST_FLOOR(noiseX); + NOISE_DATATYPE ratioX = typename T(noiseX - static_cast(noiseXInt)); + + NOISE_DATATYPE valx0y0 = m_Noise.IntNoise2D(noiseXInt, noiseYInt); + NOISE_DATATYPE valx1y0 = m_Noise.IntNoise2D(noiseXInt + 1, noiseYInt); + NOISE_DATATYPE valx0y1 = m_Noise.IntNoise2D(noiseXInt, noiseYInt + 1); + NOISE_DATATYPE valx1y1 = m_Noise.IntNoise2D(noiseXInt + 1, noiseYInt + 1); + NOISE_DATATYPE valx0 = Lerp(valx0y0, valx0y1, ratioY); + NOISE_DATATYPE valx1 = Lerp(valx1y1, valx1y1, ratioY); + a_Array[idx++] = Lerp(valx0, valx1, ratioX); + } // for x + } // for y + } + + + /** Fills a 3D array with the values of the noise. */ + void Generate3D( + NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y + a_SizeX * a_SizeY * z] + int a_SizeX, int a_SizeY, int a_SizeZ, ///< Count of the array, in each direction + NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction + NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction + NOISE_DATATYPE a_StartZ, NOISE_DATATYPE a_EndZ ///< Noise-space coords of the array in the Z direction + ) const + { + // Check params: + ASSERT(a_SizeX > 1); + ASSERT(a_SizeY > 1); + + ASSERT(a_SizeX < MAX_SIZE); + ASSERT(a_SizeY < MAX_SIZE); + ASSERT(a_SizeZ < MAX_SIZE); + ASSERT(a_StartX < a_EndX); + ASSERT(a_StartY < a_EndY); + ASSERT(a_StartZ < a_EndZ); + + // Calculate the integral and fractional parts of each coord: + int FloorX[MAX_SIZE]; + int FloorY[MAX_SIZE]; + int FloorZ[MAX_SIZE]; + NOISE_DATATYPE FracX[MAX_SIZE]; + NOISE_DATATYPE FracY[MAX_SIZE]; + NOISE_DATATYPE FracZ[MAX_SIZE]; + int SameX[MAX_SIZE]; + int SameY[MAX_SIZE]; + int SameZ[MAX_SIZE]; + int NumSameX, NumSameY, NumSameZ; + CalcFloorFrac(a_SizeX, a_StartX, a_EndX, FloorX, FracX, SameX, NumSameX); + CalcFloorFrac(a_SizeY, a_StartY, a_EndY, FloorY, FracY, SameY, NumSameY); + CalcFloorFrac(a_SizeZ, a_StartZ, a_EndZ, FloorZ, FracZ, SameZ, NumSameZ); + + cInterpolCell3D Cell( + m_Noise, a_Array, + a_SizeX, a_SizeY, a_SizeZ, + FracX, FracY, FracZ + ); + + Cell.InitWorkRnds(FloorX[0], FloorY[0], FloorZ[0]); + + // Calculate query values using Cell: + int FromZ = 0; + for (int z = 0; z < NumSameZ; z++) + { + int ToZ = FromZ + SameZ[z]; + int CurFloorZ = FloorZ[FromZ]; + int FromY = 0; + for (int y = 0; y < NumSameY; y++) + { + int ToY = FromY + SameY[y]; + int CurFloorY = FloorY[FromY]; + int FromX = 0; + for (int x = 0; x < NumSameX; x++) + { + int ToX = FromX + SameX[x]; + Cell.Generate(FromX, ToX, FromY, ToY, FromZ, ToZ); + Cell.Move(FloorX[ToX], CurFloorY, CurFloorZ); + FromX = ToX; + } + Cell.Move(FloorX[0], FloorY[ToY], CurFloorZ); + FromY = ToY; + } // for y + Cell.Move(FloorX[0], FloorY[0], FloorZ[ToZ]); + FromZ = ToZ; + } // for z + } + +protected: + + /** The noise used for the underlying value generation. */ + cNoise m_Noise; + + + /** Calculates the integral and fractional parts along one axis. + a_Floor will receive the integral parts (array of a_Size ints). + a_Frac will receive the fractional parts (array of a_Size floats). + a_Same will receive the counts of items that have the same integral parts (array of up to a_Size ints). + a_NumSame will receive the count of a_Same elements (total count of different integral parts). */ + void CalcFloorFrac( + int a_Size, + NOISE_DATATYPE a_Start, NOISE_DATATYPE a_End, + int * a_Floor, NOISE_DATATYPE * a_Frac, + int * a_Same, int & a_NumSame + ) const + { + ASSERT(a_Size > 0); + + // Calculate the floor and frac values: + NOISE_DATATYPE val = a_Start; + NOISE_DATATYPE dif = (a_End - a_Start) / (a_Size - 1); + for (int i = 0; i < a_Size; i++) + { + a_Floor[i] = FAST_FLOOR(val); + a_Frac[i] = val - a_Floor[i]; + val += dif; + } + + // Mark up the same floor values into a_Same / a_NumSame: + int CurFloor = a_Floor[0]; + int LastSame = 0; + a_NumSame = 0; + for (int i = 1; i < a_Size; i++) + { + if (a_Floor[i] != CurFloor) + { + a_Same[a_NumSame] = i - LastSame; + LastSame = i; + a_NumSame += 1; + CurFloor = a_Floor[i]; + } + } // for i - a_Floor[] + if (LastSame < a_Size) + { + a_Same[a_NumSame] = a_Size - LastSame; + a_NumSame += 1; + } + } +}; + + + + + +/** A fifth-degree curve for interpolating. +Implemented as a functor for better chance of inlining. */ +struct Interp5Deg +{ + static NOISE_DATATYPE coeff(NOISE_DATATYPE a_Val) + { + return a_Val * a_Val * a_Val * (a_Val * (a_Val * 6 - 15) + 10); + } +}; + +typedef cInterpolNoise cInterp5DegNoise; + + + -- cgit v1.2.3 From d7d4fcbdfee84bc8ac556977226aaf1d86fe7741 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Tue, 18 Nov 2014 23:22:09 +0100 Subject: cOctavedNoise: Added a forgotten comment. --- src/Noise/OctavedNoise.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Noise/OctavedNoise.h b/src/Noise/OctavedNoise.h index 166d2c205..592debbd3 100644 --- a/src/Noise/OctavedNoise.h +++ b/src/Noise/OctavedNoise.h @@ -34,7 +34,7 @@ public: } - /** */ + /** Adds a new octave to the list of octaves that compose this noise. */ void AddOctave(NOISE_DATATYPE a_Frequency, NOISE_DATATYPE a_Amplitude) { m_Octaves.emplace_back(m_Seed, a_Frequency, a_Amplitude); -- cgit v1.2.3 From b177ff8ec58374945ee184800beaa4f24ee4cb35 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 19 Nov 2014 16:52:56 +0100 Subject: cOctavedNoise: Removed misleading comment, fixed assert texts. --- src/Noise/OctavedNoise.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Noise/OctavedNoise.h b/src/Noise/OctavedNoise.h index 592debbd3..855117289 100644 --- a/src/Noise/OctavedNoise.h +++ b/src/Noise/OctavedNoise.h @@ -47,13 +47,13 @@ public: int a_SizeX, int a_SizeY, ///< Count of the array, in each direction NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction - NOISE_DATATYPE * a_Workspace ///< Workspace that this function can use and trash. Must be valid. + NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash. ) const { // Check that state is alright: if (m_Octaves.empty()) { - ASSERT(!"Perlin: No octaves to generate!"); + ASSERT(!"cOctavedNoise: No octaves to generate!"); return; } @@ -111,7 +111,7 @@ public: // Check that state is alright: if (m_Octaves.empty()) { - ASSERT(!"Perlin: No octaves to generate!"); + ASSERT(!"cOctavedNoise: No octaves to generate!"); return; } -- cgit v1.2.3 From fef4133f6d7a3bbd08cba15034d0004aa1a76753 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 19 Nov 2014 16:58:27 +0100 Subject: cInterpolNoise: Implemented optimized 2D generating. --- src/Generating/Noise3DGenerator.cpp | 61 ++++++++++-- src/Generating/Noise3DGenerator.h | 3 +- src/Noise/InterpolNoise.h | 187 +++++++++++++++++++++++++++++++----- 3 files changed, 219 insertions(+), 32 deletions(-) diff --git a/src/Generating/Noise3DGenerator.cpp b/src/Generating/Noise3DGenerator.cpp index d051948c4..78b739d32 100644 --- a/src/Generating/Noise3DGenerator.cpp +++ b/src/Generating/Noise3DGenerator.cpp @@ -68,6 +68,15 @@ static class cInterpolNoiseSpeedTest { public: cInterpolNoiseSpeedTest(void) + { + TestSpeed2D(); + TestSpeed3D(); + printf("InterpolNoise speed comparison finished.\n"); + } + + + /** Compare the speed of the 3D InterpolNoise vs 3D CubicNoise. */ + void TestSpeed3D(void) { printf("Evaluating 3D noise performance...\n"); static const int SIZE_X = 128; @@ -99,6 +108,38 @@ public: printf("3D noise performance comparison finished.\n"); } + + /** Compare the speed of the 2D InterpolNoise vs 2D CubicNoise. */ + void TestSpeed2D(void) + { + printf("Evaluating 2D noise performance...\n"); + static const int SIZE_X = 128; + static const int SIZE_Y = 128; + static const NOISE_DATATYPE MUL = 80; + std::unique_ptr arr(new NOISE_DATATYPE[SIZE_X * SIZE_Y]); + cTimer timer; + + // Test the cInterpolNoise: + cInterpolNoise interpNoise(1); + long long start = timer.GetNowTime(); + for (int i = 0; i < 500; i++) + { + interpNoise.Generate2D(arr.get(), SIZE_X, SIZE_Y, MUL * i, MUL * i + MUL, 0, MUL); + } + long long end = timer.GetNowTime(); + printf("InterpolNoise took %.02f sec\n", static_cast(end - start) / 1000); + + // Test the cCubicNoise: + cCubicNoise cubicNoise(1); + start = timer.GetNowTime(); + for (int i = 0; i < 500; i++) + { + cubicNoise.Generate2D(arr.get(), SIZE_X, SIZE_Y, MUL * i, MUL * i + MUL, 0, MUL); + } + end = timer.GetNowTime(); + printf("CubicNoise took %.02f sec\n", static_cast(end - start) / 1000); + printf("2D noise performance comparison finished.\n"); + } } g_InterpolNoiseSpeedTest; #endif @@ -120,6 +161,12 @@ cNoise3DGenerator::cNoise3DGenerator(cChunkGenerator & a_ChunkGenerator) : m_Perlin.AddOctave(8, 0.125); m_Perlin.AddOctave(16, 0.0625); + m_Cubic.AddOctave(1, 1); + m_Cubic.AddOctave(2, 0.5); + m_Cubic.AddOctave(4, 0.25); + m_Cubic.AddOctave(8, 0.125); + m_Cubic.AddOctave(16, 0.0625); + #if 0 // DEBUG: Test the noise generation: // NOTE: In order to be able to run MCS with this code, you need to increase the default thread stack size @@ -201,8 +248,8 @@ void cNoise3DGenerator::Initialize(cIniFile & a_IniFile) { // Params: m_SeaLevel = a_IniFile.GetValueSetI("Generator", "Noise3DSeaLevel", 62); - m_HeightAmplification = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DHeightAmplification", 0); - m_MidPoint = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DMidPoint", 75); + m_HeightAmplification = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DHeightAmplification", 0.1); + m_MidPoint = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DMidPoint", 68); m_FrequencyX = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DFrequencyX", 8); m_FrequencyY = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DFrequencyY", 8); m_FrequencyZ = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DFrequencyZ", 8); @@ -280,23 +327,23 @@ void cNoise3DGenerator::GenerateNoiseArray(int a_ChunkX, int a_ChunkZ, NOISE_DAT // Precalculate a "height" array: NOISE_DATATYPE Height[DIM_X * DIM_Z]; // Output for the cubic noise heightmap ("source") - m_Cubic.Generate2D(Height, DIM_X, DIM_Z, StartX / 25, EndX / 25, StartZ / 25, EndZ / 25); + m_Cubic.Generate2D(Height, DIM_X, DIM_Z, StartX / 5, EndX / 5, StartZ / 5, EndZ / 5); for (size_t i = 0; i < ARRAYCOUNT(Height); i++) { - Height[i] = std::abs(Height[i]) * m_HeightAmplification + 1; + Height[i] = Height[i] * m_HeightAmplification; } // Modify the noise by height data: for (int y = 0; y < DIM_Y; y++) { - NOISE_DATATYPE AddHeight = (y * UPSCALE_Y - m_MidPoint) / 20; - AddHeight *= AddHeight * AddHeight; + NOISE_DATATYPE AddHeight = (y * UPSCALE_Y - m_MidPoint) / 30; + // AddHeight *= AddHeight * AddHeight; for (int z = 0; z < DIM_Z; z++) { NOISE_DATATYPE * CurRow = &(NoiseO[y * DIM_X + z * DIM_X * DIM_Y]); for (int x = 0; x < DIM_X; x++) { - CurRow[x] += AddHeight / Height[x + DIM_X * z]; + CurRow[x] += AddHeight + Height[x + DIM_X * z]; } } } diff --git a/src/Generating/Noise3DGenerator.h b/src/Generating/Noise3DGenerator.h index d198c5498..07767ba84 100644 --- a/src/Generating/Noise3DGenerator.h +++ b/src/Generating/Noise3DGenerator.h @@ -47,7 +47,8 @@ protected: /** The base 3D noise source for the actual composition */ cOctavedNoise m_Perlin; - cCubicNoise m_Cubic; // The noise used for heightmap directing + /** The noise used for heightmap directing. */ + cOctavedNoise m_Cubic; int m_SeaLevel; NOISE_DATATYPE m_HeightAmplification; diff --git a/src/Noise/InterpolNoise.h b/src/Noise/InterpolNoise.h index 69e7194c9..683b54563 100644 --- a/src/Noise/InterpolNoise.h +++ b/src/Noise/InterpolNoise.h @@ -17,6 +17,134 @@ +//////////////////////////////////////////////////////////////////////////////// +// cInterpolCell2D: + +template +class cInterpolCell2D +{ +public: + cInterpolCell2D( + const cNoise & a_Noise, ///< Noise to use for generating the random values + NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y] + int a_SizeX, int a_SizeY, ///< Count of the array, in each direction + const NOISE_DATATYPE * a_FracX, ///< Pointer to the array that stores the X fractional values + const NOISE_DATATYPE * a_FracY ///< Pointer to the attay that stores the Y fractional values + ): + m_Noise(a_Noise), + m_WorkRnds(&m_Workspace1), + m_CurFloorX(0), + m_CurFloorY(0), + m_Array(a_Array), + m_SizeX(a_SizeX), + m_SizeY(a_SizeY), + m_FracX(a_FracX), + m_FracY(a_FracY) + { + } + + + /** Generates part of the output noise array using the current m_WorkRnds[] values */ + void Generate( + int a_FromX, int a_ToX, + int a_FromY, int a_ToY + ) + { + for (int y = a_FromY; y < a_ToY; y++) + { + NOISE_DATATYPE Interp[2]; + NOISE_DATATYPE FracY = T::coeff(m_FracY[y]); + Interp[0] = Lerp((*m_WorkRnds)[0][0], (*m_WorkRnds)[0][1], FracY); + Interp[1] = Lerp((*m_WorkRnds)[1][0], (*m_WorkRnds)[1][1], FracY); + int idx = y * m_SizeX + a_FromX; + for (int x = a_FromX; x < a_ToX; x++) + { + m_Array[idx++] = Lerp(Interp[0], Interp[1], T::coeff(m_FracX[x])); + } // for x + } // for y + } + + + /** Initializes m_WorkRnds[] with the specified values of the noise at the specified integral coords. */ + void InitWorkRnds(int a_FloorX, int a_FloorY) + { + m_CurFloorX = a_FloorX; + m_CurFloorY = a_FloorY; + (*m_WorkRnds)[0][0] = m_Noise.IntNoise2D(m_CurFloorX, m_CurFloorY); + (*m_WorkRnds)[0][1] = m_Noise.IntNoise2D(m_CurFloorX, m_CurFloorY + 1); + (*m_WorkRnds)[1][0] = m_Noise.IntNoise2D(m_CurFloorX + 1, m_CurFloorY); + (*m_WorkRnds)[1][1] = m_Noise.IntNoise2D(m_CurFloorX + 1, m_CurFloorY + 1); + } + + + /** Updates m_WorkRnds[] for the new integral coords */ + void Move(int a_NewFloorX, int a_NewFloorY) + { + // Swap the doublebuffer: + int OldFloorX = m_CurFloorX; + int OldFloorY = m_CurFloorY; + Workspace * OldWorkRnds = m_WorkRnds; + m_WorkRnds = (m_WorkRnds == &m_Workspace1) ? &m_Workspace2 : &m_Workspace1; + + // Reuse as much of the old workspace as possible: + // TODO: Try out if simply calculating all 4 elements each time is faster than this monster loop + int DiffX = OldFloorX - a_NewFloorX; + int DiffY = OldFloorY - a_NewFloorY; + for (int x = 0; x < 2; x++) + { + int cx = a_NewFloorX + x; + int OldX = x - DiffX; // Where would this X be in the old grid? + for (int y = 0; y < 2; y++) + { + int cy = a_NewFloorY + y; + int OldY = y - DiffY; // Where would this Y be in the old grid? + if ((OldX >= 0) && (OldX < 2) && (OldY >= 0) && (OldY < 2)) + { + (*m_WorkRnds)[x][y] = (*OldWorkRnds)[OldX][OldY]; + } + else + { + (*m_WorkRnds)[x][y] = (NOISE_DATATYPE)m_Noise.IntNoise2D(cx, cy); + } + } + } + m_CurFloorX = a_NewFloorX; + m_CurFloorY = a_NewFloorY; + } + +protected: + typedef NOISE_DATATYPE Workspace[2][2]; + + /** The noise used for generating the values at integral coords. */ + const cNoise & m_Noise; + + /** The current random values; points to either m_Workspace1 or m_Workspace2 (doublebuffering) */ + Workspace * m_WorkRnds; + + /** Buffer 1 for workspace doublebuffering, used in Move() */ + Workspace m_Workspace1; + + /** Buffer 2 for workspace doublebuffering, used in Move() */ + Workspace m_Workspace2; + + /** Coords of the currently calculated m_WorkRnds[]. */ + int m_CurFloorX, m_CurFloorY; + + /** The output array to generate into. */ + NOISE_DATATYPE * m_Array; + + /** Dimensions of the output array. */ + int m_SizeX, m_SizeY; + + /** Arrays holding the fractional values of the coords in each direction. */ + const NOISE_DATATYPE * m_FracX; + const NOISE_DATATYPE * m_FracY; +} ; + + + + + //////////////////////////////////////////////////////////////////////////////// // cInterpolCell3D: @@ -212,33 +340,44 @@ public: NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY ///< Noise-space coords of the array in the Y direction ) const { - // Check params: - ASSERT(a_SizeX > 1); - ASSERT(a_SizeY > 1); - - // Generate the noise: - size_t idx = 0; - for (int y = 0; y < a_SizeY; y++) + ASSERT(a_SizeX > 0); + ASSERT(a_SizeY > 0); + ASSERT(a_SizeX < MAX_SIZE); + ASSERT(a_SizeY < MAX_SIZE); + ASSERT(a_StartX < a_EndX); + ASSERT(a_StartY < a_EndY); + + // Calculate the integral and fractional parts of each coord: + int FloorX[MAX_SIZE]; + int FloorY[MAX_SIZE]; + NOISE_DATATYPE FracX[MAX_SIZE]; + NOISE_DATATYPE FracY[MAX_SIZE]; + int SameX[MAX_SIZE]; + int SameY[MAX_SIZE]; + int NumSameX, NumSameY; + CalcFloorFrac(a_SizeX, a_StartX, a_EndX, FloorX, FracX, SameX, NumSameX); + CalcFloorFrac(a_SizeY, a_StartY, a_EndY, FloorY, FracY, SameY, NumSameY); + + cInterpolCell2D Cell(m_Noise, a_Array, a_SizeX, a_SizeY, FracX, FracY); + + Cell.InitWorkRnds(FloorX[0], FloorY[0]); + + // Calculate query values using Cell: + int FromY = 0; + for (int y = 0; y < NumSameY; y++) { - NOISE_DATATYPE ratioY = static_cast(y) / (a_SizeY - 1); - NOISE_DATATYPE noiseY = Lerp(a_StartY, a_EndY, ratioY); - int noiseYInt = FAST_FLOOR(noiseY); - NOISE_DATATYPE ratioY = typename T(noiseY - static_cast(noiseYInt)); - for (int x = 0; x < a_SizeX; x++) + int ToY = FromY + SameY[y]; + int FromX = 0; + int CurFloorY = FloorY[FromY]; + for (int x = 0; x < NumSameX; x++) { - NOISE_DATATYPE ratioX = static_cast(x) / (a_SizeX - 1); - NOISE_DATATYPE noiseX = Lerp(a_StartX, a_EndX, ratioX); - int noiseXInt = FAST_FLOOR(noiseX); - NOISE_DATATYPE ratioX = typename T(noiseX - static_cast(noiseXInt)); - - NOISE_DATATYPE valx0y0 = m_Noise.IntNoise2D(noiseXInt, noiseYInt); - NOISE_DATATYPE valx1y0 = m_Noise.IntNoise2D(noiseXInt + 1, noiseYInt); - NOISE_DATATYPE valx0y1 = m_Noise.IntNoise2D(noiseXInt, noiseYInt + 1); - NOISE_DATATYPE valx1y1 = m_Noise.IntNoise2D(noiseXInt + 1, noiseYInt + 1); - NOISE_DATATYPE valx0 = Lerp(valx0y0, valx0y1, ratioY); - NOISE_DATATYPE valx1 = Lerp(valx1y1, valx1y1, ratioY); - a_Array[idx++] = Lerp(valx0, valx1, ratioX); + int ToX = FromX + SameX[x]; + Cell.Generate(FromX, ToX, FromY, ToY); + Cell.Move(FloorX[ToX], CurFloorY); + FromX = ToX; } // for x + Cell.Move(FloorX[0], FloorY[ToY]); + FromY = ToY; } // for y } -- cgit v1.2.3 From 5325885ef49c57ecc7d7f071fc29df6c55467eb5 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 20 Nov 2014 14:45:20 +0100 Subject: Noise3D generators: Changed noise generator to InterpolNoise. --- src/Generating/CompoGenBiomal.cpp | 2 +- src/Generating/Noise3DGenerator.h | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Generating/CompoGenBiomal.cpp b/src/Generating/CompoGenBiomal.cpp index 0bb7f4802..38c91c0d2 100644 --- a/src/Generating/CompoGenBiomal.cpp +++ b/src/Generating/CompoGenBiomal.cpp @@ -6,7 +6,7 @@ #include "Globals.h" #include "ComposableGenerator.h" #include "../IniFile.h" -#include "../Noise.h" +#include "../Noise/Noise.h" #include "../LinearUpscale.h" diff --git a/src/Generating/Noise3DGenerator.h b/src/Generating/Noise3DGenerator.h index 7822a9efa..54429b42b 100644 --- a/src/Generating/Noise3DGenerator.h +++ b/src/Generating/Noise3DGenerator.h @@ -81,17 +81,17 @@ public: void Initialize(cIniFile & a_IniFile); protected: - /** The noise that is used to choose between density noise A and B. */ - cPerlinNoise m_ChoiceNoise; + /** The 3D noise that is used to choose between density noise A and B. */ + cOctavedNoise> m_ChoiceNoise; /** Density 3D noise, variant A. */ - cPerlinNoise m_DensityNoiseA; + cOctavedNoise> m_DensityNoiseA; /** Density 3D noise, variant B. */ - cPerlinNoise m_DensityNoiseB; + cOctavedNoise> m_DensityNoiseB; /** Heightmap-like noise used to provide variance for low-amplitude biomes. */ - cPerlinNoise m_BaseNoise; + cOctavedNoise> m_BaseNoise; /** Block height of the sealevel, used for composing the terrain. */ int m_SeaLevel; @@ -155,16 +155,16 @@ protected: /** The noise that is used to choose between density noise A and B. */ - cPerlinNoise m_ChoiceNoise; + cOctavedNoise> m_ChoiceNoise; /** Density 3D noise, variant A. */ - cPerlinNoise m_DensityNoiseA; + cOctavedNoise> m_DensityNoiseA; /** Density 3D noise, variant B. */ - cPerlinNoise m_DensityNoiseB; + cOctavedNoise> m_DensityNoiseB; /** Heightmap-like noise used to provide variance for low-amplitude biomes. */ - cPerlinNoise m_BaseNoise; + cOctavedNoise> m_BaseNoise; /** The underlying biome generator. */ cBiomeGenPtr m_BiomeGen; -- cgit v1.2.3 From 76058e81833b3b7df1c6d85d199e05abde4e8244 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 20 Nov 2014 15:31:03 +0100 Subject: Generators: Unified SeaLevel into a single variable. It is shared between shape generators and composition generators and there's no sense in having two different values for those. --- src/Generating/CompoGen.cpp | 2 +- src/Generating/Noise3DGenerator.cpp | 68 ++----------------------------------- src/Generating/Noise3DGenerator.h | 3 -- 3 files changed, 3 insertions(+), 70 deletions(-) diff --git a/src/Generating/CompoGen.cpp b/src/Generating/CompoGen.cpp index db43e34b6..23cc64d78 100644 --- a/src/Generating/CompoGen.cpp +++ b/src/Generating/CompoGen.cpp @@ -197,7 +197,7 @@ void cCompoGenClassic::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc void cCompoGenClassic::InitializeCompoGen(cIniFile & a_IniFile) { - m_SeaLevel = a_IniFile.GetValueSetI("Generator", "ClassicSeaLevel", m_SeaLevel); + m_SeaLevel = a_IniFile.GetValueSetI("Generator", "SeaLevel", m_SeaLevel); m_BeachHeight = a_IniFile.GetValueSetI("Generator", "ClassicBeachHeight", m_BeachHeight); m_BeachDepth = a_IniFile.GetValueSetI("Generator", "ClassicBeachDepth", m_BeachDepth); m_BlockTop = (BLOCKTYPE)(GetIniItemSet(a_IniFile, "Generator", "ClassicBlockTop", "grass").m_ItemType); diff --git a/src/Generating/Noise3DGenerator.cpp b/src/Generating/Noise3DGenerator.cpp index 70844e6fa..4180693e0 100644 --- a/src/Generating/Noise3DGenerator.cpp +++ b/src/Generating/Noise3DGenerator.cpp @@ -166,69 +166,6 @@ cNoise3DGenerator::cNoise3DGenerator(cChunkGenerator & a_ChunkGenerator) : m_Cubic.AddOctave(4, 0.25); m_Cubic.AddOctave(8, 0.125); m_Cubic.AddOctave(16, 0.0625); - - #if 0 - // DEBUG: Test the noise generation: - // NOTE: In order to be able to run MCS with this code, you need to increase the default thread stack size - // In MSVC, it is done in Project Settings -> Configuration Properties -> Linker -> System, set Stack reserve size to at least 64M - m_SeaLevel = 62; - m_HeightAmplification = 0; - m_MidPoint = 75; - m_FrequencyX = 4; - m_FrequencyY = 4; - m_FrequencyZ = 4; - m_AirThreshold = 0.5; - - const int NumChunks = 4; - NOISE_DATATYPE Noise[NumChunks][cChunkDef::Width * cChunkDef::Width * cChunkDef::Height]; - for (int x = 0; x < NumChunks; x++) - { - GenerateNoiseArray(x, 5, Noise[x]); - } - - // Save in XY cuts: - cFile f1; - if (f1.Open("Test_XY.grab", cFile::fmWrite)) - { - for (int z = 0; z < cChunkDef::Width; z++) - { - for (int y = 0; y < cChunkDef::Height; y++) - { - for (int i = 0; i < NumChunks; i++) - { - int idx = y * cChunkDef::Width + z * cChunkDef::Width * cChunkDef::Height; - unsigned char buf[cChunkDef::Width]; - for (int x = 0; x < cChunkDef::Width; x++) - { - buf[x] = (unsigned char)(std::min(256, std::max(0, (int)(128 + 32 * Noise[i][idx++])))); - } - f1.Write(buf, cChunkDef::Width); - } - } // for y - } // for z - } // if (XY file open) - - cFile f2; - if (f2.Open("Test_XZ.grab", cFile::fmWrite)) - { - for (int y = 0; y < cChunkDef::Height; y++) - { - for (int z = 0; z < cChunkDef::Width; z++) - { - for (int i = 0; i < NumChunks; i++) - { - int idx = y * cChunkDef::Width + z * cChunkDef::Width * cChunkDef::Height; - unsigned char buf[cChunkDef::Width]; - for (int x = 0; x < cChunkDef::Width; x++) - { - buf[x] = (unsigned char)(std::min(256, std::max(0, (int)(128 + 32 * Noise[i][idx++])))); - } - f2.Write(buf, cChunkDef::Width); - } - } // for z - } // for y - } // if (XZ file open) - #endif // 0 } @@ -247,7 +184,7 @@ cNoise3DGenerator::~cNoise3DGenerator() void cNoise3DGenerator::Initialize(cIniFile & a_IniFile) { // Params: - m_SeaLevel = a_IniFile.GetValueSetI("Generator", "Noise3DSeaLevel", 62); + m_SeaLevel = a_IniFile.GetValueSetI("Generator", "SeaLevel", 62); m_HeightAmplification = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DHeightAmplification", 0.1); m_MidPoint = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DMidPoint", 68); m_FrequencyX = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DFrequencyX", 8); @@ -455,7 +392,6 @@ void cNoise3DComposable::Initialize(cIniFile & a_IniFile) { // Params: // The defaults generate extreme hills terrain - m_SeaLevel = a_IniFile.GetValueSetI("Generator", "Noise3DSeaLevel", 62); m_HeightAmplification = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DHeightAmplification", 0.045); m_MidPoint = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DMidPoint", 75); m_FrequencyX = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DFrequencyX", 40); @@ -608,7 +544,7 @@ void cBiomalNoise3DComposable::Initialize(cIniFile & a_IniFile) { // Params: // The defaults generate extreme hills terrain - m_SeaLevel = a_IniFile.GetValueSetI("Generator", "BiomalNoise3DSeaLevel", 62); + m_SeaLevel = a_IniFile.GetValueSetI("Generator", "SeaLevel", 62); m_FrequencyX = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "BiomalNoise3DFrequencyX", 40); m_FrequencyY = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "BiomalNoise3DFrequencyY", 40); m_FrequencyZ = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "BiomalNoise3DFrequencyZ", 40); diff --git a/src/Generating/Noise3DGenerator.h b/src/Generating/Noise3DGenerator.h index 54429b42b..1bc7f3fa1 100644 --- a/src/Generating/Noise3DGenerator.h +++ b/src/Generating/Noise3DGenerator.h @@ -93,9 +93,6 @@ protected: /** Heightmap-like noise used to provide variance for low-amplitude biomes. */ cOctavedNoise> m_BaseNoise; - /** Block height of the sealevel, used for composing the terrain. */ - int m_SeaLevel; - /** The main parameter of the generator, specifies the slope of the vertical linear gradient. A higher value means a steeper slope and a smaller total amplitude of the generated terrain. */ NOISE_DATATYPE m_HeightAmplification; -- cgit v1.2.3 From 1e887d138103504e9a0df4ba5a601236ae608f98 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 20 Nov 2014 18:05:30 +0100 Subject: CompoGenBiomal: Fixed sealevel not generating properly. --- src/Generating/CompoGenBiomal.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Generating/CompoGenBiomal.cpp b/src/Generating/CompoGenBiomal.cpp index 38c91c0d2..18bfa8b8c 100644 --- a/src/Generating/CompoGenBiomal.cpp +++ b/src/Generating/CompoGenBiomal.cpp @@ -427,7 +427,8 @@ protected: { bool HasHadWater = false; int PatternIdx = 0; - for (int y = a_ChunkDesc.GetHeight(a_RelX, a_RelZ); y > 0; y--) + int top = std::max(m_SeaLevel, a_ChunkDesc.GetHeight(a_RelX, a_RelZ)); + for (int y = top; y > 0; y--) { if (a_ShapeColumn[y] > 0) { -- cgit v1.2.3 From b7dd2dddf941d85f348814b21e15907c535e8898 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 20 Nov 2014 22:45:50 +0100 Subject: CompoGenBiomal: Fixed sealevel offset. --- src/Generating/CompoGenBiomal.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Generating/CompoGenBiomal.cpp b/src/Generating/CompoGenBiomal.cpp index 18bfa8b8c..995851c95 100644 --- a/src/Generating/CompoGenBiomal.cpp +++ b/src/Generating/CompoGenBiomal.cpp @@ -221,7 +221,7 @@ protected: virtual void InitializeCompoGen(cIniFile & a_IniFile) override { - m_SeaLevel = a_IniFile.GetValueSetI("Generator", "SeaLevel", m_SeaLevel) - 1; + m_SeaLevel = a_IniFile.GetValueSetI("Generator", "SeaLevel", m_SeaLevel); } -- cgit v1.2.3 From 1ed32b825eee28b9cd1494ed5a010169619d3aa0 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 20 Nov 2014 22:48:14 +0100 Subject: BiomalNoise3D generator: finished all biomes. --- src/Generating/Noise3DGenerator.cpp | 140 +++++++++++++++++++----------------- 1 file changed, 74 insertions(+), 66 deletions(-) diff --git a/src/Generating/Noise3DGenerator.cpp b/src/Generating/Noise3DGenerator.cpp index 4180693e0..fe6c9bdaf 100644 --- a/src/Generating/Noise3DGenerator.cpp +++ b/src/Generating/Noise3DGenerator.cpp @@ -481,6 +481,13 @@ void cNoise3DComposable::GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_ChunkZ) AddHeight *= 4; } + // If too high, cut off any terrain: + if (y > 28) + { + AddHeight = AddHeight + static_cast(y - 28) / 4; + } + + // Decide between the two density noises: int idx = 33 * x + 33 * 5 * z + y; Workspace[idx] = ClampedLerp(DensityNoiseA[idx], DensityNoiseB[idx], 8 * (ChoiceNoise[idx] + 0.5f)) + AddHeight + curBaseNoise; } @@ -638,7 +645,13 @@ void cBiomalNoise3DComposable::GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_Ch { AddHeight *= 4; } + // If too high, cut off any terrain: + if (y > 28) + { + AddHeight = AddHeight + static_cast(y - 28) / 4; + } + // Decide between the two density noises: int idx = 33 * x + y + 33 * 5 * z; Workspace[idx] = ClampedLerp(DensityNoiseA[idx], DensityNoiseB[idx], 8 * (ChoiceNoise[idx] + 0.5f)) + AddHeight + curBaseNoise; } @@ -702,72 +715,67 @@ void cBiomalNoise3DComposable::GetBiomeParams(EMCSBiome a_Biome, NOISE_DATATYPE { switch (a_Biome) { - case biBeach: a_HeightAmp = 0.3f; a_MidPoint = 62; break; - case biBirchForest: a_HeightAmp = 0.1f; a_MidPoint = 64; break; - case biBirchForestHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; - case biBirchForestHillsM: a_HeightAmp = 0.075f; a_MidPoint = 68; break; - case biBirchForestM: a_HeightAmp = 0.1f; a_MidPoint = 64; break; - case biColdBeach: a_HeightAmp = 0.3f; a_MidPoint = 62; break; - case biDesertHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; - case biDeepOcean: a_HeightAmp = 0.17f; a_MidPoint = 35; break; - case biDesert: a_HeightAmp = 0.29f; a_MidPoint = 62; break; - case biEnd: a_HeightAmp = 0.15f; a_MidPoint = 64; break; - case biExtremeHills: a_HeightAmp = 0.045f; a_MidPoint = 75; break; - case biExtremeHillsPlus: a_HeightAmp = 0.04f; a_MidPoint = 80; break; - case biFlowerForest: a_HeightAmp = 0.1f; a_MidPoint = 64; break; - case biForest: a_HeightAmp = 0.1f; a_MidPoint = 64; break; - case biForestHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; - case biFrozenRiver: a_HeightAmp = 0.4f; a_MidPoint = 53; break; - case biFrozenOcean: a_HeightAmp = 0.17f; a_MidPoint = 47; break; - case biIceMountains: a_HeightAmp = 0.075f; a_MidPoint = 68; break; - case biIcePlains: a_HeightAmp = 0.3f; a_MidPoint = 62; break; - case biIcePlainsSpikes: a_HeightAmp = 0.3f; a_MidPoint = 62; break; - case biJungle: a_HeightAmp = 0.1f; a_MidPoint = 63; break; - case biJungleHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; - case biJungleM: a_HeightAmp = 0.1f; a_MidPoint = 63; break; - case biMegaSpruceTaigaHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; - case biMegaTaigaHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; - case biMushroomShore: a_HeightAmp = 0.15f; a_MidPoint = 15; break; - case biOcean: a_HeightAmp = 0.3f; a_MidPoint = 62; break; - case biPlains: a_HeightAmp = 0.3f; a_MidPoint = 62; break; - case biRiver: a_HeightAmp = 0.4f; a_MidPoint = 53; break; - case biSwampland: a_HeightAmp = 0.25f; a_MidPoint = 59; break; - case biSwamplandM: a_HeightAmp = 0.11f; a_MidPoint = 59; break; - case biTaigaHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; - - /* - // Still missing: - case biColdTaiga: a_HeightAmp = 0.15f; a_MidPoint = 30; break; - case biColdTaigaHills: a_HeightAmp = 0.15f; a_MidPoint = 31; break; - case biColdTaigaM: a_HeightAmp = 0.15f; a_MidPoint = 70; break; - case biDesertM: a_HeightAmp = 0.15f; a_MidPoint = 70; break; - case biExtremeHillsEdge: a_HeightAmp = 0.15f; a_MidPoint = 20; break; - case biExtremeHillsM: a_HeightAmp = 0.15f; a_MidPoint = 70; break; - case biExtremeHillsPlusM: a_HeightAmp = 0.15f; a_MidPoint = 70; break; - case biJungleEdge: a_HeightAmp = 0.15f; a_MidPoint = 23; break; - case biJungleEdgeM: a_HeightAmp = 0.15f; a_MidPoint = 70; break; - case biMegaSpruceTaiga: a_HeightAmp = 0.15f; a_MidPoint = 70; break; - case biMegaTaiga: a_HeightAmp = 0.15f; a_MidPoint = 32; break; - case biMesa: a_HeightAmp = 0.15f; a_MidPoint = 37; break; - case biMesaBryce: a_HeightAmp = 0.15f; a_MidPoint = 70; break; - case biMesaPlateau: a_HeightAmp = 0.15f; a_MidPoint = 39; break; - case biMesaPlateauF: a_HeightAmp = 0.15f; a_MidPoint = 38; break; - case biMesaPlateauFM: a_HeightAmp = 0.15f; a_MidPoint = 70; break; - case biMesaPlateauM: a_HeightAmp = 0.15f; a_MidPoint = 70; break; - case biMushroomIsland: a_HeightAmp = 0.15f; a_MidPoint = 14; break; - case biNether: a_HeightAmp = 0.15f; a_MidPoint = 68; break; - case biRoofedForest: a_HeightAmp = 0.15f; a_MidPoint = 29; break; - case biRoofedForestM: a_HeightAmp = 0.15f; a_MidPoint = 70; break; - case biSavanna: a_HeightAmp = 0.15f; a_MidPoint = 35; break; - case biSavannaM: a_HeightAmp = 0.15f; a_MidPoint = 70; break; - case biSavannaPlateau: a_HeightAmp = 0.15f; a_MidPoint = 36; break; - case biSavannaPlateauM: a_HeightAmp = 0.15f; a_MidPoint = 70; break; - case biStoneBeach: a_HeightAmp = 0.15f; a_MidPoint = 25; break; - case biSunflowerPlains: a_HeightAmp = 0.15f; a_MidPoint = 70; break; - case biTaiga: a_HeightAmp = 0.15f; a_MidPoint = 65; break; - case biTaigaM: a_HeightAmp = 0.15f; a_MidPoint = 70; break; - */ - + case biBeach: a_HeightAmp = 0.3f; a_MidPoint = 62; break; + case biBirchForest: a_HeightAmp = 0.1f; a_MidPoint = 64; break; + case biBirchForestHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; + case biBirchForestHillsM: a_HeightAmp = 0.075f; a_MidPoint = 68; break; + case biBirchForestM: a_HeightAmp = 0.1f; a_MidPoint = 64; break; + case biColdBeach: a_HeightAmp = 0.3f; a_MidPoint = 62; break; + case biColdTaiga: a_HeightAmp = 0.1f; a_MidPoint = 64; break; + case biColdTaigaM: a_HeightAmp = 0.1f; a_MidPoint = 64; break; + case biColdTaigaHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; + case biDesertHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; + case biDeepOcean: a_HeightAmp = 0.17f; a_MidPoint = 35; break; + case biDesert: a_HeightAmp = 0.29f; a_MidPoint = 62; break; + case biDesertM: a_HeightAmp = 0.29f; a_MidPoint = 62; break; + case biEnd: a_HeightAmp = 0.15f; a_MidPoint = 64; break; + case biExtremeHills: a_HeightAmp = 0.045f; a_MidPoint = 75; break; + case biExtremeHillsEdge: a_HeightAmp = 0.1f; a_MidPoint = 70; break; + case biExtremeHillsM: a_HeightAmp = 0.045f; a_MidPoint = 75; break; + case biExtremeHillsPlus: a_HeightAmp = 0.04f; a_MidPoint = 80; break; + case biExtremeHillsPlusM: a_HeightAmp = 0.04f; a_MidPoint = 80; break; + case biFlowerForest: a_HeightAmp = 0.1f; a_MidPoint = 64; break; + case biForest: a_HeightAmp = 0.1f; a_MidPoint = 64; break; + case biForestHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; + case biFrozenRiver: a_HeightAmp = 0.4f; a_MidPoint = 57; break; + case biFrozenOcean: a_HeightAmp = 0.12f; a_MidPoint = 45; break; + case biIceMountains: a_HeightAmp = 0.075f; a_MidPoint = 68; break; + case biIcePlains: a_HeightAmp = 0.3f; a_MidPoint = 62; break; + case biIcePlainsSpikes: a_HeightAmp = 0.3f; a_MidPoint = 62; break; + case biJungle: a_HeightAmp = 0.1f; a_MidPoint = 63; break; + case biJungleEdge: a_HeightAmp = 0.15f; a_MidPoint = 62; break; + case biJungleEdgeM: a_HeightAmp = 0.15f; a_MidPoint = 62; break; + case biJungleHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; + case biJungleM: a_HeightAmp = 0.1f; a_MidPoint = 63; break; + case biMegaSpruceTaiga: a_HeightAmp = 0.09f; a_MidPoint = 64; break; + case biMegaSpruceTaigaHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; + case biMegaTaiga: a_HeightAmp = 0.1f; a_MidPoint = 64; break; + case biMegaTaigaHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; + case biMesa: a_HeightAmp = 0.09f; a_MidPoint = 61; break; + case biMesaBryce: a_HeightAmp = 0.15f; a_MidPoint = 61; break; + case biMesaPlateau: a_HeightAmp = 0.25f; a_MidPoint = 86; break; + case biMesaPlateauF: a_HeightAmp = 0.25f; a_MidPoint = 96; break; + case biMesaPlateauFM: a_HeightAmp = 0.25f; a_MidPoint = 96; break; + case biMesaPlateauM: a_HeightAmp = 0.25f; a_MidPoint = 86; break; + case biMushroomShore: a_HeightAmp = 0.075f; a_MidPoint = 60; break; + case biMushroomIsland: a_HeightAmp = 0.06f; a_MidPoint = 80; break; + case biNether: a_HeightAmp = 0.01f; a_MidPoint = 64; break; + case biOcean: a_HeightAmp = 0.12f; a_MidPoint = 45; break; + case biPlains: a_HeightAmp = 0.3f; a_MidPoint = 62; break; + case biRiver: a_HeightAmp = 0.4f; a_MidPoint = 57; break; + case biRoofedForest: a_HeightAmp = 0.1f; a_MidPoint = 64; break; + case biRoofedForestM: a_HeightAmp = 0.1f; a_MidPoint = 64; break; + case biSavanna: a_HeightAmp = 0.3f; a_MidPoint = 62; break; + case biSavannaM: a_HeightAmp = 0.3f; a_MidPoint = 62; break; + case biSavannaPlateau: a_HeightAmp = 0.3f; a_MidPoint = 85; break; + case biSavannaPlateauM: a_HeightAmp = 0.012f; a_MidPoint = 105; break; + case biStoneBeach: a_HeightAmp = 0.075f; a_MidPoint = 60; break; + case biSunflowerPlains: a_HeightAmp = 0.3f; a_MidPoint = 62; break; + case biSwampland: a_HeightAmp = 0.25f; a_MidPoint = 59; break; + case biSwamplandM: a_HeightAmp = 0.11f; a_MidPoint = 59; break; + case biTaiga: a_HeightAmp = 0.1f; a_MidPoint = 64; break; + case biTaigaM: a_HeightAmp = 0.1f; a_MidPoint = 70; break; + case biTaigaHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; default: { // Make a crazy terrain so that it stands out -- cgit v1.2.3 From a05a318cdd4140b36dd8c1a89c2f197700824242 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 20 Nov 2014 22:51:07 +0100 Subject: cWorld: Changed generator defaults. --- src/World.cpp | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/World.cpp b/src/World.cpp index df1a97460..5520fd272 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -741,28 +741,32 @@ void cWorld::InitialiseGeneratorDefaults(cIniFile & a_IniFile) { case dimEnd: { - a_IniFile.GetValueSet("Generator", "BiomeGen", "Constant"); - a_IniFile.GetValueSet("Generator", "ConstantBiome", "End"); - a_IniFile.GetValueSet("Generator", "HeightGen", "Biomal"); + a_IniFile.GetValueSet("Generator", "Generator", "Composable"); + a_IniFile.GetValueSet("Generator", "BiomeGen", "Constant"); + a_IniFile.GetValueSet("Generator", "ConstantBiome", "End"); + a_IniFile.GetValueSet("Generator", "ShapeGen", "End"); a_IniFile.GetValueSet("Generator", "CompositionGen", "End"); break; } case dimOverworld: { - a_IniFile.GetValueSet("Generator", "BiomeGen", "MultiStepMap"); - a_IniFile.GetValueSet("Generator", "HeightGen", "DistortedHeightmap"); - a_IniFile.GetValueSet("Generator", "CompositionGen", "DistortedHeightmap"); - a_IniFile.GetValueSet("Generator", "Finishers", "Ravines, WormNestCaves, WaterLakes, WaterSprings, LavaLakes, LavaSprings, OreNests, Mineshafts, Trees, SprinkleFoliage, Ice, Snow, Lilypads, BottomLava, DeadBushes, PreSimulator"); + a_IniFile.GetValueSet("Generator", "Generator", "Composable"); + a_IniFile.GetValueSet("Generator", "BiomeGen", "Grown"); + a_IniFile.GetValueSet("Generator", "ShapeGen", "BiomalNoise3D"); + a_IniFile.GetValueSet("Generator", "CompositionGen", "Biomal"); + a_IniFile.GetValueSet("Generator", "Finishers", "Ravines, WormNestCaves, WaterLakes, WaterSprings, LavaLakes, LavaSprings, OreNests, Mineshafts, Trees, Villages, SprinkleFoliage, Ice, Snow, Lilypads, BottomLava, DeadBushes, PreSimulator"); break; } case dimNether: { - a_IniFile.GetValueSet("Generator", "BiomeGen", "Constant"); - a_IniFile.GetValueSet("Generator", "ConstantBiome", "Nether"); - a_IniFile.GetValueSet("Generator", "HeightGen", "Flat"); - a_IniFile.GetValueSet("Generator", "FlatHeight", "128"); - a_IniFile.GetValueSet("Generator", "CompositionGen", "Nether"); - a_IniFile.GetValueSet("Generator", "Finishers", "WormNestCaves, BottomLava, LavaSprings, NetherClumpFoliage, NetherForts, PreSimulator"); + a_IniFile.GetValueSet("Generator", "Generator", "Composable"); + a_IniFile.GetValueSet("Generator", "BiomeGen", "Constant"); + a_IniFile.GetValueSet("Generator", "ConstantBiome", "Nether"); + a_IniFile.GetValueSet("Generator", "ShapeGen", "HeightMap"); + a_IniFile.GetValueSet("Generator", "HeightGen", "Flat"); + a_IniFile.GetValueSet("Generator", "FlatHeight", "128"); + a_IniFile.GetValueSet("Generator", "CompositionGen", "Nether"); + a_IniFile.GetValueSet("Generator", "Finishers", "WormNestCaves, BottomLava, LavaSprings, NetherClumpFoliage, NetherForts, PreSimulator"); a_IniFile.GetValueSet("Generator", "BottomLavaHeight", "30"); break; } -- cgit v1.2.3 From ac2e3ede1d9cd76aec851e50a2312a4ab548b25a Mon Sep 17 00:00:00 2001 From: p-mcgowan Date: Fri, 21 Nov 2014 23:20:44 -0800 Subject: villagers turn into witches when struck by lightning --- src/Mobs/Villager.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Mobs/Villager.cpp b/src/Mobs/Villager.cpp index 5c9999a59..371132dfb 100644 --- a/src/Mobs/Villager.cpp +++ b/src/Mobs/Villager.cpp @@ -37,6 +37,11 @@ bool cVillager::DoTakeDamage(TakeDamageInfo & a_TDI) m_World->BroadcastEntityStatus(*this, esVillagerAngry); } } + if (a_TDI.DamageType == dtLightning) + { + m_World->SpawnMob((int) GetPosX(), (int) GetPosY(), (int) GetPosZ(), mtWitch); + super::Destroy(this); + } return true; } -- cgit v1.2.3 From 635e9321c6524d0ba4bba9ce2d716869373fdfac Mon Sep 17 00:00:00 2001 From: p-mcgowan Date: Fri, 21 Nov 2014 23:36:35 -0800 Subject: villagers turn into witches on lightning --- src/Mobs/Villager.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Mobs/Villager.cpp b/src/Mobs/Villager.cpp index 371132dfb..6bf88bd80 100644 --- a/src/Mobs/Villager.cpp +++ b/src/Mobs/Villager.cpp @@ -37,10 +37,12 @@ bool cVillager::DoTakeDamage(TakeDamageInfo & a_TDI) m_World->BroadcastEntityStatus(*this, esVillagerAngry); } } + if (a_TDI.DamageType == dtLightning) { - m_World->SpawnMob((int) GetPosX(), (int) GetPosY(), (int) GetPosZ(), mtWitch); - super::Destroy(this); + Destroy(); + m_World->SpawnMob(GetPosX(), GetPosY(), GetPosZ(), mtWitch); + return true; } return true; } -- cgit v1.2.3 From 793b1012c41edbc07f81510ce1cc9f229628a712 Mon Sep 17 00:00:00 2001 From: p-mcgowan Date: Fri, 21 Nov 2014 23:58:35 -0800 Subject: formatter error --- src/Mobs/Villager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Mobs/Villager.cpp b/src/Mobs/Villager.cpp index 6bf88bd80..963595347 100644 --- a/src/Mobs/Villager.cpp +++ b/src/Mobs/Villager.cpp @@ -37,12 +37,12 @@ bool cVillager::DoTakeDamage(TakeDamageInfo & a_TDI) m_World->BroadcastEntityStatus(*this, esVillagerAngry); } } - + if (a_TDI.DamageType == dtLightning) { Destroy(); - m_World->SpawnMob(GetPosX(), GetPosY(), GetPosZ(), mtWitch); - return true; + m_World->SpawnMob(GetPosX(), GetPosY(), GetPosZ(), mtWitch); + return true; } return true; } -- cgit v1.2.3 From f0266c578ea2c2a71e3e8b1ce29dcc7af66cc737 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sat, 22 Nov 2014 13:31:58 +0100 Subject: InfoReg: Added a diagnostic for bad Info.lua command info. --- MCServer/Plugins/InfoReg.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/MCServer/Plugins/InfoReg.lua b/MCServer/Plugins/InfoReg.lua index da5a9972c..92c4a2e59 100644 --- a/MCServer/Plugins/InfoReg.lua +++ b/MCServer/Plugins/InfoReg.lua @@ -51,6 +51,7 @@ local function MultiCommandHandler(a_Split, a_Player, a_CmdString, a_CmdInfo, a_ return a_CmdInfo.Handler(a_Split, a_Player); end -- Let the player know they need to give a subcommand: + assert(type(a_CmdInfo.Subcommands) == "table", "Info.lua error: There is no handler for command \"" .. a_CmdString .. "\" and there are no subcommands defined at level " .. a_Level) ListSubcommands(a_Player, a_CmdInfo.Subcommands, a_CmdString); return true; end -- cgit v1.2.3 From b520f336da734b5971d4003ae949ea78c3994a79 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sat, 22 Nov 2014 16:00:19 +0100 Subject: cWorld: Rewritten spawn preparation. It now supports pregeneration distance of any size and runs in two threads in parallel (generator / lighting). Fixes #1597. --- src/World.cpp | 231 ++++++++++++++++++++++++++++------------------------------ src/World.h | 2 + 2 files changed, 113 insertions(+), 120 deletions(-) diff --git a/src/World.cpp b/src/World.cpp index df1a97460..1a64105c2 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -74,102 +74,137 @@ const int TIME_SPAWN_DIVISOR = 148; //////////////////////////////////////////////////////////////////////////////// -// cWorldLoadProgress: +// cSpawnPrepare: -/// A simple thread that displays the progress of world loading / saving in cWorld::InitializeSpawn() -class cWorldLoadProgress : - public cIsThread +/** Generates and lights the spawn area of the world. Runs as a separate thread. */ +class cSpawnPrepare: + public cIsThread, + public cChunkCoordCallback { + typedef cIsThread super; + public: - cWorldLoadProgress(cWorld * a_World) : - cIsThread("cWorldLoadProgress"), - m_World(a_World) - { + cSpawnPrepare(cWorld & a_World, int a_SpawnChunkX, int a_SpawnChunkZ, int a_PrepareDistance): + super("SpawnPrepare"), + m_World(a_World), + m_SpawnChunkX(a_SpawnChunkX), + m_SpawnChunkZ(a_SpawnChunkZ), + m_PrepareDistance(a_PrepareDistance), + m_MaxIdx(a_PrepareDistance * a_PrepareDistance), + m_NumPrepared(0), + m_LastReportTime(0), + m_LastReportChunkCount(0) + { + // Start the thread: Start(); + + // Wait for start confirmation, so that the thread can be waited-upon after the constructor returns: + m_EvtStarted.Wait(); } - - void Stop(void) - { - m_ShouldTerminate = true; - Wait(); - } - -protected: - cWorld * m_World; - + + // cIsThread override: virtual void Execute(void) override { - for (;;) + // Confirm thread start: + m_EvtStarted.Set(); + + // Queue the initial chunks: + m_MaxIdx = m_PrepareDistance * m_PrepareDistance; + int maxQueue = std::min(m_MaxIdx - 1, 100); // Number of chunks to queue at once + m_NextIdx = maxQueue; + m_LastReportTime = m_Timer.GetNowTime(); + for (int i = 0; i < maxQueue; i++) { - LOG("" SIZE_T_FMT " chunks to load, %d chunks to generate", - m_World->GetStorage().GetLoadQueueLength(), - m_World->GetGenerator().GetQueueLength() - ); - - // Wait for 2 sec, but be "reasonably wakeable" when the thread is to finish - for (int i = 0; i < 20; i++) - { - cSleep::MilliSleep(100); - if (m_ShouldTerminate) - { - return; - } - } - } // for (-ever) + int chunkX, chunkZ; + decodeChunkCoords(i, chunkX, chunkZ); + m_World.GetLightingThread().QueueChunk(chunkX, chunkZ, this); + } // for i + + // Wait for the lighting thread to prepare everything. Event is set in the Call() callback: + m_EvtFinished.Wait(); } - -} ; +protected: + cWorld & m_World; + int m_SpawnChunkX; + int m_SpawnChunkZ; + int m_PrepareDistance; + /** The index of the next chunk to be queued in the lighting thread. */ + int m_NextIdx; + /** The maximum index of the prepared chunks. Queueing stops when m_NextIdx reaches this number. */ + int m_MaxIdx; + /** Total number of chunks already finished preparing. Preparation finishes when this number reaches m_MaxIdx. */ + int m_NumPrepared; -//////////////////////////////////////////////////////////////////////////////// -// cWorldLightingProgress: + /** Event used to signal that the thread has started. */ + cEvent m_EvtStarted; -/// A simple thread that displays the progress of world lighting in cWorld::InitializeSpawn() -class cWorldLightingProgress : - public cIsThread -{ -public: - cWorldLightingProgress(cLightingThread * a_Lighting) : - cIsThread("cWorldLightingProgress"), - m_Lighting(a_Lighting) - { - Start(); - } - - void Stop(void) + /** Event used to signal that the preparation is finished. */ + cEvent m_EvtFinished; + + /** The timer used to report progress every second. */ + cTimer m_Timer; + + /** The timestamp of the last progress report emitted. */ + long long m_LastReportTime; + + /** Number of chunks prepared when the last progress report was emitted. */ + int m_LastReportChunkCount; + + + // cChunkCoordCallback override: + virtual void Call(int a_ChunkX, int a_ChunkZ) { - m_ShouldTerminate = true; - Wait(); + // Check if this was the last chunk: + m_NumPrepared += 1; + if (m_NumPrepared >= m_MaxIdx) + { + m_EvtFinished.Set(); + } + + // Queue another chunk, if appropriate: + if (m_NextIdx < m_MaxIdx) + { + int chunkX, chunkZ; + decodeChunkCoords(m_NextIdx, chunkX, chunkZ); + m_World.GetLightingThread().QueueChunk(chunkX, chunkZ, this); + m_NextIdx += 1; + } + + // Report progress every 1 second: + long long now = m_Timer.GetNowTime(); + if (now - m_LastReportTime > 1000) + { + float percentDone = static_cast(m_NumPrepared * 100) / m_MaxIdx; + float chunkSpeed = static_cast((m_NumPrepared - m_LastReportChunkCount) * 1000) / (now - m_LastReportTime); + LOG("Preparing spawn (%s): %.02f%% done (%d chunks out of %d; %.02f chunks / sec)", + m_World.GetName().c_str(), percentDone, m_NumPrepared, m_MaxIdx, chunkSpeed + ); + m_LastReportTime = now; + m_LastReportChunkCount = m_NumPrepared; + } } - -protected: - cLightingThread * m_Lighting; - - virtual void Execute(void) override + + /** Decodes the index into chunk coords. Provides the specific chunk ordering. */ + void decodeChunkCoords(int a_Idx, int & a_ChunkX, int & a_ChunkZ) { - for (;;) + // A zigzag pattern from the top to bottom, each row alternating between forward-x and backward-x: + int z = a_Idx / m_PrepareDistance; + int x = a_Idx % m_PrepareDistance; + if ((z & 1) == 0) { - LOG("" SIZE_T_FMT " chunks remaining to light", m_Lighting->GetQueueLength() - ); - - // Wait for 2 sec, but be "reasonably wakeable" when the thread is to finish - for (int i = 0; i < 20; i++) - { - cSleep::MilliSleep(100); - if (m_ShouldTerminate) - { - return; - } - } - } // for (-ever) + // Reverse every second row: + x = m_PrepareDistance - 1 - x; + } + a_ChunkZ = m_SpawnChunkZ + z - m_PrepareDistance / 2; + a_ChunkX = m_SpawnChunkX + x - m_PrepareDistance / 2; } - -} ; +}; @@ -432,53 +467,9 @@ void cWorld::InitializeSpawn(void) IniFile.ReadFile(m_IniFileName); int ViewDist = IniFile.GetValueSetI("SpawnPosition", "PregenerateDistance", DefaultViewDist); IniFile.WriteFile(m_IniFileName); - - LOG("Preparing spawn area in world \"%s\", %d x %d chunks, total %d chunks...", m_WorldName.c_str(), ViewDist, ViewDist, ViewDist * ViewDist); - for (int x = 0; x < ViewDist; x++) - { - for (int z = 0; z < ViewDist; z++) - { - m_ChunkMap->TouchChunk(x + ChunkX-(ViewDist - 1) / 2, z + ChunkZ-(ViewDist - 1) / 2); // Queue the chunk in the generator / loader - } - } - - { - // Display progress during this process: - cWorldLoadProgress Progress(this); - - // Wait for the loader to finish loading - m_Storage.WaitForLoadQueueEmpty(); - - // Wait for the generator to finish generating - m_Generator.WaitForQueueEmpty(); - // Wait for the loader to finish saving - m_Storage.WaitForSaveQueueEmpty(); - - Progress.Stop(); - } - - // Light all chunks that have been newly generated: - LOG("Lighting spawn area in world \"%s\"...", m_WorldName.c_str()); - - for (int x = 0; x < ViewDist; x++) - { - int ChX = x + ChunkX-(ViewDist - 1) / 2; - for (int z = 0; z < ViewDist; z++) - { - int ChZ = z + ChunkZ-(ViewDist - 1) / 2; - if (!m_ChunkMap->IsChunkLighted(ChX, ChZ)) - { - m_Lighting.QueueChunk(ChX, ChZ); // Queue the chunk in the lighting thread - } - } // for z - } // for x - - { - cWorldLightingProgress Progress(&m_Lighting); - m_Lighting.WaitForQueueEmpty(); - Progress.Stop(); - } + cSpawnPrepare prep(*this, ChunkX, ChunkZ, ViewDist); + prep.Wait(); #ifdef TEST_LINEBLOCKTRACER // DEBUG: Test out the cLineBlockTracer class by tracing a few lines: diff --git a/src/World.h b/src/World.h index fe57b0789..68d0654ee 100644 --- a/src/World.h +++ b/src/World.h @@ -696,6 +696,8 @@ public: inline size_t GetStorageLoadQueueLength(void) { return m_Storage.GetLoadQueueLength(); } // tolua_export inline size_t GetStorageSaveQueueLength(void) { return m_Storage.GetSaveQueueLength(); } // tolua_export + cLightingThread & GetLightingThread(void) { return m_Lighting; } + void InitializeSpawn(void); /** Starts threads that belong to this world */ -- cgit v1.2.3 From d1b7a965d10c66a27e1c4593ce3637a2537309d9 Mon Sep 17 00:00:00 2001 From: p-mcgowan Date: Sat, 22 Nov 2014 15:33:34 -0800 Subject: pigs turn into pigmen on lightning --- src/Mobs/Pig.cpp | 16 ++++++++++++++++ src/Mobs/Pig.h | 3 +++ 2 files changed, 19 insertions(+) diff --git a/src/Mobs/Pig.cpp b/src/Mobs/Pig.cpp index 55a4412ca..ce53d04fb 100644 --- a/src/Mobs/Pig.cpp +++ b/src/Mobs/Pig.cpp @@ -98,3 +98,19 @@ void cPig::Tick(float a_Dt, cChunk & a_Chunk) + +bool cPig::DoTakeDamage(TakeDamageInfo & a_TDI) +{ + if (!super::DoTakeDamage(a_TDI)) + { + return false; + } + + if (a_TDI.DamageType == dtLightning) + { + Destroy(); + m_World->SpawnMob(GetPosX(), GetPosY(), GetPosZ(), mtZombiePigman); + return true; + } + return true; +} \ No newline at end of file diff --git a/src/Mobs/Pig.h b/src/Mobs/Pig.h index 953850b3a..0e026933a 100644 --- a/src/Mobs/Pig.h +++ b/src/Mobs/Pig.h @@ -17,6 +17,9 @@ public: CLASS_PROTODEF(cPig) + // cEntity overrides + virtual bool DoTakeDamage(TakeDamageInfo & a_TDI) override; + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; virtual void OnRightClicked(cPlayer & a_Player) override; virtual void Tick(float a_Dt, cChunk & a_Chunk) override; -- cgit v1.2.3 From 7a08c057879d1e0476699931a50c510edf499759 Mon Sep 17 00:00:00 2001 From: p-mcgowan Date: Sat, 22 Nov 2014 15:48:05 -0800 Subject: formatting - newline at EOF inserted: Pig.cpp --- src/Mobs/Pig.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Mobs/Pig.cpp b/src/Mobs/Pig.cpp index ce53d04fb..50b69e44f 100644 --- a/src/Mobs/Pig.cpp +++ b/src/Mobs/Pig.cpp @@ -113,4 +113,8 @@ bool cPig::DoTakeDamage(TakeDamageInfo & a_TDI) return true; } return true; -} \ No newline at end of file +} + + + + -- cgit v1.2.3 From 9f4342434b7a34d0a9523e68b3d13a9eeeb116ca Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 23 Nov 2014 15:10:55 +0100 Subject: Noise3D generator: Enlarged averaging to avoid steep beach slopes. --- src/Generating/Noise3DGenerator.cpp | 4 ++-- src/Generating/Noise3DGenerator.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Generating/Noise3DGenerator.cpp b/src/Generating/Noise3DGenerator.cpp index fe6c9bdaf..a7af87bac 100644 --- a/src/Generating/Noise3DGenerator.cpp +++ b/src/Generating/Noise3DGenerator.cpp @@ -537,7 +537,7 @@ cBiomalNoise3DComposable::cBiomalNoise3DComposable(int a_Seed, cBiomeGenPtr a_Bi { for (int x = 0; x <= AVERAGING_SIZE * 2; x++) { - m_Weight[z][x] = static_cast((5 - std::abs(5 - x)) + (5 - std::abs(5 - z))); + m_Weight[z][x] = static_cast((AVERAGING_SIZE - std::abs(AVERAGING_SIZE - x)) + (AVERAGING_SIZE - std::abs(AVERAGING_SIZE - z))); m_WeightSum += m_Weight[z][x]; } } @@ -715,7 +715,7 @@ void cBiomalNoise3DComposable::GetBiomeParams(EMCSBiome a_Biome, NOISE_DATATYPE { switch (a_Biome) { - case biBeach: a_HeightAmp = 0.3f; a_MidPoint = 62; break; + case biBeach: a_HeightAmp = 0.2f; a_MidPoint = 60; break; case biBirchForest: a_HeightAmp = 0.1f; a_MidPoint = 64; break; case biBirchForestHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; case biBirchForestHillsM: a_HeightAmp = 0.075f; a_MidPoint = 68; break; diff --git a/src/Generating/Noise3DGenerator.h b/src/Generating/Noise3DGenerator.h index 1bc7f3fa1..35b1e4c94 100644 --- a/src/Generating/Noise3DGenerator.h +++ b/src/Generating/Noise3DGenerator.h @@ -144,8 +144,8 @@ public: void Initialize(cIniFile & a_IniFile); protected: - /** Number of columns around the pixel to query for biomes for averaging. */ - static const int AVERAGING_SIZE = 5; + /** Number of columns around the pixel to query for biomes for averaging. Must be less than or equal to 16. */ + static const int AVERAGING_SIZE = 9; /** Type used for a single parameter across the entire (downscaled) chunk. */ typedef NOISE_DATATYPE ChunkParam[5 * 5]; -- cgit v1.2.3 From e8e03e5df2d93109c1aa68592a70eb593bd8ed87 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 23 Nov 2014 14:21:44 +0000 Subject: Update GCC on Travis --- .travis.yml | 9 +++++++++ SetFlags.cmake | 35 +++++++++++------------------------ 2 files changed, 20 insertions(+), 24 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5260cfd17..4e8377748 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,15 @@ compiler: before_install: - if [ "$TRAVIS_MCSERVER_BUILD_TYPE" == "COVERAGE" ]; then sudo pip install cpp_coveralls; fi + # g++4.8 + - sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test + - sudo apt-get update -qq + +install: + # g++4.8 + - sudo apt-get install -qq g++-4.8 + - export CXX="g++-4.8" + # Build MCServer script: ./CIbuild.sh diff --git a/SetFlags.cmake b/SetFlags.cmake index c0a021c25..0d1bd99b3 100644 --- a/SetFlags.cmake +++ b/SetFlags.cmake @@ -64,18 +64,12 @@ macro(set_flags) execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) endif() - - if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND (NOT GCC_VERSION VERSION_GREATER 4.6)) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++0x") - set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_COVERAGE} -std=c++0x") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++0x") - else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11") - set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_COVERAGE} -std=c++11") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11") - endif() + + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11") + set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_COVERAGE} -std=c++11") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11") + #on os x clang adds pthread for us but we need to add it for gcc if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") add_flags_cxx("-stdlib=libc++") @@ -94,18 +88,11 @@ macro(set_flags) execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) endif() - - if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND (NOT GCC_VERSION VERSION_GREATER 4.6)) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++0x") - set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_COVERAGE} -std=c++0x") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++0x") - else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11") - set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_COVERAGE} -std=c++11") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11") - endif() + + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11") + set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_COVERAGE} -std=c++11") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11") # We use a signed char (fixes #640 on RasPi) add_flags_cxx("-fsigned-char") -- cgit v1.2.3 From 6382989ba08727898587f34f505a03a9035511a2 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 23 Nov 2014 14:22:05 +0000 Subject: Compilation fixes --- Tools/ProtoProxy/Connection.cpp | 4 ++-- Tools/ProtoProxy/Connection.h | 4 +--- src/Entities/Player.cpp | 12 +++++------- src/Logger.cpp | 2 +- src/OSSupport/IsThread.cpp | 4 ++-- 5 files changed, 11 insertions(+), 15 deletions(-) diff --git a/Tools/ProtoProxy/Connection.cpp b/Tools/ProtoProxy/Connection.cpp index eaf4fab02..fe61b37d1 100644 --- a/Tools/ProtoProxy/Connection.cpp +++ b/Tools/ProtoProxy/Connection.cpp @@ -189,7 +189,7 @@ cConnection::cConnection(SOCKET a_ClientSocket, cServer & a_Server) : m_Server(a_Server), m_ClientSocket(a_ClientSocket), m_ServerSocket(-1), - m_BeginTick(m_Timer.GetNowTime()), + m_BeginTick(std::chrono::steady_clock::now()), m_ClientState(csUnencrypted), m_ServerState(csUnencrypted), m_Nonce(0), @@ -436,7 +436,7 @@ bool cConnection::RelayFromClient(void) double cConnection::GetRelativeTime(void) { - return (double)(m_Timer.GetNowTime() - m_BeginTick) / 1000; + return std::chrono::duration_cast(std::chrono::steady_clock::now() - m_BeginTick).count() / 1000; } diff --git a/Tools/ProtoProxy/Connection.h b/Tools/ProtoProxy/Connection.h index 1fc9536de..c79273f8a 100644 --- a/Tools/ProtoProxy/Connection.h +++ b/Tools/ProtoProxy/Connection.h @@ -10,7 +10,6 @@ #pragma once #include "ByteBuffer.h" -#include "OSSupport/Timer.h" #include "PolarSSL++/AesCfb128Decryptor.h" #include "PolarSSL++/AesCfb128Encryptor.h" @@ -37,8 +36,7 @@ class cConnection SOCKET m_ClientSocket; SOCKET m_ServerSocket; - cTimer m_Timer; - long long m_BeginTick; // Tick when the relative time was first retrieved (used for GetRelativeTime()) + std::chrono::steady_clock::time_point m_BeginTick; // Tick when the relative time was first retrieved (used for GetRelativeTime()) enum eConnectionState { diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index acc9042a1..336dbeb72 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -354,7 +354,7 @@ float cPlayer::GetXpPercentage() bool cPlayer::SetCurrentExperience(short int a_CurrentXp) { - if (!(a_CurrentXp >= 0) || (a_CurrentXp > (SHRT_MAX - m_LifetimeTotalXp))) + if (!(a_CurrentXp >= 0) || (a_CurrentXp > (std::numeric_limits().max() - m_LifetimeTotalXp))) { LOGWARNING("Tried to update experiece with an invalid Xp value: %d", a_CurrentXp); return false; // oops, they gave us a dodgey number @@ -374,18 +374,17 @@ bool cPlayer::SetCurrentExperience(short int a_CurrentXp) short cPlayer::DeltaExperience(short a_Xp_delta) { - if (a_Xp_delta > (SHRT_MAX - m_CurrentXp)) + if (a_Xp_delta > (std::numeric_limits().max() - m_CurrentXp)) { // Value was bad, abort and report - LOGWARNING("Attempt was made to increment Xp by %d, which overflowed the short datatype. Ignoring.", - a_Xp_delta); + LOGWARNING("Attempt was made to increment Xp by %d, which overflowed the short datatype. Ignoring.", a_Xp_delta); return -1; // Should we instead just return the current Xp? } m_CurrentXp += a_Xp_delta; // Make sure they didn't subtract too much - m_CurrentXp = std::max(m_CurrentXp, 0); + m_CurrentXp = std::max(m_CurrentXp, 0); // Update total for score calculation if (a_Xp_delta > 0) @@ -393,8 +392,7 @@ short cPlayer::DeltaExperience(short a_Xp_delta) m_LifetimeTotalXp += a_Xp_delta; } - LOGD("Player \"%s\" gained/lost %d experience, total is now: %d", - GetName().c_str(), a_Xp_delta, m_CurrentXp); + LOGD("Player \"%s\" gained/lost %d experience, total is now: %d", GetName().c_str(), a_Xp_delta, m_CurrentXp); // Set experience to be updated m_bDirtyExperience = true; diff --git a/src/Logger.cpp b/src/Logger.cpp index fad4a5e75..c4adf4b48 100644 --- a/src/Logger.cpp +++ b/src/Logger.cpp @@ -45,7 +45,7 @@ void cLogger::LogSimple(AString a_Message, eLogLevel a_LogLevel) AString Line; #ifdef _DEBUG - Printf(Line, "[%04lx|%02d:%02d:%02d] %s\n", std::this_thread::get_id().hash(), timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, a_Message.c_str()); + Printf(Line, "[%04lx|%02d:%02d:%02d] %s\n", std::hash()(std::this_thread::get_id()), timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, a_Message.c_str()); #else Printf(Line, "[%02d:%02d:%02d] %s\n", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, a_Message.c_str()); #endif diff --git a/src/OSSupport/IsThread.cpp b/src/OSSupport/IsThread.cpp index 02d8a77c7..8914cac90 100644 --- a/src/OSSupport/IsThread.cpp +++ b/src/OSSupport/IsThread.cpp @@ -85,7 +85,7 @@ bool cIsThread::Start(void) } catch (std::system_error & a_Exception) { - LOGERROR("cIsThread::Wait (std::thread) error %i: could not construct thread %s; %s", m_ThreadName.c_str(), a_Exception.code().value(), a_Exception.what()); + LOGERROR("cIsThread::Wait (std::thread) error %i: could not construct thread %s; %s", a_Exception.code().value(), m_ThreadName.c_str(), a_Exception.what()); return false; } } @@ -119,7 +119,7 @@ bool cIsThread::Wait(void) } catch (std::system_error & a_Exception) { - LOGERROR("cIsThread::Wait (std::thread) error %i: could not join thread %s; %s", m_ThreadName.c_str(), a_Exception.code().value(), a_Exception.what()); + LOGERROR("cIsThread::Wait (std::thread) error %i: could not join thread %s; %s", a_Exception.code().value(), m_ThreadName.c_str(), a_Exception.what()); return false; } } -- cgit v1.2.3 From 2ae4d2a96abf705c48d3e9440f301d1f88a9722a Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 23 Nov 2014 17:13:40 +0000 Subject: Removed unnecessary #includes --- src/Generating/Noise3DGenerator.cpp | 1 - src/Noise/Noise.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/src/Generating/Noise3DGenerator.cpp b/src/Generating/Noise3DGenerator.cpp index 78b739d32..c8f87ec8e 100644 --- a/src/Generating/Noise3DGenerator.cpp +++ b/src/Generating/Noise3DGenerator.cpp @@ -6,7 +6,6 @@ #include "Globals.h" #include "Noise3DGenerator.h" #include "../OSSupport/File.h" -#include "../OSSupport/Timer.h" #include "../IniFile.h" #include "../LinearInterpolation.h" #include "../LinearUpscale.h" diff --git a/src/Noise/Noise.cpp b/src/Noise/Noise.cpp index 509be7d6c..0249ab6c1 100644 --- a/src/Noise/Noise.cpp +++ b/src/Noise/Noise.cpp @@ -2,7 +2,6 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "Noise.h" -#include "OSSupport/Timer.h" #define FAST_FLOOR(x) (((x) < 0) ? (((int)x) - 1) : ((int)x)) -- cgit v1.2.3 From 478bbad5ede86ec9f89444bdd60471ab314bf65a Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 23 Nov 2014 18:16:20 +0100 Subject: Added TwoHeights shape generator. This is a faster shape generator that can generate overhangs and has biome awareness. --- src/Generating/CMakeLists.txt | 8 ++- src/Generating/HeiGen.h | 13 ++--- src/Generating/ShapeGen.cpp | 5 ++ src/Generating/TwoHeights.cpp | 121 ++++++++++++++++++++++++++++++++++++++++++ src/Generating/TwoHeights.h | 23 ++++++++ 5 files changed, 162 insertions(+), 8 deletions(-) create mode 100644 src/Generating/TwoHeights.cpp create mode 100644 src/Generating/TwoHeights.h diff --git a/src/Generating/CMakeLists.txt b/src/Generating/CMakeLists.txt index dcb4bb3a7..a28510d40 100644 --- a/src/Generating/CMakeLists.txt +++ b/src/Generating/CMakeLists.txt @@ -31,8 +31,10 @@ SET (SRCS StructGen.cpp TestRailsGen.cpp Trees.cpp + TwoHeights.cpp UnderwaterBaseGen.cpp - VillageGen.cpp) + VillageGen.cpp +) SET (HDRS BioGen.h @@ -65,8 +67,10 @@ SET (HDRS StructGen.h TestRailsGen.h Trees.h + TwoHeights.h UnderwaterBaseGen.h - VillageGen.h) + VillageGen.h +) if(NOT MSVC) add_library(Generating ${SRCS} ${HDRS}) diff --git a/src/Generating/HeiGen.h b/src/Generating/HeiGen.h index 9c99a9326..62bb227c6 100644 --- a/src/Generating/HeiGen.h +++ b/src/Generating/HeiGen.h @@ -170,7 +170,11 @@ public: m_BiomeGen(a_BiomeGen) { } - + + // cTerrainHeightGen overrides: + virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; + virtual void InitializeHeightGen(cIniFile & a_IniFile) override; + protected: typedef cChunkDef::BiomeMap BiomeNeighbors[3][3]; @@ -187,11 +191,8 @@ protected: float m_BaseHeight; } ; static const sGenParam m_GenParam[256]; - - // cTerrainHeightGen overrides: - virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; - virtual void InitializeHeightGen(cIniFile & a_IniFile) override; - + + NOISE_DATATYPE GetHeightAt(int a_RelX, int a_RelZ, int a_ChunkX, int a_ChunkZ, const BiomeNeighbors & a_BiomeNeighbors); } ; diff --git a/src/Generating/ShapeGen.cpp b/src/Generating/ShapeGen.cpp index 750b34e10..45a9c3b93 100644 --- a/src/Generating/ShapeGen.cpp +++ b/src/Generating/ShapeGen.cpp @@ -9,6 +9,7 @@ #include "DistortedHeightmap.h" #include "EndGen.h" #include "Noise3DGenerator.h" +#include "TwoHeights.h" @@ -121,6 +122,10 @@ cTerrainShapeGenPtr cTerrainShapeGen::CreateShapeGen(cIniFile & a_IniFile, cBiom { res = std::make_shared(a_Seed); } + else if (NoCaseCompare(shapeGenName, "TwoHeights") == 0) + { + res = CreateShapeGenTwoHeights(a_Seed, a_BiomeGen); + } else { // No match found, force-set the default and retry diff --git a/src/Generating/TwoHeights.cpp b/src/Generating/TwoHeights.cpp new file mode 100644 index 000000000..e75c301de --- /dev/null +++ b/src/Generating/TwoHeights.cpp @@ -0,0 +1,121 @@ + +// TwoHeights.cpp + +// Implements the cTwoHeights class representing the terrain shape generator using two switched heightmaps + +#include "Globals.h" +#include "TwoHeights.h" +#include "../Noise/InterpolNoise.h" +#include "HeiGen.h" +#include "../LinearUpscale.h" +#include "../IniFile.h" + + + + + +class cTwoHeights: + public cTerrainShapeGen +{ + typedef cTerrainShapeGen super; +public: + cTwoHeights(int a_Seed, cBiomeGenPtr a_BiomeGen): + m_Seed(a_Seed), + m_Choice(a_Seed), + m_HeightA(a_Seed + 1, a_BiomeGen), + m_HeightB(a_Seed + 2, a_BiomeGen) + { + } + + + // cTerrainShapeGen override: + virtual void GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape) override + { + // Generate the two heightmaps: + cChunkDef::HeightMap heightsA; + cChunkDef::HeightMap heightsB; + m_HeightA.GenHeightMap(a_ChunkX, a_ChunkZ, heightsA); + m_HeightB.GenHeightMap(a_ChunkX, a_ChunkZ, heightsB); + + // Generate the choice noise: + NOISE_DATATYPE smallChoice[33 * 5 * 5]; + NOISE_DATATYPE workspace[33 * 5 * 5]; + NOISE_DATATYPE startX = 0; + NOISE_DATATYPE endX = 256 * m_FrequencyY; + NOISE_DATATYPE startY = a_ChunkX * cChunkDef::Width * m_FrequencyX; + NOISE_DATATYPE endY = (a_ChunkX * cChunkDef::Width + cChunkDef::Width + 1) * m_FrequencyX; + NOISE_DATATYPE startZ = a_ChunkZ * cChunkDef::Width * m_FrequencyZ; + NOISE_DATATYPE endZ = (a_ChunkZ * cChunkDef::Width + cChunkDef::Width + 1) * m_FrequencyZ; + m_Choice.Generate3D(smallChoice, 33, 5, 5, startX, endX, startY, endY, startZ, endZ, workspace); + NOISE_DATATYPE choice[257 * 17 * 17]; + LinearUpscale3DArray(smallChoice, 33, 5, 5, choice, 8, 4, 4); + + // Generate the shape: + int idxShape = 0; + for (int z = 0; z < cChunkDef::Width; z++) + { + for (int x = 0; x < cChunkDef::Width; x++) + { + int idxChoice = 257 * 17 * z + 257 * x; + NOISE_DATATYPE heightA = static_cast(cChunkDef::GetHeight(heightsA, x, z)); + NOISE_DATATYPE heightB = static_cast(cChunkDef::GetHeight(heightsB, x, z)); + for (int y = 0; y < cChunkDef::Height; y++) + { + int height = static_cast(ClampedLerp(heightA, heightB, choice[idxChoice++])); + a_Shape[idxShape++] = (y < height) ? 1 : 0; + } + } // for x + } // for z + } + + + virtual void InitializeShapeGen(cIniFile & a_IniFile) + { + m_FrequencyX = static_cast(a_IniFile.GetValueSetF("Generator", "TwoHeightsFrequencyX", 40)); + m_FrequencyY = static_cast(a_IniFile.GetValueSetF("Generator", "TwoHeightsFrequencyY", 40)); + m_FrequencyZ = static_cast(a_IniFile.GetValueSetF("Generator", "TwoHeightsFrequencyZ", 40)); + + // Initialize the two underlying height generators from an empty INI file: + cIniFile empty; + m_HeightA.InitializeHeightGen(empty); + m_HeightB.InitializeHeightGen(empty); + + // Add the choice octaves: + NOISE_DATATYPE freq = 0.001f; + NOISE_DATATYPE ampl = 1; + for (int i = 0; i < 4; i++) + { + m_Choice.AddOctave(freq, ampl); + freq = freq * 2; + ampl = ampl / 2; + } + } + +protected: + int m_Seed; + + /** The noise used to decide between the two heightmaps. */ + cOctavedNoise> m_Choice; + + /** The first height generator. */ + cHeiGenBiomal m_HeightA; + + /** The second height generator. */ + cHeiGenBiomal m_HeightB; + + /** The base frequencies for m_Choice in each of the world axis directions. */ + NOISE_DATATYPE m_FrequencyX, m_FrequencyY, m_FrequencyZ; +}; + + + + + +cTerrainShapeGenPtr CreateShapeGenTwoHeights(int a_Seed, cBiomeGenPtr a_BiomeGen) +{ + return std::make_shared(a_Seed, a_BiomeGen); +} + + + + diff --git a/src/Generating/TwoHeights.h b/src/Generating/TwoHeights.h new file mode 100644 index 000000000..353598011 --- /dev/null +++ b/src/Generating/TwoHeights.h @@ -0,0 +1,23 @@ + +// TwoHeights.h + +// Declares the function to create a new instance of the cTwoHeights terrain shape generator + + + + + +#pragma once + +#include "ComposableGenerator.h" + + + + +/** Creates and returns a new instance of the cTwoHeights terrain shape generator. +The instance must be Initialize()-d before it is used. */ +extern cTerrainShapeGenPtr CreateShapeGenTwoHeights(int a_Seed, cBiomeGenPtr a_BiomeGen); + + + + -- cgit v1.2.3 From 3e068a01a802363ca8cebb9a2e850916023665f5 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Mon, 24 Nov 2014 13:44:15 +0100 Subject: Changed back capitalization. --- src/World.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/World.cpp b/src/World.cpp index 1a64105c2..001ea72c7 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -117,7 +117,7 @@ public: for (int i = 0; i < maxQueue; i++) { int chunkX, chunkZ; - decodeChunkCoords(i, chunkX, chunkZ); + DecodeChunkCoords(i, chunkX, chunkZ); m_World.GetLightingThread().QueueChunk(chunkX, chunkZ, this); } // for i @@ -170,7 +170,7 @@ protected: if (m_NextIdx < m_MaxIdx) { int chunkX, chunkZ; - decodeChunkCoords(m_NextIdx, chunkX, chunkZ); + DecodeChunkCoords(m_NextIdx, chunkX, chunkZ); m_World.GetLightingThread().QueueChunk(chunkX, chunkZ, this); m_NextIdx += 1; } @@ -191,7 +191,7 @@ protected: /** Decodes the index into chunk coords. Provides the specific chunk ordering. */ - void decodeChunkCoords(int a_Idx, int & a_ChunkX, int & a_ChunkZ) + void DecodeChunkCoords(int a_Idx, int & a_ChunkX, int & a_ChunkZ) { // A zigzag pattern from the top to bottom, each row alternating between forward-x and backward-x: int z = a_Idx / m_PrepareDistance; -- cgit v1.2.3 From c1a52dc9fb54c5eb595c1e554787902b82924e9d Mon Sep 17 00:00:00 2001 From: Mattes D Date: Tue, 25 Nov 2014 21:24:25 +0100 Subject: ClientHandle: Fixed max block place distance check. Fixes #1492 --- src/ClientHandle.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index c4ce721c3..a6cbad32a 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1238,12 +1238,18 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e { // TODO: Rewrite this function - LOGD("HandleRightClick: {%d, %d, %d}, face %d, HeldItem: %s", - a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, ItemToFullString(a_HeldItem).c_str() + // Distance from the block's center to the player's eye height + double dist = (Vector3d(a_BlockX, a_BlockY, a_BlockZ) + Vector3d(0.5, 0.5, 0.5) - m_Player->GetEyePosition()).Length(); + LOGD("HandleRightClick: {%d, %d, %d}, face %d, HeldItem: %s; dist: %.02f", + a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, ItemToFullString(a_HeldItem).c_str(), dist ); - + + // Check the reach distance: + // _X 2014-11-25: I've maxed at 5.26 with a Survival client and 5.78 with a Creative client in my tests + double maxDist = m_Player->IsGameModeCreative() ? 5.78 : 5.26; + bool AreRealCoords = (dist <= maxDist); + cWorld * World = m_Player->GetWorld(); - bool AreRealCoords = (Vector3d(a_BlockX, a_BlockY, a_BlockZ) - m_Player->GetPosition()).Length() <= 5; if ( (a_BlockFace != BLOCK_FACE_NONE) && // The client is interacting with a specific block -- cgit v1.2.3 From 187bdab4fa90fbfa5b1979ea529dc9c0deac89d9 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 25 Nov 2014 23:03:33 +0000 Subject: Merge remote-tracking branch 'origin-master' into c++11 --- src/Generating/CMakeLists.txt | 12 +- src/Generating/ChunkDesc.cpp | 63 ++++ src/Generating/ChunkDesc.h | 25 +- src/Generating/CompoGen.cpp | 336 +----------------- src/Generating/CompoGen.h | 45 +-- src/Generating/CompoGenBiomal.cpp | 586 ++++++++++++++++++++++++++++++++ src/Generating/CompoGenBiomal.h | 21 ++ src/Generating/ComposableGenerator.cpp | 112 +++--- src/Generating/ComposableGenerator.h | 95 ++++-- src/Generating/CompositedHeiGen.h | 49 +++ src/Generating/DistortedHeightmap.cpp | 565 +----------------------------- src/Generating/DistortedHeightmap.h | 60 +--- src/Generating/DungeonRoomsFinisher.cpp | 25 +- src/Generating/DungeonRoomsFinisher.h | 8 +- src/Generating/EndGen.cpp | 44 +-- src/Generating/EndGen.h | 8 +- src/Generating/FinishGen.cpp | 2 +- src/Generating/HeiGen.cpp | 92 +++-- src/Generating/HeiGen.h | 98 ++++-- src/Generating/Noise3DGenerator.cpp | 407 +++++++--------------- src/Generating/Noise3DGenerator.h | 51 ++- src/Generating/ShapeGen.cpp | 145 ++++++++ src/Generating/StructGen.cpp | 36 +- src/Generating/StructGen.h | 33 +- src/Generating/TwoHeights.cpp | 121 +++++++ src/Generating/TwoHeights.h | 23 ++ src/Generating/VillageGen.cpp | 6 +- src/Globals.h | 4 +- src/Mobs/Monster.cpp | 4 +- src/Mobs/Monster.h | 8 +- src/World.cpp | 255 +++++++------- src/World.h | 2 + 32 files changed, 1688 insertions(+), 1653 deletions(-) create mode 100644 src/Generating/CompoGenBiomal.cpp create mode 100644 src/Generating/CompoGenBiomal.h create mode 100644 src/Generating/CompositedHeiGen.h create mode 100644 src/Generating/ShapeGen.cpp create mode 100644 src/Generating/TwoHeights.cpp create mode 100644 src/Generating/TwoHeights.h diff --git a/src/Generating/CMakeLists.txt b/src/Generating/CMakeLists.txt index 1a26bd0d5..a28510d40 100644 --- a/src/Generating/CMakeLists.txt +++ b/src/Generating/CMakeLists.txt @@ -10,6 +10,7 @@ SET (SRCS ChunkDesc.cpp ChunkGenerator.cpp CompoGen.cpp + CompoGenBiomal.cpp ComposableGenerator.cpp DistortedHeightmap.cpp DungeonRoomsFinisher.cpp @@ -30,8 +31,10 @@ SET (SRCS StructGen.cpp TestRailsGen.cpp Trees.cpp + TwoHeights.cpp UnderwaterBaseGen.cpp - VillageGen.cpp) + VillageGen.cpp +) SET (HDRS BioGen.h @@ -39,7 +42,9 @@ SET (HDRS ChunkDesc.h ChunkGenerator.h CompoGen.h + CompoGenBiomal.h ComposableGenerator.h + CompositedHeiGen.h DistortedHeightmap.h DungeonRoomsFinisher.h EndGen.h @@ -58,11 +63,14 @@ SET (HDRS RainbowRoadsGen.h Ravines.h RoughRavines.h + ShapeGen.cpp StructGen.h TestRailsGen.h Trees.h + TwoHeights.h UnderwaterBaseGen.h - VillageGen.h) + VillageGen.h +) if(NOT MSVC) add_library(Generating ${SRCS} ${HDRS}) diff --git a/src/Generating/ChunkDesc.cpp b/src/Generating/ChunkDesc.cpp index 042b688b7..4a5ac5a18 100644 --- a/src/Generating/ChunkDesc.cpp +++ b/src/Generating/ChunkDesc.cpp @@ -152,6 +152,52 @@ int cChunkDesc::GetHeight(int a_RelX, int a_RelZ) +void cChunkDesc::SetHeightFromShape(const Shape & a_Shape) +{ + for (int z = 0; z < cChunkDef::Width; z++) + { + for (int x = 0; x < cChunkDef::Width; x++) + { + for (int y = cChunkDef::Height - 1; y > 0; y--) + { + if (a_Shape[y + x * 256 + z * 16 * 256] != 0) + { + cChunkDef::SetHeight(m_HeightMap, x, z, y); + break; + } + } // for y + } // for x + } // for z +} + + + + + +void cChunkDesc::GetShapeFromHeight(Shape & a_Shape) const +{ + for (int z = 0; z < cChunkDef::Width; z++) + { + for (int x = 0; x < cChunkDef::Width; x++) + { + int height = cChunkDef::GetHeight(m_HeightMap, x, z); + for (int y = 0; y <= height; y++) + { + a_Shape[y + x * 256 + z * 16 * 256] = 1; + } + + for (int y = height + 1; y < cChunkDef::Height; y++) + { + a_Shape[y + x * 256 + z * 16 * 256] = 0; + } // for y + } // for x + } // for z +} + + + + + void cChunkDesc::SetUseDefaultBiomes(bool a_bUseDefaultBiomes) { m_bUseDefaultBiomes = a_bUseDefaultBiomes; @@ -366,6 +412,23 @@ HEIGHTTYPE cChunkDesc::GetMaxHeight(void) const +HEIGHTTYPE cChunkDesc::GetMinHeight(void) const +{ + HEIGHTTYPE MinHeight = m_HeightMap[0]; + for (size_t i = 1; i < ARRAYCOUNT(m_HeightMap); i++) + { + if (m_HeightMap[i] < MinHeight) + { + MinHeight = m_HeightMap[i]; + } + } + return MinHeight; +} + + + + + void cChunkDesc::FillRelCuboid( int a_MinX, int a_MaxX, int a_MinY, int a_MaxY, diff --git a/src/Generating/ChunkDesc.h b/src/Generating/ChunkDesc.h index 570132790..480106fb5 100644 --- a/src/Generating/ChunkDesc.h +++ b/src/Generating/ChunkDesc.h @@ -29,10 +29,17 @@ class cChunkDesc { public: // tolua_end + + /** The datatype used to represent the entire chunk worth of shape. + 0 = air + 1 = solid + Indexed as [y + 256 * x + 256 * 16 * z]. */ + typedef Byte Shape[256 * 16 * 16]; /** Uncompressed block metas, 1 meta per byte */ typedef NIBBLETYPE BlockNibbleBytes[cChunkDef::NumBlocks]; + cChunkDesc(int a_ChunkX, int a_ChunkZ); ~cChunkDesc(); @@ -57,10 +64,21 @@ public: EMCSBiome GetBiome(int a_RelX, int a_RelZ); // These operate on the heightmap, so they could get out of sync with the data - // Use UpdateHeightmap() to re-sync + // Use UpdateHeightmap() to re-calculate heightmap from the block data void SetHeight(int a_RelX, int a_RelZ, int a_Height); int GetHeight(int a_RelX, int a_RelZ); + // tolua_end + + /** Sets the heightmap to match the given shape data. + Note that this ignores overhangs; the method is mostly used by old composition generators. */ + void SetHeightFromShape(const Shape & a_Shape); + + /** Sets the shape in a_Shape to match the heightmap stored currently in m_HeightMap. */ + void GetShapeFromHeight(Shape & a_Shape) const; + + // tolua_begin + // Default generation: void SetUseDefaultBiomes(bool a_bUseDefaultBiomes); bool IsUsingDefaultBiomes(void) const; @@ -77,8 +95,11 @@ public: /** Reads an area from the chunk into a cBlockArea, blocktypes and blockmetas */ void ReadBlockArea(cBlockArea & a_Dest, int a_MinRelX, int a_MaxRelX, int a_MinRelY, int a_MaxRelY, int a_MinRelZ, int a_MaxRelZ); - /** Returns the maximum height value in the heightmap */ + /** Returns the maximum height value in the heightmap. */ HEIGHTTYPE GetMaxHeight(void) const; + + /** Returns the minimum height value in the heightmap. */ + HEIGHTTYPE GetMinHeight(void) const; /** Fills the relative cuboid with specified block; allows cuboid out of range of this chunk */ void FillRelCuboid( diff --git a/src/Generating/CompoGen.cpp b/src/Generating/CompoGen.cpp index 29b831dfd..23cc64d78 100644 --- a/src/Generating/CompoGen.cpp +++ b/src/Generating/CompoGen.cpp @@ -21,8 +21,9 @@ //////////////////////////////////////////////////////////////////////////////// // cCompoGenSameBlock: -void cCompoGenSameBlock::ComposeTerrain(cChunkDesc & a_ChunkDesc) +void cCompoGenSameBlock::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) { + a_ChunkDesc.SetHeightFromShape(a_Shape); a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0); for (int z = 0; z < cChunkDef::Width; z++) { @@ -63,7 +64,7 @@ void cCompoGenSameBlock::InitializeCompoGen(cIniFile & a_IniFile) //////////////////////////////////////////////////////////////////////////////// // cCompoGenDebugBiomes: -void cCompoGenDebugBiomes::ComposeTerrain(cChunkDesc & a_ChunkDesc) +void cCompoGenDebugBiomes::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) { static BLOCKTYPE Blocks[] = { @@ -92,6 +93,7 @@ void cCompoGenDebugBiomes::ComposeTerrain(cChunkDesc & a_ChunkDesc) E_BLOCK_BEDROCK, } ; + a_ChunkDesc.SetHeightFromShape(a_Shape); a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0); for (int z = 0; z < cChunkDef::Width; z++) @@ -131,7 +133,7 @@ cCompoGenClassic::cCompoGenClassic(void) : -void cCompoGenClassic::ComposeTerrain(cChunkDesc & a_ChunkDesc) +void cCompoGenClassic::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) { /* The classic composition means: - 1 layer of grass, 3 of dirt and the rest stone, if the height > sealevel + beachheight @@ -142,6 +144,7 @@ void cCompoGenClassic::ComposeTerrain(cChunkDesc & a_ChunkDesc) */ a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0); + a_ChunkDesc.SetHeightFromShape(a_Shape); // The patterns to use for different situations, must be same length! const BLOCKTYPE PatternGround[] = {m_BlockTop, m_BlockMiddle, m_BlockMiddle, m_BlockMiddle} ; @@ -194,7 +197,7 @@ void cCompoGenClassic::ComposeTerrain(cChunkDesc & a_ChunkDesc) void cCompoGenClassic::InitializeCompoGen(cIniFile & a_IniFile) { - m_SeaLevel = a_IniFile.GetValueSetI("Generator", "ClassicSeaLevel", m_SeaLevel); + m_SeaLevel = a_IniFile.GetValueSetI("Generator", "SeaLevel", m_SeaLevel); m_BeachHeight = a_IniFile.GetValueSetI("Generator", "ClassicBeachHeight", m_BeachHeight); m_BeachDepth = a_IniFile.GetValueSetI("Generator", "ClassicBeachDepth", m_BeachDepth); m_BlockTop = (BLOCKTYPE)(GetIniItemSet(a_IniFile, "Generator", "ClassicBlockTop", "grass").m_ItemType); @@ -209,323 +212,6 @@ void cCompoGenClassic::InitializeCompoGen(cIniFile & a_IniFile) -//////////////////////////////////////////////////////////////////////////////// -// cCompoGenBiomal: - -void cCompoGenBiomal::ComposeTerrain(cChunkDesc & a_ChunkDesc) -{ - a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0); - - int ChunkX = a_ChunkDesc.GetChunkX(); - int ChunkZ = a_ChunkDesc.GetChunkZ(); - - /* - _X 2013_04_22: - There's no point in generating the whole cubic noise at once, because the noise values are used in - only about 20 % of the cases, so the speed gained by precalculating is lost by precalculating too much data - */ - - for (int z = 0; z < cChunkDef::Width; z++) - { - for (int x = 0; x < cChunkDef::Width; x++) - { - int Height = a_ChunkDesc.GetHeight(x, z); - if (Height > m_SeaLevel) - { - switch (a_ChunkDesc.GetBiome(x, z)) - { - case biOcean: - case biPlains: - case biExtremeHills: - case biForest: - case biTaiga: - case biSwampland: - case biRiver: - case biFrozenOcean: - case biFrozenRiver: - case biIcePlains: - case biIceMountains: - case biForestHills: - case biTaigaHills: - case biExtremeHillsEdge: - case biJungle: - case biJungleHills: - case biJungleEdge: - case biDeepOcean: - case biStoneBeach: - case biColdBeach: - case biBirchForest: - case biBirchForestHills: - case biRoofedForest: - case biColdTaiga: - case biColdTaigaHills: - case biExtremeHillsPlus: - case biSavanna: - case biSavannaPlateau: - case biSunflowerPlains: - case biExtremeHillsM: - case biFlowerForest: - case biTaigaM: - case biSwamplandM: - case biIcePlainsSpikes: - case biJungleM: - case biJungleEdgeM: - case biBirchForestM: - case biBirchForestHillsM: - case biRoofedForestM: - case biColdTaigaM: - case biExtremeHillsPlusM: - case biSavannaM: - case biSavannaPlateauM: - { - FillColumnGrass(x, z, Height, a_ChunkDesc.GetBlockTypes()); - break; - } - - case biMesa: - case biMesaPlateauF: - case biMesaPlateau: - case biMesaBryce: - case biMesaPlateauFM: - case biMesaPlateauM: - { - FillColumnClay(x, z, Height, a_ChunkDesc.GetBlockTypes()); - break; - } - - case biMegaTaiga: - case biMegaTaigaHills: - case biMegaSpruceTaiga: - case biMegaSpruceTaigaHills: - { - FillColumnDirt(x, z, Height, a_ChunkDesc.GetBlockTypes()); - break; - } - - case biDesertHills: - case biDesert: - case biDesertM: - case biBeach: - { - FillColumnSand(x, z, Height, a_ChunkDesc.GetBlockTypes()); - break; - } - case biMushroomIsland: - case biMushroomShore: - { - FillColumnMycelium(x, z, Height, a_ChunkDesc.GetBlockTypes()); - break; - } - default: - { - // TODO - ASSERT(!"CompoGenBiomal: Biome not implemented yet!"); - break; - } - } - } - else - { - switch (a_ChunkDesc.GetBiome(x, z)) - { - case biDesert: - case biBeach: - { - // Fill with water, sand, sandstone and stone - FillColumnWaterSand(x, z, Height, a_ChunkDesc.GetBlockTypes()); - break; - } - default: - { - // Fill with water, sand/dirt/clay mix and stone - if (m_Noise.CubicNoise2D(0.3f * (cChunkDef::Width * ChunkX + x), 0.3f * (cChunkDef::Width * ChunkZ + z)) < 0) - { - FillColumnWaterSand(x, z, Height, a_ChunkDesc.GetBlockTypes()); - } - else - { - FillColumnWaterDirt(x, z, Height, a_ChunkDesc.GetBlockTypes()); - } - break; - } - } // switch (biome) - a_ChunkDesc.SetHeight(x, z, m_SeaLevel + 1); - } // else (under water) - a_ChunkDesc.SetBlockType(x, 0, z, E_BLOCK_BEDROCK); - } // for x - } // for z -} - - - - - -void cCompoGenBiomal::InitializeCompoGen(cIniFile & a_IniFile) -{ - m_SeaLevel = a_IniFile.GetValueSetI("Generator", "BiomalSeaLevel", m_SeaLevel) - 1; -} - - - - - -void cCompoGenBiomal::FillColumnGrass(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes) -{ - BLOCKTYPE Pattern[] = - { - E_BLOCK_GRASS, - E_BLOCK_DIRT, - E_BLOCK_DIRT, - E_BLOCK_DIRT, - } ; - FillColumnPattern(a_RelX, a_RelZ, a_Height, a_BlockTypes, Pattern, ARRAYCOUNT(Pattern)); - - for (int y = a_Height - ARRAYCOUNT(Pattern); y > 0; y--) - { - cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STONE); - } -} - - - - - -void cCompoGenBiomal::FillColumnClay(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes) -{ - BLOCKTYPE Pattern[] = - { - E_BLOCK_HARDENED_CLAY, - E_BLOCK_HARDENED_CLAY, - E_BLOCK_HARDENED_CLAY, - E_BLOCK_HARDENED_CLAY, - } ; - FillColumnPattern(a_RelX, a_RelZ, a_Height, a_BlockTypes, Pattern, ARRAYCOUNT(Pattern)); - - for (int y = a_Height - ARRAYCOUNT(Pattern); y > 0; y--) - { - cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STONE); - } -} - - - - - -void cCompoGenBiomal::FillColumnDirt(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes) -{ - for (int y = 0; y < 4; y++) - { - if (a_Height - y < 0) - { - return; - } - cChunkDef::SetBlock(a_BlockTypes, a_RelX, a_Height - y, a_RelZ, E_BLOCK_DIRT); - } - for (int y = a_Height - 4; y > 0; y--) - { - cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STONE); - } -} - - - - - -void cCompoGenBiomal::FillColumnSand(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes) -{ - BLOCKTYPE Pattern[] = - { - E_BLOCK_SAND, - E_BLOCK_SAND, - E_BLOCK_SAND, - E_BLOCK_SANDSTONE, - } ; - FillColumnPattern(a_RelX, a_RelZ, a_Height, a_BlockTypes, Pattern, ARRAYCOUNT(Pattern)); - - for (int y = a_Height - ARRAYCOUNT(Pattern); y > 0; y--) - { - cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STONE); - } -} - - - - - - -void cCompoGenBiomal::FillColumnMycelium (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes) -{ - BLOCKTYPE Pattern[] = - { - E_BLOCK_MYCELIUM, - E_BLOCK_DIRT, - E_BLOCK_DIRT, - E_BLOCK_DIRT, - } ; - FillColumnPattern(a_RelX, a_RelZ, a_Height, a_BlockTypes, Pattern, ARRAYCOUNT(Pattern)); - - for (int y = a_Height - ARRAYCOUNT(Pattern); y > 0; y--) - { - cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STONE); - } -} - - - - - -void cCompoGenBiomal::FillColumnWaterSand(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes) -{ - FillColumnSand(a_RelX, a_RelZ, a_Height, a_BlockTypes); - for (int y = a_Height + 1; y <= m_SeaLevel + 1; y++) - { - cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STATIONARY_WATER); - } -} - - - - - -void cCompoGenBiomal::FillColumnWaterDirt(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes) -{ - // Dirt - BLOCKTYPE Pattern[] = - { - E_BLOCK_DIRT, - E_BLOCK_DIRT, - E_BLOCK_DIRT, - E_BLOCK_DIRT, - } ; - FillColumnPattern(a_RelX, a_RelZ, a_Height, a_BlockTypes, Pattern, ARRAYCOUNT(Pattern)); - - for (int y = a_Height - ARRAYCOUNT(Pattern); y > 0; y--) - { - cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STONE); - } - for (int y = a_Height + 1; y <= m_SeaLevel + 1; y++) - { - cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STATIONARY_WATER); - } -} - - - - - - -void cCompoGenBiomal::FillColumnPattern(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes, const BLOCKTYPE * a_Pattern, int a_PatternSize) -{ - for (int y = a_Height, idx = 0; (y >= 0) && (idx < a_PatternSize); y--, idx++) - { - cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, a_Pattern[idx]); - } -} - - - - - //////////////////////////////////////////////////////////////////////////////// // cCompoGenNether: @@ -540,7 +226,7 @@ cCompoGenNether::cCompoGenNether(int a_Seed) : -void cCompoGenNether::ComposeTerrain(cChunkDesc & a_ChunkDesc) +void cCompoGenNether::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) { HEIGHTTYPE MaxHeight = a_ChunkDesc.GetMaxHeight(); @@ -696,7 +382,7 @@ cCompoGenCache::~cCompoGenCache() -void cCompoGenCache::ComposeTerrain(cChunkDesc & a_ChunkDesc) +void cCompoGenCache::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) { #ifdef _DEBUG if (((m_NumHits + m_NumMisses) % 1024) == 10) @@ -731,6 +417,7 @@ void cCompoGenCache::ComposeTerrain(cChunkDesc & a_ChunkDesc) // Use the cached data: memcpy(a_ChunkDesc.GetBlockTypes(), m_CacheData[Idx].m_BlockTypes, sizeof(a_ChunkDesc.GetBlockTypes())); memcpy(a_ChunkDesc.GetBlockMetasUncompressed(), m_CacheData[Idx].m_BlockMetas, sizeof(a_ChunkDesc.GetBlockMetasUncompressed())); + memcpy(a_ChunkDesc.GetHeightMap(), m_CacheData[Idx].m_HeightMap, sizeof(a_ChunkDesc.GetHeightMap())); m_NumHits++; m_TotalChain += i; @@ -739,7 +426,7 @@ void cCompoGenCache::ComposeTerrain(cChunkDesc & a_ChunkDesc) // Not in the cache: m_NumMisses++; - m_Underlying->ComposeTerrain(a_ChunkDesc); + m_Underlying->ComposeTerrain(a_ChunkDesc, a_Shape); // Insert it as the first item in the MRU order: int Idx = m_CacheOrder[m_CacheSize - 1]; @@ -750,6 +437,7 @@ void cCompoGenCache::ComposeTerrain(cChunkDesc & a_ChunkDesc) m_CacheOrder[0] = Idx; memcpy(m_CacheData[Idx].m_BlockTypes, a_ChunkDesc.GetBlockTypes(), sizeof(a_ChunkDesc.GetBlockTypes())); memcpy(m_CacheData[Idx].m_BlockMetas, a_ChunkDesc.GetBlockMetasUncompressed(), sizeof(a_ChunkDesc.GetBlockMetasUncompressed())); + memcpy(m_CacheData[Idx].m_HeightMap, a_ChunkDesc.GetHeightMap(), sizeof(a_ChunkDesc.GetHeightMap())); m_CacheData[Idx].m_ChunkX = ChunkX; m_CacheData[Idx].m_ChunkZ = ChunkZ; } diff --git a/src/Generating/CompoGen.h b/src/Generating/CompoGen.h index c65a07fe8..3847688cd 100644 --- a/src/Generating/CompoGen.h +++ b/src/Generating/CompoGen.h @@ -38,7 +38,7 @@ protected: bool m_IsBedrocked; // cTerrainCompositionGen overrides: - virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc) override; + virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) override; virtual void InitializeCompoGen(cIniFile & a_IniFile) override; } ; @@ -55,7 +55,7 @@ public: protected: // cTerrainCompositionGen overrides: - virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc) override; + virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) override; } ; @@ -81,7 +81,7 @@ protected: BLOCKTYPE m_BlockSea; // cTerrainCompositionGen overrides: - virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc) override; + virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) override; virtual void InitializeCompoGen(cIniFile & a_IniFile) override; } ; @@ -89,40 +89,6 @@ protected: -class cCompoGenBiomal : - public cTerrainCompositionGen -{ -public: - cCompoGenBiomal(int a_Seed) : - m_Noise(a_Seed + 1000), - m_SeaLevel(62) - { - } - -protected: - - cNoise m_Noise; - int m_SeaLevel; - - // cTerrainCompositionGen overrides: - virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc) override; - virtual void InitializeCompoGen(cIniFile & a_IniFile) override; - - void FillColumnGrass (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes); - void FillColumnClay (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes); - void FillColumnDirt (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes); - void FillColumnSand (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes); - void FillColumnMycelium (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes); - void FillColumnWaterSand(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes); - void FillColumnWaterDirt(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes); - - void FillColumnPattern (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes, const BLOCKTYPE * a_Pattern, int a_PatternSize); -} ; - - - - - class cCompoGenNether : public cTerrainCompositionGen { @@ -136,7 +102,7 @@ protected: int m_Threshold; // cTerrainCompositionGen overrides: - virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc) override; + virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) override; virtual void InitializeCompoGen(cIniFile & a_IniFile) override; } ; @@ -153,7 +119,7 @@ public: ~cCompoGenCache(); // cTerrainCompositionGen override: - virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc) override; + virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) override; virtual void InitializeCompoGen(cIniFile & a_IniFile) override; protected: @@ -166,6 +132,7 @@ protected: int m_ChunkZ; cChunkDef::BlockTypes m_BlockTypes; cChunkDesc::BlockNibbleBytes m_BlockMetas; // The metas are uncompressed, 1 meta per byte + cChunkDef::HeightMap m_HeightMap; } ; // To avoid moving large amounts of data for the MRU behavior, we MRU-ize indices to an array of the actual data diff --git a/src/Generating/CompoGenBiomal.cpp b/src/Generating/CompoGenBiomal.cpp new file mode 100644 index 000000000..995851c95 --- /dev/null +++ b/src/Generating/CompoGenBiomal.cpp @@ -0,0 +1,586 @@ + +// CompoGenBiomal.cpp + +// Implements the cCompoGenBiomal class representing the biome-aware composition generator + +#include "Globals.h" +#include "ComposableGenerator.h" +#include "../IniFile.h" +#include "../Noise/Noise.h" +#include "../LinearUpscale.h" + + + + + +//////////////////////////////////////////////////////////////////////////////// +// cPattern: + +/** This class is used to store a column pattern initialized at runtime, +so that the program doesn't need to explicitly set 256 values for each pattern +Each pattern has 256 blocks so that there's no need to check pattern bounds when assigning the +pattern - there will always be enough pattern left, even for the whole-chunk-height columns. */ +class cPattern +{ +public: + struct BlockInfo + { + BLOCKTYPE m_BlockType; + NIBBLETYPE m_BlockMeta; + }; + + cPattern(BlockInfo * a_TopBlocks, size_t a_Count) + { + // Copy the pattern into the top: + for (size_t i = 0; i < a_Count; i++) + { + m_Pattern[i] = a_TopBlocks[i]; + } + + // Fill the rest with stone: + static BlockInfo Stone = {E_BLOCK_STONE, 0}; + for (size_t i = a_Count; i < cChunkDef::Height; i++) + { + m_Pattern[i] = Stone; + } + } + + const BlockInfo * Get(void) const { return m_Pattern; } + +protected: + BlockInfo m_Pattern[cChunkDef::Height]; +} ; + + + + + +//////////////////////////////////////////////////////////////////////////////// +// The arrays to use for the top block pattern definitions: + +static cPattern::BlockInfo tbGrass[] = +{ + {E_BLOCK_GRASS, 0}, + {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, + {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, + {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, +} ; + +static cPattern::BlockInfo tbSand[] = +{ + { E_BLOCK_SAND, 0}, + { E_BLOCK_SAND, 0}, + { E_BLOCK_SAND, 0}, + { E_BLOCK_SANDSTONE, 0}, +} ; + +static cPattern::BlockInfo tbDirt[] = +{ + {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, + {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, + {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, + {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, +} ; + +static cPattern::BlockInfo tbPodzol[] = +{ + {E_BLOCK_DIRT, E_META_DIRT_PODZOL}, + {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, + {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, + {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, +} ; + +static cPattern::BlockInfo tbGrassLess[] = +{ + {E_BLOCK_DIRT, E_META_DIRT_GRASSLESS}, + {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, + {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, + {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, +} ; + +static cPattern::BlockInfo tbMycelium[] = +{ + {E_BLOCK_MYCELIUM, 0}, + {E_BLOCK_DIRT, 0}, + {E_BLOCK_DIRT, 0}, + {E_BLOCK_DIRT, 0}, +} ; + +static cPattern::BlockInfo tbGravel[] = +{ + {E_BLOCK_GRAVEL, 0}, + {E_BLOCK_GRAVEL, 0}, + {E_BLOCK_GRAVEL, 0}, + {E_BLOCK_STONE, 0}, +} ; + +static cPattern::BlockInfo tbStone[] = +{ + {E_BLOCK_STONE, 0}, + {E_BLOCK_STONE, 0}, + {E_BLOCK_STONE, 0}, + {E_BLOCK_STONE, 0}, +} ; + + + +//////////////////////////////////////////////////////////////////////////////// +// Ocean floor pattern top-block definitions: + +static cPattern::BlockInfo tbOFSand[] = +{ + {E_BLOCK_SAND, 0}, + {E_BLOCK_SAND, 0}, + {E_BLOCK_SAND, 0}, + {E_BLOCK_SANDSTONE, 0} +} ; + +static cPattern::BlockInfo tbOFClay[] = +{ + { E_BLOCK_CLAY, 0}, + { E_BLOCK_CLAY, 0}, + { E_BLOCK_SAND, 0}, + { E_BLOCK_SAND, 0}, +} ; + +static cPattern::BlockInfo tbOFOrangeClay[] = +{ + { E_BLOCK_STAINED_CLAY, E_META_STAINED_GLASS_ORANGE}, + { E_BLOCK_STAINED_CLAY, E_META_STAINED_GLASS_ORANGE}, + { E_BLOCK_STAINED_CLAY, E_META_STAINED_GLASS_ORANGE}, +} ; + + + + + + +//////////////////////////////////////////////////////////////////////////////// +// Individual patterns to use: + +static cPattern patGrass (tbGrass, ARRAYCOUNT(tbGrass)); +static cPattern patSand (tbSand, ARRAYCOUNT(tbSand)); +static cPattern patDirt (tbDirt, ARRAYCOUNT(tbDirt)); +static cPattern patPodzol (tbPodzol, ARRAYCOUNT(tbPodzol)); +static cPattern patGrassLess(tbGrassLess, ARRAYCOUNT(tbGrassLess)); +static cPattern patMycelium (tbMycelium, ARRAYCOUNT(tbMycelium)); +static cPattern patGravel (tbGravel, ARRAYCOUNT(tbGravel)); +static cPattern patStone (tbStone, ARRAYCOUNT(tbStone)); + +static cPattern patOFSand (tbOFSand, ARRAYCOUNT(tbOFSand)); +static cPattern patOFClay (tbOFClay, ARRAYCOUNT(tbOFClay)); +static cPattern patOFOrangeClay(tbOFOrangeClay, ARRAYCOUNT(tbOFOrangeClay)); + + + + + +//////////////////////////////////////////////////////////////////////////////// +// cCompoGenBiomal: + +class cCompoGenBiomal : + public cTerrainCompositionGen +{ +public: + cCompoGenBiomal(int a_Seed) : + m_SeaLevel(62), + m_OceanFloorSelect(a_Seed + 1), + m_MesaFloor(a_Seed + 2) + { + initMesaPattern(a_Seed); + } + +protected: + /** The block height at which water is generated instead of air. */ + int m_SeaLevel; + + /** The pattern used for mesa biomes. Initialized by seed on generator creation. */ + cPattern::BlockInfo m_MesaPattern[2 * cChunkDef::Height]; + + /** Noise used for selecting between dirt and sand on the ocean floor. */ + cNoise m_OceanFloorSelect; + + /** Noise used for the floor of the clay blocks in mesa biomes. */ + cNoise m_MesaFloor; + + + // cTerrainCompositionGen overrides: + virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) override + { + a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0); + for (int z = 0; z < cChunkDef::Width; z++) + { + for (int x = 0; x < cChunkDef::Width; x++) + { + ComposeColumn(a_ChunkDesc, x, z, &(a_Shape[x * 256 + z * 16 * 256])); + } // for x + } // for z + } + + + + virtual void InitializeCompoGen(cIniFile & a_IniFile) override + { + m_SeaLevel = a_IniFile.GetValueSetI("Generator", "SeaLevel", m_SeaLevel); + } + + + + /** Initializes the m_MesaPattern with a pattern based on the generator's seed. */ + void initMesaPattern(int a_Seed) + { + // In a loop, choose whether to use one, two or three layers of stained clay, then choose a color and width for each layer + // Separate each group with another layer of hardened clay + cNoise patternNoise((unsigned)a_Seed); + static NIBBLETYPE allowedColors[] = + { + E_META_STAINED_CLAY_YELLOW, + E_META_STAINED_CLAY_YELLOW, + E_META_STAINED_CLAY_RED, + E_META_STAINED_CLAY_RED, + E_META_STAINED_CLAY_WHITE, + E_META_STAINED_CLAY_BROWN, + E_META_STAINED_CLAY_BROWN, + E_META_STAINED_CLAY_BROWN, + E_META_STAINED_CLAY_ORANGE, + E_META_STAINED_CLAY_ORANGE, + E_META_STAINED_CLAY_ORANGE, + E_META_STAINED_CLAY_ORANGE, + E_META_STAINED_CLAY_ORANGE, + E_META_STAINED_CLAY_ORANGE, + E_META_STAINED_CLAY_LIGHTGRAY, + } ; + static int layerSizes[] = // Adjust the chance so that thinner layers occur more commonly + { + 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, + 3, 3, + } ; + int idx = ARRAYCOUNT(m_MesaPattern) - 1; + while (idx >= 0) + { + // A layer group of 1 - 2 color stained clay: + int rnd = patternNoise.IntNoise1DInt(idx) / 7; + int numLayers = (rnd % 2) + 1; + rnd /= 2; + for (int lay = 0; lay < numLayers; lay++) + { + int numBlocks = layerSizes[(rnd % ARRAYCOUNT(layerSizes))]; + NIBBLETYPE Color = allowedColors[(rnd / 4) % ARRAYCOUNT(allowedColors)]; + if ( + ((numBlocks == 3) && (numLayers == 2)) || // In two-layer mode disallow the 3-high layers: + (Color == E_META_STAINED_CLAY_WHITE)) // White stained clay can ever be only 1 block high + { + numBlocks = 1; + } + numBlocks = std::min(idx + 1, numBlocks); // Limit by idx so that we don't have to check inside the loop + rnd /= 32; + for (int block = 0; block < numBlocks; block++, idx--) + { + m_MesaPattern[idx].m_BlockMeta = Color; + m_MesaPattern[idx].m_BlockType = E_BLOCK_STAINED_CLAY; + } // for block + } // for lay + + // A layer of hardened clay in between the layer group: + int numBlocks = (rnd % 4) + 1; // All heights the same probability + if ((numLayers == 2) && (numBlocks < 4)) + { + // For two layers of stained clay, add an extra block of hardened clay: + numBlocks++; + } + numBlocks = std::min(idx + 1, numBlocks); // Limit by idx so that we don't have to check inside the loop + for (int block = 0; block < numBlocks; block++, idx--) + { + m_MesaPattern[idx].m_BlockMeta = 0; + m_MesaPattern[idx].m_BlockType = E_BLOCK_HARDENED_CLAY; + } // for block + } // while (idx >= 0) + } + + + + /** Composes a single column in a_ChunkDesc. Chooses what to do based on the biome in that column. */ + void ComposeColumn(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelZ, const Byte * a_ShapeColumn) + { + // Frequencies for the podzol floor selecting noise: + const NOISE_DATATYPE FrequencyX = 8; + const NOISE_DATATYPE FrequencyZ = 8; + + EMCSBiome Biome = a_ChunkDesc.GetBiome(a_RelX, a_RelZ); + switch (Biome) + { + case biOcean: + case biPlains: + case biForest: + case biTaiga: + case biSwampland: + case biRiver: + case biFrozenOcean: + case biFrozenRiver: + case biIcePlains: + case biIceMountains: + case biForestHills: + case biTaigaHills: + case biExtremeHillsEdge: + case biExtremeHillsPlus: + case biExtremeHills: + case biJungle: + case biJungleHills: + case biJungleEdge: + case biDeepOcean: + case biStoneBeach: + case biColdBeach: + case biBirchForest: + case biBirchForestHills: + case biRoofedForest: + case biColdTaiga: + case biColdTaigaHills: + case biSavanna: + case biSavannaPlateau: + case biSunflowerPlains: + case biFlowerForest: + case biTaigaM: + case biSwamplandM: + case biIcePlainsSpikes: + case biJungleM: + case biJungleEdgeM: + case biBirchForestM: + case biBirchForestHillsM: + case biRoofedForestM: + case biColdTaigaM: + case biSavannaM: + case biSavannaPlateauM: + { + FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, patGrass.Get(), a_ShapeColumn); + return; + } + + case biMegaTaiga: + case biMegaTaigaHills: + case biMegaSpruceTaiga: + case biMegaSpruceTaigaHills: + { + // Select the pattern to use - podzol, grass or grassless dirt: + NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(a_ChunkDesc.GetChunkX() * cChunkDef::Width + a_RelX)) / FrequencyX; + NOISE_DATATYPE NoiseY = ((NOISE_DATATYPE)(a_ChunkDesc.GetChunkZ() * cChunkDef::Width + a_RelZ)) / FrequencyZ; + NOISE_DATATYPE Val = m_OceanFloorSelect.CubicNoise2D(NoiseX, NoiseY); + const cPattern::BlockInfo * Pattern = (Val < -0.9) ? patGrassLess.Get() : ((Val > 0) ? patPodzol.Get() : patGrass.Get()); + FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, Pattern, a_ShapeColumn); + return; + } + + case biDesertHills: + case biDesert: + case biDesertM: + case biBeach: + { + FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, patSand.Get(), a_ShapeColumn); + return; + } + + case biMushroomIsland: + case biMushroomShore: + { + FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, patMycelium.Get(), a_ShapeColumn); + return; + } + + case biMesa: + case biMesaPlateauF: + case biMesaPlateau: + case biMesaBryce: + case biMesaPlateauFM: + case biMesaPlateauM: + { + // Mesa biomes need special handling, because they don't follow the usual "4 blocks from top pattern", + // instead, they provide a "from bottom" pattern with varying base height, + // usually 4 blocks below the ocean level + FillColumnMesa(a_ChunkDesc, a_RelX, a_RelZ, a_ShapeColumn); + return; + } + + case biExtremeHillsPlusM: + case biExtremeHillsM: + { + // Select the pattern to use - gravel, stone or grass: + NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(a_ChunkDesc.GetChunkX() * cChunkDef::Width + a_RelX)) / FrequencyX; + NOISE_DATATYPE NoiseY = ((NOISE_DATATYPE)(a_ChunkDesc.GetChunkZ() * cChunkDef::Width + a_RelZ)) / FrequencyZ; + NOISE_DATATYPE Val = m_OceanFloorSelect.CubicNoise2D(NoiseX, NoiseY); + const cPattern::BlockInfo * Pattern = (Val < 0.0) ? patStone.Get() : patGrass.Get(); + FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, Pattern, a_ShapeColumn); + return; + } + default: + { + ASSERT(!"Unhandled biome"); + return; + } + } // switch (Biome) + } + + + + /** Fills the specified column with the specified pattern; restarts the pattern when air is reached, + switches to ocean floor pattern if ocean is reached. Always adds bedrock at the very bottom. */ + void FillColumnPattern(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelZ, const cPattern::BlockInfo * a_Pattern, const Byte * a_ShapeColumn) + { + bool HasHadWater = false; + int PatternIdx = 0; + int top = std::max(m_SeaLevel, a_ChunkDesc.GetHeight(a_RelX, a_RelZ)); + for (int y = top; y > 0; y--) + { + if (a_ShapeColumn[y] > 0) + { + // "ground" part, use the pattern: + a_ChunkDesc.SetBlockTypeMeta(a_RelX, y, a_RelZ, a_Pattern[PatternIdx].m_BlockType, a_Pattern[PatternIdx].m_BlockMeta); + PatternIdx++; + continue; + } + + // "air" or "water" part: + // Reset the pattern index to zero, so that the pattern is repeated from the top again: + PatternIdx = 0; + + if (y >= m_SeaLevel) + { + // "air" part, do nothing + continue; + } + + a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_STATIONARY_WATER); + if (HasHadWater) + { + continue; + } + + // Select the ocean-floor pattern to use: + if (a_ChunkDesc.GetBiome(a_RelX, a_RelZ) == biDeepOcean) + { + a_Pattern = patGravel.Get(); + } + else + { + a_Pattern = ChooseOceanFloorPattern(a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ(), a_RelX, a_RelZ); + } + HasHadWater = true; + } // for y + a_ChunkDesc.SetBlockType(a_RelX, 0, a_RelZ, E_BLOCK_BEDROCK); + } + + + + /** Fills the specified column with mesa pattern, based on the column height */ + void FillColumnMesa(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelZ, const Byte * a_ShapeColumn) + { + // Frequencies for the clay floor noise: + const NOISE_DATATYPE FrequencyX = 50; + const NOISE_DATATYPE FrequencyZ = 50; + + int Top = a_ChunkDesc.GetHeight(a_RelX, a_RelZ); + if (Top < m_SeaLevel) + { + // The terrain is below sealevel, handle as regular ocean with red sand floor: + FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, patOFOrangeClay.Get(), a_ShapeColumn); + return; + } + + NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(a_ChunkDesc.GetChunkX() * cChunkDef::Width + a_RelX)) / FrequencyX; + NOISE_DATATYPE NoiseY = ((NOISE_DATATYPE)(a_ChunkDesc.GetChunkZ() * cChunkDef::Width + a_RelZ)) / FrequencyZ; + int ClayFloor = m_SeaLevel - 6 + (int)(4.f * m_MesaFloor.CubicNoise2D(NoiseX, NoiseY)); + if (ClayFloor >= Top) + { + ClayFloor = Top - 1; + } + + if (Top - m_SeaLevel < 5) + { + // Simple case: top is red sand, then hardened clay down to ClayFloor, then stone: + a_ChunkDesc.SetBlockTypeMeta(a_RelX, Top, a_RelZ, E_BLOCK_SAND, E_META_SAND_RED); + for (int y = Top - 1; y >= ClayFloor; y--) + { + a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_HARDENED_CLAY); + } + for (int y = ClayFloor - 1; y > 0; y--) + { + a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_STONE); + } + a_ChunkDesc.SetBlockType(a_RelX, 0, a_RelZ, E_BLOCK_BEDROCK); + return; + } + + // Difficult case: use the mesa pattern and watch for overhangs: + int PatternIdx = cChunkDef::Height - (Top - ClayFloor); // We want the block at index ClayFloor to be pattern's 256th block (first stone) + const cPattern::BlockInfo * Pattern = m_MesaPattern; + bool HasHadWater = false; + for (int y = Top; y > 0; y--) + { + if (a_ShapeColumn[y] > 0) + { + // "ground" part, use the pattern: + a_ChunkDesc.SetBlockTypeMeta(a_RelX, y, a_RelZ, Pattern[PatternIdx].m_BlockType, Pattern[PatternIdx].m_BlockMeta); + PatternIdx++; + continue; + } + + if (y >= m_SeaLevel) + { + // "air" part, do nothing + continue; + } + + // "water" part, fill with water and choose new pattern for ocean floor, if not chosen already: + PatternIdx = 0; + a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_STATIONARY_WATER); + if (HasHadWater) + { + continue; + } + + // Select the ocean-floor pattern to use: + Pattern = ChooseOceanFloorPattern(a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ(), a_RelX, a_RelZ); + HasHadWater = true; + } // for y + a_ChunkDesc.SetBlockType(a_RelX, 0, a_RelZ, E_BLOCK_BEDROCK); + } + + + + /** Returns the pattern to use for an ocean floor in the specified column. + The returned pattern is guaranteed to be 256 blocks long. */ + const cPattern::BlockInfo * ChooseOceanFloorPattern(int a_ChunkX, int a_ChunkZ, int a_RelX, int a_RelZ) + { + // Frequencies for the ocean floor selecting noise: + const NOISE_DATATYPE FrequencyX = 3; + const NOISE_DATATYPE FrequencyZ = 3; + + // Select the ocean-floor pattern to use: + NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(a_ChunkX * cChunkDef::Width + a_RelX)) / FrequencyX; + NOISE_DATATYPE NoiseY = ((NOISE_DATATYPE)(a_ChunkZ * cChunkDef::Width + a_RelZ)) / FrequencyZ; + NOISE_DATATYPE Val = m_OceanFloorSelect.CubicNoise2D(NoiseX, NoiseY); + if (Val < -0.95) + { + return patOFClay.Get(); + } + else if (Val < 0) + { + return patOFSand.Get(); + } + else + { + return patDirt.Get(); + } + } +} ; + + + + + +cTerrainCompositionGenPtr CreateCompoGenBiomal(int a_Seed) +{ + return std::make_shared(a_Seed); +} + + + diff --git a/src/Generating/CompoGenBiomal.h b/src/Generating/CompoGenBiomal.h new file mode 100644 index 000000000..a3a65d3dc --- /dev/null +++ b/src/Generating/CompoGenBiomal.h @@ -0,0 +1,21 @@ + +// CompoGenBiomal.h + + + + + +#pragma once + +#include "ComposableGenerator.h" + + + + + +/** Returns a new instance of the Biomal composition generator. */ +cTerrainCompositionGenPtr CreateCompoGenBiomal(int a_Seed); + + + + diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index 5f46574c7..4192dfa72 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -17,6 +17,10 @@ #include "StructGen.h" #include "FinishGen.h" +#include "CompoGenBiomal.h" + +#include "CompositedHeiGen.h" + #include "Caves.h" #include "DistortedHeightmap.h" #include "DungeonRoomsFinisher.h" @@ -39,7 +43,7 @@ //////////////////////////////////////////////////////////////////////////////// // cTerrainCompositionGen: -cTerrainCompositionGenPtr cTerrainCompositionGen::CreateCompositionGen(cIniFile & a_IniFile, cBiomeGenPtr a_BiomeGen, cTerrainHeightGen & a_HeightGen, int a_Seed) +cTerrainCompositionGenPtr cTerrainCompositionGen::CreateCompositionGen(cIniFile & a_IniFile, cBiomeGenPtr a_BiomeGen, cTerrainShapeGenPtr a_ShapeGen, int a_Seed) { AString CompoGenName = a_IniFile.GetValueSet("Generator", "CompositionGen", ""); if (CompoGenName.empty()) @@ -48,63 +52,52 @@ cTerrainCompositionGenPtr cTerrainCompositionGen::CreateCompositionGen(cIniFile CompoGenName = "Biomal"; } - cTerrainCompositionGen * res = nullptr; - if (NoCaseCompare(CompoGenName, "sameblock") == 0) + // Compositor list is alpha-sorted + cTerrainCompositionGenPtr res; + if (NoCaseCompare(CompoGenName, "Biomal") == 0) { - res = new cCompoGenSameBlock; + res = CreateCompoGenBiomal(a_Seed); } - else if (NoCaseCompare(CompoGenName, "debugbiomes") == 0) + else if (NoCaseCompare(CompoGenName, "BiomalNoise3D") == 0) { - res = new cCompoGenDebugBiomes; + // The composition that used to be provided with BiomalNoise3D is now provided by the Biomal compositor: + res = CreateCompoGenBiomal(a_Seed); } - else if (NoCaseCompare(CompoGenName, "classic") == 0) + else if (NoCaseCompare(CompoGenName, "Classic") == 0) { - res = new cCompoGenClassic; + res = std::make_shared(); } - else if (NoCaseCompare(CompoGenName, "DistortedHeightmap") == 0) + else if (NoCaseCompare(CompoGenName, "DebugBiomes") == 0) { - res = new cDistortedHeightmap(a_Seed, a_BiomeGen); + res = std::make_shared(); } - else if (NoCaseCompare(CompoGenName, "end") == 0) + else if (NoCaseCompare(CompoGenName, "DistortedHeightmap") == 0) { - res = new cEndGen(a_Seed); + // The composition that used to be provided with DistortedHeightmap is now provided by the Biomal compositor: + res = CreateCompoGenBiomal(a_Seed); } - else if (NoCaseCompare(CompoGenName, "nether") == 0) + else if (NoCaseCompare(CompoGenName, "End") == 0) { - res = new cCompoGenNether(a_Seed); + res = std::make_shared(a_Seed); } - else if (NoCaseCompare(CompoGenName, "BiomalNoise3D") == 0) + else if (NoCaseCompare(CompoGenName, "Nether") == 0) { - res = new cBiomalNoise3DComposable(a_Seed, a_BiomeGen); + res = std::make_shared(a_Seed); } else if (NoCaseCompare(CompoGenName, "Noise3D") == 0) { - res = new cNoise3DComposable(a_Seed); + // The composition that used to be provided with Noise3D is now provided by the Biomal compositor: + res = CreateCompoGenBiomal(a_Seed); } - else if (NoCaseCompare(CompoGenName, "biomal") == 0) + else if (NoCaseCompare(CompoGenName, "SameBlock") == 0) { - res = new cCompoGenBiomal(a_Seed); - - /* - // Performance-testing: - LOGINFO("Measuring performance of cCompoGenBiomal..."); - clock_t BeginTick = clock(); - for (int x = 0; x < 500; x++) - { - cChunkDesc Desc(200 + x * 8, 200 + x * 8); - a_BiomeGen->GenBiomes(Desc.GetChunkX(), Desc.GetChunkZ(), Desc.GetBiomeMap()); - a_HeightGen->GenHeightMap(Desc.GetChunkX(), Desc.GetChunkZ(), Desc.GetHeightMap()); - res->ComposeTerrain(Desc); - } - clock_t Duration = clock() - BeginTick; - LOGINFO("CompositionGen for 500 chunks took %d ticks (%.02f sec)", Duration, (double)Duration / CLOCKS_PER_SEC); - //*/ + res = std::make_shared(); } else { LOGWARN("Unknown CompositionGen \"%s\", using \"Biomal\" instead.", CompoGenName.c_str()); a_IniFile.SetValue("Generator", "CompositionGen", "Biomal"); - return CreateCompositionGen(a_IniFile, a_BiomeGen, a_HeightGen, a_Seed); + return CreateCompositionGen(a_IniFile, a_BiomeGen, a_ShapeGen, a_Seed); } ASSERT(res != nullptr); @@ -124,7 +117,7 @@ cTerrainCompositionGenPtr cTerrainCompositionGen::CreateCompositionGen(cIniFile cComposableGenerator::cComposableGenerator(cChunkGenerator & a_ChunkGenerator) : super(a_ChunkGenerator), m_BiomeGen(), - m_HeightGen(), + m_ShapeGen(), m_CompositionGen() { } @@ -138,7 +131,7 @@ void cComposableGenerator::Initialize(cIniFile & a_IniFile) super::Initialize(a_IniFile); InitBiomeGen(a_IniFile); - InitHeightGen(a_IniFile); + InitShapeGen(a_IniFile); InitCompositionGen(a_IniFile); InitFinishGens(a_IniFile); } @@ -166,16 +159,22 @@ void cComposableGenerator::DoGenerate(int a_ChunkX, int a_ChunkZ, cChunkDesc & a m_BiomeGen->GenBiomes(a_ChunkX, a_ChunkZ, a_ChunkDesc.GetBiomeMap()); } + cChunkDesc::Shape shape; if (a_ChunkDesc.IsUsingDefaultHeight()) { - m_HeightGen->GenHeightMap(a_ChunkX, a_ChunkZ, a_ChunkDesc.GetHeightMap()); + m_ShapeGen->GenShape(a_ChunkX, a_ChunkZ, shape); + a_ChunkDesc.SetHeightFromShape(shape); + } + else + { + // Convert the heightmap in a_ChunkDesc into shape: + a_ChunkDesc.GetShapeFromHeight(shape); } bool ShouldUpdateHeightmap = false; if (a_ChunkDesc.IsUsingDefaultComposition()) { - m_CompositionGen->ComposeTerrain(a_ChunkDesc); - ShouldUpdateHeightmap = true; + m_CompositionGen->ComposeTerrain(a_ChunkDesc, shape); } if (a_ChunkDesc.IsUsingDefaultFinish()) @@ -234,13 +233,15 @@ void cComposableGenerator::InitBiomeGen(cIniFile & a_IniFile) -void cComposableGenerator::InitHeightGen(cIniFile & a_IniFile) +void cComposableGenerator::InitShapeGen(cIniFile & a_IniFile) { bool CacheOffByDefault = false; - m_HeightGen = cTerrainHeightGen::CreateHeightGen(a_IniFile, m_BiomeGen, m_ChunkGenerator.GetSeed(), CacheOffByDefault); + m_ShapeGen = cTerrainShapeGen::CreateShapeGen(a_IniFile, m_BiomeGen, m_ChunkGenerator.GetSeed(), CacheOffByDefault); + /* + // TODO // Add a cache, if requested: - int CacheSize = a_IniFile.GetValueSetI("Generator", "HeightGenCacheSize", CacheOffByDefault ? 0 : 64); + int CacheSize = a_IniFile.GetValueSetI("Generator", "ShapeGenCacheSize", CacheOffByDefault ? 0 : 64); if (CacheSize > 0) { if (CacheSize < 4) @@ -253,6 +254,7 @@ void cComposableGenerator::InitHeightGen(cIniFile & a_IniFile) LOGD("Using a cache for Heightgen of size %d.", CacheSize); m_HeightGen = cTerrainHeightGenPtr(new cHeiGenCache(m_HeightGen, CacheSize)); } + */ } @@ -261,13 +263,19 @@ void cComposableGenerator::InitHeightGen(cIniFile & a_IniFile) void cComposableGenerator::InitCompositionGen(cIniFile & a_IniFile) { - m_CompositionGen = cTerrainCompositionGen::CreateCompositionGen(a_IniFile, m_BiomeGen, *m_HeightGen, m_ChunkGenerator.GetSeed()); + m_CompositionGen = cTerrainCompositionGen::CreateCompositionGen(a_IniFile, m_BiomeGen, m_ShapeGen, m_ChunkGenerator.GetSeed()); + // Add a cache over the composition generator: + // Even a cache of size 1 is useful due to the CompositedHeiGen cache after us doing re-composition on its misses int CompoGenCacheSize = a_IniFile.GetValueSetI("Generator", "CompositionGenCacheSize", 64); - if (CompoGenCacheSize > 1) + if (CompoGenCacheSize > 0) { - m_CompositionGen = cTerrainCompositionGenPtr(new cCompoGenCache(m_CompositionGen, 32)); + m_CompositionGen = std::make_shared(m_CompositionGen, CompoGenCacheSize); } + + // Create a cache of the composited heightmaps, so that finishers may use it: + m_CompositedHeightCache = std::make_shared(std::make_shared(m_ShapeGen, m_CompositionGen), 16, 24); + // 24 subcaches of depth 16 each = 96 KiB of RAM. Acceptable, for the amount of work this saves. } @@ -333,7 +341,7 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) int MaxSize = a_IniFile.GetValueSetI("Generator", "DungeonRoomsMaxSize", 7); int MinSize = a_IniFile.GetValueSetI("Generator", "DungeonRoomsMinSize", 5); AString HeightDistrib = a_IniFile.GetValueSet ("Generator", "DungeonRoomsHeightDistrib", "0, 0; 10, 10; 11, 500; 40, 500; 60, 40; 90, 1"); - m_FinishGens.push_back(cFinishGenPtr(new cDungeonRoomsFinisher(m_HeightGen, Seed, GridSize, MaxSize, MinSize, HeightDistrib))); + m_FinishGens.push_back(cFinishGenPtr(new cDungeonRoomsFinisher(m_ShapeGen, Seed, GridSize, MaxSize, MinSize, HeightDistrib))); } else if (NoCaseCompare(*itr, "Ice") == 0) { @@ -342,7 +350,7 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) else if (NoCaseCompare(*itr, "LavaLakes") == 0) { int Probability = a_IniFile.GetValueSetI("Generator", "LavaLakesProbability", 10); - m_FinishGens.push_back(cFinishGenPtr(new cStructGenLakes(Seed * 5 + 16873, E_BLOCK_STATIONARY_LAVA, m_HeightGen, Probability))); + m_FinishGens.push_back(cFinishGenPtr(new cStructGenLakes(Seed * 5 + 16873, E_BLOCK_STATIONARY_LAVA, m_ShapeGen, Probability))); } else if (NoCaseCompare(*itr, "LavaSprings") == 0) { @@ -580,7 +588,7 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) } else if (NoCaseCompare(*itr, "Trees") == 0) { - m_FinishGens.push_back(cFinishGenPtr(new cStructGenTrees(Seed, m_BiomeGen, m_HeightGen, m_CompositionGen))); + m_FinishGens.push_back(cFinishGenPtr(new cStructGenTrees(Seed, m_BiomeGen, m_ShapeGen, m_CompositionGen))); } else if (NoCaseCompare(*itr, "UnderwaterBases") == 0) { @@ -588,7 +596,7 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) int MaxOffset = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxOffset", 128); int MaxDepth = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxDepth", 7); int MaxSize = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxSize", 128); - m_FinishGens.push_back(cFinishGenPtr(new cUnderwaterBaseGen(Seed, GridSize, MaxOffset, MaxDepth, MaxSize, m_BiomeGen))); + m_FinishGens.push_back(std::make_shared(Seed, GridSize, MaxOffset, MaxDepth, MaxSize, m_BiomeGen)); } else if (NoCaseCompare(*itr, "Villages") == 0) { @@ -598,12 +606,12 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) int MaxSize = a_IniFile.GetValueSetI("Generator", "VillageMaxSize", 128); int MinDensity = a_IniFile.GetValueSetI("Generator", "VillageMinDensity", 50); int MaxDensity = a_IniFile.GetValueSetI("Generator", "VillageMaxDensity", 80); - m_FinishGens.push_back(cFinishGenPtr(new cVillageGen(Seed, GridSize, MaxOffset, MaxDepth, MaxSize, MinDensity, MaxDensity, m_BiomeGen, m_HeightGen))); + m_FinishGens.push_back(std::make_shared(Seed, GridSize, MaxOffset, MaxDepth, MaxSize, MinDensity, MaxDensity, m_BiomeGen, m_CompositedHeightCache)); } else if (NoCaseCompare(*itr, "WaterLakes") == 0) { int Probability = a_IniFile.GetValueSetI("Generator", "WaterLakesProbability", 25); - m_FinishGens.push_back(cFinishGenPtr(new cStructGenLakes(Seed * 3 + 652, E_BLOCK_STATIONARY_WATER, m_HeightGen, Probability))); + m_FinishGens.push_back(cFinishGenPtr(new cStructGenLakes(Seed * 3 + 652, E_BLOCK_STATIONARY_WATER, m_ShapeGen, Probability))); } else if (NoCaseCompare(*itr, "WaterSprings") == 0) { diff --git a/src/Generating/ComposableGenerator.h b/src/Generating/ComposableGenerator.h index a091f8d53..86c30e090 100644 --- a/src/Generating/ComposableGenerator.h +++ b/src/Generating/ComposableGenerator.h @@ -26,20 +26,16 @@ See http://forum.mc-server.org/showthread.php?tid=409 for details. // Forward-declare the shared pointers to subgenerator classes: class cBiomeGen; +class cTerrainShapeGen; class cTerrainHeightGen; class cTerrainCompositionGen; class cFinishGen; typedef SharedPtr cBiomeGenPtr; +typedef SharedPtr cTerrainShapeGenPtr; typedef SharedPtr cTerrainHeightGenPtr; typedef SharedPtr cTerrainCompositionGenPtr; typedef SharedPtr cFinishGenPtr; -// fwd: Noise3DGenerator.h -class cNoise3DComposable; - -// fwd: DistortedHeightmap.h -class cDistortedHeightmap; - @@ -70,28 +66,54 @@ public: -/** The interface that a terrain height generator must implement -A terrain height generator takes chunk coords on input and outputs an array of terrain heights for that chunk. -The output array is sequenced in the same way as the BiomeGen's biome data. +/** The interface that a terrain shape generator must implement +A terrain shape generator takes chunk coords on input and outputs a 3D array of "shape" for that chunk. The shape here +represents the distinction between air and solid; there's no representation of Water since that is added by the +composition geenrator. +The output array is indexed [y + 256 * z + 16 * 256 * x], so that it's fast to later compose a single column of the terrain, +which is the dominant operation following the shape generation. The generator may request biome information from the underlying BiomeGen, it may even request information for -other chunks than the one it's currently generating (possibly neighbors - for averaging) +other chunks than the one it's currently generating (neighbors - for averaging) */ -class cTerrainHeightGen +class cTerrainShapeGen { public: - virtual ~cTerrainHeightGen() {} // Force a virtual destructor in descendants + virtual ~cTerrainShapeGen() {} // Force a virtual destructor in descendants - /** Generates heightmap for the given chunk */ - virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) = 0; + /** Generates the shape for the given chunk */ + virtual void GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape) = 0; /** Reads parameters from the ini file, prepares generator for use. */ - virtual void InitializeHeightGen(cIniFile & a_IniFile) {} + virtual void InitializeShapeGen(cIniFile & a_IniFile) {} - /** Creates the correct TerrainHeightGen descendant based on the ini file settings and the seed provided. - a_BiomeGen is the underlying biome generator, some height generators may depend on it to generate more biomes + /** Creates the correct TerrainShapeGen descendant based on the ini file settings and the seed provided. + a_BiomeGen is the underlying biome generator, some shape generators may depend on it providing additional biomes data around the chunk a_CacheOffByDefault gets set to whether the cache should be disabled by default - Implemented in HeiGen.cpp! + Implemented in ShapeGen.cpp! */ + static cTerrainShapeGenPtr CreateShapeGen(cIniFile & a_IniFile, cBiomeGenPtr a_BiomeGen, int a_Seed, bool & a_CacheOffByDefault); +} ; + + + + + +/** The interface that is used to query terrain height from the shape generator. +Usually the structure generators require only the final heightmap, and generating the whole shape only to +consume the heightmap is wasteful, so this interface is used instead; it has a cache implemented over it so +that data is retained. */ +class cTerrainHeightGen +{ +public: + virtual ~cTerrainHeightGen() {} // Force a virtual destructor in descendants + + /** Retrieves the heightmap for the specified chunk. */ + virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) = 0; + + /** Initializes the generator, reading its parameters from the INI file. */ + virtual void InitializeHeightGen(cIniFile & a_IniFile) {} + + /** Creates a cTerrainHeightGen descendant based on the INI file settings. */ static cTerrainHeightGenPtr CreateHeightGen(cIniFile & a_IniFile, cBiomeGenPtr a_BiomeGen, int a_Seed, bool & a_CacheOffByDefault); } ; @@ -109,16 +131,18 @@ class cTerrainCompositionGen public: virtual ~cTerrainCompositionGen() {} // Force a virtual destructor in descendants - virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc) = 0; + /** Generates the chunk's composition into a_ChunkDesc, using the terrain shape provided in a_Shape. + Is expected to fill a_ChunkDesc's heightmap with the data from a_Shape. */ + virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) = 0; /** Reads parameters from the ini file, prepares generator for use. */ virtual void InitializeCompoGen(cIniFile & a_IniFile) {} /** Creates the correct TerrainCompositionGen descendant based on the ini file settings and the seed provided. - a_BiomeGen is the underlying biome generator, some composition generators may depend on it to generate more biomes - a_HeightGen is the underlying height generator, some composition generators may depend on it providing additional values + a_BiomeGen is the underlying biome generator, some composition generators may depend on it providing additional biomes around the chunk + a_ShapeGen is the underlying shape generator, some composition generators may depend on it providing additional shape around the chunk */ - static cTerrainCompositionGenPtr CreateCompositionGen(cIniFile & a_IniFile, cBiomeGenPtr a_BiomeGen, cTerrainHeightGen & a_HeightGen, int a_Seed); + static cTerrainCompositionGenPtr CreateCompositionGen(cIniFile & a_IniFile, cBiomeGenPtr a_BiomeGen, cTerrainShapeGenPtr a_ShapeGen, int a_Seed); } ; @@ -128,7 +152,7 @@ public: /** The interface that a finisher must implement Finisher implements changes to the chunk after the rough terrain has been generated. Examples of finishers are trees, snow, ore, lilypads and others. -Note that a worldgenerator may contain multiple finishers. +Note that a worldgenerator may contain multiple finishers, chained one after another. Also note that previously we used to distinguish between a structuregen and a finisher; this distinction is no longer relevant, all structure generators are considered finishers now (#398) */ @@ -154,23 +178,34 @@ class cComposableGenerator : public: cComposableGenerator(cChunkGenerator & a_ChunkGenerator); + // cChunkGenerator::cGenerator overrides: virtual void Initialize(cIniFile & a_IniFile) override; virtual void GenerateBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; virtual void DoGenerate(int a_ChunkX, int a_ChunkZ, cChunkDesc & a_ChunkDesc) override; protected: - // The generation composition: - cBiomeGenPtr m_BiomeGen; - cTerrainHeightGenPtr m_HeightGen; + // The generator's composition: + /** The biome generator. */ + cBiomeGenPtr m_BiomeGen; + + /** The terrain shape generator. */ + cTerrainShapeGenPtr m_ShapeGen; + + /** The terrain composition generator. */ cTerrainCompositionGenPtr m_CompositionGen; - cFinishGenList m_FinishGens; + + /** The cache for the heights of the composited terrain. */ + cTerrainHeightGenPtr m_CompositedHeightCache; + + /** The finisher generators, in the order in which they are applied. */ + cFinishGenList m_FinishGens; - /** Reads the biome gen settings from the ini and initializes m_BiomeGen accordingly */ + /** Reads the BiomeGen settings from the ini and initializes m_BiomeGen accordingly */ void InitBiomeGen(cIniFile & a_IniFile); - /** Reads the HeightGen settings from the ini and initializes m_HeightGen accordingly */ - void InitHeightGen(cIniFile & a_IniFile); + /** Reads the ShapeGen settings from the ini and initializes m_ShapeGen accordingly */ + void InitShapeGen(cIniFile & a_IniFile); /** Reads the CompositionGen settings from the ini and initializes m_CompositionGen accordingly */ void InitCompositionGen(cIniFile & a_IniFile); diff --git a/src/Generating/CompositedHeiGen.h b/src/Generating/CompositedHeiGen.h new file mode 100644 index 000000000..fa33a7861 --- /dev/null +++ b/src/Generating/CompositedHeiGen.h @@ -0,0 +1,49 @@ + +// CompositedHeiGen.h + +// Declares the cCompositedHeiGen class representing a cTerrainHeightGen descendant that calculates heightmap of the composited terrain +// This is used to further cache heightmaps for chunks already generated for finishers that require only heightmap information + + + + + +#pragma once + +#include "ComposableGenerator.h" + + + + + +class cCompositedHeiGen: + public cTerrainHeightGen +{ +public: + cCompositedHeiGen(cTerrainShapeGenPtr a_ShapeGen, cTerrainCompositionGenPtr a_CompositionGen): + m_ShapeGen(a_ShapeGen), + m_CompositionGen(a_CompositionGen) + { + } + + + + // cTerrainheightGen overrides: + virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override + { + cChunkDesc::Shape shape; + m_ShapeGen->GenShape(a_ChunkX, a_ChunkZ, shape); + cChunkDesc desc(a_ChunkX, a_ChunkZ); + desc.SetHeightFromShape(shape); + m_CompositionGen->ComposeTerrain(desc, shape); + memcpy(a_HeightMap, desc.GetHeightMap(), sizeof(a_HeightMap)); + } + +protected: + cTerrainShapeGenPtr m_ShapeGen; + cTerrainCompositionGenPtr m_CompositionGen; +}; + + + + diff --git a/src/Generating/DistortedHeightmap.cpp b/src/Generating/DistortedHeightmap.cpp index d5bc6ab55..e1ed9b450 100644 --- a/src/Generating/DistortedHeightmap.cpp +++ b/src/Generating/DistortedHeightmap.cpp @@ -14,163 +14,6 @@ -//////////////////////////////////////////////////////////////////////////////// -// cPattern: - -/// This class is used to store a column pattern initialized at runtime, -/// so that the program doesn't need to explicitly set 256 values for each pattern -/// Each pattern has 256 blocks so that there's no need to check pattern bounds when assigning the -/// pattern - there will always be enough pattern left, even for the whole chunk height -class cPattern -{ -public: - cPattern(cDistortedHeightmap::sBlockInfo * a_TopBlocks, size_t a_Count) - { - // Copy the pattern into the top: - for (size_t i = 0; i < a_Count; i++) - { - m_Pattern[i] = a_TopBlocks[i]; - } - - // Fill the rest with stone: - static cDistortedHeightmap::sBlockInfo Stone = {E_BLOCK_STONE, 0}; - for (size_t i = a_Count; i < cChunkDef::Height; i++) - { - m_Pattern[i] = Stone; - } - } - - const cDistortedHeightmap::sBlockInfo * Get(void) const { return m_Pattern; } - -protected: - cDistortedHeightmap::sBlockInfo m_Pattern[cChunkDef::Height]; -} ; - - - - - -//////////////////////////////////////////////////////////////////////////////// -// The arrays to use for the top block pattern definitions: - -static cDistortedHeightmap::sBlockInfo tbGrass[] = -{ - {E_BLOCK_GRASS, 0}, - {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, - {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, - {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, -} ; - -static cDistortedHeightmap::sBlockInfo tbSand[] = -{ - { E_BLOCK_SAND, 0}, - { E_BLOCK_SAND, 0}, - { E_BLOCK_SAND, 0}, - { E_BLOCK_SANDSTONE, 0}, -} ; - -static cDistortedHeightmap::sBlockInfo tbDirt[] = -{ - {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, - {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, - {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, - {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, -} ; - -static cDistortedHeightmap::sBlockInfo tbPodzol[] = -{ - {E_BLOCK_DIRT, E_META_DIRT_PODZOL}, - {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, - {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, - {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, -} ; - -static cDistortedHeightmap::sBlockInfo tbGrassLess[] = -{ - {E_BLOCK_DIRT, E_META_DIRT_GRASSLESS}, - {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, - {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, - {E_BLOCK_DIRT, E_META_DIRT_NORMAL}, -} ; - -static cDistortedHeightmap::sBlockInfo tbMycelium[] = -{ - {E_BLOCK_MYCELIUM, 0}, - {E_BLOCK_DIRT, 0}, - {E_BLOCK_DIRT, 0}, - {E_BLOCK_DIRT, 0}, -} ; - -static cDistortedHeightmap::sBlockInfo tbGravel[] = -{ - {E_BLOCK_GRAVEL, 0}, - {E_BLOCK_GRAVEL, 0}, - {E_BLOCK_GRAVEL, 0}, - {E_BLOCK_STONE, 0}, -} ; - -static cDistortedHeightmap::sBlockInfo tbStone[] = -{ - {E_BLOCK_STONE, 0}, - {E_BLOCK_STONE, 0}, - {E_BLOCK_STONE, 0}, - {E_BLOCK_STONE, 0}, -} ; - - - -//////////////////////////////////////////////////////////////////////////////// -// Ocean floor pattern top-block definitions: - -static cDistortedHeightmap::sBlockInfo tbOFSand[] = -{ - {E_BLOCK_SAND, 0}, - {E_BLOCK_SAND, 0}, - {E_BLOCK_SAND, 0}, - {E_BLOCK_SANDSTONE, 0} -} ; - -static cDistortedHeightmap::sBlockInfo tbOFClay[] = -{ - { E_BLOCK_CLAY, 0}, - { E_BLOCK_CLAY, 0}, - { E_BLOCK_SAND, 0}, - { E_BLOCK_SAND, 0}, -} ; - -static cDistortedHeightmap::sBlockInfo tbOFRedSand[] = -{ - { E_BLOCK_SAND, E_META_SAND_RED}, - { E_BLOCK_SAND, E_META_SAND_RED}, - { E_BLOCK_SAND, E_META_SAND_RED}, - { E_BLOCK_SANDSTONE, 0}, -} ; - - - - - - -//////////////////////////////////////////////////////////////////////////////// -// Individual patterns to use: - -static cPattern patGrass (tbGrass, ARRAYCOUNT(tbGrass)); -static cPattern patSand (tbSand, ARRAYCOUNT(tbSand)); -static cPattern patDirt (tbDirt, ARRAYCOUNT(tbDirt)); -static cPattern patPodzol (tbPodzol, ARRAYCOUNT(tbPodzol)); -static cPattern patGrassLess(tbGrassLess, ARRAYCOUNT(tbGrassLess)); -static cPattern patMycelium (tbMycelium, ARRAYCOUNT(tbMycelium)); -static cPattern patGravel (tbGravel, ARRAYCOUNT(tbGravel)); -static cPattern patStone (tbStone, ARRAYCOUNT(tbStone)); - -static cPattern patOFSand (tbOFSand, ARRAYCOUNT(tbOFSand)); -static cPattern patOFClay (tbOFClay, ARRAYCOUNT(tbOFClay)); -static cPattern patOFRedSand(tbOFRedSand, ARRAYCOUNT(tbOFRedSand)); - - - - - //////////////////////////////////////////////////////////////////////////////// // cDistortedHeightmap: @@ -237,7 +80,7 @@ const cDistortedHeightmap::sGenParam cDistortedHeightmap::m_GenParam[256] = {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, // 110 .. 119 {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, // 120 .. 128 - // Release 1.7 /* biome variants: + // Release 1.7 biome variants: /* biSunflowerPlains */ { 1.0f, 1.0f}, // 129 /* biDesertM */ { 1.0f, 1.0f}, // 130 /* biExtremeHillsM */ {16.0f, 16.0f}, // 131 @@ -279,8 +122,6 @@ const cDistortedHeightmap::sGenParam cDistortedHeightmap::m_GenParam[256] = cDistortedHeightmap::cDistortedHeightmap(int a_Seed, cBiomeGenPtr a_BiomeGen) : m_NoiseDistortX(a_Seed + 1000), m_NoiseDistortZ(a_Seed + 2000), - m_OceanFloorSelect(a_Seed + 3000), - m_MesaFloor(a_Seed + 4000), m_BiomeGen(a_BiomeGen), m_UnderlyingHeiGen(new cHeiGenBiomal(a_Seed, a_BiomeGen)), m_HeightGen(m_UnderlyingHeiGen, 64), @@ -293,8 +134,6 @@ cDistortedHeightmap::cDistortedHeightmap(int a_Seed, cBiomeGenPtr a_BiomeGen) : m_NoiseDistortZ.AddOctave((NOISE_DATATYPE)1, (NOISE_DATATYPE)0.5); m_NoiseDistortZ.AddOctave((NOISE_DATATYPE)0.5, (NOISE_DATATYPE)1); m_NoiseDistortZ.AddOctave((NOISE_DATATYPE)0.25, (NOISE_DATATYPE)2); - - InitMesaPattern(a_Seed); } @@ -309,7 +148,7 @@ void cDistortedHeightmap::Initialize(cIniFile & a_IniFile) } // Read the params from the INI file: - m_SeaLevel = a_IniFile.GetValueSetI("Generator", "DistortedHeightmapSeaLevel", 62); + m_SeaLevel = a_IniFile.GetValueSetI("Generator", "SeaLevel", 62); m_FrequencyX = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "DistortedHeightmapFrequencyX", 10); m_FrequencyY = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "DistortedHeightmapFrequencyY", 10); m_FrequencyZ = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "DistortedHeightmapFrequencyZ", 10); @@ -321,89 +160,6 @@ void cDistortedHeightmap::Initialize(cIniFile & a_IniFile) -void cDistortedHeightmap::InitMesaPattern(int a_Seed) -{ - // Stone in the bottom half of the pattern: - for (int i = cChunkDef::Height; i < 2 * cChunkDef::Height; i++) - { - m_MesaPattern[i].BlockMeta = 0; - m_MesaPattern[i].BlockType = E_BLOCK_STONE; - } - - // Stained and hardened clay in the top half of the pattern - // In a loop, choose whether to use one or two layers of stained clay, then choose a color and width for each layer - // Separate each group with another layer of hardened clay - cNoise PatternNoise((unsigned)a_Seed); - static NIBBLETYPE AllowedColors[] = - { - E_META_STAINED_CLAY_YELLOW, - E_META_STAINED_CLAY_YELLOW, - E_META_STAINED_CLAY_RED, - E_META_STAINED_CLAY_RED, - E_META_STAINED_CLAY_WHITE, - E_META_STAINED_CLAY_BROWN, - E_META_STAINED_CLAY_BROWN, - E_META_STAINED_CLAY_BROWN, - E_META_STAINED_CLAY_ORANGE, - E_META_STAINED_CLAY_ORANGE, - E_META_STAINED_CLAY_ORANGE, - E_META_STAINED_CLAY_ORANGE, - E_META_STAINED_CLAY_ORANGE, - E_META_STAINED_CLAY_ORANGE, - E_META_STAINED_CLAY_LIGHTGRAY, - } ; - static int LayerSizes[] = // Adjust the chance so that thinner layers occur more commonly - { - 1, 1, 1, 1, 1, 1, - 2, 2, 2, 2, - 3, 3, - } ; - int Idx = cChunkDef::Height - 1; - while (Idx >= 0) - { - // A layer group of 1 - 2 color stained clay: - int Random = PatternNoise.IntNoise1DInt(Idx) / 7; - int NumLayers = (Random % 2) + 1; - Random /= 2; - for (int Lay = 0; Lay < NumLayers; Lay++) - { - int NumBlocks = LayerSizes[(Random % ARRAYCOUNT(LayerSizes))]; - NIBBLETYPE Color = AllowedColors[(Random / 4) % ARRAYCOUNT(AllowedColors)]; - if ( - ((NumBlocks == 3) && (NumLayers == 2)) || // In two-layer mode disallow the 3-high layers: - (Color == E_META_STAINED_CLAY_WHITE)) // White stained clay can ever be only 1 block high - { - NumBlocks = 1; - } - NumBlocks = std::min(Idx + 1, NumBlocks); // Limit by Idx so that we don't have to check inside the loop - Random /= 32; - for (int Block = 0; Block < NumBlocks; Block++, Idx--) - { - m_MesaPattern[Idx].BlockMeta = Color; - m_MesaPattern[Idx].BlockType = E_BLOCK_STAINED_CLAY; - } // for Block - } // for Lay - - // A layer of hardened clay in between the layer group: - int NumBlocks = (Random % 4) + 1; // All heights the same probability - if ((NumLayers == 2) && (NumBlocks < 4)) - { - // For two layers of stained clay, add an extra block of hardened clay: - NumBlocks++; - } - NumBlocks = std::min(Idx + 1, NumBlocks); // Limit by Idx so that we don't have to check inside the loop - for (int Block = 0; Block < NumBlocks; Block++, Idx--) - { - m_MesaPattern[Idx].BlockMeta = 0; - m_MesaPattern[Idx].BlockType = E_BLOCK_HARDENED_CLAY; - } // for Block - } // while (Idx >= 0) -} - - - - - void cDistortedHeightmap::PrepareState(int a_ChunkX, int a_ChunkZ) { if ((m_CurChunkX == a_ChunkX) && (m_CurChunkZ == a_ChunkZ)) @@ -474,23 +230,17 @@ void cDistortedHeightmap::GenerateHeightArray(void) -void cDistortedHeightmap::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) +void cDistortedHeightmap::GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape) { PrepareState(a_ChunkX, a_ChunkZ); for (int z = 0; z < cChunkDef::Width; z++) { for (int x = 0; x < cChunkDef::Width; x++) { - int NoiseArrayIdx = x + 17 * 257 * z; - cChunkDef::SetHeight(a_HeightMap, x, z, m_SeaLevel - 1); - for (int y = cChunkDef::Height - 1; y > m_SeaLevel - 1; y--) + int idx = x + 17 * 257 * z; + for (int y = 0; y < cChunkDef::Height; y++) { - int HeightMapHeight = (int)m_DistortedHeightmap[NoiseArrayIdx + 17 * y]; - if (y < HeightMapHeight) - { - cChunkDef::SetHeight(a_HeightMap, x, z, y); - break; - } + a_Shape[y + x * 256 + z * 16 * 256] = (y < m_DistortedHeightmap[idx + y * 17]) ? 1 : 0; } // for y } // for x } // for z @@ -500,36 +250,7 @@ void cDistortedHeightmap::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::He -void cDistortedHeightmap::InitializeHeightGen(cIniFile & a_IniFile) -{ - Initialize(a_IniFile); -} - - - - - -void cDistortedHeightmap::ComposeTerrain(cChunkDesc & a_ChunkDesc) -{ - // Prepare the internal state for generating this chunk: - PrepareState(a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ()); - - // Compose: - a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0); - for (int z = 0; z < cChunkDef::Width; z++) - { - for (int x = 0; x < cChunkDef::Width; x++) - { - ComposeColumn(a_ChunkDesc, x, z); - } // for x - } // for z -} - - - - - -void cDistortedHeightmap::InitializeCompoGen(cIniFile & a_IniFile) +void cDistortedHeightmap::InitializeShapeGen(cIniFile & a_IniFile) { Initialize(a_IniFile); } @@ -654,275 +375,3 @@ void cDistortedHeightmap::GetDistortAmpsAt(BiomeNeighbors & a_Neighbors, int a_R -void cDistortedHeightmap::ComposeColumn(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelZ) -{ - // Frequencies for the podzol floor selecting noise: - const NOISE_DATATYPE FrequencyX = 8; - const NOISE_DATATYPE FrequencyZ = 8; - - EMCSBiome Biome = a_ChunkDesc.GetBiome(a_RelX, a_RelZ); - switch (Biome) - { - case biOcean: - case biPlains: - case biForest: - case biTaiga: - case biSwampland: - case biRiver: - case biFrozenOcean: - case biFrozenRiver: - case biIcePlains: - case biIceMountains: - case biForestHills: - case biTaigaHills: - case biExtremeHillsEdge: - case biExtremeHillsPlus: - case biExtremeHills: - case biJungle: - case biJungleHills: - case biJungleEdge: - case biDeepOcean: - case biStoneBeach: - case biColdBeach: - case biBirchForest: - case biBirchForestHills: - case biRoofedForest: - case biColdTaiga: - case biColdTaigaHills: - case biSavanna: - case biSavannaPlateau: - case biSunflowerPlains: - case biFlowerForest: - case biTaigaM: - case biSwamplandM: - case biIcePlainsSpikes: - case biJungleM: - case biJungleEdgeM: - case biBirchForestM: - case biBirchForestHillsM: - case biRoofedForestM: - case biColdTaigaM: - case biSavannaM: - case biSavannaPlateauM: - { - FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, patGrass.Get()); - return; - } - - case biMegaTaiga: - case biMegaTaigaHills: - case biMegaSpruceTaiga: - case biMegaSpruceTaigaHills: - { - // Select the pattern to use - podzol, grass or grassless dirt: - NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(m_CurChunkX * cChunkDef::Width + a_RelX)) / FrequencyX; - NOISE_DATATYPE NoiseY = ((NOISE_DATATYPE)(m_CurChunkZ * cChunkDef::Width + a_RelZ)) / FrequencyZ; - NOISE_DATATYPE Val = m_OceanFloorSelect.CubicNoise2D(NoiseX, NoiseY); - const sBlockInfo * Pattern = (Val < -0.9) ? patGrassLess.Get() : ((Val > 0) ? patPodzol.Get() : patGrass.Get()); - FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, Pattern); - return; - } - - case biDesertHills: - case biDesert: - case biDesertM: - case biBeach: - { - FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, patSand.Get()); - return; - } - - case biMushroomIsland: - case biMushroomShore: - { - FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, patMycelium.Get()); - return; - } - - case biMesa: - case biMesaPlateauF: - case biMesaPlateau: - case biMesaBryce: - case biMesaPlateauFM: - case biMesaPlateauM: - { - // Mesa biomes need special handling, because they don't follow the usual "4 blocks from top pattern", - // instead, they provide a "from bottom" pattern with varying base height, - // usually 4 blocks below the ocean level - FillColumnMesa(a_ChunkDesc, a_RelX, a_RelZ); - return; - } - - case biExtremeHillsPlusM: - case biExtremeHillsM: - { - // Select the pattern to use - gravel, stone or grass: - NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(m_CurChunkX * cChunkDef::Width + a_RelX)) / FrequencyX; - NOISE_DATATYPE NoiseY = ((NOISE_DATATYPE)(m_CurChunkZ * cChunkDef::Width + a_RelZ)) / FrequencyZ; - NOISE_DATATYPE Val = m_OceanFloorSelect.CubicNoise2D(NoiseX, NoiseY); - const sBlockInfo * Pattern = (Val < 0.0) ? patStone.Get() : patGrass.Get(); - FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, Pattern); - return; - } - default: - { - ASSERT(!"Unhandled biome"); - return; - } - } // switch (Biome) -} - - - - - -void cDistortedHeightmap::FillColumnPattern(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelZ, const sBlockInfo * a_Pattern) -{ - int NoiseArrayIdx = a_RelX + 17 * 257 * a_RelZ; - bool HasHadWater = false; - int PatternIdx = 0; - for (int y = a_ChunkDesc.GetHeight(a_RelX, a_RelZ); y > 0; y--) - { - int HeightMapHeight = (int)m_DistortedHeightmap[NoiseArrayIdx + 17 * y]; - - if (y < HeightMapHeight) - { - // "ground" part, use the pattern: - a_ChunkDesc.SetBlockTypeMeta(a_RelX, y, a_RelZ, a_Pattern[PatternIdx].BlockType, a_Pattern[PatternIdx].BlockMeta); - PatternIdx++; - continue; - } - - // "air" or "water" part: - // Reset the pattern index to zero, so that the pattern is repeated from the top again: - PatternIdx = 0; - - if (y >= m_SeaLevel) - { - // "air" part, do nothing - continue; - } - - a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_STATIONARY_WATER); - if (HasHadWater) - { - continue; - } - - // Select the ocean-floor pattern to use: - a_Pattern = a_ChunkDesc.GetBiome(a_RelX, a_RelZ) == biDeepOcean ? patGravel.Get() : ChooseOceanFloorPattern(a_RelX, a_RelZ); - HasHadWater = true; - } // for y - a_ChunkDesc.SetBlockType(a_RelX, 0, a_RelZ, E_BLOCK_BEDROCK); -} - - - - - -void cDistortedHeightmap::FillColumnMesa(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelZ) -{ - // Frequencies for the clay floor noise: - const NOISE_DATATYPE FrequencyX = 50; - const NOISE_DATATYPE FrequencyZ = 50; - - int Top = a_ChunkDesc.GetHeight(a_RelX, a_RelZ); - if (Top < m_SeaLevel) - { - // The terrain is below sealevel, handle as regular ocean: - FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, patOFRedSand.Get()); - return; - } - - NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(m_CurChunkX * cChunkDef::Width + a_RelX)) / FrequencyX; - NOISE_DATATYPE NoiseY = ((NOISE_DATATYPE)(m_CurChunkZ * cChunkDef::Width + a_RelZ)) / FrequencyZ; - int ClayFloor = m_SeaLevel - 6 + (int)(4.f * m_MesaFloor.CubicNoise2D(NoiseX, NoiseY)); - if (ClayFloor >= Top) - { - ClayFloor = Top - 1; - } - - if (Top - m_SeaLevel < 5) - { - // Simple case: top is red sand, then hardened clay down to ClayFloor, then stone: - a_ChunkDesc.SetBlockTypeMeta(a_RelX, Top, a_RelZ, E_BLOCK_SAND, E_META_SAND_RED); - for (int y = Top - 1; y >= ClayFloor; y--) - { - a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_HARDENED_CLAY); - } - for (int y = ClayFloor - 1; y > 0; y--) - { - a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_STONE); - } - a_ChunkDesc.SetBlockType(a_RelX, 0, a_RelZ, E_BLOCK_BEDROCK); - return; - } - - // Difficult case: use the mesa pattern and watch for overhangs: - int NoiseArrayIdx = a_RelX + 17 * 257 * a_RelZ; - int PatternIdx = cChunkDef::Height - (Top - ClayFloor); // We want the block at index ClayFloor to be pattern's 256th block (first stone) - const sBlockInfo * Pattern = m_MesaPattern; - bool HasHadWater = false; - for (int y = Top; y > 0; y--) - { - int HeightMapHeight = (int)m_DistortedHeightmap[NoiseArrayIdx + 17 * y]; - if (y < HeightMapHeight) - { - // "ground" part, use the pattern: - a_ChunkDesc.SetBlockTypeMeta(a_RelX, y, a_RelZ, Pattern[PatternIdx].BlockType, Pattern[PatternIdx].BlockMeta); - PatternIdx++; - continue; - } - - if (y >= m_SeaLevel) - { - // "air" part, do nothing - continue; - } - - // "water" part, fill with water and choose new pattern for ocean floor, if not chosen already: - PatternIdx = 0; - a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_STATIONARY_WATER); - if (HasHadWater) - { - continue; - } - - // Select the ocean-floor pattern to use: - Pattern = ChooseOceanFloorPattern(a_RelX, a_RelZ); - HasHadWater = true; - } // for y - a_ChunkDesc.SetBlockType(a_RelX, 0, a_RelZ, E_BLOCK_BEDROCK); -} - - - - - -const cDistortedHeightmap::sBlockInfo * cDistortedHeightmap::ChooseOceanFloorPattern(int a_RelX, int a_RelZ) -{ - // Frequencies for the ocean floor selecting noise: - const NOISE_DATATYPE FrequencyX = 3; - const NOISE_DATATYPE FrequencyZ = 3; - - // Select the ocean-floor pattern to use: - NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(m_CurChunkX * cChunkDef::Width + a_RelX)) / FrequencyX; - NOISE_DATATYPE NoiseY = ((NOISE_DATATYPE)(m_CurChunkZ * cChunkDef::Width + a_RelZ)) / FrequencyZ; - NOISE_DATATYPE Val = m_OceanFloorSelect.CubicNoise2D(NoiseX, NoiseY); - if (Val < -0.95) - { - return patOFClay.Get(); - } - else if (Val < 0) - { - return patOFSand.Get(); - } - else - { - return patDirt.Get(); - } -} - - - - diff --git a/src/Generating/DistortedHeightmap.h b/src/Generating/DistortedHeightmap.h index 955e57a1e..79fc35542 100644 --- a/src/Generating/DistortedHeightmap.h +++ b/src/Generating/DistortedHeightmap.h @@ -23,17 +23,9 @@ class cDistortedHeightmap : - public cTerrainHeightGen, - public cTerrainCompositionGen + public cTerrainShapeGen { public: - /// Structure used for storing block patterns for columns - struct sBlockInfo - { - BLOCKTYPE BlockType; - NIBBLETYPE BlockMeta; - } ; - cDistortedHeightmap(int a_Seed, cBiomeGenPtr a_BiomeGen); protected: @@ -51,8 +43,6 @@ protected: cPerlinNoise m_NoiseDistortX; cPerlinNoise m_NoiseDistortZ; - cNoise m_OceanFloorSelect; ///< Used for selecting between dirt and sand on the ocean floor - cNoise m_MesaFloor; ///< Used for the floor of the clay blocks in mesa biomes int m_SeaLevel; NOISE_DATATYPE m_FrequencyX; @@ -70,9 +60,9 @@ protected: cTerrainHeightGenPtr m_UnderlyingHeiGen; /** Cache for m_UnderlyingHeiGen. */ - cHeiGenCache m_HeightGen; + cHeiGenCache m_HeightGen; - /// Heightmap for the current chunk, before distortion (from m_HeightGen). Used for optimization. + /** Heightmap for the current chunk, before distortion (from m_HeightGen). Used for optimization. */ cChunkDef::HeightMap m_CurChunkHeights; // Per-biome terrain generator parameters: @@ -87,54 +77,30 @@ protected: NOISE_DATATYPE m_DistortAmpX[DIM_X * DIM_Z]; NOISE_DATATYPE m_DistortAmpZ[DIM_X * DIM_Z]; - /// True if Initialize() has been called. Used to initialize-once even with multiple init entrypoints (HeiGen / CompoGen) + /** True if Initialize() has been called. Used to initialize-once even with multiple init entrypoints (HeiGen / CompoGen). */ bool m_IsInitialized; - /// The vertical pattern to be used for mesa biomes. Seed-dependant. - /// One Height of pattern and one Height of stone to avoid checking pattern dimensions - sBlockInfo m_MesaPattern[2 * cChunkDef::Height]; - - /// Initializes m_MesaPattern with a reasonable pattern of stained clay / hardened clay, based on the seed - void InitMesaPattern(int a_Seed); - - /// Unless the LastChunk coords are equal to coords given, prepares the internal state (noise arrays, heightmap) + /** Unless the LastChunk coords are equal to coords given, prepares the internal state (noise arrays, heightmap). */ void PrepareState(int a_ChunkX, int a_ChunkZ); - /// Generates the m_DistortedHeightmap array for the current chunk + /** Generates the m_DistortedHeightmap array for the current chunk. */ void GenerateHeightArray(void); - /// Calculates the heightmap value (before distortion) at the specified (floating-point) coords + /** Calculates the heightmap value (before distortion) at the specified (floating-point) coords. */ int GetHeightmapAt(NOISE_DATATYPE a_X, NOISE_DATATYPE a_Z); - /// Updates m_DistortAmpX/Z[] based on m_CurChunkX and m_CurChunkZ + /** Updates m_DistortAmpX/Z[] based on m_CurChunkX and m_CurChunkZ. */ void UpdateDistortAmps(void); - /// Calculates the X and Z distortion amplitudes based on the neighbors' biomes + /** Calculates the X and Z distortion amplitudes based on the neighbors' biomes. */ void GetDistortAmpsAt(BiomeNeighbors & a_Neighbors, int a_RelX, int a_RelZ, NOISE_DATATYPE & a_DistortAmpX, NOISE_DATATYPE & a_DistortAmpZ); - /// Reads the settings from the ini file. Skips reading if already initialized + /** Reads the settings from the ini file. Skips reading if already initialized. */ void Initialize(cIniFile & a_IniFile); - /// Composes a single column in a_ChunkDesc. Chooses what to do based on the biome in that column - void ComposeColumn(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelZ); - /// Fills the specified column with the specified pattern; restarts the pattern when air is reached, - /// switches to ocean floor pattern if ocean is reached. Always adds bedrock at the very bottom. - void FillColumnPattern(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelZ, const sBlockInfo * a_Pattern); - - /// Fills the specified column with mesa pattern, based on the column height - void FillColumnMesa(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelZ); - - /// Returns the pattern to use for an ocean floor in the specified column - const sBlockInfo * ChooseOceanFloorPattern(int a_RelX, int a_RelZ); - - - // cTerrainHeightGen overrides: - virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; - virtual void InitializeHeightGen(cIniFile & a_IniFile) override; - - // cTerrainCompositionGen overrides: - virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc) override; - virtual void InitializeCompoGen(cIniFile & a_IniFile) override; + // cTerrainShapeGen overrides: + virtual void GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape) override; + virtual void InitializeShapeGen(cIniFile & a_IniFile) override; } ; diff --git a/src/Generating/DungeonRoomsFinisher.cpp b/src/Generating/DungeonRoomsFinisher.cpp index 3f328868d..7ab22c2c5 100644 --- a/src/Generating/DungeonRoomsFinisher.cpp +++ b/src/Generating/DungeonRoomsFinisher.cpp @@ -78,7 +78,8 @@ protected: - /** Decodes the position index along the room walls into a proper 2D position for a chest. */ + /** Decodes the position index along the room walls into a proper 2D position for a chest. + The Y coord of the returned vector specifies the chest's meta value*/ Vector3i DecodeChestCoords(int a_PosIdx, int a_SizeX, int a_SizeZ) { if (a_PosIdx < a_SizeX) @@ -258,9 +259,9 @@ protected: //////////////////////////////////////////////////////////////////////////////// // cDungeonRoomsFinisher: -cDungeonRoomsFinisher::cDungeonRoomsFinisher(cTerrainHeightGenPtr a_HeightGen, int a_Seed, int a_GridSize, int a_MaxSize, int a_MinSize, const AString & a_HeightDistrib) : +cDungeonRoomsFinisher::cDungeonRoomsFinisher(cTerrainShapeGenPtr a_ShapeGen, int a_Seed, int a_GridSize, int a_MaxSize, int a_MinSize, const AString & a_HeightDistrib) : super(a_Seed + 100, a_GridSize, a_GridSize, a_GridSize, a_GridSize, a_MaxSize, a_MaxSize, 1024), - m_HeightGen(a_HeightGen), + m_ShapeGen(a_ShapeGen), m_MaxHalfSize((a_MaxSize + 1) / 2), m_MinHalfSize((a_MinSize + 1) / 2), m_HeightProbability(cChunkDef::Height) @@ -293,13 +294,21 @@ cDungeonRoomsFinisher::cStructurePtr cDungeonRoomsFinisher::CreateStructure(int int ChunkX, ChunkZ; int RelX = a_OriginX, RelY = 0, RelZ = a_OriginZ; cChunkDef::AbsoluteToRelative(RelX, RelY, RelZ, ChunkX, ChunkZ); - cChunkDef::HeightMap HeightMap; - m_HeightGen->GenHeightMap(ChunkX, ChunkZ, HeightMap); - int Height = cChunkDef::GetHeight(HeightMap, RelX, RelZ); // Max room height at {a_OriginX, a_OriginZ} - Height = Clamp(m_HeightProbability.MapValue(rnd % m_HeightProbability.GetSum()), 10, Height - 5); + cChunkDesc::Shape shape; + m_ShapeGen->GenShape(ChunkX, ChunkZ, shape); + int height = 0; + int idx = RelX * 256 + RelZ * 16 * 256; + for (int y = 6; y < cChunkDef::Height; y++) + { + if (shape[idx + y] != 0) + { + continue; + } + height = Clamp(m_HeightProbability.MapValue(rnd % m_HeightProbability.GetSum()), 10, y - 5); + } // Create the dungeon room descriptor: - return cStructurePtr(new cDungeonRoom(a_GridX, a_GridZ, a_OriginX, a_OriginZ, HalfSizeX, HalfSizeZ, Height, m_Noise)); + return cStructurePtr(new cDungeonRoom(a_GridX, a_GridZ, a_OriginX, a_OriginZ, HalfSizeX, HalfSizeZ, height, m_Noise)); } diff --git a/src/Generating/DungeonRoomsFinisher.h b/src/Generating/DungeonRoomsFinisher.h index 09dd0448a..e5828f989 100644 --- a/src/Generating/DungeonRoomsFinisher.h +++ b/src/Generating/DungeonRoomsFinisher.h @@ -23,15 +23,15 @@ class cDungeonRoomsFinisher : public: /** Creates a new dungeon room finisher. - a_HeightGen is the underlying height generator, so that the rooms can always be placed under the terrain. + a_ShapeGen is the underlying terrain shape generator, so that the rooms can always be placed under the terrain. a_MaxSize and a_MinSize are the maximum and minimum sizes of the room's internal (air) area, in blocks across. a_HeightDistrib is the string defining the height distribution for the rooms (cProbabDistrib format). */ - cDungeonRoomsFinisher(cTerrainHeightGenPtr a_HeightGen, int a_Seed, int a_GridSize, int a_MaxSize, int a_MinSize, const AString & a_HeightDistrib); + cDungeonRoomsFinisher(cTerrainShapeGenPtr a_ShapeGen, int a_Seed, int a_GridSize, int a_MaxSize, int a_MinSize, const AString & a_HeightDistrib); protected: - /** The height gen that is used for limiting the rooms' Y coords */ - cTerrainHeightGenPtr m_HeightGen; + /** The shape gen that is used for limiting the rooms' Y coords */ + cTerrainShapeGenPtr m_ShapeGen; /** Maximum half-size (from center to wall) of the dungeon room's inner (air) area. Default is 3 (vanilla). */ int m_MaxHalfSize; diff --git a/src/Generating/EndGen.cpp b/src/Generating/EndGen.cpp index 0111d2fa3..89d6117bb 100644 --- a/src/Generating/EndGen.cpp +++ b/src/Generating/EndGen.cpp @@ -147,13 +147,14 @@ bool cEndGen::IsChunkOutsideRange(int a_ChunkX, int a_ChunkZ) -void cEndGen::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) +void cEndGen::GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape) { + // If the chunk is outside out range, fill the shape with zeroes: if (IsChunkOutsideRange(a_ChunkX, a_ChunkZ)) { - for (size_t i = 0; i < ARRAYCOUNT(a_HeightMap); i++) + for (size_t i = 0; i < ARRAYCOUNT(a_Shape); i++) { - a_HeightMap[i] = 0; + a_Shape[i] = 0; } return; } @@ -165,15 +166,14 @@ void cEndGen::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_ { for (int x = 0; x < cChunkDef::Width; x++) { - cChunkDef::SetHeight(a_HeightMap, x, z, MaxY); - for (int y = MaxY; y > 0; y--) + for (int y = 0; y < MaxY; y++) { - if (m_NoiseArray[y * 17 * 17 + z * 17 + x] <= 0) - { - cChunkDef::SetHeight(a_HeightMap, x, z, y); - break; - } - } // for y + a_Shape[(x + 16 * z) * 256 + y] = (m_NoiseArray[y * 17 * 17 + z * 17 + z] > 0) ? 1 : 0; + } + for (int y = MaxY; y < cChunkDef::Height; y++) + { + a_Shape[(x + 16 * z) * 256 + y] = 0; + } } // for x } // for z } @@ -182,30 +182,18 @@ void cEndGen::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_ -void cEndGen::ComposeTerrain(cChunkDesc & a_ChunkDesc) +void cEndGen::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) { - if (IsChunkOutsideRange(a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ())) - { - a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0); - return; - } - - PrepareState(a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ()); - - int MaxY = std::min((int)(1.75 * m_IslandSizeY + 1), cChunkDef::Height - 1); + a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0); for (int z = 0; z < cChunkDef::Width; z++) { for (int x = 0; x < cChunkDef::Width; x++) { - for (int y = MaxY; y > 0; y--) + for (int y = 0; y < cChunkDef::Height; y++) { - if (m_NoiseArray[y * 17 * 17 + z * 17 + x] <= 0) - { - a_ChunkDesc.SetBlockTypeMeta(x, y, z, E_BLOCK_END_STONE, 0); - } - else + if (a_Shape[(x + 16 * z) * 256 + y] != 0) { - a_ChunkDesc.SetBlockTypeMeta(x, y, z, E_BLOCK_AIR, 0); + a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_END_STONE); } } // for y } // for x diff --git a/src/Generating/EndGen.h b/src/Generating/EndGen.h index c2278c1e1..f9e3f6e53 100644 --- a/src/Generating/EndGen.h +++ b/src/Generating/EndGen.h @@ -17,7 +17,7 @@ class cEndGen : - public cTerrainHeightGen, + public cTerrainShapeGen, public cTerrainCompositionGen { public: @@ -59,10 +59,10 @@ protected: /// Returns true if the chunk is outside of the island's dimensions bool IsChunkOutsideRange(int a_ChunkX, int a_ChunkZ); - // cTerrainHeightGen overrides: - virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; + // cTerrainShapeGen overrides: + virtual void GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape) override; // cTerrainCompositionGen overrides: - virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc) override; + virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) override; virtual void InitializeCompoGen(cIniFile & a_IniFile) override; } ; diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index 42ecdf8a8..2ff3e7f67 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -411,7 +411,7 @@ void cFinishGenSnow::GenFinish(cChunkDesc & a_ChunkDesc) case biFrozenOcean: { int Height = a_ChunkDesc.GetHeight(x, z); - if (cBlockInfo::IsSnowable(a_ChunkDesc.GetBlockType(x, Height, z))) + if (cBlockInfo::IsSnowable(a_ChunkDesc.GetBlockType(x, Height, z)) && (Height < cChunkDef::Height - 1)) { a_ChunkDesc.SetBlockType(x, Height + 1, z, E_BLOCK_SNOW); a_ChunkDesc.SetHeight(x, z, Height + 1); diff --git a/src/Generating/HeiGen.cpp b/src/Generating/HeiGen.cpp index 1d9f1e3aa..61d087c17 100644 --- a/src/Generating/HeiGen.cpp +++ b/src/Generating/HeiGen.cpp @@ -15,7 +15,6 @@ - //////////////////////////////////////////////////////////////////////////////// // cHeiGenFlat: @@ -133,15 +132,6 @@ void cHeiGenCache::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap -void cHeiGenCache::InitializeHeightGen(cIniFile & a_IniFile) -{ - m_HeiGenToCache->InitializeHeightGen(a_IniFile); -} - - - - - bool cHeiGenCache::GetHeightAt(int a_ChunkX, int a_ChunkZ, int a_RelX, int a_RelZ, HEIGHTTYPE & a_Height) { for (int i = 0; i < m_CacheSize; i++) @@ -159,6 +149,51 @@ bool cHeiGenCache::GetHeightAt(int a_ChunkX, int a_ChunkZ, int a_RelX, int a_Rel +//////////////////////////////////////////////////////////////////////////////// +// cHeiGenMultiCache: + +cHeiGenMultiCache::cHeiGenMultiCache(cTerrainHeightGenPtr a_HeiGenToCache, size_t a_SubCacheSize, size_t a_NumSubCaches): + m_NumSubCaches(a_NumSubCaches) +{ + // Create the individual sub-caches: + m_SubCaches.reserve(a_NumSubCaches); + for (size_t i = 0; i < a_NumSubCaches; i++) + { + m_SubCaches.push_back(std::make_shared(a_HeiGenToCache, a_SubCacheSize)); + } +} + + + + + +void cHeiGenMultiCache::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) +{ + // Get the subcache responsible for this chunk: + const size_t cacheIdx = ((size_t)a_ChunkX + m_CoeffZ * (size_t)a_ChunkZ) % m_NumSubCaches; + + // Ask the subcache: + m_SubCaches[cacheIdx]->GenHeightMap(a_ChunkX, a_ChunkZ, a_HeightMap); +} + + + + + +bool cHeiGenMultiCache::GetHeightAt(int a_ChunkX, int a_ChunkZ, int a_RelX, int a_RelZ, HEIGHTTYPE & a_Height) +{ + // Get the subcache responsible for this chunk: + const size_t cacheIdx = ((size_t)a_ChunkX + m_CoeffZ * (size_t)a_ChunkZ) % m_NumSubCaches; + + // Ask the subcache: + return m_SubCaches[cacheIdx]->GetHeightAt(a_ChunkX, a_ChunkZ, a_RelX, a_RelZ, a_Height); +} + + + + + + //////////////////////////////////////////////////////////////////////////////// // cHeiGenClassic: @@ -750,43 +785,51 @@ cTerrainHeightGenPtr cTerrainHeightGen::CreateHeightGen(cIniFile & a_IniFile, cB } a_CacheOffByDefault = false; - cTerrainHeightGen * res = nullptr; - if (NoCaseCompare(HeightGenName, "flat") == 0) + cTerrainHeightGenPtr res; + if (NoCaseCompare(HeightGenName, "Flat") == 0) { - res = new cHeiGenFlat; + res = std::make_shared(); a_CacheOffByDefault = true; // We're generating faster than a cache would retrieve data } else if (NoCaseCompare(HeightGenName, "classic") == 0) { - res = new cHeiGenClassic(a_Seed); + res = std::make_shared(a_Seed); } else if (NoCaseCompare(HeightGenName, "DistortedHeightmap") == 0) { - res = new cDistortedHeightmap(a_Seed, a_BiomeGen); + // Not a heightmap-based generator, but it used to be accessible via HeightGen, so we need to skip making the default out of it + // Return an empty pointer, the caller will create the proper generator: + return cTerrainHeightGenPtr(); } else if (NoCaseCompare(HeightGenName, "End") == 0) { - res = new cEndGen(a_Seed); + // Not a heightmap-based generator, but it used to be accessible via HeightGen, so we need to skip making the default out of it + // Return an empty pointer, the caller will create the proper generator: + return cTerrainHeightGenPtr(); } else if (NoCaseCompare(HeightGenName, "MinMax") == 0) { - res = new cHeiGenMinMax(a_Seed, a_BiomeGen); + res = std::make_shared(a_Seed, a_BiomeGen); } else if (NoCaseCompare(HeightGenName, "Mountains") == 0) { - res = new cHeiGenMountains(a_Seed); + res = std::make_shared(a_Seed); } else if (NoCaseCompare(HeightGenName, "BiomalNoise3D") == 0) { - res = new cBiomalNoise3DComposable(a_Seed, a_BiomeGen); + // Not a heightmap-based generator, but it used to be accessible via HeightGen, so we need to skip making the default out of it + // Return an empty pointer, the caller will create the proper generator: + return cTerrainHeightGenPtr(); } else if (NoCaseCompare(HeightGenName, "Noise3D") == 0) { - res = new cNoise3DComposable(a_Seed); + // Not a heightmap-based generator, but it used to be accessible via HeightGen, so we need to skip making the default out of it + // Return an empty pointer, the caller will create the proper generator: + return cTerrainHeightGenPtr(); } - else if (NoCaseCompare(HeightGenName, "biomal") == 0) + else if (NoCaseCompare(HeightGenName, "Biomal") == 0) { - res = new cHeiGenBiomal(a_Seed, a_BiomeGen); + res = std::make_shared(a_Seed, a_BiomeGen); /* // Performance-testing: @@ -805,15 +848,14 @@ cTerrainHeightGenPtr cTerrainHeightGen::CreateHeightGen(cIniFile & a_IniFile, cB { // No match found, force-set the default and retry LOGWARN("Unknown HeightGen \"%s\", using \"Biomal\" instead.", HeightGenName.c_str()); - a_IniFile.DeleteValue("Generator", "HeightGen"); a_IniFile.SetValue("Generator", "HeightGen", "Biomal"); return CreateHeightGen(a_IniFile, a_BiomeGen, a_Seed, a_CacheOffByDefault); } // Read the settings: res->InitializeHeightGen(a_IniFile); - - return cTerrainHeightGenPtr(res); + + return res; } diff --git a/src/Generating/HeiGen.h b/src/Generating/HeiGen.h index b3c9483fb..62bb227c6 100644 --- a/src/Generating/HeiGen.h +++ b/src/Generating/HeiGen.h @@ -2,10 +2,12 @@ // HeiGen.h /* -Interfaces to the various height generators: +Interfaces to the various height-based terrain shape generators: - cHeiGenFlat - cHeiGenClassic - cHeiGenBiomal + +Also implements the heightmap cache */ @@ -21,26 +23,7 @@ Interfaces to the various height generators: -class cHeiGenFlat : - public cTerrainHeightGen -{ -public: - cHeiGenFlat(void) : m_Height(5) {} - -protected: - - int m_Height; - - // cTerrainHeightGen overrides: - virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; - virtual void InitializeHeightGen(cIniFile & a_IniFile) override; -} ; - - - - - -/// A simple cache that stores N most recently generated chunks' heightmaps; N being settable upon creation +/** A simple cache that stores N most recently generated chunks' heightmaps; N being settable upon creation */ class cHeiGenCache : public cTerrainHeightGen { @@ -50,15 +33,11 @@ public: // cTerrainHeightGen overrides: virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; - virtual void InitializeHeightGen(cIniFile & a_IniFile) override; - /// Retrieves height at the specified point in the cache, returns true if found, false if not found + /** Retrieves height at the specified point in the cache, returns true if found, false if not found */ bool GetHeightAt(int a_ChunkX, int a_ChunkZ, int a_RelX, int a_RelZ, HEIGHTTYPE & a_Height); protected: - - cTerrainHeightGenPtr m_HeiGenToCache; - struct sCacheData { int m_ChunkX; @@ -66,6 +45,9 @@ protected: cChunkDef::HeightMap m_HeightMap; } ; + /** The terrain height generator that is being cached. */ + cTerrainHeightGenPtr m_HeiGenToCache; + // To avoid moving large amounts of data for the MRU behavior, we MRU-ize indices to an array of the actual data int m_CacheSize; int * m_CacheOrder; // MRU-ized order, indices into m_CacheData array @@ -81,6 +63,57 @@ protected: +/** Caches heightmaps in multiple underlying caches to improve the distribution and lower the chain length. */ +class cHeiGenMultiCache: + public cTerrainHeightGen +{ +public: + cHeiGenMultiCache(cTerrainHeightGenPtr a_HeightGenToCache, size_t a_SubCacheSize, size_t a_NumSubCaches); + + // cTerrainHeightGen overrides: + virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; + + /** Retrieves height at the specified point in the cache, returns true if found, false if not found */ + bool GetHeightAt(int a_ChunkX, int a_ChunkZ, int a_RelX, int a_RelZ, HEIGHTTYPE & a_Height); + +protected: + typedef SharedPtr cHeiGenCachePtr; + typedef std::vector cHeiGenCachePtrs; + + + /** The coefficient used to turn Z coords into index (x + Coeff * z). */ + static const size_t m_CoeffZ = 5; + + /** Number of sub-caches, pulled out of m_SubCaches.size() for performance reasons. */ + size_t m_NumSubCaches; + + /** The individual sub-caches. */ + cHeiGenCachePtrs m_SubCaches; +}; + + + + + +class cHeiGenFlat : + public cTerrainHeightGen +{ +public: + cHeiGenFlat(void) : m_Height(5) {} + +protected: + + int m_Height; + + // cTerrainHeightGen overrides: + virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; + virtual void InitializeHeightGen(cIniFile & a_IniFile) override; +} ; + + + + + class cHeiGenClassic : public cTerrainHeightGen { @@ -137,7 +170,11 @@ public: m_BiomeGen(a_BiomeGen) { } - + + // cTerrainHeightGen overrides: + virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; + virtual void InitializeHeightGen(cIniFile & a_IniFile) override; + protected: typedef cChunkDef::BiomeMap BiomeNeighbors[3][3]; @@ -154,11 +191,8 @@ protected: float m_BaseHeight; } ; static const sGenParam m_GenParam[256]; - - // cTerrainHeightGen overrides: - virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; - virtual void InitializeHeightGen(cIniFile & a_IniFile) override; - + + NOISE_DATATYPE GetHeightAt(int a_RelX, int a_RelZ, int a_ChunkX, int a_ChunkZ, const BiomeNeighbors & a_BiomeNeighbors); } ; diff --git a/src/Generating/Noise3DGenerator.cpp b/src/Generating/Noise3DGenerator.cpp index c8f87ec8e..5cf46b873 100644 --- a/src/Generating/Noise3DGenerator.cpp +++ b/src/Generating/Noise3DGenerator.cpp @@ -165,69 +165,6 @@ cNoise3DGenerator::cNoise3DGenerator(cChunkGenerator & a_ChunkGenerator) : m_Cubic.AddOctave(4, 0.25); m_Cubic.AddOctave(8, 0.125); m_Cubic.AddOctave(16, 0.0625); - - #if 0 - // DEBUG: Test the noise generation: - // NOTE: In order to be able to run MCS with this code, you need to increase the default thread stack size - // In MSVC, it is done in Project Settings -> Configuration Properties -> Linker -> System, set Stack reserve size to at least 64M - m_SeaLevel = 62; - m_HeightAmplification = 0; - m_MidPoint = 75; - m_FrequencyX = 4; - m_FrequencyY = 4; - m_FrequencyZ = 4; - m_AirThreshold = 0.5; - - const int NumChunks = 4; - NOISE_DATATYPE Noise[NumChunks][cChunkDef::Width * cChunkDef::Width * cChunkDef::Height]; - for (int x = 0; x < NumChunks; x++) - { - GenerateNoiseArray(x, 5, Noise[x]); - } - - // Save in XY cuts: - cFile f1; - if (f1.Open("Test_XY.grab", cFile::fmWrite)) - { - for (int z = 0; z < cChunkDef::Width; z++) - { - for (int y = 0; y < cChunkDef::Height; y++) - { - for (int i = 0; i < NumChunks; i++) - { - int idx = y * cChunkDef::Width + z * cChunkDef::Width * cChunkDef::Height; - unsigned char buf[cChunkDef::Width]; - for (int x = 0; x < cChunkDef::Width; x++) - { - buf[x] = (unsigned char)(std::min(256, std::max(0, (int)(128 + 32 * Noise[i][idx++])))); - } - f1.Write(buf, cChunkDef::Width); - } - } // for y - } // for z - } // if (XY file open) - - cFile f2; - if (f2.Open("Test_XZ.grab", cFile::fmWrite)) - { - for (int y = 0; y < cChunkDef::Height; y++) - { - for (int z = 0; z < cChunkDef::Width; z++) - { - for (int i = 0; i < NumChunks; i++) - { - int idx = y * cChunkDef::Width + z * cChunkDef::Width * cChunkDef::Height; - unsigned char buf[cChunkDef::Width]; - for (int x = 0; x < cChunkDef::Width; x++) - { - buf[x] = (unsigned char)(std::min(256, std::max(0, (int)(128 + 32 * Noise[i][idx++])))); - } - f2.Write(buf, cChunkDef::Width); - } - } // for z - } // for y - } // if (XZ file open) - #endif // 0 } @@ -246,7 +183,7 @@ cNoise3DGenerator::~cNoise3DGenerator() void cNoise3DGenerator::Initialize(cIniFile & a_IniFile) { // Params: - m_SeaLevel = a_IniFile.GetValueSetI("Generator", "Noise3DSeaLevel", 62); + m_SeaLevel = a_IniFile.GetValueSetI("Generator", "SeaLevel", 62); m_HeightAmplification = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DHeightAmplification", 0.1); m_MidPoint = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DMidPoint", 68); m_FrequencyX = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DFrequencyX", 8); @@ -454,7 +391,6 @@ void cNoise3DComposable::Initialize(cIniFile & a_IniFile) { // Params: // The defaults generate extreme hills terrain - m_SeaLevel = a_IniFile.GetValueSetI("Generator", "Noise3DSeaLevel", 62); m_HeightAmplification = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DHeightAmplification", 0.045); m_MidPoint = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DMidPoint", 75); m_FrequencyX = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DFrequencyX", 40); @@ -522,110 +458,60 @@ void cNoise3DComposable::GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_ChunkZ) NOISE_DATATYPE BaseNoise[5 * 5]; NOISE_DATATYPE BlockX = static_cast(a_ChunkX * cChunkDef::Width); NOISE_DATATYPE BlockZ = static_cast(a_ChunkZ * cChunkDef::Width); - // Note that we have to swap the coords, because noise generator uses [x + SizeX * y + SizeX * SizeY * z] ordering and we want "BlockY" to be "z": - m_ChoiceNoise.Generate3D (ChoiceNoise, 5, 5, 33, BlockX / m_ChoiceFrequencyX, (BlockX + 17) / m_ChoiceFrequencyX, BlockZ / m_ChoiceFrequencyZ, (BlockZ + 17) / m_ChoiceFrequencyZ, 0, 257 / m_ChoiceFrequencyY, Workspace); - m_DensityNoiseA.Generate3D(DensityNoiseA, 5, 5, 33, BlockX / m_FrequencyX, (BlockX + 17) / m_FrequencyX, BlockZ / m_FrequencyZ, (BlockZ + 17) / m_FrequencyZ, 0, 257 / m_FrequencyY, Workspace); - m_DensityNoiseB.Generate3D(DensityNoiseB, 5, 5, 33, BlockX / m_FrequencyX, (BlockX + 17) / m_FrequencyX, BlockZ / m_FrequencyZ, (BlockZ + 17) / m_FrequencyZ, 0, 257 / m_FrequencyY, Workspace); + // Note that we have to swap the X and Y coords, because noise generator uses [x + SizeX * y + SizeX * SizeY * z] ordering and we want "BlockY" to be "x": + m_ChoiceNoise.Generate3D (ChoiceNoise, 33, 5, 5, 0, 257 / m_ChoiceFrequencyY, BlockX / m_ChoiceFrequencyX, (BlockX + 17) / m_ChoiceFrequencyX, BlockZ / m_ChoiceFrequencyZ, (BlockZ + 17) / m_ChoiceFrequencyZ, Workspace); + m_DensityNoiseA.Generate3D(DensityNoiseA, 33, 5, 5, 0, 257 / m_FrequencyY, BlockX / m_FrequencyX, (BlockX + 17) / m_FrequencyX, BlockZ / m_FrequencyZ, (BlockZ + 17) / m_FrequencyZ, Workspace); + m_DensityNoiseB.Generate3D(DensityNoiseB, 33, 5, 5, 0, 257 / m_FrequencyY, BlockX / m_FrequencyX, (BlockX + 17) / m_FrequencyX, BlockZ / m_FrequencyZ, (BlockZ + 17) / m_FrequencyZ, Workspace); m_BaseNoise.Generate2D (BaseNoise, 5, 5, BlockX / m_BaseFrequencyX, (BlockX + 17) / m_BaseFrequencyX, BlockZ / m_FrequencyZ, (BlockZ + 17) / m_FrequencyZ, Workspace); // Calculate the final noise based on the partial noises: - for (int y = 0; y < 33; y++) + for (int z = 0; z < 5; z++) { - NOISE_DATATYPE AddHeight = (static_cast(y * 8) - m_MidPoint) * m_HeightAmplification; - - // If "underground", make the terrain smoother by forcing the vertical linear gradient into steeper slope: - if (AddHeight < 0) - { - AddHeight *= 4; - } - - for (int z = 0; z < 5; z++) + for (int x = 0; x < 5; x++) { - for (int x = 0; x < 5; x++) + NOISE_DATATYPE curBaseNoise = BaseNoise[x + 5 * z]; + for (int y = 0; y < 33; y++) { - int idx = x + 5 * z + 5 * 5 * y; - Workspace[idx] = ClampedLerp(DensityNoiseA[idx], DensityNoiseB[idx], 8 * (ChoiceNoise[idx] + 0.5f)) + AddHeight + BaseNoise[x + 5 * z]; - } - } - } - LinearUpscale3DArray(Workspace, 5, 5, 33, m_NoiseArray, 4, 4, 8); -} + NOISE_DATATYPE AddHeight = (static_cast(y * 8) - m_MidPoint) * m_HeightAmplification; + // If "underground", make the terrain smoother by forcing the vertical linear gradient into steeper slope: + if (AddHeight < 0) + { + AddHeight *= 4; + } - - - -void cNoise3DComposable::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) -{ - GenerateNoiseArrayIfNeeded(a_ChunkX, a_ChunkZ); - - for (int z = 0; z < cChunkDef::Width; z++) - { - for (int x = 0; x < cChunkDef::Width; x++) - { - cChunkDef::SetHeight(a_HeightMap, x, z, m_SeaLevel); - for (int y = cChunkDef::Height - 1; y > m_SeaLevel; y--) - { - if (m_NoiseArray[y * 17 * 17 + z * 17 + x] <= m_AirThreshold) + // If too high, cut off any terrain: + if (y > 28) { - cChunkDef::SetHeight(a_HeightMap, x, z, y); - break; + AddHeight = AddHeight + static_cast(y - 28) / 4; } - } // for y - } // for x - } // for z + + // Decide between the two density noises: + int idx = 33 * x + 33 * 5 * z + y; + Workspace[idx] = ClampedLerp(DensityNoiseA[idx], DensityNoiseB[idx], 8 * (ChoiceNoise[idx] + 0.5f)) + AddHeight + curBaseNoise; + } + } + } + LinearUpscale3DArray(Workspace, 33, 5, 5, m_NoiseArray, 8, 4, 4); } -void cNoise3DComposable::ComposeTerrain(cChunkDesc & a_ChunkDesc) +void cNoise3DComposable::GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape) { - GenerateNoiseArrayIfNeeded(a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ()); - - a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0); + GenerateNoiseArrayIfNeeded(a_ChunkX, a_ChunkZ); - // Make basic terrain composition: + // Translate the noise array into Shape: for (int z = 0; z < cChunkDef::Width; z++) { for (int x = 0; x < cChunkDef::Width; x++) { - int LastAir = a_ChunkDesc.GetHeight(x, z) + 1; - bool HasHadWater = false; - for (int y = LastAir; y < m_SeaLevel; y++) + for (int y = 0; y < cChunkDef::Height; y++) { - a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_STATIONARY_WATER); + a_Shape[y + x * 256 + z * 256 * 16] = (m_NoiseArray[y + 257 * x + 257 * 17 * z] > m_AirThreshold) ? 0 : 1; } - for (int y = LastAir - 1; y > 0; y--) - { - if (m_NoiseArray[x + 17 * z + 17 * 17 * y] > m_AirThreshold) - { - // "air" part - LastAir = y; - if (y < m_SeaLevel) - { - a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_STATIONARY_WATER); - HasHadWater = true; - } - continue; - } - // "ground" part: - if (LastAir - y > 4) - { - a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_STONE); - continue; - } - if (HasHadWater) - { - a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_SAND); - } - else - { - a_ChunkDesc.SetBlockType(x, y, z, (LastAir == y + 1) ? E_BLOCK_GRASS : E_BLOCK_DIRT); - } - } // for y - a_ChunkDesc.SetBlockType(x, 0, z, E_BLOCK_BEDROCK); } // for x } // for z } @@ -650,7 +536,7 @@ cBiomalNoise3DComposable::cBiomalNoise3DComposable(int a_Seed, cBiomeGenPtr a_Bi { for (int x = 0; x <= AVERAGING_SIZE * 2; x++) { - m_Weight[z][x] = static_cast((5 - std::abs(5 - x)) + (5 - std::abs(5 - z))); + m_Weight[z][x] = static_cast((AVERAGING_SIZE - std::abs(AVERAGING_SIZE - x)) + (AVERAGING_SIZE - std::abs(AVERAGING_SIZE - z))); m_WeightSum += m_Weight[z][x]; } } @@ -664,7 +550,7 @@ void cBiomalNoise3DComposable::Initialize(cIniFile & a_IniFile) { // Params: // The defaults generate extreme hills terrain - m_SeaLevel = a_IniFile.GetValueSetI("Generator", "BiomalNoise3DSeaLevel", 62); + m_SeaLevel = a_IniFile.GetValueSetI("Generator", "SeaLevel", 62); m_FrequencyX = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "BiomalNoise3DFrequencyX", 40); m_FrequencyY = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "BiomalNoise3DFrequencyY", 40); m_FrequencyZ = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "BiomalNoise3DFrequencyZ", 40); @@ -735,34 +621,42 @@ void cBiomalNoise3DComposable::GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_Ch NOISE_DATATYPE BaseNoise[5 * 5]; NOISE_DATATYPE BlockX = static_cast(a_ChunkX * cChunkDef::Width); NOISE_DATATYPE BlockZ = static_cast(a_ChunkZ * cChunkDef::Width); - // Note that we have to swap the coords, because noise generator uses [x + SizeX * y + SizeX * SizeY * z] ordering and we want "BlockY" to be "z": - m_ChoiceNoise.Generate3D (ChoiceNoise, 5, 5, 33, BlockX / m_ChoiceFrequencyX, (BlockX + 17) / m_ChoiceFrequencyX, BlockZ / m_ChoiceFrequencyZ, (BlockZ + 17) / m_ChoiceFrequencyZ, 0, 257 / m_ChoiceFrequencyY, Workspace); - m_DensityNoiseA.Generate3D(DensityNoiseA, 5, 5, 33, BlockX / m_FrequencyX, (BlockX + 17) / m_FrequencyX, BlockZ / m_FrequencyZ, (BlockZ + 17) / m_FrequencyZ, 0, 257 / m_FrequencyY, Workspace); - m_DensityNoiseB.Generate3D(DensityNoiseB, 5, 5, 33, BlockX / m_FrequencyX, (BlockX + 17) / m_FrequencyX, BlockZ / m_FrequencyZ, (BlockZ + 17) / m_FrequencyZ, 0, 257 / m_FrequencyY, Workspace); + // Note that we have to swap the X and Y coords, because noise generator uses [x + SizeX * y + SizeX * SizeY * z] ordering and we want "BlockY" to be "x": + m_ChoiceNoise.Generate3D (ChoiceNoise, 33, 5, 5, 0, 257 / m_ChoiceFrequencyY, BlockX / m_ChoiceFrequencyX, (BlockX + 17) / m_ChoiceFrequencyX, BlockZ / m_ChoiceFrequencyZ, (BlockZ + 17) / m_ChoiceFrequencyZ, Workspace); + m_DensityNoiseA.Generate3D(DensityNoiseA, 33, 5, 5, 0, 257 / m_FrequencyY, BlockX / m_FrequencyX, (BlockX + 17) / m_FrequencyX, BlockZ / m_FrequencyZ, (BlockZ + 17) / m_FrequencyZ, Workspace); + m_DensityNoiseB.Generate3D(DensityNoiseB, 33, 5, 5, 0, 257 / m_FrequencyY, BlockX / m_FrequencyX, (BlockX + 17) / m_FrequencyX, BlockZ / m_FrequencyZ, (BlockZ + 17) / m_FrequencyZ, Workspace); m_BaseNoise.Generate2D (BaseNoise, 5, 5, BlockX / m_BaseFrequencyX, (BlockX + 17) / m_BaseFrequencyX, BlockZ / m_FrequencyZ, (BlockZ + 17) / m_FrequencyZ, Workspace); // Calculate the final noise based on the partial noises: - for (int y = 0; y < 33; y++) + for (int z = 0; z < 5; z++) { - NOISE_DATATYPE BlockHeight = static_cast(y * 8); - for (int z = 0; z < 5; z++) + for (int x = 0; x < 5; x++) { - for (int x = 0; x < 5; x++) + NOISE_DATATYPE curMidPoint = MidPoint[x + 5 * z]; + NOISE_DATATYPE curHeightAmp = HeightAmp[x + 5 * z]; + NOISE_DATATYPE curBaseNoise = BaseNoise[x + 5 * z]; + for (int y = 0; y < 33; y++) { - NOISE_DATATYPE AddHeight = (BlockHeight - MidPoint[x + 5 * z]) * HeightAmp[x + 5 * z]; + NOISE_DATATYPE AddHeight = (static_cast(y * 8) - curMidPoint) * curHeightAmp; // If "underground", make the terrain smoother by forcing the vertical linear gradient into steeper slope: if (AddHeight < 0) { AddHeight *= 4; } + // If too high, cut off any terrain: + if (y > 28) + { + AddHeight = AddHeight + static_cast(y - 28) / 4; + } - int idx = x + 5 * z + 5 * 5 * y; - Workspace[idx] = ClampedLerp(DensityNoiseA[idx], DensityNoiseB[idx], 8 * (ChoiceNoise[idx] + 0.5f)) + AddHeight + BaseNoise[x + 5 * z]; + // Decide between the two density noises: + int idx = 33 * x + y + 33 * 5 * z; + Workspace[idx] = ClampedLerp(DensityNoiseA[idx], DensityNoiseB[idx], 8 * (ChoiceNoise[idx] + 0.5f)) + AddHeight + curBaseNoise; } } } - LinearUpscale3DArray(Workspace, 5, 5, 33, m_NoiseArray, 4, 4, 8); + LinearUpscale3DArray(Workspace, 33, 5, 5, m_NoiseArray, 8, 4, 4); } @@ -820,72 +714,67 @@ void cBiomalNoise3DComposable::GetBiomeParams(EMCSBiome a_Biome, NOISE_DATATYPE { switch (a_Biome) { - case biBeach: a_HeightAmp = 0.3f; a_MidPoint = 62; break; - case biBirchForest: a_HeightAmp = 0.1f; a_MidPoint = 64; break; - case biBirchForestHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; - case biBirchForestHillsM: a_HeightAmp = 0.075f; a_MidPoint = 68; break; - case biBirchForestM: a_HeightAmp = 0.1f; a_MidPoint = 64; break; - case biColdBeach: a_HeightAmp = 0.3f; a_MidPoint = 62; break; - case biDesertHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; - case biDeepOcean: a_HeightAmp = 0.17f; a_MidPoint = 35; break; - case biDesert: a_HeightAmp = 0.29f; a_MidPoint = 62; break; - case biEnd: a_HeightAmp = 0.15f; a_MidPoint = 64; break; - case biExtremeHills: a_HeightAmp = 0.045f; a_MidPoint = 75; break; - case biExtremeHillsPlus: a_HeightAmp = 0.04f; a_MidPoint = 80; break; - case biFlowerForest: a_HeightAmp = 0.1f; a_MidPoint = 64; break; - case biForest: a_HeightAmp = 0.1f; a_MidPoint = 64; break; - case biForestHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; - case biFrozenRiver: a_HeightAmp = 0.4f; a_MidPoint = 53; break; - case biFrozenOcean: a_HeightAmp = 0.17f; a_MidPoint = 47; break; - case biIceMountains: a_HeightAmp = 0.075f; a_MidPoint = 68; break; - case biIcePlains: a_HeightAmp = 0.3f; a_MidPoint = 62; break; - case biIcePlainsSpikes: a_HeightAmp = 0.3f; a_MidPoint = 62; break; - case biJungle: a_HeightAmp = 0.1f; a_MidPoint = 63; break; - case biJungleHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; - case biJungleM: a_HeightAmp = 0.1f; a_MidPoint = 63; break; - case biMegaSpruceTaigaHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; - case biMegaTaigaHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; - case biMushroomShore: a_HeightAmp = 0.15f; a_MidPoint = 15; break; - case biOcean: a_HeightAmp = 0.3f; a_MidPoint = 62; break; - case biPlains: a_HeightAmp = 0.3f; a_MidPoint = 62; break; - case biRiver: a_HeightAmp = 0.4f; a_MidPoint = 53; break; - case biSwampland: a_HeightAmp = 0.25f; a_MidPoint = 59; break; - case biSwamplandM: a_HeightAmp = 0.11f; a_MidPoint = 59; break; - case biTaigaHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; - - /* - // Still missing: - case biColdTaiga: a_HeightAmp = 0.15f; a_MidPoint = 30; break; - case biColdTaigaHills: a_HeightAmp = 0.15f; a_MidPoint = 31; break; - case biColdTaigaM: a_HeightAmp = 0.15f; a_MidPoint = 70; break; - case biDesertM: a_HeightAmp = 0.15f; a_MidPoint = 70; break; - case biExtremeHillsEdge: a_HeightAmp = 0.15f; a_MidPoint = 20; break; - case biExtremeHillsM: a_HeightAmp = 0.15f; a_MidPoint = 70; break; - case biExtremeHillsPlusM: a_HeightAmp = 0.15f; a_MidPoint = 70; break; - case biJungleEdge: a_HeightAmp = 0.15f; a_MidPoint = 23; break; - case biJungleEdgeM: a_HeightAmp = 0.15f; a_MidPoint = 70; break; - case biMegaSpruceTaiga: a_HeightAmp = 0.15f; a_MidPoint = 70; break; - case biMegaTaiga: a_HeightAmp = 0.15f; a_MidPoint = 32; break; - case biMesa: a_HeightAmp = 0.15f; a_MidPoint = 37; break; - case biMesaBryce: a_HeightAmp = 0.15f; a_MidPoint = 70; break; - case biMesaPlateau: a_HeightAmp = 0.15f; a_MidPoint = 39; break; - case biMesaPlateauF: a_HeightAmp = 0.15f; a_MidPoint = 38; break; - case biMesaPlateauFM: a_HeightAmp = 0.15f; a_MidPoint = 70; break; - case biMesaPlateauM: a_HeightAmp = 0.15f; a_MidPoint = 70; break; - case biMushroomIsland: a_HeightAmp = 0.15f; a_MidPoint = 14; break; - case biNether: a_HeightAmp = 0.15f; a_MidPoint = 68; break; - case biRoofedForest: a_HeightAmp = 0.15f; a_MidPoint = 29; break; - case biRoofedForestM: a_HeightAmp = 0.15f; a_MidPoint = 70; break; - case biSavanna: a_HeightAmp = 0.15f; a_MidPoint = 35; break; - case biSavannaM: a_HeightAmp = 0.15f; a_MidPoint = 70; break; - case biSavannaPlateau: a_HeightAmp = 0.15f; a_MidPoint = 36; break; - case biSavannaPlateauM: a_HeightAmp = 0.15f; a_MidPoint = 70; break; - case biStoneBeach: a_HeightAmp = 0.15f; a_MidPoint = 25; break; - case biSunflowerPlains: a_HeightAmp = 0.15f; a_MidPoint = 70; break; - case biTaiga: a_HeightAmp = 0.15f; a_MidPoint = 65; break; - case biTaigaM: a_HeightAmp = 0.15f; a_MidPoint = 70; break; - */ - + case biBeach: a_HeightAmp = 0.2f; a_MidPoint = 60; break; + case biBirchForest: a_HeightAmp = 0.1f; a_MidPoint = 64; break; + case biBirchForestHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; + case biBirchForestHillsM: a_HeightAmp = 0.075f; a_MidPoint = 68; break; + case biBirchForestM: a_HeightAmp = 0.1f; a_MidPoint = 64; break; + case biColdBeach: a_HeightAmp = 0.3f; a_MidPoint = 62; break; + case biColdTaiga: a_HeightAmp = 0.1f; a_MidPoint = 64; break; + case biColdTaigaM: a_HeightAmp = 0.1f; a_MidPoint = 64; break; + case biColdTaigaHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; + case biDesertHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; + case biDeepOcean: a_HeightAmp = 0.17f; a_MidPoint = 35; break; + case biDesert: a_HeightAmp = 0.29f; a_MidPoint = 62; break; + case biDesertM: a_HeightAmp = 0.29f; a_MidPoint = 62; break; + case biEnd: a_HeightAmp = 0.15f; a_MidPoint = 64; break; + case biExtremeHills: a_HeightAmp = 0.045f; a_MidPoint = 75; break; + case biExtremeHillsEdge: a_HeightAmp = 0.1f; a_MidPoint = 70; break; + case biExtremeHillsM: a_HeightAmp = 0.045f; a_MidPoint = 75; break; + case biExtremeHillsPlus: a_HeightAmp = 0.04f; a_MidPoint = 80; break; + case biExtremeHillsPlusM: a_HeightAmp = 0.04f; a_MidPoint = 80; break; + case biFlowerForest: a_HeightAmp = 0.1f; a_MidPoint = 64; break; + case biForest: a_HeightAmp = 0.1f; a_MidPoint = 64; break; + case biForestHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; + case biFrozenRiver: a_HeightAmp = 0.4f; a_MidPoint = 57; break; + case biFrozenOcean: a_HeightAmp = 0.12f; a_MidPoint = 45; break; + case biIceMountains: a_HeightAmp = 0.075f; a_MidPoint = 68; break; + case biIcePlains: a_HeightAmp = 0.3f; a_MidPoint = 62; break; + case biIcePlainsSpikes: a_HeightAmp = 0.3f; a_MidPoint = 62; break; + case biJungle: a_HeightAmp = 0.1f; a_MidPoint = 63; break; + case biJungleEdge: a_HeightAmp = 0.15f; a_MidPoint = 62; break; + case biJungleEdgeM: a_HeightAmp = 0.15f; a_MidPoint = 62; break; + case biJungleHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; + case biJungleM: a_HeightAmp = 0.1f; a_MidPoint = 63; break; + case biMegaSpruceTaiga: a_HeightAmp = 0.09f; a_MidPoint = 64; break; + case biMegaSpruceTaigaHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; + case biMegaTaiga: a_HeightAmp = 0.1f; a_MidPoint = 64; break; + case biMegaTaigaHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; + case biMesa: a_HeightAmp = 0.09f; a_MidPoint = 61; break; + case biMesaBryce: a_HeightAmp = 0.15f; a_MidPoint = 61; break; + case biMesaPlateau: a_HeightAmp = 0.25f; a_MidPoint = 86; break; + case biMesaPlateauF: a_HeightAmp = 0.25f; a_MidPoint = 96; break; + case biMesaPlateauFM: a_HeightAmp = 0.25f; a_MidPoint = 96; break; + case biMesaPlateauM: a_HeightAmp = 0.25f; a_MidPoint = 86; break; + case biMushroomShore: a_HeightAmp = 0.075f; a_MidPoint = 60; break; + case biMushroomIsland: a_HeightAmp = 0.06f; a_MidPoint = 80; break; + case biNether: a_HeightAmp = 0.01f; a_MidPoint = 64; break; + case biOcean: a_HeightAmp = 0.12f; a_MidPoint = 45; break; + case biPlains: a_HeightAmp = 0.3f; a_MidPoint = 62; break; + case biRiver: a_HeightAmp = 0.4f; a_MidPoint = 57; break; + case biRoofedForest: a_HeightAmp = 0.1f; a_MidPoint = 64; break; + case biRoofedForestM: a_HeightAmp = 0.1f; a_MidPoint = 64; break; + case biSavanna: a_HeightAmp = 0.3f; a_MidPoint = 62; break; + case biSavannaM: a_HeightAmp = 0.3f; a_MidPoint = 62; break; + case biSavannaPlateau: a_HeightAmp = 0.3f; a_MidPoint = 85; break; + case biSavannaPlateauM: a_HeightAmp = 0.012f; a_MidPoint = 105; break; + case biStoneBeach: a_HeightAmp = 0.075f; a_MidPoint = 60; break; + case biSunflowerPlains: a_HeightAmp = 0.3f; a_MidPoint = 62; break; + case biSwampland: a_HeightAmp = 0.25f; a_MidPoint = 59; break; + case biSwamplandM: a_HeightAmp = 0.11f; a_MidPoint = 59; break; + case biTaiga: a_HeightAmp = 0.1f; a_MidPoint = 64; break; + case biTaigaM: a_HeightAmp = 0.1f; a_MidPoint = 70; break; + case biTaigaHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; default: { // Make a crazy terrain so that it stands out @@ -899,78 +788,19 @@ void cBiomalNoise3DComposable::GetBiomeParams(EMCSBiome a_Biome, NOISE_DATATYPE - -void cBiomalNoise3DComposable::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) +void cBiomalNoise3DComposable::GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape) { GenerateNoiseArrayIfNeeded(a_ChunkX, a_ChunkZ); + // Translate the noise array into Shape: for (int z = 0; z < cChunkDef::Width; z++) { for (int x = 0; x < cChunkDef::Width; x++) { - cChunkDef::SetHeight(a_HeightMap, x, z, m_SeaLevel); - for (int y = cChunkDef::Height - 1; y > m_SeaLevel; y--) - { - if (m_NoiseArray[y * 17 * 17 + z * 17 + x] <= m_AirThreshold) - { - cChunkDef::SetHeight(a_HeightMap, x, z, y); - break; - } - } // for y - } // for x - } // for z -} - - - - - -void cBiomalNoise3DComposable::ComposeTerrain(cChunkDesc & a_ChunkDesc) -{ - GenerateNoiseArrayIfNeeded(a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ()); - - a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0); - - // Make basic terrain composition: - for (int z = 0; z < cChunkDef::Width; z++) - { - for (int x = 0; x < cChunkDef::Width; x++) - { - int LastAir = a_ChunkDesc.GetHeight(x, z) + 1; - bool HasHadWater = false; - for (int y = LastAir; y < m_SeaLevel; y++) + for (int y = 0; y < cChunkDef::Height; y++) { - a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_STATIONARY_WATER); + a_Shape[y + x * 256 + z * 256 * 16] = (m_NoiseArray[y + 257 * x + 257 * 17 * z] > m_AirThreshold) ? 0 : 1; } - for (int y = LastAir - 1; y > 0; y--) - { - if (m_NoiseArray[x + 17 * z + 17 * 17 * y] > m_AirThreshold) - { - // "air" part - LastAir = y; - if (y < m_SeaLevel) - { - a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_STATIONARY_WATER); - HasHadWater = true; - } - continue; - } - // "ground" part: - if (LastAir - y > 4) - { - a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_STONE); - continue; - } - if (HasHadWater) - { - a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_SAND); - } - else - { - a_ChunkDesc.SetBlockType(x, y, z, (LastAir == y + 1) ? E_BLOCK_GRASS : E_BLOCK_DIRT); - } - } // for y - a_ChunkDesc.SetBlockType(x, 0, z, E_BLOCK_BEDROCK); } // for x } // for z } @@ -978,3 +808,4 @@ void cBiomalNoise3DComposable::ComposeTerrain(cChunkDesc & a_ChunkDesc) + diff --git a/src/Generating/Noise3DGenerator.h b/src/Generating/Noise3DGenerator.h index 07767ba84..35b1e4c94 100644 --- a/src/Generating/Noise3DGenerator.h +++ b/src/Generating/Noise3DGenerator.h @@ -73,8 +73,7 @@ protected: class cNoise3DComposable : - public cTerrainHeightGen, - public cTerrainCompositionGen + public cTerrainShapeGen { public: cNoise3DComposable(int a_Seed); @@ -82,21 +81,18 @@ public: void Initialize(cIniFile & a_IniFile); protected: - /** The noise that is used to choose between density noise A and B. */ - cPerlinNoise m_ChoiceNoise; + /** The 3D noise that is used to choose between density noise A and B. */ + cOctavedNoise> m_ChoiceNoise; /** Density 3D noise, variant A. */ - cPerlinNoise m_DensityNoiseA; + cOctavedNoise> m_DensityNoiseA; /** Density 3D noise, variant B. */ - cPerlinNoise m_DensityNoiseB; + cOctavedNoise> m_DensityNoiseB; /** Heightmap-like noise used to provide variance for low-amplitude biomes. */ - cPerlinNoise m_BaseNoise; + cOctavedNoise> m_BaseNoise; - /** Block height of the sealevel, used for composing the terrain. */ - int m_SeaLevel; - /** The main parameter of the generator, specifies the slope of the vertical linear gradient. A higher value means a steeper slope and a smaller total amplitude of the generated terrain. */ NOISE_DATATYPE m_HeightAmplification; @@ -131,12 +127,8 @@ protected: void GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_ChunkZ); // cTerrainHeightGen overrides: - virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; - virtual void InitializeHeightGen(cIniFile & a_IniFile) override { Initialize(a_IniFile); } - - // cTerrainCompositionGen overrides: - virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc) override; - virtual void InitializeCompoGen(cIniFile & a_IniFile) override { Initialize(a_IniFile); } + virtual void GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape) override; + virtual void InitializeShapeGen(cIniFile & a_IniFile) override { Initialize(a_IniFile); } } ; @@ -144,8 +136,7 @@ protected: class cBiomalNoise3DComposable : - public cTerrainHeightGen, - public cTerrainCompositionGen + public cTerrainShapeGen { public: cBiomalNoise3DComposable(int a_Seed, cBiomeGenPtr a_BiomeGen); @@ -153,24 +144,24 @@ public: void Initialize(cIniFile & a_IniFile); protected: - /** Number of columns around the pixel to query for biomes for averaging. */ - static const int AVERAGING_SIZE = 5; + /** Number of columns around the pixel to query for biomes for averaging. Must be less than or equal to 16. */ + static const int AVERAGING_SIZE = 9; /** Type used for a single parameter across the entire (downscaled) chunk. */ typedef NOISE_DATATYPE ChunkParam[5 * 5]; /** The noise that is used to choose between density noise A and B. */ - cPerlinNoise m_ChoiceNoise; + cOctavedNoise> m_ChoiceNoise; /** Density 3D noise, variant A. */ - cPerlinNoise m_DensityNoiseA; + cOctavedNoise> m_DensityNoiseA; /** Density 3D noise, variant B. */ - cPerlinNoise m_DensityNoiseB; + cOctavedNoise> m_DensityNoiseB; /** Heightmap-like noise used to provide variance for low-amplitude biomes. */ - cPerlinNoise m_BaseNoise; + cOctavedNoise> m_BaseNoise; /** The underlying biome generator. */ cBiomeGenPtr m_BiomeGen; @@ -198,7 +189,7 @@ protected: // Cache for the last calculated chunk (reused between heightmap and composition queries): int m_LastChunkX; int m_LastChunkZ; - NOISE_DATATYPE m_NoiseArray[17 * 17 * 257]; // x + 17 * z + 17 * 17 * y + NOISE_DATATYPE m_NoiseArray[17 * 17 * 257]; // 257 * x + y + 257 * 17 * z /** Weights for summing up neighboring biomes. */ NOISE_DATATYPE m_Weight[AVERAGING_SIZE * 2 + 1][AVERAGING_SIZE * 2 + 1]; @@ -216,13 +207,9 @@ protected: /** Returns the parameters for the specified biome. */ void GetBiomeParams(EMCSBiome a_Biome, NOISE_DATATYPE & a_HeightAmp, NOISE_DATATYPE & a_MidPoint); - // cTerrainHeightGen overrides: - virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; - virtual void InitializeHeightGen(cIniFile & a_IniFile) override { Initialize(a_IniFile); } - - // cTerrainCompositionGen overrides: - virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc) override; - virtual void InitializeCompoGen(cIniFile & a_IniFile) override { Initialize(a_IniFile); } + // cTerrainShapeGen overrides: + virtual void GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape) override; + virtual void InitializeShapeGen(cIniFile & a_IniFile) override { Initialize(a_IniFile); } } ; diff --git a/src/Generating/ShapeGen.cpp b/src/Generating/ShapeGen.cpp new file mode 100644 index 000000000..45a9c3b93 --- /dev/null +++ b/src/Generating/ShapeGen.cpp @@ -0,0 +1,145 @@ + +// ShapeGen.cpp + +// Implements the function to create a cTerrainShapeGen descendant based on INI file settings + +#include "Globals.h" +#include "HeiGen.h" +#include "../IniFile.h" +#include "DistortedHeightmap.h" +#include "EndGen.h" +#include "Noise3DGenerator.h" +#include "TwoHeights.h" + + + + + +//////////////////////////////////////////////////////////////////////////////// +// cTerrainHeightToShapeGen: + +/** Converts old-style height-generators into new-style shape-generators. */ +class cTerrainHeightToShapeGen: + public cTerrainShapeGen +{ +public: + cTerrainHeightToShapeGen(cTerrainHeightGenPtr a_HeightGen): + m_HeightGen(a_HeightGen) + { + } + + + // cTerrainShapeGen overrides: + virtual void GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape) override + { + // Generate the heightmap: + cChunkDef::HeightMap heightMap; + m_HeightGen->GenHeightMap(a_ChunkX, a_ChunkZ, heightMap); + + // Convert from heightmap to shape: + for (int z = 0; z < cChunkDef::Width; z++) + { + for (int x = 0; x < cChunkDef::Width; x++) + { + HEIGHTTYPE height = cChunkDef::GetHeight(heightMap, x, z) + 1; + Byte * shapeColumn = &(a_Shape[(x + 16 * z) * 256]); + for (int y = 0; y < height; y++) + { + shapeColumn[y] = 1; + } + for (int y = height; y < cChunkDef::Height; y++) + { + shapeColumn[y] = 0; + } + } // for x + } // for z + } + + + virtual void InitializeShapeGen(cIniFile & a_IniFile) override + { + m_HeightGen->InitializeHeightGen(a_IniFile); + } + +protected: + /** The height generator being converted. */ + cTerrainHeightGenPtr m_HeightGen; +}; + +typedef SharedPtr cTerrainHeightToShapeGenPtr; + + + + + +//////////////////////////////////////////////////////////////////////////////// +// cTerrainShapeGen: + +cTerrainShapeGenPtr cTerrainShapeGen::CreateShapeGen(cIniFile & a_IniFile, cBiomeGenPtr a_BiomeGen, int a_Seed, bool & a_CacheOffByDefault) +{ + AString shapeGenName = a_IniFile.GetValueSet("Generator", "ShapeGen", ""); + if (shapeGenName.empty()) + { + LOGWARN("[Generator] ShapeGen value not set in world.ini, using \"BiomalNoise3D\"."); + shapeGenName = "BiomalNoise3D"; + } + + // If the shapegen is HeightMap, redirect to older HeightMap-based generators: + if (NoCaseCompare(shapeGenName, "HeightMap") == 0) + { + cTerrainHeightGenPtr heightGen = cTerrainHeightGen::CreateHeightGen(a_IniFile, a_BiomeGen, a_Seed, a_CacheOffByDefault); + if (heightGen != nullptr) + { + return std::make_shared(heightGen); + } + + // The height gen was not recognized; several heightgens were promoted to shape gens, so let's try them instead: + shapeGenName = a_IniFile.GetValue("Generator", "HeightGen", ""); + if (shapeGenName.empty()) + { + LOGWARNING("[Generator] ShapeGen set to HeightMap, but HeightGen not set. Reverting to \"BiomalNoise3D\"."); + shapeGenName = "BiomalNoise3D"; + a_IniFile.SetValue("Generator", "ShapeGen", shapeGenName); + } + } + + // Choose the shape generator based on the name: + a_CacheOffByDefault = false; + cTerrainShapeGenPtr res; + if (NoCaseCompare(shapeGenName, "DistortedHeightmap") == 0) + { + res = std::make_shared(a_Seed, a_BiomeGen); + } + else if (NoCaseCompare(shapeGenName, "End") == 0) + { + res = std::make_shared(a_Seed); + } + else if (NoCaseCompare(shapeGenName, "BiomalNoise3D") == 0) + { + res = std::make_shared(a_Seed, a_BiomeGen); + } + else if (NoCaseCompare(shapeGenName, "Noise3D") == 0) + { + res = std::make_shared(a_Seed); + } + else if (NoCaseCompare(shapeGenName, "TwoHeights") == 0) + { + res = CreateShapeGenTwoHeights(a_Seed, a_BiomeGen); + } + else + { + // No match found, force-set the default and retry + LOGWARN("Unknown ShapeGen \"%s\", using \"BiomalNoise3D\" instead.", shapeGenName.c_str()); + a_IniFile.SetValue("Generator", "ShapeGen", "BiomalNoise3D"); + return CreateShapeGen(a_IniFile, a_BiomeGen, a_Seed, a_CacheOffByDefault); + } + + // Read the settings: + res->InitializeShapeGen(a_IniFile); + + return res; +} + + + + diff --git a/src/Generating/StructGen.cpp b/src/Generating/StructGen.cpp index bdefcd8c1..2f685c808 100644 --- a/src/Generating/StructGen.cpp +++ b/src/Generating/StructGen.cpp @@ -37,10 +37,13 @@ void cStructGenTrees::GenFinish(cChunkDesc & a_ChunkDesc) Dest = &WorkerDesc; WorkerDesc.SetChunkCoords(BaseX, BaseZ); + // TODO: This may cause a lot of wasted calculations, instead of pulling data out of a single (cChunkDesc) cache + + cChunkDesc::Shape workerShape; m_BiomeGen->GenBiomes (BaseX, BaseZ, WorkerDesc.GetBiomeMap()); - m_HeightGen->GenHeightMap (BaseX, BaseZ, WorkerDesc.GetHeightMap()); - m_CompositionGen->ComposeTerrain(WorkerDesc); - // TODO: Free the entity lists + m_ShapeGen->GenShape (BaseX, BaseZ, workerShape); + WorkerDesc.SetHeightFromShape (workerShape); + m_CompositionGen->ComposeTerrain(WorkerDesc, workerShape); } else { @@ -97,7 +100,7 @@ void cStructGenTrees::GenerateSingleTree( int Height = a_ChunkDesc.GetHeight(x, z); - if ((Height <= 0) || (Height > 240)) + if ((Height <= 0) || (Height >= 230)) { return; } @@ -125,6 +128,11 @@ void cStructGenTrees::GenerateSingleTree( // Outside the chunk continue; } + if (itr->y >= cChunkDef::Height) + { + // Above the chunk, cut off (this shouldn't happen too often, we're limiting trees to y < 230) + continue; + } BLOCKTYPE Block = a_ChunkDesc.GetBlockType(itr->x, itr->y, itr->z); switch (Block) @@ -159,7 +167,7 @@ void cStructGenTrees::ApplyTreeImage( // Put the generated image into a_BlockTypes, push things outside this chunk into a_Blocks for (sSetBlockVector::const_iterator itr = a_Image.begin(), end = a_Image.end(); itr != end; ++itr) { - if ((itr->ChunkX == a_ChunkX) && (itr->ChunkZ == a_ChunkZ)) + if ((itr->ChunkX == a_ChunkX) && (itr->ChunkZ == a_ChunkZ) && (itr->y < cChunkDef::Height)) { // Inside this chunk, integrate into a_ChunkDesc: switch (a_ChunkDesc.GetBlockType(itr->x, itr->y, itr->z)) @@ -390,7 +398,7 @@ void cStructGenLakes::GenFinish(cChunkDesc & a_ChunkDesc) } cBlockArea Lake; - CreateLakeImage(ChunkX + x, ChunkZ + z, Lake); + CreateLakeImage(ChunkX + x, ChunkZ + z, a_ChunkDesc.GetMinHeight(), Lake); int OfsX = Lake.GetOriginX() + x * cChunkDef::Width; int OfsZ = Lake.GetOriginZ() + z * cChunkDef::Width; @@ -404,25 +412,13 @@ void cStructGenLakes::GenFinish(cChunkDesc & a_ChunkDesc) -void cStructGenLakes::CreateLakeImage(int a_ChunkX, int a_ChunkZ, cBlockArea & a_Lake) +void cStructGenLakes::CreateLakeImage(int a_ChunkX, int a_ChunkZ, int a_MaxLakeHeight, cBlockArea & a_Lake) { a_Lake.Create(16, 8, 16); a_Lake.Fill(cBlockArea::baTypes, E_BLOCK_SPONGE); // Sponge is the NOP blocktype for lake merging strategy - // Find the minimum height in this chunk: - cChunkDef::HeightMap HeightMap; - m_HeiGen->GenHeightMap(a_ChunkX, a_ChunkZ, HeightMap); - HEIGHTTYPE MinHeight = HeightMap[0]; - for (size_t i = 1; i < ARRAYCOUNT(HeightMap); i++) - { - if (HeightMap[i] < MinHeight) - { - MinHeight = HeightMap[i]; - } - } - // Make a random position in the chunk by using a random 16 block XZ offset and random height up to chunk's max height minus 6 - MinHeight = std::max(MinHeight - 6, 2); + int MinHeight = std::max(a_MaxLakeHeight - 6, 2); int Rnd = m_Noise.IntNoise3DInt(a_ChunkX, 128, a_ChunkZ) / 11; // Random offset [-8 .. 8], with higher probability around 0; add up four three-bit-wide randoms [0 .. 28], divide and subtract to get range int OffsetX = 4 * ((Rnd & 0x07) + ((Rnd & 0x38) >> 3) + ((Rnd & 0x1c0) >> 6) + ((Rnd & 0xe00) >> 9)) / 7 - 8; diff --git a/src/Generating/StructGen.h b/src/Generating/StructGen.h index d3b0b5544..796abf0f5 100644 --- a/src/Generating/StructGen.h +++ b/src/Generating/StructGen.h @@ -24,11 +24,11 @@ class cStructGenTrees : public cFinishGen { public: - cStructGenTrees(int a_Seed, cBiomeGenPtr a_BiomeGen, cTerrainHeightGenPtr a_HeightGen, cTerrainCompositionGenPtr a_CompositionGen) : + cStructGenTrees(int a_Seed, cBiomeGenPtr a_BiomeGen, cTerrainShapeGenPtr a_ShapeGen, cTerrainCompositionGenPtr a_CompositionGen) : m_Seed(a_Seed), m_Noise(a_Seed), m_BiomeGen(a_BiomeGen), - m_HeightGen(a_HeightGen), + m_ShapeGen(a_ShapeGen), m_CompositionGen(a_CompositionGen) {} @@ -37,12 +37,12 @@ protected: int m_Seed; cNoise m_Noise; cBiomeGenPtr m_BiomeGen; - cTerrainHeightGenPtr m_HeightGen; + cTerrainShapeGenPtr m_ShapeGen; cTerrainCompositionGenPtr m_CompositionGen; /** Generates and applies an image of a single tree. - Parts of the tree inside the chunk are applied to a_BlockX. - Parts of the tree outside the chunk are stored in a_OutsideX + Parts of the tree inside the chunk are applied to a_ChunkDesc. + Parts of the tree outside the chunk are stored in a_OutsideXYZ */ void GenerateSingleTree( int a_ChunkX, int a_ChunkZ, int a_Seq, @@ -51,7 +51,7 @@ protected: sSetBlockVector & a_OutsideOther ) ; - /// Applies an image into chunk blockdata; all blocks outside the chunk will be appended to a_Overflow + /** Applies an image into chunk blockdata; all blocks outside the chunk will be appended to a_Overflow. */ void ApplyTreeImage( int a_ChunkX, int a_ChunkZ, cChunkDesc & a_ChunkDesc, @@ -124,27 +124,30 @@ class cStructGenLakes : public cFinishGen { public: - cStructGenLakes(int a_Seed, BLOCKTYPE a_Fluid, cTerrainHeightGenPtr a_HeiGen, int a_Probability) : + cStructGenLakes(int a_Seed, BLOCKTYPE a_Fluid, cTerrainShapeGenPtr a_ShapeGen, int a_Probability) : m_Noise(a_Seed), m_Seed(a_Seed), m_Fluid(a_Fluid), - m_HeiGen(a_HeiGen), + m_ShapeGen(a_ShapeGen), m_Probability(a_Probability) { } protected: - cNoise m_Noise; - int m_Seed; - BLOCKTYPE m_Fluid; - cTerrainHeightGenPtr m_HeiGen; - int m_Probability; ///< Chance, 0 .. 100, of a chunk having the lake + cNoise m_Noise; + int m_Seed; + BLOCKTYPE m_Fluid; + cTerrainShapeGenPtr m_ShapeGen; + + /** Chance, [0 .. 100], of a chunk having the lake. */ + int m_Probability; + // cFinishGen override: virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; - /// Creates a lake image for the specified chunk into a_Lake - void CreateLakeImage(int a_ChunkX, int a_ChunkZ, cBlockArea & a_Lake); + /** Creates a lake image for the specified chunk into a_Lake. */ + void CreateLakeImage(int a_ChunkX, int a_ChunkZ, int a_MaxLakeHeight, cBlockArea & a_Lake); } ; diff --git a/src/Generating/TwoHeights.cpp b/src/Generating/TwoHeights.cpp new file mode 100644 index 000000000..e75c301de --- /dev/null +++ b/src/Generating/TwoHeights.cpp @@ -0,0 +1,121 @@ + +// TwoHeights.cpp + +// Implements the cTwoHeights class representing the terrain shape generator using two switched heightmaps + +#include "Globals.h" +#include "TwoHeights.h" +#include "../Noise/InterpolNoise.h" +#include "HeiGen.h" +#include "../LinearUpscale.h" +#include "../IniFile.h" + + + + + +class cTwoHeights: + public cTerrainShapeGen +{ + typedef cTerrainShapeGen super; +public: + cTwoHeights(int a_Seed, cBiomeGenPtr a_BiomeGen): + m_Seed(a_Seed), + m_Choice(a_Seed), + m_HeightA(a_Seed + 1, a_BiomeGen), + m_HeightB(a_Seed + 2, a_BiomeGen) + { + } + + + // cTerrainShapeGen override: + virtual void GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape) override + { + // Generate the two heightmaps: + cChunkDef::HeightMap heightsA; + cChunkDef::HeightMap heightsB; + m_HeightA.GenHeightMap(a_ChunkX, a_ChunkZ, heightsA); + m_HeightB.GenHeightMap(a_ChunkX, a_ChunkZ, heightsB); + + // Generate the choice noise: + NOISE_DATATYPE smallChoice[33 * 5 * 5]; + NOISE_DATATYPE workspace[33 * 5 * 5]; + NOISE_DATATYPE startX = 0; + NOISE_DATATYPE endX = 256 * m_FrequencyY; + NOISE_DATATYPE startY = a_ChunkX * cChunkDef::Width * m_FrequencyX; + NOISE_DATATYPE endY = (a_ChunkX * cChunkDef::Width + cChunkDef::Width + 1) * m_FrequencyX; + NOISE_DATATYPE startZ = a_ChunkZ * cChunkDef::Width * m_FrequencyZ; + NOISE_DATATYPE endZ = (a_ChunkZ * cChunkDef::Width + cChunkDef::Width + 1) * m_FrequencyZ; + m_Choice.Generate3D(smallChoice, 33, 5, 5, startX, endX, startY, endY, startZ, endZ, workspace); + NOISE_DATATYPE choice[257 * 17 * 17]; + LinearUpscale3DArray(smallChoice, 33, 5, 5, choice, 8, 4, 4); + + // Generate the shape: + int idxShape = 0; + for (int z = 0; z < cChunkDef::Width; z++) + { + for (int x = 0; x < cChunkDef::Width; x++) + { + int idxChoice = 257 * 17 * z + 257 * x; + NOISE_DATATYPE heightA = static_cast(cChunkDef::GetHeight(heightsA, x, z)); + NOISE_DATATYPE heightB = static_cast(cChunkDef::GetHeight(heightsB, x, z)); + for (int y = 0; y < cChunkDef::Height; y++) + { + int height = static_cast(ClampedLerp(heightA, heightB, choice[idxChoice++])); + a_Shape[idxShape++] = (y < height) ? 1 : 0; + } + } // for x + } // for z + } + + + virtual void InitializeShapeGen(cIniFile & a_IniFile) + { + m_FrequencyX = static_cast(a_IniFile.GetValueSetF("Generator", "TwoHeightsFrequencyX", 40)); + m_FrequencyY = static_cast(a_IniFile.GetValueSetF("Generator", "TwoHeightsFrequencyY", 40)); + m_FrequencyZ = static_cast(a_IniFile.GetValueSetF("Generator", "TwoHeightsFrequencyZ", 40)); + + // Initialize the two underlying height generators from an empty INI file: + cIniFile empty; + m_HeightA.InitializeHeightGen(empty); + m_HeightB.InitializeHeightGen(empty); + + // Add the choice octaves: + NOISE_DATATYPE freq = 0.001f; + NOISE_DATATYPE ampl = 1; + for (int i = 0; i < 4; i++) + { + m_Choice.AddOctave(freq, ampl); + freq = freq * 2; + ampl = ampl / 2; + } + } + +protected: + int m_Seed; + + /** The noise used to decide between the two heightmaps. */ + cOctavedNoise> m_Choice; + + /** The first height generator. */ + cHeiGenBiomal m_HeightA; + + /** The second height generator. */ + cHeiGenBiomal m_HeightB; + + /** The base frequencies for m_Choice in each of the world axis directions. */ + NOISE_DATATYPE m_FrequencyX, m_FrequencyY, m_FrequencyZ; +}; + + + + + +cTerrainShapeGenPtr CreateShapeGenTwoHeights(int a_Seed, cBiomeGenPtr a_BiomeGen) +{ + return std::make_shared(a_Seed, a_BiomeGen); +} + + + + diff --git a/src/Generating/TwoHeights.h b/src/Generating/TwoHeights.h new file mode 100644 index 000000000..353598011 --- /dev/null +++ b/src/Generating/TwoHeights.h @@ -0,0 +1,23 @@ + +// TwoHeights.h + +// Declares the function to create a new instance of the cTwoHeights terrain shape generator + + + + + +#pragma once + +#include "ComposableGenerator.h" + + + + +/** Creates and returns a new instance of the cTwoHeights terrain shape generator. +The instance must be Initialize()-d before it is used. */ +extern cTerrainShapeGenPtr CreateShapeGenTwoHeights(int a_Seed, cBiomeGenPtr a_BiomeGen); + + + + diff --git a/src/Generating/VillageGen.cpp b/src/Generating/VillageGen.cpp index a9b359b6a..f7d9a8316 100644 --- a/src/Generating/VillageGen.cpp +++ b/src/Generating/VillageGen.cpp @@ -18,8 +18,8 @@ /* How village generating works: -By descending from a cGridStructGen, a semi-random grid is generated. A village may be generated for each of -the grid's cells. Each cell checks the biomes in an entire chunk around it, only generating a village if all +By descending from a cGridStructGen, a semi-random (jitter) grid is generated. A village may be generated for each +of the grid's cells. Each cell checks the biomes in an entire chunk around it, only generating a village if all biomes are village-friendly. If yes, the entire village structure is built for that cell. If not, the cell is left village-less. @@ -125,7 +125,7 @@ public: m_Noise(a_Seed), m_MaxSize(a_MaxSize), m_Density(a_Density), - m_Borders(a_OriginX - a_MaxSize, 0, a_OriginZ - a_MaxSize, a_OriginX + a_MaxSize, 255, a_OriginZ + a_MaxSize), + m_Borders(a_OriginX - a_MaxSize, 0, a_OriginZ - a_MaxSize, a_OriginX + a_MaxSize, cChunkDef::Height - 1, a_OriginZ + a_MaxSize), m_Prefabs(a_Prefabs), m_HeightGen(a_HeightGen), m_RoadBlock(a_RoadBlock), diff --git a/src/Globals.h b/src/Globals.h index a64be8d54..fcadc3269 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -184,9 +184,9 @@ template class SizeChecker; // OS-dependent stuff: #ifdef _WIN32 - #define WIN32_LEAN_AND_MEAN - #define _WIN32_WINNT_WS03 // We want to target Windows XP with Service Pack 2 & Windows Server 2003 with Service Pack 1 and higher + #define WIN32_LEAN_AND_MEAN + #define _WIN32_WINNT _WIN32_WINNT_WS03 // We want to target Windows XP with Service Pack 2 & Windows Server 2003 with Service Pack 1 and higher #include #include diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index bcdc404c2..4f8afa0de 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -159,7 +159,7 @@ void cMonster::TickPathFinding() BLOCKTYPE BlockAtYP = m_World->GetBlock(gCrossCoords[i].x + PosX, PosY + 1, gCrossCoords[i].z + PosZ); BLOCKTYPE BlockAtYPP = m_World->GetBlock(gCrossCoords[i].x + PosX, PosY + 2, gCrossCoords[i].z + PosZ); int LowestY = FindFirstNonAirBlockPosition(gCrossCoords[i].x + PosX, gCrossCoords[i].z + PosZ); - BLOCKTYPE BlockAtLowestY = m_World->GetBlock(gCrossCoords[i].x + PosX, LowestY, gCrossCoords[i].z + PosZ); + BLOCKTYPE BlockAtLowestY = (LowestY >= cChunkDef::Height) ? E_BLOCK_AIR : m_World->GetBlock(gCrossCoords[i].x + PosX, LowestY, gCrossCoords[i].z + PosZ); if ( (!cBlockInfo::IsSolid(BlockAtY)) && @@ -452,7 +452,7 @@ int cMonster::FindFirstNonAirBlockPosition(double a_PosX, double a_PosZ) } else { - while (cBlockInfo::IsSolid(m_World->GetBlock((int)floor(a_PosX), PosY, (int)floor(a_PosZ))) && (PosY < cChunkDef::Height)) + while ((PosY < cChunkDef::Height) && cBlockInfo::IsSolid(m_World->GetBlock((int)floor(a_PosX), PosY, (int)floor(a_PosZ)))) { PosY++; } diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h index f5ae2cb4d..e5dcb0309 100644 --- a/src/Mobs/Monster.h +++ b/src/Mobs/Monster.h @@ -169,10 +169,12 @@ protected: /** Stores if mobile is currently moving towards the ultimate, final destination */ bool m_bMovingToDestination; - /** Finds the first non-air block position (not the highest, as cWorld::GetHeight does) - If current Y is nonsolid, goes down to try to find a solid block, then returns that + 1 - If current Y is solid, goes up to find first nonsolid block, and returns that */ + /** Finds the lowest non-air block position (not the highest, as cWorld::GetHeight does) + If current Y is nonsolid, goes down to try to find a solid block, then returns that + 1 + If current Y is solid, goes up to find first nonsolid block, and returns that. + If no suitable position is found, returns cChunkDef::Height. */ int FindFirstNonAirBlockPosition(double a_PosX, double a_PosZ); + /** Returns if a monster can actually reach a given height by jumping or walking */ inline bool IsNextYPosReachable(int a_PosY) { diff --git a/src/World.cpp b/src/World.cpp index 09fb90a12..1602de4bb 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -72,99 +72,130 @@ const int TIME_SPAWN_DIVISOR = 148; //////////////////////////////////////////////////////////////////////////////// -// cWorldLoadProgress: +// cSpawnPrepare: -/// A simple thread that displays the progress of world loading / saving in cWorld::InitializeSpawn() -class cWorldLoadProgress : - public cIsThread +/** Generates and lights the spawn area of the world. Runs as a separate thread. */ +class cSpawnPrepare: + public cIsThread, + public cChunkCoordCallback { + typedef cIsThread super; + public: - cWorldLoadProgress(cWorld * a_World) : - cIsThread("cWorldLoadProgress"), - m_World(a_World) - { + cSpawnPrepare(cWorld & a_World, int a_SpawnChunkX, int a_SpawnChunkZ, int a_PrepareDistance): + super("SpawnPrepare"), + m_World(a_World), + m_SpawnChunkX(a_SpawnChunkX), + m_SpawnChunkZ(a_SpawnChunkZ), + m_PrepareDistance(a_PrepareDistance), + m_MaxIdx(a_PrepareDistance * a_PrepareDistance), + m_NumPrepared(0), + m_LastReportChunkCount(0) + { + // Start the thread: Start(); + + // Wait for start confirmation, so that the thread can be waited-upon after the constructor returns: + m_EvtStarted.Wait(); } - - void Stop(void) - { - m_ShouldTerminate = true; - Wait(); - } - -protected: - cWorld * m_World; - + + // cIsThread override: virtual void Execute(void) override { - for (;;) + // Confirm thread start: + m_EvtStarted.Set(); + + // Queue the initial chunks: + m_MaxIdx = m_PrepareDistance * m_PrepareDistance; + int maxQueue = std::min(m_MaxIdx - 1, 100); // Number of chunks to queue at once + m_NextIdx = maxQueue; + m_LastReportTime = std::chrono::steady_clock::now(); + for (int i = 0; i < maxQueue; i++) { - LOG("" SIZE_T_FMT " chunks to load, %d chunks to generate", - m_World->GetStorage().GetLoadQueueLength(), - m_World->GetGenerator().GetQueueLength() - ); - - // Wait for 2 sec, but be "reasonably wakeable" when the thread is to finish - for (int i = 0; i < 20; i++) - { - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - if (m_ShouldTerminate) - { - return; - } - } - } // for (-ever) + int chunkX, chunkZ; + DecodeChunkCoords(i, chunkX, chunkZ); + m_World.GetLightingThread().QueueChunk(chunkX, chunkZ, this); + } // for i + + // Wait for the lighting thread to prepare everything. Event is set in the Call() callback: + m_EvtFinished.Wait(); } - -} ; +protected: + cWorld & m_World; + int m_SpawnChunkX; + int m_SpawnChunkZ; + int m_PrepareDistance; + /** The index of the next chunk to be queued in the lighting thread. */ + int m_NextIdx; + /** The maximum index of the prepared chunks. Queueing stops when m_NextIdx reaches this number. */ + int m_MaxIdx; + /** Total number of chunks already finished preparing. Preparation finishes when this number reaches m_MaxIdx. */ + int m_NumPrepared; -//////////////////////////////////////////////////////////////////////////////// -// cWorldLightingProgress: + /** Event used to signal that the thread has started. */ + cEvent m_EvtStarted; -/// A simple thread that displays the progress of world lighting in cWorld::InitializeSpawn() -class cWorldLightingProgress : - public cIsThread -{ -public: - cWorldLightingProgress(cLightingThread * a_Lighting) : - cIsThread("cWorldLightingProgress"), - m_Lighting(a_Lighting) - { - Start(); - } - - void Stop(void) + /** Event used to signal that the preparation is finished. */ + cEvent m_EvtFinished; + + /** The timestamp of the last progress report emitted. */ + std::chrono::steady_clock::time_point m_LastReportTime; + + /** Number of chunks prepared when the last progress report was emitted. */ + int m_LastReportChunkCount; + + // cChunkCoordCallback override: + virtual void Call(int a_ChunkX, int a_ChunkZ) { - m_ShouldTerminate = true; - Wait(); + // Check if this was the last chunk: + m_NumPrepared += 1; + if (m_NumPrepared >= m_MaxIdx) + { + m_EvtFinished.Set(); + } + + // Queue another chunk, if appropriate: + if (m_NextIdx < m_MaxIdx) + { + int chunkX, chunkZ; + DecodeChunkCoords(m_NextIdx, chunkX, chunkZ); + m_World.GetLightingThread().QueueChunk(chunkX, chunkZ, this); + m_NextIdx += 1; + } + + // Report progress every 1 second: + auto Now = std::chrono::steady_clock::now(); + if (Now - m_LastReportTime > std::chrono::seconds(1)) + { + float PercentDone = static_cast(m_NumPrepared * 100) / m_MaxIdx; + float ChunkSpeed = static_cast((m_NumPrepared - m_LastReportChunkCount) * 1000) / std::chrono::duration_cast(Now - m_LastReportTime).count(); + LOG("Preparing spawn (%s): %.02f%% (%d/%d; %.02f chunks/s)", + m_World.GetName().c_str(), PercentDone, m_NumPrepared, m_MaxIdx, ChunkSpeed + ); + m_LastReportTime = Now; + m_LastReportChunkCount = m_NumPrepared; + } } - -protected: - cLightingThread * m_Lighting; - - virtual void Execute(void) override + + /** Decodes the index into chunk coords. Provides the specific chunk ordering. */ + void DecodeChunkCoords(int a_Idx, int & a_ChunkX, int & a_ChunkZ) { - for (;;) + // A zigzag pattern from the top to bottom, each row alternating between forward-x and backward-x: + int z = a_Idx / m_PrepareDistance; + int x = a_Idx % m_PrepareDistance; + if ((z & 1) == 0) { - LOG("" SIZE_T_FMT " chunks remaining to light", m_Lighting->GetQueueLength() - ); - - // Wait for 2 sec, but be "reasonably wakeable" when the thread is to finish - for (int i = 0; i < 20; i++) - { - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - if (m_ShouldTerminate) - { - return; - } - } - } // for (-ever) + // Reverse every second row: + x = m_PrepareDistance - 1 - x; + } + a_ChunkZ = m_SpawnChunkZ + z - m_PrepareDistance / 2; + a_ChunkX = m_SpawnChunkX + x - m_PrepareDistance / 2; } }; @@ -206,7 +237,7 @@ void cWorld::cTickThread::Execute(void) while (!m_ShouldTerminate) { auto NowTime = std::chrono::steady_clock::now(); - m_World.Tick(std::chrono::duration_cast(NowTime - LastTime).count(), std::chrono::duration_cast>(TickTime).count()); + m_World.Tick(static_cast(std::chrono::duration_cast(NowTime - LastTime).count()), std::chrono::duration_cast>(TickTime).count()); TickTime = std::chrono::steady_clock::now() - NowTime; if (TickTime < msPerTick) @@ -426,53 +457,9 @@ void cWorld::InitializeSpawn(void) IniFile.ReadFile(m_IniFileName); int ViewDist = IniFile.GetValueSetI("SpawnPosition", "PregenerateDistance", DefaultViewDist); IniFile.WriteFile(m_IniFileName); - - LOG("Preparing spawn area in world \"%s\", %d x %d chunks, total %d chunks...", m_WorldName.c_str(), ViewDist, ViewDist, ViewDist * ViewDist); - for (int x = 0; x < ViewDist; x++) - { - for (int z = 0; z < ViewDist; z++) - { - m_ChunkMap->TouchChunk(x + ChunkX-(ViewDist - 1) / 2, z + ChunkZ-(ViewDist - 1) / 2); // Queue the chunk in the generator / loader - } - } - - { - // Display progress during this process: - cWorldLoadProgress Progress(this); - - // Wait for the loader to finish loading - m_Storage.WaitForLoadQueueEmpty(); - - // Wait for the generator to finish generating - m_Generator.WaitForQueueEmpty(); - // Wait for the loader to finish saving - m_Storage.WaitForSaveQueueEmpty(); - - Progress.Stop(); - } - - // Light all chunks that have been newly generated: - LOG("Lighting spawn area in world \"%s\"...", m_WorldName.c_str()); - - for (int x = 0; x < ViewDist; x++) - { - int ChX = x + ChunkX-(ViewDist - 1) / 2; - for (int z = 0; z < ViewDist; z++) - { - int ChZ = z + ChunkZ-(ViewDist - 1) / 2; - if (!m_ChunkMap->IsChunkLighted(ChX, ChZ)) - { - m_Lighting.QueueChunk(ChX, ChZ); // Queue the chunk in the lighting thread - } - } // for z - } // for x - - { - cWorldLightingProgress Progress(&m_Lighting); - m_Lighting.WaitForQueueEmpty(); - Progress.Stop(); - } + cSpawnPrepare prep(*this, ChunkX, ChunkZ, ViewDist); + prep.Wait(); #ifdef TEST_LINEBLOCKTRACER // DEBUG: Test out the cLineBlockTracer class by tracing a few lines: @@ -735,28 +722,32 @@ void cWorld::InitialiseGeneratorDefaults(cIniFile & a_IniFile) { case dimEnd: { - a_IniFile.GetValueSet("Generator", "BiomeGen", "Constant"); - a_IniFile.GetValueSet("Generator", "ConstantBiome", "End"); - a_IniFile.GetValueSet("Generator", "HeightGen", "Biomal"); + a_IniFile.GetValueSet("Generator", "Generator", "Composable"); + a_IniFile.GetValueSet("Generator", "BiomeGen", "Constant"); + a_IniFile.GetValueSet("Generator", "ConstantBiome", "End"); + a_IniFile.GetValueSet("Generator", "ShapeGen", "End"); a_IniFile.GetValueSet("Generator", "CompositionGen", "End"); break; } case dimOverworld: { - a_IniFile.GetValueSet("Generator", "BiomeGen", "MultiStepMap"); - a_IniFile.GetValueSet("Generator", "HeightGen", "DistortedHeightmap"); - a_IniFile.GetValueSet("Generator", "CompositionGen", "DistortedHeightmap"); - a_IniFile.GetValueSet("Generator", "Finishers", "Ravines, WormNestCaves, WaterLakes, WaterSprings, LavaLakes, LavaSprings, OreNests, Mineshafts, Trees, SprinkleFoliage, Ice, Snow, Lilypads, BottomLava, DeadBushes, PreSimulator"); + a_IniFile.GetValueSet("Generator", "Generator", "Composable"); + a_IniFile.GetValueSet("Generator", "BiomeGen", "Grown"); + a_IniFile.GetValueSet("Generator", "ShapeGen", "BiomalNoise3D"); + a_IniFile.GetValueSet("Generator", "CompositionGen", "Biomal"); + a_IniFile.GetValueSet("Generator", "Finishers", "Ravines, WormNestCaves, WaterLakes, WaterSprings, LavaLakes, LavaSprings, OreNests, Mineshafts, Trees, Villages, SprinkleFoliage, Ice, Snow, Lilypads, BottomLava, DeadBushes, PreSimulator"); break; } case dimNether: { - a_IniFile.GetValueSet("Generator", "BiomeGen", "Constant"); - a_IniFile.GetValueSet("Generator", "ConstantBiome", "Nether"); - a_IniFile.GetValueSet("Generator", "HeightGen", "Flat"); - a_IniFile.GetValueSet("Generator", "FlatHeight", "128"); - a_IniFile.GetValueSet("Generator", "CompositionGen", "Nether"); - a_IniFile.GetValueSet("Generator", "Finishers", "WormNestCaves, BottomLava, LavaSprings, NetherClumpFoliage, NetherForts, PreSimulator"); + a_IniFile.GetValueSet("Generator", "Generator", "Composable"); + a_IniFile.GetValueSet("Generator", "BiomeGen", "Constant"); + a_IniFile.GetValueSet("Generator", "ConstantBiome", "Nether"); + a_IniFile.GetValueSet("Generator", "ShapeGen", "HeightMap"); + a_IniFile.GetValueSet("Generator", "HeightGen", "Flat"); + a_IniFile.GetValueSet("Generator", "FlatHeight", "128"); + a_IniFile.GetValueSet("Generator", "CompositionGen", "Nether"); + a_IniFile.GetValueSet("Generator", "Finishers", "WormNestCaves, BottomLava, LavaSprings, NetherClumpFoliage, NetherForts, PreSimulator"); a_IniFile.GetValueSet("Generator", "BottomLavaHeight", "30"); break; } diff --git a/src/World.h b/src/World.h index 9e91064df..c5fdaeff5 100644 --- a/src/World.h +++ b/src/World.h @@ -696,6 +696,8 @@ public: inline size_t GetStorageLoadQueueLength(void) { return m_Storage.GetLoadQueueLength(); } // tolua_export inline size_t GetStorageSaveQueueLength(void) { return m_Storage.GetSaveQueueLength(); } // tolua_export + cLightingThread & GetLightingThread(void) { return m_Lighting; } + void InitializeSpawn(void); /** Starts threads that belong to this world */ -- cgit v1.2.3 From 0ca891da6d7b527cdd8a34332d7a8acd99e7caf3 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 26 Nov 2014 10:14:11 +0100 Subject: WSSAnvil: Fixed bad code in arrow loading. --- src/WorldStorage/WSSAnvil.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 0c77b4d67..395aabb1b 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -1807,9 +1807,10 @@ void cWSSAnvil::LoadArrowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ int InBlockZIdx = a_NBT.FindChildByName(a_TagIdx, "zTile"); if ((InBlockXIdx > 0) && (InBlockYIdx > 0) && (InBlockZIdx > 0)) { - if (a_NBT.GetType(InBlockXIdx) == a_NBT.GetType(InBlockYIdx) == a_NBT.GetType(InBlockZIdx)) + eTagType typeX = a_NBT.GetType(InBlockXIdx); + if ((typeX == a_NBT.GetType(InBlockYIdx)) && (typeX == a_NBT.GetType(InBlockZIdx))) { - switch (a_NBT.GetType(InBlockXIdx)) + switch (typeX) { case TAG_Int: { @@ -1823,6 +1824,11 @@ void cWSSAnvil::LoadArrowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ Arrow->SetBlockHit(Vector3i((int)a_NBT.GetShort(InBlockXIdx), (int)a_NBT.GetShort(InBlockYIdx), (int)a_NBT.GetShort(InBlockZIdx))); break; } + default: + { + // No hit block, the arrow is still flying? + break; + } } } } -- cgit v1.2.3 From 413e5c20fe688ad6f91542ee3227ccb659374cb2 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 26 Nov 2014 11:00:21 +0100 Subject: Windows: Fixed builds with LeakFinder enabled. --- src/CMakeLists.txt | 4 +++- src/main.cpp | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9720c9941..c702ac770 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -39,6 +39,7 @@ SET (SRCS Inventory.cpp Item.cpp ItemGrid.cpp + LeakFinder.cpp LightingThread.cpp LineBlockTracer.cpp LinearInterpolation.cpp @@ -58,6 +59,7 @@ SET (SRCS Scoreboard.cpp Server.cpp SetChunkData.cpp + StackWalker.cpp Statistics.cpp StringCompression.cpp StringUtils.cpp @@ -225,7 +227,7 @@ else () Bindings/Bindings.cpp PROPERTIES COMPILE_FLAGS "/Yc\"string.h\" /Fp\"$(IntDir)/Bindings.pch\"" ) SET_SOURCE_FILES_PROPERTIES( - "StackWalker.cpp LeakFinder.h" PROPERTIES COMPILE_FLAGS "/Yc\"Globals.h\"" + "StackWalker.cpp LeakFinder.cpp" PROPERTIES COMPILE_FLAGS "/Yc\"Globals.h\"" ) list(APPEND SOURCE "Resources/MCServer.rc") diff --git a/src/main.cpp b/src/main.cpp index 463c54c28..c60e13a8c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -182,7 +182,7 @@ int main( int argc, char **argv) #if defined(_MSC_VER) && defined(_DEBUG) && defined(ENABLE_LEAK_FINDER) InitLeakFinder(); #endif - + // Magic code to produce dump-files on Windows if the server crashes: #if defined(_WIN32) && !defined(_WIN64) && defined(_MSC_VER) HINSTANCE hDbgHelp = LoadLibrary("DBGHELP.DLL"); -- cgit v1.2.3 From a9e77fe7daa0874cb67d055b34d2a0efee6adbd3 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 26 Nov 2014 11:00:46 +0100 Subject: cRoot: Fixed a memory leak with cRankManager. --- src/Root.cpp | 2 +- src/Root.h | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Root.cpp b/src/Root.cpp index 55e1c1156..e309bb174 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -154,7 +154,7 @@ void cRoot::Start(void) m_WebAdmin->Init(); LOGD("Loading settings..."); - m_RankManager = new cRankManager(); + m_RankManager.reset(new cRankManager()); m_RankManager->Initialize(m_MojangAPI); m_CraftingRecipes = new cCraftingRecipes; m_FurnaceRecipe = new cFurnaceRecipe(); diff --git a/src/Root.h b/src/Root.h index ec6b83fcc..29753a47d 100644 --- a/src/Root.h +++ b/src/Root.h @@ -86,7 +86,7 @@ public: cPluginManager * GetPluginManager (void) { return m_PluginManager; } // tolua_export cAuthenticator & GetAuthenticator (void) { return m_Authenticator; } cMojangAPI & GetMojangAPI (void) { return m_MojangAPI; } - cRankManager * GetRankManager (void) { return m_RankManager; } + cRankManager * GetRankManager (void) { return m_RankManager.get(); } /** Queues a console command for execution through the cServer class. The command will be executed in the tick thread @@ -188,7 +188,9 @@ private: cPluginManager * m_PluginManager; cAuthenticator m_Authenticator; cMojangAPI m_MojangAPI; - cRankManager * m_RankManager; + + std::unique_ptr m_RankManager; + cHTTPServer m_HTTPServer; bool m_bStop; -- cgit v1.2.3 From a971dee379e9de211629b5a8604a152e43990e89 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 26 Nov 2014 12:45:53 +0100 Subject: CMake: Fixed linux builds. --- src/CMakeLists.txt | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c702ac770..d6218ff42 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -39,7 +39,6 @@ SET (SRCS Inventory.cpp Item.cpp ItemGrid.cpp - LeakFinder.cpp LightingThread.cpp LineBlockTracer.cpp LinearInterpolation.cpp @@ -59,7 +58,6 @@ SET (SRCS Scoreboard.cpp Server.cpp SetChunkData.cpp - StackWalker.cpp Statistics.cpp StringCompression.cpp StringUtils.cpp @@ -106,7 +104,6 @@ SET (HDRS Inventory.h Item.h ItemGrid.h - LeakFinder.h LightingThread.h LineBlockTracer.h LinearInterpolation.h @@ -116,7 +113,6 @@ SET (HDRS Map.h MapManager.h Matrix4.h - MemoryLeak.h MersenneTwister.h MobCensus.h MobFamilyCollecter.h @@ -130,7 +126,6 @@ SET (HDRS Scoreboard.h Server.h SetChunkData.h - StackWalker.h Statistics.h StringCompression.h StringUtils.h @@ -178,6 +173,10 @@ if (NOT MSVC) else () # MSVC-specific handling: Put all files into one project, separate by the folders: + # Add the MSVC-specific LeakFinder sources: + list (APPEND SRCS LeakFinder.cpp StackWalker.cpp) + list (APPEND HDRS LeakFinder.h StackWalker.h MemoryLeak.h) + source_group(Bindings FILES "Bindings/Bindings.cpp" "Bindings/Bindings.h") # Add all subfolders as solution-folders: -- cgit v1.2.3 From e3e13f552fe717256e2ba4cb9bea7c00834d1ec4 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 27 Nov 2014 21:19:52 +0100 Subject: Fixed BlockStringToType return value. -1 was not a valid BLOCKTYPE and would not be recognized by the callers, ever. --- src/BlockID.cpp | 2 +- src/BlockID.h | 2 +- src/Generating/ChunkGenerator.cpp | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/BlockID.cpp b/src/BlockID.cpp index c98e0cad1..06f4232d3 100644 --- a/src/BlockID.cpp +++ b/src/BlockID.cpp @@ -200,7 +200,7 @@ public: -BLOCKTYPE BlockStringToType(const AString & a_BlockTypeString) +int BlockStringToType(const AString & a_BlockTypeString) { int res = atoi(a_BlockTypeString.c_str()); if ((res != 0) || (a_BlockTypeString.compare("0") == 0)) diff --git a/src/BlockID.h b/src/BlockID.h index 24de2dc8a..8f2cee02e 100644 --- a/src/BlockID.h +++ b/src/BlockID.h @@ -1096,7 +1096,7 @@ class cIniFile; // tolua_begin /// Translates a blocktype string into blocktype. Takes either a number or an items.ini alias as input. Returns -1 on failure. -extern BLOCKTYPE BlockStringToType(const AString & a_BlockTypeString); +extern int BlockStringToType(const AString & a_BlockTypeString); /// Translates an itemtype string into an item. Takes either a number, number^number, number:number or an items.ini alias as input. Returns true if successful. extern bool StringToItem(const AString & a_ItemTypeString, cItem & a_Item); diff --git a/src/Generating/ChunkGenerator.cpp b/src/Generating/ChunkGenerator.cpp index 92e1bb31d..3ee02c767 100644 --- a/src/Generating/ChunkGenerator.cpp +++ b/src/Generating/ChunkGenerator.cpp @@ -191,13 +191,13 @@ EMCSBiome cChunkGenerator::GetBiomeAt(int a_BlockX, int a_BlockZ) BLOCKTYPE cChunkGenerator::GetIniBlock(cIniFile & a_IniFile, const AString & a_SectionName, const AString & a_ValueName, const AString & a_Default) { AString BlockType = a_IniFile.GetValueSet(a_SectionName, a_ValueName, a_Default); - BLOCKTYPE Block = BlockStringToType(BlockType); + int Block = BlockStringToType(BlockType); if (Block < 0) { LOGWARN("[%s].%s Could not parse block value \"%s\". Using default: \"%s\".", a_SectionName.c_str(), a_ValueName.c_str(), BlockType.c_str(), a_Default.c_str()); - return BlockStringToType(a_Default); + return static_cast(BlockStringToType(a_Default)); } - return Block; + return static_cast(Block); } -- cgit v1.2.3 From 61ce09e4d0c5c86e4191010707d89ef02f5df29e Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 27 Nov 2014 21:24:03 +0100 Subject: CompoGenBiomal: Fixed signed vs unsigned comparison. --- src/Generating/CompoGenBiomal.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Generating/CompoGenBiomal.cpp b/src/Generating/CompoGenBiomal.cpp index 995851c95..030c2baa5 100644 --- a/src/Generating/CompoGenBiomal.cpp +++ b/src/Generating/CompoGenBiomal.cpp @@ -39,7 +39,7 @@ public: // Fill the rest with stone: static BlockInfo Stone = {E_BLOCK_STONE, 0}; - for (size_t i = a_Count; i < cChunkDef::Height; i++) + for (int i = static_cast(a_Count); i < cChunkDef::Height; i++) { m_Pattern[i] = Stone; } -- cgit v1.2.3 From 186b2f3bd06a5f1c34f2cfb3f21ed4ee1f32d0f2 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 27 Nov 2014 21:27:03 +0100 Subject: Replaced auto_ptr with unique_ptr. --- src/CraftingRecipes.cpp | 6 +++--- src/FurnaceRecipe.cpp | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/CraftingRecipes.cpp b/src/CraftingRecipes.cpp index 64fb21181..2c2b02a69 100644 --- a/src/CraftingRecipes.cpp +++ b/src/CraftingRecipes.cpp @@ -289,7 +289,7 @@ void cCraftingRecipes::GetRecipe(cPlayer & a_Player, cCraftingGrid & a_CraftingG } // Built-in recipes: - std::auto_ptr Recipe(FindRecipe(a_CraftingGrid.GetItems(), a_CraftingGrid.GetWidth(), a_CraftingGrid.GetHeight())); + std::unique_ptr Recipe(FindRecipe(a_CraftingGrid.GetItems(), a_CraftingGrid.GetWidth(), a_CraftingGrid.GetHeight())); a_Recipe.Clear(); if (Recipe.get() == nullptr) { @@ -377,7 +377,7 @@ void cCraftingRecipes::AddRecipeLine(int a_LineNum, const AString & a_RecipeLine return; } - std::auto_ptr Recipe(new cCraftingRecipes::cRecipe); + std::unique_ptr Recipe(new cCraftingRecipes::cRecipe); // Parse the result: AStringVector ResultSplit = StringSplit(Sides[0], ","); @@ -758,7 +758,7 @@ cCraftingRecipes::cRecipe * cCraftingRecipes::MatchRecipe(const cItem * a_Crafti } // for y, for x // The recipe has matched. Create a copy of the recipe and set its coords to match the crafting grid: - std::auto_ptr Recipe(new cRecipe); + std::unique_ptr Recipe(new cRecipe); Recipe->m_Result = a_Recipe->m_Result; Recipe->m_Width = a_Recipe->m_Width; Recipe->m_Height = a_Recipe->m_Height; diff --git a/src/FurnaceRecipe.cpp b/src/FurnaceRecipe.cpp index 9b3b2ecbe..112aa8146 100644 --- a/src/FurnaceRecipe.cpp +++ b/src/FurnaceRecipe.cpp @@ -115,7 +115,7 @@ void cFurnaceRecipe::AddFuelFromLine(const AString & a_Line, unsigned int a_Line Line.erase(Line.begin()); // Remove the beginning "!" Line.erase(std::remove_if(Line.begin(), Line.end(), isspace), Line.end()); - std::auto_ptr Item(new cItem); + std::unique_ptr Item(new cItem); int BurnTime; const AStringVector & Sides = StringSplit(Line, "="); @@ -157,8 +157,8 @@ void cFurnaceRecipe::AddRecipeFromLine(const AString & a_Line, unsigned int a_Li Line.erase(std::remove_if(Line.begin(), Line.end(), isspace), Line.end()); int CookTime = 200; - std::auto_ptr InputItem(new cItem()); - std::auto_ptr OutputItem(new cItem()); + std::unique_ptr InputItem(new cItem()); + std::unique_ptr OutputItem(new cItem()); const AStringVector & Sides = StringSplit(Line, "="); if (Sides.size() != 2) -- cgit v1.2.3 From a6ed5cb1d8edc3c2e0804df9345094c89965af4b Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 27 Nov 2014 22:42:08 +0100 Subject: BlockEntities: Removed the extra semicolon. --- src/BlockEntities/BeaconEntity.cpp | 19 ++++++++++--------- src/BlockEntities/BeaconEntity.h | 2 +- src/BlockEntities/BlockEntityWithItems.h | 2 +- src/BlockEntities/ChestEntity.h | 2 +- src/BlockEntities/CommandBlockEntity.h | 2 +- src/BlockEntities/DispenserEntity.h | 2 +- src/BlockEntities/DropSpenserEntity.h | 2 +- src/BlockEntities/DropperEntity.h | 2 +- src/BlockEntities/EnderChestEntity.h | 2 +- src/BlockEntities/FlowerPotEntity.h | 2 +- src/BlockEntities/FurnaceEntity.h | 2 +- src/BlockEntities/HopperEntity.h | 2 +- src/BlockEntities/JukeboxEntity.h | 2 +- src/BlockEntities/MobHeadEntity.h | 2 +- src/BlockEntities/NoteEntity.h | 2 +- src/BlockEntities/SignEntity.h | 2 +- 16 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/BlockEntities/BeaconEntity.cpp b/src/BlockEntities/BeaconEntity.cpp index 85819446c..409f2937c 100644 --- a/src/BlockEntities/BeaconEntity.cpp +++ b/src/BlockEntities/BeaconEntity.cpp @@ -247,15 +247,16 @@ void cBeaconEntity::GiveEffects(void) } public: - cPlayerCallback(int a_Radius, int a_PosX, int a_PosY, int a_PosZ, cEntityEffect::eType a_PrimaryEffect, cEntityEffect::eType a_SecondaryEffect, short a_EffectLevel) - : m_Radius(a_Radius) - , m_PosX(a_PosX) - , m_PosY(a_PosY) - , m_PosZ(a_PosZ) - , m_PrimaryEffect(a_PrimaryEffect) - , m_SecondaryEffect(a_SecondaryEffect) - , m_EffectLevel(a_EffectLevel) - {}; + cPlayerCallback(int a_Radius, int a_PosX, int a_PosY, int a_PosZ, cEntityEffect::eType a_PrimaryEffect, cEntityEffect::eType a_SecondaryEffect, short a_EffectLevel): + m_Radius(a_Radius), + m_PosX(a_PosX), + m_PosY(a_PosY), + m_PosZ(a_PosZ), + m_PrimaryEffect(a_PrimaryEffect), + m_SecondaryEffect(a_SecondaryEffect), + m_EffectLevel(a_EffectLevel) + { + } } PlayerCallback(Radius, m_PosX, m_PosY, m_PosZ, m_PrimaryEffect, SecondaryEffect, EffectLevel); GetWorld()->ForEachPlayer(PlayerCallback); diff --git a/src/BlockEntities/BeaconEntity.h b/src/BlockEntities/BeaconEntity.h index d1db3a68f..0417e0464 100644 --- a/src/BlockEntities/BeaconEntity.h +++ b/src/BlockEntities/BeaconEntity.h @@ -32,7 +32,7 @@ class cBeaconEntity : public: // tolua_end - BLOCKENTITY_PROTODEF(cBeaconEntity); + BLOCKENTITY_PROTODEF(cBeaconEntity) cBeaconEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); diff --git a/src/BlockEntities/BlockEntityWithItems.h b/src/BlockEntities/BlockEntityWithItems.h index 8c7d4749b..2c2ced1cb 100644 --- a/src/BlockEntities/BlockEntityWithItems.h +++ b/src/BlockEntities/BlockEntityWithItems.h @@ -29,7 +29,7 @@ class cBlockEntityWithItems : public: // tolua_end - BLOCKENTITY_PROTODEF(cBlockEntityWithItems); + BLOCKENTITY_PROTODEF(cBlockEntityWithItems) cBlockEntityWithItems( BLOCKTYPE a_BlockType, // Type of the block that the entity represents diff --git a/src/BlockEntities/ChestEntity.h b/src/BlockEntities/ChestEntity.h index 09fffb923..5ab0a4800 100644 --- a/src/BlockEntities/ChestEntity.h +++ b/src/BlockEntities/ChestEntity.h @@ -33,7 +33,7 @@ public: // tolua_end - BLOCKENTITY_PROTODEF(cChestEntity); + BLOCKENTITY_PROTODEF(cChestEntity) /** Constructor used for normal operation */ cChestEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World, BLOCKTYPE a_Type); diff --git a/src/BlockEntities/CommandBlockEntity.h b/src/BlockEntities/CommandBlockEntity.h index 217390293..8deff6964 100644 --- a/src/BlockEntities/CommandBlockEntity.h +++ b/src/BlockEntities/CommandBlockEntity.h @@ -36,7 +36,7 @@ public: // tolua_end - BLOCKENTITY_PROTODEF(cCommandBlockEntity); + BLOCKENTITY_PROTODEF(cCommandBlockEntity) /// Creates a new empty command block entity cCommandBlockEntity(int a_X, int a_Y, int a_Z, cWorld * a_World); diff --git a/src/BlockEntities/DispenserEntity.h b/src/BlockEntities/DispenserEntity.h index 5ba87b716..12e12942a 100644 --- a/src/BlockEntities/DispenserEntity.h +++ b/src/BlockEntities/DispenserEntity.h @@ -17,7 +17,7 @@ public: // tolua_end - BLOCKENTITY_PROTODEF(cDispenserEntity); + BLOCKENTITY_PROTODEF(cDispenserEntity) /** Constructor used for normal operation */ cDispenserEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); diff --git a/src/BlockEntities/DropSpenserEntity.h b/src/BlockEntities/DropSpenserEntity.h index f77a28c28..9092bc077 100644 --- a/src/BlockEntities/DropSpenserEntity.h +++ b/src/BlockEntities/DropSpenserEntity.h @@ -45,7 +45,7 @@ public: // tolua_end - BLOCKENTITY_PROTODEF(cDropSpenserEntity); + BLOCKENTITY_PROTODEF(cDropSpenserEntity) cDropSpenserEntity(BLOCKTYPE a_BlockType, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); virtual ~cDropSpenserEntity(); diff --git a/src/BlockEntities/DropperEntity.h b/src/BlockEntities/DropperEntity.h index 91adf660f..c638dafa8 100644 --- a/src/BlockEntities/DropperEntity.h +++ b/src/BlockEntities/DropperEntity.h @@ -25,7 +25,7 @@ public: // tolua_end - BLOCKENTITY_PROTODEF(cDropperEntity); + BLOCKENTITY_PROTODEF(cDropperEntity) /// Constructor used for normal operation cDropperEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); diff --git a/src/BlockEntities/EnderChestEntity.h b/src/BlockEntities/EnderChestEntity.h index 17abd880a..af59cf170 100644 --- a/src/BlockEntities/EnderChestEntity.h +++ b/src/BlockEntities/EnderChestEntity.h @@ -18,7 +18,7 @@ class cEnderChestEntity : public: // tolua_end - BLOCKENTITY_PROTODEF(cEnderChestEntity); + BLOCKENTITY_PROTODEF(cEnderChestEntity) cEnderChestEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); virtual ~cEnderChestEntity(); diff --git a/src/BlockEntities/FlowerPotEntity.h b/src/BlockEntities/FlowerPotEntity.h index fc886c51f..005a3841a 100644 --- a/src/BlockEntities/FlowerPotEntity.h +++ b/src/BlockEntities/FlowerPotEntity.h @@ -36,7 +36,7 @@ public: // tolua_end - BLOCKENTITY_PROTODEF(cFlowerPotEntity); + BLOCKENTITY_PROTODEF(cFlowerPotEntity) /** Creates a new flowerpot entity at the specified block coords. a_World may be nullptr */ cFlowerPotEntity(int a_BlocX, int a_BlockY, int a_BlockZ, cWorld * a_World); diff --git a/src/BlockEntities/FurnaceEntity.h b/src/BlockEntities/FurnaceEntity.h index 71c2fe127..1ad812d8b 100644 --- a/src/BlockEntities/FurnaceEntity.h +++ b/src/BlockEntities/FurnaceEntity.h @@ -38,7 +38,7 @@ public: // tolua_end - BLOCKENTITY_PROTODEF(cFurnaceEntity); + BLOCKENTITY_PROTODEF(cFurnaceEntity) /** Constructor used for normal operation */ cFurnaceEntity(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cWorld * a_World); diff --git a/src/BlockEntities/HopperEntity.h b/src/BlockEntities/HopperEntity.h index 7070bbad3..da65aa671 100644 --- a/src/BlockEntities/HopperEntity.h +++ b/src/BlockEntities/HopperEntity.h @@ -31,7 +31,7 @@ public: // tolua_end - BLOCKENTITY_PROTODEF(cHopperEntity); + BLOCKENTITY_PROTODEF(cHopperEntity) /// Constructor used for normal operation cHopperEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); diff --git a/src/BlockEntities/JukeboxEntity.h b/src/BlockEntities/JukeboxEntity.h index 7a69d6499..301d018d1 100644 --- a/src/BlockEntities/JukeboxEntity.h +++ b/src/BlockEntities/JukeboxEntity.h @@ -26,7 +26,7 @@ public: // tolua_end - BLOCKENTITY_PROTODEF(cJukeboxEntity); + BLOCKENTITY_PROTODEF(cJukeboxEntity) cJukeboxEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); virtual ~cJukeboxEntity(); diff --git a/src/BlockEntities/MobHeadEntity.h b/src/BlockEntities/MobHeadEntity.h index 7132ef558..de033fd16 100644 --- a/src/BlockEntities/MobHeadEntity.h +++ b/src/BlockEntities/MobHeadEntity.h @@ -34,7 +34,7 @@ public: // tolua_end - BLOCKENTITY_PROTODEF(cMobHeadEntity); + BLOCKENTITY_PROTODEF(cMobHeadEntity) /** Creates a new mob head entity at the specified block coords. a_World may be nullptr */ cMobHeadEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); diff --git a/src/BlockEntities/NoteEntity.h b/src/BlockEntities/NoteEntity.h index fc5f27d07..d63ff56b6 100644 --- a/src/BlockEntities/NoteEntity.h +++ b/src/BlockEntities/NoteEntity.h @@ -40,7 +40,7 @@ public: // tolua_end - BLOCKENTITY_PROTODEF(cNoteEntity); + BLOCKENTITY_PROTODEF(cNoteEntity) /// Creates a new note entity. a_World may be nullptr cNoteEntity(int a_X, int a_Y, int a_Z, cWorld * a_World); diff --git a/src/BlockEntities/SignEntity.h b/src/BlockEntities/SignEntity.h index 52baa486d..347689d0a 100644 --- a/src/BlockEntities/SignEntity.h +++ b/src/BlockEntities/SignEntity.h @@ -34,7 +34,7 @@ public: // tolua_end - BLOCKENTITY_PROTODEF(cSignEntity); + BLOCKENTITY_PROTODEF(cSignEntity) /// Creates a new empty sign entity at the specified block coords and block type (wall or standing). a_World may be nullptr cSignEntity(BLOCKTYPE a_BlockType, int a_X, int a_Y, int a_Z, cWorld * a_World); -- cgit v1.2.3 From 9f24c0c4da7031776144bc9bf5d9de8f1094334a Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 27 Nov 2014 22:44:02 +0100 Subject: OctavedNoise: Unshadowed a local variable. --- src/Noise/OctavedNoise.h | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/Noise/OctavedNoise.h b/src/Noise/OctavedNoise.h index 855117289..4af18bd1b 100644 --- a/src/Noise/OctavedNoise.h +++ b/src/Noise/OctavedNoise.h @@ -124,18 +124,20 @@ public: } // Generate the first octave directly into array: - const cOctave & FirstOctave = m_Octaves.front(); int ArrayCount = a_SizeX * a_SizeY * a_SizeZ; - FirstOctave.m_Noise.Generate3D( - a_Workspace, a_SizeX, a_SizeY, a_SizeZ, - a_StartX * FirstOctave.m_Frequency, a_EndX * FirstOctave.m_Frequency, - a_StartY * FirstOctave.m_Frequency, a_EndY * FirstOctave.m_Frequency, - a_StartZ * FirstOctave.m_Frequency, a_EndZ * FirstOctave.m_Frequency - ); - NOISE_DATATYPE Amplitude = FirstOctave.m_Amplitude; - for (int i = 0; i < ArrayCount; i++) { - a_Array[i] = a_Workspace[i] * Amplitude; + const cOctave & FirstOctave = m_Octaves.front(); + FirstOctave.m_Noise.Generate3D( + a_Workspace, a_SizeX, a_SizeY, a_SizeZ, + a_StartX * FirstOctave.m_Frequency, a_EndX * FirstOctave.m_Frequency, + a_StartY * FirstOctave.m_Frequency, a_EndY * FirstOctave.m_Frequency, + a_StartZ * FirstOctave.m_Frequency, a_EndZ * FirstOctave.m_Frequency + ); + NOISE_DATATYPE Amplitude = FirstOctave.m_Amplitude; + for (int i = 0; i < ArrayCount; i++) + { + a_Array[i] = a_Workspace[i] * Amplitude; + } } // Add each octave: -- cgit v1.2.3 From 2cff4e8c8318d8f3a0af9c9440014cc07d64eeee Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 27 Nov 2014 22:48:31 +0100 Subject: RidgedNoise: Replaced fabs with std::abs(). --- src/Noise/RidgedNoise.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Noise/RidgedNoise.h b/src/Noise/RidgedNoise.h index 69b480f60..f59a0512f 100644 --- a/src/Noise/RidgedNoise.h +++ b/src/Noise/RidgedNoise.h @@ -54,7 +54,7 @@ public: ); for (int i = 0; i < ArrayCount; i++) { - a_Array[i] = fabs(a_Array[i]); + a_Array[i] = std::abs(a_Array[i]); } } @@ -77,7 +77,7 @@ public: ); for (int i = 0; i < ArrayCount; i++) { - a_Array[i] = fabs(a_Array[i]); + a_Array[i] = std::abs(a_Array[i]); } } -- cgit v1.2.3 From 12ad2a07c0658210e46652101740e101a32bea20 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 27 Nov 2014 22:50:18 +0100 Subject: Minecart.h: Fixed integral conversion warning. --- src/Entities/Minecart.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Entities/Minecart.h b/src/Entities/Minecart.h index 40e22c641..f7d0d5dda 100644 --- a/src/Entities/Minecart.h +++ b/src/Entities/Minecart.h @@ -128,7 +128,7 @@ public: }; const cItem & GetSlot(int a_Idx) const { return m_Contents.GetSlot(a_Idx); } - void SetSlot(size_t a_Idx, const cItem & a_Item) { m_Contents.SetSlot(a_Idx, a_Item); } + void SetSlot(size_t a_Idx, const cItem & a_Item) { m_Contents.SetSlot(static_cast(a_Idx), a_Item); } protected: cItemGrid m_Contents; -- cgit v1.2.3 From 4545b8eed9262d1748410b18f62da0e2cdbd39d5 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 27 Nov 2014 23:13:40 +0100 Subject: OctavedNoise: Another unshadowed local variable. --- src/Noise/OctavedNoise.h | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/Noise/OctavedNoise.h b/src/Noise/OctavedNoise.h index 4af18bd1b..efb9a0167 100644 --- a/src/Noise/OctavedNoise.h +++ b/src/Noise/OctavedNoise.h @@ -66,17 +66,19 @@ public: } // Generate the first octave directly into array: - const cOctave & FirstOctave = m_Octaves.front(); int ArrayCount = a_SizeX * a_SizeY; - FirstOctave.m_Noise.Generate2D( - a_Workspace, a_SizeX, a_SizeY, - a_StartX * FirstOctave.m_Frequency, a_EndX * FirstOctave.m_Frequency, - a_StartY * FirstOctave.m_Frequency, a_EndY * FirstOctave.m_Frequency - ); - NOISE_DATATYPE Amplitude = FirstOctave.m_Amplitude; - for (int i = 0; i < ArrayCount; i++) { - a_Array[i] = a_Workspace[i] * Amplitude; + const cOctave & FirstOctave = m_Octaves.front(); + FirstOctave.m_Noise.Generate2D( + a_Workspace, a_SizeX, a_SizeY, + a_StartX * FirstOctave.m_Frequency, a_EndX * FirstOctave.m_Frequency, + a_StartY * FirstOctave.m_Frequency, a_EndY * FirstOctave.m_Frequency + ); + NOISE_DATATYPE Amplitude = FirstOctave.m_Amplitude; + for (int i = 0; i < ArrayCount; i++) + { + a_Array[i] = a_Workspace[i] * Amplitude; + } } // Add each octave: -- cgit v1.2.3 From 1480cdb944b0c81efbaeb47ae1bf8b153d7d98fe Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 27 Nov 2014 23:15:08 +0100 Subject: Chunk: Fixed same-name iterators. --- src/Chunk.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Chunk.cpp b/src/Chunk.cpp index d9333afc7..a2a11f130 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -1869,18 +1869,18 @@ bool cChunk::AddClient(cClientHandle * a_Client) void cChunk::RemoveClient(cClientHandle * a_Client) { - for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) + for (cClientHandleList::iterator itrC = m_LoadedByClient.begin(); itrC != m_LoadedByClient.end(); ++itrC) { - if (*itr != a_Client) + if (*itrC != a_Client) { continue; } - m_LoadedByClient.erase(itr); + m_LoadedByClient.erase(itrC); if (!a_Client->IsDestroyed()) { - for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr) + for (cEntityList::iterator itrE = m_Entities.begin(); itrE != m_Entities.end(); ++itrE) { /* // DEBUG: @@ -1889,7 +1889,7 @@ void cChunk::RemoveClient(cClientHandle * a_Client) (*itr)->GetUniqueID(), a_Client->GetUsername().c_str() ); */ - a_Client->SendDestroyEntity(*(*itr)); + a_Client->SendDestroyEntity(*(*itrE)); } } return; -- cgit v1.2.3 From ab9c0069387d93a1b64a58b798dc7be2808bd8df Mon Sep 17 00:00:00 2001 From: M10360 Date: Sat, 29 Nov 2014 01:47:13 -0600 Subject: Removed duplicate. --- MCServer/crafting.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/MCServer/crafting.txt b/MCServer/crafting.txt index 8e68d5cb5..4d28b1f52 100644 --- a/MCServer/crafting.txt +++ b/MCServer/crafting.txt @@ -75,7 +75,6 @@ Wool = String, 1:1, 1:2, 2:1, 2:2 TNT = Gunpowder, 1:1, 3:1, 2:2, 1:3, 3:3 | Sand, 2:1, 1:2, 3:2, 2:3 PillarQuartzBlock = QuartzSlab, 1:1, 1:2 ChiseledQuartzBlock, 2 = QuartzBlock, 1:1, 1:2 -CoalBlock = Coal, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3 HayBale = Wheat, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3 SnowBlock = SnowBall, 1:1, 1:2, 2:1, 2:2 ClayBlock = Clay, 1:1, 1:2, 2:1, 2:2 -- cgit v1.2.3 From 23a176057db0d6bb9b2ddd473d5050591282f578 Mon Sep 17 00:00:00 2001 From: M10360 Date: Sat, 29 Nov 2014 01:56:44 -0600 Subject: Added missing fuels. --- MCServer/furnace.txt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/MCServer/furnace.txt b/MCServer/furnace.txt index 0c12a798d..8efa712e7 100644 --- a/MCServer/furnace.txt +++ b/MCServer/furnace.txt @@ -90,6 +90,25 @@ RawMutton = CookedMutton ! CoalBlock = 16000 # -> 800 sec ! BlazeRod = 2400 # -> 120 sec ! NoteBlock = 300 # -> 15 sec +! HugeRedMushroom = 300 # -> 15 sec +! HugeBrownMushroom = 300 # -> 15 sec +! Banner = 300 # -> 15 sec +! BlackBanner = 300 # -> 15 sec +! RedBanner = 300 # -> 15 sec +! GreenBanner = 300 # -> 15 sec +! BrownBanner = 300 # -> 15 sec +! BlueBanner = 300 # -> 15 sec +! PurpleBanner = 300 # -> 15 sec +! CyanBanner = 300 # -> 15 sec +! SilverBanner = 300 # -> 15 sec +! GrayBanner = 300 # -> 15 sec +! PinkBanner = 300 # -> 15 sec +! LimeBanner = 300 # -> 15 sec +! YellowBanner = 300 # -> 15 sec +! LightBlueBanner = 300 # -> 15 sec +! MagentaBanner = 300 # -> 15 sec +! OrangeBanner = 300 # -> 15 sec +! WhiteBanner = 300 # -> 15 sec ! DaylightSensor = 300 # -> 15 sec ! FenceGate = 300 # -> 15 sec ! SpruceFenceGate = 300 # -> 15 sec -- cgit v1.2.3 From 7f190c4ec24ed6d4cd2c390a33741c058dc04a6c Mon Sep 17 00:00:00 2001 From: M10360 Date: Sat, 29 Nov 2014 01:59:01 -0600 Subject: Smelting Netherrack not TallGrass gives you NetherBrickItem. --- MCServer/furnace.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MCServer/furnace.txt b/MCServer/furnace.txt index 8efa712e7..7179b5299 100644 --- a/MCServer/furnace.txt +++ b/MCServer/furnace.txt @@ -52,7 +52,7 @@ RawBeef = Steak RawChicken = CookedChicken Clay = Brick ClayBlock = HardenedClay -TallGrass = NetherBrickItem +Netherrack = NetherBrickItem RawFish = CookedFish Log = CharCoal Cactus = GreenDye -- cgit v1.2.3 From 02828304c2a26c5b175e862f0525e76c4974b710 Mon Sep 17 00:00:00 2001 From: M10360 Date: Sat, 29 Nov 2014 02:02:35 -0600 Subject: Added M10360. --- CONTRIBUTORS | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 8620a1475..fffc55b2a 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -10,6 +10,7 @@ Howaner keyboard Lapayo Luksor +M10360 marmot21 Masy98 mborland -- cgit v1.2.3 From 2478e290f9f7f6a74bba4ac885cfaef6327bc9ee Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 29 Nov 2014 15:20:44 +0100 Subject: Many api fixes, add vanilla names to mob type -> string functions and mob spawner fixes. --- MCServer/Plugins/APIDump/APIDesc.lua | 20 ++-- MCServer/Plugins/APIDump/Classes/BlockEntities.lua | 37 +++++++ src/Bindings/AllToLua.pkg | 1 + src/BlockEntities/MobHeadEntity.h | 12 +-- src/BlockEntities/MobSpawnerEntity.cpp | 47 +-------- src/BlockEntities/MobSpawnerEntity.h | 10 +- src/Mobs/Monster.cpp | 113 +++++++++++---------- src/Mobs/Monster.h | 11 +- src/Protocol/Protocol17x.cpp | 2 +- src/Protocol/Protocol17x.h | 1 + src/Protocol/Protocol18x.cpp | 2 +- src/Protocol/Protocol18x.h | 1 + src/WorldStorage/NBTChunkSerializer.cpp | 2 +- 13 files changed, 137 insertions(+), 122 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 9b87781a6..832540d3e 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -1668,13 +1668,14 @@ a_Player:OpenWindow(Window); SetCustomName = { Params = "string", Return = "", Notes = "Sets the custom name of the monster. You see the name over the monster. If you want to disable the custom name, simply set an empty string." }, IsCustomNameAlwaysVisible = { Params = "", Return = "bool", Notes = "Is the custom name of this monster always visible? If not, you only see the name when you sight the mob." }, SetCustomNameAlwaysVisible = { Params = "bool", Return = "", Notes = "Sets the custom name visiblity of this monster. If it's false, you only see the name when you sight the mob. If it's true, you always see the custom name." }, - FamilyFromType = { Params = "{{cMonster#MobType|MobType}}", Return = "{{cMonster#MobFamily|MobFamily}}", Notes = "(STATIC) Returns the mob family ({{cMonster#MobFamily|mfXXX}} constants) based on the mob type ({{cMonster#MobType|mtXXX}} constants)" }, + FamilyFromType = { Params = "{{Globals#MobType|MobType}}", Return = "{{cMonster#MobFamily|MobFamily}}", Notes = "(STATIC) Returns the mob family ({{cMonster#MobFamily|mfXXX}} constants) based on the mob type ({{Globals#MobType|mtXXX}} constants)" }, GetMobFamily = { Params = "", Return = "{{cMonster#MobFamily|MobFamily}}", Notes = "Returns this mob's family ({{cMonster#MobFamily|mfXXX}} constant)" }, - GetMobType = { Params = "", Return = "{{cMonster#MobType|MobType}}", Notes = "Returns the type of this mob ({{cMonster#MobType|mtXXX}} constant)" }, + GetMobType = { Params = "", Return = "{{Globals#MobType|MobType}}", Notes = "Returns the type of this mob ({{Globals#MobType|mtXXX}} constant)" }, GetSpawnDelay = { Params = "{{cMonster#MobFamily|MobFamily}}", Return = "number", Notes = "(STATIC) Returns the spawn delay - the number of game ticks between spawn attempts - for the specified mob family." }, - MobTypeToString = { Params = "{{cMonster#MobType|MobType}}", Return = "string", Notes = "(STATIC) Returns the string representing the given mob type ({{cMonster#MobType|mtXXX}} constant), or empty string if unknown type." }, + MobTypeToString = { Params = "{{Globals#MobType|MobType}}", Return = "string", Notes = "(STATIC) Returns the string representing the given mob type ({{Globals#MobType|mtXXX}} constant), or empty string if unknown type." }, + MobTypeToVanillaName = { Params = "{{Globals#MobType|MobType}}", Return = "string", Notes = "(STATIC) Returns the correct vanilla name of the given mob type, or empty string if unknown type." }, MoveToPosition = { Params = "Position", Return = "", Notes = "Moves mob to the specified position" }, - StringToMobType = { Params = "string", Return = "{{cMonster#MobType|MobType}}", Notes = "(STATIC) Returns the mob type ({{cMonster#MobType|mtXXX}} constant) parsed from the string type (\"creeper\"), or mtInvalidType if unrecognized." }, + StringToMobType = { Params = "string", Return = "{{Globals#MobType|MobType}}", Notes = "(STATIC) Returns the mob type ({{Globals#MobType|mtXXX}} constant) parsed from the string type (\"creeper\"), or mtInvalidType if unrecognized." }, GetRelativeWalkSpeed = { Params = "", Return = "number", Notes = "Returns the relative walk speed of this mob. Standard is 1.0" }, SetRelativeWalkSpeed = { Params = "number", Return = "", Notes = "Sets the relative walk speed of this mob. Standard is 1.0" }, }, @@ -2571,7 +2572,7 @@ World:ForEachEntity( return; end local Monster = tolua.cast(a_Entity, "cMonster"); -- Get the cMonster out of cEntity, now that we know the entity represents one. - if (Monster:GetMobType() == cMonster.mtSpider) then + if (Monster:GetMobType() == mtSpider) then Monster:TeleportToCoords(Monster:GetPosX(), Monster:GetPosY() + 100, Monster:GetPosZ()); end end @@ -2928,7 +2929,7 @@ end StringToDamageType = {Params = "string", Return = "{{Globals#DamageType|DamageType}}", Notes = "Converts a string representation to a {{Globals#DamageType|DamageType}} enumerated value."}, StringToDimension = {Params = "string", Return = "{{Globals#WorldDimension|Dimension}}", Notes = "Converts a string representation to a {{Globals#WorldDimension|Dimension}} enumerated value"}, StringToItem = {Params = "string, {{cItem|cItem}}", Return = "bool", Notes = "Parses the given string and sets the item; returns true if successful"}, - StringToMobType = {Params = "string", Return = "{{cMonster#MobType|MobType}}", Notes = "Converts a string representation to a {{cMonster#MobType|MobType}} enumerated value"}, + StringToMobType = {Params = "string", Return = "{{Globals#MobType|MobType}}", Notes = "Converts a string representation to a {{Globals#MobType|MobType}} enumerated value"}, StripColorCodes = {Params = "string", Return = "string", Notes = "Removes all control codes used by MC for colors and styles"}, TrimString = {Params = "string", Return = "string", Notes = "Trims whitespace at both ends of the string"}, md5 = {Params = "string", Return = "string", Notes = "converts a string to an md5 hash"}, @@ -3014,6 +3015,13 @@ end gmXXX constants, the eGameMode_ constants are deprecated and will be removed from the API. ]], }, + MobType = + { + Include = { "^mt.*" }, + TextBefore = [[ + The following constants are used for the mob types. + ]], + }, Weather = { Include = { "^eWeather_.*", "wSunny", "wRain", "wStorm", "wThunderstorm" }, diff --git a/MCServer/Plugins/APIDump/Classes/BlockEntities.lua b/MCServer/Plugins/APIDump/Classes/BlockEntities.lua index 90ebf12e6..daa658654 100644 --- a/MCServer/Plugins/APIDump/Classes/BlockEntities.lua +++ b/MCServer/Plugins/APIDump/Classes/BlockEntities.lua @@ -231,6 +231,43 @@ World:ForEachChestInChunk(Player:GetChunkX(), Player:GetChunkZ(), }, }, -- cJukeboxEntity + cMobHeadEntity = + { + Desc = [[ + This class represents a mob head block entity in the world. + ]], + Inherits = "cBlockEntity", + Functions = + { + SetType = { Params = "eMobHeadType", Return = "", Notes = "Set the type of the mob head" }, + SetRotation = { Params = "eMobHeadRotation", Return = "", Notes = "Sets the rotation of the mob head" }, + SetOwner = { Params = "string", Return = "", Notes = "Set the player name for mob heads with player type" }, + GetType = { Params = "", Return = "eMobHeadType", Notes = "Returns the type of the mob head" }, + GetRotation = { Params = "", Return = "eMobHeadRotation", Notes = "Returns the rotation of the mob head" }, + GetOwner = { Params = "", Return = "string", Notes = "Returns the player name of the mob head" }, + }, + }, -- cMobHeadEntity + + cMobSpawnerEntity = + { + Desc = [[ + This class represents a mob spawner block entity in the world. + ]], + Inherits = "cBlockEntity", + Functions = + { + UpdateActiveState = { Params = "", Return = "", Notes = "Upate the active flag from the mob spawner. This function will called every 5 seconds from the Tick() function." }, + ResetTimer = { Params = "", Return = "", Notes = "Sets the spawn delay to a new random value." }, + SpawnEntity = { Params = "", Return = "", Notes = "Spawns the entity. This function automaticly change the spawn delay!" }, + GetEntity = { Params = "", Return = "{{Globals#MobType|MobType}}", Notes = "Returns the entity type that will be spawn by this mob spawner." }, + SetEntity = { Params = "{{Globals#MobType|MobType}}", Return = "", Notes = "Sets the entity type who will be spawn by this mob spawner." }, + GetSpawnDelay = { Params = "", Return = "number", Notes = "Returns the spawn delay. This is the tick delay that is needed to spawn new monsters." }, + SetSpawnDelay = { Params = "number", Return = "", Notes = "Sets the spawn delay." }, + GetNearbyPlayersNum = { Params = "", Return = "number", Notes = "Returns the amount of the nearby players in a 16-block radius." }, + GetNearbyMonsterNum = { Params = "", Return = "number", Notes = "Returns the amount of this monster type in a 8-block radius (Y: 4-block radius)." }, + }, + }, -- cMobSpawnerEntity + cNoteEntity = { Desc = [[ diff --git a/src/Bindings/AllToLua.pkg b/src/Bindings/AllToLua.pkg index 7b78578ee..7e174e770 100644 --- a/src/Bindings/AllToLua.pkg +++ b/src/Bindings/AllToLua.pkg @@ -74,6 +74,7 @@ $cfile "../BlockEntities/JukeboxEntity.h" $cfile "../BlockEntities/NoteEntity.h" $cfile "../BlockEntities/SignEntity.h" $cfile "../BlockEntities/MobHeadEntity.h" +$cfile "../BlockEntities/MobSpawnerEntity.h" $cfile "../BlockEntities/FlowerPotEntity.h" $cfile "../WebAdmin.h" $cfile "../Root.h" diff --git a/src/BlockEntities/MobHeadEntity.h b/src/BlockEntities/MobHeadEntity.h index e26c0bdd0..7f08c5ab2 100644 --- a/src/BlockEntities/MobHeadEntity.h +++ b/src/BlockEntities/MobHeadEntity.h @@ -33,22 +33,22 @@ public: // tolua_begin - /** Set the Type */ + /** Set the type of the mob head */ void SetType(const eMobHeadType & a_SkullType); - /** Set the Rotation */ + /** Set the rotation of the mob head */ void SetRotation(eMobHeadRotation a_Rotation); - /** Set the Player Name for Mobheads with Player type */ + /** Set the player name for mob heads with player type */ void SetOwner(const AString & a_Owner); - /** Get the Type */ + /** Returns the type of the mob head */ eMobHeadType GetType(void) const { return m_Type; } - /** Get the Rotation */ + /** Returns the rotation of the mob head */ eMobHeadRotation GetRotation(void) const { return m_Rotation; } - /** Get the setted Player Name */ + /** Returns the player name of the mob head */ AString GetOwner(void) const { return m_Owner; } // tolua_end diff --git a/src/BlockEntities/MobSpawnerEntity.cpp b/src/BlockEntities/MobSpawnerEntity.cpp index 696a109d1..26499972d 100644 --- a/src/BlockEntities/MobSpawnerEntity.cpp +++ b/src/BlockEntities/MobSpawnerEntity.cpp @@ -49,7 +49,7 @@ void cMobSpawnerEntity::UsedBy(cPlayer * a_Player) { a_Player->GetInventory().RemoveOneEquippedItem(); } - LOGD("Changed monster spawner at {%d, %d, %d} to type %s.", GetPosX(), GetPosY(), GetPosZ(), GetEntityName().c_str()); + LOGD("Changed monster spawner at {%d, %d, %d} to type %s.", GetPosX(), GetPosY(), GetPosZ(), cMonster::MobTypeToString(MonsterType).c_str()); } } @@ -195,51 +195,6 @@ void cMobSpawnerEntity::SpawnEntity(void) -AString cMobSpawnerEntity::GetEntityName() const -{ - switch (m_Entity) - { - case mtBat: return "Bat"; - case mtBlaze: return "Blaze"; - case mtCaveSpider: return "CaveSpider"; - case mtChicken: return "Chicken"; - case mtCow: return "Cow"; - case mtCreeper: return "Creeper"; - case mtEnderDragon: return "EnderDragon"; - case mtEnderman: return "Enderman"; - case mtGhast: return "Ghast"; - case mtGiant: return "Giant"; - case mtHorse: return "EntityHorse"; - case mtIronGolem: return "VillagerGolem"; - case mtMagmaCube: return "LavaSlime"; - case mtMooshroom: return "MushroomCow"; - case mtOcelot: return "Ozelot"; - case mtPig: return "Pig"; - case mtSheep: return "Sheep"; - case mtSilverfish: return "Silverfish"; - case mtSkeleton: return "Skeleton"; - case mtSlime: return "Slime"; - case mtSnowGolem: return "SnowMan"; - case mtSpider: return "Spider"; - case mtSquid: return "Squid"; - case mtVillager: return "Villager"; - case mtWitch: return "Witch"; - case mtWither: return "WitherBoss"; - case mtWolf: return "Wolf"; - case mtZombie: return "Zombie"; - case mtZombiePigman: return "PigZombie"; - default: - { - ASSERT(!"Unknown monster type!"); - return "Pig"; - } - } -} - - - - - int cMobSpawnerEntity::GetNearbyPlayersNum(void) { Vector3d SpawnerPos(m_PosX + 0.5, m_PosY + 0.5, m_PosZ + 0.5); diff --git a/src/BlockEntities/MobSpawnerEntity.h b/src/BlockEntities/MobSpawnerEntity.h index 073eb03ab..0a3367c97 100644 --- a/src/BlockEntities/MobSpawnerEntity.h +++ b/src/BlockEntities/MobSpawnerEntity.h @@ -35,22 +35,22 @@ public: /** Spawns the entity. This function automaticly change the spawn delay! */ void SpawnEntity(void); - /** Returns the entity type who will be spawn by this mob spawner. */ + /** Returns the entity type that will be spawn by this mob spawner. */ eMonsterType GetEntity(void) const { return m_Entity; } /** Sets the entity type who will be spawn by this mob spawner. */ void SetEntity(eMonsterType a_EntityType) { m_Entity = a_EntityType; } - /** Returns the entity name. (Required by the protocol) */ - AString GetEntityName(void) const; - - /** Returns the spawn delay. */ + /** Returns the spawn delay. This is the tick delay that is needed to spawn new monsters. */ short GetSpawnDelay(void) const { return m_SpawnDelay; } /** Sets the spawn delay. */ void SetSpawnDelay(short a_Delay) { m_SpawnDelay = a_Delay; } + /** Returns the amount of the nearby players in a 16-block radius. */ int GetNearbyPlayersNum(void); + + /** Returns the amount of this monster type in a 8-block radius (Y: 4-block radius). */ int GetNearbyMonsterNum(eMonsterType a_EntityType); // tolua_end diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 5319bdf91..9937e6a95 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -26,36 +26,37 @@ static const struct { eMonsterType m_Type; const char * m_lcName; + const char * m_VanillaName; } g_MobTypeNames[] = { - {mtBat, "bat"}, - {mtBlaze, "blaze"}, - {mtCaveSpider, "cavespider"}, - {mtChicken, "chicken"}, - {mtCow, "cow"}, - {mtCreeper, "creeper"}, - {mtEnderman, "enderman"}, - {mtEnderDragon, "enderdragon"}, - {mtGhast, "ghast"}, - {mtHorse, "horse"}, - {mtIronGolem, "irongolem"}, - {mtMagmaCube, "magmacube"}, - {mtMooshroom, "mooshroom"}, - {mtOcelot, "ocelot"}, - {mtPig, "pig"}, - {mtSheep, "sheep"}, - {mtSilverfish, "silverfish"}, - {mtSkeleton, "skeleton"}, - {mtSlime, "slime"}, - {mtSnowGolem, "snowgolem"}, - {mtSpider, "spider"}, - {mtSquid, "squid"}, - {mtVillager, "villager"}, - {mtWitch, "witch"}, - {mtWither, "wither"}, - {mtWolf, "wolf"}, - {mtZombie, "zombie"}, - {mtZombiePigman, "zombiepigman"}, + {mtBat, "bat", "Bat"}, + {mtBlaze, "blaze", "Blaze"}, + {mtCaveSpider, "cavespider", "CaveSpider"}, + {mtChicken, "chicken", "Chicken"}, + {mtCow, "cow", "Cow"}, + {mtCreeper, "creeper", "Creeper"}, + {mtEnderman, "enderman", "Enderman"}, + {mtEnderDragon, "enderdragon", "EnderDragon"}, + {mtGhast, "ghast", "Ghast"}, + {mtHorse, "horse", "EntityHorse"}, + {mtIronGolem, "irongolem", "VillagerGolem"}, + {mtMagmaCube, "magmacube", "LavaSlime"}, + {mtMooshroom, "mooshroom", "MushroomCow"}, + {mtOcelot, "ocelot", "Ozelot"}, + {mtPig, "pig", "Pig"}, + {mtSheep, "sheep", "Sheep"}, + {mtSilverfish, "silverfish", "Silverfish"}, + {mtSkeleton, "skeleton", "Skeleton"}, + {mtSlime, "slime", "Slime"}, + {mtSnowGolem, "snowgolem", "SnowMan"}, + {mtSpider, "spider", "Spider"}, + {mtSquid, "squid", "Squid"}, + {mtVillager, "villager", "Villager"}, + {mtWitch, "witch", "Witch"}, + {mtWither, "wither", "WitherBoss"}, + {mtWolf, "wolf", "Wolf"}, + {mtZombie, "zombie", "Zombie"}, + {mtZombiePigman, "zombiepigman", "PigZombie"}, } ; @@ -784,39 +785,47 @@ AString cMonster::MobTypeToString(eMonsterType a_MobType) -eMonsterType cMonster::StringToMobType(const AString & a_Name) +AString cMonster::MobTypeToVanillaName(eMonsterType a_MobType) { - AString lcName = StrToLower(a_Name); - - // Binary-search for the lowercase name: - int lo = 0, hi = ARRAYCOUNT(g_MobTypeNames) - 1; - while (hi - lo > 1) + // Mob types aren't sorted, so we need to search linearly: + for (size_t i = 0; i < ARRAYCOUNT(g_MobTypeNames); i++) { - int mid = (lo + hi) / 2; - int res = strcmp(g_MobTypeNames[mid].m_lcName, lcName.c_str()); - if (res == 0) - { - return g_MobTypeNames[mid].m_Type; - } - if (res < 0) - { - lo = mid; - } - else + if (g_MobTypeNames[i].m_Type == a_MobType) { - hi = mid; + return g_MobTypeNames[i].m_VanillaName; } } - // Range has collapsed to at most two elements, compare each: - if (strcmp(g_MobTypeNames[lo].m_lcName, lcName.c_str()) == 0) + + // Not found: + return ""; +} + + + + + +eMonsterType cMonster::StringToMobType(const AString & a_Name) +{ + AString lcName = StrToLower(a_Name); + + // Search MCServer name: + for (size_t i = 0; i < ARRAYCOUNT(g_MobTypeNames); i++) { - return g_MobTypeNames[lo].m_Type; + if (strcmp(g_MobTypeNames[i].m_lcName, lcName.c_str()) == 0) + { + return g_MobTypeNames[i].m_Type; + } } - if ((lo != hi) && (strcmp(g_MobTypeNames[hi].m_lcName, lcName.c_str()) == 0)) + + // Not found. Search Vanilla name: + for (size_t i = 0; i < ARRAYCOUNT(g_MobTypeNames); i++) { - return g_MobTypeNames[hi].m_Type; + if (strcmp(StrToLower(g_MobTypeNames[i].m_VanillaName).c_str(), lcName.c_str()) == 0) + { + return g_MobTypeNames[i].m_Type; + } } - + // Not found: return mtInvalidType; } diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h index fd4e8a659..4903c38ad 100644 --- a/src/Mobs/Monster.h +++ b/src/Mobs/Monster.h @@ -133,16 +133,19 @@ public: If it's false, you only see the name when you sight the mob. If it's true, you always see the custom name. */ void SetCustomNameAlwaysVisible(bool a_CustomNameAlwaysVisible); - /// Translates MobType enum to a string, empty string if unknown + /** Translates MobType enum to a string, empty string if unknown */ static AString MobTypeToString(eMonsterType a_MobType); - /// Translates MobType string to the enum, mtInvalidType if not recognized + /** Translates MobType enum to the correct vanilla name of the mob, empty string if unknown. */ + static AString MobTypeToVanillaName(eMonsterType a_MobType); + + /** Translates MobType string to the enum, mtInvalidType if not recognized */ static eMonsterType StringToMobType(const AString & a_MobTypeName); - /// Returns the mob family based on the type + /** Returns the mob family based on the type */ static eFamily FamilyFromType(eMonsterType a_MobType); - /// Returns the spawn delay (number of game ticks between spawn attempts) for the given mob family + /** Returns the spawn delay (number of game ticks between spawn attempts) for the given mob family */ static int GetSpawnDelay(cMonster::eFamily a_MobFamily); // tolua_end diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 9067131b2..1e5fe5586 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -2670,7 +2670,7 @@ void cProtocol172::cPacketizer::WriteBlockEntity(const cBlockEntity & a_BlockEnt Writer.AddInt("x", MobSpawnerEntity.GetPosX()); Writer.AddInt("y", MobSpawnerEntity.GetPosY()); Writer.AddInt("z", MobSpawnerEntity.GetPosZ()); - Writer.AddString("EntityId", MobSpawnerEntity.GetEntityName()); + Writer.AddString("EntityId", cMonster::MobTypeToVanillaName(MobSpawnerEntity.GetEntity())); Writer.AddShort("Delay", MobSpawnerEntity.GetSpawnDelay()); Writer.AddString("id", "MobSpawner"); break; diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index f939bfb5e..3865b086c 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -33,6 +33,7 @@ Declares the 1.7.x protocol classes: #include "PolarSSL++/AesCfb128Decryptor.h" #include "PolarSSL++/AesCfb128Encryptor.h" +#include "../Mobs/MonsterTypes.h" diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index 42f365e80..ce580d73e 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -2980,7 +2980,7 @@ void cProtocol180::cPacketizer::WriteBlockEntity(const cBlockEntity & a_BlockEnt Writer.AddInt("x", MobSpawnerEntity.GetPosX()); Writer.AddInt("y", MobSpawnerEntity.GetPosY()); Writer.AddInt("z", MobSpawnerEntity.GetPosZ()); - Writer.AddString("EntityId", MobSpawnerEntity.GetEntityName()); + Writer.AddString("EntityId", cMonster::MobTypeToVanillaName(MobSpawnerEntity.GetEntity())); Writer.AddShort("Delay", MobSpawnerEntity.GetSpawnDelay()); Writer.AddString("id", "MobSpawner"); break; diff --git a/src/Protocol/Protocol18x.h b/src/Protocol/Protocol18x.h index 92d9825ef..216639319 100644 --- a/src/Protocol/Protocol18x.h +++ b/src/Protocol/Protocol18x.h @@ -32,6 +32,7 @@ Declares the 1.8.x protocol classes: #include "PolarSSL++/AesCfb128Decryptor.h" #include "PolarSSL++/AesCfb128Encryptor.h" +#include "../Mobs/MonsterTypes.h" diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index 228df2686..432e122b5 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -296,7 +296,7 @@ void cNBTChunkSerializer::AddMobSpawnerEntity(cMobSpawnerEntity * a_MobSpawner) m_Writer.BeginCompound(""); AddBasicTileEntity(a_MobSpawner, "MobSpawner"); m_Writer.AddShort("Entity", static_cast(a_MobSpawner->GetEntity())); - m_Writer.AddString("EntityId", a_MobSpawner->GetEntityName()); + m_Writer.AddString("EntityId", cMonster::MobTypeToVanillaName(a_MobSpawner->GetEntity())); m_Writer.AddShort("Delay", a_MobSpawner->GetSpawnDelay()); m_Writer.EndCompound(); } -- cgit v1.2.3 From 473cb6e0b2ec3c0fd497e66d407204ca47ec1cc9 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 29 Nov 2014 15:22:24 +0100 Subject: Removed unused imports. --- src/Protocol/Protocol17x.h | 1 - src/Protocol/Protocol18x.h | 1 - 2 files changed, 2 deletions(-) diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index 3865b086c..f939bfb5e 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -33,7 +33,6 @@ Declares the 1.7.x protocol classes: #include "PolarSSL++/AesCfb128Decryptor.h" #include "PolarSSL++/AesCfb128Encryptor.h" -#include "../Mobs/MonsterTypes.h" diff --git a/src/Protocol/Protocol18x.h b/src/Protocol/Protocol18x.h index 216639319..92d9825ef 100644 --- a/src/Protocol/Protocol18x.h +++ b/src/Protocol/Protocol18x.h @@ -32,7 +32,6 @@ Declares the 1.8.x protocol classes: #include "PolarSSL++/AesCfb128Decryptor.h" #include "PolarSSL++/AesCfb128Encryptor.h" -#include "../Mobs/MonsterTypes.h" -- cgit v1.2.3 From c673eb590f3ed656e78d8301598d84b534c65a48 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 29 Nov 2014 15:40:38 +0100 Subject: Mark StringToMobType() as deprecated. Use cMonster:StringToMobType() instead --- MCServer/Plugins/APIDump/APIDesc.lua | 2 +- src/Bindings/DeprecatedBindings.cpp | 38 ++++++++++++++++++++++++++++++++++++ src/Mobs/MonsterTypes.h | 10 +--------- 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 9b87781a6..731248805 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -2928,7 +2928,7 @@ end StringToDamageType = {Params = "string", Return = "{{Globals#DamageType|DamageType}}", Notes = "Converts a string representation to a {{Globals#DamageType|DamageType}} enumerated value."}, StringToDimension = {Params = "string", Return = "{{Globals#WorldDimension|Dimension}}", Notes = "Converts a string representation to a {{Globals#WorldDimension|Dimension}} enumerated value"}, StringToItem = {Params = "string, {{cItem|cItem}}", Return = "bool", Notes = "Parses the given string and sets the item; returns true if successful"}, - StringToMobType = {Params = "string", Return = "{{cMonster#MobType|MobType}}", Notes = "Converts a string representation to a {{cMonster#MobType|MobType}} enumerated value"}, + StringToMobType = {Params = "string", Return = "{{cMonster#MobType|MobType}}", Notes = "DEPRECATED! Please use cMonster:StringToMobType(). Converts a string representation to a {{cMonster#MobType|MobType}} enumerated value"}, StripColorCodes = {Params = "string", Return = "string", Notes = "Removes all control codes used by MC for colors and styles"}, TrimString = {Params = "string", Return = "string", Notes = "Trims whitespace at both ends of the string"}, md5 = {Params = "string", Return = "string", Notes = "converts a string to an md5 hash"}, diff --git a/src/Bindings/DeprecatedBindings.cpp b/src/Bindings/DeprecatedBindings.cpp index 345ab2a07..0b2539fde 100644 --- a/src/Bindings/DeprecatedBindings.cpp +++ b/src/Bindings/DeprecatedBindings.cpp @@ -225,6 +225,42 @@ static int tolua_get_AllToLua_g_BlockFullyOccupiesVoxel(lua_State* tolua_S) +/* function: StringToMobType */ +static int tolua_AllToLua_StringToMobType00(lua_State* tolua_S) +{ + cLuaState LuaState(tolua_S); + + #ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_iscppstring(tolua_S,1,0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else + #endif + { + const AString a_MobString = tolua_tocppstring(LuaState, 1, 0); + eMonsterType MobType = cMonster::StringToMobType(a_MobString); + tolua_pushnumber(LuaState, (lua_Number) MobType); + tolua_pushcppstring(LuaState, (const char *) a_MobString); + } + + LOGWARNING("Warning in function call 'StringToMobType': StringToMobType() is deprecated. Please use cMonster:StringToMobType()"); + LuaState.LogStackTrace(0); + return 2; + + #ifndef TOLUA_RELEASE +tolua_lerror: + tolua_error(LuaState, "#ferror in function 'StringToMobType'.", &tolua_err); + return 0; + #endif +} + + + + + /** function: cWorld:SetSignLines */ static int tolua_cWorld_SetSignLines(lua_State * tolua_S) { @@ -296,6 +332,8 @@ void DeprecatedBindings::Bind(lua_State * tolua_S) tolua_array(tolua_S, "g_BlockIsSolid", tolua_get_AllToLua_g_BlockIsSolid, nullptr); tolua_array(tolua_S, "g_BlockFullyOccupiesVoxel", tolua_get_AllToLua_g_BlockFullyOccupiesVoxel, nullptr); + tolua_function(tolua_S, "StringToMobType", tolua_AllToLua_StringToMobType00); + tolua_beginmodule(tolua_S, "cWorld"); tolua_function(tolua_S, "UpdateSign", tolua_cWorld_SetSignLines); tolua_endmodule(tolua_S); diff --git a/src/Mobs/MonsterTypes.h b/src/Mobs/MonsterTypes.h index 852eb3446..dc6dd3992 100644 --- a/src/Mobs/MonsterTypes.h +++ b/src/Mobs/MonsterTypes.h @@ -2,6 +2,7 @@ #pragma once /// This identifies individual monster type, as well as their network type-ID + // tolua_begin enum eMonsterType { @@ -38,15 +39,6 @@ enum eMonsterType mtZombiePigman = E_META_SPAWN_EGG_ZOMBIE_PIGMAN, } ; - - - - -/** Translates a mob string ("ocelot") to mobtype (mtOcelot). -OBSOLETE, use cMonster::StringToMobType() instead. -Implemented in Monster.cpp. */ -extern eMonsterType StringToMobType(const AString & a_MobString); - // tolua_end -- cgit v1.2.3 From ea20ccaa960f2eab1a249080bfa5bb870d0f5b6f Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 29 Nov 2014 15:45:12 +0100 Subject: Removed old MobType category. --- MCServer/Plugins/APIDump/APIDesc.lua | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 832540d3e..5a64345ca 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -1726,13 +1726,6 @@ a_Player:OpenWindow(Window); Mobs are divided into families. The following constants are used for individual family types: ]], }, - MobType = - { - Include = "mt.*", - TextBefore = [[ - The following constants are used for distinguishing between the individual mob types: - ]], - }, }, Inherits = "cPawn", }, -- cMonster @@ -3019,7 +3012,7 @@ end { Include = { "^mt.*" }, TextBefore = [[ - The following constants are used for the mob types. + The following constants are used for distinguishing between the individual mob types: ]], }, Weather = -- cgit v1.2.3 From 615bca156720a2027545cce7a0e7d403b0daca11 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 29 Nov 2014 16:00:52 +0100 Subject: Update core --- MCServer/Plugins/Core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MCServer/Plugins/Core b/MCServer/Plugins/Core index 470247194..5b7a6d464 160000 --- a/MCServer/Plugins/Core +++ b/MCServer/Plugins/Core @@ -1 +1 @@ -Subproject commit 4702471943511f641458c7e8e89b430a723f43ea +Subproject commit 5b7a6d464ed3e0e5d2a438ebf119430cacab26ae -- cgit v1.2.3 From 201313a9f84192ad7f2fcd7e4ab2cc793a85b96f Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sat, 29 Nov 2014 23:06:10 +0100 Subject: Added a basic stacktracing for assert and signal failures. --- src/Globals.h | 5 +++-- src/OSSupport/CMakeLists.txt | 8 ++++++-- src/OSSupport/StackTrace.cpp | 43 +++++++++++++++++++++++++++++++++++++++++++ src/OSSupport/StackTrace.h | 15 +++++++++++++++ src/main.cpp | 6 ++++++ 5 files changed, 73 insertions(+), 4 deletions(-) create mode 100644 src/OSSupport/StackTrace.cpp create mode 100644 src/OSSupport/StackTrace.h diff --git a/src/Globals.h b/src/Globals.h index 582f5fdaa..d75ae0093 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -264,6 +264,7 @@ template class SizeChecker; #include "OSSupport/Thread.h" #include "OSSupport/File.h" #include "Logger.h" + #include "OSSupport/StackTrace.h" #else // Logging functions void inline LOGERROR(const char* a_Format, ...) FORMATSTRING(1, 2); @@ -349,14 +350,14 @@ void inline LOGD(const char* a_Format, ...) #else #ifdef _DEBUG - #define ASSERT( x) ( !!(x) || ( LOGERROR("Assertion failed: %s, file %s, line %i", #x, __FILE__, __LINE__), assert(0), 0)) + #define ASSERT( x) ( !!(x) || ( LOGERROR("Assertion failed: %s, file %s, line %i", #x, __FILE__, __LINE__), PrintStackTrace(), assert(0), 0)) #else #define ASSERT(x) ((void)(x)) #endif #endif // Pretty much the same as ASSERT() but stays in Release builds -#define VERIFY( x) ( !!(x) || ( LOGERROR("Verification failed: %s, file %s, line %i", #x, __FILE__, __LINE__), exit(1), 0)) +#define VERIFY( x) ( !!(x) || ( LOGERROR("Verification failed: %s, file %s, line %i", #x, __FILE__, __LINE__), PrintStackTrace(), exit(1), 0)) // Same as assert but in all Self test builds #ifdef SELF_TEST diff --git a/src/OSSupport/CMakeLists.txt b/src/OSSupport/CMakeLists.txt index c3eabeef6..592525941 100644 --- a/src/OSSupport/CMakeLists.txt +++ b/src/OSSupport/CMakeLists.txt @@ -16,8 +16,10 @@ SET (SRCS Sleep.cpp Socket.cpp SocketThreads.cpp + StackTrace.cpp Thread.cpp - Timer.cpp) + Timer.cpp +) SET (HDRS CriticalSection.h @@ -32,8 +34,10 @@ SET (HDRS Sleep.h Socket.h SocketThreads.h + StackTrace.h Thread.h - Timer.h) + Timer.h +) if(NOT MSVC) add_library(OSSupport ${SRCS} ${HDRS}) diff --git a/src/OSSupport/StackTrace.cpp b/src/OSSupport/StackTrace.cpp new file mode 100644 index 000000000..57c547fa1 --- /dev/null +++ b/src/OSSupport/StackTrace.cpp @@ -0,0 +1,43 @@ + +// StackTrace.cpp + +// Implements the functions to print current stack traces + +#include "Globals.h" +#include "StackTrace.h" +#ifdef _WIN32 + #include "../StackWalker.h" +#else + #include +#endif + + + + + +void PrintStackTrace(void) +{ + #ifdef _WIN32 + // Reuse the StackWalker from the LeakFinder project already bound to MCS + // Define a subclass of the StackWalker that outputs everything to stdout + class PrintingStackWalker : + public StackWalker + { + virtual void OnOutput(LPCSTR szText) override + { + puts(szText); + } + } sw; + sw.ShowCallstack(); + #else + // Use the backtrace() function to get and output the stackTrace: + // Code adapted from http://stackoverflow.com/questions/77005/how-to-generate-a-stacktrace-when-my-gcc-c-app-crashes + void * stackTrace[30]; + size_t numItems = backtrace(stackTrace, ARRAYCOUNT(stackTrace)); + backtrace_symbols_fd(stackTrace, numItems, STDERR_FILENO); + #endif +} + + + + diff --git a/src/OSSupport/StackTrace.h b/src/OSSupport/StackTrace.h new file mode 100644 index 000000000..228a00077 --- /dev/null +++ b/src/OSSupport/StackTrace.h @@ -0,0 +1,15 @@ + +// StackTrace.h + +// Declares the functions to print current stack trace + + + + + +/** Prints the stacktrace for the current thread. */ +extern void PrintStackTrace(void); + + + + diff --git a/src/main.cpp b/src/main.cpp index c60e13a8c..0a8521fbc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,6 +10,7 @@ #ifdef _MSC_VER #include #endif // _MSC_VER +#include "OSSupport/StackTrace.h" bool cRoot::m_TerminateEventRaised = false; // If something has told the server to stop; checked periodically in cRoot @@ -61,6 +62,7 @@ void NonCtrlHandler(int a_Signal) std::signal(SIGSEGV, SIG_DFL); LOGERROR(" D: | MCServer has encountered an error and needs to close"); LOGERROR("Details | SIGSEGV: Segmentation fault"); + PrintStackTrace(); abort(); } case SIGABRT: @@ -71,6 +73,7 @@ void NonCtrlHandler(int a_Signal) std::signal(a_Signal, SIG_DFL); LOGERROR(" D: | MCServer has encountered an error and needs to close"); LOGERROR("Details | SIGABRT: Server self-terminated due to an internal fault"); + PrintStackTrace(); abort(); } case SIGINT: @@ -137,6 +140,9 @@ LONG WINAPI LastChanceExceptionFilter(__in struct _EXCEPTION_POINTERS * a_Except g_WriteMiniDump(GetCurrentProcess(), GetCurrentProcessId(), dumpFile, g_DumpFlags, (a_ExceptionInfo) ? &ExcInformation : nullptr, nullptr, nullptr); CloseHandle(dumpFile); + // Print the stack trace for the basic debugging: + PrintStackTrace(); + // Revert to old stack: _asm { -- cgit v1.2.3 From 8e6f98eb40375fbc3330b2ef9774d63760126bcd Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sat, 29 Nov 2014 23:30:27 +0100 Subject: Fixed missing files in ProtoProxy. --- Tools/ProtoProxy/CMakeLists.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Tools/ProtoProxy/CMakeLists.txt b/Tools/ProtoProxy/CMakeLists.txt index bc3923d90..fc8721da0 100644 --- a/Tools/ProtoProxy/CMakeLists.txt +++ b/Tools/ProtoProxy/CMakeLists.txt @@ -57,14 +57,22 @@ set(SHARED_OSS_SRC ../../src/OSSupport/CriticalSection.cpp ../../src/OSSupport/File.cpp ../../src/OSSupport/IsThread.cpp + ../../src/OSSupport/StackTrace.cpp ../../src/OSSupport/Timer.cpp ) set(SHARED_OSS_HDR ../../src/OSSupport/CriticalSection.h ../../src/OSSupport/File.h ../../src/OSSupport/IsThread.h + ../../src/OSSupport/StackTrace.h ../../src/OSSupport/Timer.h ) + +if(WIN32) + list (APPEND SHARED_OSS_SRC ../../src/StackWalker.cpp) + list (APPEND SHARED_OSS_HDR ../../src/StackWalker.h) +endif() + flatten_files(SHARED_SRC) flatten_files(SHARED_HDR) flatten_files(SHARED_OSS_SRC) -- cgit v1.2.3 From abbe18c0ab8a9966ffc2a2d86cbac7bc79cd77de Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sat, 29 Nov 2014 23:55:06 +0100 Subject: Fixed QtBiomeVisualiser compilation. --- Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro | 19 +++++++++++++++++-- src/Noise/Noise.cpp | 1 - 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro b/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro index 9522491a8..cccee1305 100644 --- a/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro +++ b/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro @@ -17,7 +17,7 @@ SOURCES += \ BiomeView.cpp \ ../../src/Generating/BioGen.cpp \ ../../src/VoronoiMap.cpp \ - ../../src/Noise.cpp \ + ../../src/Noise/Noise.cpp \ ../../src/StringUtils.cpp \ ../../src/LoggerListeners.cpp \ ../../src/Logger.cpp \ @@ -25,7 +25,9 @@ SOURCES += \ ../../src/OSSupport/File.cpp \ ../../src/OSSupport/CriticalSection.cpp \ ../../src/OSSupport/IsThread.cpp \ + ../../src/OSSupport/StackTrace.cpp \ ../../src/BiomeDef.cpp \ + ../../src/StackWalker.cpp \ ../../src/StringCompression.cpp \ ../../src/WorldStorage/FastNBT.cpp \ ../../lib/zlib/adler32.c \ @@ -62,7 +64,7 @@ HEADERS += \ ../../src/Generating/IntGen.h \ ../../src/Generating/ProtIntGen.h \ ../../src/VoronoiMap.h \ - ../../src/Noise.h \ + ../../src/Noise/Noise.h \ ../../src/StringUtils.h \ ../../src/LoggerListeners.h \ ../../src/Logger.h \ @@ -70,7 +72,9 @@ HEADERS += \ ../../src/OSSupport/File.h \ ../../src/OSSupport/CriticalSection.h \ ../../src/OSSupport/IsThread.h \ + ../../src/OSSupport/StackTrace.h \ ../../src/BiomeDef.h \ + ../../src/StackWalker.h \ ../../src/StringCompression.h \ ../../src/WorldStorage/FastNBT.h \ ../../lib/zlib/crc32.h \ @@ -107,4 +111,15 @@ CONFIG += C++11 OTHER_FILES += +win* { + # Add the advapi32 library for windows compiles; needed for the StackWalker: + LIBS += advapi32.lib + + # StackWalker doesn't like how Qt inconsistently defines only UNICODE, but not _UNICODE: + DEFINES -= UNICODE +} + + + + diff --git a/src/Noise/Noise.cpp b/src/Noise/Noise.cpp index 509be7d6c..0249ab6c1 100644 --- a/src/Noise/Noise.cpp +++ b/src/Noise/Noise.cpp @@ -2,7 +2,6 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "Noise.h" -#include "OSSupport/Timer.h" #define FAST_FLOOR(x) (((x) < 0) ? (((int)x) - 1) : ((int)x)) -- cgit v1.2.3 From e0a846d8059da4e470f57a63bf396d30f29c4043 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sat, 29 Nov 2014 23:55:15 +0100 Subject: Removed unneeded include. --- src/main.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 0a8521fbc..fe4b360a5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,7 +10,6 @@ #ifdef _MSC_VER #include #endif // _MSC_VER -#include "OSSupport/StackTrace.h" bool cRoot::m_TerminateEventRaised = false; // If something has told the server to stop; checked periodically in cRoot -- cgit v1.2.3 From dec89478a78a4feb9411de9c288134c55e0febcb Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sat, 29 Nov 2014 23:58:26 +0100 Subject: Fixed MCADefrag compilation. --- Tools/MCADefrag/CMakeLists.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Tools/MCADefrag/CMakeLists.txt b/Tools/MCADefrag/CMakeLists.txt index 42b42018b..618719d68 100644 --- a/Tools/MCADefrag/CMakeLists.txt +++ b/Tools/MCADefrag/CMakeLists.txt @@ -46,6 +46,7 @@ set(SHARED_HDR ../../src/ByteBuffer.h ../../src/StringUtils.h ) + flatten_files(SHARED_SRC) flatten_files(SHARED_HDR) source_group("Shared" FILES ${SHARED_SRC} ${SHARED_HDR}) @@ -54,15 +55,22 @@ set(SHARED_OSS_SRC ../../src/OSSupport/CriticalSection.cpp ../../src/OSSupport/File.cpp ../../src/OSSupport/IsThread.cpp + ../../src/OSSupport/StackTrace.cpp ../../src/OSSupport/Timer.cpp ) set(SHARED_OSS_HDR ../../src/OSSupport/CriticalSection.h ../../src/OSSupport/File.h ../../src/OSSupport/IsThread.h + ../../src/OSSupport/StackTrace.h ../../src/OSSupport/Timer.h ) +if(WIN32) + list (APPEND SHARED_OSS_SRC ../../src/StackWalker.cpp) + list (APPEND SHARED_OSS_HDR ../../src/StackWalker.h) +endif() + flatten_files(SHARED_OSS_SRC) flatten_files(SHARED_OSS_HDR) -- cgit v1.2.3 From c173bf61ad9106431e5466f12b8212940a00cf0c Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 30 Nov 2014 02:29:17 +0100 Subject: Removed old StringToMobType() function from Monster.cpp --- src/Mobs/Monster.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 5319bdf91..e422521b6 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -62,16 +62,6 @@ static const struct -eMonsterType StringToMobType(const AString & a_MobString) -{ - LOGWARNING("%s: Function is obsolete, use cMonster::StringToMobType() instead", __FUNCTION__); - return cMonster::StringToMobType(a_MobString); -} - - - - - //////////////////////////////////////////////////////////////////////////////// // cMonster: -- cgit v1.2.3 From a73c800377be83f6a4ed1cc16ba32f8deef4d27f Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 30 Nov 2014 11:11:47 +0100 Subject: Improved comments for cWorld::DoWithPlayer(). --- src/World.cpp | 2 +- src/World.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/World.cpp b/src/World.cpp index 0dec0bd96..84d40d53b 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -2678,7 +2678,7 @@ bool cWorld::ForEachPlayer(cPlayerListCallback & a_Callback) bool cWorld::DoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_Callback) { - // Calls the callback for each player in the list + // Calls the callback for the specified player in the list cCSLock Lock(m_CSPlayers); for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { diff --git a/src/World.h b/src/World.h index 68d0654ee..31bc9dad6 100644 --- a/src/World.h +++ b/src/World.h @@ -315,7 +315,8 @@ public: /** Calls the callback for each player in the list; returns true if all players processed, false if the callback aborted by returning true */ virtual bool ForEachPlayer(cPlayerListCallback & a_Callback) override; // >> EXPORTED IN MANUALBINDINGS << - /** Calls the callback for the player of the given name; returns true if the player was found and the callback called, false if player not found. Callback return ignored */ + /** Calls the callback for the player of the given name; returns true if the player was found and the callback called, false if player not found. + Callback return value is ignored. If there are multiple players of the same name, only (random) one is processed by the callback. */ bool DoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS << /** Finds a player from a partial or complete player name and calls the callback - case-insensitive */ -- cgit v1.2.3 From 7049db5bf88e6a75f108fa0640dfb9ada85fadff Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 30 Nov 2014 14:23:51 +0100 Subject: Fixed compiling on linux. --- src/OSSupport/StackTrace.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/OSSupport/StackTrace.cpp b/src/OSSupport/StackTrace.cpp index 57c547fa1..a56568457 100644 --- a/src/OSSupport/StackTrace.cpp +++ b/src/OSSupport/StackTrace.cpp @@ -9,6 +9,7 @@ #include "../StackWalker.h" #else #include + #include #endif -- cgit v1.2.3 From 65dc452923f8db74f0fcb3869d4301cb10ee1ca6 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 30 Nov 2014 16:34:41 +0100 Subject: Fixed nether ceiling --- src/Generating/CompoGen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Generating/CompoGen.cpp b/src/Generating/CompoGen.cpp index 23cc64d78..6c3b50b4e 100644 --- a/src/Generating/CompoGen.cpp +++ b/src/Generating/CompoGen.cpp @@ -324,7 +324,7 @@ void cCompoGenNether::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc: CeilingDisguise = -CeilingDisguise; } - int CeilingDisguiseHeight = Height - 2 - (int)CeilingDisguise * 3; + int CeilingDisguiseHeight = Height - 2 - FloorC(CeilingDisguise * 3); for (int y = Height - 1; y > CeilingDisguiseHeight; y--) { -- cgit v1.2.3 From db0f791d431a7ed690139515a42a946fc35a6a36 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 30 Nov 2014 18:19:20 +0100 Subject: Fixed a crash in cSpawnPrepare. --- src/World.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/World.cpp b/src/World.cpp index 84d40d53b..5fe64ea3a 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -164,6 +164,8 @@ protected: if (m_NumPrepared >= m_MaxIdx) { m_EvtFinished.Set(); + // Must return here, because "this" may have gotten deleted by the previous line + return; } // Queue another chunk, if appropriate: -- cgit v1.2.3 From e972c52e540ca49214d378207e2064f80bcb7983 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 30 Nov 2014 18:44:44 +0100 Subject: Hopefully fixed random build fails --- src/Generating/FinishGen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index 2ff3e7f67..1e8a67dd0 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -516,7 +516,7 @@ void cFinishGenSingleTopBlock::GenFinish(cChunkDesc & a_ChunkDesc) } int Height = a_ChunkDesc.GetHeight(x, z); - if (Height >= cChunkDef::Height) + if (Height >= cChunkDef::Height - 1) { // Too high up continue; -- cgit v1.2.3 From f0ad6221c3a409e7cc9cde631c50bc026486b4ae Mon Sep 17 00:00:00 2001 From: Mattes D Date: Mon, 1 Dec 2014 00:08:44 +0100 Subject: Noise3D: Fixed missing initialization. This should fix terrain being at Y=0 or Y=255 for the spawn chunk. Fixes #1433. --- src/Generating/Noise3DGenerator.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Generating/Noise3DGenerator.cpp b/src/Generating/Noise3DGenerator.cpp index a7af87bac..57e23809e 100644 --- a/src/Generating/Noise3DGenerator.cpp +++ b/src/Generating/Noise3DGenerator.cpp @@ -529,7 +529,9 @@ cBiomalNoise3DComposable::cBiomalNoise3DComposable(int a_Seed, cBiomeGenPtr a_Bi m_DensityNoiseA(a_Seed + 1), m_DensityNoiseB(a_Seed + 2), m_BaseNoise(a_Seed + 3), - m_BiomeGen(a_BiomeGen) + m_BiomeGen(a_BiomeGen), + m_LastChunkX(0x7fffffff), // Set impossible coords for the chunk so that it's always considered stale + m_LastChunkZ(0x7fffffff) { // Generate the weight distribution for summing up neighboring biomes: m_WeightSum = 0; -- cgit v1.2.3 From cc313c91ab0e62f269e30c9f525919b7b7bc61f5 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Mon, 1 Dec 2014 00:14:27 +0100 Subject: DistortedHeightmap: Added missing initialization. This was probably the original cause for the "empty chunks". Fixes #1433. --- src/Generating/DistortedHeightmap.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Generating/DistortedHeightmap.cpp b/src/Generating/DistortedHeightmap.cpp index e1ed9b450..37a51c18e 100644 --- a/src/Generating/DistortedHeightmap.cpp +++ b/src/Generating/DistortedHeightmap.cpp @@ -122,6 +122,8 @@ const cDistortedHeightmap::sGenParam cDistortedHeightmap::m_GenParam[256] = cDistortedHeightmap::cDistortedHeightmap(int a_Seed, cBiomeGenPtr a_BiomeGen) : m_NoiseDistortX(a_Seed + 1000), m_NoiseDistortZ(a_Seed + 2000), + m_CurChunkX(0x7fffffff), // Set impossible coords for the chunk so that it's always considered stale + m_CurChunkZ(0x7fffffff), m_BiomeGen(a_BiomeGen), m_UnderlyingHeiGen(new cHeiGenBiomal(a_Seed, a_BiomeGen)), m_HeightGen(m_UnderlyingHeiGen, 64), -- cgit v1.2.3 From bcbd73f7d80b0a64b87c30840048f99613308ce0 Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 1 Dec 2014 14:58:13 +0100 Subject: MobSpawner fixes. --- MCServer/Plugins/APIDump/APIDesc.lua | 2 +- src/BlockEntities/BlockEntity.cpp | 2 +- src/BlockEntities/MobSpawnerEntity.cpp | 4 ++-- src/BlockEntities/MobSpawnerEntity.h | 7 +++++++ src/Mobs/Monster.cpp | 1 + src/Mobs/Monster.h | 2 +- src/WorldStorage/WSSAnvil.cpp | 2 +- 7 files changed, 14 insertions(+), 6 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index ecb8f6226..72dcce5e4 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -1673,7 +1673,7 @@ a_Player:OpenWindow(Window); GetMobType = { Params = "", Return = "{{Globals#MobType|MobType}}", Notes = "Returns the type of this mob ({{Globals#MobType|mtXXX}} constant)" }, GetSpawnDelay = { Params = "{{cMonster#MobFamily|MobFamily}}", Return = "number", Notes = "(STATIC) Returns the spawn delay - the number of game ticks between spawn attempts - for the specified mob family." }, MobTypeToString = { Params = "{{Globals#MobType|MobType}}", Return = "string", Notes = "(STATIC) Returns the string representing the given mob type ({{Globals#MobType|mtXXX}} constant), or empty string if unknown type." }, - MobTypeToVanillaName = { Params = "{{Globals#MobType|MobType}}", Return = "string", Notes = "(STATIC) Returns the correct vanilla name of the given mob type, or empty string if unknown type." }, + MobTypeToVanillaName = { Params = "{{Globals#MobType|MobType}}", Return = "string", Notes = "(STATIC) Returns the vanilla name of the given mob type, or empty string if unknown type." }, MoveToPosition = { Params = "Position", Return = "", Notes = "Moves mob to the specified position" }, StringToMobType = { Params = "string", Return = "{{Globals#MobType|MobType}}", Notes = "(STATIC) Returns the mob type ({{Globals#MobType|mtXXX}} constant) parsed from the string type (\"creeper\"), or mtInvalidType if unrecognized." }, GetRelativeWalkSpeed = { Params = "", Return = "number", Notes = "Returns the relative walk speed of this mob. Standard is 1.0" }, diff --git a/src/BlockEntities/BlockEntity.cpp b/src/BlockEntities/BlockEntity.cpp index 346970cd2..c59198e79 100644 --- a/src/BlockEntities/BlockEntity.cpp +++ b/src/BlockEntities/BlockEntity.cpp @@ -36,8 +36,8 @@ cBlockEntity * cBlockEntity::CreateByBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE case E_BLOCK_ENDER_CHEST: return new cEnderChestEntity (a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_FLOWER_POT: return new cFlowerPotEntity (a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_FURNACE: return new cFurnaceEntity (a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_World); - case E_BLOCK_HOPPER: return new cHopperEntity (a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_HEAD: return new cMobHeadEntity (a_BlockX, a_BlockY, a_BlockZ, a_World); + case E_BLOCK_HOPPER: return new cHopperEntity (a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_MOB_SPAWNER: return new cMobSpawnerEntity (a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_JUKEBOX: return new cJukeboxEntity (a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_LIT_FURNACE: return new cFurnaceEntity (a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_World); diff --git a/src/BlockEntities/MobSpawnerEntity.cpp b/src/BlockEntities/MobSpawnerEntity.cpp index 26499972d..5edee888a 100644 --- a/src/BlockEntities/MobSpawnerEntity.cpp +++ b/src/BlockEntities/MobSpawnerEntity.cpp @@ -104,7 +104,7 @@ bool cMobSpawnerEntity::Tick(float a_Dt, cChunk & a_Chunk) void cMobSpawnerEntity::ResetTimer(void) { - m_SpawnDelay = (short) (200 + m_World->GetTickRandomNumber(600)); + m_SpawnDelay = static_cast(200 + m_World->GetTickRandomNumber(600)); m_World->BroadcastBlockEntity(m_PosX, m_PosY, m_PosZ); } @@ -266,7 +266,7 @@ int cMobSpawnerEntity::GetNearbyMonsterNum(eMonsterType a_EntityType) return; } - if (((m_SpawnerPos - a_Entity->GetPosition()).Length() <= 8) && (Diff(m_SpawnerPos.y, a_Entity->GetPosY()) <= 4.0)) + if ((Diff(m_SpawnerPos.x, a_Entity->GetPosX()) <= 8.0) && (Diff(m_SpawnerPos.y, a_Entity->GetPosY()) <= 4.0) && (Diff(m_SpawnerPos.z, a_Entity->GetPosZ()) <= 8.0)) { m_NumEntities++; } diff --git a/src/BlockEntities/MobSpawnerEntity.h b/src/BlockEntities/MobSpawnerEntity.h index 0a3367c97..594b5301e 100644 --- a/src/BlockEntities/MobSpawnerEntity.h +++ b/src/BlockEntities/MobSpawnerEntity.h @@ -1,3 +1,10 @@ +// MobSpawnerEntity.h + +// Declares the cMobSpawnerEntity class representing a single mob spawner in the world + + + + #pragma once diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 3011acd85..b8926e31d 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -21,6 +21,7 @@ /** Map for eType <-> string Needs to be alpha-sorted by the strings, because binary search is used in StringToMobType() The strings need to be lowercase (for more efficient comparisons in StringToMobType()) +m_VanillaName is the name that vanilla use for this mob. */ static const struct { diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h index 4903c38ad..f04e45ac6 100644 --- a/src/Mobs/Monster.h +++ b/src/Mobs/Monster.h @@ -136,7 +136,7 @@ public: /** Translates MobType enum to a string, empty string if unknown */ static AString MobTypeToString(eMonsterType a_MobType); - /** Translates MobType enum to the correct vanilla name of the mob, empty string if unknown. */ + /** Translates MobType enum to the vanilla name of the mob, empty string if unknown. */ static AString MobTypeToVanillaName(eMonsterType a_MobType); /** Translates MobType string to the enum, mtInvalidType if not recognized */ diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 4520751c7..ddee5e514 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -1095,7 +1095,7 @@ cBlockEntity * cWSSAnvil::LoadMobSpawnerFromNBT(const cParsedNBT & a_NBT, int a_ return nullptr; } - std::auto_ptr MobSpawner(new cMobSpawnerEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); + std::unique_ptr MobSpawner(new cMobSpawnerEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); // Load entity (MCServer worlds): int Type = a_NBT.FindChildByName(a_TagIdx, "Entity"); -- cgit v1.2.3 From e74ad386f076348114d871842265c81d2bb7b87e Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 1 Dec 2014 16:04:49 +0100 Subject: Reverted bad .gitignore change --- MCServer/Plugins/.gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MCServer/Plugins/.gitignore b/MCServer/Plugins/.gitignore index 92424459f..8553945b5 100644 --- a/MCServer/Plugins/.gitignore +++ b/MCServer/Plugins/.gitignore @@ -1,3 +1,3 @@ *.txt *.md - +*/ -- cgit v1.2.3 From 3bf9e978aea9dd66bfb56dce6eb5ffc56853d0c8 Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 1 Dec 2014 16:05:22 +0100 Subject: Updated core --- MCServer/Plugins/Core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MCServer/Plugins/Core b/MCServer/Plugins/Core index 5b7a6d464..4183d6cfb 160000 --- a/MCServer/Plugins/Core +++ b/MCServer/Plugins/Core @@ -1 +1 @@ -Subproject commit 5b7a6d464ed3e0e5d2a438ebf119430cacab26ae +Subproject commit 4183d6cfb2049d0757d811a65bd4e75ed78b9f41 -- cgit v1.2.3 From fa4a85c91518575e600fbd5755dda179931d9436 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 1 Dec 2014 16:36:48 +0100 Subject: Added better soulsand rims As a finisher called SoulsandRims --- src/Generating/CompoGen.cpp | 12 +---- src/Generating/ComposableGenerator.cpp | 4 ++ src/Generating/FinishGen.cpp | 82 ++++++++++++++++++++++++++++++++++ src/Generating/FinishGen.h | 19 ++++++++ src/World.cpp | 2 +- 5 files changed, 107 insertions(+), 12 deletions(-) diff --git a/src/Generating/CompoGen.cpp b/src/Generating/CompoGen.cpp index 6c3b50b4e..cb9c04fd7 100644 --- a/src/Generating/CompoGen.cpp +++ b/src/Generating/CompoGen.cpp @@ -290,17 +290,7 @@ void cCompoGenNether::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc: BLOCKTYPE Block = E_BLOCK_AIR; if (Val < m_Threshold) // Don't calculate if the block should be Netherrack or Soulsand when it's already decided that it's air. { - NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(BaseX + x)) / 8; - NOISE_DATATYPE NoiseY = ((NOISE_DATATYPE)(BaseZ + z)) / 8; - NOISE_DATATYPE CompBlock = m_Noise1.CubicNoise3D(NoiseX, (float) (y + Segment) / 2, NoiseY); - if (CompBlock < -0.5) - { - Block = E_BLOCK_SOULSAND; - } - else - { - Block = E_BLOCK_NETHERRACK; - } + Block = E_BLOCK_NETHERRACK; } a_ChunkDesc.SetBlockType(x, y + Segment, z, Block); } diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index 4192dfa72..6b8923955 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -570,6 +570,10 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) GridSize, MaxOffset ))); } + else if (NoCaseCompare(*itr, "SoulsandRims") == 0) + { + m_FinishGens.push_back(cFinishGenPtr(new cFinishGenSoulsandRims(Seed))); + } else if (NoCaseCompare(*itr, "Snow") == 0) { m_FinishGens.push_back(cFinishGenPtr(new cFinishGenSnow)); diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index 1e8a67dd0..898a9b268 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -391,6 +391,88 @@ void cFinishGenSprinkleFoliage::GenFinish(cChunkDesc & a_ChunkDesc) +//////////////////////////////////////////////////////////////////////////////// +// cFinishGenSoulsandRims + +void cFinishGenSoulsandRims::GenFinish(cChunkDesc & a_ChunkDesc) +{ + int ChunkX = a_ChunkDesc.GetChunkX() * cChunkDef::Width; + int ChunkZ = a_ChunkDesc.GetChunkZ() * cChunkDef::Width; + HEIGHTTYPE MaxHeight = a_ChunkDesc.GetMaxHeight(); + + for (int x = 0; x < 16; x++) + { + int xx = ChunkX + x; + for (int z = 0; z < 16; z++) + { + int zz = ChunkZ + z; + + // Place soulsand rims when netherrack gets thin + for (int y = 2; y < MaxHeight - 2; y++) + { + // The current block is air. Let's bail ut. + BLOCKTYPE Block = a_ChunkDesc.GetBlockType(x, y, z); + if (Block == E_BLOCK_AIR) + { + continue; + } + + // Check how many blocks there are above the current block. Don't go higher than 2 blocks, because we already bail out if that's the case. + int NumBlocksAbove = 0; + for (int I = y + 1; I <= y + 2; I++) + { + if (a_ChunkDesc.GetBlockType(x, I, z) != E_BLOCK_AIR) + { + NumBlocksAbove++; + } + else + { + break; + } + } + + // There are too many blocks above the current block. + if (NumBlocksAbove == 2) + { + continue; + } + + // Check how many blocks there below the current block. Don't go lower than 2 blocks, because we already bail out if that's the case. + int NumBlocksBelow = 0; + for (int I = y - 1; I >= y - 2; I--) + { + if (a_ChunkDesc.GetBlockType(x, I, z) != E_BLOCK_AIR) + { + NumBlocksBelow++; + } + else + { + break; + } + } + + // There are too many blocks below the current block + if (NumBlocksBelow == 2) + { + continue; + } + + NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(xx)) / 32; + NOISE_DATATYPE NoiseY = ((NOISE_DATATYPE)(zz)) / 32; + NOISE_DATATYPE CompBlock = m_Noise.CubicNoise3D(NoiseX, (float) (y) / 4, NoiseY); + if (CompBlock < 0) + { + a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_SOULSAND); + } + } + } + } +} + + + + + //////////////////////////////////////////////////////////////////////////////// // cFinishGenSnow: diff --git a/src/Generating/FinishGen.h b/src/Generating/FinishGen.h index 991a85787..d45365683 100644 --- a/src/Generating/FinishGen.h +++ b/src/Generating/FinishGen.h @@ -117,6 +117,25 @@ protected: +class cFinishGenSoulsandRims : + public cFinishGen +{ +public: + cFinishGenSoulsandRims(int a_Seed) : + m_Noise(a_Seed) + { + } + +protected: + cNoise m_Noise; + + virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; +} ; + + + + + class cFinishGenSprinkleFoliage : public cFinishGen { diff --git a/src/World.cpp b/src/World.cpp index 5fe64ea3a..00c8caf13 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -759,7 +759,7 @@ void cWorld::InitialiseGeneratorDefaults(cIniFile & a_IniFile) a_IniFile.GetValueSet("Generator", "HeightGen", "Flat"); a_IniFile.GetValueSet("Generator", "FlatHeight", "128"); a_IniFile.GetValueSet("Generator", "CompositionGen", "Nether"); - a_IniFile.GetValueSet("Generator", "Finishers", "WormNestCaves, BottomLava, LavaSprings, NetherClumpFoliage, NetherForts, PreSimulator"); + a_IniFile.GetValueSet("Generator", "Finishers", "SoulsandRims, WormNestCaves, BottomLava, LavaSprings, NetherClumpFoliage, NetherForts, PreSimulator"); a_IniFile.GetValueSet("Generator", "BottomLavaHeight", "30"); break; } -- cgit v1.2.3 From 1bf0827a2f88b84df010e24ef52a5d472bd55eb7 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 1 Dec 2014 17:29:35 +0100 Subject: Simplefied SoulsandRims Replaced two for loops with a single if --- src/Generating/FinishGen.cpp | 42 ++++++------------------------------------ 1 file changed, 6 insertions(+), 36 deletions(-) diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index 898a9b268..b9d702429 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -417,42 +417,12 @@ void cFinishGenSoulsandRims::GenFinish(cChunkDesc & a_ChunkDesc) continue; } - // Check how many blocks there are above the current block. Don't go higher than 2 blocks, because we already bail out if that's the case. - int NumBlocksAbove = 0; - for (int I = y + 1; I <= y + 2; I++) - { - if (a_ChunkDesc.GetBlockType(x, I, z) != E_BLOCK_AIR) - { - NumBlocksAbove++; - } - else - { - break; - } - } - - // There are too many blocks above the current block. - if (NumBlocksAbove == 2) - { - continue; - } - - // Check how many blocks there below the current block. Don't go lower than 2 blocks, because we already bail out if that's the case. - int NumBlocksBelow = 0; - for (int I = y - 1; I >= y - 2; I--) - { - if (a_ChunkDesc.GetBlockType(x, I, z) != E_BLOCK_AIR) - { - NumBlocksBelow++; - } - else - { - break; - } - } - - // There are too many blocks below the current block - if (NumBlocksBelow == 2) + if ( + ((a_ChunkDesc.GetBlockType(x, y + 1, z) != E_BLOCK_AIR) && + ( a_ChunkDesc.GetBlockType(x, y + 2, z) != E_BLOCK_AIR)) || + ((a_ChunkDesc.GetBlockType(x, y - 1, z) != E_BLOCK_AIR) && + ( a_ChunkDesc.GetBlockType(x, y - 2, z) != E_BLOCK_AIR)) + ) { continue; } -- cgit v1.2.3 From c0b08a6c1e4666c1d3044a264fc47711e821ce14 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 1 Dec 2014 17:51:20 +0100 Subject: Dungeons spawners now spawn mobs 25% for a spider, 25% for a skeleton and 50% for a zombie spawner. --- src/Generating/DungeonRoomsFinisher.cpp | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/Generating/DungeonRoomsFinisher.cpp b/src/Generating/DungeonRoomsFinisher.cpp index 7ab22c2c5..0267c41fa 100644 --- a/src/Generating/DungeonRoomsFinisher.cpp +++ b/src/Generating/DungeonRoomsFinisher.cpp @@ -7,6 +7,7 @@ #include "DungeonRoomsFinisher.h" #include "../FastRandom.h" #include "../BlockEntities/ChestEntity.h" +#include "../BlockEntities/MobSpawnerEntity.h" @@ -57,6 +58,22 @@ public: int SecondChestPos = (FirstChestPos + 2 + (rnd % (NumPositions - 3))) % NumPositions; m_Chest1 = DecodeChestCoords(FirstChestPos, SizeX, SizeZ); m_Chest2 = DecodeChestCoords(SecondChestPos, SizeX, SizeZ); + + // Choose what the mobspawner will spawn. + // 25% chance for a spider, 25% for a skeleton and 50% chance to get a zombie spawer. + NOISE_DATATYPE MobType = a_Noise.IntNoise3D(a_OriginX, m_FloorHeight, a_OriginZ); + if (MobType <= -0.5) + { + m_MonsterType = mtSkeleton; + } + else if (MobType <= 0) + { + m_MonsterType = mtSpider; + } + else + { + m_MonsterType = mtZombie; + } } protected: @@ -76,6 +93,8 @@ protected: /** The (absolute) coords of the second chest. The Y coord represents the chest's Meta value (facing). */ Vector3i m_Chest2; + /** The monster type for the mobspawner entity. */ + eMonsterType m_MonsterType; /** Decodes the position index along the room walls into a proper 2D position for a chest. @@ -246,7 +265,9 @@ protected: ) { a_ChunkDesc.SetBlockTypeMeta(CenterX, b, CenterZ, E_BLOCK_MOB_SPAWNER, 0); - // TODO: Set the spawned mob + cMobSpawnerEntity * MobSpawner = (cMobSpawnerEntity *)a_ChunkDesc.GetBlockEntity(CenterX, b, CenterZ); + ASSERT((MobSpawner != nullptr) && (MobSpawner->GetBlockType() == E_BLOCK_MOB_SPAWNER)); + MobSpawner->SetEntity(m_MonsterType); } } } ; -- cgit v1.2.3 From 25e3869485106966aebbf0041f416d61c41114db Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 1 Dec 2014 18:47:39 +0100 Subject: Mineshaft spawners now spawn cave spiders --- src/Generating/MineShafts.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Generating/MineShafts.cpp b/src/Generating/MineShafts.cpp index 55b3b64dd..33835160c 100644 --- a/src/Generating/MineShafts.cpp +++ b/src/Generating/MineShafts.cpp @@ -20,6 +20,7 @@ in a depth-first processing. Each of the descendants will branch randomly, if no #include "MineShafts.h" #include "../Cuboid.h" #include "../BlockEntities/ChestEntity.h" +#include "../BlockEntities/MobSpawnerEntity.h" @@ -875,7 +876,9 @@ void cMineShaftCorridor::PlaceSpawner(cChunkDesc & a_ChunkDesc) ) { a_ChunkDesc.SetBlockTypeMeta(SpawnerRelX, m_BoundingBox.p1.y + 1, SpawnerRelZ, E_BLOCK_MOB_SPAWNER, 0); - // TODO: The spawner needs its accompanying cMobSpawnerEntity, when implemented + cMobSpawnerEntity * MobSpawner = (cMobSpawnerEntity *)a_ChunkDesc.GetBlockEntity(SpawnerRelX, m_BoundingBox.p1.y + 1, SpawnerRelZ); + ASSERT((MobSpawner != nullptr) && (MobSpawner->GetBlockType() == E_BLOCK_MOB_SPAWNER)); + MobSpawner->SetEntity(mtCaveSpider); } } -- cgit v1.2.3 From ca728da9b6c0ac433907ee95db622ec961facd1f Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 1 Dec 2014 19:05:44 +0100 Subject: Using static cast for MineShaft spawners --- src/Generating/MineShafts.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Generating/MineShafts.cpp b/src/Generating/MineShafts.cpp index 33835160c..65588ce4b 100644 --- a/src/Generating/MineShafts.cpp +++ b/src/Generating/MineShafts.cpp @@ -876,7 +876,7 @@ void cMineShaftCorridor::PlaceSpawner(cChunkDesc & a_ChunkDesc) ) { a_ChunkDesc.SetBlockTypeMeta(SpawnerRelX, m_BoundingBox.p1.y + 1, SpawnerRelZ, E_BLOCK_MOB_SPAWNER, 0); - cMobSpawnerEntity * MobSpawner = (cMobSpawnerEntity *)a_ChunkDesc.GetBlockEntity(SpawnerRelX, m_BoundingBox.p1.y + 1, SpawnerRelZ); + cMobSpawnerEntity * MobSpawner = static_cast(a_ChunkDesc.GetBlockEntity(SpawnerRelX, m_BoundingBox.p1.y + 1, SpawnerRelZ)); ASSERT((MobSpawner != nullptr) && (MobSpawner->GetBlockType() == E_BLOCK_MOB_SPAWNER)); MobSpawner->SetEntity(mtCaveSpider); } -- cgit v1.2.3 From 7586069829af86a03f900daebc0cbf9622071f30 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 1 Dec 2014 19:07:54 +0100 Subject: Using static cast for Dungeon spawners --- src/Generating/DungeonRoomsFinisher.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Generating/DungeonRoomsFinisher.cpp b/src/Generating/DungeonRoomsFinisher.cpp index 0267c41fa..492ab1ed9 100644 --- a/src/Generating/DungeonRoomsFinisher.cpp +++ b/src/Generating/DungeonRoomsFinisher.cpp @@ -265,7 +265,7 @@ protected: ) { a_ChunkDesc.SetBlockTypeMeta(CenterX, b, CenterZ, E_BLOCK_MOB_SPAWNER, 0); - cMobSpawnerEntity * MobSpawner = (cMobSpawnerEntity *)a_ChunkDesc.GetBlockEntity(CenterX, b, CenterZ); + cMobSpawnerEntity * MobSpawner = static_cast(a_ChunkDesc.GetBlockEntity(CenterX, b, CenterZ)); ASSERT((MobSpawner != nullptr) && (MobSpawner->GetBlockType() == E_BLOCK_MOB_SPAWNER)); MobSpawner->SetEntity(m_MonsterType); } -- cgit v1.2.3 From cb584a87bd8336d590941cec0c204cbf75ab53eb Mon Sep 17 00:00:00 2001 From: p-mcgowan Date: Mon, 1 Dec 2014 11:44:20 -0800 Subject: cacti no longer spawn outside of desert variants --- src/Generating/FinishGen.cpp | 14 +++++++++++++- src/Generating/FinishGen.h | 3 +++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index b9d702429..e09646758 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -370,7 +370,8 @@ void cFinishGenSprinkleFoliage::GenFinish(cChunkDesc & a_ChunkDesc) (a_ChunkDesc.GetBlockType(x + 1, y, z) == E_BLOCK_AIR) && (a_ChunkDesc.GetBlockType(x - 1, y, z) == E_BLOCK_AIR) && (a_ChunkDesc.GetBlockType(x, y, z + 1) == E_BLOCK_AIR) && - (a_ChunkDesc.GetBlockType(x, y, z - 1) == E_BLOCK_AIR) + (a_ChunkDesc.GetBlockType(x, y, z - 1) == E_BLOCK_AIR) && + IsDesertVariant(a_ChunkDesc.GetBiome(x, z) ) { a_ChunkDesc.SetBlockType(x, ++Top, z, E_BLOCK_CACTUS); @@ -391,6 +392,17 @@ void cFinishGenSprinkleFoliage::GenFinish(cChunkDesc & a_ChunkDesc) +bool cFinishGenSprinkleFoliage::IsDesertVariant(EMCSBiome a_biome) +{ + return a_biome == biDesertHills || + a_biome == biDesert || + a_biome == biDesertM; +} + + + + + //////////////////////////////////////////////////////////////////////////////// // cFinishGenSoulsandRims diff --git a/src/Generating/FinishGen.h b/src/Generating/FinishGen.h index d45365683..16128efa5 100644 --- a/src/Generating/FinishGen.h +++ b/src/Generating/FinishGen.h @@ -149,6 +149,9 @@ protected: /// Tries to place sugarcane at the coords specified, returns true if successful bool TryAddSugarcane(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelY, int a_RelZ); + // Checks if biome is a desert to spawn cacti as opposed to just sand + bool IsDesertVariant(EMCSBiome a_biome); + // cFinishGen override: virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; } ; -- cgit v1.2.3 From 3bf111c69e11623947da70520063c57238d67bf0 Mon Sep 17 00:00:00 2001 From: p-mcgowan Date: Mon, 1 Dec 2014 17:28:46 -0800 Subject: formatting and commenting fixes --- src/Generating/FinishGen.cpp | 8 ++++---- src/Generating/FinishGen.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index e09646758..cba45c0a1 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -392,11 +392,11 @@ void cFinishGenSprinkleFoliage::GenFinish(cChunkDesc & a_ChunkDesc) -bool cFinishGenSprinkleFoliage::IsDesertVariant(EMCSBiome a_biome) +bool cFinishGenSprinkleFoliage::IsDesertVariant(EMCSBiome a_Biome) { - return a_biome == biDesertHills || - a_biome == biDesert || - a_biome == biDesertM; + return (a_Biome == biDesertHills) || + (a_Biome == biDesert ) || + (a_Biome == biDesertM ); } diff --git a/src/Generating/FinishGen.h b/src/Generating/FinishGen.h index 16128efa5..dd6a09c6a 100644 --- a/src/Generating/FinishGen.h +++ b/src/Generating/FinishGen.h @@ -149,8 +149,8 @@ protected: /// Tries to place sugarcane at the coords specified, returns true if successful bool TryAddSugarcane(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelY, int a_RelZ); - // Checks if biome is a desert to spawn cacti as opposed to just sand - bool IsDesertVariant(EMCSBiome a_biome); + // Returns true is the specified biome is a desert or its variant + static bool IsDesertVariant(EMCSBiome a_biome); // cFinishGen override: virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; -- cgit v1.2.3 From bb5a7d8f151bc7c2426f16becc5f7a0c70ca7fef Mon Sep 17 00:00:00 2001 From: p-mcgowan Date: Mon, 1 Dec 2014 17:47:36 -0800 Subject: reformat for lua and CI --- src/Generating/FinishGen.cpp | 13 ++++++++----- src/Generating/FinishGen.h | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index cba45c0a1..7ef658dc2 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -371,7 +371,7 @@ void cFinishGenSprinkleFoliage::GenFinish(cChunkDesc & a_ChunkDesc) (a_ChunkDesc.GetBlockType(x - 1, y, z) == E_BLOCK_AIR) && (a_ChunkDesc.GetBlockType(x, y, z + 1) == E_BLOCK_AIR) && (a_ChunkDesc.GetBlockType(x, y, z - 1) == E_BLOCK_AIR) && - IsDesertVariant(a_ChunkDesc.GetBiome(x, z) + IsDesertVariant(a_ChunkDesc.GetBiome(x, z)) ) { a_ChunkDesc.SetBlockType(x, ++Top, z, E_BLOCK_CACTUS); @@ -394,9 +394,12 @@ void cFinishGenSprinkleFoliage::GenFinish(cChunkDesc & a_ChunkDesc) bool cFinishGenSprinkleFoliage::IsDesertVariant(EMCSBiome a_Biome) { - return (a_Biome == biDesertHills) || - (a_Biome == biDesert ) || - (a_Biome == biDesertM ); + return + ( + (a_Biome == biDesertHills) || + (a_Biome == biDesert) || + (a_Biome == biDesertM) + ); } @@ -412,7 +415,7 @@ void cFinishGenSoulsandRims::GenFinish(cChunkDesc & a_ChunkDesc) int ChunkZ = a_ChunkDesc.GetChunkZ() * cChunkDef::Width; HEIGHTTYPE MaxHeight = a_ChunkDesc.GetMaxHeight(); - for (int x = 0; x < 16; x++) + for (int x = 0; x < 16; x++) { int xx = ChunkX + x; for (int z = 0; z < 16; z++) diff --git a/src/Generating/FinishGen.h b/src/Generating/FinishGen.h index dd6a09c6a..d8d67671d 100644 --- a/src/Generating/FinishGen.h +++ b/src/Generating/FinishGen.h @@ -121,7 +121,7 @@ class cFinishGenSoulsandRims : public cFinishGen { public: - cFinishGenSoulsandRims(int a_Seed) : + cFinishGenSoulsandRims(int a_Seed) : m_Noise(a_Seed) { } -- cgit v1.2.3 From ae47c00547f7bfd114f10aa2696f08b38ce3aea2 Mon Sep 17 00:00:00 2001 From: p-mcgowan Date: Mon, 1 Dec 2014 22:11:28 -0800 Subject: added spawning rule to mooshroom --- src/MobSpawner.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/MobSpawner.cpp b/src/MobSpawner.cpp index a1d375e9e..b8f64807e 100644 --- a/src/MobSpawner.cpp +++ b/src/MobSpawner.cpp @@ -285,6 +285,19 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R ) ); } + + case mtMooshroom: + { + return ( + (TargetBlock == E_BLOCK_AIR) && + (BlockAbove == E_BLOCK_AIR) && + (!cBlockInfo::IsTransparent(BlockBelow)) && + ( + a_Biome == biMushroomShore || + a_Biome == biMushroomIsland + ) + ); + } default: { -- cgit v1.2.3 From 865b56766526906200cab7027b852f4b03dd89d6 Mon Sep 17 00:00:00 2001 From: p-mcgowan Date: Mon, 1 Dec 2014 22:13:52 -0800 Subject: extra formatting parentheses --- src/MobSpawner.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/MobSpawner.cpp b/src/MobSpawner.cpp index b8f64807e..6014cceb6 100644 --- a/src/MobSpawner.cpp +++ b/src/MobSpawner.cpp @@ -293,8 +293,8 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R (BlockAbove == E_BLOCK_AIR) && (!cBlockInfo::IsTransparent(BlockBelow)) && ( - a_Biome == biMushroomShore || - a_Biome == biMushroomIsland + (a_Biome == biMushroomShore) || + (a_Biome == biMushroomIsland) ) ); } -- cgit v1.2.3 From 5db3ceb333e5a705de3ff03834d1c212e1c38e63 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Tue, 2 Dec 2014 09:42:49 +0100 Subject: Suggestions by xoft Using IntNoise3D to prevent needless floating point math --- src/Generating/DungeonRoomsFinisher.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Generating/DungeonRoomsFinisher.cpp b/src/Generating/DungeonRoomsFinisher.cpp index 492ab1ed9..19ac3b8b2 100644 --- a/src/Generating/DungeonRoomsFinisher.cpp +++ b/src/Generating/DungeonRoomsFinisher.cpp @@ -61,12 +61,12 @@ public: // Choose what the mobspawner will spawn. // 25% chance for a spider, 25% for a skeleton and 50% chance to get a zombie spawer. - NOISE_DATATYPE MobType = a_Noise.IntNoise3D(a_OriginX, m_FloorHeight, a_OriginZ); - if (MobType <= -0.5) + int MobType = (a_Noise.IntNoise3D(a_OriginX, m_FloorHeight, a_OriginZ) / 7) % 100 + if (MobType <= 25) { m_MonsterType = mtSkeleton; } - else if (MobType <= 0) + else if (MobType <= 50) { m_MonsterType = mtSpider; } -- cgit v1.2.3 From a466986f53c2bec54bc25951d05036db5a3fb2e1 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Tue, 2 Dec 2014 09:55:25 +0100 Subject: Using IntNoise3DInt instead of IntNoise3D --- src/Generating/DungeonRoomsFinisher.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Generating/DungeonRoomsFinisher.cpp b/src/Generating/DungeonRoomsFinisher.cpp index 19ac3b8b2..847fcbf10 100644 --- a/src/Generating/DungeonRoomsFinisher.cpp +++ b/src/Generating/DungeonRoomsFinisher.cpp @@ -61,7 +61,7 @@ public: // Choose what the mobspawner will spawn. // 25% chance for a spider, 25% for a skeleton and 50% chance to get a zombie spawer. - int MobType = (a_Noise.IntNoise3D(a_OriginX, m_FloorHeight, a_OriginZ) / 7) % 100 + int MobType = (a_Noise.IntNoise3DInt(a_OriginX, m_FloorHeight, a_OriginZ) / 7) % 100 if (MobType <= 25) { m_MonsterType = mtSkeleton; -- cgit v1.2.3 From f1177984f102e7b9c8cdc9ca5e8d9b5c67a4330f Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Tue, 2 Dec 2014 10:20:20 +0100 Subject: Fixed forgotten semicolon --- src/Generating/DungeonRoomsFinisher.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Generating/DungeonRoomsFinisher.cpp b/src/Generating/DungeonRoomsFinisher.cpp index 847fcbf10..092e232ab 100644 --- a/src/Generating/DungeonRoomsFinisher.cpp +++ b/src/Generating/DungeonRoomsFinisher.cpp @@ -61,7 +61,7 @@ public: // Choose what the mobspawner will spawn. // 25% chance for a spider, 25% for a skeleton and 50% chance to get a zombie spawer. - int MobType = (a_Noise.IntNoise3DInt(a_OriginX, m_FloorHeight, a_OriginZ) / 7) % 100 + int MobType = (a_Noise.IntNoise3DInt(a_OriginX, m_FloorHeight, a_OriginZ) / 7) % 100; if (MobType <= 25) { m_MonsterType = mtSkeleton; -- cgit v1.2.3 From 9831220a1cfc84804619e497f8b56853de98bf82 Mon Sep 17 00:00:00 2001 From: p-mcgowan Date: Tue, 2 Dec 2014 01:37:17 -0800 Subject: animal terrain finisher --- src/Generating/FinishGen.cpp | 212 +++++++++++++++++++++++++++++++++++++++++++ src/Generating/FinishGen.h | 29 ++++++ 2 files changed, 241 insertions(+) diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index b9d702429..b8575f4f8 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -26,6 +26,8 @@ #define DEF_OVERWORLD_LAVA_SPRINGS "0, 0; 10, 5; 11, 45; 48, 2; 64, 1; 255, 0" #define DEF_END_WATER_SPRINGS "0, 1; 255, 1" #define DEF_END_LAVA_SPRINGS "0, 1; 255, 1" +#define DEF_ANIMAL_SPAWN_PERCENT 10 +#define DEF_NO_ANIMALS 0 @@ -943,3 +945,213 @@ bool cFinishGenFluidSprings::TryPlaceSpring(cChunkDesc & a_ChunkDesc, int x, int + +//////////////////////////////////////////////////////////////////////////////// +// cFinishGenPassiveMobs: + +cFinishGenPassiveMobs::cFinishGenPassiveMobs(int a_Seed, cIniFile & a_IniFile, eDimension a_Dimension) : + m_Noise(a_Seed) +{ + AString SectionName = "Animals"; + int DefaultAnimalSpawnChunkPercentage = DEF_ANIMAL_SPAWN_PERCENT; + switch (a_Dimension) + { + case dimOverworld: + { + DefaultAnimalSpawnChunkPercentage = DEF_ANIMAL_SPAWN_PERCENT; + break; + } + case dimNether: + case dimEnd: // No nether or end animals (currently) + { + DefaultAnimalSpawnChunkPercentage = DEF_NO_ANIMALS; + break; + } + default: + { + ASSERT(!"Unhandled world dimension"); + break; + } + } // switch (dimension) + m_AnimalProbability = a_IniFile.GetValueSetI(SectionName, "AnimalSpawnChunkPercentage", DefaultAnimalSpawnChunkPercentage); + if (m_AnimalProbability < 0 || m_AnimalProbability > 100) + { + LOGWARNING("[Animals]: AnimalSpawnChunkPercentage is invalid, using the default of \"%d\".", DefaultAnimalSpawnChunkPercentage); + } +} + + + + + +void cFinishGenPassiveMobs::GenFinish(cChunkDesc & a_ChunkDesc) +{ + int ChanceRnd = m_Random.NextInt(100); + if (ChanceRnd > m_AnimalProbability) + { + return; + } + + eMonsterType RandomMob = GetRandomMob(a_ChunkDesc); + if (RandomMob == mtInvalidType) + { + LOGWARNING("Attempted to spawn invalid mob type."); + return; + } + + // Try spawning a pack center 10 times, should get roughly the same probability + for (int Tries = 0; Tries < 10; Tries++) + { + int PackCenterX = m_Random.NextInt(cChunkDef::Width - 1); + int PackCenterZ = m_Random.NextInt(cChunkDef::Width - 1); + if (TrySpawnAnimals(a_ChunkDesc, PackCenterX, a_ChunkDesc.GetHeight(PackCenterX, PackCenterZ), PackCenterZ, RandomMob)) + { + for (int i = 0; i < 5; i++) + { + int OffsetX = m_Random.NextInt(cChunkDef::Width - 1); + int OffsetZ = m_Random.NextInt(cChunkDef::Width - 1); + TrySpawnAnimals(a_ChunkDesc, OffsetX, a_ChunkDesc.GetHeight(OffsetX, OffsetZ), OffsetZ, RandomMob); + } + + return; + + } // if pack center spawn successful + } // for tries +} + + + + + +bool cFinishGenPassiveMobs::TrySpawnAnimals(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelY, int a_RelZ, eMonsterType AnimalToSpawn) +{ + BLOCKTYPE BlockAtHead = a_ChunkDesc.GetBlockType(a_RelX, a_RelY + 1, a_RelZ); + BLOCKTYPE BlockAtFeet = a_ChunkDesc.GetBlockType(a_RelX, a_RelY , a_RelZ); + BLOCKTYPE BlockUnderFeet = a_ChunkDesc.GetBlockType(a_RelX, a_RelY - 1, a_RelZ); + + // Check block below (opaque, grass, water), and above (air) + if (AnimalToSpawn == mtSquid && BlockAtFeet != E_BLOCK_WATER) + { + return false; + } + if ( + (AnimalToSpawn != mtSquid) && + (BlockAtHead != E_BLOCK_AIR) && + (BlockAtFeet != E_BLOCK_AIR) && + (!cBlockInfo::IsTransparent(BlockUnderFeet)) + ) + { + return false; + } + if ( + (BlockUnderFeet != E_BLOCK_GRASS) && + ( + (AnimalToSpawn == mtSheep) || + (AnimalToSpawn == mtChicken) || + (AnimalToSpawn == mtPig) + ) + ) + { + return false; + } + + int AnimalX, AnimalY, AnimalZ; + AnimalX = (double)(a_ChunkDesc.GetChunkX()*cChunkDef::Width + a_RelX + 0.5); + AnimalY = a_RelY; + AnimalZ = (double)(a_ChunkDesc.GetChunkZ()*cChunkDef::Width + a_RelZ + 0.5); + + cEntityList ChunkEntities = a_ChunkDesc.GetEntities(); + cMonster * NewMob = cMonster::NewMonsterFromType(AnimalToSpawn); + NewMob->SetPosition(AnimalX, AnimalY, AnimalZ); + ChunkEntities.push_back(NewMob); + LOGD("Spawning %s #%i at {%d, %d, %d}", NewMob->GetClass(), NewMob->GetUniqueID(), AnimalX, AnimalY, AnimalZ); + + return true; +} + + + + + +eMonsterType cFinishGenPassiveMobs::GetRandomMob(cChunkDesc & a_ChunkDesc) +{ + + std::set ListOfSpawnables; + std::set::iterator MobIter = ListOfSpawnables.begin(); + int x = m_Random.NextInt(cChunkDef::Width - 1); + int z = m_Random.NextInt(cChunkDef::Width - 1); + + // Check biomes first to get a list of animals + switch (a_ChunkDesc.GetBiome(x, z)) + { + // No animals + case biNether: + case biEnd: + return mtInvalidType; + + // Squid only + case biOcean: + case biFrozenOcean: + case biFrozenRiver: + case biRiver: + case biDeepOcean: + ListOfSpawnables.insert(MobIter, mtSquid); + break; + + // Mooshroom only + case biMushroomIsland: + case biMushroomShore: + ListOfSpawnables.insert(MobIter, mtMooshroom); + break; + + case biJungle: + case biJungleHills: + case biJungleEdge: + case biJungleM: + case biJungleEdgeM: + ListOfSpawnables.insert(MobIter, mtOcelot); + + case biPlains: + case biSunflowerPlains: + case biSavanna: + case biSavannaPlateau: + case biSavannaM: + case biSavannaPlateauM: + ListOfSpawnables.insert(MobIter, mtHorse); + // ListOfSpawnables.insert(mtDonkey); + + // Wolves only + case biForest: + case biTaiga: + case biMegaTaiga: + case biColdTaiga: + case biColdTaigaM: + ListOfSpawnables.insert(MobIter, mtWolf); + + // All other mobs + default: + ListOfSpawnables.insert(MobIter, mtChicken); + ListOfSpawnables.insert(MobIter, mtCow); + ListOfSpawnables.insert(MobIter, mtPig); + ListOfSpawnables.insert(MobIter, mtSheep); + } + + if (ListOfSpawnables.size() == 0) + { + LOGD("Tried to spawn an animal from an empty list."); + return mtInvalidType; + } + + int RandMob = m_Random.NextInt(ListOfSpawnables.size()); + MobIter=ListOfSpawnables.begin(); + for (int i = 0; i < RandMob; i++) + { + ++MobIter; + } + + return *MobIter; +} + + + + diff --git a/src/Generating/FinishGen.h b/src/Generating/FinishGen.h index d45365683..38bb93d2a 100644 --- a/src/Generating/FinishGen.h +++ b/src/Generating/FinishGen.h @@ -18,6 +18,8 @@ #include "ComposableGenerator.h" #include "../Noise/Noise.h" #include "../ProbabDistrib.h" +#include "../Mobs/Monster.h" +#include "FastRandom.h" @@ -315,3 +317,30 @@ protected: + +class cFinishGenPassiveMobs : + public cFinishGen +{ +public: + + cFinishGenPassiveMobs(int a_Seed, cIniFile & a_IniFile, eDimension a_Dimension); + +protected: + + cNoise m_Noise; + int m_AnimalProbability; // Chance, [0..100], that an animal pack will be generated in a chunk + cFastRandom m_Random; + + // cFinishGen override: + virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; + + // Tries to spawn a mob in the center of the pack. If successful, spawns 0-5 more. + bool TrySpawnAnimals(cChunkDesc & a_ChunkDesc, int x, int y, int z, eMonsterType AnimalToSpawn); + + // Gets a random mob from biome-dependant list + eMonsterType GetRandomMob(cChunkDesc & a_ChunkDesc); +} ; + + + + -- cgit v1.2.3 From 2d93274a90a86829ff6edfa02dd575c8811a6cfd Mon Sep 17 00:00:00 2001 From: p-mcgowan Date: Tue, 2 Dec 2014 01:58:30 -0800 Subject: animal terrain finisher --- src/Generating/FinishGen.cpp | 350 +++++++++++++++++++++---------------------- src/Generating/FinishGen.h | 24 +-- 2 files changed, 187 insertions(+), 187 deletions(-) diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index b8575f4f8..296e92139 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -402,7 +402,7 @@ void cFinishGenSoulsandRims::GenFinish(cChunkDesc & a_ChunkDesc) int ChunkZ = a_ChunkDesc.GetChunkZ() * cChunkDef::Width; HEIGHTTYPE MaxHeight = a_ChunkDesc.GetMaxHeight(); - for (int x = 0; x < 16; x++) + for (int x = 0; x < 16; x++) { int xx = ChunkX + x; for (int z = 0; z < 16; z++) @@ -950,34 +950,34 @@ bool cFinishGenFluidSprings::TryPlaceSpring(cChunkDesc & a_ChunkDesc, int x, int // cFinishGenPassiveMobs: cFinishGenPassiveMobs::cFinishGenPassiveMobs(int a_Seed, cIniFile & a_IniFile, eDimension a_Dimension) : - m_Noise(a_Seed) + m_Noise(a_Seed) { - AString SectionName = "Animals"; - int DefaultAnimalSpawnChunkPercentage = DEF_ANIMAL_SPAWN_PERCENT; - switch (a_Dimension) - { - case dimOverworld: - { - DefaultAnimalSpawnChunkPercentage = DEF_ANIMAL_SPAWN_PERCENT; - break; - } - case dimNether: - case dimEnd: // No nether or end animals (currently) - { - DefaultAnimalSpawnChunkPercentage = DEF_NO_ANIMALS; - break; - } - default: - { - ASSERT(!"Unhandled world dimension"); - break; - } - } // switch (dimension) - m_AnimalProbability = a_IniFile.GetValueSetI(SectionName, "AnimalSpawnChunkPercentage", DefaultAnimalSpawnChunkPercentage); - if (m_AnimalProbability < 0 || m_AnimalProbability > 100) - { - LOGWARNING("[Animals]: AnimalSpawnChunkPercentage is invalid, using the default of \"%d\".", DefaultAnimalSpawnChunkPercentage); - } + AString SectionName = "Animals"; + int DefaultAnimalSpawnChunkPercentage = DEF_ANIMAL_SPAWN_PERCENT; + switch (a_Dimension) + { + case dimOverworld: + { + DefaultAnimalSpawnChunkPercentage = DEF_ANIMAL_SPAWN_PERCENT; + break; + } + case dimNether: + case dimEnd:// No nether or end animals (currently) + { + DefaultAnimalSpawnChunkPercentage = DEF_NO_ANIMALS; + break; + } + default: + { + ASSERT(!"Unhandled world dimension"); + break; + } + }// switch (dimension) + m_AnimalProbability = a_IniFile.GetValueSetI(SectionName, "AnimalSpawnChunkPercentage", DefaultAnimalSpawnChunkPercentage); + if (m_AnimalProbability < 0 || m_AnimalProbability > 100) + { + LOGWARNING("[Animals]: AnimalSpawnChunkPercentage is invalid, using the default of \"%d\".", DefaultAnimalSpawnChunkPercentage); + } } @@ -986,37 +986,37 @@ cFinishGenPassiveMobs::cFinishGenPassiveMobs(int a_Seed, cIniFile & a_IniFile, e void cFinishGenPassiveMobs::GenFinish(cChunkDesc & a_ChunkDesc) { - int ChanceRnd = m_Random.NextInt(100); - if (ChanceRnd > m_AnimalProbability) - { - return; - } - - eMonsterType RandomMob = GetRandomMob(a_ChunkDesc); - if (RandomMob == mtInvalidType) - { - LOGWARNING("Attempted to spawn invalid mob type."); - return; - } - - // Try spawning a pack center 10 times, should get roughly the same probability - for (int Tries = 0; Tries < 10; Tries++) - { - int PackCenterX = m_Random.NextInt(cChunkDef::Width - 1); - int PackCenterZ = m_Random.NextInt(cChunkDef::Width - 1); - if (TrySpawnAnimals(a_ChunkDesc, PackCenterX, a_ChunkDesc.GetHeight(PackCenterX, PackCenterZ), PackCenterZ, RandomMob)) - { - for (int i = 0; i < 5; i++) - { - int OffsetX = m_Random.NextInt(cChunkDef::Width - 1); - int OffsetZ = m_Random.NextInt(cChunkDef::Width - 1); - TrySpawnAnimals(a_ChunkDesc, OffsetX, a_ChunkDesc.GetHeight(OffsetX, OffsetZ), OffsetZ, RandomMob); - } - - return; - - } // if pack center spawn successful - } // for tries + int ChanceRnd = m_Random.NextInt(100); + if (ChanceRnd > m_AnimalProbability) + { + return; + } + + eMonsterType RandomMob = GetRandomMob(a_ChunkDesc); + if (RandomMob == mtInvalidType) + { + LOGWARNING("Attempted to spawn invalid mob type."); + return; + } + + // Try spawning a pack center 10 times, should get roughly the same probability + for (int Tries = 0; Tries < 10; Tries++) + { + int PackCenterX = m_Random.NextInt(cChunkDef::Width - 1); + int PackCenterZ = m_Random.NextInt(cChunkDef::Width - 1); + if (TrySpawnAnimals(a_ChunkDesc, PackCenterX, a_ChunkDesc.GetHeight(PackCenterX, PackCenterZ), PackCenterZ, RandomMob)) + { + for (int i = 0; i < 5; i++) + { + int OffsetX = m_Random.NextInt(cChunkDef::Width - 1); + int OffsetZ = m_Random.NextInt(cChunkDef::Width - 1); + TrySpawnAnimals(a_ChunkDesc, OffsetX, a_ChunkDesc.GetHeight(OffsetX, OffsetZ), OffsetZ, RandomMob); + } + + return; + + }// if pack center spawn successful + }// for tries } @@ -1025,48 +1025,48 @@ void cFinishGenPassiveMobs::GenFinish(cChunkDesc & a_ChunkDesc) bool cFinishGenPassiveMobs::TrySpawnAnimals(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelY, int a_RelZ, eMonsterType AnimalToSpawn) { - BLOCKTYPE BlockAtHead = a_ChunkDesc.GetBlockType(a_RelX, a_RelY + 1, a_RelZ); - BLOCKTYPE BlockAtFeet = a_ChunkDesc.GetBlockType(a_RelX, a_RelY , a_RelZ); - BLOCKTYPE BlockUnderFeet = a_ChunkDesc.GetBlockType(a_RelX, a_RelY - 1, a_RelZ); - - // Check block below (opaque, grass, water), and above (air) - if (AnimalToSpawn == mtSquid && BlockAtFeet != E_BLOCK_WATER) - { - return false; - } - if ( - (AnimalToSpawn != mtSquid) && - (BlockAtHead != E_BLOCK_AIR) && - (BlockAtFeet != E_BLOCK_AIR) && - (!cBlockInfo::IsTransparent(BlockUnderFeet)) - ) - { - return false; - } - if ( - (BlockUnderFeet != E_BLOCK_GRASS) && - ( - (AnimalToSpawn == mtSheep) || - (AnimalToSpawn == mtChicken) || - (AnimalToSpawn == mtPig) - ) - ) - { - return false; - } - - int AnimalX, AnimalY, AnimalZ; - AnimalX = (double)(a_ChunkDesc.GetChunkX()*cChunkDef::Width + a_RelX + 0.5); - AnimalY = a_RelY; - AnimalZ = (double)(a_ChunkDesc.GetChunkZ()*cChunkDef::Width + a_RelZ + 0.5); - - cEntityList ChunkEntities = a_ChunkDesc.GetEntities(); - cMonster * NewMob = cMonster::NewMonsterFromType(AnimalToSpawn); - NewMob->SetPosition(AnimalX, AnimalY, AnimalZ); - ChunkEntities.push_back(NewMob); - LOGD("Spawning %s #%i at {%d, %d, %d}", NewMob->GetClass(), NewMob->GetUniqueID(), AnimalX, AnimalY, AnimalZ); - - return true; + BLOCKTYPE BlockAtHead = a_ChunkDesc.GetBlockType(a_RelX, a_RelY + 1, a_RelZ); + BLOCKTYPE BlockAtFeet = a_ChunkDesc.GetBlockType(a_RelX, a_RelY, a_RelZ); + BLOCKTYPE BlockUnderFeet = a_ChunkDesc.GetBlockType(a_RelX, a_RelY - 1, a_RelZ); + + // Check block below (opaque, grass, water), and above (air) + if (AnimalToSpawn == mtSquid && BlockAtFeet != E_BLOCK_WATER) + { + return false; + } + if ( + (AnimalToSpawn != mtSquid) && + (BlockAtHead != E_BLOCK_AIR) && + (BlockAtFeet != E_BLOCK_AIR) && + (!cBlockInfo::IsTransparent(BlockUnderFeet)) + ) + { + return false; + } + if ( + (BlockUnderFeet != E_BLOCK_GRASS) && + ( + (AnimalToSpawn == mtSheep) || + (AnimalToSpawn == mtChicken) || + (AnimalToSpawn == mtPig) + ) + ) + { + return false; + } + + int AnimalX, AnimalY, AnimalZ; + AnimalX = (double)(a_ChunkDesc.GetChunkX()*cChunkDef::Width + a_RelX + 0.5); + AnimalY = a_RelY; + AnimalZ = (double)(a_ChunkDesc.GetChunkZ()*cChunkDef::Width + a_RelZ + 0.5); + + cEntityList ChunkEntities = a_ChunkDesc.GetEntities(); + cMonster * NewMob = cMonster::NewMonsterFromType(AnimalToSpawn); + NewMob->SetPosition(AnimalX, AnimalY, AnimalZ); + ChunkEntities.push_back(NewMob); + LOGD("Spawning %s #%i at {%d, %d, %d}", NewMob->GetClass(), NewMob->GetUniqueID(), AnimalX, AnimalY, AnimalZ); + + return true; } @@ -1076,80 +1076,80 @@ bool cFinishGenPassiveMobs::TrySpawnAnimals(cChunkDesc & a_ChunkDesc, int a_RelX eMonsterType cFinishGenPassiveMobs::GetRandomMob(cChunkDesc & a_ChunkDesc) { - std::set ListOfSpawnables; - std::set::iterator MobIter = ListOfSpawnables.begin(); - int x = m_Random.NextInt(cChunkDef::Width - 1); - int z = m_Random.NextInt(cChunkDef::Width - 1); - - // Check biomes first to get a list of animals - switch (a_ChunkDesc.GetBiome(x, z)) - { - // No animals - case biNether: - case biEnd: - return mtInvalidType; - - // Squid only - case biOcean: - case biFrozenOcean: - case biFrozenRiver: - case biRiver: - case biDeepOcean: - ListOfSpawnables.insert(MobIter, mtSquid); - break; - - // Mooshroom only - case biMushroomIsland: - case biMushroomShore: - ListOfSpawnables.insert(MobIter, mtMooshroom); - break; - - case biJungle: - case biJungleHills: - case biJungleEdge: - case biJungleM: - case biJungleEdgeM: - ListOfSpawnables.insert(MobIter, mtOcelot); - - case biPlains: - case biSunflowerPlains: - case biSavanna: - case biSavannaPlateau: - case biSavannaM: - case biSavannaPlateauM: - ListOfSpawnables.insert(MobIter, mtHorse); - // ListOfSpawnables.insert(mtDonkey); - - // Wolves only - case biForest: - case biTaiga: - case biMegaTaiga: - case biColdTaiga: - case biColdTaigaM: - ListOfSpawnables.insert(MobIter, mtWolf); - - // All other mobs - default: - ListOfSpawnables.insert(MobIter, mtChicken); - ListOfSpawnables.insert(MobIter, mtCow); - ListOfSpawnables.insert(MobIter, mtPig); - ListOfSpawnables.insert(MobIter, mtSheep); - } - - if (ListOfSpawnables.size() == 0) - { - LOGD("Tried to spawn an animal from an empty list."); - return mtInvalidType; - } - - int RandMob = m_Random.NextInt(ListOfSpawnables.size()); - MobIter=ListOfSpawnables.begin(); - for (int i = 0; i < RandMob; i++) - { - ++MobIter; - } - - return *MobIter; + std::set ListOfSpawnables; + std::set::iterator MobIter = ListOfSpawnables.begin(); + int x = m_Random.NextInt(cChunkDef::Width - 1); + int z = m_Random.NextInt(cChunkDef::Width - 1); + + // Check biomes first to get a list of animals + switch (a_ChunkDesc.GetBiome(x, z)) + { + // No animals + case biNether: + case biEnd: + return mtInvalidType; + + // Squid only + case biOcean: + case biFrozenOcean: + case biFrozenRiver: + case biRiver: + case biDeepOcean: + ListOfSpawnables.insert(MobIter, mtSquid); + break; + + // Mooshroom only + case biMushroomIsland: + case biMushroomShore: + ListOfSpawnables.insert(MobIter, mtMooshroom); + break; + + case biJungle: + case biJungleHills: + case biJungleEdge: + case biJungleM: + case biJungleEdgeM: + ListOfSpawnables.insert(MobIter, mtOcelot); + + case biPlains: + case biSunflowerPlains: + case biSavanna: + case biSavannaPlateau: + case biSavannaM: + case biSavannaPlateauM: + ListOfSpawnables.insert(MobIter, mtHorse); + // ListOfSpawnables.insert(mtDonkey); + + // Wolves only + case biForest: + case biTaiga: + case biMegaTaiga: + case biColdTaiga: + case biColdTaigaM: + ListOfSpawnables.insert(MobIter, mtWolf); + + // All other mobs + default: + ListOfSpawnables.insert(MobIter, mtChicken); + ListOfSpawnables.insert(MobIter, mtCow); + ListOfSpawnables.insert(MobIter, mtPig); + ListOfSpawnables.insert(MobIter, mtSheep); + } + + if (ListOfSpawnables.size() == 0) + { + LOGD("Tried to spawn an animal from an empty list."); + return mtInvalidType; + } + + int RandMob = m_Random.NextInt(ListOfSpawnables.size()); + MobIter=ListOfSpawnables.begin(); + for (int i = 0; i < RandMob; i++) + { + ++MobIter; + } + + return *MobIter; } diff --git a/src/Generating/FinishGen.h b/src/Generating/FinishGen.h index 38bb93d2a..c8575f4d1 100644 --- a/src/Generating/FinishGen.h +++ b/src/Generating/FinishGen.h @@ -123,7 +123,7 @@ class cFinishGenSoulsandRims : public cFinishGen { public: - cFinishGenSoulsandRims(int a_Seed) : + cFinishGenSoulsandRims(int a_Seed) : m_Noise(a_Seed) { } @@ -319,26 +319,26 @@ protected: class cFinishGenPassiveMobs : - public cFinishGen + public cFinishGen { public: - cFinishGenPassiveMobs(int a_Seed, cIniFile & a_IniFile, eDimension a_Dimension); + cFinishGenPassiveMobs(int a_Seed, cIniFile & a_IniFile, eDimension a_Dimension); protected: - cNoise m_Noise; - int m_AnimalProbability; // Chance, [0..100], that an animal pack will be generated in a chunk - cFastRandom m_Random; + cNoise m_Noise; + int m_AnimalProbability; // Chance, [0..100], that an animal pack will be generated in a chunk + cFastRandom m_Random; - // cFinishGen override: - virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; + // cFinishGen override: + virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; - // Tries to spawn a mob in the center of the pack. If successful, spawns 0-5 more. - bool TrySpawnAnimals(cChunkDesc & a_ChunkDesc, int x, int y, int z, eMonsterType AnimalToSpawn); + // Tries to spawn a mob in the center of the pack. If successful, spawns 0-5 more. + bool TrySpawnAnimals(cChunkDesc & a_ChunkDesc, int x, int y, int z, eMonsterType AnimalToSpawn); - // Gets a random mob from biome-dependant list - eMonsterType GetRandomMob(cChunkDesc & a_ChunkDesc); + // Gets a random mob from biome-dependant list + eMonsterType GetRandomMob(cChunkDesc & a_ChunkDesc); } ; -- cgit v1.2.3 From 978c9967adb4dbafdb6ade3f05345d473fcef2e5 Mon Sep 17 00:00:00 2001 From: p-mcgowan Date: Tue, 2 Dec 2014 02:03:29 -0800 Subject: fix comments after replacing spaces with tabs --- src/Generating/FinishGen.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index 296e92139..2b0194a27 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -962,7 +962,7 @@ cFinishGenPassiveMobs::cFinishGenPassiveMobs(int a_Seed, cIniFile & a_IniFile, e break; } case dimNether: - case dimEnd:// No nether or end animals (currently) + case dimEnd: // No nether or end animals (currently) { DefaultAnimalSpawnChunkPercentage = DEF_NO_ANIMALS; break; @@ -972,7 +972,7 @@ cFinishGenPassiveMobs::cFinishGenPassiveMobs(int a_Seed, cIniFile & a_IniFile, e ASSERT(!"Unhandled world dimension"); break; } - }// switch (dimension) + } // switch (dimension) m_AnimalProbability = a_IniFile.GetValueSetI(SectionName, "AnimalSpawnChunkPercentage", DefaultAnimalSpawnChunkPercentage); if (m_AnimalProbability < 0 || m_AnimalProbability > 100) { @@ -1015,8 +1015,8 @@ void cFinishGenPassiveMobs::GenFinish(cChunkDesc & a_ChunkDesc) return; - }// if pack center spawn successful - }// for tries + } // if pack center spawn successful + } // for tries } -- cgit v1.2.3 From 14bc241ec1e485421cf960db7f3b7c39237d9742 Mon Sep 17 00:00:00 2001 From: p-mcgowan Date: Tue, 2 Dec 2014 11:10:20 -0800 Subject: updated mooshroom check for mycelium --- src/MobSpawner.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MobSpawner.cpp b/src/MobSpawner.cpp index 6014cceb6..e477e2dac 100644 --- a/src/MobSpawner.cpp +++ b/src/MobSpawner.cpp @@ -291,7 +291,7 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R return ( (TargetBlock == E_BLOCK_AIR) && (BlockAbove == E_BLOCK_AIR) && - (!cBlockInfo::IsTransparent(BlockBelow)) && + (BlockBelow == E_BLOCK_MYCELIUM) && ( (a_Biome == biMushroomShore) || (a_Biome == biMushroomIsland) -- cgit v1.2.3 From 585662e63f33470a6c241340f0b527102fcf406a Mon Sep 17 00:00:00 2001 From: p-mcgowan Date: Tue, 2 Dec 2014 11:21:51 -0800 Subject: indentation, repeatable random, small corrections --- src/Generating/FinishGen.cpp | 191 +++++++++++++++++++++---------------------- 1 file changed, 93 insertions(+), 98 deletions(-) diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index 2b0194a27..3e5b24017 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -956,27 +956,27 @@ cFinishGenPassiveMobs::cFinishGenPassiveMobs(int a_Seed, cIniFile & a_IniFile, e int DefaultAnimalSpawnChunkPercentage = DEF_ANIMAL_SPAWN_PERCENT; switch (a_Dimension) { - case dimOverworld: - { - DefaultAnimalSpawnChunkPercentage = DEF_ANIMAL_SPAWN_PERCENT; - break; - } - case dimNether: - case dimEnd: // No nether or end animals (currently) - { - DefaultAnimalSpawnChunkPercentage = DEF_NO_ANIMALS; - break; - } - default: - { - ASSERT(!"Unhandled world dimension"); - break; - } + case dimOverworld: + { + DefaultAnimalSpawnChunkPercentage = DEF_ANIMAL_SPAWN_PERCENT; + break; + } + case dimNether: + case dimEnd: // No nether or end animals (currently) + { + DefaultAnimalSpawnChunkPercentage = DEF_NO_ANIMALS; + break; + } + default: + { + ASSERT(!"Unhandled world dimension"); + break; + } } // switch (dimension) m_AnimalProbability = a_IniFile.GetValueSetI(SectionName, "AnimalSpawnChunkPercentage", DefaultAnimalSpawnChunkPercentage); if (m_AnimalProbability < 0 || m_AnimalProbability > 100) { - LOGWARNING("[Animals]: AnimalSpawnChunkPercentage is invalid, using the default of \"%d\".", DefaultAnimalSpawnChunkPercentage); + LOGWARNING("[Animals]: AnimalSpawnChunkPercentage is invalid, using the default of \"%d\".", DefaultAnimalSpawnChunkPercentage); } } @@ -986,33 +986,32 @@ cFinishGenPassiveMobs::cFinishGenPassiveMobs(int a_Seed, cIniFile & a_IniFile, e void cFinishGenPassiveMobs::GenFinish(cChunkDesc & a_ChunkDesc) { - int ChanceRnd = m_Random.NextInt(100); + int ChanceRnd = (m_Noise.IntNoise2DInt(chunkX, chunkZ) / 7) % 100; if (ChanceRnd > m_AnimalProbability) { - return; + return; } eMonsterType RandomMob = GetRandomMob(a_ChunkDesc); if (RandomMob == mtInvalidType) { - LOGWARNING("Attempted to spawn invalid mob type."); - return; + LOGWARNING("Attempted to spawn invalid mob type."); + return; } // Try spawning a pack center 10 times, should get roughly the same probability for (int Tries = 0; Tries < 10; Tries++) { - int PackCenterX = m_Random.NextInt(cChunkDef::Width - 1); - int PackCenterZ = m_Random.NextInt(cChunkDef::Width - 1); + int PackCenterX = (m_Noise.IntNoise2DInt(chunkX, chunkZ) / 7) % cChunkDef::Width; + int PackCenterZ = (m_Noise.IntNoise2DInt(chunkX, chunkZ) / 7) % cChunkDef::Width; if (TrySpawnAnimals(a_ChunkDesc, PackCenterX, a_ChunkDesc.GetHeight(PackCenterX, PackCenterZ), PackCenterZ, RandomMob)) { for (int i = 0; i < 5; i++) { - int OffsetX = m_Random.NextInt(cChunkDef::Width - 1); - int OffsetZ = m_Random.NextInt(cChunkDef::Width - 1); + int OffsetX = (m_Noise.IntNoise2DInt(chunkX, chunkZ) / 7) % cChunkDef::Width; + int OffsetZ = (m_Noise.IntNoise2DInt(chunkX, chunkZ) / 7) % cChunkDef::Width; TrySpawnAnimals(a_ChunkDesc, OffsetX, a_ChunkDesc.GetHeight(OffsetX, OffsetZ), OffsetZ, RandomMob); } - return; } // if pack center spawn successful @@ -1032,27 +1031,24 @@ bool cFinishGenPassiveMobs::TrySpawnAnimals(cChunkDesc & a_ChunkDesc, int a_RelX // Check block below (opaque, grass, water), and above (air) if (AnimalToSpawn == mtSquid && BlockAtFeet != E_BLOCK_WATER) { - return false; + return false; } - if ( - (AnimalToSpawn != mtSquid) && - (BlockAtHead != E_BLOCK_AIR) && - (BlockAtFeet != E_BLOCK_AIR) && - (!cBlockInfo::IsTransparent(BlockUnderFeet)) + if ((AnimalToSpawn != mtSquid) && + (BlockAtHead != E_BLOCK_AIR) && + (BlockAtFeet != E_BLOCK_AIR) && + (!cBlockInfo::IsTransparent(BlockUnderFeet)) ) { - return false; + return false; } - if ( - (BlockUnderFeet != E_BLOCK_GRASS) && - ( - (AnimalToSpawn == mtSheep) || - (AnimalToSpawn == mtChicken) || - (AnimalToSpawn == mtPig) - ) - ) + if ((BlockUnderFeet != E_BLOCK_GRASS) && + ((AnimalToSpawn == mtSheep) || (AnimalToSpawn == mtChicken) || (AnimalToSpawn == mtPig))) { - return false; + return false; + } + if (AnimalToSpawn == mtMooshroom && BlockUnderFeet != E_BLOCK_MYCELIUM) + { + return false; } int AnimalX, AnimalY, AnimalZ; @@ -1078,75 +1074,74 @@ eMonsterType cFinishGenPassiveMobs::GetRandomMob(cChunkDesc & a_ChunkDesc) std::set ListOfSpawnables; std::set::iterator MobIter = ListOfSpawnables.begin(); - int x = m_Random.NextInt(cChunkDef::Width - 1); - int z = m_Random.NextInt(cChunkDef::Width - 1); + int x = (m_Noise.IntNoise2DInt(chunkX, chunkZ) / 7) % cChunkDef::Width; + int z = (m_Noise.IntNoise2DInt(chunkX, chunkZ) / 7) % cChunkDef::Width; // Check biomes first to get a list of animals switch (a_ChunkDesc.GetBiome(x, z)) { - // No animals - case biNether: - case biEnd: - return mtInvalidType; - - // Squid only - case biOcean: - case biFrozenOcean: - case biFrozenRiver: - case biRiver: - case biDeepOcean: - ListOfSpawnables.insert(MobIter, mtSquid); - break; - - // Mooshroom only - case biMushroomIsland: - case biMushroomShore: - ListOfSpawnables.insert(MobIter, mtMooshroom); - break; - - case biJungle: - case biJungleHills: - case biJungleEdge: - case biJungleM: - case biJungleEdgeM: - ListOfSpawnables.insert(MobIter, mtOcelot); - - case biPlains: - case biSunflowerPlains: - case biSavanna: - case biSavannaPlateau: - case biSavannaM: - case biSavannaPlateauM: - ListOfSpawnables.insert(MobIter, mtHorse); - // ListOfSpawnables.insert(mtDonkey); - - // Wolves only - case biForest: - case biTaiga: - case biMegaTaiga: - case biColdTaiga: - case biColdTaigaM: - ListOfSpawnables.insert(MobIter, mtWolf); - - // All other mobs - default: - ListOfSpawnables.insert(MobIter, mtChicken); - ListOfSpawnables.insert(MobIter, mtCow); - ListOfSpawnables.insert(MobIter, mtPig); - ListOfSpawnables.insert(MobIter, mtSheep); + // No animals + case biNether: + case biEnd: + return mtInvalidType; + + // Squid only + case biOcean: + case biFrozenOcean: + case biFrozenRiver: + case biRiver: + case biDeepOcean: + ListOfSpawnables.insert(MobIter, mtSquid); + break; + + // Mooshroom only + case biMushroomIsland: + case biMushroomShore: + ListOfSpawnables.insert(MobIter, mtMooshroom); + break; + + case biJungle: + case biJungleHills: + case biJungleEdge: + case biJungleM: + case biJungleEdgeM: + ListOfSpawnables.insert(MobIter, mtOcelot); + + case biPlains: + case biSunflowerPlains: + case biSavanna: + case biSavannaPlateau: + case biSavannaM: + case biSavannaPlateauM: + ListOfSpawnables.insert(MobIter, mtHorse); + // ListOfSpawnables.insert(mtDonkey); + + // Wolves only + case biForest: + case biTaiga: + case biMegaTaiga: + case biColdTaiga: + case biColdTaigaM: + ListOfSpawnables.insert(MobIter, mtWolf); + + // All other mobs + default: + ListOfSpawnables.insert(MobIter, mtChicken); + ListOfSpawnables.insert(MobIter, mtCow); + ListOfSpawnables.insert(MobIter, mtPig); + ListOfSpawnables.insert(MobIter, mtSheep); } - if (ListOfSpawnables.size() == 0) + if (ListOfSpawnables.empty()) { - LOGD("Tried to spawn an animal from an empty list."); - return mtInvalidType; + return mtInvalidType; } int RandMob = m_Random.NextInt(ListOfSpawnables.size()); MobIter=ListOfSpawnables.begin(); for (int i = 0; i < RandMob; i++) { - ++MobIter; + ++MobIter; } return *MobIter; -- cgit v1.2.3 From 8d7c2d4b13c0a0903cc43d612dddcb10c12d7e21 Mon Sep 17 00:00:00 2001 From: p-mcgowan Date: Tue, 2 Dec 2014 11:26:37 -0800 Subject: fastRandom unused --- src/Generating/FinishGen.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Generating/FinishGen.h b/src/Generating/FinishGen.h index c8575f4d1..c4d2a0799 100644 --- a/src/Generating/FinishGen.h +++ b/src/Generating/FinishGen.h @@ -329,7 +329,6 @@ protected: cNoise m_Noise; int m_AnimalProbability; // Chance, [0..100], that an animal pack will be generated in a chunk - cFastRandom m_Random; // cFinishGen override: virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; -- cgit v1.2.3 From 6803df129f6e197e4f45294d46002f6dd8469655 Mon Sep 17 00:00:00 2001 From: p-mcgowan Date: Tue, 2 Dec 2014 11:32:53 -0800 Subject: typos and oversights for lua and CI --- src/Generating/FinishGen.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index 3e5b24017..0844b01ab 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -986,6 +986,8 @@ cFinishGenPassiveMobs::cFinishGenPassiveMobs(int a_Seed, cIniFile & a_IniFile, e void cFinishGenPassiveMobs::GenFinish(cChunkDesc & a_ChunkDesc) { + int chunkX = a_ChunkDesc.GetChunkX(); + int chunkZ = a_ChunkDesc.GetChunkZ(); int ChanceRnd = (m_Noise.IntNoise2DInt(chunkX, chunkZ) / 7) % 100; if (ChanceRnd > m_AnimalProbability) { @@ -1074,6 +1076,8 @@ eMonsterType cFinishGenPassiveMobs::GetRandomMob(cChunkDesc & a_ChunkDesc) std::set ListOfSpawnables; std::set::iterator MobIter = ListOfSpawnables.begin(); + int chunkX = a_ChunkDesc.GetChunkX(); + int chunkZ = a_ChunkDesc.GetChunkZ(); int x = (m_Noise.IntNoise2DInt(chunkX, chunkZ) / 7) % cChunkDef::Width; int z = (m_Noise.IntNoise2DInt(chunkX, chunkZ) / 7) % cChunkDef::Width; @@ -1137,7 +1141,7 @@ eMonsterType cFinishGenPassiveMobs::GetRandomMob(cChunkDesc & a_ChunkDesc) return mtInvalidType; } - int RandMob = m_Random.NextInt(ListOfSpawnables.size()); + int RandMob = (m_Noise.IntNoise2DInt(chunkX, chunkZ) / 7) % ListOfSpawnables.size(); MobIter=ListOfSpawnables.begin(); for (int i = 0; i < RandMob; i++) { -- cgit v1.2.3 From 2ea8a36df6bf0fd4d4eef21521ef0f07a87e895a Mon Sep 17 00:00:00 2001 From: p-mcgowan Date: Tue, 2 Dec 2014 15:55:09 -0800 Subject: forgot initializer --- src/Generating/ComposableGenerator.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index 6b8923955..bda45ad92 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -294,7 +294,11 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) for (AStringVector::const_iterator itr = Str.begin(); itr != Str.end(); ++itr) { // Finishers, alpha-sorted: - if (NoCaseCompare(*itr, "BottomLava") == 0) + if (NoCaseCompare(*itr, "Animals") == 0) + { + m_FinishGens.push_back(cFinishGenPtr(new cFinishGenPassiveMobs(Seed, a_IniFile, Dimension))); + } + else if (NoCaseCompare(*itr, "BottomLava") == 0) { int DefaultBottomLavaLevel = (Dimension == dimNether) ? 30 : 10; int BottomLavaLevel = a_IniFile.GetValueSetI("Generator", "BottomLavaLevel", DefaultBottomLavaLevel); -- cgit v1.2.3 From 7f8f2f1e704d77aed7a3406b88c3a93d61ae45a6 Mon Sep 17 00:00:00 2001 From: p-mcgowan Date: Tue, 2 Dec 2014 15:57:41 -0800 Subject: forgot generation defaul init --- src/World.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/World.cpp b/src/World.cpp index 00c8caf13..309be66b7 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -747,7 +747,7 @@ void cWorld::InitialiseGeneratorDefaults(cIniFile & a_IniFile) a_IniFile.GetValueSet("Generator", "BiomeGen", "Grown"); a_IniFile.GetValueSet("Generator", "ShapeGen", "BiomalNoise3D"); a_IniFile.GetValueSet("Generator", "CompositionGen", "Biomal"); - a_IniFile.GetValueSet("Generator", "Finishers", "Ravines, WormNestCaves, WaterLakes, WaterSprings, LavaLakes, LavaSprings, OreNests, Mineshafts, Trees, Villages, SprinkleFoliage, Ice, Snow, Lilypads, BottomLava, DeadBushes, PreSimulator"); + a_IniFile.GetValueSet("Generator", "Finishers", "Ravines, WormNestCaves, WaterLakes, WaterSprings, LavaLakes, LavaSprings, OreNests, Mineshafts, Trees, Villages, SprinkleFoliage, Ice, Snow, Lilypads, BottomLava, DeadBushes, PreSimulator, Animals"); break; } case dimNether: -- cgit v1.2.3 From b0e4643eb65f926a9e6b08ef73fa51adf03d92df Mon Sep 17 00:00:00 2001 From: Jonathan Fabian Date: Tue, 2 Dec 2014 20:24:05 -0500 Subject: Allow Spectator Gamemode as a world default. --- src/World.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/World.cpp b/src/World.cpp index 00c8caf13..9a6ef5c30 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -614,7 +614,7 @@ void cWorld::Start(void) } // Adjust the enum-backed variables into their respective bounds: - m_GameMode = (eGameMode) Clamp(GameMode, (int)gmSurvival, (int)gmAdventure); + m_GameMode = (eGameMode) Clamp(GameMode, (int)gmSurvival, (int)gmSpectator); m_TNTShrapnelLevel = (eShrapnelLevel)Clamp(TNTShrapnelLevel, (int)slNone, (int)slAll); m_Weather = (eWeather) Clamp(Weather, (int)wSunny, (int)wStorm); -- cgit v1.2.3 From 24c6da6209be2d6726c1bad441945310f1c4aaab Mon Sep 17 00:00:00 2001 From: Jonathan Fabian Date: Tue, 2 Dec 2014 20:25:41 -0500 Subject: Add missing IsSpectatorMode() checks in Player.cpp, make sure that player is flying when spawned otherwise it will fall through the world. --- src/Entities/Player.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index edcdb4799..e422d4042 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -120,6 +120,11 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) : { m_CanFly = true; } + if (World->IsGameModeSpectator()) //Otherwise Player will fall out of the world on join + { + m_CanFly = true; + m_IsFlying = true; + } } cRoot::Get()->GetServer()->PlayerCreated(this); @@ -1074,7 +1079,7 @@ bool cPlayer::IsGameModeAdventure(void) const bool cPlayer::IsGameModeSpectator(void) const { return (m_GameMode == gmSpectator) || // Either the player is explicitly in Spectator - ((m_GameMode == gmNotSet) && m_World->IsGameModeSpectator()); // or they inherit from the world and the world is Adventure + ((m_GameMode == gmNotSet) && m_World->IsGameModeSpectator()); // or they inherit from the world and the world is Spectator } @@ -1893,8 +1898,8 @@ void cPlayer::UseEquippedItem(int a_Amount) void cPlayer::TickBurning(cChunk & a_Chunk) { - // Don't burn in creative and stop burning in creative if necessary - if (!IsGameModeCreative()) + // Don't burn in creative or spectator and stop burning in creative if necessary + if (!(IsGameModeCreative() || IsGameModeSpectator())) { super::TickBurning(a_Chunk); } @@ -1913,9 +1918,9 @@ void cPlayer::HandleFood(void) { // Ref.: http://www.minecraftwiki.net/wiki/Hunger - if (IsGameModeCreative()) + if (IsGameModeCreative() || IsGameModeSpectator()) { - // Hunger is disabled for Creative + // Hunger is disabled for Creative and Spectator return; } @@ -2080,7 +2085,7 @@ void cPlayer::UpdateMovementStats(const Vector3d & a_DeltaPos) void cPlayer::ApplyFoodExhaustionFromMovement() { - if (IsGameModeCreative()) + if (IsGameModeCreative() || IsGameModeSpectator()) { return; } -- cgit v1.2.3 From 1e6c13ea51061be078f705135a0183f38d3f0bdd Mon Sep 17 00:00:00 2001 From: Jonathan Fabian Date: Tue, 2 Dec 2014 20:54:56 -0500 Subject: Fix Spaces to Tabs --- src/Entities/Player.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index e422d4042..e066df1bd 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -120,11 +120,11 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) : { m_CanFly = true; } - if (World->IsGameModeSpectator()) //Otherwise Player will fall out of the world on join - { - m_CanFly = true; - m_IsFlying = true; - } + if (World->IsGameModeSpectator()) //Otherwise Player will fall out of the world on join + { + m_CanFly = true; + m_IsFlying = true; + } } cRoot::Get()->GetServer()->PlayerCreated(this); -- cgit v1.2.3 From d3484334064d950654bdf12ec0a81e1b860f627c Mon Sep 17 00:00:00 2001 From: p-mcgowan Date: Tue, 2 Dec 2014 22:35:34 -0800 Subject: doxy-commenting --- src/Generating/FinishGen.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Generating/FinishGen.h b/src/Generating/FinishGen.h index c4d2a0799..15dd70e15 100644 --- a/src/Generating/FinishGen.h +++ b/src/Generating/FinishGen.h @@ -310,7 +310,7 @@ protected: // cFinishGen override: virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; - /// Tries to place a spring at the specified coords, checks neighbors. Returns true if successful + // Tries to place a spring at the specified coords, checks neighbors. Returns true if successful bool TryPlaceSpring(cChunkDesc & a_ChunkDesc, int x, int y, int z); } ; @@ -333,10 +333,10 @@ protected: // cFinishGen override: virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; - // Tries to spawn a mob in the center of the pack. If successful, spawns 0-5 more. + /** Tries to spawn a mob in the center of the pack. If successful, spawns 0-5 more. */ bool TrySpawnAnimals(cChunkDesc & a_ChunkDesc, int x, int y, int z, eMonsterType AnimalToSpawn); - // Gets a random mob from biome-dependant list + /** Gets a random mob from biome-dependant list */ eMonsterType GetRandomMob(cChunkDesc & a_ChunkDesc); } ; -- cgit v1.2.3 From 8c3b9ae15b8c590610fb05f32bd19d2d480f3fd6 Mon Sep 17 00:00:00 2001 From: p-mcgowan Date: Wed, 3 Dec 2014 00:12:32 -0800 Subject: class description and doxy-commenting --- src/Generating/FinishGen.cpp | 6 +++--- src/Generating/FinishGen.h | 7 +++++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index 0844b01ab..d938c34bd 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -1001,7 +1001,7 @@ void cFinishGenPassiveMobs::GenFinish(cChunkDesc & a_ChunkDesc) return; } - // Try spawning a pack center 10 times, should get roughly the same probability + /** Try spawning a pack center 10 times, should get roughly the same probability */ for (int Tries = 0; Tries < 10; Tries++) { int PackCenterX = (m_Noise.IntNoise2DInt(chunkX, chunkZ) / 7) % cChunkDef::Width; @@ -1030,7 +1030,7 @@ bool cFinishGenPassiveMobs::TrySpawnAnimals(cChunkDesc & a_ChunkDesc, int a_RelX BLOCKTYPE BlockAtFeet = a_ChunkDesc.GetBlockType(a_RelX, a_RelY, a_RelZ); BLOCKTYPE BlockUnderFeet = a_ChunkDesc.GetBlockType(a_RelX, a_RelY - 1, a_RelZ); - // Check block below (opaque, grass, water), and above (air) + /** Check block below (opaque, grass, water), and above (air) */ if (AnimalToSpawn == mtSquid && BlockAtFeet != E_BLOCK_WATER) { return false; @@ -1081,7 +1081,7 @@ eMonsterType cFinishGenPassiveMobs::GetRandomMob(cChunkDesc & a_ChunkDesc) int x = (m_Noise.IntNoise2DInt(chunkX, chunkZ) / 7) % cChunkDef::Width; int z = (m_Noise.IntNoise2DInt(chunkX, chunkZ) / 7) % cChunkDef::Width; - // Check biomes first to get a list of animals + /** Check biomes first to get a list of animals */ switch (a_ChunkDesc.GetBiome(x, z)) { // No animals diff --git a/src/Generating/FinishGen.h b/src/Generating/FinishGen.h index 15dd70e15..e11e6f414 100644 --- a/src/Generating/FinishGen.h +++ b/src/Generating/FinishGen.h @@ -318,6 +318,9 @@ protected: +/** This class populates generated chunks with packs of biome-dependant animals +Animals: cows, sheep, pigs, mooshrooms, squid, horses, wolves, ocelots +*/ class cFinishGenPassiveMobs : public cFinishGen { @@ -328,9 +331,9 @@ public: protected: cNoise m_Noise; - int m_AnimalProbability; // Chance, [0..100], that an animal pack will be generated in a chunk + int m_AnimalProbability; /** Chance, [0..100], that an animal pack will be generated in a chunk */ - // cFinishGen override: + /** cFinishGen override: */ virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; /** Tries to spawn a mob in the center of the pack. If successful, spawns 0-5 more. */ -- cgit v1.2.3 From 27185dd3748b04af35a3d17eb5c2c58e826cd9cb Mon Sep 17 00:00:00 2001 From: p-mcgowan Date: Wed, 3 Dec 2014 00:26:15 -0800 Subject: clearing CheckBasicStyle.lua messages --- src/Bindings/DeprecatedBindings.cpp | 4 ++-- src/Generating/FinishGen.cpp | 26 +++++++++++++------------- src/Generating/FinishGen.h | 30 +++++++++++++++--------------- src/Mobs/Pig.cpp | 8 ++++---- 4 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/Bindings/DeprecatedBindings.cpp b/src/Bindings/DeprecatedBindings.cpp index 0b2539fde..95cd9c4f7 100644 --- a/src/Bindings/DeprecatedBindings.cpp +++ b/src/Bindings/DeprecatedBindings.cpp @@ -233,8 +233,8 @@ static int tolua_AllToLua_StringToMobType00(lua_State* tolua_S) #ifndef TOLUA_RELEASE tolua_Error tolua_err; if ( - !tolua_iscppstring(tolua_S,1,0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) + !tolua_iscppstring(tolua_S, 1, 0, &tolua_err) || + !tolua_isnoobj(tolua_S, 2, &tolua_err) ) goto tolua_lerror; else diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index b9d702429..9e035926e 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -65,7 +65,7 @@ void cFinishGenNetherClumpFoliage::GenFinish(cChunkDesc & a_ChunkDesc) { continue; } - + // Choose what block to use. NOISE_DATATYPE BlockType = m_Noise.IntNoise3D((int) ChunkX, y, (int) ChunkZ); if (BlockType < -0.7) @@ -195,10 +195,10 @@ void cFinishGenTallGrass::GenFinish(cChunkDesc & a_ChunkDesc) { continue; } - + // Get the top block + 1. This is the place where the grass would finaly be placed: int y = a_ChunkDesc.GetHeight(x, z) + 1; - + if (y >= 255) { continue; @@ -281,7 +281,7 @@ bool cFinishGenSprinkleFoliage::TryAddSugarcane(cChunkDesc & a_ChunkDesc, int a_ { return false; } - + // All conditions met, place a sugarcane here: a_ChunkDesc.SetBlockType(a_RelX, a_RelY + 1, a_RelZ, E_BLOCK_SUGARCANE); return true; @@ -294,7 +294,7 @@ bool cFinishGenSprinkleFoliage::TryAddSugarcane(cChunkDesc & a_ChunkDesc, int a_ void cFinishGenSprinkleFoliage::GenFinish(cChunkDesc & a_ChunkDesc) { // Generate small foliage (1-block): - + // TODO: Update heightmap with 1-block-tall foliage for (int z = 0; z < cChunkDef::Width; z++) { @@ -319,7 +319,7 @@ void cFinishGenSprinkleFoliage::GenFinish(cChunkDesc & a_ChunkDesc) // WEIRD, since we're using heightmap, so there should NOT be anything above it continue; } - + const float xx = (float)BlockX; float val1 = m_Noise.CubicNoise2D(xx * 0.1f, zz * 0.1f); float val2 = m_Noise.CubicNoise2D(xx * 0.01f, zz * 0.01f); @@ -359,7 +359,7 @@ void cFinishGenSprinkleFoliage::GenFinish(cChunkDesc & a_ChunkDesc) } break; } // case E_BLOCK_GRASS - + case E_BLOCK_SAND: { int y = Top + 1; @@ -400,7 +400,7 @@ void cFinishGenSoulsandRims::GenFinish(cChunkDesc & a_ChunkDesc) int ChunkZ = a_ChunkDesc.GetChunkZ() * cChunkDef::Width; HEIGHTTYPE MaxHeight = a_ChunkDesc.GetMaxHeight(); - for (int x = 0; x < 16; x++) + for (int x = 0; x < 16; x++) { int xx = ChunkX + x; for (int z = 0; z < 16; z++) @@ -768,7 +768,7 @@ void cFinishGenPreSimulator::StationarizeFluid( } // for y } // for x } // for z - + // Turn fluid at the chunk edges into non-stationary fluid: for (int y = 0; y < cChunkDef::Height; y++) { @@ -860,12 +860,12 @@ void cFinishGenFluidSprings::GenFinish(cChunkDesc & a_ChunkDesc) // Not in this chunk return; } - + // Get the height at which to try: int Height = m_Noise.IntNoise3DInt(128 * a_ChunkDesc.GetChunkX(), 1024, 256 * a_ChunkDesc.GetChunkZ()) / 11; Height %= m_HeightDistribution.GetSum(); Height = m_HeightDistribution.MapValue(Height); - + // Try adding the spring at the height, if unsuccessful, move lower: for (int y = Height; y > 1; y--) { @@ -903,7 +903,7 @@ bool cFinishGenFluidSprings::TryPlaceSpring(cChunkDesc & a_ChunkDesc, int x, int { return false; } - + static const struct { int x, y, z; @@ -934,7 +934,7 @@ bool cFinishGenFluidSprings::TryPlaceSpring(cChunkDesc & a_ChunkDesc, int x, int { return false; } - + // Has exactly one air neighbor, place a spring: a_ChunkDesc.SetBlockTypeMeta(x, y, z, m_Fluid, 0); return true; diff --git a/src/Generating/FinishGen.h b/src/Generating/FinishGen.h index d45365683..c1100b51f 100644 --- a/src/Generating/FinishGen.h +++ b/src/Generating/FinishGen.h @@ -121,7 +121,7 @@ class cFinishGenSoulsandRims : public cFinishGen { public: - cFinishGenSoulsandRims(int a_Seed) : + cFinishGenSoulsandRims(int a_Seed) : m_Noise(a_Seed) { } @@ -141,14 +141,14 @@ class cFinishGenSprinkleFoliage : { public: cFinishGenSprinkleFoliage(int a_Seed) : m_Noise(a_Seed), m_Seed(a_Seed) {} - + protected: cNoise m_Noise; int m_Seed; - + /// Tries to place sugarcane at the coords specified, returns true if successful bool TryAddSugarcane(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelY, int a_RelZ); - + // cFinishGen override: virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; } ; @@ -186,31 +186,31 @@ public: { m_IsAllowedBelow[idx] = false; } - + // Load the allowed blocks into m_IsAllowedBelow for (BlockList::iterator itr = a_AllowedBelow.begin(); itr != a_AllowedBelow.end(); ++itr) { m_IsAllowedBelow[*itr] = true; } - + // Initialize all the biome types. for (size_t idx = 0; idx < ARRAYCOUNT(m_IsBiomeAllowed); ++idx) { m_IsBiomeAllowed[idx] = false; } - + // Load the allowed biomes into m_IsBiomeAllowed for (BiomeList::iterator itr = a_Biomes.begin(); itr != a_Biomes.end(); ++itr) { m_IsBiomeAllowed[*itr] = true; } } - + protected: cNoise m_Noise; BLOCKTYPE m_BlockType; int m_Amount; ///< Relative amount of blocks to try adding. 1 = one block per 256 biome columns. - + int GetNumToGen(const cChunkDef::BiomeMap & a_BiomeMap); // Returns true if the given biome is a biome that is allowed. @@ -225,7 +225,7 @@ protected: return m_IsAllowedBelow[a_BlockBelow]; } - + // cFinishGen override: virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; } ; @@ -242,11 +242,11 @@ public: m_Level(a_Level) { } - + int GetLevel(void) const { return m_Level; } protected: int m_Level; - + // cFinishGen override: virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; } ; @@ -260,7 +260,7 @@ class cFinishGenPreSimulator : { public: cFinishGenPreSimulator(bool a_PreSimulateFallingBlocks, bool a_PreSimulateWater, bool a_PreSimulateLava); - + protected: bool m_PreSimulateFallingBlocks; @@ -272,7 +272,7 @@ protected: cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change cChunkDef::HeightMap & a_HeightMap // Height map to update by the current data ); - + /** For each fluid block: - if all surroundings are of the same fluid, makes it stationary; otherwise makes it flowing (excl. top) - all fluid on the chunk's edge is made flowing @@ -297,7 +297,7 @@ class cFinishGenFluidSprings : { public: cFinishGenFluidSprings(int a_Seed, BLOCKTYPE a_Fluid, cIniFile & a_IniFile, eDimension a_Dimension); - + protected: cNoise m_Noise; diff --git a/src/Mobs/Pig.cpp b/src/Mobs/Pig.cpp index 50b69e44f..1e4c35acd 100644 --- a/src/Mobs/Pig.cpp +++ b/src/Mobs/Pig.cpp @@ -49,17 +49,17 @@ void cPig::OnRightClicked(cPlayer & a_Player) a_Player.Detach(); return; } - + if (m_Attachee->IsPlayer()) { // Another player is already sitting in here, cannot attach return; } - + // Detach whatever is sitting in this pig now: m_Attachee->Detach(); } - + // Attach the player to this pig a_Player.AttachTo(this); } @@ -100,7 +100,7 @@ void cPig::Tick(float a_Dt, cChunk & a_Chunk) bool cPig::DoTakeDamage(TakeDamageInfo & a_TDI) -{ +{ if (!super::DoTakeDamage(a_TDI)) { return false; -- cgit v1.2.3 From 010546051e60856cfaeebbf60e1fc641d467c566 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 3 Dec 2014 16:14:26 +0100 Subject: Fixes socket leak in HTTP server. Fixes #1643. --- src/OSSupport/SocketThreads.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/OSSupport/SocketThreads.cpp b/src/OSSupport/SocketThreads.cpp index 7a3ef4274..153d6ed1d 100644 --- a/src/OSSupport/SocketThreads.cpp +++ b/src/OSSupport/SocketThreads.cpp @@ -86,7 +86,8 @@ void cSocketThreads::RemoveClient(const cCallback * a_Client) } } // for itr - m_Threads[] - ASSERT(!"Removing an unknown client"); + // This client wasn't found. + // It's not an error, because it may have been removed by a different thread in the meantime. } @@ -491,10 +492,17 @@ void cSocketThreads::cSocketThread::ReadFromSockets(fd_set * a_Read) { case sSlot::ssNormal: { - // Notify the callback that the remote has closed the socket; keep the slot - m_Slots[i].m_Client->SocketClosed(); + // Close the socket on our side: m_Slots[i].m_State = sSlot::ssRemoteClosed; m_Slots[i].m_Socket.CloseSocket(); + + // Notify the callback that the remote has closed the socket, *after* removing the socket: + cCallback * client = m_Slots[i].m_Client; + m_Slots[i] = m_Slots[--m_NumSlots]; + if (client != nullptr) + { + client->SocketClosed(); + } break; } case sSlot::ssWritingRestOut: -- cgit v1.2.3 From 664ea804a3fe4a5574d31b27ebe584aafb816be7 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 3 Dec 2014 18:04:08 +0100 Subject: ByteBuffer: Re-added Single-thread access checker. --- src/ByteBuffer.cpp | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/ByteBuffer.h | 6 ++++ 2 files changed, 90 insertions(+) diff --git a/src/ByteBuffer.cpp b/src/ByteBuffer.cpp index 6406a2625..acda8a839 100644 --- a/src/ByteBuffer.cpp +++ b/src/ByteBuffer.cpp @@ -109,6 +109,47 @@ public: +#ifdef _DEBUG + + /** Simple RAII class that is used for checking that no two threads are using an object simultanously. + It requires the monitored object to provide the storage for a thread ID. + It uses that storage to check if the thread ID of consecutive calls is the same all the time. */ + class cSingleThreadAccessChecker + { + public: + cSingleThreadAccessChecker(std::thread::id * a_ThreadID) : + m_ThreadID(a_ThreadID) + { + ASSERT( + (*a_ThreadID == std::this_thread::get_id()) || // Either the object is used by current thread... + (*a_ThreadID == std::thread::id()) // ... or by no thread at all + ); + + // Mark as being used by this thread: + *m_ThreadID = std::this_thread::get_id(); + } + + ~cSingleThreadAccessChecker() + { + // Mark as not being used by any thread: + *m_ThreadID = std::thread::id(); + } + + protected: + /** Points to the storage used for ID of the thread using the object. */ + std::thread::id * m_ThreadID; + }; + +#define CHECK_THREAD cSingleThreadAccessChecker Checker(&m_ThreadID); + +#else + #define CHECK_THREAD +#endif + + + + + //////////////////////////////////////////////////////////////////////////////// // cByteBuffer: @@ -140,6 +181,7 @@ cByteBuffer::~cByteBuffer() bool cByteBuffer::Write(const void * a_Bytes, size_t a_Count) { + CHECK_THREAD CheckValid(); // Store the current free space for a check after writing: @@ -186,6 +228,7 @@ bool cByteBuffer::Write(const void * a_Bytes, size_t a_Count) size_t cByteBuffer::GetFreeSpace(void) const { + CHECK_THREAD CheckValid(); if (m_WritePos >= m_DataStart) { @@ -207,6 +250,7 @@ size_t cByteBuffer::GetFreeSpace(void) const /// Returns the number of bytes that are currently in the ringbuffer. Note GetReadableBytes() size_t cByteBuffer::GetUsedSpace(void) const { + CHECK_THREAD CheckValid(); ASSERT(m_BufferSize >= GetFreeSpace()); ASSERT((m_BufferSize - GetFreeSpace()) >= 1); @@ -220,6 +264,7 @@ size_t cByteBuffer::GetUsedSpace(void) const /// Returns the number of bytes that are currently available for reading (may be less than UsedSpace due to some data having been read already) size_t cByteBuffer::GetReadableSpace(void) const { + CHECK_THREAD CheckValid(); if (m_ReadPos > m_WritePos) { @@ -238,6 +283,7 @@ size_t cByteBuffer::GetReadableSpace(void) const bool cByteBuffer::CanReadBytes(size_t a_Count) const { + CHECK_THREAD CheckValid(); return (a_Count <= GetReadableSpace()); } @@ -248,6 +294,7 @@ bool cByteBuffer::CanReadBytes(size_t a_Count) const bool cByteBuffer::CanWriteBytes(size_t a_Count) const { + CHECK_THREAD CheckValid(); return (a_Count <= GetFreeSpace()); } @@ -258,6 +305,7 @@ bool cByteBuffer::CanWriteBytes(size_t a_Count) const bool cByteBuffer::ReadChar(char & a_Value) { + CHECK_THREAD CheckValid(); NEEDBYTES(1); ReadBuf(&a_Value, 1); @@ -270,6 +318,7 @@ bool cByteBuffer::ReadChar(char & a_Value) bool cByteBuffer::ReadByte(unsigned char & a_Value) { + CHECK_THREAD CheckValid(); NEEDBYTES(1); ReadBuf(&a_Value, 1); @@ -282,6 +331,7 @@ bool cByteBuffer::ReadByte(unsigned char & a_Value) bool cByteBuffer::ReadBEShort(short & a_Value) { + CHECK_THREAD CheckValid(); NEEDBYTES(2); ReadBuf(&a_Value, 2); @@ -295,6 +345,7 @@ bool cByteBuffer::ReadBEShort(short & a_Value) bool cByteBuffer::ReadBEInt(int & a_Value) { + CHECK_THREAD CheckValid(); NEEDBYTES(4); ReadBuf(&a_Value, 4); @@ -308,6 +359,7 @@ bool cByteBuffer::ReadBEInt(int & a_Value) bool cByteBuffer::ReadBEInt64(Int64 & a_Value) { + CHECK_THREAD CheckValid(); NEEDBYTES(8); ReadBuf(&a_Value, 8); @@ -321,6 +373,7 @@ bool cByteBuffer::ReadBEInt64(Int64 & a_Value) bool cByteBuffer::ReadBEFloat(float & a_Value) { + CHECK_THREAD CheckValid(); NEEDBYTES(4); ReadBuf(&a_Value, 4); @@ -334,6 +387,7 @@ bool cByteBuffer::ReadBEFloat(float & a_Value) bool cByteBuffer::ReadBEDouble(double & a_Value) { + CHECK_THREAD CheckValid(); NEEDBYTES(8); ReadBuf(&a_Value, 8); @@ -347,6 +401,7 @@ bool cByteBuffer::ReadBEDouble(double & a_Value) bool cByteBuffer::ReadBool(bool & a_Value) { + CHECK_THREAD CheckValid(); NEEDBYTES(1); char Value = 0; @@ -361,6 +416,7 @@ bool cByteBuffer::ReadBool(bool & a_Value) bool cByteBuffer::ReadBEUTF16String16(AString & a_Value) { + CHECK_THREAD CheckValid(); short Length; if (!ReadBEShort(Length)) @@ -381,6 +437,7 @@ bool cByteBuffer::ReadBEUTF16String16(AString & a_Value) bool cByteBuffer::ReadVarInt(UInt32 & a_Value) { + CHECK_THREAD CheckValid(); UInt32 Value = 0; int Shift = 0; @@ -402,6 +459,7 @@ bool cByteBuffer::ReadVarInt(UInt32 & a_Value) bool cByteBuffer::ReadVarUTF8String(AString & a_Value) { + CHECK_THREAD CheckValid(); UInt32 Size = 0; if (!ReadVarInt(Size)) @@ -421,6 +479,7 @@ bool cByteBuffer::ReadVarUTF8String(AString & a_Value) bool cByteBuffer::ReadLEInt(int & a_Value) { + CHECK_THREAD CheckValid(); NEEDBYTES(4); ReadBuf(&a_Value, 4); @@ -439,6 +498,7 @@ bool cByteBuffer::ReadLEInt(int & a_Value) bool cByteBuffer::ReadPosition(int & a_BlockX, int & a_BlockY, int & a_BlockZ) { + CHECK_THREAD Int64 Value; if (!ReadBEInt64(Value)) { @@ -463,6 +523,7 @@ bool cByteBuffer::ReadPosition(int & a_BlockX, int & a_BlockY, int & a_BlockZ) bool cByteBuffer::WriteChar(char a_Value) { + CHECK_THREAD CheckValid(); PUTBYTES(1); return WriteBuf(&a_Value, 1); @@ -474,6 +535,7 @@ bool cByteBuffer::WriteChar(char a_Value) bool cByteBuffer::WriteByte(unsigned char a_Value) { + CHECK_THREAD CheckValid(); PUTBYTES(1); return WriteBuf(&a_Value, 1); @@ -485,6 +547,7 @@ bool cByteBuffer::WriteByte(unsigned char a_Value) bool cByteBuffer::WriteBEShort(short a_Value) { + CHECK_THREAD CheckValid(); PUTBYTES(2); u_short Converted = htons((u_short)a_Value); @@ -497,6 +560,7 @@ bool cByteBuffer::WriteBEShort(short a_Value) bool cByteBuffer::WriteBEUShort(unsigned short a_Value) { + CHECK_THREAD CheckValid(); PUTBYTES(2); u_short Converted = htons((u_short)a_Value); @@ -509,6 +573,7 @@ bool cByteBuffer::WriteBEUShort(unsigned short a_Value) bool cByteBuffer::WriteBEInt(int a_Value) { + CHECK_THREAD CheckValid(); PUTBYTES(4); UInt32 Converted = HostToNetwork4(&a_Value); @@ -521,6 +586,7 @@ bool cByteBuffer::WriteBEInt(int a_Value) bool cByteBuffer::WriteBEInt64(Int64 a_Value) { + CHECK_THREAD CheckValid(); PUTBYTES(8); UInt64 Converted = HostToNetwork8(&a_Value); @@ -533,6 +599,7 @@ bool cByteBuffer::WriteBEInt64(Int64 a_Value) bool cByteBuffer::WriteBEFloat(float a_Value) { + CHECK_THREAD CheckValid(); PUTBYTES(4); UInt32 Converted = HostToNetwork4(&a_Value); @@ -545,6 +612,7 @@ bool cByteBuffer::WriteBEFloat(float a_Value) bool cByteBuffer::WriteBEDouble(double a_Value) { + CHECK_THREAD CheckValid(); PUTBYTES(8); UInt64 Converted = HostToNetwork8(&a_Value); @@ -558,6 +626,7 @@ bool cByteBuffer::WriteBEDouble(double a_Value) bool cByteBuffer::WriteBool(bool a_Value) { + CHECK_THREAD CheckValid(); return WriteChar(a_Value ? 1 : 0); } @@ -568,6 +637,7 @@ bool cByteBuffer::WriteBool(bool a_Value) bool cByteBuffer::WriteVarInt(UInt32 a_Value) { + CHECK_THREAD CheckValid(); // A 32-bit integer can be encoded by at most 5 bytes: @@ -588,6 +658,7 @@ bool cByteBuffer::WriteVarInt(UInt32 a_Value) bool cByteBuffer::WriteVarUTF8String(const AString & a_Value) { + CHECK_THREAD CheckValid(); PUTBYTES(a_Value.size() + 1); // This is a lower-bound on the bytes that will be actually written. Fail early. bool res = WriteVarInt((UInt32)(a_Value.size())); @@ -604,6 +675,7 @@ bool cByteBuffer::WriteVarUTF8String(const AString & a_Value) bool cByteBuffer::WriteLEInt(int a_Value) { + CHECK_THREAD CheckValid(); #ifdef IS_LITTLE_ENDIAN return WriteBuf((const char *)&a_Value, 4); @@ -619,6 +691,7 @@ bool cByteBuffer::WriteLEInt(int a_Value) bool cByteBuffer::WritePosition(int a_BlockX, int a_BlockY, int a_BlockZ) { + CHECK_THREAD return WriteBEInt64(((Int64)a_BlockX & 0x3FFFFFF) << 38 | ((Int64)a_BlockY & 0xFFF) << 26 | ((Int64)a_BlockZ & 0x3FFFFFF)); } @@ -628,6 +701,7 @@ bool cByteBuffer::WritePosition(int a_BlockX, int a_BlockY, int a_BlockZ) bool cByteBuffer::ReadBuf(void * a_Buffer, size_t a_Count) { + CHECK_THREAD CheckValid(); NEEDBYTES(a_Count); char * Dst = (char *)a_Buffer; // So that we can do byte math @@ -660,6 +734,7 @@ bool cByteBuffer::ReadBuf(void * a_Buffer, size_t a_Count) bool cByteBuffer::WriteBuf(const void * a_Buffer, size_t a_Count) { + CHECK_THREAD CheckValid(); PUTBYTES(a_Count); char * Src = (char *)a_Buffer; // So that we can do byte math @@ -689,6 +764,7 @@ bool cByteBuffer::WriteBuf(const void * a_Buffer, size_t a_Count) bool cByteBuffer::ReadString(AString & a_String, size_t a_Count) { + CHECK_THREAD CheckValid(); NEEDBYTES(a_Count); a_String.clear(); @@ -723,6 +799,7 @@ bool cByteBuffer::ReadString(AString & a_String, size_t a_Count) bool cByteBuffer::ReadUTF16String(AString & a_String, size_t a_NumChars) { // Reads 2 * a_NumChars bytes and interprets it as a UTF16 string, converting it into UTF8 string a_String + CHECK_THREAD CheckValid(); AString RawData; if (!ReadString(RawData, a_NumChars * 2)) @@ -739,6 +816,7 @@ bool cByteBuffer::ReadUTF16String(AString & a_String, size_t a_NumChars) bool cByteBuffer::SkipRead(size_t a_Count) { + CHECK_THREAD CheckValid(); if (!CanReadBytes(a_Count)) { @@ -754,6 +832,7 @@ bool cByteBuffer::SkipRead(size_t a_Count) void cByteBuffer::ReadAll(AString & a_Data) { + CHECK_THREAD CheckValid(); ReadString(a_Data, GetReadableSpace()); } @@ -764,6 +843,7 @@ void cByteBuffer::ReadAll(AString & a_Data) bool cByteBuffer::ReadToByteBuffer(cByteBuffer & a_Dst, size_t a_NumBytes) { + CHECK_THREAD if (!a_Dst.CanWriteBytes(a_NumBytes) || !CanReadBytes(a_NumBytes)) { // There's not enough source bytes or space in the dest BB @@ -788,6 +868,7 @@ bool cByteBuffer::ReadToByteBuffer(cByteBuffer & a_Dst, size_t a_NumBytes) void cByteBuffer::CommitRead(void) { + CHECK_THREAD CheckValid(); m_DataStart = m_ReadPos; } @@ -798,6 +879,7 @@ void cByteBuffer::CommitRead(void) void cByteBuffer::ResetRead(void) { + CHECK_THREAD CheckValid(); m_ReadPos = m_DataStart; } @@ -810,6 +892,7 @@ void cByteBuffer::ReadAgain(AString & a_Out) { // Return the data between m_DataStart and m_ReadPos (the data that has been read but not committed) // Used by ProtoProxy to repeat communication twice, once for parsing and the other time for the remote party + CHECK_THREAD CheckValid(); size_t DataStart = m_DataStart; if (m_ReadPos < m_DataStart) @@ -829,6 +912,7 @@ void cByteBuffer::ReadAgain(AString & a_Out) void cByteBuffer::AdvanceReadPos(size_t a_Count) { + CHECK_THREAD CheckValid(); m_ReadPos += a_Count; if (m_ReadPos >= m_BufferSize) diff --git a/src/ByteBuffer.h b/src/ByteBuffer.h index e80763772..2a316fa32 100644 --- a/src/ByteBuffer.h +++ b/src/ByteBuffer.h @@ -133,6 +133,12 @@ protected: size_t m_DataStart; // Where the data starts in the ringbuffer size_t m_WritePos; // Where the data ends in the ringbuffer size_t m_ReadPos; // Where the next read will start in the ringbuffer + + #ifdef _DEBUG + /** The ID of the thread currently accessing the object. + Used for checking that only one thread accesses the object at a time, via cSingleThreadAccessChecker. */ + mutable std::thread::id m_ThreadID; + #endif /** Advances the m_ReadPos by a_Count bytes */ void AdvanceReadPos(size_t a_Count); -- cgit v1.2.3 From f206f34a3d1d5bdda7625a61dcf35514f485af79 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 3 Dec 2014 18:04:21 +0100 Subject: Server: Fixed a MSVC warning. --- src/Server.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Server.cpp b/src/Server.cpp index 8759d5747..db1522602 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -78,7 +78,7 @@ void cServer::cTickThread::Execute(void) while (!m_ShouldTerminate) { auto NowTime = std::chrono::steady_clock::now(); - m_ShouldTerminate = !m_Server.Tick(std::chrono::duration_cast(NowTime - LastTime).count()); + m_ShouldTerminate = !m_Server.Tick(static_cast(std::chrono::duration_cast(NowTime - LastTime).count())); auto TickTime = std::chrono::steady_clock::now() - NowTime; if (TickTime < msPerTick) -- cgit v1.2.3 From 0ecc16c61858f4635ea87cc80718230f6c35f5b8 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 3 Dec 2014 18:24:28 +0100 Subject: Fixed indent. --- src/ByteBuffer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ByteBuffer.cpp b/src/ByteBuffer.cpp index acda8a839..080176dcd 100644 --- a/src/ByteBuffer.cpp +++ b/src/ByteBuffer.cpp @@ -140,10 +140,10 @@ public: std::thread::id * m_ThreadID; }; -#define CHECK_THREAD cSingleThreadAccessChecker Checker(&m_ThreadID); + #define CHECK_THREAD cSingleThreadAccessChecker Checker(&m_ThreadID); #else - #define CHECK_THREAD + #define CHECK_THREAD #endif -- cgit v1.2.3 From 6ca47185c467a8972ecea66df44c2145e061053e Mon Sep 17 00:00:00 2001 From: Jonathan Fabian Date: Wed, 3 Dec 2014 23:04:53 -0500 Subject: Updated whitespace in comment, changed conditional to logical equivalent due to popular demand --- src/Entities/Player.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index e066df1bd..bafd06277 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -120,7 +120,7 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) : { m_CanFly = true; } - if (World->IsGameModeSpectator()) //Otherwise Player will fall out of the world on join + if (World->IsGameModeSpectator()) // Otherwise Player will fall out of the world on join { m_CanFly = true; m_IsFlying = true; @@ -1899,7 +1899,7 @@ void cPlayer::UseEquippedItem(int a_Amount) void cPlayer::TickBurning(cChunk & a_Chunk) { // Don't burn in creative or spectator and stop burning in creative if necessary - if (!(IsGameModeCreative() || IsGameModeSpectator())) + if (!IsGameModeCreative() && !IsGameModeSpectator()) { super::TickBurning(a_Chunk); } -- cgit v1.2.3 From 34807248e269c9fae99ac63b3185f134c4c4fa56 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 4 Dec 2014 09:21:57 +0100 Subject: Fixed the CRAFTING_NO_RECIPE hook call. It used a pointer-to-pointer-to-cCraftingRecipe, which the Lua bindings didn't know how to handle, and emitted a warning message at runtime. Fixes #1641. --- src/Bindings/Plugin.h | 2 +- src/Bindings/PluginLua.cpp | 2 +- src/Bindings/PluginLua.h | 2 +- src/Bindings/PluginManager.cpp | 2 +- src/Bindings/PluginManager.h | 2 +- src/CraftingRecipes.cpp | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index 8cc9ff0cd..08677553c 100644 --- a/src/Bindings/Plugin.h +++ b/src/Bindings/Plugin.h @@ -54,7 +54,7 @@ public: virtual bool OnChunkUnloaded (cWorld & a_World, int a_ChunkX, int a_ChunkZ) = 0; virtual bool OnChunkUnloading (cWorld & a_World, int a_ChunkX, int a_ChunkZ) = 0; virtual bool OnCollectingPickup (cPlayer & a_Player, cPickup & a_Pickup) = 0; - virtual bool OnCraftingNoRecipe (cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe * a_Recipe) = 0; + virtual bool OnCraftingNoRecipe (cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe & a_Recipe) = 0; virtual bool OnDisconnect (cClientHandle & a_Client, const AString & a_Reason) = 0; virtual bool OnEntityAddEffect (cEntity & a_Entity, int a_EffectType, int a_EffectDurationTicks, int a_EffectIntensity, double a_DistanceModifier) = 0; virtual bool OnExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split) = 0; diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index 391d8bcbe..ea782ea3f 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -382,7 +382,7 @@ bool cPluginLua::OnCollectingPickup(cPlayer & a_Player, cPickup & a_Pickup) -bool cPluginLua::OnCraftingNoRecipe(cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe * a_Recipe) +bool cPluginLua::OnCraftingNoRecipe(cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe & a_Recipe) { cCSLock Lock(m_CriticalSection); bool res = false; diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index 6bb134efc..7de5ffec4 100644 --- a/src/Bindings/PluginLua.h +++ b/src/Bindings/PluginLua.h @@ -78,7 +78,7 @@ public: virtual bool OnChunkUnloaded (cWorld & a_World, int a_ChunkX, int a_ChunkZ) override; virtual bool OnChunkUnloading (cWorld & a_World, int a_ChunkX, int a_ChunkZ) override; virtual bool OnCollectingPickup (cPlayer & a_Player, cPickup & a_Pickup) override; - virtual bool OnCraftingNoRecipe (cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe * a_Recipe) override; + virtual bool OnCraftingNoRecipe (cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe & a_Recipe) override; virtual bool OnDisconnect (cClientHandle & a_Client, const AString & a_Reason) override; virtual bool OnEntityAddEffect (cEntity & a_Entity, int a_EffectType, int a_EffectDurationTicks, int a_EffectIntensity, double a_DistanceModifier) override; virtual bool OnExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split) override; diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index f63578885..f951f6221 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -448,7 +448,7 @@ bool cPluginManager::CallHookCollectingPickup(cPlayer & a_Player, cPickup & a_Pi -bool cPluginManager::CallHookCraftingNoRecipe(cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe * a_Recipe) +bool cPluginManager::CallHookCraftingNoRecipe(cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe & a_Recipe) { FIND_HOOK(HOOK_CRAFTING_NO_RECIPE); VERIFY_HOOK; diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index bc8c1f5e6..3a2aecc92 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -187,7 +187,7 @@ public: bool CallHookChunkUnloaded (cWorld & a_World, int a_ChunkX, int a_ChunkZ); bool CallHookChunkUnloading (cWorld & a_World, int a_ChunkX, int a_ChunkZ); bool CallHookCollectingPickup (cPlayer & a_Player, cPickup & a_Pickup); - bool CallHookCraftingNoRecipe (cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe * a_Recipe); + bool CallHookCraftingNoRecipe (cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe & a_Recipe); bool CallHookDisconnect (cClientHandle & a_Client, const AString & a_Reason); bool CallHookEntityAddEffect (cEntity & a_Entity, int a_EffectType, int a_EffectDurationTicks, int a_EffectIntensity, double a_DistanceModifier); bool CallHookExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split); // If a_Player == nullptr, it is a console cmd diff --git a/src/CraftingRecipes.cpp b/src/CraftingRecipes.cpp index 2c2b02a69..202fb900e 100644 --- a/src/CraftingRecipes.cpp +++ b/src/CraftingRecipes.cpp @@ -294,7 +294,7 @@ void cCraftingRecipes::GetRecipe(cPlayer & a_Player, cCraftingGrid & a_CraftingG if (Recipe.get() == nullptr) { // Allow plugins to intercept a no-recipe-found situation: - cRoot::Get()->GetPluginManager()->CallHookCraftingNoRecipe(a_Player, a_CraftingGrid, &a_Recipe); + cRoot::Get()->GetPluginManager()->CallHookCraftingNoRecipe(a_Player, a_CraftingGrid, a_Recipe); return; } for (cRecipeSlots::const_iterator itr = Recipe->m_Ingredients.begin(); itr != Recipe->m_Ingredients.end(); ++itr) -- cgit v1.2.3 From 83d4bec369643c82c3f13e2e1c6d13009a2a0bd9 Mon Sep 17 00:00:00 2001 From: p-mcgowan Date: Thu, 4 Dec 2014 01:08:17 -0800 Subject: awful comment fixing, randomizer fix --- src/Generating/FinishGen.cpp | 35 ++++++++++++++++++++++++----------- src/Generating/FinishGen.h | 16 ++++++++-------- 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index d938c34bd..e9cdfe91e 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -974,7 +974,7 @@ cFinishGenPassiveMobs::cFinishGenPassiveMobs(int a_Seed, cIniFile & a_IniFile, e } } // switch (dimension) m_AnimalProbability = a_IniFile.GetValueSetI(SectionName, "AnimalSpawnChunkPercentage", DefaultAnimalSpawnChunkPercentage); - if (m_AnimalProbability < 0 || m_AnimalProbability > 100) + if ((m_AnimalProbability < 0) || (m_AnimalProbability > 100)) { LOGWARNING("[Animals]: AnimalSpawnChunkPercentage is invalid, using the default of \"%d\".", DefaultAnimalSpawnChunkPercentage); } @@ -1001,7 +1001,7 @@ void cFinishGenPassiveMobs::GenFinish(cChunkDesc & a_ChunkDesc) return; } - /** Try spawning a pack center 10 times, should get roughly the same probability */ + // Try spawning a pack center 10 times, should get roughly the same probability for (int Tries = 0; Tries < 10; Tries++) { int PackCenterX = (m_Noise.IntNoise2DInt(chunkX, chunkZ) / 7) % cChunkDef::Width; @@ -1010,8 +1010,8 @@ void cFinishGenPassiveMobs::GenFinish(cChunkDesc & a_ChunkDesc) { for (int i = 0; i < 5; i++) { - int OffsetX = (m_Noise.IntNoise2DInt(chunkX, chunkZ) / 7) % cChunkDef::Width; - int OffsetZ = (m_Noise.IntNoise2DInt(chunkX, chunkZ) / 7) % cChunkDef::Width; + int OffsetX = (m_Noise.IntNoise2DInt(chunkX + chunkZ, Tries) / 7) % cChunkDef::Width; + int OffsetZ = (m_Noise.IntNoise2DInt(chunkX, chunkZ + Tries) / 7) % cChunkDef::Width; TrySpawnAnimals(a_ChunkDesc, OffsetX, a_ChunkDesc.GetHeight(OffsetX, OffsetZ), OffsetZ, RandomMob); } return; @@ -1026,11 +1026,16 @@ void cFinishGenPassiveMobs::GenFinish(cChunkDesc & a_ChunkDesc) bool cFinishGenPassiveMobs::TrySpawnAnimals(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelY, int a_RelZ, eMonsterType AnimalToSpawn) { + if ((a_RelY >= cChunkDef::Height - 1) || (a_RelY <= 0)) + { + return false; + } + BLOCKTYPE BlockAtHead = a_ChunkDesc.GetBlockType(a_RelX, a_RelY + 1, a_RelZ); BLOCKTYPE BlockAtFeet = a_ChunkDesc.GetBlockType(a_RelX, a_RelY, a_RelZ); BLOCKTYPE BlockUnderFeet = a_ChunkDesc.GetBlockType(a_RelX, a_RelY - 1, a_RelZ); - /** Check block below (opaque, grass, water), and above (air) */ + // Check block below (opaque, grass, water), and above (air) if (AnimalToSpawn == mtSquid && BlockAtFeet != E_BLOCK_WATER) { return false; @@ -1087,53 +1092,61 @@ eMonsterType cFinishGenPassiveMobs::GetRandomMob(cChunkDesc & a_ChunkDesc) // No animals case biNether: case biEnd: + { return mtInvalidType; - + } // Squid only case biOcean: case biFrozenOcean: case biFrozenRiver: case biRiver: case biDeepOcean: + { ListOfSpawnables.insert(MobIter, mtSquid); break; - + } // Mooshroom only case biMushroomIsland: case biMushroomShore: + { ListOfSpawnables.insert(MobIter, mtMooshroom); break; - + } case biJungle: case biJungleHills: case biJungleEdge: case biJungleM: case biJungleEdgeM: + { ListOfSpawnables.insert(MobIter, mtOcelot); - + } case biPlains: case biSunflowerPlains: case biSavanna: case biSavannaPlateau: case biSavannaM: case biSavannaPlateauM: + { ListOfSpawnables.insert(MobIter, mtHorse); // ListOfSpawnables.insert(mtDonkey); - + } // Wolves only case biForest: case biTaiga: case biMegaTaiga: case biColdTaiga: case biColdTaigaM: + { ListOfSpawnables.insert(MobIter, mtWolf); - + } // All other mobs default: + { ListOfSpawnables.insert(MobIter, mtChicken); ListOfSpawnables.insert(MobIter, mtCow); ListOfSpawnables.insert(MobIter, mtPig); ListOfSpawnables.insert(MobIter, mtSheep); + } } if (ListOfSpawnables.empty()) diff --git a/src/Generating/FinishGen.h b/src/Generating/FinishGen.h index e11e6f414..1866d6133 100644 --- a/src/Generating/FinishGen.h +++ b/src/Generating/FinishGen.h @@ -318,28 +318,28 @@ protected: -/** This class populates generated chunks with packs of biome-dependant animals -Animals: cows, sheep, pigs, mooshrooms, squid, horses, wolves, ocelots -*/ class cFinishGenPassiveMobs : public cFinishGen { public: - + + /** This class populates generated chunks with packs of biome-dependant animals + Animals: cows, sheep, pigs, mooshrooms, squid, horses, wolves, ocelots + */ cFinishGenPassiveMobs(int a_Seed, cIniFile & a_IniFile, eDimension a_Dimension); protected: cNoise m_Noise; - int m_AnimalProbability; /** Chance, [0..100], that an animal pack will be generated in a chunk */ + int m_AnimalProbability; // Chance, [0..100], that an animal pack will be generated in a chunk - /** cFinishGen override: */ + // cFinishGen override: virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; - /** Tries to spawn a mob in the center of the pack. If successful, spawns 0-5 more. */ + // Returns false if an animal cannot spawn at given coords, else adds it to the chunk's entity list and returns true bool TrySpawnAnimals(cChunkDesc & a_ChunkDesc, int x, int y, int z, eMonsterType AnimalToSpawn); - /** Gets a random mob from biome-dependant list */ + // Gets a random animal from biome-dependant list eMonsterType GetRandomMob(cChunkDesc & a_ChunkDesc); } ; -- cgit v1.2.3 From a36e7669a798d9756d7c13780aa017f60bc4ead5 Mon Sep 17 00:00:00 2001 From: p-mcgowan Date: Thu, 4 Dec 2014 01:14:38 -0800 Subject: added p-mcgowan to contributors --- CONTRIBUTORS | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index fffc55b2a..9a0a675e7 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -18,6 +18,7 @@ mgueydan MikeHunsinger mtilden nesco +p-mcgowan rs2k SamJBarney Sofapriester -- cgit v1.2.3 From b7c4ef05ac320428cfa2fdeed562302f78d1a7ab Mon Sep 17 00:00:00 2001 From: p-mcgowan Date: Thu, 4 Dec 2014 01:18:55 -0800 Subject: last doxy fix --- src/Generating/FinishGen.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Generating/FinishGen.h b/src/Generating/FinishGen.h index 1866d6133..f2b59fa08 100644 --- a/src/Generating/FinishGen.h +++ b/src/Generating/FinishGen.h @@ -318,14 +318,14 @@ protected: +/** This class populates generated chunks with packs of biome-dependant animals + Animals: cows, sheep, pigs, mooshrooms, squid, horses, wolves, ocelots + */ class cFinishGenPassiveMobs : public cFinishGen { public: - /** This class populates generated chunks with packs of biome-dependant animals - Animals: cows, sheep, pigs, mooshrooms, squid, horses, wolves, ocelots - */ cFinishGenPassiveMobs(int a_Seed, cIniFile & a_IniFile, eDimension a_Dimension); protected: -- cgit v1.2.3 From 64f8428d037e56986bb18e064a4b49de96c480ff Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 4 Dec 2014 22:07:04 +0100 Subject: Fixed trailing whitespace. --- src/OSSupport/IsThread.cpp | 10 +++++----- src/Root.cpp | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/OSSupport/IsThread.cpp b/src/OSSupport/IsThread.cpp index 8914cac90..9c62c89bf 100644 --- a/src/OSSupport/IsThread.cpp +++ b/src/OSSupport/IsThread.cpp @@ -18,10 +18,10 @@ #pragma pack(push, 8) struct THREADNAME_INFO { - DWORD dwType; // Must be 0x1000. - LPCSTR szName; // Pointer to name (in user addr space). - DWORD dwThreadID; // Thread ID (-1 = caller thread). - DWORD dwFlags; // Reserved for future use, must be zero. + DWORD dwType; // Must be 0x1000. + LPCSTR szName; // Pointer to name (in user addr space). + DWORD dwThreadID; // Thread ID (-1 = caller thread). + DWORD dwFlags; // Reserved for future use, must be zero. }; #pragma pack(pop) @@ -39,7 +39,7 @@ { } } -#endif // _MSC_VER && _DEBUG +#endif // _MSC_VER && _DEBUG diff --git a/src/Root.cpp b/src/Root.cpp index c69710628..865b2a213 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -116,7 +116,7 @@ void cRoot::Start(void) m_bStop = false; while (!m_bStop) { - auto BeginTime = std::chrono::steady_clock::now(); + auto BeginTime = std::chrono::steady_clock::now(); m_bRestart = false; LoadGlobalSettings(); -- cgit v1.2.3 From 99a5b38e27647e4535eed53b7b6d9cc6ea74c538 Mon Sep 17 00:00:00 2001 From: p-mcgowan Date: Thu, 4 Dec 2014 13:28:27 -0800 Subject: format blocks and randomizing --- src/Generating/FinishGen.cpp | 17 +++++++++-------- src/Generating/FinishGen.h | 1 - 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index e9cdfe91e..e72e91c85 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -1004,14 +1004,14 @@ void cFinishGenPassiveMobs::GenFinish(cChunkDesc & a_ChunkDesc) // Try spawning a pack center 10 times, should get roughly the same probability for (int Tries = 0; Tries < 10; Tries++) { - int PackCenterX = (m_Noise.IntNoise2DInt(chunkX, chunkZ) / 7) % cChunkDef::Width; - int PackCenterZ = (m_Noise.IntNoise2DInt(chunkX, chunkZ) / 7) % cChunkDef::Width; + int PackCenterX = (m_Noise.IntNoise2DInt(chunkX + chunkZ, Tries) / 7) % cChunkDef::Width; + int PackCenterZ = (m_Noise.IntNoise2DInt(chunkX, chunkZ + Tries) / 7) % cChunkDef::Width; if (TrySpawnAnimals(a_ChunkDesc, PackCenterX, a_ChunkDesc.GetHeight(PackCenterX, PackCenterZ), PackCenterZ, RandomMob)) { for (int i = 0; i < 5; i++) { - int OffsetX = (m_Noise.IntNoise2DInt(chunkX + chunkZ, Tries) / 7) % cChunkDef::Width; - int OffsetZ = (m_Noise.IntNoise2DInt(chunkX, chunkZ + Tries) / 7) % cChunkDef::Width; + int OffsetX = (m_Noise.IntNoise2DInt(chunkX + chunkZ + i, Tries) / 7) % cChunkDef::Width; + int OffsetZ = (m_Noise.IntNoise2DInt(chunkX, chunkZ + Tries + i) / 7) % cChunkDef::Width; TrySpawnAnimals(a_ChunkDesc, OffsetX, a_ChunkDesc.GetHeight(OffsetX, OffsetZ), OffsetZ, RandomMob); } return; @@ -1040,7 +1040,8 @@ bool cFinishGenPassiveMobs::TrySpawnAnimals(cChunkDesc & a_ChunkDesc, int a_RelX { return false; } - if ((AnimalToSpawn != mtSquid) && + if ( + (AnimalToSpawn != mtSquid) && (BlockAtHead != E_BLOCK_AIR) && (BlockAtFeet != E_BLOCK_AIR) && (!cBlockInfo::IsTransparent(BlockUnderFeet)) @@ -1083,8 +1084,8 @@ eMonsterType cFinishGenPassiveMobs::GetRandomMob(cChunkDesc & a_ChunkDesc) std::set::iterator MobIter = ListOfSpawnables.begin(); int chunkX = a_ChunkDesc.GetChunkX(); int chunkZ = a_ChunkDesc.GetChunkZ(); - int x = (m_Noise.IntNoise2DInt(chunkX, chunkZ) / 7) % cChunkDef::Width; - int z = (m_Noise.IntNoise2DInt(chunkX, chunkZ) / 7) % cChunkDef::Width; + int x = (m_Noise.IntNoise2DInt(chunkX, chunkZ + 10) / 7) % cChunkDef::Width; + int z = (m_Noise.IntNoise2DInt(chunkX + chunkZ, chunkZ) / 7) % cChunkDef::Width; /** Check biomes first to get a list of animals */ switch (a_ChunkDesc.GetBiome(x, z)) @@ -1154,7 +1155,7 @@ eMonsterType cFinishGenPassiveMobs::GetRandomMob(cChunkDesc & a_ChunkDesc) return mtInvalidType; } - int RandMob = (m_Noise.IntNoise2DInt(chunkX, chunkZ) / 7) % ListOfSpawnables.size(); + int RandMob = (m_Noise.IntNoise2DInt(chunkX - chunkZ + 2, chunkX + 5) / 7) % ListOfSpawnables.size(); MobIter=ListOfSpawnables.begin(); for (int i = 0; i < RandMob; i++) { diff --git a/src/Generating/FinishGen.h b/src/Generating/FinishGen.h index f2b59fa08..600a506bc 100644 --- a/src/Generating/FinishGen.h +++ b/src/Generating/FinishGen.h @@ -19,7 +19,6 @@ #include "../Noise/Noise.h" #include "../ProbabDistrib.h" #include "../Mobs/Monster.h" -#include "FastRandom.h" -- cgit v1.2.3 From 22a3419791815471bcbbf86e4fa88a92cca1faa8 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 4 Dec 2014 22:44:24 +0100 Subject: CheckBasicStyle: Doesn't report false positives ending in a keyword. --- src/CheckBasicStyle.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/CheckBasicStyle.lua b/src/CheckBasicStyle.lua index 76ae8c325..ef750e381 100644 --- a/src/CheckBasicStyle.lua +++ b/src/CheckBasicStyle.lua @@ -116,11 +116,11 @@ local g_ViolationPatterns = -- Space after keywords: {"[^_]if%(", "Needs a space after \"if\""}, - {"for%(", "Needs a space after \"for\""}, - {"while%(", "Needs a space after \"while\""}, - {"switch%(", "Needs a space after \"switch\""}, - {"catch%(", "Needs a space after \"catch\""}, - {"template<", "Needs a space after \"template\""}, + {"%sfor%(", "Needs a space after \"for\""}, + {"%swhile%(", "Needs a space after \"while\""}, + {"%sswitch%(", "Needs a space after \"switch\""}, + {"%scatch%(", "Needs a space after \"catch\""}, + {"%stemplate<", "Needs a space after \"template\""}, -- No space after keyword's parenthesis: {"[^%a#]if %( ", "Remove the space after \"(\""}, -- cgit v1.2.3 From ed99216ba4cff29b2621d89e7fad6a05cf276624 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 4 Dec 2014 22:51:40 +0100 Subject: Tools: Removed unused Timer.* file from CMakeLists.txt. --- Tools/MCADefrag/CMakeLists.txt | 3 +-- Tools/ProtoProxy/CMakeLists.txt | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/Tools/MCADefrag/CMakeLists.txt b/Tools/MCADefrag/CMakeLists.txt index 618719d68..82e048671 100644 --- a/Tools/MCADefrag/CMakeLists.txt +++ b/Tools/MCADefrag/CMakeLists.txt @@ -56,14 +56,13 @@ set(SHARED_OSS_SRC ../../src/OSSupport/File.cpp ../../src/OSSupport/IsThread.cpp ../../src/OSSupport/StackTrace.cpp - ../../src/OSSupport/Timer.cpp ) + set(SHARED_OSS_HDR ../../src/OSSupport/CriticalSection.h ../../src/OSSupport/File.h ../../src/OSSupport/IsThread.h ../../src/OSSupport/StackTrace.h - ../../src/OSSupport/Timer.h ) if(WIN32) diff --git a/Tools/ProtoProxy/CMakeLists.txt b/Tools/ProtoProxy/CMakeLists.txt index fc8721da0..cca0c1b8b 100644 --- a/Tools/ProtoProxy/CMakeLists.txt +++ b/Tools/ProtoProxy/CMakeLists.txt @@ -58,14 +58,12 @@ set(SHARED_OSS_SRC ../../src/OSSupport/File.cpp ../../src/OSSupport/IsThread.cpp ../../src/OSSupport/StackTrace.cpp - ../../src/OSSupport/Timer.cpp ) set(SHARED_OSS_HDR ../../src/OSSupport/CriticalSection.h ../../src/OSSupport/File.h ../../src/OSSupport/IsThread.h ../../src/OSSupport/StackTrace.h - ../../src/OSSupport/Timer.h ) if(WIN32) -- cgit v1.2.3 From 53a33595b7c53d3728cc38627a3d0601fce735aa Mon Sep 17 00:00:00 2001 From: p-mcgowan Date: Thu, 4 Dec 2014 16:44:18 -0800 Subject: formatting fixes --- src/Generating/FinishGen.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index e72e91c85..e50942073 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -1049,12 +1049,14 @@ bool cFinishGenPassiveMobs::TrySpawnAnimals(cChunkDesc & a_ChunkDesc, int a_RelX { return false; } - if ((BlockUnderFeet != E_BLOCK_GRASS) && - ((AnimalToSpawn == mtSheep) || (AnimalToSpawn == mtChicken) || (AnimalToSpawn == mtPig))) + if ( + (BlockUnderFeet != E_BLOCK_GRASS) && + ((AnimalToSpawn == mtSheep) || (AnimalToSpawn == mtChicken) || (AnimalToSpawn == mtPig)) + ) { return false; } - if (AnimalToSpawn == mtMooshroom && BlockUnderFeet != E_BLOCK_MYCELIUM) + if ((AnimalToSpawn == mtMooshroom) && (BlockUnderFeet != E_BLOCK_MYCELIUM)) { return false; } @@ -1150,13 +1152,18 @@ eMonsterType cFinishGenPassiveMobs::GetRandomMob(cChunkDesc & a_ChunkDesc) } } + ListOfSpawnables.insert(MobIter, mtChicken); + ListOfSpawnables.insert(MobIter, mtCow); + ListOfSpawnables.insert(MobIter, mtPig); + ListOfSpawnables.insert(MobIter, mtSheep); + if (ListOfSpawnables.empty()) { return mtInvalidType; } int RandMob = (m_Noise.IntNoise2DInt(chunkX - chunkZ + 2, chunkX + 5) / 7) % ListOfSpawnables.size(); - MobIter=ListOfSpawnables.begin(); + MobIter = ListOfSpawnables.begin(); for (int i = 0; i < RandMob; i++) { ++MobIter; -- cgit v1.2.3 From 538991c973fc6839b16b48b40a22084fe1218f74 Mon Sep 17 00:00:00 2001 From: p-mcgowan Date: Thu, 4 Dec 2014 16:59:45 -0800 Subject: handle non-vanilla dimensions --- src/Generating/FinishGen.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index e50942073..c83dfec67 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -835,6 +835,7 @@ cFinishGenFluidSprings::cFinishGenFluidSprings(int a_Seed, BLOCKTYPE a_Fluid, cI default: { ASSERT(!"Unhandled world dimension"); + DefaultChance = 0; break; } } // switch (dimension) @@ -970,7 +971,7 @@ cFinishGenPassiveMobs::cFinishGenPassiveMobs(int a_Seed, cIniFile & a_IniFile, e default: { ASSERT(!"Unhandled world dimension"); - break; + return; } } // switch (dimension) m_AnimalProbability = a_IniFile.GetValueSetI(SectionName, "AnimalSpawnChunkPercentage", DefaultAnimalSpawnChunkPercentage); @@ -1156,7 +1157,7 @@ eMonsterType cFinishGenPassiveMobs::GetRandomMob(cChunkDesc & a_ChunkDesc) ListOfSpawnables.insert(MobIter, mtCow); ListOfSpawnables.insert(MobIter, mtPig); ListOfSpawnables.insert(MobIter, mtSheep); - + if (ListOfSpawnables.empty()) { return mtInvalidType; -- cgit v1.2.3 From 78f0aebaf4bdef13d2cc61880111365297723517 Mon Sep 17 00:00:00 2001 From: p-mcgowan Date: Thu, 4 Dec 2014 17:01:34 -0800 Subject: handle non-vanilla dimensions --- src/Generating/FinishGen.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index c83dfec67..a34f61fcf 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -835,7 +835,6 @@ cFinishGenFluidSprings::cFinishGenFluidSprings(int a_Seed, BLOCKTYPE a_Fluid, cI default: { ASSERT(!"Unhandled world dimension"); - DefaultChance = 0; break; } } // switch (dimension) @@ -971,7 +970,8 @@ cFinishGenPassiveMobs::cFinishGenPassiveMobs(int a_Seed, cIniFile & a_IniFile, e default: { ASSERT(!"Unhandled world dimension"); - return; + DefaultChance = 0; + break; } } // switch (dimension) m_AnimalProbability = a_IniFile.GetValueSetI(SectionName, "AnimalSpawnChunkPercentage", DefaultAnimalSpawnChunkPercentage); -- cgit v1.2.3 From bd8c1850da9c80ae59334fd96da51c624893aac4 Mon Sep 17 00:00:00 2001 From: p-mcgowan Date: Thu, 4 Dec 2014 17:20:19 -0800 Subject: restructured random animals, added check for desert (update as per wiki) --- src/Generating/FinishGen.cpp | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index a34f61fcf..97ee5a9f9 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -970,7 +970,7 @@ cFinishGenPassiveMobs::cFinishGenPassiveMobs(int a_Seed, cIniFile & a_IniFile, e default: { ASSERT(!"Unhandled world dimension"); - DefaultChance = 0; + DefaultAnimalSpawnChunkPercentage = DEF_NO_ANIMALS; break; } } // switch (dimension) @@ -1009,7 +1009,7 @@ void cFinishGenPassiveMobs::GenFinish(cChunkDesc & a_ChunkDesc) int PackCenterZ = (m_Noise.IntNoise2DInt(chunkX, chunkZ + Tries) / 7) % cChunkDef::Width; if (TrySpawnAnimals(a_ChunkDesc, PackCenterX, a_ChunkDesc.GetHeight(PackCenterX, PackCenterZ), PackCenterZ, RandomMob)) { - for (int i = 0; i < 5; i++) + for (int i = 0; i < 3; i++) { int OffsetX = (m_Noise.IntNoise2DInt(chunkX + chunkZ + i, Tries) / 7) % cChunkDef::Width; int OffsetZ = (m_Noise.IntNoise2DInt(chunkX, chunkZ + Tries + i) / 7) % cChunkDef::Width; @@ -1093,13 +1093,23 @@ eMonsterType cFinishGenPassiveMobs::GetRandomMob(cChunkDesc & a_ChunkDesc) /** Check biomes first to get a list of animals */ switch (a_ChunkDesc.GetBiome(x, z)) { - // No animals + // No animals in deserts or non-overworld dimensions case biNether: case biEnd: + case biDesertHills: + case biDesert: + case biDesertM: { return mtInvalidType; } - // Squid only + // Mooshroom only - no other mobs on mushroom islands + case biMushroomIsland: + case biMushroomShore: + { + ListOfSpawnables.insert(MobIter, mtMooshroom); + break; + } + // Add squid in ocean biomes case biOcean: case biFrozenOcean: case biFrozenRiver: @@ -1107,15 +1117,8 @@ eMonsterType cFinishGenPassiveMobs::GetRandomMob(cChunkDesc & a_ChunkDesc) case biDeepOcean: { ListOfSpawnables.insert(MobIter, mtSquid); - break; - } - // Mooshroom only - case biMushroomIsland: - case biMushroomShore: - { - ListOfSpawnables.insert(MobIter, mtMooshroom); - break; } + // Add ocelots in jungle biomes case biJungle: case biJungleHills: case biJungleEdge: @@ -1134,7 +1137,7 @@ eMonsterType cFinishGenPassiveMobs::GetRandomMob(cChunkDesc & a_ChunkDesc) ListOfSpawnables.insert(MobIter, mtHorse); // ListOfSpawnables.insert(mtDonkey); } - // Wolves only + // Add wolves in forest and spruce forests case biForest: case biTaiga: case biMegaTaiga: @@ -1143,7 +1146,7 @@ eMonsterType cFinishGenPassiveMobs::GetRandomMob(cChunkDesc & a_ChunkDesc) { ListOfSpawnables.insert(MobIter, mtWolf); } - // All other mobs + // All other animals can be added to the list default: { ListOfSpawnables.insert(MobIter, mtChicken); @@ -1153,11 +1156,6 @@ eMonsterType cFinishGenPassiveMobs::GetRandomMob(cChunkDesc & a_ChunkDesc) } } - ListOfSpawnables.insert(MobIter, mtChicken); - ListOfSpawnables.insert(MobIter, mtCow); - ListOfSpawnables.insert(MobIter, mtPig); - ListOfSpawnables.insert(MobIter, mtSheep); - if (ListOfSpawnables.empty()) { return mtInvalidType; -- cgit v1.2.3 From a1c6e89273ce9a46b49421c739e2205d957cfb17 Mon Sep 17 00:00:00 2001 From: Jonathan Fabian Date: Thu, 4 Dec 2014 23:25:46 -0500 Subject: Fix duplicate commands added to README.md --- MCServer/Plugins/InfoDump.lua | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/MCServer/Plugins/InfoDump.lua b/MCServer/Plugins/InfoDump.lua index de1d1f451..07a534b88 100644 --- a/MCServer/Plugins/InfoDump.lua +++ b/MCServer/Plugins/InfoDump.lua @@ -444,7 +444,18 @@ local function BuildPermissions(a_PluginInfo) Permissions[info.Permission] = Permission -- Add the command to the list of commands using this permission: Permission.CommandsAffected = Permission.CommandsAffected or {} - table.insert(Permission.CommandsAffected, CommandString) + -- First, make sure that we don't already have this command in the list, + -- it may have already been present in a_PluginInfo + local NewCommand = true + for _, existCmd in ipairs(Permission.CommandsAffected) do + if CommandString == existCmd then + NewCommand = false + break + end + end + if NewCommand then + table.insert(Permission.CommandsAffected, CommandString) + end end -- Process the command param combinations for permissions: -- cgit v1.2.3 From c655d97c9db9408dc178f436baa87d894363ecb3 Mon Sep 17 00:00:00 2001 From: p-mcgowan Date: Fri, 5 Dec 2014 00:57:40 -0800 Subject: restructure, with logic this time --- src/Generating/FinishGen.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index 97ee5a9f9..6788afca3 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -1117,6 +1117,7 @@ eMonsterType cFinishGenPassiveMobs::GetRandomMob(cChunkDesc & a_ChunkDesc) case biDeepOcean: { ListOfSpawnables.insert(MobIter, mtSquid); + break; } // Add ocelots in jungle biomes case biJungle: @@ -1126,6 +1127,7 @@ eMonsterType cFinishGenPassiveMobs::GetRandomMob(cChunkDesc & a_ChunkDesc) case biJungleEdgeM: { ListOfSpawnables.insert(MobIter, mtOcelot); + break; } case biPlains: case biSunflowerPlains: @@ -1136,6 +1138,7 @@ eMonsterType cFinishGenPassiveMobs::GetRandomMob(cChunkDesc & a_ChunkDesc) { ListOfSpawnables.insert(MobIter, mtHorse); // ListOfSpawnables.insert(mtDonkey); + break; } // Add wolves in forest and spruce forests case biForest: @@ -1145,16 +1148,21 @@ eMonsterType cFinishGenPassiveMobs::GetRandomMob(cChunkDesc & a_ChunkDesc) case biColdTaigaM: { ListOfSpawnables.insert(MobIter, mtWolf); + break; } - // All other animals can be added to the list + // Nothing special about this biome default: { - ListOfSpawnables.insert(MobIter, mtChicken); - ListOfSpawnables.insert(MobIter, mtCow); - ListOfSpawnables.insert(MobIter, mtPig); - ListOfSpawnables.insert(MobIter, mtSheep); + break; } } + if ((a_ChunkDesc.GetBiome(x, z) != biMushroomIsland) && (a_ChunkDesc.GetBiome(x, z) != biMushroomShore)) + { + ListOfSpawnables.insert(MobIter, mtChicken); + ListOfSpawnables.insert(MobIter, mtCow); + ListOfSpawnables.insert(MobIter, mtPig); + ListOfSpawnables.insert(MobIter, mtSheep); + } if (ListOfSpawnables.empty()) { -- cgit v1.2.3 From 750b4a3eaadab231cd215cbc8557ad67a67742cc Mon Sep 17 00:00:00 2001 From: p-mcgowan Date: Fri, 5 Dec 2014 01:01:10 -0800 Subject: reformat --- src/Generating/FinishGen.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index 6788afca3..358ed16a1 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -1106,8 +1106,7 @@ eMonsterType cFinishGenPassiveMobs::GetRandomMob(cChunkDesc & a_ChunkDesc) case biMushroomIsland: case biMushroomShore: { - ListOfSpawnables.insert(MobIter, mtMooshroom); - break; + return mtMooshroom; } // Add squid in ocean biomes case biOcean: @@ -1156,13 +1155,10 @@ eMonsterType cFinishGenPassiveMobs::GetRandomMob(cChunkDesc & a_ChunkDesc) break; } } - if ((a_ChunkDesc.GetBiome(x, z) != biMushroomIsland) && (a_ChunkDesc.GetBiome(x, z) != biMushroomShore)) - { - ListOfSpawnables.insert(MobIter, mtChicken); - ListOfSpawnables.insert(MobIter, mtCow); - ListOfSpawnables.insert(MobIter, mtPig); - ListOfSpawnables.insert(MobIter, mtSheep); - } + ListOfSpawnables.insert(MobIter, mtChicken); + ListOfSpawnables.insert(MobIter, mtCow); + ListOfSpawnables.insert(MobIter, mtPig); + ListOfSpawnables.insert(MobIter, mtSheep); if (ListOfSpawnables.empty()) { -- cgit v1.2.3 From 44644ae0254bf3659c0995575041e2f656f20398 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 5 Dec 2014 12:56:53 +0100 Subject: Fixed reported parentheses around comparisons. --- src/Entities/Entity.cpp | 2 +- src/Inventory.cpp | 8 ++- src/MobSpawner.cpp | 8 +-- src/Mobs/Blaze.cpp | 2 +- src/Mobs/Ghast.cpp | 2 +- src/Mobs/Skeleton.cpp | 2 +- src/Mobs/SnowGolem.cpp | 2 +- src/OSSupport/Socket.h | 2 +- src/Simulator/FluidSimulator.cpp | 4 +- src/StringUtils.cpp | 33 ++++++------ src/Tracer.cpp | 105 +++++++++++++++++++++------------------ src/UI/SlotArea.cpp | 2 +- src/World.cpp | 4 +- src/XMLParser.h | 6 +-- 14 files changed, 99 insertions(+), 83 deletions(-) diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index afc61c73f..3b2fa9b4e 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -1276,7 +1276,7 @@ bool cEntity::DetectPortal() return false; } - if (IsPlayer() && !((cPlayer *)this)->IsGameModeCreative() && m_PortalCooldownData.m_TicksDelayed != 80) + if (IsPlayer() && !((cPlayer *)this)->IsGameModeCreative() && (m_PortalCooldownData.m_TicksDelayed != 80)) { // Delay teleportation for four seconds if the entity is a non-creative player m_PortalCooldownData.m_TicksDelayed++; diff --git a/src/Inventory.cpp b/src/Inventory.cpp index 51ac32da9..fba6f4aea 100644 --- a/src/Inventory.cpp +++ b/src/Inventory.cpp @@ -507,7 +507,11 @@ bool cInventory::AddToBar( cItem & a_Item, const int a_Offset, const int a_Size, int MaxStackSize = cItemHandler::GetItemHandler(a_Item.m_ItemType)->GetMaxStackSize(); for (int i = 0; i < a_Size; i++) { - if (m_Slots[i + a_Offset].m_ItemType == a_Item.m_ItemType && m_Slots[i + a_Offset].m_ItemCount < MaxStackSize && m_Slots[i + a_Offset].m_ItemDamage == a_Item.m_ItemDamage) + if ( + (m_Slots[i + a_Offset].m_ItemType == a_Item.m_ItemType) && + (m_Slots[i + a_Offset].m_ItemCount < MaxStackSize) && + (m_Slots[i + a_Offset].m_ItemDamage == a_Item.m_ItemDamage) + ) { int NumFree = MaxStackSize - m_Slots[i + a_Offset].m_ItemCount; if (NumFree >= a_Item.m_ItemCount) @@ -533,7 +537,7 @@ bool cInventory::AddToBar( cItem & a_Item, const int a_Offset, const int a_Size, if (a_Mode > 0) { // If we got more left, find first empty slot - for (int i = 0; i < a_Size && a_Item.m_ItemCount > 0; i++) + for (int i = 0; (i < a_Size) && (a_Item.m_ItemCount > 0); i++) { if (m_Slots[i + a_Offset].m_ItemType == -1) { diff --git a/src/MobSpawner.cpp b/src/MobSpawner.cpp index e477e2dac..ee9e569a7 100644 --- a/src/MobSpawner.cpp +++ b/src/MobSpawner.cpp @@ -61,7 +61,7 @@ eMonsterType cMobSpawner::ChooseMobType(EMCSBiome a_Biome) { std::set allowedMobs; - if (a_Biome == biMushroomIsland || a_Biome == biMushroomShore) + if ((a_Biome == biMushroomIsland) || (a_Biome == biMushroomShore)) { addIfAllowed(mtMooshroom, allowedMobs); } @@ -84,7 +84,7 @@ eMonsterType cMobSpawner::ChooseMobType(EMCSBiome a_Biome) addIfAllowed(mtCreeper, allowedMobs); addIfAllowed(mtSquid, allowedMobs); - if (a_Biome != biDesert && a_Biome != biBeach && a_Biome != biOcean) + if ((a_Biome != biDesert) && (a_Biome != biBeach) && (a_Biome != biOcean)) { addIfAllowed(mtSheep, allowedMobs); addIfAllowed(mtPig, allowedMobs); @@ -93,11 +93,11 @@ eMonsterType cMobSpawner::ChooseMobType(EMCSBiome a_Biome) addIfAllowed(mtEnderman, allowedMobs); addIfAllowed(mtSlime, allowedMobs); // MG TODO : much more complicated rule - if (a_Biome == biForest || a_Biome == biForestHills || a_Biome == biTaiga || a_Biome == biTaigaHills) + if ((a_Biome == biForest) || (a_Biome == biForestHills) || (a_Biome == biTaiga) || (a_Biome == biTaigaHills)) { addIfAllowed(mtWolf, allowedMobs); } - else if (a_Biome == biJungle || a_Biome == biJungleHills) + else if ((a_Biome == biJungle) || (a_Biome == biJungleHills)) { addIfAllowed(mtOcelot, allowedMobs); } diff --git a/src/Mobs/Blaze.cpp b/src/Mobs/Blaze.cpp index 16869c79d..1fa9d2c37 100644 --- a/src/Mobs/Blaze.cpp +++ b/src/Mobs/Blaze.cpp @@ -34,7 +34,7 @@ void cBlaze::Attack(float a_Dt) { m_AttackInterval += a_Dt * m_AttackRate; - if (m_Target != nullptr && m_AttackInterval > 3.0) + if ((m_Target != nullptr) && (m_AttackInterval > 3.0)) { // Setting this higher gives us more wiggle room for attackrate Vector3d Speed = GetLookVector() * 20; diff --git a/src/Mobs/Ghast.cpp b/src/Mobs/Ghast.cpp index c65c0d29a..fc8de8362 100644 --- a/src/Mobs/Ghast.cpp +++ b/src/Mobs/Ghast.cpp @@ -36,7 +36,7 @@ void cGhast::Attack(float a_Dt) { m_AttackInterval += a_Dt * m_AttackRate; - if (m_Target != nullptr && m_AttackInterval > 3.0) + if ((m_Target != nullptr) && (m_AttackInterval > 3.0)) { // Setting this higher gives us more wiggle room for attackrate Vector3d Speed = GetLookVector() * 20; diff --git a/src/Mobs/Skeleton.cpp b/src/Mobs/Skeleton.cpp index f17bc307c..da5ddc670 100644 --- a/src/Mobs/Skeleton.cpp +++ b/src/Mobs/Skeleton.cpp @@ -71,7 +71,7 @@ void cSkeleton::Attack(float a_Dt) { m_AttackInterval += a_Dt * m_AttackRate; - if (m_Target != nullptr && m_AttackInterval > 3.0) + if ((m_Target != nullptr) && (m_AttackInterval > 3.0)) { // Setting this higher gives us more wiggle room for attackrate Vector3d Speed = GetLookVector() * 20; diff --git a/src/Mobs/SnowGolem.cpp b/src/Mobs/SnowGolem.cpp index 76334d970..8c4178beb 100644 --- a/src/Mobs/SnowGolem.cpp +++ b/src/Mobs/SnowGolem.cpp @@ -38,7 +38,7 @@ void cSnowGolem::Tick(float a_Dt, cChunk & a_Chunk) { BLOCKTYPE BlockBelow = m_World->GetBlock((int) floor(GetPosX()), (int) floor(GetPosY()) - 1, (int) floor(GetPosZ())); BLOCKTYPE Block = m_World->GetBlock((int) floor(GetPosX()), (int) floor(GetPosY()), (int) floor(GetPosZ())); - if (Block == E_BLOCK_AIR && cBlockInfo::IsSolid(BlockBelow)) + if ((Block == E_BLOCK_AIR) && cBlockInfo::IsSolid(BlockBelow)) { m_World->SetBlock((int) floor(GetPosX()), (int) floor(GetPosY()), (int) floor(GetPosZ()), E_BLOCK_SNOW, 0); } diff --git a/src/OSSupport/Socket.h b/src/OSSupport/Socket.h index e4ec895cb..9ec8c1111 100644 --- a/src/OSSupport/Socket.h +++ b/src/OSSupport/Socket.h @@ -74,7 +74,7 @@ public: inline static bool IsSocketError(int a_ReturnedValue) { #ifdef _WIN32 - return (a_ReturnedValue == SOCKET_ERROR || a_ReturnedValue == 0); + return ((a_ReturnedValue == SOCKET_ERROR) || (a_ReturnedValue == 0)); #else return (a_ReturnedValue <= 0); #endif diff --git a/src/Simulator/FluidSimulator.cpp b/src/Simulator/FluidSimulator.cpp index 9c8453d04..a7551d9bc 100644 --- a/src/Simulator/FluidSimulator.cpp +++ b/src/Simulator/FluidSimulator.cpp @@ -133,8 +133,10 @@ Direction cFluidSimulator::GetFlowingDirection(int a_X, int a_Y, int a_Z, bool a /* Disabled because of causing problems and being useless atm char BlockBelow = m_World.GetBlock(a_X, a_Y - 1, a_Z); // If there is nothing or fluid below it -> dominating flow is down :D - if (BlockBelow == E_BLOCK_AIR || IsAllowedBlock(BlockBelow)) + if ((BlockBelow == E_BLOCK_AIR) || IsAllowedBlock(BlockBelow)) + { return Y_MINUS; + } */ NIBBLETYPE LowestPoint = m_World.GetBlockMeta(a_X, a_Y, a_Z); // Current Block Meta so only lower points will be counted diff --git a/src/StringUtils.cpp b/src/StringUtils.cpp index 34f2da682..fe145521f 100644 --- a/src/StringUtils.cpp +++ b/src/StringUtils.cpp @@ -416,24 +416,27 @@ static bool isLegalUTF8(const unsigned char * source, int length) { default: return false; // Everything else falls through when "true"... - case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; - case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; + case 4: if (((a = (*--srcptr)) < 0x80) || (a > 0xbf)) return false; + case 3: if (((a = (*--srcptr)) < 0x80) || (a > 0xbf)) return false; case 2: { - if ((a = (*--srcptr)) > 0xBF) return false; + if ((a = (*--srcptr)) > 0xbf) return false; switch (*source) { // no fall-through in this inner switch - case 0xE0: if (a < 0xA0) return false; break; - case 0xED: if (a > 0x9F) return false; break; - case 0xF0: if (a < 0x90) return false; break; - case 0xF4: if (a > 0x8F) return false; break; + case 0xe0: if (a < 0xa0) return false; break; + case 0xed: if (a > 0x9f) return false; break; + case 0xf0: if (a < 0x90) return false; break; + case 0xf4: if (a > 0x8f) return false; break; default: if (a < 0x80) return false; } } - case 1: if (*source >= 0x80 && *source < 0xC2) return false; + case 1: if ((*source >= 0x80) && (*source < 0xc2)) return false; + } + if (*source > 0xf4) + { + return false; } - if (*source > 0xF4) return false; return true; } @@ -446,11 +449,11 @@ AString UTF8ToRawBEUTF16(const char * a_UTF8, size_t a_UTF8Length) AString UTF16; UTF16.reserve(a_UTF8Length * 3); - const unsigned char * source = (const unsigned char*)a_UTF8; + const unsigned char * source = (const unsigned char *)a_UTF8; const unsigned char * sourceEnd = source + a_UTF8Length; const int halfShift = 10; // used for shifting by 10 bits const unsigned int halfBase = 0x0010000UL; - const unsigned int halfMask = 0x3FFUL; + const unsigned int halfMask = 0x3ffUL; while (source < sourceEnd) { @@ -481,7 +484,7 @@ AString UTF8ToRawBEUTF16(const char * a_UTF8, size_t a_UTF8Length) if (ch <= UNI_MAX_BMP) { // Target is a character <= 0xFFFF - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) + if ((ch >= UNI_SUR_HIGH_START) && (ch <= UNI_SUR_LOW_END)) { // UTF-16 surrogate values are illegal in UTF-32 ch = ' '; @@ -723,15 +726,15 @@ AString ReplaceAllCharOccurrences(const AString & a_String, char a_From, char a_ /// Converts one Hex character in a Base64 encoding into the data value static inline int UnBase64(char c) { - if (c >='A' && c <= 'Z') + if ((c >='A') && (c <= 'Z')) { return c - 'A'; } - if (c >='a' && c <= 'z') + if ((c >='a') && (c <= 'z')) { return c - 'a' + 26; } - if (c >= '0' && c <= '9') + if ((c >= '0') && (c <= '9')) { return c - '0' + 52; } diff --git a/src/Tracer.cpp b/src/Tracer.cpp index e125c6aa4..53884dee8 100644 --- a/src/Tracer.cpp +++ b/src/Tracer.cpp @@ -14,15 +14,15 @@ -cTracer::cTracer(cWorld * a_World) - : m_World(a_World) +cTracer::cTracer(cWorld * a_World): + m_World(a_World) { - m_NormalTable[0].Set(-1, 0, 0); - m_NormalTable[1].Set( 0, 0, -1); - m_NormalTable[2].Set( 1, 0, 0); - m_NormalTable[3].Set( 0, 0, 1); - m_NormalTable[4].Set( 0, 1, 0); - m_NormalTable[5].Set( 0, -1, 0); + m_NormalTable[0].Set(-1, 0, 0); + m_NormalTable[1].Set( 0, 0, -1); + m_NormalTable[2].Set( 1, 0, 0); + m_NormalTable[3].Set( 0, 0, 1); + m_NormalTable[4].Set( 0, 1, 0); + m_NormalTable[5].Set( 0, -1, 0); } @@ -37,7 +37,7 @@ cTracer::~cTracer() -float cTracer::SigNum( float a_Num) +float cTracer::SigNum(float a_Num) { if (a_Num < 0.f) return -1.f; if (a_Num > 0.f) return 1.f; @@ -127,7 +127,7 @@ void cTracer::SetValues(const Vector3f & a_Start, const Vector3f & a_Direction) -bool cTracer::Trace( const Vector3f & a_Start, const Vector3f & a_Direction, int a_Distance, bool a_LineOfSight) +bool cTracer::Trace(const Vector3f & a_Start, const Vector3f & a_Direction, int a_Distance, bool a_LineOfSight) { if ((a_Start.y < 0) || (a_Start.y >= cChunkDef::Height)) { @@ -249,35 +249,42 @@ int LinesCross(float x0, float y0, float x1, float y1, float x2, float y2, float { // float linx, liny; - float d=(x1-x0)*(y3-y2)-(y1-y0)*(x3-x2); - if (std::abs(d)<0.001) {return 0;} - float AB=((y0-y2)*(x3-x2)-(x0-x2)*(y3-y2))/d; - if (AB>=0.0 && AB<=1.0) + float d = (x1 - x0) * (y3 - y2) - (y1 - y0) * (x3 - x2); + if (std::abs(d) < 0.001) { - float CD=((y0-y2)*(x1-x0)-(x0-x2)*(y1-y0))/d; - if (CD>=0.0 && CD<=1.0) + return 0; + } + + float AB = ((y0 - y2) * (x3 - x2) - (x0 - x2) * (y3 - y2)) / d; + if ((AB >= 0.0) && (AB <= 1.0)) + { + float CD = ((y0 - y2) * (x1 - x0) - (x0 - x2) * (y1 - y0)) / d; + if ((CD >= 0.0) && (CD <= 1.0)) { - // linx=x0+AB*(x1-x0); - // liny=y0+AB*(y1-y0); + // linx = x0 + AB * (x1 - x0); + // liny = y0 + AB * (y1 - y0); return 1; } } return 0; } + + + // intersect3D_SegmentPlane(): intersect a segment and a plane // Input: a_Ray = a segment, and a_Plane = a plane = {Point V0; Vector n;} // Output: *I0 = the intersect point (when it exists) // Return: 0 = disjoint (no intersection) // 1 = intersection in the unique point *I0 // 2 = the segment lies in the plane -int cTracer::intersect3D_SegmentPlane( const Vector3f & a_Origin, const Vector3f & a_End, const Vector3f & a_PlanePos, const Vector3f & a_PlaneNormal) +int cTracer::intersect3D_SegmentPlane(const Vector3f & a_Origin, const Vector3f & a_End, const Vector3f & a_PlanePos, const Vector3f & a_PlaneNormal) { Vector3f u = a_End - a_Origin; // a_Ray.P1 - S.P0; Vector3f w = a_Origin - a_PlanePos; // S.P0 - Pn.V0; - float D = a_PlaneNormal.Dot( u); // dot(Pn.n, u); - float N = -(a_PlaneNormal.Dot( w)); // -dot(a_Plane.n, w); + float D = a_PlaneNormal.Dot(u); // dot(Pn.n, u); + float N = -(a_PlaneNormal.Dot(w)); // -dot(a_Plane.n, w); const float EPSILON = 0.0001f; if (fabs(D) < EPSILON) @@ -294,12 +301,12 @@ int cTracer::intersect3D_SegmentPlane( const Vector3f & a_Origin, const Vector3f // they are not parallel // compute intersect param float sI = N / D; - if (sI < 0 || sI > 1) + if ((sI < 0) || (sI > 1)) { return 0; // no intersection } - // Vector3f I ( a_Ray->GetOrigin() + sI * u);// S.P0 + sI * u; // compute segment intersect point + // Vector3f I (a_Ray->GetOrigin() + sI * u);// S.P0 + sI * u; // compute segment intersect point RealHit = a_Origin + u * sI; return 1; } @@ -311,9 +318,9 @@ int cTracer::intersect3D_SegmentPlane( const Vector3f & a_Origin, const Vector3f int cTracer::GetHitNormal(const Vector3f & start, const Vector3f & end, const Vector3i & a_BlockPos) { Vector3i SmallBlockPos = a_BlockPos; - char BlockID = m_World->GetBlock( a_BlockPos.x, a_BlockPos.y, a_BlockPos.z); + char BlockID = m_World->GetBlock(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z); - if (BlockID == E_BLOCK_AIR || IsBlockWater(BlockID)) + if ((BlockID == E_BLOCK_AIR) || IsBlockWater(BlockID)) { return 0; } @@ -324,86 +331,86 @@ int cTracer::GetHitNormal(const Vector3f & start, const Vector3f & end, const Ve Vector3f Look = (end - start); Look.Normalize(); - float dot = Look.Dot( Vector3f(-1, 0, 0)); // first face normal is x -1 + float dot = Look.Dot(Vector3f(-1, 0, 0)); // first face normal is x -1 if (dot < 0) { - int Lines = LinesCross( start.x, start.y, end.x, end.y, BlockPos.x, BlockPos.y, BlockPos.x, BlockPos.y + 1); + int Lines = LinesCross(start.x, start.y, end.x, end.y, BlockPos.x, BlockPos.y, BlockPos.x, BlockPos.y + 1); if (Lines == 1) { - Lines = LinesCross( start.x, start.z, end.x, end.z, BlockPos.x, BlockPos.z, BlockPos.x, BlockPos.z + 1); + Lines = LinesCross(start.x, start.z, end.x, end.z, BlockPos.x, BlockPos.z, BlockPos.x, BlockPos.z + 1); if (Lines == 1) { - intersect3D_SegmentPlane( start, end, BlockPos, Vector3f(-1, 0, 0)); + intersect3D_SegmentPlane(start, end, BlockPos, Vector3f(-1, 0, 0)); return 1; } } } - dot = Look.Dot( Vector3f(0, 0, -1)); // second face normal is z -1 + dot = Look.Dot(Vector3f(0, 0, -1)); // second face normal is z -1 if (dot < 0) { - int Lines = LinesCross( start.z, start.y, end.z, end.y, BlockPos.z, BlockPos.y, BlockPos.z, BlockPos.y + 1); + int Lines = LinesCross(start.z, start.y, end.z, end.y, BlockPos.z, BlockPos.y, BlockPos.z, BlockPos.y + 1); if (Lines == 1) { - Lines = LinesCross( start.z, start.x, end.z, end.x, BlockPos.z, BlockPos.x, BlockPos.z, BlockPos.x + 1); + Lines = LinesCross(start.z, start.x, end.z, end.x, BlockPos.z, BlockPos.x, BlockPos.z, BlockPos.x + 1); if (Lines == 1) { - intersect3D_SegmentPlane( start, end, BlockPos, Vector3f(0, 0, -1)); + intersect3D_SegmentPlane(start, end, BlockPos, Vector3f(0, 0, -1)); return 2; } } } - dot = Look.Dot( Vector3f(1, 0, 0)); // third face normal is x 1 + dot = Look.Dot(Vector3f(1, 0, 0)); // third face normal is x 1 if (dot < 0) { - int Lines = LinesCross( start.x, start.y, end.x, end.y, BlockPos.x + 1, BlockPos.y, BlockPos.x + 1, BlockPos.y + 1); + int Lines = LinesCross(start.x, start.y, end.x, end.y, BlockPos.x + 1, BlockPos.y, BlockPos.x + 1, BlockPos.y + 1); if (Lines == 1) { - Lines = LinesCross( start.x, start.z, end.x, end.z, BlockPos.x + 1, BlockPos.z, BlockPos.x + 1, BlockPos.z + 1); + Lines = LinesCross(start.x, start.z, end.x, end.z, BlockPos.x + 1, BlockPos.z, BlockPos.x + 1, BlockPos.z + 1); if (Lines == 1) { - intersect3D_SegmentPlane( start, end, BlockPos + Vector3f(1, 0, 0), Vector3f(1, 0, 0)); + intersect3D_SegmentPlane(start, end, BlockPos + Vector3f(1, 0, 0), Vector3f(1, 0, 0)); return 3; } } } - dot = Look.Dot( Vector3f(0, 0, 1)); // fourth face normal is z 1 + dot = Look.Dot(Vector3f(0, 0, 1)); // fourth face normal is z 1 if (dot < 0) { - int Lines = LinesCross( start.z, start.y, end.z, end.y, BlockPos.z + 1, BlockPos.y, BlockPos.z + 1, BlockPos.y + 1); + int Lines = LinesCross(start.z, start.y, end.z, end.y, BlockPos.z + 1, BlockPos.y, BlockPos.z + 1, BlockPos.y + 1); if (Lines == 1) { - Lines = LinesCross( start.z, start.x, end.z, end.x, BlockPos.z + 1, BlockPos.x, BlockPos.z + 1, BlockPos.x + 1); + Lines = LinesCross(start.z, start.x, end.z, end.x, BlockPos.z + 1, BlockPos.x, BlockPos.z + 1, BlockPos.x + 1); if (Lines == 1) { - intersect3D_SegmentPlane( start, end, BlockPos + Vector3f(0, 0, 1), Vector3f(0, 0, 1)); + intersect3D_SegmentPlane(start, end, BlockPos + Vector3f(0, 0, 1), Vector3f(0, 0, 1)); return 4; } } } - dot = Look.Dot( Vector3f(0, 1, 0)); // fifth face normal is y 1 + dot = Look.Dot(Vector3f(0, 1, 0)); // fifth face normal is y 1 if (dot < 0) { - int Lines = LinesCross( start.y, start.x, end.y, end.x, BlockPos.y + 1, BlockPos.x, BlockPos.y + 1, BlockPos.x + 1); + int Lines = LinesCross(start.y, start.x, end.y, end.x, BlockPos.y + 1, BlockPos.x, BlockPos.y + 1, BlockPos.x + 1); if (Lines == 1) { - Lines = LinesCross( start.y, start.z, end.y, end.z, BlockPos.y + 1, BlockPos.z, BlockPos.y + 1, BlockPos.z + 1); + Lines = LinesCross(start.y, start.z, end.y, end.z, BlockPos.y + 1, BlockPos.z, BlockPos.y + 1, BlockPos.z + 1); if (Lines == 1) { - intersect3D_SegmentPlane( start, end, BlockPos + Vector3f(0, 1, 0), Vector3f(0, 1, 0)); + intersect3D_SegmentPlane(start, end, BlockPos + Vector3f(0, 1, 0), Vector3f(0, 1, 0)); return 5; } } } - dot = Look.Dot( Vector3f(0, -1, 0)); // sixth face normal is y -1 + dot = Look.Dot(Vector3f(0, -1, 0)); // sixth face normal is y -1 if (dot < 0) { - int Lines = LinesCross( start.y, start.x, end.y, end.x, BlockPos.y, BlockPos.x, BlockPos.y, BlockPos.x + 1); + int Lines = LinesCross(start.y, start.x, end.y, end.x, BlockPos.y, BlockPos.x, BlockPos.y, BlockPos.x + 1); if (Lines == 1) { - Lines = LinesCross( start.y, start.z, end.y, end.z, BlockPos.y, BlockPos.z, BlockPos.y, BlockPos.z + 1); + Lines = LinesCross(start.y, start.z, end.y, end.z, BlockPos.y, BlockPos.z, BlockPos.y, BlockPos.z + 1); if (Lines == 1) { - intersect3D_SegmentPlane( start, end, BlockPos, Vector3f(0, -1, 0)); + intersect3D_SegmentPlane(start, end, BlockPos, Vector3f(0, -1, 0)); return 6; } } diff --git a/src/UI/SlotArea.cpp b/src/UI/SlotArea.cpp index 9113ec343..ff934c049 100644 --- a/src/UI/SlotArea.cpp +++ b/src/UI/SlotArea.cpp @@ -1167,7 +1167,7 @@ void cSlotAreaAnvil::UpdateResult(cPlayer & a_Player) { m_MaximumCost = 39; } - if (m_MaximumCost >= 40 && !a_Player.IsGameModeCreative()) + if ((m_MaximumCost >= 40) && !a_Player.IsGameModeCreative()) { Input.Empty(); } diff --git a/src/World.cpp b/src/World.cpp index 9a6ef5c30..7518327b9 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -1809,7 +1809,7 @@ void cWorld::SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_FlyAwaySpeed /= 100; // Pre-divide, so that we don't have to divide each time inside the loop for (cItems::const_iterator itr = a_Pickups.begin(); itr != a_Pickups.end(); ++itr) { - if (!IsValidItem(itr->m_ItemType) || itr->m_ItemType == E_BLOCK_AIR) + if (!IsValidItem(itr->m_ItemType) || (itr->m_ItemType == E_BLOCK_AIR)) { // Don't spawn pickup if item isn't even valid; should prevent client crashing too continue; @@ -1835,7 +1835,7 @@ void cWorld::SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double { for (cItems::const_iterator itr = a_Pickups.begin(); itr != a_Pickups.end(); ++itr) { - if (!IsValidItem(itr->m_ItemType) || itr->m_ItemType == E_BLOCK_AIR) + if (!IsValidItem(itr->m_ItemType) || (itr->m_ItemType == E_BLOCK_AIR)) { continue; } diff --git a/src/XMLParser.h b/src/XMLParser.h index 5b53e55cf..dab9699c9 100644 --- a/src/XMLParser.h +++ b/src/XMLParser.h @@ -105,11 +105,11 @@ public: Destroy (); // If the encoding or seperator are empty, then nullptr - if (pszEncoding != nullptr && pszEncoding [0] == 0) + if ((pszEncoding != nullptr) && (pszEncoding[0] == 0)) { pszEncoding = nullptr; } - if (pszSep != nullptr && pszSep [0] == 0) + if ((pszSep != nullptr) && (pszSep[0] == 0)) { pszSep = nullptr; } @@ -147,7 +147,7 @@ public: bool Parse (const char *pszBuffer, int nLength, bool fIsFinal = true) { assert (m_p != nullptr); - return XML_Parse (m_p, pszBuffer, nLength, fIsFinal) != 0; + return (XML_Parse (m_p, pszBuffer, nLength, fIsFinal) != 0); } // @cmember Parse internal buffer -- cgit v1.2.3 From 21d5374b979329aa04e0ee5af63becca08439d86 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 5 Dec 2014 12:58:30 +0100 Subject: CheckBasicStyle: Added a check for parentheses around comparisons. The check is only rudimentary and tends to fall towards missed positived rather than false positives. --- src/CheckBasicStyle.lua | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/CheckBasicStyle.lua b/src/CheckBasicStyle.lua index 76ae8c325..d703c3816 100644 --- a/src/CheckBasicStyle.lua +++ b/src/CheckBasicStyle.lua @@ -92,6 +92,25 @@ end local g_ViolationPatterns = { + -- Parenthesis around comparisons: + {"==[^)]+&&", "Add parenthesis around comparison"}, + {"&&[^(]+==", "Add parenthesis around comparison"}, + {"==[^)]+||", "Add parenthesis around comparison"}, + {"||[^(]+==", "Add parenthesis around comparison"}, + {"!=[^)]+&&", "Add parenthesis around comparison"}, + {"&&[^(]+!=", "Add parenthesis around comparison"}, + {"!=[^)]+||", "Add parenthesis around comparison"}, + {"||[^(]+!=", "Add parenthesis around comparison"}, + {"<[^)T][^)]*&&", "Add parenthesis around comparison"}, -- Must take special care of templates: "template fn(Args && ...)" + {"&&[^(]+<", "Add parenthesis around comparison"}, + {"<[^)T][^)]*||", "Add parenthesis around comparison"}, -- Must take special care of templates: "template fn(Args && ...)" + {"||[^(]+<", "Add parenthesis around comparison"}, + -- Cannot check ">" because of "obj->m_Flag &&". Check at least ">=": + {">=[^)]+&&", "Add parenthesis around comparison"}, + {"&&[^(]+>=", "Add parenthesis around comparison"}, + {">=[^)]+||", "Add parenthesis around comparison"}, + {"||[^(]+>=", "Add parenthesis around comparison"}, + -- Check against indenting using spaces: {"^\t* +", "Indenting with a space"}, @@ -227,6 +246,9 @@ end +-- Remove buffering from stdout, so that the output appears immediately in IDEs: +io.stdout:setvbuf("no") + -- Process all files in the AllFiles.lst file (generated by cmake): for fnam in io.lines("AllFiles.lst") do ProcessItem(fnam) -- cgit v1.2.3 From e2a04f580a0813206f527a61244cb3382248fd12 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 5 Dec 2014 16:59:11 +0100 Subject: BasicStyle: Added missing braces to control statements. --- src/Bindings/DeprecatedBindings.cpp | 14 ++++++ src/Bindings/PluginManager.cpp | 9 +++- src/Blocks/BlockBed.h | 5 ++- src/Blocks/BlockDoor.cpp | 10 ++++- src/Blocks/BlockRail.h | 88 ++++++++++++++++++++++++++++++------- src/ClientHandle.cpp | 4 ++ src/Entities/Entity.cpp | 20 +++++++-- src/Entities/Minecart.cpp | 29 +++++++++--- src/Generating/Caves.cpp | 10 ++++- src/Mobs/AggressiveMonster.cpp | 2 + src/Mobs/Monster.cpp | 27 +++++++++--- src/OSSupport/Thread.cpp | 11 ++++- src/Simulator/FluidSimulator.cpp | 2 + src/StringUtils.cpp | 10 ++++- src/Tracer.cpp | 15 +++++-- src/WorldStorage/WSSAnvil.cpp | 31 ++++++++----- src/XMLParser.h | 8 ++++ 17 files changed, 241 insertions(+), 54 deletions(-) diff --git a/src/Bindings/DeprecatedBindings.cpp b/src/Bindings/DeprecatedBindings.cpp index 95cd9c4f7..6dd6a4e59 100644 --- a/src/Bindings/DeprecatedBindings.cpp +++ b/src/Bindings/DeprecatedBindings.cpp @@ -52,7 +52,9 @@ static int tolua_get_AllToLua_g_BlockSpreadLightFalloff(lua_State* tolua_S) { tolua_Error tolua_err; if (!tolua_isnumber(tolua_S, 2, 0, &tolua_err)) + { tolua_error(tolua_S, "#vinvalid type in array indexing.", &tolua_err); + } } #endif BlockType = (int)tolua_tonumber(tolua_S, 2, 0); @@ -78,7 +80,9 @@ static int tolua_get_AllToLua_g_BlockTransparent(lua_State* tolua_S) { tolua_Error tolua_err; if (!tolua_isnumber(tolua_S, 2, 0, &tolua_err)) + { tolua_error(tolua_S, "#vinvalid type in array indexing.", &tolua_err); + } } #endif BlockType = (int)tolua_tonumber(tolua_S, 2, 0); @@ -104,7 +108,9 @@ static int tolua_get_AllToLua_g_BlockOneHitDig(lua_State* tolua_S) { tolua_Error tolua_err; if (!tolua_isnumber(tolua_S, 2, 0, &tolua_err)) + { tolua_error(tolua_S, "#vinvalid type in array indexing.", &tolua_err); + } } #endif BlockType = (int)tolua_tonumber(tolua_S, 2, 0); @@ -130,7 +136,9 @@ static int tolua_get_AllToLua_g_BlockPistonBreakable(lua_State* tolua_S) { tolua_Error tolua_err; if (!tolua_isnumber(tolua_S, 2, 0, &tolua_err)) + { tolua_error(tolua_S, "#vinvalid type in array indexing.", &tolua_err); + } } #endif BlockType = (int)tolua_tonumber(tolua_S, 2, 0); @@ -156,7 +164,9 @@ static int tolua_get_AllToLua_g_BlockIsSnowable(lua_State* tolua_S) { tolua_Error tolua_err; if (!tolua_isnumber(tolua_S, 2, 0, &tolua_err)) + { tolua_error(tolua_S, "#vinvalid type in array indexing.", &tolua_err); + } } #endif BlockType = (int)tolua_tonumber(tolua_S, 2, 0); @@ -182,7 +192,9 @@ static int tolua_get_AllToLua_g_BlockIsSolid(lua_State* tolua_S) { tolua_Error tolua_err; if (!tolua_isnumber(tolua_S, 2, 0, &tolua_err)) + { tolua_error(tolua_S, "#vinvalid type in array indexing.", &tolua_err); + } } #endif BlockType = (int)tolua_tonumber(tolua_S, 2, 0); @@ -208,7 +220,9 @@ static int tolua_get_AllToLua_g_BlockFullyOccupiesVoxel(lua_State* tolua_S) { tolua_Error tolua_err; if (!tolua_isnumber(tolua_S, 2, 0, &tolua_err)) + { tolua_error(tolua_S, "#vinvalid type in array indexing.", &tolua_err); + } } #endif BlockType = (int)tolua_tonumber(tolua_S, 2, 0); diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index f951f6221..406a540f4 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -1459,11 +1459,16 @@ cPluginManager::CommandResult cPluginManager::HandleCommand(cPlayer & a_Player, -cPlugin * cPluginManager::GetPlugin( const AString & a_Plugin) const +cPlugin * cPluginManager::GetPlugin(const AString & a_Plugin) const { for (PluginMap::const_iterator itr = m_Plugins.begin(); itr != m_Plugins.end(); ++itr) { - if (itr->second == nullptr) continue; + if (itr->second == nullptr) + { + // The plugin is currently unloaded + continue; + } + if (itr->second->GetName().compare(a_Plugin) == 0) { return itr->second; diff --git a/src/Blocks/BlockBed.h b/src/Blocks/BlockBed.h index 9fd45644b..a8b5be899 100644 --- a/src/Blocks/BlockBed.h +++ b/src/Blocks/BlockBed.h @@ -52,7 +52,10 @@ public: static NIBBLETYPE RotationToMetaData(double a_Rotation) { a_Rotation += 180 + (180 / 4); // So its not aligned with axis - if (a_Rotation > 360) a_Rotation -= 360; + if (a_Rotation > 360) + { + a_Rotation -= 360; + } a_Rotation = (a_Rotation / 360) * 4; diff --git a/src/Blocks/BlockDoor.cpp b/src/Blocks/BlockDoor.cpp index 96345a2df..90b7b15c2 100644 --- a/src/Blocks/BlockDoor.cpp +++ b/src/Blocks/BlockDoor.cpp @@ -145,7 +145,10 @@ NIBBLETYPE cBlockDoorHandler::MetaMirrorXY(NIBBLETYPE a_Meta) // in only the bottom tile while the hinge position is in the top tile. This function only operates on one tile at a time, // so the function can only see either the hinge position or orientation, but not both, at any given time. The class itself // needs extra datamembers. - if (a_Meta & 0x08) return a_Meta; + if (a_Meta & 0x08) + { + return a_Meta; + } // Holds open/closed meta data. 0x0C == 1100. NIBBLETYPE OtherMeta = a_Meta & 0x0C; @@ -173,7 +176,10 @@ NIBBLETYPE cBlockDoorHandler::MetaMirrorYZ(NIBBLETYPE a_Meta) // so the function can only see either the hinge position or orientation, but not both, at any given time.The class itself // needs extra datamembers. - if (a_Meta & 0x08) return a_Meta; + if (a_Meta & 0x08) + { + return a_Meta; + } // Holds open/closed meta data. 0x0C == 1100. NIBBLETYPE OtherMeta = a_Meta & 0x0C; diff --git a/src/Blocks/BlockRail.h b/src/Blocks/BlockRail.h index 87ce069ab..21a34d8ce 100644 --- a/src/Blocks/BlockRail.h +++ b/src/Blocks/BlockRail.h @@ -151,13 +151,21 @@ public: Neighbors[6] = (IsUnstable(a_ChunkInterface, a_BlockX, a_BlockY + 1, a_BlockZ - 1) || !IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_NORTH, E_PURE_NONE)); Neighbors[7] = (IsUnstable(a_ChunkInterface, a_BlockX, a_BlockY + 1, a_BlockZ + 1) || !IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_SOUTH, E_PURE_NONE)); if (IsUnstable(a_ChunkInterface, a_BlockX + 1, a_BlockY - 1, a_BlockZ) || !IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_EAST)) + { Neighbors[0] = true; + } if (IsUnstable(a_ChunkInterface, a_BlockX - 1, a_BlockY - 1, a_BlockZ) || !IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_WEST)) + { Neighbors[1] = true; + } if (IsUnstable(a_ChunkInterface, a_BlockX, a_BlockY - 1, a_BlockZ - 1) || !IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_NORTH)) + { Neighbors[2] = true; + } if (IsUnstable(a_ChunkInterface, a_BlockX, a_BlockY - 1, a_BlockZ + 1) || !IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_SOUTH)) + { Neighbors[3] = true; + } for (int i = 0; i < 8; i++) { if (Neighbors[i]) @@ -167,12 +175,30 @@ public: } if (RailsCnt == 1) { - if (Neighbors[7]) return E_META_RAIL_ASCEND_ZP; - else if (Neighbors[6]) return E_META_RAIL_ASCEND_ZM; - else if (Neighbors[5]) return E_META_RAIL_ASCEND_XM; - else if (Neighbors[4]) return E_META_RAIL_ASCEND_XP; - else if (Neighbors[0] || Neighbors[1]) return E_META_RAIL_XM_XP; - else if (Neighbors[2] || Neighbors[3]) return E_META_RAIL_ZM_ZP; + if (Neighbors[7]) + { + return E_META_RAIL_ASCEND_ZP; + } + else if (Neighbors[6]) + { + return E_META_RAIL_ASCEND_ZM; + } + else if (Neighbors[5]) + { + return E_META_RAIL_ASCEND_XM; + } + else if (Neighbors[4]) + { + return E_META_RAIL_ASCEND_XP; + } + else if (Neighbors[0] || Neighbors[1]) + { + return E_META_RAIL_XM_XP; + } + else if (Neighbors[2] || Neighbors[3]) + { + return E_META_RAIL_ZM_ZP; + } ASSERT(!"Weird neighbor count"); return Meta; } @@ -185,16 +211,46 @@ public: } if (RailsCnt > 1) { - if (Neighbors[3] && Neighbors[0] && CanThisRailCurve()) return E_META_RAIL_CURVED_ZP_XP; - else if (Neighbors[3] && Neighbors[1] && CanThisRailCurve()) return E_META_RAIL_CURVED_ZP_XM; - else if (Neighbors[2] && Neighbors[0] && CanThisRailCurve()) return E_META_RAIL_CURVED_ZM_XP; - else if (Neighbors[2] && Neighbors[1] && CanThisRailCurve()) return E_META_RAIL_CURVED_ZM_XM; - else if (Neighbors[7] && Neighbors[2]) return E_META_RAIL_ASCEND_ZP; - else if (Neighbors[3] && Neighbors[6]) return E_META_RAIL_ASCEND_ZM; - else if (Neighbors[5] && Neighbors[0]) return E_META_RAIL_ASCEND_XM; - else if (Neighbors[4] && Neighbors[1]) return E_META_RAIL_ASCEND_XP; - else if (Neighbors[0] && Neighbors[1]) return E_META_RAIL_XM_XP; - else if (Neighbors[2] && Neighbors[3]) return E_META_RAIL_ZM_ZP; + if (Neighbors[3] && Neighbors[0] && CanThisRailCurve()) + { + return E_META_RAIL_CURVED_ZP_XP; + } + else if (Neighbors[3] && Neighbors[1] && CanThisRailCurve()) + { + return E_META_RAIL_CURVED_ZP_XM; + } + else if (Neighbors[2] && Neighbors[0] && CanThisRailCurve()) + { + return E_META_RAIL_CURVED_ZM_XP; + } + else if (Neighbors[2] && Neighbors[1] && CanThisRailCurve()) + { + return E_META_RAIL_CURVED_ZM_XM; + } + else if (Neighbors[7] && Neighbors[2]) + { + return E_META_RAIL_ASCEND_ZP; + } + else if (Neighbors[3] && Neighbors[6]) + { + return E_META_RAIL_ASCEND_ZM; + } + else if (Neighbors[5] && Neighbors[0]) + { + return E_META_RAIL_ASCEND_XM; + } + else if (Neighbors[4] && Neighbors[1]) + { + return E_META_RAIL_ASCEND_XP; + } + else if (Neighbors[0] && Neighbors[1]) + { + return E_META_RAIL_XM_XP; + } + else if (Neighbors[2] && Neighbors[3]) + { + return E_META_RAIL_ZM_ZP; + } if (CanThisRailCurve()) { diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index a6cbad32a..366f20170 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -199,9 +199,13 @@ void cClientHandle::GenerateOfflineUUID(void) AString cClientHandle::FormatChatPrefix(bool ShouldAppendChatPrefixes, AString a_ChatPrefixS, AString m_Color1, AString m_Color2) { if (ShouldAppendChatPrefixes) + { return Printf("%s[%s] %s", m_Color1.c_str(), a_ChatPrefixS.c_str(), m_Color2.c_str()); + } else + { return Printf("%s", m_Color1.c_str()); + } } diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 3b2fa9b4e..54b9f2a20 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -665,7 +665,10 @@ int cEntity::GetArmorCoverAgainst(const cEntity * a_Attacker, eDamageType a_Dama // Returns the hitpoints out of a_RawDamage that the currently equipped armor would cover // Filter out damage types that are not protected by armor: - if (!ArmorCoversAgainst(a_DamageType)) return 0; + if (!ArmorCoversAgainst(a_DamageType)) + { + return 0; + } // Add up all armor points: // Ref.: http://www.minecraftwiki.net/wiki/Armor#Defense_points as of 2012_12_20 @@ -1011,9 +1014,18 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk) // Block hit was within our projected path // Begin by stopping movement in the direction that we hit something. The Normal is the line perpendicular to a 2D face and in this case, stores what block face was hit through either -1 or 1. // For example: HitNormal.y = -1 : BLOCK_FACE_YM; HitNormal.y = 1 : BLOCK_FACE_YP - if (Tracer.HitNormal.x != 0.f) NextSpeed.x = 0.f; - if (Tracer.HitNormal.y != 0.f) NextSpeed.y = 0.f; - if (Tracer.HitNormal.z != 0.f) NextSpeed.z = 0.f; + if (Tracer.HitNormal.x != 0.f) + { + NextSpeed.x = 0.f; + } + if (Tracer.HitNormal.y != 0.f) + { + NextSpeed.y = 0.f; + } + if (Tracer.HitNormal.z != 0.f) + { + NextSpeed.z = 0.f; + } if (Tracer.HitNormal.y == 1.f) // Hit BLOCK_FACE_YP, we are on the ground { diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index 22e046800..fac4f0714 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -142,8 +142,13 @@ void cMinecart::HandlePhysics(float a_Dt, cChunk & a_Chunk) if (!IsBlockRail(InsideType)) { - Chunk->GetBlockTypeMeta(RelPosX, PosY + 1, RelPosZ, InsideType, InsideMeta); // When an descending minecart hits a flat rail, it goes through the ground; check for this - if (IsBlockRail(InsideType)) AddPosY(1); // Push cart upwards + // When a descending minecart hits a flat rail, it goes through the ground; check for this + Chunk->GetBlockTypeMeta(RelPosX, PosY + 1, RelPosZ, InsideType, InsideMeta); + if (IsBlockRail(InsideType)) + { + // Push cart upwards + AddPosY(1); + } } bool WasDetectorRail = false; @@ -218,7 +223,10 @@ void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt) // Execute both the entity and block collision checks bool BlckCol = TestBlockCollision(a_RailMeta), EntCol = TestEntityCollision(a_RailMeta); - if (EntCol || BlckCol) return; + if (EntCol || BlckCol) + { + return; + } if (GetSpeedZ() != NO_SPEED) // Don't do anything if cart is stationary { @@ -243,7 +251,10 @@ void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt) SetSpeedZ(NO_SPEED); bool BlckCol = TestBlockCollision(a_RailMeta), EntCol = TestEntityCollision(a_RailMeta); - if (EntCol || BlckCol) return; + if (EntCol || BlckCol) + { + return; + } if (GetSpeedX() != NO_SPEED) { @@ -422,7 +433,10 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta) SetSpeedX(0); bool BlckCol = TestBlockCollision(a_RailMeta), EntCol = TestEntityCollision(a_RailMeta); - if (EntCol || BlckCol) return; + if (EntCol || BlckCol) + { + return; + } if (GetSpeedZ() != NO_SPEED) { @@ -445,7 +459,10 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta) SetSpeedZ(NO_SPEED); bool BlckCol = TestBlockCollision(a_RailMeta), EntCol = TestEntityCollision(a_RailMeta); - if (EntCol || BlckCol) return; + if (EntCol || BlckCol) + { + return; + } if (GetSpeedX() != NO_SPEED) { diff --git a/src/Generating/Caves.cpp b/src/Generating/Caves.cpp index fc925a150..e4735cb83 100644 --- a/src/Generating/Caves.cpp +++ b/src/Generating/Caves.cpp @@ -692,8 +692,14 @@ static float GetMarbleNoise( float x, float y, float z, cNoise & a_Noise) float oct1 = (a_Noise.CubicNoise3D(x * 0.1f, y * 0.1f, z * 0.1f)) * 4; oct1 = oct1 * oct1 * oct1; - if (oct1 < 0.f) oct1 = PI_2; - if (oct1 > PI_2) oct1 = PI_2; + if (oct1 < 0.f) + { + oct1 = PI_2; + } + if (oct1 > PI_2) + { + oct1 = PI_2; + } return oct1; } diff --git a/src/Mobs/AggressiveMonster.cpp b/src/Mobs/AggressiveMonster.cpp index 41ef26e2a..7ca7a9d66 100644 --- a/src/Mobs/AggressiveMonster.cpp +++ b/src/Mobs/AggressiveMonster.cpp @@ -75,7 +75,9 @@ void cAggressiveMonster::Tick(float a_Dt, cChunk & a_Chunk) } if (m_Target == nullptr) + { return; + } cTracer LineOfSight(GetWorld()); Vector3d AttackDirection(m_Target->GetPosition() - GetPosition()); diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index b8926e31d..c8b2ed774 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -267,7 +267,9 @@ void cMonster::Tick(float a_Dt, cChunk & a_Chunk) } if ((m_Target != nullptr) && m_Target->IsDestroyed()) + { m_Target = nullptr; + } // Burning in daylight HandleDaylightBurning(a_Chunk); @@ -1028,22 +1030,34 @@ void cMonster::AddRandomArmorDropItem(cItems & a_Drops, short a_LootingLevel) MTRand r1; if (r1.randInt() % 200 < ((m_DropChanceHelmet * 200) + (a_LootingLevel * 2))) { - if (!GetEquippedHelmet().IsEmpty()) a_Drops.push_back(GetEquippedHelmet()); + if (!GetEquippedHelmet().IsEmpty()) + { + a_Drops.push_back(GetEquippedHelmet()); + } } if (r1.randInt() % 200 < ((m_DropChanceChestplate * 200) + (a_LootingLevel * 2))) { - if (!GetEquippedChestplate().IsEmpty()) a_Drops.push_back(GetEquippedChestplate()); + if (!GetEquippedChestplate().IsEmpty()) + { + a_Drops.push_back(GetEquippedChestplate()); + } } if (r1.randInt() % 200 < ((m_DropChanceLeggings * 200) + (a_LootingLevel * 2))) { - if (!GetEquippedLeggings().IsEmpty()) a_Drops.push_back(GetEquippedLeggings()); + if (!GetEquippedLeggings().IsEmpty()) + { + a_Drops.push_back(GetEquippedLeggings()); + } } if (r1.randInt() % 200 < ((m_DropChanceBoots * 200) + (a_LootingLevel * 2))) { - if (!GetEquippedBoots().IsEmpty()) a_Drops.push_back(GetEquippedBoots()); + if (!GetEquippedBoots().IsEmpty()) + { + a_Drops.push_back(GetEquippedBoots()); + } } } @@ -1056,7 +1070,10 @@ void cMonster::AddRandomWeaponDropItem(cItems & a_Drops, short a_LootingLevel) MTRand r1; if (r1.randInt() % 200 < ((m_DropChanceWeapon * 200) + (a_LootingLevel * 2))) { - if (!GetEquippedWeapon().IsEmpty()) a_Drops.push_back(GetEquippedWeapon()); + if (!GetEquippedWeapon().IsEmpty()) + { + a_Drops.push_back(GetEquippedWeapon()); + } } } diff --git a/src/OSSupport/Thread.cpp b/src/OSSupport/Thread.cpp index faaccce96..6188d5088 100644 --- a/src/OSSupport/Thread.cpp +++ b/src/OSSupport/Thread.cpp @@ -83,12 +83,16 @@ cThread::~cThread() void cThread::Start( bool a_bWaitOnDelete /* = true */) { if (a_bWaitOnDelete) + { m_StopEvent = new cEvent(); + } #ifndef _WIN32 pthread_t SndThread; if (pthread_create( &SndThread, NULL, MyThread, this)) + { LOGERROR("ERROR: Could not create thread!"); + } #else DWORD ThreadID = 0; HANDLE hThread = CreateThread(NULL // security @@ -132,6 +136,11 @@ void *cThread::MyThread( void *a_Param) ThreadFunction( ThreadParam); - if (StopEvent) StopEvent->Set(); + // If the thread was marked as wait-on-delete, signal the event being waited on: + if (StopEvent != nullptr) + { + StopEvent->Set(); + } + return 0; } diff --git a/src/Simulator/FluidSimulator.cpp b/src/Simulator/FluidSimulator.cpp index a7551d9bc..ecd74ee52 100644 --- a/src/Simulator/FluidSimulator.cpp +++ b/src/Simulator/FluidSimulator.cpp @@ -184,7 +184,9 @@ Direction cFluidSimulator::GetFlowingDirection(int a_X, int a_Y, int a_Z, bool a } if (LowestPoint == m_World.GetBlockMeta(a_X, a_Y, a_Z)) + { return NONE; + } if (a_X - X > 0) { diff --git a/src/StringUtils.cpp b/src/StringUtils.cpp index fe145521f..5febf5d6c 100644 --- a/src/StringUtils.cpp +++ b/src/StringUtils.cpp @@ -420,7 +420,10 @@ static bool isLegalUTF8(const unsigned char * source, int length) case 3: if (((a = (*--srcptr)) < 0x80) || (a > 0xbf)) return false; case 2: { - if ((a = (*--srcptr)) > 0xbf) return false; + if ((a = (*--srcptr)) > 0xbf) + { + return false; + } switch (*source) { // no fall-through in this inner switch @@ -523,7 +526,10 @@ are equivalent to the following loop: { ch += *source++; --tmpBytesToRead; - if (tmpBytesToRead) ch <<= 6; + if (tmpBytesToRead) + { + ch <<= 6; + } } while (tmpBytesToRead > 0); } --------------------------------------------------------------------- diff --git a/src/Tracer.cpp b/src/Tracer.cpp index 53884dee8..e604f4a5b 100644 --- a/src/Tracer.cpp +++ b/src/Tracer.cpp @@ -39,8 +39,14 @@ cTracer::~cTracer() float cTracer::SigNum(float a_Num) { - if (a_Num < 0.f) return -1.f; - if (a_Num > 0.f) return 1.f; + if (a_Num < 0.f) + { + return -1.f; + } + if (a_Num > 0.f) + { + return 1.f; + } return 0.f; } @@ -59,7 +65,10 @@ void cTracer::SetValues(const Vector3f & a_Start, const Vector3f & a_Direction) step.z = (int) SigNum(dir.z); // normalize the direction vector - if (dir.SqrLength() > 0.f) dir.Normalize(); + if (dir.SqrLength() > 0.f) + { + dir.Normalize(); + } // how far we must move in the ray direction before // we encounter a new voxel in x-direction diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index ddee5e514..26a9104bc 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -1526,7 +1526,10 @@ void cWSSAnvil::LoadFallingBlockFromNBT(cEntityList & a_Entities, const cParsedN int TypeIdx = a_NBT.FindChildByName(a_TagIdx, "TileID"); int MetaIdx = a_NBT.FindChildByName(a_TagIdx, "Data"); - if ((TypeIdx < 0) || (MetaIdx < 0)) { return; } + if ((TypeIdx < 0) || (MetaIdx < 0)) + { + return; + } int Type = a_NBT.GetInt(TypeIdx); NIBBLETYPE Meta = (NIBBLETYPE)a_NBT.GetByte(MetaIdx); @@ -2196,11 +2199,13 @@ void cWSSAnvil::LoadGiantFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ void cWSSAnvil::LoadHorseFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - int TypeIdx = a_NBT.FindChildByName(a_TagIdx, "Type"); + int TypeIdx = a_NBT.FindChildByName(a_TagIdx, "Type"); int ColorIdx = a_NBT.FindChildByName(a_TagIdx, "Color"); int StyleIdx = a_NBT.FindChildByName(a_TagIdx, "Style"); - - if ((TypeIdx < 0) || (ColorIdx < 0) || (StyleIdx < 0)) { return; } + if ((TypeIdx < 0) || (ColorIdx < 0) || (StyleIdx < 0)) + { + return; + } int Type = a_NBT.GetInt(TypeIdx); int Color = a_NBT.GetInt(ColorIdx); @@ -2390,8 +2395,10 @@ void cWSSAnvil::LoadSilverfishFromNBT(cEntityList & a_Entities, const cParsedNBT void cWSSAnvil::LoadSkeletonFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { int TypeIdx = a_NBT.FindChildByName(a_TagIdx, "SkeletonType"); - - if (TypeIdx < 0) { return; } + if (TypeIdx < 0) + { + return; + } bool Type = ((a_NBT.GetByte(TypeIdx) == 1) ? true : false); @@ -2505,8 +2512,10 @@ void cWSSAnvil::LoadSquidFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ void cWSSAnvil::LoadVillagerFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { int TypeIdx = a_NBT.FindChildByName(a_TagIdx, "Profession"); - - if (TypeIdx < 0) { return; } + if (TypeIdx < 0) + { + return; + } int Type = a_NBT.GetInt(TypeIdx); @@ -2630,8 +2639,10 @@ void cWSSAnvil::LoadWolfFromNBT(cEntityList & a_Entities, const cParsedNBT & a_N void cWSSAnvil::LoadZombieFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { int IsVillagerIdx = a_NBT.FindChildByName(a_TagIdx, "IsVillager"); - - if (IsVillagerIdx < 0) { return; } + if (IsVillagerIdx < 0) + { + return; + } bool IsVillagerZombie = ((a_NBT.GetByte(IsVillagerIdx) == 1) ? true : false); diff --git a/src/XMLParser.h b/src/XMLParser.h index dab9699c9..ea341bce6 100644 --- a/src/XMLParser.h +++ b/src/XMLParser.h @@ -254,7 +254,9 @@ protected: XML_SetDefaultHandlerExpand (m_p, fEnable ? DefaultHandler : nullptr); } else + { XML_SetDefaultHandler (m_p, fEnable ? DefaultHandler : nullptr); + } } // @cmember Enable/Disable external entity ref handler @@ -402,11 +404,17 @@ public: { XML_expat_version v = XML_ExpatVersionInfo (); if (pnMajor) + { *pnMajor = v .major; + } if (pnMinor) + { *pnMinor = v .minor; + } if (pnMicro) + { *pnMicro = v .micro; + } } // @cmember Get last error string -- cgit v1.2.3 From 8e56d7539d03e6d344f5e27f9be391c6cd1846bf Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 5 Dec 2014 16:59:56 +0100 Subject: CheckBasicStyle: Check missing braces for control statements. Only single-line control statements are checked. --- src/CheckBasicStyle.lua | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/CheckBasicStyle.lua b/src/CheckBasicStyle.lua index d703c3816..7914aedfd 100644 --- a/src/CheckBasicStyle.lua +++ b/src/CheckBasicStyle.lua @@ -181,6 +181,7 @@ local function ProcessFile(a_FileName) -- Ref.: http://stackoverflow.com/questions/10416869/iterate-over-possibly-empty-lines-in-a-way-that-matches-the-expectations-of-exis local lineCounter = 1 local lastIndentLevel = 0 + local isLastLineControl = false all:gsub("\r\n", "\n") -- normalize CRLF into LF-only string.gsub(all .. "\n", "[^\n]*\n", -- Iterate over each line, while preserving empty lines function(a_Line) @@ -217,6 +218,24 @@ local function ProcessFile(a_FileName) end lastIndentLevel = indentLevel end + + -- Check that control statements have braces on separate lines after them: + -- Note that if statements can be broken into multiple lines, in which case this test is not taken + if (isLastLineControl) then + if not(a_Line:find("^%s*{") or a_Line:find("^%s*#")) then + -- Not followed by a brace, not followed by a preprocessor + ReportViolation(a_FileName, lineCounter - 1, 1, 1, "Control statement needs a brace on separate line") + end + end + local lineWithSpace = " " .. a_Line + isLastLineControl = + lineWithSpace:find("^%s+if %b()") or + lineWithSpace:find("^%s+else if %b()") or + lineWithSpace:find("^%s+for %b()") or + lineWithSpace:find("^%s+switch %b()") or + lineWithSpace:find("^%s+else\n") or + lineWithSpace:find("^%s+else //") or + lineWithSpace:find("^%s+do %b()") lineCounter = lineCounter + 1 end -- cgit v1.2.3 From b25fcb0972554facbd4dfd79cb256a77a2cb6773 Mon Sep 17 00:00:00 2001 From: p-mcgowan Date: Fri, 5 Dec 2014 11:31:01 -0800 Subject: formatting and default spawn percentage --- src/Generating/FinishGen.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index 41dbdca16..ad3dc5293 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -993,6 +993,7 @@ cFinishGenPassiveMobs::cFinishGenPassiveMobs(int a_Seed, cIniFile & a_IniFile, e if ((m_AnimalProbability < 0) || (m_AnimalProbability > 100)) { LOGWARNING("[Animals]: AnimalSpawnChunkPercentage is invalid, using the default of \"%d\".", DefaultAnimalSpawnChunkPercentage); + m_AnimalProbability = DefaultAnimalSpawnChunkPercentage; } } @@ -1052,7 +1053,7 @@ bool cFinishGenPassiveMobs::TrySpawnAnimals(cChunkDesc & a_ChunkDesc, int a_RelX BLOCKTYPE BlockUnderFeet = a_ChunkDesc.GetBlockType(a_RelX, a_RelY - 1, a_RelZ); // Check block below (opaque, grass, water), and above (air) - if (AnimalToSpawn == mtSquid && BlockAtFeet != E_BLOCK_WATER) + if ((AnimalToSpawn == mtSquid) && (BlockAtFeet != E_BLOCK_WATER)) { return false; } -- cgit v1.2.3 From c5dc5ac45f19aac55f99629603cfaf81ac3d0b10 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 5 Dec 2014 22:46:46 +0100 Subject: FinishGenPassiveMobs: Cosmetic changes. --- src/Generating/FinishGen.cpp | 45 ++++++++++++++++++++++---------------------- src/Generating/FinishGen.h | 18 +++++++++++------- 2 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index ad3dc5293..e6732dbd5 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -1078,16 +1078,14 @@ bool cFinishGenPassiveMobs::TrySpawnAnimals(cChunkDesc & a_ChunkDesc, int a_RelX return false; } - int AnimalX, AnimalY, AnimalZ; - AnimalX = (double)(a_ChunkDesc.GetChunkX()*cChunkDef::Width + a_RelX + 0.5); - AnimalY = a_RelY; - AnimalZ = (double)(a_ChunkDesc.GetChunkZ()*cChunkDef::Width + a_RelZ + 0.5); + double AnimalX = static_cast(a_ChunkDesc.GetChunkX() * cChunkDef::Width + a_RelX + 0.5); + double AnimalY = a_RelY; + double AnimalZ = static_cast(a_ChunkDesc.GetChunkZ() * cChunkDef::Width + a_RelZ + 0.5); - cEntityList ChunkEntities = a_ChunkDesc.GetEntities(); cMonster * NewMob = cMonster::NewMonsterFromType(AnimalToSpawn); NewMob->SetPosition(AnimalX, AnimalY, AnimalZ); - ChunkEntities.push_back(NewMob); - LOGD("Spawning %s #%i at {%d, %d, %d}", NewMob->GetClass(), NewMob->GetUniqueID(), AnimalX, AnimalY, AnimalZ); + a_ChunkDesc.GetEntities().push_back(NewMob); + LOGD("Spawning %s #%i at {%.02f, %.02f, %.02f}", NewMob->GetClass(), NewMob->GetUniqueID(), AnimalX, AnimalY, AnimalZ); return true; } @@ -1100,13 +1098,12 @@ eMonsterType cFinishGenPassiveMobs::GetRandomMob(cChunkDesc & a_ChunkDesc) { std::set ListOfSpawnables; - std::set::iterator MobIter = ListOfSpawnables.begin(); int chunkX = a_ChunkDesc.GetChunkX(); int chunkZ = a_ChunkDesc.GetChunkZ(); int x = (m_Noise.IntNoise2DInt(chunkX, chunkZ + 10) / 7) % cChunkDef::Width; int z = (m_Noise.IntNoise2DInt(chunkX + chunkZ, chunkZ) / 7) % cChunkDef::Width; - /** Check biomes first to get a list of animals */ + // Check biomes first to get a list of animals switch (a_ChunkDesc.GetBiome(x, z)) { // No animals in deserts or non-overworld dimensions @@ -1118,12 +1115,14 @@ eMonsterType cFinishGenPassiveMobs::GetRandomMob(cChunkDesc & a_ChunkDesc) { return mtInvalidType; } + // Mooshroom only - no other mobs on mushroom islands case biMushroomIsland: case biMushroomShore: { return mtMooshroom; } + // Add squid in ocean biomes case biOcean: case biFrozenOcean: @@ -1131,9 +1130,10 @@ eMonsterType cFinishGenPassiveMobs::GetRandomMob(cChunkDesc & a_ChunkDesc) case biRiver: case biDeepOcean: { - ListOfSpawnables.insert(MobIter, mtSquid); + ListOfSpawnables.insert(mtSquid); break; } + // Add ocelots in jungle biomes case biJungle: case biJungleHills: @@ -1141,9 +1141,11 @@ eMonsterType cFinishGenPassiveMobs::GetRandomMob(cChunkDesc & a_ChunkDesc) case biJungleM: case biJungleEdgeM: { - ListOfSpawnables.insert(MobIter, mtOcelot); + ListOfSpawnables.insert(mtOcelot); break; } + + // Add horses in plains-like biomes case biPlains: case biSunflowerPlains: case biSavanna: @@ -1151,10 +1153,10 @@ eMonsterType cFinishGenPassiveMobs::GetRandomMob(cChunkDesc & a_ChunkDesc) case biSavannaM: case biSavannaPlateauM: { - ListOfSpawnables.insert(MobIter, mtHorse); - // ListOfSpawnables.insert(mtDonkey); + ListOfSpawnables.insert(mtHorse); break; } + // Add wolves in forest and spruce forests case biForest: case biTaiga: @@ -1162,7 +1164,7 @@ eMonsterType cFinishGenPassiveMobs::GetRandomMob(cChunkDesc & a_ChunkDesc) case biColdTaiga: case biColdTaigaM: { - ListOfSpawnables.insert(MobIter, mtWolf); + ListOfSpawnables.insert(mtWolf); break; } // Nothing special about this biome @@ -1171,10 +1173,10 @@ eMonsterType cFinishGenPassiveMobs::GetRandomMob(cChunkDesc & a_ChunkDesc) break; } } - ListOfSpawnables.insert(MobIter, mtChicken); - ListOfSpawnables.insert(MobIter, mtCow); - ListOfSpawnables.insert(MobIter, mtPig); - ListOfSpawnables.insert(MobIter, mtSheep); + ListOfSpawnables.insert(mtChicken); + ListOfSpawnables.insert(mtCow); + ListOfSpawnables.insert(mtPig); + ListOfSpawnables.insert(mtSheep); if (ListOfSpawnables.empty()) { @@ -1182,11 +1184,8 @@ eMonsterType cFinishGenPassiveMobs::GetRandomMob(cChunkDesc & a_ChunkDesc) } int RandMob = (m_Noise.IntNoise2DInt(chunkX - chunkZ + 2, chunkX + 5) / 7) % ListOfSpawnables.size(); - MobIter = ListOfSpawnables.begin(); - for (int i = 0; i < RandMob; i++) - { - ++MobIter; - } + auto MobIter = ListOfSpawnables.begin(); + std::advance(MobIter, RandMob); return *MobIter; } diff --git a/src/Generating/FinishGen.h b/src/Generating/FinishGen.h index 8305908c0..ae6dee590 100644 --- a/src/Generating/FinishGen.h +++ b/src/Generating/FinishGen.h @@ -312,7 +312,7 @@ protected: // cFinishGen override: virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; - // Tries to place a spring at the specified coords, checks neighbors. Returns true if successful + /** Tries to place a spring at the specified coords, checks neighbors. Returns true if successful. */ bool TryPlaceSpring(cChunkDesc & a_ChunkDesc, int x, int y, int z); } ; @@ -321,8 +321,7 @@ protected: /** This class populates generated chunks with packs of biome-dependant animals - Animals: cows, sheep, pigs, mooshrooms, squid, horses, wolves, ocelots - */ +Animals: cows, sheep, pigs, mooshrooms, squid, horses, wolves, ocelots */ class cFinishGenPassiveMobs : public cFinishGen { @@ -332,16 +331,21 @@ public: protected: - cNoise m_Noise; - int m_AnimalProbability; // Chance, [0..100], that an animal pack will be generated in a chunk + /** The noise used as the source of randomness */ + cNoise m_Noise; + + /** Chance, [0..100], that an animal pack will be generated in a chunk */ + int m_AnimalProbability; + // cFinishGen override: virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; - // Returns false if an animal cannot spawn at given coords, else adds it to the chunk's entity list and returns true + /** Returns false if an animal cannot spawn at given coords, else adds it to the chunk's entity list and returns true */ bool TrySpawnAnimals(cChunkDesc & a_ChunkDesc, int x, int y, int z, eMonsterType AnimalToSpawn); - // Gets a random animal from biome-dependant list + /** Picks a random animal from biome-dependant list for a random position in the chunk. + Returns the chosen mob type, or mtInvalid if no mob chosen. */ eMonsterType GetRandomMob(cChunkDesc & a_ChunkDesc); } ; -- cgit v1.2.3 From 263fabc81661b76edc36330ef42cd6be947aa91c Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sat, 6 Dec 2014 23:02:49 +0100 Subject: Replaced most auto_ptr with unique_ptr. --- src/HTTPServer/HTTPFormParser.h | 2 +- src/WorldStorage/WSSAnvil.cpp | 122 ++++++++++++++++++++-------------------- 2 files changed, 62 insertions(+), 62 deletions(-) diff --git a/src/HTTPServer/HTTPFormParser.h b/src/HTTPServer/HTTPFormParser.h index edc6d2471..d9d29d9bc 100644 --- a/src/HTTPServer/HTTPFormParser.h +++ b/src/HTTPServer/HTTPFormParser.h @@ -82,7 +82,7 @@ protected: bool m_IsValid; /// The parser for the multipart data, if used - std::auto_ptr m_MultipartParser; + std::unique_ptr m_MultipartParser; /// Name of the currently parsed part in multipart data AString m_CurrentPartName; diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 26a9104bc..5a0932bbe 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -631,7 +631,7 @@ void cWSSAnvil::LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntities, con // Load the proper BlockEntity type based on the block type: BLOCKTYPE BlockType = cChunkDef::GetBlock(a_BlockTypes, RelX, RelY, RelZ); NIBBLETYPE BlockMeta = cChunkDef::GetNibble(a_BlockMetas, RelX, RelY, RelZ); - std::auto_ptr be(LoadBlockEntityFromNBT(a_NBT, Child, x, y, z, BlockType, BlockMeta)); + std::unique_ptr be(LoadBlockEntityFromNBT(a_NBT, Child, x, y, z, BlockType, BlockMeta)); if (be.get() == nullptr) { continue; @@ -858,7 +858,7 @@ cBlockEntity * cWSSAnvil::LoadBeaconFromNBT(const cParsedNBT & a_NBT, int a_TagI return nullptr; } - std::auto_ptr Beacon(new cBeaconEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); + std::unique_ptr Beacon(new cBeaconEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); int CurrentLine = a_NBT.FindChildByName(a_TagIdx, "Levels"); if (CurrentLine >= 0) @@ -908,7 +908,7 @@ cBlockEntity * cWSSAnvil::LoadChestFromNBT(const cParsedNBT & a_NBT, int a_TagId { return nullptr; // Make it an empty chest - the chunk loader will provide an empty cChestEntity for this } - std::auto_ptr Chest(new cChestEntity(a_BlockX, a_BlockY, a_BlockZ, m_World, a_ChestBlockType)); + std::unique_ptr Chest(new cChestEntity(a_BlockX, a_BlockY, a_BlockZ, m_World, a_ChestBlockType)); LoadItemGridFromNBT(Chest->GetContents(), a_NBT, Items); return Chest.release(); } @@ -925,7 +925,7 @@ cBlockEntity * cWSSAnvil::LoadCommandBlockFromNBT(const cParsedNBT & a_NBT, int return nullptr; } - std::auto_ptr CmdBlock(new cCommandBlockEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); + std::unique_ptr CmdBlock(new cCommandBlockEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); int currentLine = a_NBT.FindChildByName(a_TagIdx, "Command"); if (currentLine >= 0) @@ -967,7 +967,7 @@ cBlockEntity * cWSSAnvil::LoadDispenserFromNBT(const cParsedNBT & a_NBT, int a_T { return nullptr; // Make it an empty dispenser - the chunk loader will provide an empty cDispenserEntity for this } - std::auto_ptr Dispenser(new cDispenserEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); + std::unique_ptr Dispenser(new cDispenserEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); LoadItemGridFromNBT(Dispenser->GetContents(), a_NBT, Items); return Dispenser.release(); } @@ -989,7 +989,7 @@ cBlockEntity * cWSSAnvil::LoadDropperFromNBT(const cParsedNBT & a_NBT, int a_Tag { return nullptr; // Make it an empty dropper - the chunk loader will provide an empty cDropperEntity for this } - std::auto_ptr Dropper(new cDropperEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); + std::unique_ptr Dropper(new cDropperEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); LoadItemGridFromNBT(Dropper->GetContents(), a_NBT, Items); return Dropper.release(); } @@ -1006,7 +1006,7 @@ cBlockEntity * cWSSAnvil::LoadFlowerPotFromNBT(const cParsedNBT & a_NBT, int a_T return nullptr; } - std::auto_ptr FlowerPot(new cFlowerPotEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); + std::unique_ptr FlowerPot(new cFlowerPotEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); short ItemType = 0, ItemData = 0; int currentLine = a_NBT.FindChildByName(a_TagIdx, "Item"); @@ -1043,7 +1043,7 @@ cBlockEntity * cWSSAnvil::LoadFurnaceFromNBT(const cParsedNBT & a_NBT, int a_Tag return nullptr; // Make it an empty furnace - the chunk loader will provide an empty cFurnaceEntity for this } - std::auto_ptr Furnace(new cFurnaceEntity(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, m_World)); + std::unique_ptr Furnace(new cFurnaceEntity(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, m_World)); // Load slots: for (int Child = a_NBT.GetFirstChild(Items); Child != -1; Child = a_NBT.GetNextSibling(Child)) @@ -1148,7 +1148,7 @@ cBlockEntity * cWSSAnvil::LoadHopperFromNBT(const cParsedNBT & a_NBT, int a_TagI { return nullptr; // Make it an empty hopper - the chunk loader will provide an empty cHopperEntity for this } - std::auto_ptr Hopper(new cHopperEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); + std::unique_ptr Hopper(new cHopperEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); LoadItemGridFromNBT(Hopper->GetContents(), a_NBT, Items); return Hopper.release(); } @@ -1165,7 +1165,7 @@ cBlockEntity * cWSSAnvil::LoadJukeboxFromNBT(const cParsedNBT & a_NBT, int a_Tag return nullptr; } - std::auto_ptr Jukebox(new cJukeboxEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); + std::unique_ptr Jukebox(new cJukeboxEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); int Record = a_NBT.FindChildByName(a_TagIdx, "Record"); if (Record >= 0) { @@ -1186,7 +1186,7 @@ cBlockEntity * cWSSAnvil::LoadMobHeadFromNBT(const cParsedNBT & a_NBT, int a_Tag return nullptr; } - std::auto_ptr MobHead(new cMobHeadEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); + std::unique_ptr MobHead(new cMobHeadEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); int currentLine = a_NBT.FindChildByName(a_TagIdx, "SkullType"); if (currentLine >= 0) @@ -1221,7 +1221,7 @@ cBlockEntity * cWSSAnvil::LoadNoteBlockFromNBT(const cParsedNBT & a_NBT, int a_T return nullptr; } - std::auto_ptr NoteBlock(new cNoteEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); + std::unique_ptr NoteBlock(new cNoteEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); int note = a_NBT.FindChildByName(a_TagIdx, "note"); if (note >= 0) { @@ -1242,7 +1242,7 @@ cBlockEntity * cWSSAnvil::LoadSignFromNBT(const cParsedNBT & a_NBT, int a_TagIdx return nullptr; } - std::auto_ptr Sign(new cSignEntity(a_BlockType, a_BlockX, a_BlockY, a_BlockZ, m_World)); + std::unique_ptr Sign(new cSignEntity(a_BlockType, a_BlockX, a_BlockY, a_BlockZ, m_World)); int currentLine = a_NBT.FindChildByName(a_TagIdx, "Text1"); if (currentLine >= 0) @@ -1495,7 +1495,7 @@ void cWSSAnvil::LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a void cWSSAnvil::LoadBoatFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr Boat(new cBoat(0, 0, 0)); + std::unique_ptr Boat(new cBoat(0, 0, 0)); if (!LoadEntityBaseFromNBT(*Boat.get(), a_NBT, a_TagIdx)) { return; @@ -1509,7 +1509,7 @@ void cWSSAnvil::LoadBoatFromNBT(cEntityList & a_Entities, const cParsedNBT & a_N void cWSSAnvil::LoadEnderCrystalFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr EnderCrystal(new cEnderCrystal(0, 0, 0)); + std::unique_ptr EnderCrystal(new cEnderCrystal(0, 0, 0)); if (!LoadEntityBaseFromNBT(*EnderCrystal.get(), a_NBT, a_TagIdx)) { return; @@ -1534,7 +1534,7 @@ void cWSSAnvil::LoadFallingBlockFromNBT(cEntityList & a_Entities, const cParsedN int Type = a_NBT.GetInt(TypeIdx); NIBBLETYPE Meta = (NIBBLETYPE)a_NBT.GetByte(MetaIdx); - std::auto_ptr FallingBlock(new cFallingBlock(Vector3i(0, 0, 0), Type, Meta)); + std::unique_ptr FallingBlock(new cFallingBlock(Vector3i(0, 0, 0), Type, Meta)); if (!LoadEntityBaseFromNBT(*FallingBlock.get(), a_NBT, a_TagIdx)) { return; @@ -1548,7 +1548,7 @@ void cWSSAnvil::LoadFallingBlockFromNBT(cEntityList & a_Entities, const cParsedN void cWSSAnvil::LoadMinecartRFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr Minecart(new cRideableMinecart(0, 0, 0, cItem(), 1)); // TODO: Load the block and the height + std::unique_ptr Minecart(new cRideableMinecart(0, 0, 0, cItem(), 1)); // TODO: Load the block and the height if (!LoadEntityBaseFromNBT(*Minecart.get(), a_NBT, a_TagIdx)) { return; @@ -1567,7 +1567,7 @@ void cWSSAnvil::LoadMinecartCFromNBT(cEntityList & a_Entities, const cParsedNBT { return; // Make it an empty chest - the chunk loader will provide an empty cChestEntity for this } - std::auto_ptr Minecart(new cMinecartWithChest(0, 0, 0)); + std::unique_ptr Minecart(new cMinecartWithChest(0, 0, 0)); if (!LoadEntityBaseFromNBT(*Minecart.get(), a_NBT, a_TagIdx)) { return; @@ -1594,7 +1594,7 @@ void cWSSAnvil::LoadMinecartCFromNBT(cEntityList & a_Entities, const cParsedNBT void cWSSAnvil::LoadMinecartFFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr Minecart(new cMinecartWithFurnace(0, 0, 0)); + std::unique_ptr Minecart(new cMinecartWithFurnace(0, 0, 0)); if (!LoadEntityBaseFromNBT(*Minecart.get(), a_NBT, a_TagIdx)) { return; @@ -1611,7 +1611,7 @@ void cWSSAnvil::LoadMinecartFFromNBT(cEntityList & a_Entities, const cParsedNBT void cWSSAnvil::LoadMinecartTFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr Minecart(new cMinecartWithTNT(0, 0, 0)); + std::unique_ptr Minecart(new cMinecartWithTNT(0, 0, 0)); if (!LoadEntityBaseFromNBT(*Minecart.get(), a_NBT, a_TagIdx)) { return; @@ -1628,7 +1628,7 @@ void cWSSAnvil::LoadMinecartTFromNBT(cEntityList & a_Entities, const cParsedNBT void cWSSAnvil::LoadMinecartHFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr Minecart(new cMinecartWithHopper(0, 0, 0)); + std::unique_ptr Minecart(new cMinecartWithHopper(0, 0, 0)); if (!LoadEntityBaseFromNBT(*Minecart.get(), a_NBT, a_TagIdx)) { return; @@ -1657,7 +1657,7 @@ void cWSSAnvil::LoadPickupFromNBT(cEntityList & a_Entities, const cParsedNBT & a return; } - std::auto_ptr Pickup(new cPickup(0, 0, 0, Item, false)); // Pickup delay doesn't matter, just say false + std::unique_ptr Pickup(new cPickup(0, 0, 0, Item, false)); // Pickup delay doesn't matter, just say false if (!LoadEntityBaseFromNBT(*Pickup.get(), a_NBT, a_TagIdx)) { return; @@ -1679,7 +1679,7 @@ void cWSSAnvil::LoadPickupFromNBT(cEntityList & a_Entities, const cParsedNBT & a void cWSSAnvil::LoadTNTFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr TNT(new cTNTEntity(0.0, 0.0, 0.0, 0)); + std::unique_ptr TNT(new cTNTEntity(0.0, 0.0, 0.0, 0)); if (!LoadEntityBaseFromNBT(*TNT.get(), a_NBT, a_TagIdx)) { return; @@ -1701,7 +1701,7 @@ void cWSSAnvil::LoadTNTFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NB void cWSSAnvil::LoadExpOrbFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr ExpOrb(new cExpOrb(0.0, 0.0, 0.0, 0)); + std::unique_ptr ExpOrb(new cExpOrb(0.0, 0.0, 0.0, 0)); if (!LoadEntityBaseFromNBT(*ExpOrb.get(), a_NBT, a_TagIdx)) { return; @@ -1800,7 +1800,7 @@ void cWSSAnvil::LoadItemFrameFromNBT(cEntityList & a_Entities, const cParsedNBT return; } - std::auto_ptr ItemFrame(new cItemFrame(BLOCK_FACE_NONE, 0.0, 0.0, 0.0)); + std::unique_ptr ItemFrame(new cItemFrame(BLOCK_FACE_NONE, 0.0, 0.0, 0.0)); if (!LoadEntityBaseFromNBT(*ItemFrame.get(), a_NBT, a_TagIdx)) { return; @@ -1825,7 +1825,7 @@ void cWSSAnvil::LoadItemFrameFromNBT(cEntityList & a_Entities, const cParsedNBT void cWSSAnvil::LoadArrowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr Arrow(new cArrowEntity(nullptr, 0, 0, 0, Vector3d(0, 0, 0))); + std::unique_ptr Arrow(new cArrowEntity(nullptr, 0, 0, 0, Vector3d(0, 0, 0))); if (!LoadProjectileBaseFromNBT(*Arrow.get(), a_NBT, a_TagIdx)) { return; @@ -1895,7 +1895,7 @@ void cWSSAnvil::LoadArrowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ void cWSSAnvil::LoadSplashPotionFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr SplashPotion(new cSplashPotionEntity(nullptr, 0, 0, 0, Vector3d(0, 0, 0), cItem())); + std::unique_ptr SplashPotion(new cSplashPotionEntity(nullptr, 0, 0, 0, Vector3d(0, 0, 0), cItem())); if (!LoadProjectileBaseFromNBT(*SplashPotion.get(), a_NBT, a_TagIdx)) { return; @@ -1919,7 +1919,7 @@ void cWSSAnvil::LoadSplashPotionFromNBT(cEntityList & a_Entities, const cParsedN void cWSSAnvil::LoadSnowballFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr Snowball(new cThrownSnowballEntity(nullptr, 0, 0, 0, Vector3d(0, 0, 0))); + std::unique_ptr Snowball(new cThrownSnowballEntity(nullptr, 0, 0, 0, Vector3d(0, 0, 0))); if (!LoadProjectileBaseFromNBT(*Snowball.get(), a_NBT, a_TagIdx)) { return; @@ -1935,7 +1935,7 @@ void cWSSAnvil::LoadSnowballFromNBT(cEntityList & a_Entities, const cParsedNBT & void cWSSAnvil::LoadEggFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr Egg(new cThrownEggEntity(nullptr, 0, 0, 0, Vector3d(0, 0, 0))); + std::unique_ptr Egg(new cThrownEggEntity(nullptr, 0, 0, 0, Vector3d(0, 0, 0))); if (!LoadProjectileBaseFromNBT(*Egg.get(), a_NBT, a_TagIdx)) { return; @@ -1951,7 +1951,7 @@ void cWSSAnvil::LoadEggFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NB void cWSSAnvil::LoadFireballFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr Fireball(new cGhastFireballEntity(nullptr, 0, 0, 0, Vector3d(0, 0, 0))); + std::unique_ptr Fireball(new cGhastFireballEntity(nullptr, 0, 0, 0, Vector3d(0, 0, 0))); if (!LoadProjectileBaseFromNBT(*Fireball.get(), a_NBT, a_TagIdx)) { return; @@ -1967,7 +1967,7 @@ void cWSSAnvil::LoadFireballFromNBT(cEntityList & a_Entities, const cParsedNBT & void cWSSAnvil::LoadFireChargeFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr FireCharge(new cFireChargeEntity(nullptr, 0, 0, 0, Vector3d(0, 0, 0))); + std::unique_ptr FireCharge(new cFireChargeEntity(nullptr, 0, 0, 0, Vector3d(0, 0, 0))); if (!LoadProjectileBaseFromNBT(*FireCharge.get(), a_NBT, a_TagIdx)) { return; @@ -1983,7 +1983,7 @@ void cWSSAnvil::LoadFireChargeFromNBT(cEntityList & a_Entities, const cParsedNBT void cWSSAnvil::LoadThrownEnderpearlFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr Enderpearl(new cThrownEnderPearlEntity(nullptr, 0, 0, 0, Vector3d(0, 0, 0))); + std::unique_ptr Enderpearl(new cThrownEnderPearlEntity(nullptr, 0, 0, 0, Vector3d(0, 0, 0))); if (!LoadProjectileBaseFromNBT(*Enderpearl.get(), a_NBT, a_TagIdx)) { return; @@ -1999,7 +1999,7 @@ void cWSSAnvil::LoadThrownEnderpearlFromNBT(cEntityList & a_Entities, const cPar void cWSSAnvil::LoadBatFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr Monster(new cBat()); + std::unique_ptr Monster(new cBat()); if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2019,7 +2019,7 @@ void cWSSAnvil::LoadBatFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NB void cWSSAnvil::LoadBlazeFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr Monster(new cBlaze()); + std::unique_ptr Monster(new cBlaze()); if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2039,7 +2039,7 @@ void cWSSAnvil::LoadBlazeFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ void cWSSAnvil::LoadCaveSpiderFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr Monster(new cCaveSpider()); + std::unique_ptr Monster(new cCaveSpider()); if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2059,7 +2059,7 @@ void cWSSAnvil::LoadCaveSpiderFromNBT(cEntityList & a_Entities, const cParsedNBT void cWSSAnvil::LoadChickenFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr Monster(new cChicken()); + std::unique_ptr Monster(new cChicken()); if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2079,7 +2079,7 @@ void cWSSAnvil::LoadChickenFromNBT(cEntityList & a_Entities, const cParsedNBT & void cWSSAnvil::LoadCowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr Monster(new cCow()); + std::unique_ptr Monster(new cCow()); if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2099,7 +2099,7 @@ void cWSSAnvil::LoadCowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NB void cWSSAnvil::LoadCreeperFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr Monster(new cCreeper()); + std::unique_ptr Monster(new cCreeper()); if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2119,7 +2119,7 @@ void cWSSAnvil::LoadCreeperFromNBT(cEntityList & a_Entities, const cParsedNBT & void cWSSAnvil::LoadEnderDragonFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr Monster(new cEnderDragon()); + std::unique_ptr Monster(new cEnderDragon()); if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2139,7 +2139,7 @@ void cWSSAnvil::LoadEnderDragonFromNBT(cEntityList & a_Entities, const cParsedNB void cWSSAnvil::LoadEndermanFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr Monster(new cEnderman()); + std::unique_ptr Monster(new cEnderman()); if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2159,7 +2159,7 @@ void cWSSAnvil::LoadEndermanFromNBT(cEntityList & a_Entities, const cParsedNBT & void cWSSAnvil::LoadGhastFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr Monster(new cGhast()); + std::unique_ptr Monster(new cGhast()); if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2179,7 +2179,7 @@ void cWSSAnvil::LoadGhastFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ void cWSSAnvil::LoadGiantFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr Monster(new cGiant()); + std::unique_ptr Monster(new cGiant()); if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2211,7 +2211,7 @@ void cWSSAnvil::LoadHorseFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ int Color = a_NBT.GetInt(ColorIdx); int Style = a_NBT.GetInt(StyleIdx); - std::auto_ptr Monster(new cHorse(Type, Color, Style, 1)); + std::unique_ptr Monster(new cHorse(Type, Color, Style, 1)); if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { @@ -2232,7 +2232,7 @@ void cWSSAnvil::LoadHorseFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ void cWSSAnvil::LoadIronGolemFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr Monster(new cIronGolem()); + std::unique_ptr Monster(new cIronGolem()); if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2261,7 +2261,7 @@ void cWSSAnvil::LoadMagmaCubeFromNBT(cEntityList & a_Entities, const cParsedNBT int Size = a_NBT.GetInt(SizeIdx); - std::auto_ptr Monster(new cMagmaCube(Size)); + std::unique_ptr Monster(new cMagmaCube(Size)); if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2281,7 +2281,7 @@ void cWSSAnvil::LoadMagmaCubeFromNBT(cEntityList & a_Entities, const cParsedNBT void cWSSAnvil::LoadMooshroomFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr Monster(new cMooshroom()); + std::unique_ptr Monster(new cMooshroom()); if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2301,7 +2301,7 @@ void cWSSAnvil::LoadMooshroomFromNBT(cEntityList & a_Entities, const cParsedNBT void cWSSAnvil::LoadOcelotFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr Monster(new cOcelot()); + std::unique_ptr Monster(new cOcelot()); if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2321,7 +2321,7 @@ void cWSSAnvil::LoadOcelotFromNBT(cEntityList & a_Entities, const cParsedNBT & a void cWSSAnvil::LoadPigFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr Monster(new cPig()); + std::unique_ptr Monster(new cPig()); if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2348,7 +2348,7 @@ void cWSSAnvil::LoadSheepFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ Color = (int)a_NBT.GetByte(ColorIdx); } - std::auto_ptr Monster(new cSheep(Color)); + std::unique_ptr Monster(new cSheep(Color)); if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2374,7 +2374,7 @@ void cWSSAnvil::LoadSheepFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ void cWSSAnvil::LoadSilverfishFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr Monster(new cSilverfish()); + std::unique_ptr Monster(new cSilverfish()); if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2402,7 +2402,7 @@ void cWSSAnvil::LoadSkeletonFromNBT(cEntityList & a_Entities, const cParsedNBT & bool Type = ((a_NBT.GetByte(TypeIdx) == 1) ? true : false); - std::auto_ptr Monster(new cSkeleton(Type)); + std::unique_ptr Monster(new cSkeleton(Type)); if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2431,7 +2431,7 @@ void cWSSAnvil::LoadSlimeFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ int Size = a_NBT.GetInt(SizeIdx); - std::auto_ptr Monster(new cSlime(Size)); + std::unique_ptr Monster(new cSlime(Size)); if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2451,7 +2451,7 @@ void cWSSAnvil::LoadSlimeFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ void cWSSAnvil::LoadSnowGolemFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr Monster(new cSnowGolem()); + std::unique_ptr Monster(new cSnowGolem()); if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2471,7 +2471,7 @@ void cWSSAnvil::LoadSnowGolemFromNBT(cEntityList & a_Entities, const cParsedNBT void cWSSAnvil::LoadSpiderFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr Monster(new cSpider()); + std::unique_ptr Monster(new cSpider()); if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2491,7 +2491,7 @@ void cWSSAnvil::LoadSpiderFromNBT(cEntityList & a_Entities, const cParsedNBT & a void cWSSAnvil::LoadSquidFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr Monster(new cSquid()); + std::unique_ptr Monster(new cSquid()); if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2519,7 +2519,7 @@ void cWSSAnvil::LoadVillagerFromNBT(cEntityList & a_Entities, const cParsedNBT & int Type = a_NBT.GetInt(TypeIdx); - std::auto_ptr Monster(new cVillager(cVillager::eVillagerType(Type))); + std::unique_ptr Monster(new cVillager(cVillager::eVillagerType(Type))); if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2539,7 +2539,7 @@ void cWSSAnvil::LoadVillagerFromNBT(cEntityList & a_Entities, const cParsedNBT & void cWSSAnvil::LoadWitchFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr Monster(new cWitch()); + std::unique_ptr Monster(new cWitch()); if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2559,7 +2559,7 @@ void cWSSAnvil::LoadWitchFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ void cWSSAnvil::LoadWitherFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr Monster(new cWither()); + std::unique_ptr Monster(new cWither()); if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2585,7 +2585,7 @@ void cWSSAnvil::LoadWitherFromNBT(cEntityList & a_Entities, const cParsedNBT & a void cWSSAnvil::LoadWolfFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr Monster(new cWolf()); + std::unique_ptr Monster(new cWolf()); if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2646,7 +2646,7 @@ void cWSSAnvil::LoadZombieFromNBT(cEntityList & a_Entities, const cParsedNBT & a bool IsVillagerZombie = ((a_NBT.GetByte(IsVillagerIdx) == 1) ? true : false); - std::auto_ptr Monster(new cZombie(IsVillagerZombie)); + std::unique_ptr Monster(new cZombie(IsVillagerZombie)); if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2666,7 +2666,7 @@ void cWSSAnvil::LoadZombieFromNBT(cEntityList & a_Entities, const cParsedNBT & a void cWSSAnvil::LoadPigZombieFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr Monster(new cZombiePigman()); + std::unique_ptr Monster(new cZombiePigman()); if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; -- cgit v1.2.3 From 95c83abcdb11d285ef409a6ed8900985927e9de0 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 7 Dec 2014 12:00:36 +0100 Subject: Fixed error message in cFinishGenPassiveMobs It would send an error message when trying to spawn mobs in a desert --- src/Generating/FinishGen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index e6732dbd5..e10cb00f8 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -1014,7 +1014,7 @@ void cFinishGenPassiveMobs::GenFinish(cChunkDesc & a_ChunkDesc) eMonsterType RandomMob = GetRandomMob(a_ChunkDesc); if (RandomMob == mtInvalidType) { - LOGWARNING("Attempted to spawn invalid mob type."); + // No mobs here. Don't send an error, because if the biome was a desert it would return mtInvalidType as well. return; } -- cgit v1.2.3 From ba991075910abca0f512c7a77d1fc6af412b1f4d Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 7 Dec 2014 12:03:52 +0100 Subject: Reduced river height Rivers would exceed the water height quite often --- src/Generating/Noise3DGenerator.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Generating/Noise3DGenerator.cpp b/src/Generating/Noise3DGenerator.cpp index 57e23809e..5ed97a945 100644 --- a/src/Generating/Noise3DGenerator.cpp +++ b/src/Generating/Noise3DGenerator.cpp @@ -739,7 +739,7 @@ void cBiomalNoise3DComposable::GetBiomeParams(EMCSBiome a_Biome, NOISE_DATATYPE case biFlowerForest: a_HeightAmp = 0.1f; a_MidPoint = 64; break; case biForest: a_HeightAmp = 0.1f; a_MidPoint = 64; break; case biForestHills: a_HeightAmp = 0.075f; a_MidPoint = 68; break; - case biFrozenRiver: a_HeightAmp = 0.4f; a_MidPoint = 57; break; + case biFrozenRiver: a_HeightAmp = 0.4f; a_MidPoint = 54; break; case biFrozenOcean: a_HeightAmp = 0.12f; a_MidPoint = 45; break; case biIceMountains: a_HeightAmp = 0.075f; a_MidPoint = 68; break; case biIcePlains: a_HeightAmp = 0.3f; a_MidPoint = 62; break; @@ -764,7 +764,7 @@ void cBiomalNoise3DComposable::GetBiomeParams(EMCSBiome a_Biome, NOISE_DATATYPE case biNether: a_HeightAmp = 0.01f; a_MidPoint = 64; break; case biOcean: a_HeightAmp = 0.12f; a_MidPoint = 45; break; case biPlains: a_HeightAmp = 0.3f; a_MidPoint = 62; break; - case biRiver: a_HeightAmp = 0.4f; a_MidPoint = 57; break; + case biRiver: a_HeightAmp = 0.4f; a_MidPoint = 54; break; case biRoofedForest: a_HeightAmp = 0.1f; a_MidPoint = 64; break; case biRoofedForestM: a_HeightAmp = 0.1f; a_MidPoint = 64; break; case biSavanna: a_HeightAmp = 0.3f; a_MidPoint = 62; break; -- cgit v1.2.3 From 3c3cb198f33fd55b9cb20188cc42034b21660d21 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 7 Dec 2014 15:46:27 +0100 Subject: Fixed c++11 branch issues. --- Tools/ProtoProxy/Connection.cpp | 3 ++- src/ClientHandle.cpp | 12 ++++++++---- src/ClientHandle.h | 11 +++++++---- src/FastRandom.cpp | 32 ++++++++++++++++---------------- src/FastRandom.h | 19 +++++++++++-------- src/OSSupport/IsThread.cpp | 20 ++++++++++---------- src/Server.cpp | 3 ++- src/World.cpp | 4 +++- 8 files changed, 59 insertions(+), 45 deletions(-) diff --git a/Tools/ProtoProxy/Connection.cpp b/Tools/ProtoProxy/Connection.cpp index fe61b37d1..fb2d40e5b 100644 --- a/Tools/ProtoProxy/Connection.cpp +++ b/Tools/ProtoProxy/Connection.cpp @@ -436,7 +436,8 @@ bool cConnection::RelayFromClient(void) double cConnection::GetRelativeTime(void) { - return std::chrono::duration_cast(std::chrono::steady_clock::now() - m_BeginTick).count() / 1000; + Int64 msec = std::chrono::duration_cast(std::chrono::steady_clock::now() - m_BeginTick).count(); + return static_cast(msec) / 1000; } diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index d246f6da2..c4a620565 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -38,6 +38,11 @@ /** Maximum number of block change interactions a player can perform per tick - exceeding this causes a kick */ #define MAX_BLOCK_CHANGE_INTERACTIONS 20 +/** The interval for sending pings to clients. +Vanilla sends one ping every 1 second. */ +static const std::chrono::milliseconds PING_TIME_MS = std::chrono::milliseconds(1000); + + @@ -86,7 +91,7 @@ cClientHandle::cClientHandle(const cSocket * a_Socket, int a_ViewDistance) : s_ClientCount++; // Not protected by CS because clients are always constructed from the same thread m_UniqueID = s_ClientCount; - m_LastPingTime = std::chrono::steady_clock::now(); + m_PingStartTime = std::chrono::steady_clock::now(); LOGD("New ClientHandle created at %p", this); } @@ -384,7 +389,7 @@ void cClientHandle::Authenticate(const AString & a_Name, const AString & a_UUID, // Delay the first ping until the client "settles down" // This should fix #889, "BadCast exception, cannot convert bit to fm" error in client - m_LastPingTime = std::chrono::steady_clock::now() + std::chrono::seconds(3); // Send the first KeepAlive packet in 3 seconds + m_PingStartTime = std::chrono::steady_clock::now() + std::chrono::seconds(3); // Send the first KeepAlive packet in 3 seconds cRoot::Get()->GetPluginManager()->CallHookPlayerSpawned(*m_Player); } @@ -1990,12 +1995,11 @@ void cClientHandle::Tick(float a_Dt) // Send a ping packet: if (m_State == csPlaying) { - if ((m_LastPingTime + cClientHandle::PING_TIME_MS <= std::chrono::steady_clock::now())) + if ((m_PingStartTime + PING_TIME_MS <= std::chrono::steady_clock::now())) { m_PingID++; m_PingStartTime = std::chrono::steady_clock::now(); m_Protocol->SendKeepAlive(m_PingID); - m_LastPingTime = m_PingStartTime; } } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 3431e3a71..495348ac3 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -378,12 +378,15 @@ private: /** Seconds since the last packet data was received (updated in Tick(), reset in DataReceived()) */ float m_TimeSinceLastPacket; + /** Duration of the last completed client ping. */ std::chrono::steady_clock::duration m_Ping; - int m_PingID; + + /** ID of the last ping request sent to the client. */ + int m_PingID; + + /** Time of the last ping request sent to the client. */ std::chrono::steady_clock::time_point m_PingStartTime; - std::chrono::steady_clock::time_point m_LastPingTime; - std::chrono::milliseconds PING_TIME_MS = std::chrono::milliseconds(1000); // Vanilla sends 1 per 20 ticks (1 second or every 1000 ms) - + // Values required for block dig animation int m_BlockDigAnimStage; // Current stage of the animation; -1 if not digging int m_BlockDigAnimSpeed; // Current speed of the animation (units ???) diff --git a/src/FastRandom.cpp b/src/FastRandom.cpp index cfafc7486..515dc25ea 100644 --- a/src/FastRandom.cpp +++ b/src/FastRandom.cpp @@ -96,8 +96,8 @@ cFastRandom::cFastRandom(void) : int cFastRandom::NextInt(int a_Range) { - m_IntDistribution = std::uniform_int_distribution<>(0, a_Range - 1); - return m_IntDistribution(m_LinearRand); + std::uniform_int_distribution<> distribution(0, a_Range - 1); + return distribution(m_LinearRand); } @@ -108,8 +108,8 @@ int cFastRandom::NextInt(int a_Range) int cFastRandom::NextInt(int a_Range, int a_Salt) { m_LinearRand.seed(a_Salt); - m_IntDistribution = std::uniform_int_distribution<>(0, a_Range - 1); - return m_IntDistribution(m_LinearRand); + std::uniform_int_distribution<> distribution(0, a_Range - 1); + return distribution(m_LinearRand); } @@ -119,8 +119,8 @@ int cFastRandom::NextInt(int a_Range, int a_Salt) float cFastRandom::NextFloat(float a_Range) { - m_FloatDistribution = std::uniform_real_distribution(0, a_Range - 1); - return m_FloatDistribution(m_LinearRand); + std::uniform_real_distribution distribution(0, a_Range); + return distribution(m_LinearRand); } @@ -131,8 +131,8 @@ float cFastRandom::NextFloat(float a_Range) float cFastRandom::NextFloat(float a_Range, int a_Salt) { m_LinearRand.seed(a_Salt); - m_FloatDistribution = std::uniform_real_distribution(0, a_Range - 1); - return m_FloatDistribution(m_LinearRand); + std::uniform_real_distribution distribution(0, a_Range); + return distribution(m_LinearRand); } @@ -142,8 +142,8 @@ float cFastRandom::NextFloat(float a_Range, int a_Salt) int cFastRandom::GenerateRandomInteger(int a_Begin, int a_End) { - m_IntDistribution = std::uniform_int_distribution<>(a_Begin, a_End - 1); - return m_IntDistribution(m_LinearRand); + std::uniform_int_distribution<> distribution(a_Begin, a_End); + return distribution(m_LinearRand); } @@ -164,8 +164,8 @@ MTRand::MTRand() : int MTRand::randInt(int a_Range) { - m_IntDistribution = std::uniform_int_distribution<>(0, a_Range); - return m_IntDistribution(m_MersenneRand); + std::uniform_int_distribution<> distribution(0, a_Range); + return distribution(m_MersenneRand); } @@ -174,8 +174,8 @@ int MTRand::randInt(int a_Range) int MTRand::randInt() { - m_IntDistribution = std::uniform_int_distribution<>(0, std::numeric_limits::max()); - return m_IntDistribution(m_MersenneRand); + std::uniform_int_distribution<> distribution(0, std::numeric_limits::max()); + return distribution(m_MersenneRand); } @@ -184,8 +184,8 @@ int MTRand::randInt() double MTRand::rand(double a_Range) { - m_DoubleDistribution = std::uniform_real_distribution<>(0, a_Range); - return m_DoubleDistribution(m_MersenneRand); + std::uniform_real_distribution<> distribution(0, a_Range); + return distribution(m_MersenneRand); } diff --git a/src/FastRandom.h b/src/FastRandom.h index 7eecc698a..64a087c97 100644 --- a/src/FastRandom.h +++ b/src/FastRandom.h @@ -34,16 +34,16 @@ public: cFastRandom(void); - /// Returns a random int in the range [0 .. a_Range - 1]; a_Range must be less than 1M + /** Returns a random int in the range [0 .. a_Range - 1]; a_Range must be less than 1M */ int NextInt(int a_Range); - /// Returns a random int in the range [0 .. a_Range - 1]; a_Range must be less than 1M; a_Salt is additional source of randomness + /** Returns a random int in the range [0 .. a_Range - 1]; a_Range must be less than 1M; a_Salt is additional source of randomness */ int NextInt(int a_Range, int a_Salt); - /// Returns a random float in the range [0 .. a_Range]; a_Range must be less than 1M + /** Returns a random float in the range [0 .. a_Range]; a_Range must be less than 1M */ float NextFloat(float a_Range); - /// Returns a random float in the range [0 .. a_Range]; a_Range must be less than 1M; a_Salt is additional source of randomness + /** Returns a random float in the range [0 .. a_Range]; a_Range must be less than 1M; a_Salt is additional source of randomness */ float NextFloat(float a_Range, int a_Salt); /** Returns a random float between 0 and 1. */ @@ -55,8 +55,6 @@ public: private: std::minstd_rand m_LinearRand; - std::uniform_int_distribution<> m_IntDistribution; - std::uniform_real_distribution m_FloatDistribution; }; @@ -69,15 +67,20 @@ public: MTRand(void); + /** Returns a random integer in the range [0 .. a_Range]. */ int randInt(int a_Range); + /** Returns a random integer in the range [0 .. MAX_INT]. */ int randInt(void); + /** Returns a random floating point number in the range [0 .. a_Range]. */ double rand(double a_Range); private: std::mt19937 m_MersenneRand; - std::uniform_int_distribution<> m_IntDistribution; - std::uniform_real_distribution<> m_DoubleDistribution; }; + + + + diff --git a/src/OSSupport/IsThread.cpp b/src/OSSupport/IsThread.cpp index 9c62c89bf..94bed1f56 100644 --- a/src/OSSupport/IsThread.cpp +++ b/src/OSSupport/IsThread.cpp @@ -85,7 +85,7 @@ bool cIsThread::Start(void) } catch (std::system_error & a_Exception) { - LOGERROR("cIsThread::Wait (std::thread) error %i: could not construct thread %s; %s", a_Exception.code().value(), m_ThreadName.c_str(), a_Exception.what()); + LOGERROR("cIsThread::Start error %i: could not construct thread %s; %s", a_Exception.code().value(), m_ThreadName.c_str(), a_Exception.code().message().c_str()); return false; } } @@ -96,6 +96,12 @@ bool cIsThread::Start(void) void cIsThread::Stop(void) { + if (!m_Thread.joinable()) + { + // The thread hasn't been started or has already been joined + return; + } + m_ShouldTerminate = true; Wait(); } @@ -106,10 +112,7 @@ void cIsThread::Stop(void) bool cIsThread::Wait(void) { - #ifdef LOGD // ProtoProxy doesn't have LOGD - LOGD("Waiting for thread %s to finish", m_ThreadName.c_str()); - #endif // LOGD - + LOGD("Waiting for thread %s to finish", m_ThreadName.c_str()); if (m_Thread.joinable()) { try @@ -119,15 +122,12 @@ bool cIsThread::Wait(void) } catch (std::system_error & a_Exception) { - LOGERROR("cIsThread::Wait (std::thread) error %i: could not join thread %s; %s", a_Exception.code().value(), m_ThreadName.c_str(), a_Exception.what()); + LOGERROR("cIsThread::Wait error %i: could not join thread %s; %s", a_Exception.code().value(), m_ThreadName.c_str(), a_Exception.code().message().c_str()); return false; } } - #ifdef LOGD // ProtoProxy doesn't have LOGD - LOGD("Thread %s finished", m_ThreadName.c_str()); - #endif - + LOGD("Thread %s finished", m_ThreadName.c_str()); return true; } diff --git a/src/Server.cpp b/src/Server.cpp index db1522602..d6163df7e 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -78,7 +78,8 @@ void cServer::cTickThread::Execute(void) while (!m_ShouldTerminate) { auto NowTime = std::chrono::steady_clock::now(); - m_ShouldTerminate = !m_Server.Tick(static_cast(std::chrono::duration_cast(NowTime - LastTime).count())); + auto msec = std::chrono::duration_cast(NowTime - LastTime).count(); + m_ShouldTerminate = !m_Server.Tick(static_cast(msec)); auto TickTime = std::chrono::steady_clock::now() - NowTime; if (TickTime < msPerTick) diff --git a/src/World.cpp b/src/World.cpp index 14010b8b1..91e1199ee 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -239,7 +239,9 @@ void cWorld::cTickThread::Execute(void) while (!m_ShouldTerminate) { auto NowTime = std::chrono::steady_clock::now(); - m_World.Tick(static_cast(std::chrono::duration_cast(NowTime - LastTime).count()), std::chrono::duration_cast>(TickTime).count()); + auto msec = std::chrono::duration_cast(NowTime - LastTime).count(); + auto LastTickMsec = std::chrono::duration_cast>(TickTime).count(); + m_World.Tick(static_cast(msec), LastTickMsec); TickTime = std::chrono::steady_clock::now() - NowTime; if (TickTime < msPerTick) -- cgit v1.2.3 From e08331a24b1c6bb2994c8dabfe5911e72c14f974 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 7 Dec 2014 16:14:27 +0100 Subject: Fixed crash on server stop. The entity destructors called through chunkmap destructor and chunk destructor were accessing the world which was in an already invalid state (half-destroyed). Fixed by destroying chunkmap explicitly and providing a nullptr check in the HasEntity() function. --- src/World.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/World.cpp b/src/World.cpp index 91e1199ee..e73dcb915 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -346,6 +346,10 @@ cWorld::~cWorld() Serializer.Save(); m_MapManager.SaveMapData(); + + // Explicitly destroy the chunkmap, so that it's guaranteed to be destroyed before the other internals + // This fixes crashes on stopping the server, because chunk destructor deletes entities and those access the world. + m_ChunkMap.reset(); } @@ -3122,6 +3126,11 @@ bool cWorld::HasEntity(int a_UniqueID) } // Check if the entity is in the chunkmap: + if (m_ChunkMap.get() == nullptr) + { + // Chunkmap has already been destroyed, there are no entities anymore. + return false; + } return m_ChunkMap->HasEntity(a_UniqueID); } -- cgit v1.2.3 From 77cf65779043312087a7813a7492a71c077555bc Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 7 Dec 2014 17:28:55 +0100 Subject: Fixed format warning. --- src/Logger.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Logger.cpp b/src/Logger.cpp index c4adf4b48..292622a46 100644 --- a/src/Logger.cpp +++ b/src/Logger.cpp @@ -45,12 +45,12 @@ void cLogger::LogSimple(AString a_Message, eLogLevel a_LogLevel) AString Line; #ifdef _DEBUG - Printf(Line, "[%04lx|%02d:%02d:%02d] %s\n", std::hash()(std::this_thread::get_id()), timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, a_Message.c_str()); + Printf(Line, "[%04llx|%02d:%02d:%02d] %s\n", static_cast(std::hash()(std::this_thread::get_id())), timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, a_Message.c_str()); #else Printf(Line, "[%02d:%02d:%02d] %s\n", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, a_Message.c_str()); #endif - + cCSLock Lock(m_CriticalSection); for (size_t i = 0; i < m_LogListeners.size(); i++) { -- cgit v1.2.3