From 5c99f3fadafa03664da4a179af28ed4db4980048 Mon Sep 17 00:00:00 2001
From: Howaner
Date: Wed, 17 Dec 2014 17:28:24 +0100
Subject: Fixed eMonsterType lua bugs.
---
src/Mobs/MonsterTypes.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/Mobs/MonsterTypes.h b/src/Mobs/MonsterTypes.h
index dc6dd3992..3175f0606 100644
--- a/src/Mobs/MonsterTypes.h
+++ b/src/Mobs/MonsterTypes.h
@@ -37,6 +37,7 @@ enum eMonsterType
mtWolf = E_META_SPAWN_EGG_WOLF,
mtZombie = E_META_SPAWN_EGG_ZOMBIE,
mtZombiePigman = E_META_SPAWN_EGG_ZOMBIE_PIGMAN,
+ mtMax = 120,
} ;
// tolua_end
--
cgit v1.2.3
From fff108f20a8962f6690a9dff45176c7f31c8cf01 Mon Sep 17 00:00:00 2001
From: Howaner
Date: Wed, 17 Dec 2014 19:16:35 +0100
Subject: Added comment.
---
src/Mobs/MonsterTypes.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Mobs/MonsterTypes.h b/src/Mobs/MonsterTypes.h
index 3175f0606..6886bd51a 100644
--- a/src/Mobs/MonsterTypes.h
+++ b/src/Mobs/MonsterTypes.h
@@ -37,7 +37,7 @@ enum eMonsterType
mtWolf = E_META_SPAWN_EGG_WOLF,
mtZombie = E_META_SPAWN_EGG_ZOMBIE,
mtZombiePigman = E_META_SPAWN_EGG_ZOMBIE_PIGMAN,
- mtMax = 120,
+ mtMax = 120, // This is just a hotfix for #http://forum.mc-server.org/showthread.php?tid=1616. Tolua is too bad to find the highest value, so this is needed.
} ;
// tolua_end
--
cgit v1.2.3
From c2926f8de1709d660cdca130f95a24623e2007c2 Mon Sep 17 00:00:00 2001
From: Howaner
Date: Wed, 17 Dec 2014 20:08:55 +0100
Subject: derp
---
src/Mobs/MonsterTypes.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Mobs/MonsterTypes.h b/src/Mobs/MonsterTypes.h
index 6886bd51a..bbe9e0471 100644
--- a/src/Mobs/MonsterTypes.h
+++ b/src/Mobs/MonsterTypes.h
@@ -37,7 +37,7 @@ enum eMonsterType
mtWolf = E_META_SPAWN_EGG_WOLF,
mtZombie = E_META_SPAWN_EGG_ZOMBIE,
mtZombiePigman = E_META_SPAWN_EGG_ZOMBIE_PIGMAN,
- mtMax = 120, // This is just a hotfix for #http://forum.mc-server.org/showthread.php?tid=1616. Tolua is too bad to find the highest value, so this is needed.
+ mtMax = 120, // This is just a hotfix for http://forum.mc-server.org/showthread.php?tid=1616. Tolua is too bad to find the highest value, so this is needed.
} ;
// tolua_end
--
cgit v1.2.3
From f6cb0e4cb26d4f9db6b15cbd6af7d69c1d5dcc36 Mon Sep 17 00:00:00 2001
From: Julian Laubstein
Date: Wed, 17 Dec 2014 23:18:10 +0100
Subject: Added itemblacklist to gitignore
---
.gitignore | 1 +
1 file changed, 1 insertion(+)
diff --git a/.gitignore b/.gitignore
index b85b172cb..c7f032b00 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,7 @@ nbproject/
ipch/
Win32/
MCServer/MCServer
+MCServer/itemblacklist
ChunkWorxSave.ini
doxy/
Profiling
--
cgit v1.2.3
From dd1df3b6f740fad699855de26d3f7f512008671b Mon Sep 17 00:00:00 2001
From: Tiger Wang
Date: Thu, 18 Dec 2014 00:22:46 +0000
Subject: Fix repeater unpowering
---
src/Simulator/IncrementalRedstoneSimulator.cpp | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp
index 8a56287a8..544a0689d 100644
--- a/src/Simulator/IncrementalRedstoneSimulator.cpp
+++ b/src/Simulator/IncrementalRedstoneSimulator.cpp
@@ -2074,9 +2074,11 @@ void cIncrementalRedstoneSimulator::SetSourceUnpowered(int a_RelSourceX, int a_R
for (const auto & itr : BlocksPotentiallyUnpowered)
{
- if (!AreCoordsPowered(itr.x, itr.y, itr.z))
+ auto Neighbour = a_Chunk->GetRelNeighborChunk(itr.x, itr.z);
+ if (!AreCoordsPowered(itr.x, itr.y, itr.z) && (Neighbour->GetBlock(itr) != E_BLOCK_REDSTONE_REPEATER_ON))
{
- SetSourceUnpowered(itr.x, itr.y, itr.z, a_Chunk->GetRelNeighborChunk(itr.x, itr.z));
+ // Repeaters time themselves with regards to unpowering; ensure we don't do it for them
+ SetSourceUnpowered(itr.x, itr.y, itr.z, Neighbour);
}
}
}
--
cgit v1.2.3
From c836b52dd1b8d6a2999721f235e6c2b6079b266c Mon Sep 17 00:00:00 2001
From: Masy98
Date: Thu, 18 Dec 2014 19:30:32 +0100
Subject: Added Entity Guardian
---
MCServer/Plugins/ProtectionAreas | 2 +-
Tools/AnvilStats/Utils.cpp | 1 +
Tools/AnvilStats/Utils.h | 1 +
src/BlockID.h | 1 +
src/Items/ItemSpawnEgg.h | 1 +
src/MobSpawner.cpp | 6 +++
src/Mobs/CMakeLists.txt | 2 +
src/Mobs/Guardian.cpp | 65 +++++++++++++++++++++++++++++++++
src/Mobs/Guardian.h | 31 ++++++++++++++++
src/Mobs/IncludeAllMonsters.h | 1 +
src/Mobs/Monster.cpp | 4 ++
src/Mobs/Monster.h | 2 +-
src/Mobs/MonsterTypes.h | 1 +
src/World.cpp | 2 +-
src/WorldStorage/NBTChunkSerializer.cpp | 2 +
src/WorldStorage/WSSAnvil.cpp | 24 ++++++++++++
src/WorldStorage/WSSAnvil.h | 1 +
17 files changed, 144 insertions(+), 3 deletions(-)
create mode 100644 src/Mobs/Guardian.cpp
create mode 100644 src/Mobs/Guardian.h
diff --git a/MCServer/Plugins/ProtectionAreas b/MCServer/Plugins/ProtectionAreas
index 624580e5b..7765048fa 160000
--- a/MCServer/Plugins/ProtectionAreas
+++ b/MCServer/Plugins/ProtectionAreas
@@ -1 +1 @@
-Subproject commit 624580e5b522ba2799dfe5b5902b4002b1a8da3e
+Subproject commit 7765048fa740b8f119db72a4ccc546504f86b2ab
diff --git a/Tools/AnvilStats/Utils.cpp b/Tools/AnvilStats/Utils.cpp
index d7543cb4c..f5b3b58fb 100644
--- a/Tools/AnvilStats/Utils.cpp
+++ b/Tools/AnvilStats/Utils.cpp
@@ -26,6 +26,7 @@ struct
{entEnderman, "Enderman"},
{entGhast, "Ghast"},
{entGiant, "Giant"},
+ {entGuardian, "Guardian"},
{entLavaSlime, "LavaSlime"},
{entMushroomCow, "MushroomCow"},
{entOzelot, "Ozelot"},
diff --git a/Tools/AnvilStats/Utils.h b/Tools/AnvilStats/Utils.h
index ab2d7166c..4c4e89f26 100644
--- a/Tools/AnvilStats/Utils.h
+++ b/Tools/AnvilStats/Utils.h
@@ -25,6 +25,7 @@ enum eEntityType
entEnderman,
entGhast,
entGiant,
+ entGuardian,
entLavaSlime,
entMushroomCow,
entOzelot,
diff --git a/src/BlockID.h b/src/BlockID.h
index 8f2cee02e..bfb6b8d6d 100644
--- a/src/BlockID.h
+++ b/src/BlockID.h
@@ -959,6 +959,7 @@ enum
E_META_SPAWN_EGG_WITHER = 64,
E_META_SPAWN_EGG_BAT = 65,
E_META_SPAWN_EGG_WITCH = 66,
+ E_META_SPAWN_EGG_GUARDIAN = 68,
E_META_SPAWN_EGG_PIG = 90,
E_META_SPAWN_EGG_SHEEP = 91,
E_META_SPAWN_EGG_COW = 92,
diff --git a/src/Items/ItemSpawnEgg.h b/src/Items/ItemSpawnEgg.h
index 617ecd808..2f28ec6eb 100644
--- a/src/Items/ItemSpawnEgg.h
+++ b/src/Items/ItemSpawnEgg.h
@@ -64,6 +64,7 @@ public:
case E_META_SPAWN_EGG_CREEPER: return mtCreeper;
case E_META_SPAWN_EGG_ENDERMAN: return mtEnderman;
case E_META_SPAWN_EGG_GHAST: return mtGhast;
+ case E_META_SPAWN_EGG_GUARDIAN: return mtGuardian;
case E_META_SPAWN_EGG_HORSE: return mtHorse;
case E_META_SPAWN_EGG_MAGMA_CUBE: return mtMagmaCube;
case E_META_SPAWN_EGG_MOOSHROOM: return mtMooshroom;
diff --git a/src/MobSpawner.cpp b/src/MobSpawner.cpp
index ee9e569a7..bd34d8fcd 100644
--- a/src/MobSpawner.cpp
+++ b/src/MobSpawner.cpp
@@ -83,6 +83,7 @@ eMonsterType cMobSpawner::ChooseMobType(EMCSBiome a_Biome)
addIfAllowed(mtSkeleton, allowedMobs);
addIfAllowed(mtCreeper, allowedMobs);
addIfAllowed(mtSquid, allowedMobs);
+ addIfAllowed(mtGuardian, allowedMobs);
if ((a_Biome != biDesert) && (a_Biome != biBeach) && (a_Biome != biOcean))
{
@@ -144,6 +145,11 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R
switch (a_MobType)
{
+ case mtGuardian:
+ {
+ return IsBlockWater(TargetBlock) && (a_RelY >= 45) && (a_RelY <= 62);
+ }
+
case mtSquid:
{
return IsBlockWater(TargetBlock) && (a_RelY >= 45) && (a_RelY <= 62);
diff --git a/src/Mobs/CMakeLists.txt b/src/Mobs/CMakeLists.txt
index bbbb9287a..c1ac2de32 100644
--- a/src/Mobs/CMakeLists.txt
+++ b/src/Mobs/CMakeLists.txt
@@ -16,6 +16,7 @@ SET (SRCS
Enderman.cpp
Ghast.cpp
Giant.cpp
+ Guardian.cpp
Horse.cpp
IronGolem.cpp
MagmaCube.cpp
@@ -49,6 +50,7 @@ SET (HDRS
Enderman.h
Ghast.h
Giant.h
+ Guardian.h
Horse.h
IncludeAllMonsters.h
IronGolem.h
diff --git a/src/Mobs/Guardian.cpp b/src/Mobs/Guardian.cpp
new file mode 100644
index 000000000..166057865
--- /dev/null
+++ b/src/Mobs/Guardian.cpp
@@ -0,0 +1,65 @@
+
+#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
+
+#include "Guardian.h"
+#include "../Vector3.h"
+#include "../Chunk.h"
+
+
+
+
+
+cGuardian::cGuardian(void) :
+ super("Guardian", mtGuardian, "mob.guardian.idle", "mob.guardian.death", 0.95, 0.95)
+{
+}
+
+
+
+
+
+void cGuardian::GetDrops(cItems & a_Drops, cEntity * a_Killer)
+{
+ // Drops 0-3 Ink Sacs
+ int LootingLevel = 0;
+ if (a_Killer != nullptr)
+ {
+ LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting);
+ }
+ AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_PRISMARINE_SHARD);
+ AddRandomDropItem(a_Drops, 0, 1 + LootingLevel, E_ITEM_RAW_FISH);
+ AddRandomDropItem(a_Drops, 0, 1 + LootingLevel, E_ITEM_PRISMARINE_CRYSTALS); // ToDo: Prismarine Crystals only drop if the raw fish drop is 0
+}
+
+
+
+
+
+void cGuardian::Tick(float a_Dt, cChunk & a_Chunk)
+{
+ // We must first process current location, and only then tick, otherwise we risk processing a location in a chunk
+ // that is not where the entity currently resides (FS #411)
+
+ Vector3d Pos = GetPosition();
+
+ // TODO: Not a real behavior, but cool :D
+ int RelY = (int)floor(Pos.y);
+ if ((RelY < 0) || (RelY >= cChunkDef::Height))
+ {
+ return;
+ }
+ int RelX = (int)floor(Pos.x) - a_Chunk.GetPosX() * cChunkDef::Width;
+ int RelZ = (int)floor(Pos.z) - a_Chunk.GetPosZ() * cChunkDef::Width;
+ BLOCKTYPE BlockType;
+ if (a_Chunk.UnboundedRelGetBlockType(RelX, RelY, RelZ, BlockType) && !IsBlockWater(BlockType) && !IsOnFire())
+ {
+ // Burn for 10 ticks, then decide again
+ StartBurning(10);
+ }
+
+ super::Tick(a_Dt, a_Chunk);
+}
+
+
+
+
diff --git a/src/Mobs/Guardian.h b/src/Mobs/Guardian.h
new file mode 100644
index 000000000..50c034036
--- /dev/null
+++ b/src/Mobs/Guardian.h
@@ -0,0 +1,31 @@
+
+#pragma once
+
+#include "AggressiveMonster.h"
+
+
+
+
+
+class cGuardian :
+ public cAggressiveMonster
+{
+ typedef cAggressiveMonster super;
+
+public:
+ cGuardian();
+
+ virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
+
+ CLASS_PROTODEF(cGuardian)
+
+ virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override;
+
+ // Guardians do not drown (or float)
+ virtual void HandleAir(void) override {}
+ virtual void SetSwimState(cChunk & a_Chunk) override {}
+} ;
+
+
+
+
diff --git a/src/Mobs/IncludeAllMonsters.h b/src/Mobs/IncludeAllMonsters.h
index 3460db993..f5eb9dcc3 100644
--- a/src/Mobs/IncludeAllMonsters.h
+++ b/src/Mobs/IncludeAllMonsters.h
@@ -8,6 +8,7 @@
#include "EnderDragon.h"
#include "Ghast.h"
#include "Giant.h"
+#include "Guardian.h"
#include "Horse.h"
#include "IronGolem.h"
#include "MagmaCube.h"
diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp
index 7b8f763af..963ca628c 100644
--- a/src/Mobs/Monster.cpp
+++ b/src/Mobs/Monster.cpp
@@ -38,6 +38,7 @@ static const struct
{mtEnderman, "enderman", "Enderman"},
{mtEnderDragon, "enderdragon", "EnderDragon"},
{mtGhast, "ghast", "Ghast"},
+ {mtGuardian, "guardian", "Guardian"},
{mtHorse, "horse", "EntityHorse"},
{mtIronGolem, "irongolem", "VillagerGolem"},
{mtMagmaCube, "magmacube", "LavaSlime"},
@@ -513,6 +514,7 @@ void cMonster::KilledBy(TakeDamageInfo & a_TDI)
case mtCreeper:
case mtEnderman:
case mtGhast:
+ case mtGuardian:
case mtSilverfish:
case mtSkeleton:
case mtSpider:
@@ -842,6 +844,7 @@ cMonster::eFamily cMonster::FamilyFromType(eMonsterType a_Type)
case mtEnderman: return mfHostile;
case mtGhast: return mfHostile;
case mtGiant: return mfNoSpawn;
+ case mtGuardian: return mfNoSpawn; // Just because they have special spawning conditions. If Watertemples have been added, this needs to be edited!
case mtHorse: return mfPassive;
case mtIronGolem: return mfPassive;
case mtMagmaCube: return mfHostile;
@@ -955,6 +958,7 @@ cMonster * cMonster::NewMonsterFromType(eMonsterType a_MobType)
case mtEnderman: toReturn = new cEnderman(); break;
case mtGhast: toReturn = new cGhast(); break;
case mtGiant: toReturn = new cGiant(); break;
+ case mtGuardian: toReturn = new cGuardian(); break;
case mtIronGolem: toReturn = new cIronGolem(); break;
case mtMooshroom: toReturn = new cMooshroom(); break;
case mtOcelot: toReturn = new cOcelot(); break;
diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h
index f04e45ac6..fb1bc550d 100644
--- a/src/Mobs/Monster.h
+++ b/src/Mobs/Monster.h
@@ -30,7 +30,7 @@ public:
mfHostile = 0, // Spider, Zombies ...
mfPassive = 1, // Cows, Pigs
mfAmbient = 2, // Bats
- mfWater = 3, // Squid
+ mfWater = 3, // Squid, Guardian
mfNoSpawn,
mfUnhandled, // Nothing. Be sure this is the last and the others are in order
diff --git a/src/Mobs/MonsterTypes.h b/src/Mobs/MonsterTypes.h
index dc6dd3992..50fcf971a 100644
--- a/src/Mobs/MonsterTypes.h
+++ b/src/Mobs/MonsterTypes.h
@@ -18,6 +18,7 @@ enum eMonsterType
mtEnderman = E_META_SPAWN_EGG_ENDERMAN,
mtGhast = E_META_SPAWN_EGG_GHAST,
mtGiant = E_META_SPAWN_EGG_GIANT,
+ mtGuardian = E_META_SPAWN_EGG_GUARDIAN,
mtHorse = E_META_SPAWN_EGG_HORSE,
mtIronGolem = E_META_SPAWN_EGG_IRON_GOLEM,
mtMagmaCube = E_META_SPAWN_EGG_MAGMA_CUBE,
diff --git a/src/World.cpp b/src/World.cpp
index 1bee6e344..99701e11b 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -776,7 +776,7 @@ void cWorld::InitialiseAndLoadMobSpawningValues(cIniFile & a_IniFile)
AString DefaultMonsters;
switch (m_Dimension)
{
- case dimOverworld: DefaultMonsters = "bat, cavespider, chicken, cow, creeper, enderman, horse, mooshroom, ocelot, pig, sheep, silverfish, skeleton, slime, spider, squid, wolf, zombie"; break;
+ case dimOverworld: DefaultMonsters = "bat, cavespider, chicken, cow, creeper, enderman, guardian, horse, mooshroom, ocelot, pig, sheep, silverfish, skeleton, slime, spider, squid, wolf, zombie"; break;
case dimNether: DefaultMonsters = "blaze, ghast, magmacube, skeleton, zombie, zombiepigman"; break;
case dimEnd: DefaultMonsters = "enderman"; break;
case dimNotSet: ASSERT(!"Dimension not set"); break;
diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp
index 432e122b5..9d8e20b0b 100644
--- a/src/WorldStorage/NBTChunkSerializer.cpp
+++ b/src/WorldStorage/NBTChunkSerializer.cpp
@@ -495,6 +495,7 @@ void cNBTChunkSerializer::AddMonsterEntity(cMonster * a_Monster)
case mtEnderman: EntityClass = "Enderman"; break;
case mtGhast: EntityClass = "Ghast"; break;
case mtGiant: EntityClass = "Giant"; break;
+ case mtGuardian: EntityClass = "Guardian"; break;
case mtHorse: EntityClass = "Horse"; break;
case mtIronGolem: EntityClass = "VillagerGolem"; break;
case mtMagmaCube: EntityClass = "LavaSlime"; break;
@@ -627,6 +628,7 @@ void cNBTChunkSerializer::AddMonsterEntity(cMonster * a_Monster)
case mtEnderDragon:
case mtGhast:
case mtGiant:
+ case mtGuardian:
case mtIronGolem:
case mtMooshroom:
case mtOcelot:
diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp
index af65db700..a045497bc 100755
--- a/src/WorldStorage/WSSAnvil.cpp
+++ b/src/WorldStorage/WSSAnvil.cpp
@@ -1410,6 +1410,10 @@ void cWSSAnvil::LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a
{
LoadGiantFromNBT(a_Entities, a_NBT, a_EntityTagIdx);
}
+ else if (strncmp(a_IDTag, "Guardian", a_IDTagLength) == 0)
+ {
+ LoadGuardianFromNBT(a_Entities, a_NBT, a_EntityTagIdx);
+ }
else if (strncmp(a_IDTag, "Horse", a_IDTagLength) == 0)
{
LoadHorseFromNBT(a_Entities, a_NBT, a_EntityTagIdx);
@@ -2197,6 +2201,26 @@ void cWSSAnvil::LoadGiantFromNBT(cEntityList & a_Entities, const cParsedNBT & a_
+void cWSSAnvil::LoadGuardianFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx)
+{
+ std::unique_ptr Monster(new cGuardian());
+ if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
+ {
+ return;
+ }
+
+ if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
+ {
+ return;
+ }
+
+ a_Entities.push_back(Monster.release());
+}
+
+
+
+
+
void cWSSAnvil::LoadHorseFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx)
{
int TypeIdx = a_NBT.FindChildByName(a_TagIdx, "Type");
diff --git a/src/WorldStorage/WSSAnvil.h b/src/WorldStorage/WSSAnvil.h
index 974ba932e..7bcdd259e 100755
--- a/src/WorldStorage/WSSAnvil.h
+++ b/src/WorldStorage/WSSAnvil.h
@@ -191,6 +191,7 @@ protected:
void LoadEndermanFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadGhastFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadGiantFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
+ void LoadGuardianFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadHorseFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadIronGolemFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadMagmaCubeFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
--
cgit v1.2.3
From f09c6701eb9126b627503bc301084ffb4039fabd Mon Sep 17 00:00:00 2001
From: Masy98
Date: Thu, 18 Dec 2014 20:44:39 +0100
Subject: Guardian can now spawn if wanted!?
---
src/Mobs/Monster.cpp | 2 +-
src/World.cpp | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp
index 963ca628c..3d174677c 100644
--- a/src/Mobs/Monster.cpp
+++ b/src/Mobs/Monster.cpp
@@ -844,7 +844,7 @@ cMonster::eFamily cMonster::FamilyFromType(eMonsterType a_Type)
case mtEnderman: return mfHostile;
case mtGhast: return mfHostile;
case mtGiant: return mfNoSpawn;
- case mtGuardian: return mfNoSpawn; // Just because they have special spawning conditions. If Watertemples have been added, this needs to be edited!
+ case mtGuardian: return mfWater; // Just because they have special spawning conditions. If Watertemples have been added, this needs to be edited!
case mtHorse: return mfPassive;
case mtIronGolem: return mfPassive;
case mtMagmaCube: return mfHostile;
diff --git a/src/World.cpp b/src/World.cpp
index b3d34b48c..69b39f831 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -776,7 +776,7 @@ void cWorld::InitialiseAndLoadMobSpawningValues(cIniFile & a_IniFile)
AString DefaultMonsters;
switch (m_Dimension)
{
- case dimOverworld: DefaultMonsters = "bat, cavespider, chicken, cow, creeper, enderman, guardian, horse, mooshroom, ocelot, pig, sheep, silverfish, skeleton, slime, spider, squid, wolf, zombie"; break;
+ case dimOverworld: DefaultMonsters = "bat, cavespider, chicken, cow, creeper, enderman, horse, mooshroom, ocelot, pig, sheep, silverfish, skeleton, slime, spider, squid, wolf, zombie"; break;
case dimNether: DefaultMonsters = "blaze, ghast, magmacube, skeleton, zombie, zombiepigman"; break;
case dimEnd: DefaultMonsters = "enderman"; break;
case dimNotSet: ASSERT(!"Dimension not set"); break;
--
cgit v1.2.3
From 5cfb6063c37243477ea79319706dae7cdde27ab2 Mon Sep 17 00:00:00 2001
From: Masy98
Date: Fri, 19 Dec 2014 16:06:43 +0100
Subject: Fixed Guardians size and health
---
MCServer/Plugins/ProtectionAreas | 2 +-
MCServer/monsters.ini | 7 +++++++
src/Mobs/Guardian.cpp | 2 +-
3 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/MCServer/Plugins/ProtectionAreas b/MCServer/Plugins/ProtectionAreas
index 7765048fa..624580e5b 160000
--- a/MCServer/Plugins/ProtectionAreas
+++ b/MCServer/Plugins/ProtectionAreas
@@ -1 +1 @@
-Subproject commit 7765048fa740b8f119db72a4ccc546504f86b2ab
+Subproject commit 624580e5b522ba2799dfe5b5902b4002b1a8da3e
diff --git a/MCServer/monsters.ini b/MCServer/monsters.ini
index c4bc8c810..70c845b5c 100644
--- a/MCServer/monsters.ini
+++ b/MCServer/monsters.ini
@@ -192,3 +192,10 @@ AttackDamage=0.0
SightDistance=25.0
MaxHealth=6
+[Guardian]
+AttackRange=2.0
+AttackRate=1
+AttackDamage=9.0
+SightDistance=25.0
+MaxHealth=30
+
diff --git a/src/Mobs/Guardian.cpp b/src/Mobs/Guardian.cpp
index 166057865..d69ee1683 100644
--- a/src/Mobs/Guardian.cpp
+++ b/src/Mobs/Guardian.cpp
@@ -10,7 +10,7 @@
cGuardian::cGuardian(void) :
- super("Guardian", mtGuardian, "mob.guardian.idle", "mob.guardian.death", 0.95, 0.95)
+ super("Guardian", mtGuardian, "mob.guardian.idle", "mob.guardian.death", 0.875, 0.8)
{
}
--
cgit v1.2.3
From 6e8e1c6d8da3d5a0f5ca39f6f18d88c2ca6c1e71 Mon Sep 17 00:00:00 2001
From: Masy98
Date: Sat, 20 Dec 2014 10:31:34 +0100
Subject: Added Rabbits
---
MCServer/monsters.ini | 196 +++++++++++++++++---------------
Tools/AnvilStats/Utils.cpp | 1 +
Tools/AnvilStats/Utils.h | 1 +
src/BlockID.h | 1 +
src/Items/ItemSpawnEgg.h | 1 +
src/MobSpawner.cpp | 2 +
src/Mobs/IncludeAllMonsters.h | 1 +
src/Mobs/Monster.cpp | 4 +
src/Mobs/MonsterTypes.h | 1 +
src/Mobs/Rabbit.cpp | 38 +++++++
src/Mobs/Rabbit.h | 24 ++++
src/WorldStorage/NBTChunkSerializer.cpp | 2 +
src/WorldStorage/WSSAnvil.cpp | 24 ++++
src/WorldStorage/WSSAnvil.h | 1 +
14 files changed, 205 insertions(+), 92 deletions(-)
create mode 100644 src/Mobs/Rabbit.cpp
create mode 100644 src/Mobs/Rabbit.h
diff --git a/MCServer/monsters.ini b/MCServer/monsters.ini
index 70c845b5c..af1938e3e 100644
--- a/MCServer/monsters.ini
+++ b/MCServer/monsters.ini
@@ -1,44 +1,52 @@
-[Spider]
+[Bat]
AttackRange=2.0
AttackRate=1
-AttackDamage=2.0
+AttackDamage=0.0
SightDistance=25.0
-MaxHealth=16
+MaxHealth=6
-[Chicken]
+[Blaze]
+AttackRange=15.0
+AttackRate=1
+AttackDamage=6.0
+SightDistance=25.0
+MaxHealth=20
+IsFireproof=1
+
+[CaveSpider]
AttackRange=2.0
AttackRate=1
-AttackDamage=1.0
+AttackDamage=2.0
SightDistance=25.0
-MaxHealth=4
+MaxHealth=12
-[Cow]
+[Chicken]
AttackRange=2.0
AttackRate=1
-AttackDamage=1.0
+AttackDamage=0.0
SightDistance=25.0
-MaxHealth=10
+MaxHealth=4
-[Pig]
+[Cow]
AttackRange=2.0
AttackRate=1
-AttackDamage=1.0
+AttackDamage=0.0
SightDistance=25.0
MaxHealth=10
-[Sheep]
-AttackRange=2.0
+[Creeper]
+AttackRange=3.0
AttackRate=1
-AttackDamage=1.0
+AttackDamage=0.0
SightDistance=25.0
-MaxHealth=8
+MaxHealth=20
-[Squid]
+[EnderDragon]
AttackRange=2.0
AttackRate=1
-AttackDamage=1.0
+AttackDamage=6.0
SightDistance=25.0
-MaxHealth=10
+MaxHealth=200
[Enderman]
AttackRange=2.0
@@ -47,27 +55,6 @@ AttackDamage=4.0
SightDistance=64.0
MaxHealth=40
-[ZombiePigman]
-AttackRange=2.0
-AttackRate=1
-AttackDamage=7.0
-SightDistance=25.0
-MaxHealth=20
-IsFireproof=1
-
-[CaveSpider]
-AttackRange=2.0
-AttackRate=1
-AttackDamage=2.0
-SightDistance=25.0
-MaxHealth=12
-
-[Creeper]
-AttackRange=3.0
-AttackRate=1
-AttackDamage=0.0
-SightDistance=25.0
-MaxHealth=20
[Ghast]
AttackRange=50.0
@@ -77,125 +64,150 @@ SightDistance=50.0
MaxHealth=10
IsFireproof=1
-[Silverfish]
+[Giant]
AttackRange=2.0
AttackRate=1
-AttackDamage=1.0
+AttackDamage=6.0
SightDistance=25.0
-MaxHealth=8
-
-[Skeleton]
-AttackRange=15.0
-AttackRate=1
-SightDistance=40.0
-MaxHealth=20
+MaxHealth=100
-[Slime]
+[Guardian]
AttackRange=2.0
-AttackRate=1
-AttackDamage=4.0
+AttackRate=1
+AttackDamage=9.0
SightDistance=25.0
-MaxHealth=16
+MaxHealth=30
-[Zombie]
+[Horse]
AttackRange=2.0
AttackRate=1
-AttackDamage=4.0
+AttackDamage=6.0
SightDistance=25.0
-MaxHealth=20
+MaxHealth=30
-[Wolf]
+[IronGolem]
AttackRange=2.0
AttackRate=1
-AttackDamage=4.0
+AttackDamage=6.0
SightDistance=25.0
-MaxHealth=20
+MaxHealth=100
-[Blaze]
-AttackRange=15.0
+[MagmaCube]
+AttackRange=2.0
AttackRate=1
AttackDamage=6.0
SightDistance=25.0
-MaxHealth=20
+MaxHealth=16
IsFireproof=1
-[Villager]
+[Mooshroom]
AttackRange=2.0
AttackRate=1
AttackDamage=0.0
SightDistance=25.0
-MaxHealth=20
-IsFireproof=0
+MaxHealth=10
-[Witch]
+[Ocelot]
AttackRange=2.0
AttackRate=1
AttackDamage=0.0
SightDistance=25.0
-MaxHealth=26
-
+MaxHealth=10
-[Ocelot]
+[Pig]
AttackRange=2.0
AttackRate=1
AttackDamage=0.0
SightDistance=25.0
MaxHealth=10
-[Mooshroom]
+[Rabbit]
AttackRange=2.0
AttackRate=1
AttackDamage=0.0
SightDistance=25.0
MaxHealth=10
-[MagmaCube]
+[Sheep]
AttackRange=2.0
AttackRate=1
-AttackDamage=6.0
+AttackDamage=0.0
SightDistance=25.0
-MaxHealth=16
-IsFireproof=1
+MaxHealth=8
-[Horse]
+[Silverfish]
AttackRange=2.0
AttackRate=1
-AttackDamage=6.0
+AttackDamage=1.0
SightDistance=25.0
-MaxHealth=30
+MaxHealth=8
-[EnderDragon]
+[Skeleton]
+AttackRange=15.0
+AttackRate=1
+SightDistance=40.0
+MaxHealth=20
+
+[Slime]
AttackRange=2.0
AttackRate=1
-AttackDamage=6.0
+AttackDamage=4.0
SightDistance=25.0
-MaxHealth=200
+MaxHealth=16
-[Giant]
+[SnowGolem]
AttackRange=2.0
AttackRate=1
-AttackDamage=6.0
+AttackDamage=0.0
SightDistance=25.0
-MaxHealth=100
+MaxHealth=4
-[IronGolem]
+[Spider]
+AttackRange=2.0
+AttackRate=1
+AttackDamage=2.0
+SightDistance=25.0
+MaxHealth=16
+
+[Squid]
AttackRange=2.0
AttackRate=1
-AttackDamage=6.0
+AttackDamage=0.0
SightDistance=25.0
-MaxHealth=100
+MaxHealth=10
-[Bat]
+[Villager]
AttackRange=2.0
-AttackRate=1
+AttackRate=1
AttackDamage=0.0
SightDistance=25.0
-MaxHealth=6
+MaxHealth=20
-[Guardian]
+[Witch]
AttackRange=2.0
-AttackRate=1
-AttackDamage=9.0
+AttackRate=1
+AttackDamage=0.0
SightDistance=25.0
-MaxHealth=30
+MaxHealth=26
+
+[Wolf]
+AttackRange=2.0
+AttackRate=1
+AttackDamage=4.0
+SightDistance=25.0
+MaxHealth=20
+
+[Zombie]
+AttackRange=2.0
+AttackRate=1
+AttackDamage=4.0
+SightDistance=25.0
+MaxHealth=20
+[ZombiePigman]
+AttackRange=2.0
+AttackRate=1
+AttackDamage=7.0
+SightDistance=25.0
+MaxHealth=20
+IsFireproof=1
diff --git a/Tools/AnvilStats/Utils.cpp b/Tools/AnvilStats/Utils.cpp
index f5b3b58fb..34374647b 100644
--- a/Tools/AnvilStats/Utils.cpp
+++ b/Tools/AnvilStats/Utils.cpp
@@ -32,6 +32,7 @@ struct
{entOzelot, "Ozelot"},
{entPig, "Pig"},
{entPigZombie, "PigZombie"},
+ {entRabbit, "Rabbit"},
{entSheep, "Sheep"},
{entSilverfish, "Slverfish"},
{entSkeleton, "Skeleton"},
diff --git a/Tools/AnvilStats/Utils.h b/Tools/AnvilStats/Utils.h
index 4c4e89f26..e3172649c 100644
--- a/Tools/AnvilStats/Utils.h
+++ b/Tools/AnvilStats/Utils.h
@@ -31,6 +31,7 @@ enum eEntityType
entOzelot,
entPig,
entPigZombie,
+ entRabbit,
entSheep,
entSilverfish,
entSkeleton,
diff --git a/src/BlockID.h b/src/BlockID.h
index bfb6b8d6d..41ccf90b5 100644
--- a/src/BlockID.h
+++ b/src/BlockID.h
@@ -971,6 +971,7 @@ enum
E_META_SPAWN_EGG_OCELOT = 98,
E_META_SPAWN_EGG_IRON_GOLEM = 99,
E_META_SPAWN_EGG_HORSE = 100,
+ E_META_SPAWN_EGG_RABBIT = 101,
E_META_SPAWN_EGG_VILLAGER = 120,
E_META_SPAWN_EGG_ENDER_CRYSTAL = 200,
} ;
diff --git a/src/Items/ItemSpawnEgg.h b/src/Items/ItemSpawnEgg.h
index 2f28ec6eb..dee8a9057 100644
--- a/src/Items/ItemSpawnEgg.h
+++ b/src/Items/ItemSpawnEgg.h
@@ -70,6 +70,7 @@ public:
case E_META_SPAWN_EGG_MOOSHROOM: return mtMooshroom;
case E_META_SPAWN_EGG_OCELOT: return mtOcelot;
case E_META_SPAWN_EGG_PIG: return mtPig;
+ case E_META_SPAWN_EGG_RABBIT: return mtRabbit;
case E_META_SPAWN_EGG_SHEEP: return mtSheep;
case E_META_SPAWN_EGG_SILVERFISH: return mtSilverfish;
case E_META_SPAWN_EGG_SKELETON: return mtSkeleton;
diff --git a/src/MobSpawner.cpp b/src/MobSpawner.cpp
index bd34d8fcd..0a32d17ef 100644
--- a/src/MobSpawner.cpp
+++ b/src/MobSpawner.cpp
@@ -92,6 +92,7 @@ eMonsterType cMobSpawner::ChooseMobType(EMCSBiome a_Biome)
addIfAllowed(mtCow, allowedMobs);
addIfAllowed(mtChicken, allowedMobs);
addIfAllowed(mtEnderman, allowedMobs);
+ addIfAllowed(mtRabbit, allowedMobs);
addIfAllowed(mtSlime, allowedMobs); // MG TODO : much more complicated rule
if ((a_Biome == biForest) || (a_Biome == biForestHills) || (a_Biome == biTaiga) || (a_Biome == biTaigaHills))
@@ -164,6 +165,7 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R
case mtCow:
case mtPig:
case mtHorse:
+ case mtRabbit:
case mtSheep:
{
return (
diff --git a/src/Mobs/IncludeAllMonsters.h b/src/Mobs/IncludeAllMonsters.h
index f5eb9dcc3..53c709c2b 100644
--- a/src/Mobs/IncludeAllMonsters.h
+++ b/src/Mobs/IncludeAllMonsters.h
@@ -15,6 +15,7 @@
#include "Mooshroom.h"
#include "Ocelot.h"
#include "Pig.h"
+#include "Rabbit.h"
#include "Sheep.h"
#include "Silverfish.h"
#include "Skeleton.h"
diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp
index 3d174677c..a02ea357e 100644
--- a/src/Mobs/Monster.cpp
+++ b/src/Mobs/Monster.cpp
@@ -45,6 +45,7 @@ static const struct
{mtMooshroom, "mooshroom", "MushroomCow"},
{mtOcelot, "ocelot", "Ozelot"},
{mtPig, "pig", "Pig"},
+ {mtRabbit, "rabbit", "Rabbit"},
{mtSheep, "sheep", "Sheep"},
{mtSilverfish, "silverfish", "Silverfish"},
{mtSkeleton, "skeleton", "Skeleton"},
@@ -499,6 +500,7 @@ void cMonster::KilledBy(TakeDamageInfo & a_TDI)
case mtCow:
case mtHorse:
case mtPig:
+ case mtRabbit:
case mtSheep:
case mtSquid:
case mtMooshroom:
@@ -851,6 +853,7 @@ cMonster::eFamily cMonster::FamilyFromType(eMonsterType a_Type)
case mtMooshroom: return mfHostile;
case mtOcelot: return mfPassive;
case mtPig: return mfPassive;
+ case mtRabbit: return mfPassive;
case mtSheep: return mfPassive;
case mtSilverfish: return mfHostile;
case mtSkeleton: return mfHostile;
@@ -963,6 +966,7 @@ cMonster * cMonster::NewMonsterFromType(eMonsterType a_MobType)
case mtMooshroom: toReturn = new cMooshroom(); break;
case mtOcelot: toReturn = new cOcelot(); break;
case mtPig: toReturn = new cPig(); break;
+ case mtRabbit: toReturn = new cRabbit(); break;
case mtSheep: toReturn = new cSheep(); break;
case mtSilverfish: toReturn = new cSilverfish(); break;
case mtSnowGolem: toReturn = new cSnowGolem(); break;
diff --git a/src/Mobs/MonsterTypes.h b/src/Mobs/MonsterTypes.h
index 0d716cca3..02bec267b 100644
--- a/src/Mobs/MonsterTypes.h
+++ b/src/Mobs/MonsterTypes.h
@@ -25,6 +25,7 @@ enum eMonsterType
mtMooshroom = E_META_SPAWN_EGG_MOOSHROOM,
mtOcelot = E_META_SPAWN_EGG_OCELOT,
mtPig = E_META_SPAWN_EGG_PIG,
+ mtRabbit = E_META_SPAWN_EGG_RABBIT,
mtSheep = E_META_SPAWN_EGG_SHEEP,
mtSilverfish = E_META_SPAWN_EGG_SILVERFISH,
mtSkeleton = E_META_SPAWN_EGG_SKELETON,
diff --git a/src/Mobs/Rabbit.cpp b/src/Mobs/Rabbit.cpp
new file mode 100644
index 000000000..1c7d810b7
--- /dev/null
+++ b/src/Mobs/Rabbit.cpp
@@ -0,0 +1,38 @@
+
+#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
+
+#include "Rabbit.h"
+#include "../Entities/Player.h"
+#include "../World.h"
+
+
+
+
+
+cRabbit::cRabbit(void) :
+ super("Rabbit", mtRabbit, "mob.rabbit.idle", "mob.rabbit.death", 0.9, 0.9)
+{
+}
+
+
+
+
+
+void cRabbit::GetDrops(cItems & a_Drops, cEntity * a_Killer)
+{
+ int LootingLevel = 0;
+ if (a_Killer != nullptr)
+ {
+ LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting);
+ }
+ AddRandomDropItem(a_Drops, 0, 1 + LootingLevel, IsOnFire() ? E_ITEM_COOKED_RABBIT : E_ITEM_RAW_RABBIT);
+ AddRandomDropItem(a_Drops, 0, 1 + LootingLevel, E_ITEM_RABBIT_HIDE);
+ cItems RareDrops;
+ RareDrops.Add(cItem(E_ITEM_RABBITS_FOOT));
+ AddRandomRareDropItem(a_Drops, RareDrops, LootingLevel);
+}
+
+
+
+
+
diff --git a/src/Mobs/Rabbit.h b/src/Mobs/Rabbit.h
new file mode 100644
index 000000000..5ea03d09b
--- /dev/null
+++ b/src/Mobs/Rabbit.h
@@ -0,0 +1,24 @@
+
+#pragma once
+
+#include "PassiveMonster.h"
+
+
+
+
+
+class cRabbit :
+ public cPassiveMonster
+{
+ typedef cPassiveMonster super;
+
+public:
+ cRabbit();
+
+ CLASS_PROTODEF(cRabbit)
+
+ virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override;
+
+ virtual const cItem GetFollowedItem(void) const override { return cItem(E_ITEM_CARROT); }
+
+} ;
\ No newline at end of file
diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp
index 9d8e20b0b..c87397542 100644
--- a/src/WorldStorage/NBTChunkSerializer.cpp
+++ b/src/WorldStorage/NBTChunkSerializer.cpp
@@ -502,6 +502,7 @@ void cNBTChunkSerializer::AddMonsterEntity(cMonster * a_Monster)
case mtMooshroom: EntityClass = "MushroomCow"; break;
case mtOcelot: EntityClass = "Ozelot"; break;
case mtPig: EntityClass = "Pig"; break;
+ case mtRabbit: EntityClass = "Rabbit"; break;
case mtSheep: EntityClass = "Sheep"; break;
case mtSilverfish: EntityClass = "Silverfish"; break;
case mtSkeleton: EntityClass = "Skeleton"; break;
@@ -633,6 +634,7 @@ void cNBTChunkSerializer::AddMonsterEntity(cMonster * a_Monster)
case mtMooshroom:
case mtOcelot:
case mtPig:
+ case mtRabbit:
case mtSilverfish:
case mtSnowGolem:
case mtSpider:
diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp
index a045497bc..cf51ab19c 100755
--- a/src/WorldStorage/WSSAnvil.cpp
+++ b/src/WorldStorage/WSSAnvil.cpp
@@ -1442,6 +1442,10 @@ void cWSSAnvil::LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a
{
LoadPigFromNBT(a_Entities, a_NBT, a_EntityTagIdx);
}
+ else if (strncmp(a_IDTag, "Rabbit", a_IDTagLength) == 0)
+ {
+ LoadRabbitFromNBT(a_Entities, a_NBT, a_EntityTagIdx);
+ }
else if (strncmp(a_IDTag, "Sheep", a_IDTagLength) == 0)
{
LoadSheepFromNBT(a_Entities, a_NBT, a_EntityTagIdx);
@@ -2363,6 +2367,26 @@ void cWSSAnvil::LoadPigFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NB
+void cWSSAnvil::LoadRabbitFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx)
+{
+ std::unique_ptr Monster(new cRabbit());
+ if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
+ {
+ return;
+ }
+
+ if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
+ {
+ return;
+ }
+
+ a_Entities.push_back(Monster.release());
+}
+
+
+
+
+
void cWSSAnvil::LoadSheepFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx)
{
int ColorIdx = a_NBT.FindChildByName(a_TagIdx, "Color");
diff --git a/src/WorldStorage/WSSAnvil.h b/src/WorldStorage/WSSAnvil.h
index 7bcdd259e..362796614 100755
--- a/src/WorldStorage/WSSAnvil.h
+++ b/src/WorldStorage/WSSAnvil.h
@@ -198,6 +198,7 @@ protected:
void LoadMooshroomFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadOcelotFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadPigFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
+ void LoadRabbitFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadSheepFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadSilverfishFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadSkeletonFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
--
cgit v1.2.3
From 3d2b1875a196a6aa39414381d580bdf5b2135bff Mon Sep 17 00:00:00 2001
From: Masy98
Date: Sat, 20 Dec 2014 10:38:56 +0100
Subject: Fixed Rabbit size
---
src/Mobs/Rabbit.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Mobs/Rabbit.cpp b/src/Mobs/Rabbit.cpp
index 1c7d810b7..7b873da33 100644
--- a/src/Mobs/Rabbit.cpp
+++ b/src/Mobs/Rabbit.cpp
@@ -10,7 +10,7 @@
cRabbit::cRabbit(void) :
- super("Rabbit", mtRabbit, "mob.rabbit.idle", "mob.rabbit.death", 0.9, 0.9)
+ super("Rabbit", mtRabbit, "mob.rabbit.idle", "mob.rabbit.death", 0.82, 0.68)
{
}
--
cgit v1.2.3
From 7903ee485ee58b67c6bc4a6b7a182c5d855d5418 Mon Sep 17 00:00:00 2001
From: Masy98
Date: Sat, 20 Dec 2014 11:41:23 +0100
Subject: Added Rabbit.h and Rabbit.cpp to the CMakeList
---
src/Mobs/CMakeLists.txt | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/Mobs/CMakeLists.txt b/src/Mobs/CMakeLists.txt
index c1ac2de32..7a291dcf2 100644
--- a/src/Mobs/CMakeLists.txt
+++ b/src/Mobs/CMakeLists.txt
@@ -25,6 +25,7 @@ SET (SRCS
PassiveAggressiveMonster.cpp
PassiveMonster.cpp
Pig.cpp
+ Rabbit.cpp
Sheep.cpp
Skeleton.cpp
Slime.cpp
@@ -62,6 +63,7 @@ SET (HDRS
PassiveAggressiveMonster.h
PassiveMonster.h
Pig.h
+ Rabbit.h
Sheep.h
Silverfish.h
Skeleton.h
--
cgit v1.2.3
From 5695649bb94276a7465c6c1df5a271889650abc0 Mon Sep 17 00:00:00 2001
From: Masy98
Date: Sat, 20 Dec 2014 13:04:42 +0100
Subject: Fixed damn empty line with no use
---
src/Mobs/Rabbit.cpp | 4 ----
src/Mobs/Rabbit.h | 2 +-
2 files changed, 1 insertion(+), 5 deletions(-)
diff --git a/src/Mobs/Rabbit.cpp b/src/Mobs/Rabbit.cpp
index 7b873da33..cf49d2744 100644
--- a/src/Mobs/Rabbit.cpp
+++ b/src/Mobs/Rabbit.cpp
@@ -32,7 +32,3 @@ void cRabbit::GetDrops(cItems & a_Drops, cEntity * a_Killer)
AddRandomRareDropItem(a_Drops, RareDrops, LootingLevel);
}
-
-
-
-
diff --git a/src/Mobs/Rabbit.h b/src/Mobs/Rabbit.h
index 5ea03d09b..e86c85579 100644
--- a/src/Mobs/Rabbit.h
+++ b/src/Mobs/Rabbit.h
@@ -21,4 +21,4 @@ public:
virtual const cItem GetFollowedItem(void) const override { return cItem(E_ITEM_CARROT); }
-} ;
\ No newline at end of file
+} ;
--
cgit v1.2.3
From 0d6672bf5d976f86f2746a120acd3c19c9d4c8a2 Mon Sep 17 00:00:00 2001
From: Tiger Wang
Date: Sun, 21 Dec 2014 14:31:20 +0000
Subject: Fixed crash on restart
---
src/Root.cpp | 15 ++++++++++++---
src/Root.h | 4 ++--
2 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/src/Root.cpp b/src/Root.cpp
index 9f8ffeeff..9725502ee 100644
--- a/src/Root.cpp
+++ b/src/Root.cpp
@@ -135,8 +135,9 @@ void cRoot::Start(void)
}
LOG("Starting server...");
+ m_MojangAPI = new cMojangAPI;
bool ShouldAuthenticate = IniFile.GetValueSetB("Authentication", "Authenticate", true);
- m_MojangAPI.Start(IniFile, ShouldAuthenticate); // Mojang API needs to be started before plugins, so that plugins may use it for DB upgrades on server init
+ m_MojangAPI->Start(IniFile, ShouldAuthenticate); // Mojang API needs to be started before plugins, so that plugins may use it for DB upgrades on server init
if (!m_Server->InitServer(IniFile, ShouldAuthenticate))
{
IniFile.WriteFile("settings.ini");
@@ -149,7 +150,7 @@ void cRoot::Start(void)
LOGD("Loading settings...");
m_RankManager.reset(new cRankManager());
- m_RankManager->Initialize(m_MojangAPI);
+ m_RankManager->Initialize(*m_MojangAPI);
m_CraftingRecipes = new cCraftingRecipes;
m_FurnaceRecipe = new cFurnaceRecipe();
@@ -196,7 +197,7 @@ void cRoot::Start(void)
}
#endif
- LOG("Startup complete, took %ld ms!", static_cast(std::chrono::duration_cast(std::chrono::steady_clock::now() - BeginTime).count()));
+ LOG("Startup complete, took %ldms!", static_cast(std::chrono::duration_cast(std::chrono::steady_clock::now() - BeginTime).count()));
#ifdef _WIN32
EnableMenuItem(hmenu, SC_CLOSE, MF_ENABLED); // Re-enable close button
#endif
@@ -213,21 +214,28 @@ void cRoot::Start(void)
// Stop the server:
m_WebAdmin->Stop();
+
LOG("Shutting down server...");
m_Server->Shutdown();
+ delete m_MojangAPI; m_MojangAPI = nullptr;
+
LOGD("Shutting down deadlock detector...");
dd.Stop();
+
LOGD("Stopping world threads...");
StopWorlds();
+
LOGD("Stopping authenticator...");
m_Authenticator.Stop();
LOGD("Freeing MonsterConfig...");
delete m_MonsterConfig; m_MonsterConfig = nullptr;
delete m_WebAdmin; m_WebAdmin = nullptr;
+
LOGD("Unloading recipes...");
delete m_FurnaceRecipe; m_FurnaceRecipe = nullptr;
delete m_CraftingRecipes; m_CraftingRecipes = nullptr;
+
LOGD("Unloading worlds...");
UnloadWorlds();
@@ -238,6 +246,7 @@ void cRoot::Start(void)
LOG("Cleaning up...");
delete m_Server; m_Server = nullptr;
+
LOG("Shutdown successful!");
}
diff --git a/src/Root.h b/src/Root.h
index 2c512a5df..fdaf444bd 100644
--- a/src/Root.h
+++ b/src/Root.h
@@ -86,7 +86,7 @@ public:
cWebAdmin * GetWebAdmin (void) { return m_WebAdmin; } // tolua_export
cPluginManager * GetPluginManager (void) { return m_PluginManager; } // tolua_export
cAuthenticator & GetAuthenticator (void) { return m_Authenticator; }
- cMojangAPI & GetMojangAPI (void) { return m_MojangAPI; }
+ cMojangAPI & GetMojangAPI (void) { return *m_MojangAPI; }
cRankManager * GetRankManager (void) { return m_RankManager.get(); }
/** Queues a console command for execution through the cServer class.
@@ -191,7 +191,7 @@ private:
cWebAdmin * m_WebAdmin;
cPluginManager * m_PluginManager;
cAuthenticator m_Authenticator;
- cMojangAPI m_MojangAPI;
+ cMojangAPI * m_MojangAPI;
std::unique_ptr m_RankManager;
--
cgit v1.2.3
From 9e9459a36735b768f647a4cb5013c2928464a6eb Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Sun, 21 Dec 2014 19:48:29 +0100
Subject: Fixed a possible division by zero.
---
src/Enchantments.cpp | 14 +++++++++++---
src/Enchantments.h | 6 ++++--
src/ItemGrid.cpp | 2 +-
3 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/src/Enchantments.cpp b/src/Enchantments.cpp
index 36c451b81..e72ec668a 100644
--- a/src/Enchantments.cpp
+++ b/src/Enchantments.cpp
@@ -1021,26 +1021,34 @@ cEnchantments cEnchantments::GetRandomEnchantmentFromVector(cWeightedEnchantment
-cEnchantments cEnchantments::GenerateEnchantmentFromVector(cWeightedEnchantments & a_Enchantments, int a_Seed)
+cEnchantments cEnchantments::SelectEnchantmentFromVector(const cWeightedEnchantments & a_Enchantments, int a_Seed)
{
+ // Sum up all the enchantments' weights:
int AllWeights = 0;
for (const auto Enchantment : a_Enchantments)
{
AllWeights += Enchantment.m_Weight;
}
+ // If there's no weight for any of the enchantments, return an empty enchantment
+ if (AllWeights <= 0)
+ {
+ return cEnchantments();
+ }
+
+ // Pick a random enchantment:
cNoise Noise(a_Seed);
int RandomNumber = Noise.IntNoise1DInt(AllWeights) / 7 % AllWeights;
-
for (const auto Enchantment : a_Enchantments)
{
RandomNumber -= Enchantment.m_Weight;
- if (RandomNumber < 0)
+ if (RandomNumber <= 0)
{
return Enchantment.m_Enchantments;
}
}
+ // No enchantment picked, return an empty one (we probably shouldn't ever get here):
return cEnchantments();
}
diff --git a/src/Enchantments.h b/src/Enchantments.h
index e4390a5f2..31226b5c2 100644
--- a/src/Enchantments.h
+++ b/src/Enchantments.h
@@ -128,8 +128,10 @@ public:
/** Gets random enchantment from Vector and returns it */
static cEnchantments GetRandomEnchantmentFromVector(cWeightedEnchantments & a_Enchantments);
- /** Returns an enchantment from a Vector using cNoise. Mostly used for generators.*/
- static cEnchantments GenerateEnchantmentFromVector(cWeightedEnchantments & a_Enchantments, int a_Seed);
+ /** Selects one enchantment from a Vector using cNoise. Mostly used for generators.
+ Uses the enchantments' weights for the random distribution.
+ If a_Enchantments is empty, returns an empty enchantment. */
+ static cEnchantments SelectEnchantmentFromVector(const cWeightedEnchantments & a_Enchantments, int a_Seed);
/** Returns true if a_Other doesn't contain exactly the same enchantments and levels */
bool operator !=(const cEnchantments & a_Other) const;
diff --git a/src/ItemGrid.cpp b/src/ItemGrid.cpp
index d49ea9df1..06971a1ac 100644
--- a/src/ItemGrid.cpp
+++ b/src/ItemGrid.cpp
@@ -646,7 +646,7 @@ void cItemGrid::GenerateRandomLootWithBooks(const cLootProbab * a_LootProbabs, s
for (int j = 0; j <= NumEnchantments; j++)
{
- cEnchantments Enchantment = cEnchantments::GenerateEnchantmentFromVector(Enchantments, Noise.IntNoise2DInt(NumEnchantments, i));
+ cEnchantments Enchantment = cEnchantments::SelectEnchantmentFromVector(Enchantments, Noise.IntNoise2DInt(NumEnchantments, i));
CurrentLoot.m_Enchantments.Add(Enchantment);
cEnchantments::RemoveEnchantmentWeightFromVector(Enchantments, Enchantment);
cEnchantments::CheckEnchantmentConflictsFromVector(Enchantments, Enchantment);
--
cgit v1.2.3
From d4c3821eca6249399a2d690c3c8735526d1d5a4c Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Sun, 21 Dec 2014 20:01:42 +0100
Subject: Fixed coverity issues in protocols.
Fixes CID 73099, CID 66411.
---
src/Protocol/Protocol17x.cpp | 7 +++++--
src/Protocol/Protocol18x.cpp | 8 ++++++--
2 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp
index 1e5fe5586..1e33ec433 100644
--- a/src/Protocol/Protocol17x.cpp
+++ b/src/Protocol/Protocol17x.cpp
@@ -1524,7 +1524,7 @@ void cProtocol172::AddReceivedData(const char * a_Data, size_t a_Size)
AString PacketData;
bb.ReadAll(PacketData);
bb.ResetRead();
- bb.ReadVarInt(PacketType);
+ bb.ReadVarInt(PacketType); // We have already read the packet type once, it will be there again.
ASSERT(PacketData.size() > 0); // We have written an extra NUL, so there had to be at least one byte read
PacketData.resize(PacketData.size() - 1);
AString PacketDataHex;
@@ -1753,7 +1753,10 @@ void cProtocol172::HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffe
{
return;
}
- a_ByteBuffer.ReadBEShort(EncNonceLength);
+ if (!a_ByteBuffer.ReadBEShort(EncNonceLength))
+ {
+ return;
+ }
AString EncNonce;
if (!a_ByteBuffer.ReadString(EncNonce, EncNonceLength))
{
diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp
index ce580d73e..1a13f4f7c 100644
--- a/src/Protocol/Protocol18x.cpp
+++ b/src/Protocol/Protocol18x.cpp
@@ -1723,7 +1723,11 @@ void cProtocol180::AddReceivedData(const char * a_Data, size_t a_Size)
{
// Decompress the data:
AString CompressedData;
- m_ReceivedData.ReadString(CompressedData, CompressedSize);
+ if (!m_ReceivedData.ReadString(CompressedData, CompressedSize))
+ {
+ m_Client->Kick("Compression failure");
+ return;
+ }
InflateString(CompressedData.data(), CompressedSize, UncompressedData);
PacketLen = UncompressedData.size();
}
@@ -1765,7 +1769,7 @@ void cProtocol180::AddReceivedData(const char * a_Data, size_t a_Size)
AString PacketData;
bb.ReadAll(PacketData);
bb.ResetRead();
- bb.ReadVarInt(PacketType);
+ bb.ReadVarInt(PacketType); // We have already read the packet type once, it will be there again
ASSERT(PacketData.size() > 0); // We have written an extra NUL, so there had to be at least one byte read
PacketData.resize(PacketData.size() - 1);
AString PacketDataHex;
--
cgit v1.2.3
From c9697083e57e7062a68f61b5516b73c412e83004 Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Sun, 21 Dec 2014 21:56:34 +0100
Subject: cNoise3DComposable: Fixed unitialized member variables.
Fixes CID 43665.
---
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 b43a1a6de..29471f936 100644
--- a/src/Generating/Noise3DGenerator.cpp
+++ b/src/Generating/Noise3DGenerator.cpp
@@ -379,7 +379,9 @@ cNoise3DComposable::cNoise3DComposable(int a_Seed) :
m_ChoiceNoise(a_Seed),
m_DensityNoiseA(a_Seed + 1),
m_DensityNoiseB(a_Seed + 2),
- m_BaseNoise(a_Seed + 3)
+ m_BaseNoise(a_Seed + 3),
+ m_LastChunkX(0x7fffffff), // Use dummy coords that won't ever be used by real chunks
+ m_LastChunkZ(0x7fffffff)
{
}
--
cgit v1.2.3
From fe00c99c9518be022f8faaa52899e68fc0738ce4 Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Sun, 21 Dec 2014 21:59:44 +0100
Subject: cEndGen: Fixed unitialized member variables.
Fixes CID 43671.
---
src/Generating/EndGen.cpp | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/Generating/EndGen.cpp b/src/Generating/EndGen.cpp
index 89d6117bb..bc26edb20 100644
--- a/src/Generating/EndGen.cpp
+++ b/src/Generating/EndGen.cpp
@@ -39,7 +39,9 @@ cEndGen::cEndGen(int a_Seed) :
m_IslandSizeZ(256),
m_FrequencyX(80),
m_FrequencyY(80),
- m_FrequencyZ(80)
+ m_FrequencyZ(80),
+ m_LastChunkX(0x7fffffff), // Use dummy coords that won't ever be used by real chunks
+ m_LastChunkZ(0x7fffffff)
{
m_Perlin.AddOctave(1, 1);
m_Perlin.AddOctave(2, 0.5);
--
cgit v1.2.3
From ecf778bbec2794562bf5e5b8645e2171f7cd081c Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Sun, 21 Dec 2014 22:19:22 +0100
Subject: cWorld: Moved initialization into constructor.
Fixes CID 71781.
---
src/World.cpp | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/World.cpp b/src/World.cpp
index 69b39f831..cd17cde08 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -279,6 +279,8 @@ cWorld::cWorld(const AString & a_WorldName, eDimension a_Dimension, const AStrin
m_WorldAge(0),
m_TimeOfDay(0),
m_LastTimeUpdate(0),
+ m_LastSave(0),
+ m_LastUnload(0),
m_SkyDarkness(0),
m_GameMode(gmNotSet),
m_bEnabledPVP(false),
@@ -620,9 +622,6 @@ void cWorld::Start(void)
m_ChunkMap = make_unique(this);
- m_LastSave = 0;
- m_LastUnload = 0;
-
// preallocate some memory for ticking blocks so we don't need to allocate that often
m_BlockTickQueue.reserve(1000);
m_BlockTickQueueCopy.reserve(1000);
--
cgit v1.2.3
From afdd53729c2a51a3720800e1b82aa5c40840dffe Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Sun, 21 Dec 2014 22:19:53 +0100
Subject: cChunk: Fixed missing initialization.
Fixes CID 72670.
---
src/Chunk.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/Chunk.cpp b/src/Chunk.cpp
index 39e97f5cf..555e85015 100644
--- a/src/Chunk.cpp
+++ b/src/Chunk.cpp
@@ -73,6 +73,7 @@ cChunk::cChunk(
cAllocationPool & a_Pool
) :
m_Presence(cpInvalid),
+ m_ShouldGenerateIfLoadFailed(false),
m_IsLightValid(false),
m_IsDirty(false),
m_IsSaving(false),
@@ -93,6 +94,7 @@ cChunk::cChunk(
m_WaterSimulatorData(a_World->GetWaterSimulator()->CreateChunkData()),
m_LavaSimulatorData (a_World->GetLavaSimulator ()->CreateChunkData()),
m_RedstoneSimulatorData(a_World->GetRedstoneSimulator()->CreateChunkData()),
+ m_IsRedstoneDirty(false),
m_AlwaysTicked(0)
{
if (a_NeighborXM != nullptr)
--
cgit v1.2.3
From e192da5316e5617a5fd597d4de9181a36b5e4c2e Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Sun, 21 Dec 2014 22:25:01 +0100
Subject: FastNBT: Added a sanity check for number of list items.
Fixes CID 55812.
---
src/WorldStorage/FastNBT.cpp | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/src/WorldStorage/FastNBT.cpp b/src/WorldStorage/FastNBT.cpp
index ed8e8bb14..aaef2fdfe 100644
--- a/src/WorldStorage/FastNBT.cpp
+++ b/src/WorldStorage/FastNBT.cpp
@@ -10,6 +10,13 @@
+/** If a list being loaded has more than this number of items, it's considered corrupted. */
+static const int MAX_LIST_ITEMS = 10000;
+
+
+
+
+
// The number of NBT tags that are reserved when an NBT parsing is started.
// You can override this by using a cmdline define
#ifndef NBT_RESERVE_SIZE
@@ -142,7 +149,7 @@ bool cParsedNBT::ReadList(eTagType a_ChildrenType)
NEEDBYTES(4);
int Count = GetBEInt(m_Data + m_Pos);
m_Pos += 4;
- if (Count < 0)
+ if ((Count < 0) || (Count > MAX_LIST_ITEMS))
{
return false;
}
--
cgit v1.2.3
From f2327042037383abc2773710dac78af527bc5500 Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Sun, 21 Dec 2014 22:37:48 +0100
Subject: WSSAnvil: Added clamping to entity coords.
Fixes CID 72854.
---
src/WorldStorage/WSSAnvil.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp
index cf51ab19c..a76e9461a 100755
--- a/src/WorldStorage/WSSAnvil.cpp
+++ b/src/WorldStorage/WSSAnvil.cpp
@@ -2945,9 +2945,9 @@ bool cWSSAnvil::GetBlockEntityNBTPos(const cParsedNBT & a_NBT, int a_TagIdx, int
{
return false;
}
- a_X = a_NBT.GetInt(x);
- a_Y = a_NBT.GetInt(y);
- a_Z = a_NBT.GetInt(z);
+ a_X = Clamp(a_NBT.GetInt(x), -40000000, 40000000); // World is limited to 30M blocks in XZ, we clamp to 40M
+ a_Y = Clamp(a_NBT.GetInt(y), -10000, 10000); // Y is limited to 0 .. 255, we clamp to 10K
+ a_Z = Clamp(a_NBT.GetInt(z), -40000000, 40000000);
return true;
}
--
cgit v1.2.3
From f5b4c92a10a6e196d9487083672e91fbe60a12fd Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Sun, 21 Dec 2014 22:50:32 +0100
Subject: MCADefrag: Added a sanity check for chunk size.
Fixes CID 66448.
---
Tools/MCADefrag/MCADefrag.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Tools/MCADefrag/MCADefrag.cpp b/Tools/MCADefrag/MCADefrag.cpp
index d5d233fd2..0d38a87f1 100644
--- a/Tools/MCADefrag/MCADefrag.cpp
+++ b/Tools/MCADefrag/MCADefrag.cpp
@@ -269,7 +269,7 @@ bool cMCADefrag::cThread::ReadChunk(cFile & a_File, const Byte * a_LocationRaw)
return false;
}
m_CompressedChunkDataSize = (Buf[0] << 24) | (Buf[1] << 16) | (Buf[2] << 8) | Buf[3];
- if (m_CompressedChunkDataSize > SizeInSectors)
+ if ((m_CompressedChunkDataSize > SizeInSectors) || (m_CompressedChunkDataSize < 0))
{
LOGWARNING("Invalid chunk data - SizeInSectors (%d) smaller that RealSize (%d)", SizeInSectors, m_CompressedChunkDataSize);
return false;
--
cgit v1.2.3
From 557dc5a93f04798474e7ca114a47f7c379547f94 Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Sun, 21 Dec 2014 22:51:17 +0100
Subject: ProtoProxy: Added a sanity check to metadata string lengths.
Fixes CID 66415.
---
Tools/ProtoProxy/Connection.cpp | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/Tools/ProtoProxy/Connection.cpp b/Tools/ProtoProxy/Connection.cpp
index fb2d40e5b..468529124 100644
--- a/Tools/ProtoProxy/Connection.cpp
+++ b/Tools/ProtoProxy/Connection.cpp
@@ -2687,7 +2687,7 @@ bool cConnection::ParseSlot(cByteBuffer & a_Buffer, AString & a_ItemDesc)
char ItemCount;
short ItemDamage;
short MetadataLength;
- a_Buffer.ReadChar(ItemCount);
+ a_Buffer.ReadChar(ItemCount); // We already know we can read these bytes - we checked before.
a_Buffer.ReadBEShort(ItemDamage);
a_Buffer.ReadBEShort(MetadataLength);
Printf(a_ItemDesc, "%d:%d * %d", ItemType, ItemDamage, ItemCount);
@@ -2846,7 +2846,11 @@ void cConnection::LogMetadata(const AString & a_Metadata, size_t a_IndentCount)
bb.Write(a_Metadata.data() + pos + 1, RestLen);
UInt32 Length;
int rs = bb.GetReadableSpace();
- bb.ReadVarInt(Length);
+ if (!bb.ReadVarInt(Length))
+ {
+ Log("Invalid metadata value, was supposed to be a varint-prefixed string, but cannot read the varint");
+ break;
+ }
rs = rs - bb.GetReadableSpace();
Log("%sstring[%d] = \"%*s\"", Indent.c_str(), Index, Length, a_Metadata.c_str() + pos + rs + 1);
pos += Length + rs + 2;
--
cgit v1.2.3
From ae8c871565e7a13159eb2a0839053f1b5b6bcfc4 Mon Sep 17 00:00:00 2001
From: Jonathan Fabian
Date: Sun, 21 Dec 2014 19:29:34 -0500
Subject: Added Depth Strider enchantment
---
src/Enchantments.cpp | 15 +++++++++++++++
src/Enchantments.h | 1 +
2 files changed, 16 insertions(+)
diff --git a/src/Enchantments.cpp b/src/Enchantments.cpp
index e72ec668a..5ed18de6b 100644
--- a/src/Enchantments.cpp
+++ b/src/Enchantments.cpp
@@ -183,6 +183,7 @@ int cEnchantments::StringToEnchantmentID(const AString & a_EnchantmentName)
{ enchRespiration, "Respiration"},
{ enchAquaAffinity, "AquaAffinity"},
{ enchThorns, "Thorns"},
+ { enchDepthStrider, "DepthStrider"},
{ enchSharpness, "Sharpness"},
{ enchSmite, "Smite"},
{ enchBaneOfArthropods, "BaneOfArthropods"},
@@ -506,6 +507,20 @@ void cEnchantments::AddItemEnchantmentWeights(cWeightedEnchantments & a_Enchantm
{
AddEnchantmentWeightToVector(a_Enchantments, 5, enchFeatherFalling, 1);
}
+
+ // Depth Strider
+ if ((a_EnchantmentLevel >= 30) && (a_EnchantmentLevel <= 45))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchDepthStrider, 3);
+ }
+ else if ((a_EnchantmentLevel >= 20) && (a_EnchantmentLevel <= 35))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchDepthStrider, 2);
+ }
+ else if ((a_EnchantmentLevel >= 10) && (a_EnchantmentLevel <= 25))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchDepthStrider, 1);
+ }
}
}
diff --git a/src/Enchantments.h b/src/Enchantments.h
index 31226b5c2..e8e84d43c 100644
--- a/src/Enchantments.h
+++ b/src/Enchantments.h
@@ -53,6 +53,7 @@ public:
enchRespiration = 5,
enchAquaAffinity = 6,
enchThorns = 7,
+ enchDepthStrider = 8,
enchSharpness = 16,
enchSmite = 17,
enchBaneOfArthropods = 18,
--
cgit v1.2.3
From fbd0cf74bdc3a6c3a2524691da07e4ac4ad7940d Mon Sep 17 00:00:00 2001
From: Jonathan Fabian
Date: Sun, 21 Dec 2014 23:02:02 -0500
Subject: Fix compile error on OS X introduced by commit
ecf778bbec2794562bf5e5b8645e2171f7cd081c
The following error occurs on OS X with the order reversed: `MCServer/src/World.cpp:282:2: error: field 'm_LastSave' will be initialized after field 'm_LastUnload' [-Werror,-Wreorder] m_LastSave(0),`. Reversing the order of initialization fixes this.
---
src/World.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/World.cpp b/src/World.cpp
index cd17cde08..ae739a2c3 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -279,8 +279,8 @@ cWorld::cWorld(const AString & a_WorldName, eDimension a_Dimension, const AStrin
m_WorldAge(0),
m_TimeOfDay(0),
m_LastTimeUpdate(0),
- m_LastSave(0),
m_LastUnload(0),
+ m_LastSave(0),
m_SkyDarkness(0),
m_GameMode(gmNotSet),
m_bEnabledPVP(false),
--
cgit v1.2.3
From 9fde173142921339f6b65dccb8fe6b82427c4d04 Mon Sep 17 00:00:00 2001
From: worktycho
Date: Tue, 23 Dec 2014 00:41:46 +0000
Subject: Init Mojang API pointer
Fixes CID 90583
---
src/Root.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/Root.cpp b/src/Root.cpp
index 9725502ee..8951bafe6 100644
--- a/src/Root.cpp
+++ b/src/Root.cpp
@@ -47,6 +47,7 @@ cRoot::cRoot(void) :
m_FurnaceRecipe(nullptr),
m_WebAdmin(nullptr),
m_PluginManager(nullptr),
+ m_MojangAPI(nullptr),
m_bStop(false),
m_bRestart(false)
{
--
cgit v1.2.3
From 9693251da4ccc79b087e89a0badbe4b1d4cc1020 Mon Sep 17 00:00:00 2001
From: Alexander Harkness
Date: Tue, 23 Dec 2014 08:08:23 +0000
Subject: Fixed armhf download URL.
---
easyinstall.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/easyinstall.sh b/easyinstall.sh
index 77ffb2290..9b4007144 100755
--- a/easyinstall.sh
+++ b/easyinstall.sh
@@ -7,7 +7,7 @@ case $PLATFORM in
"i686") DOWNLOADURL="http://builds.cuberite.org/job/MCServer%20Linux%20x86/lastSuccessfulBuild/artifact/MCServer.tar" ;;
"x86_64") DOWNLOADURL="http://builds.cuberite.org/job/MCServer%20Linux%20x64/lastSuccessfulBuild/artifact/MCServer.tar" ;;
# Assume that all arm devices are a raspi for now.
- "arm*") DOWNLOADURL="http://builds.cuberite.org/job/MCServer%20Linux%20armhf/lastSuccessfulBuild/artifact/MCServer.tar"
+ "arm*") DOWNLOADURL="http://builds.cuberite.org/job/MCServer%20Linux%20armhf/lastSuccessfulBuild/artifact/MCServer/MCServer.tar"
esac
echo "Downloading precompiled binaries."
--
cgit v1.2.3
From fc21b1cc10f9a9deace1b571a03386a0d9472aa7 Mon Sep 17 00:00:00 2001
From: Alexander Harkness
Date: Tue, 23 Dec 2014 11:54:09 +0000
Subject: Better installation script.
---
app.yml | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/app.yml b/app.yml
index 44edf0852..b8a2ff7a1 100644
--- a/app.yml
+++ b/app.yml
@@ -3,9 +3,7 @@ image: ubuntu-14-04-x64
config:
#cloud-config
packages:
- - curl
- - screen
+ - git
runcmd:
- - mkdir /minecraft
- - cd /minecraft && curl -s https://raw.githubusercontent.com/mc-server/MCServer/master/easyinstall.sh | sh
- - cd /minecraft/MCServer && screen -S mcserver -d -m ./MCServer
+ - cd /tmp && git clone https://github.com/cuberite/mcserver-ocean.git
+ - cd //tmp/mcserver-ocean && ./initialinstall.sh
--
cgit v1.2.3
From 3dd94bac5e9df13ff57f5da4348e7d283c5f7b4d Mon Sep 17 00:00:00 2001
From: Alexander Harkness
Date: Tue, 23 Dec 2014 14:50:47 +0000
Subject: Fixed too many slashes.
---
app.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app.yml b/app.yml
index b8a2ff7a1..51f9b0f58 100644
--- a/app.yml
+++ b/app.yml
@@ -6,4 +6,4 @@ config:
- git
runcmd:
- cd /tmp && git clone https://github.com/cuberite/mcserver-ocean.git
- - cd //tmp/mcserver-ocean && ./initialinstall.sh
+ - cd /tmp/mcserver-ocean && ./initialinstall.sh
--
cgit v1.2.3
From 075b19c7cbf5d6e45dbd14e8fab5740d7000bf0f Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Wed, 24 Dec 2014 06:43:28 +0100
Subject: Added Vector3::TurnCW() and Vector3::TurnCCW()
---
src/Vector3.h | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/src/Vector3.h b/src/Vector3.h
index 1e4a1f5d9..1f3f6b955 100644
--- a/src/Vector3.h
+++ b/src/Vector3.h
@@ -307,6 +307,22 @@ public:
return (a_X - x) / (a_OtherEnd.x - x);
}
+ /** Rotates the vector 90 degrees clockwise around the vertical axis.
+ Note that this is specific to minecraft's axis ordering, which is X+ left, Z+ down. */
+ inline void TurnCW(void)
+ {
+ std::swap(x, z);
+ x = -x;
+ }
+
+ /** Rotates the vector 90 degrees counterclockwise around the vertical axis.
+ Note that this is specific to minecraft's axis ordering, which is X+ left, Z+ down. */
+ inline void TurnCCW(void)
+ {
+ std::swap(x, z);
+ z = -z;
+ }
+
/** The max difference between two coords for which the coords are assumed equal. */
static const double EPS;
--
cgit v1.2.3
From ccdf03daaf880dd0c89a03b50c11eb083ee1cfb0 Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Wed, 24 Dec 2014 07:20:17 +0100
Subject: Refactored all player block placing to go through hooks.
Fixes #1618.
---
src/Bindings/Plugin.h | 4 +-
src/Bindings/PluginLua.cpp | 18 ++-
src/Bindings/PluginLua.h | 4 +-
src/Bindings/PluginManager.cpp | 8 +-
src/Bindings/PluginManager.h | 6 +-
src/Blocks/BlockBed.cpp | 20 +---
src/Blocks/BlockBed.h | 1 -
src/Blocks/BlockBigFlower.h | 12 --
src/Blocks/BlockChest.h | 65 ++--------
src/Blocks/BlockDoor.cpp | 40 ++-----
src/Blocks/BlockDoor.h | 39 ++++--
src/Blocks/BlockHandler.cpp | 2 +-
src/Blocks/BlockHandler.h | 21 ++--
src/Blocks/BlockMobHead.h | 204 +-------------------------------
src/Blocks/BlockPumpkin.h | 64 ----------
src/Blocks/BlockSignPost.h | 11 --
src/Blocks/BlockWallSign.h | 11 --
src/Chunk.cpp | 16 +--
src/ChunkDef.h | 48 ++++++--
src/ChunkMap.cpp | 103 ++++++++++------
src/ChunkMap.h | 23 +++-
src/ClientHandle.cpp | 158 ++-----------------------
src/ClientHandle.h | 3 -
src/Entities/Player.cpp | 96 +++++++++++++++
src/Entities/Player.h | 18 +++
src/Generating/StructGen.cpp | 14 +--
src/Generating/Trees.cpp | 14 +--
src/Items/CMakeLists.txt | 7 +-
src/Items/ItemBed.h | 28 +++--
src/Items/ItemBigFlower.h | 56 +++++++++
src/Items/ItemChest.h | 167 ++++++++++++++++++++++++++
src/Items/ItemDoor.h | 96 +++++++++++----
src/Items/ItemDye.h | 25 ++--
src/Items/ItemHandler.cpp | 199 ++++++++++++++++++++++++-------
src/Items/ItemHandler.h | 39 ++++--
src/Items/ItemMobHead.h | 261 +++++++++++++++++++++++++++++++++++++++++
src/Items/ItemPumpkin.h | 156 ++++++++++++++++++++++++
src/Items/ItemSign.h | 22 +++-
src/Items/ItemSlab.h | 93 +++++++++++++++
src/Protocol/Protocol17x.cpp | 4 +-
src/Protocol/Protocol18x.cpp | 4 +-
src/World.cpp | 13 +-
src/World.h | 5 +
43 files changed, 1423 insertions(+), 775 deletions(-)
create mode 100644 src/Items/ItemBigFlower.h
create mode 100644 src/Items/ItemChest.h
create mode 100644 src/Items/ItemPumpkin.h
create mode 100644 src/Items/ItemSlab.h
diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h
index 08677553c..b5944e9cb 100644
--- a/src/Bindings/Plugin.h
+++ b/src/Bindings/Plugin.h
@@ -76,8 +76,8 @@ public:
virtual bool OnPlayerJoined (cPlayer & a_Player) = 0;
virtual bool OnPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status) = 0;
virtual bool OnPlayerMoving (cPlayer & a_Player, const Vector3d & a_OldPosition, const Vector3d & a_NewPosition) = 0;
- virtual bool OnPlayerPlacedBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) = 0;
- virtual bool OnPlayerPlacingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) = 0;
+ virtual bool OnPlayerPlacedBlock (cPlayer & a_Player, const sSetBlock & a_BlockChange) = 0;
+ virtual bool OnPlayerPlacingBlock (cPlayer & a_Player, const sSetBlock & a_BlockChange) = 0;
virtual bool OnPlayerRightClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) = 0;
virtual bool OnPlayerRightClickingEntity(cPlayer & a_Player, cEntity & a_Entity) = 0;
virtual bool OnPlayerShooting (cPlayer & a_Player) = 0;
diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp
index ea782ea3f..cc3146610 100644
--- a/src/Bindings/PluginLua.cpp
+++ b/src/Bindings/PluginLua.cpp
@@ -857,14 +857,19 @@ bool cPluginLua::OnPlayerMoving(cPlayer & a_Player, const Vector3d & a_OldPositi
-bool cPluginLua::OnPlayerPlacedBlock(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
+bool cPluginLua::OnPlayerPlacedBlock(cPlayer & a_Player, const sSetBlock & a_BlockChange)
{
cCSLock Lock(m_CriticalSection);
bool res = false;
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_PLAYER_PLACED_BLOCK];
for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
{
- m_LuaState.Call((int)(**itr), &a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, a_BlockType, a_BlockMeta, cLuaState::Return, res);
+ m_LuaState.Call((int)(**itr), &a_Player,
+ a_BlockChange.GetX(), a_BlockChange.GetY(), a_BlockChange.GetZ(),
+ a_BlockChange.m_BlockType, a_BlockChange.m_BlockMeta,
+ cLuaState::Return,
+ res
+ );
if (res)
{
return true;
@@ -877,14 +882,19 @@ bool cPluginLua::OnPlayerPlacedBlock(cPlayer & a_Player, int a_BlockX, int a_Blo
-bool cPluginLua::OnPlayerPlacingBlock(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
+bool cPluginLua::OnPlayerPlacingBlock(cPlayer & a_Player, const sSetBlock & a_BlockChange)
{
cCSLock Lock(m_CriticalSection);
bool res = false;
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_PLAYER_PLACING_BLOCK];
for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
{
- m_LuaState.Call((int)(**itr), &a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, a_BlockType, a_BlockMeta, cLuaState::Return, res);
+ m_LuaState.Call((int)(**itr), &a_Player,
+ a_BlockChange.GetX(), a_BlockChange.GetY(), a_BlockChange.GetZ(),
+ a_BlockChange.m_BlockType, a_BlockChange.m_BlockMeta,
+ cLuaState::Return,
+ res
+ );
if (res)
{
return true;
diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h
index 7de5ffec4..ad3f82b42 100644
--- a/src/Bindings/PluginLua.h
+++ b/src/Bindings/PluginLua.h
@@ -100,8 +100,8 @@ public:
virtual bool OnPlayerJoined (cPlayer & a_Player) override;
virtual bool OnPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status) override;
virtual bool OnPlayerMoving (cPlayer & a_Player, const Vector3d & a_OldPosition, const Vector3d & a_NewPosition) override;
- virtual bool OnPlayerPlacedBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
- virtual bool OnPlayerPlacingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
+ virtual bool OnPlayerPlacedBlock (cPlayer & a_Player, const sSetBlock & a_BlockChange) override;
+ virtual bool OnPlayerPlacingBlock (cPlayer & a_Player, const sSetBlock & a_BlockChange) override;
virtual bool OnPlayerRightClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override;
virtual bool OnPlayerRightClickingEntity(cPlayer & a_Player, cEntity & a_Entity) override;
virtual bool OnPlayerShooting (cPlayer & a_Player) override;
diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp
index 406a540f4..fad0a36d2 100644
--- a/src/Bindings/PluginManager.cpp
+++ b/src/Bindings/PluginManager.cpp
@@ -866,14 +866,14 @@ bool cPluginManager::CallHookPlayerMoving(cPlayer & a_Player, const Vector3d a_O
-bool cPluginManager::CallHookPlayerPlacedBlock(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
+bool cPluginManager::CallHookPlayerPlacedBlock(cPlayer & a_Player, const sSetBlock & a_BlockChange)
{
FIND_HOOK(HOOK_PLAYER_PLACED_BLOCK);
VERIFY_HOOK;
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
- if ((*itr)->OnPlayerPlacedBlock(a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, a_BlockType, a_BlockMeta))
+ if ((*itr)->OnPlayerPlacedBlock(a_Player, a_BlockChange))
{
return true;
}
@@ -885,14 +885,14 @@ bool cPluginManager::CallHookPlayerPlacedBlock(cPlayer & a_Player, int a_BlockX,
-bool cPluginManager::CallHookPlayerPlacingBlock(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
+bool cPluginManager::CallHookPlayerPlacingBlock(cPlayer & a_Player, const sSetBlock & a_BlockChange)
{
FIND_HOOK(HOOK_PLAYER_PLACING_BLOCK);
VERIFY_HOOK;
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
- if ((*itr)->OnPlayerPlacingBlock(a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, a_BlockType, a_BlockMeta))
+ if ((*itr)->OnPlayerPlacingBlock(a_Player, a_BlockChange))
{
return true;
}
diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h
index 3a2aecc92..d4b82376a 100644
--- a/src/Bindings/PluginManager.h
+++ b/src/Bindings/PluginManager.h
@@ -207,10 +207,10 @@ public:
bool CallHookPlayerFishing (cPlayer & a_Player, cItems a_Reward);
bool CallHookPlayerFoodLevelChange (cPlayer & a_Player, int a_NewFoodLevel);
bool CallHookPlayerJoined (cPlayer & a_Player);
- bool CallHookPlayerMoving (cPlayer & a_Player, const Vector3d a_OldPosition, const Vector3d a_NewPosition);
bool CallHookPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status);
- bool CallHookPlayerPlacedBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
- bool CallHookPlayerPlacingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
+ bool CallHookPlayerMoving (cPlayer & a_Player, const Vector3d a_OldPosition, const Vector3d a_NewPosition);
+ bool CallHookPlayerPlacedBlock (cPlayer & a_Player, const sSetBlock & a_BlockChange);
+ bool CallHookPlayerPlacingBlock (cPlayer & a_Player, const sSetBlock & a_BlockChange);
bool CallHookPlayerRightClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ);
bool CallHookPlayerRightClickingEntity(cPlayer & a_Player, cEntity & a_Entity);
bool CallHookPlayerShooting (cPlayer & a_Player);
diff --git a/src/Blocks/BlockBed.cpp b/src/Blocks/BlockBed.cpp
index 3b6328b38..57b9855d0 100644
--- a/src/Blocks/BlockBed.cpp
+++ b/src/Blocks/BlockBed.cpp
@@ -14,24 +14,6 @@
-void cBlockBedHandler::OnPlacedByPlayer(
- 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,
- BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
-)
-{
- if (a_BlockMeta < 8)
- {
- Vector3i Direction = MetaDataToDirection(a_BlockMeta);
- a_ChunkInterface.SetBlock(a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z, E_BLOCK_BED, a_BlockMeta | 0x8);
- }
-}
-
-
-
-
-
void cBlockBedHandler::OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
{
NIBBLETYPE OldMeta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
@@ -151,7 +133,7 @@ void cBlockBedHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface
cPlayerBedStateUnsetter Unsetter(Vector3i(a_BlockX + PillowDirection.x, a_BlockY, a_BlockZ + PillowDirection.z), a_WorldInterface);
a_WorldInterface.ForEachPlayer(Unsetter);
a_WorldInterface.SetTimeOfDay(0);
- a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta & 0xB); // Where 0xB = 1011, and zero is to make sure 'occupied' bit is always unset
+ a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta & 0x0b); // Clear the "occupied" bit of the bed's block
}
}
}
diff --git a/src/Blocks/BlockBed.h b/src/Blocks/BlockBed.h
index a8b5be899..5b746110a 100644
--- a/src/Blocks/BlockBed.h
+++ b/src/Blocks/BlockBed.h
@@ -23,7 +23,6 @@ public:
}
- virtual void OnPlacedByPlayer(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, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
virtual void OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ) override;
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;
diff --git a/src/Blocks/BlockBigFlower.h b/src/Blocks/BlockBigFlower.h
index 3577bdd40..5240ddf53 100644
--- a/src/Blocks/BlockBigFlower.h
+++ b/src/Blocks/BlockBigFlower.h
@@ -85,18 +85,6 @@ public:
}
- virtual void OnPlacedByPlayer(
- 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,
- BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
- ) override
- {
- int Meta = (((int)floor(a_Player->GetYaw() * 4.0 / 360.0 + 0.5) & 0x3) + 2) % 4;
- a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY + 1, a_BlockZ, m_BlockType, 0x8 | Meta);
- }
-
-
virtual void OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ) override
{
NIBBLETYPE OldMeta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
diff --git a/src/Blocks/BlockChest.h b/src/Blocks/BlockChest.h
index 201f2309b..01fec7f8b 100644
--- a/src/Blocks/BlockChest.h
+++ b/src/Blocks/BlockChest.h
@@ -62,50 +62,11 @@ public:
}
// Single chest, get meta from rotation only
- a_BlockMeta = RotationToMetaData(yaw);
+ a_BlockMeta = PlayerYawToMetaData(yaw);
return true;
}
- virtual void OnPlacedByPlayer(
- 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,
- BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
- ) override
- {
- // Check if this forms a doublechest, if so, need to adjust the meta:
- cBlockArea Area;
- if (!Area.Read(&a_ChunkInterface, a_BlockX - 1, a_BlockX + 1, a_BlockY, a_BlockY, a_BlockZ - 1, a_BlockZ + 1))
- {
- return;
- }
-
- double rot = a_Player->GetYaw(); // FIXME: Rename rot to yaw
- // Choose meta from player rotation, choose only between 2 or 3
- NIBBLETYPE NewMeta = ((rot >= -90) && (rot < 90)) ? 2 : 3;
- if (
- CheckAndAdjustNeighbor(a_ChunkInterface, Area, 0, 1, NewMeta) ||
- CheckAndAdjustNeighbor(a_ChunkInterface, Area, 2, 1, NewMeta)
- )
- {
- // Forming a double chest in the X direction
- return;
- }
- // Choose meta from player rotation, choose only between 4 or 5
- NewMeta = (rot < 0) ? 4 : 5;
- if (
- CheckAndAdjustNeighbor(a_ChunkInterface, Area, 1, 0, NewMeta) ||
- CheckAndAdjustNeighbor(a_ChunkInterface, Area, 2, 2, NewMeta)
- )
- {
- // Forming a double chest in the Z direction
- return;
- }
-
- // Single chest, no further processing needed
- }
-
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{
int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width;
@@ -180,30 +141,30 @@ public:
}
- /// Translates player rotation when placing a chest into the chest block metadata. Valid for single chests only
- static NIBBLETYPE RotationToMetaData(double a_Rotation)
+ /** Translates player yaw when placing a chest into the chest block metadata. Valid for single chests only */
+ static NIBBLETYPE PlayerYawToMetaData(double a_Yaw)
{
- a_Rotation += 90 + 45; // So its not aligned with axis
+ a_Yaw += 90 + 45; // So its not aligned with axis
- if (a_Rotation > 360.f)
+ if (a_Yaw > 360.f)
{
- a_Rotation -= 360.f;
+ a_Yaw -= 360.f;
}
- if ((a_Rotation >= 0.f) && (a_Rotation < 90.f))
+ if ((a_Yaw >= 0.f) && (a_Yaw < 90.f))
{
- return 0x4;
+ return 0x04;
}
- else if ((a_Rotation >= 180) && (a_Rotation < 270))
+ else if ((a_Yaw >= 180) && (a_Yaw < 270))
{
- return 0x5;
+ return 0x05;
}
- else if ((a_Rotation >= 90) && (a_Rotation < 180))
+ else if ((a_Yaw >= 90) && (a_Yaw < 180))
{
- return 0x2;
+ return 0x02;
}
else
{
- return 0x3;
+ return 0x03;
}
}
diff --git a/src/Blocks/BlockDoor.cpp b/src/Blocks/BlockDoor.cpp
index 90b7b15c2..d2bf180be 100644
--- a/src/Blocks/BlockDoor.cpp
+++ b/src/Blocks/BlockDoor.cpp
@@ -23,7 +23,7 @@ void cBlockDoorHandler::OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldIn
if (OldMeta & 8)
{
// Was upper part of door
- if (IsDoor(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ)))
+ if (IsDoorBlockType(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ)))
{
a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0);
}
@@ -31,7 +31,7 @@ void cBlockDoorHandler::OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldIn
else
{
// Was lower part
- if (IsDoor(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ)))
+ if (IsDoorBlockType(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ)))
{
a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY + 1, a_BlockZ, E_BLOCK_AIR, 0);
}
@@ -84,52 +84,34 @@ void cBlockDoorHandler::OnCancelRightClick(cChunkInterface & a_ChunkInterface, c
-void cBlockDoorHandler::OnPlacedByPlayer(
- 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,
- BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
-)
-{
- NIBBLETYPE a_TopBlockMeta = 8;
- if (
- ((a_BlockMeta == 0) && (a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ - 1) == m_BlockType)) ||
- ((a_BlockMeta == 1) && (a_ChunkInterface.GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ) == m_BlockType)) ||
- ((a_BlockMeta == 2) && (a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ + 1) == m_BlockType)) ||
- ((a_BlockMeta == 3) && (a_ChunkInterface.GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ) == m_BlockType))
- )
- {
- a_TopBlockMeta = 9;
- }
- a_ChunkInterface.SetBlock(a_BlockX, a_BlockY + 1, a_BlockZ, m_BlockType, a_TopBlockMeta);
-}
-
-
-
-
-
NIBBLETYPE cBlockDoorHandler::MetaRotateCCW(NIBBLETYPE a_Meta)
{
if (a_Meta & 0x08)
{
+ // The meta doesn't change for the top block
return a_Meta;
}
else
{
+ // Rotate the bottom block
return super::MetaRotateCCW(a_Meta);
}
}
+
+
NIBBLETYPE cBlockDoorHandler::MetaRotateCW(NIBBLETYPE a_Meta)
{
if (a_Meta & 0x08)
{
+ // The meta doesn't change for the top block
return a_Meta;
}
else
{
+ // Rotate the bottom block
return super::MetaRotateCW(a_Meta);
}
}
@@ -138,8 +120,10 @@ NIBBLETYPE cBlockDoorHandler::MetaRotateCW(NIBBLETYPE a_Meta)
NIBBLETYPE cBlockDoorHandler::MetaMirrorXY(NIBBLETYPE a_Meta)
{
- // Top bit (0x08) contains door panel type (Top/Bottom panel) Only Bottom panels contain position data
- // Return a_Meta if panel is a top panel (0x08 bit is set to 1)
+ /*
+ Top bit (0x08) contains door block position (Top / Bottom). Only Bottom blocks contain position data
+ Return a_Meta if panel is a top panel (0x08 bit is set to 1)
+ */
// Note: Currently, you can not properly mirror the hinges on a double door. The orientation of the door is stored
// in only the bottom tile while the hinge position is in the top tile. This function only operates on one tile at a time,
diff --git a/src/Blocks/BlockDoor.h b/src/Blocks/BlockDoor.h
index 92ad8da12..334519077 100644
--- a/src/Blocks/BlockDoor.h
+++ b/src/Blocks/BlockDoor.h
@@ -101,14 +101,6 @@ public:
}
- virtual void OnPlacedByPlayer(
- 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,
- BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
- ) override;
-
-
virtual bool IsUseable(void) override
{
return true;
@@ -117,11 +109,19 @@ public:
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{
- return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) != E_BLOCK_AIR));
+ return ((a_RelY > 0) && CanBeOn(a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)));
+ }
+
+
+ /** Returns true if door can be placed on the specified block type. */
+ static bool CanBeOn(BLOCKTYPE a_BlockType)
+ {
+ // Vanilla refuses to place doors on transparent blocks
+ return !cBlockInfo::IsTransparent(a_BlockType);
}
- bool CanReplaceBlock(BLOCKTYPE a_BlockType)
+ static bool CanReplaceBlock(BLOCKTYPE a_BlockType)
{
switch (a_BlockType)
{
@@ -170,8 +170,21 @@ public:
}
+ /** Returns a vector pointing one block in the direction the door is facing (where the outside is). */
+ inline static Vector3i GetRelativeDirectionToOutside(NIBBLETYPE a_BlockMeta)
+ {
+ switch (a_BlockMeta & 0x03)
+ {
+ case 0: return Vector3i(-1, 0, 0); // Facing West / XM
+ case 1: return Vector3i( 0, 0, -1); // Facing North / ZM
+ case 2: return Vector3i( 1, 0, 0); // Facing East / XP
+ default: return Vector3i( 0, 0, 1); // Facing South / ZP
+ }
+ }
+
+
/** Returns true if the specified blocktype is any kind of door */
- inline static bool IsDoor(BLOCKTYPE a_Block)
+ inline static bool IsDoorBlockType(BLOCKTYPE a_Block)
{
switch (a_Block)
{
@@ -193,6 +206,8 @@ public:
}
+ /** Returns true iff the door at the specified coords is open.
+ The coords may point to either the top part or the bottom part of the door. */
static NIBBLETYPE IsOpen(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
{
NIBBLETYPE Meta = GetCompleteDoorMeta(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ);
@@ -237,7 +252,7 @@ public:
static void SetOpen(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ, bool a_Open)
{
BLOCKTYPE Block = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ);
- if (!IsDoor(Block))
+ if (!IsDoorBlockType(Block))
{
return;
}
diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp
index d532aa1dc..2de4a3e4c 100644
--- a/src/Blocks/BlockHandler.cpp
+++ b/src/Blocks/BlockHandler.cpp
@@ -369,7 +369,7 @@ void cBlockHandler::OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface
-void cBlockHandler::OnPlacedByPlayer(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, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
+void cBlockHandler::OnPlacedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, const sSetBlock & a_BlockChange)
{
}
diff --git a/src/Blocks/BlockHandler.h b/src/Blocks/BlockHandler.h
index f2298afb5..4dec0dc95 100644
--- a/src/Blocks/BlockHandler.h
+++ b/src/Blocks/BlockHandler.h
@@ -42,15 +42,12 @@ public:
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
);
- /// Called by cWorld::SetBlock() after the block has been set
+ /** Called by cWorld::SetBlock() after the block has been set */
virtual void OnPlaced(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
- /// Called by cClientHandle::HandlePlaceBlock() after the player has placed a new block. Called after OnPlaced().
+ /** Called by cPlayer::PlaceBlocks() for each block after it has been set to the world. Called after OnPlaced(). */
virtual void OnPlacedByPlayer(
- 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,
- BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
+ cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, const sSetBlock & a_BlockChange
);
/// Called before the player has destroyed a block
@@ -96,7 +93,8 @@ public:
*/
// virtual bool CanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir);
- /// Called to check whether this block supports a rclk action. If it returns true, OnUse() is called
+ /** Called to check whether this block supports a rclk action.
+ If it returns true, OnUse() is called */
virtual bool IsUseable(void);
/** Indicates whether the client will click through this block.
@@ -109,20 +107,21 @@ public:
*/
virtual bool DoesIgnoreBuildCollision(void);
- /// Similar to DoesIgnoreBuildCollision(void), but is used for cases where block meta/player item-in-hand is needed to determine collision (thin snow)
+ /** Similar to DoesIgnoreBuildCollision(void), but is used for cases where block's meta or
+ player's item-in-hand is needed to determine collision (thin snow) */
virtual bool DoesIgnoreBuildCollision(cPlayer *, NIBBLETYPE a_Meta)
{
UNUSED(a_Meta);
return DoesIgnoreBuildCollision();
}
- /// Returns if this block drops if it gets destroyed by an unsuitable situation. Default: true
+ /** Returns if this block drops if it gets destroyed by an unsuitable situation.
+ Default: true */
virtual bool DoesDropOnUnsuitable(void);
/** Called when one of the neighbors gets set; equivalent to MC block update.
By default drops if position no more suitable (CanBeAt(), DoesDropOnUnsuitable(), Drop()),
- and wakes up all simulators on the block.
- */
+ and wakes up all simulators on the block. */
virtual void Check(cChunkInterface & ChunkInterface, cBlockPluginInterface & a_PluginInterface, int a_RelX, int a_RelY, int a_RelZ, cChunk & a_Chunk);
/// Rotates a given block meta counter-clockwise. Default: no change
diff --git a/src/Blocks/BlockMobHead.h b/src/Blocks/BlockMobHead.h
index e21e42334..cb8143749 100644
--- a/src/Blocks/BlockMobHead.h
+++ b/src/Blocks/BlockMobHead.h
@@ -12,16 +12,18 @@ class cBlockMobHeadHandler :
public cBlockEntityHandler
{
public:
- cBlockMobHeadHandler(BLOCKTYPE a_BlockType)
- : cBlockEntityHandler(a_BlockType)
+ cBlockMobHeadHandler(BLOCKTYPE a_BlockType):
+ cBlockEntityHandler(a_BlockType)
{
}
+
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
{
- // The drop spawn is in OnDestroyed method
+ // The drop spawn is in the OnDestroyedByPlayer method
}
+
virtual void OnDestroyedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override
{
if (a_Player->IsGameModeCreative())
@@ -61,202 +63,6 @@ public:
a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ, Callback);
}
-
- bool TrySpawnWither(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
- {
- if (a_BlockY < 2)
- {
- return false;
- }
-
- class cCallback : public cBlockEntityCallback
- {
- bool m_IsWither;
-
- virtual bool Item(cBlockEntity * a_BlockEntity)
- {
- if (a_BlockEntity->GetBlockType() != E_BLOCK_HEAD)
- {
- return false;
- }
- cMobHeadEntity * MobHeadEntity = static_cast(a_BlockEntity);
-
- m_IsWither = (MobHeadEntity->GetType() == SKULL_TYPE_WITHER);
- return false;
- }
-
- public:
- cCallback () : m_IsWither(false) {}
-
- bool IsWither(void) const { return m_IsWither; }
-
- void Reset(void) { m_IsWither = false; }
-
- } CallbackA, CallbackB;
-
- class cPlayerCallback : public cPlayerListCallback
- {
- Vector3f m_Pos;
-
- virtual bool Item(cPlayer * a_Player)
- {
- // TODO 2014-05-21 xdot: Vanilla minecraft uses an AABB check instead of a radius one
- double Dist = (a_Player->GetPosition() - m_Pos).Length();
- if (Dist < 50.0)
- {
- // If player is close, award achievement
- a_Player->AwardAchievement(achSpawnWither);
- }
- return false;
- }
-
- public:
- cPlayerCallback(const Vector3f & a_Pos) : m_Pos(a_Pos) {}
-
- } PlayerCallback(Vector3f((float)a_BlockX, (float)a_BlockY, (float)a_BlockZ));
-
- a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ, CallbackA);
-
- if (!CallbackA.IsWither())
- {
- return false;
- }
-
- CallbackA.Reset();
-
- BLOCKTYPE BlockY1 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ);
- BLOCKTYPE BlockY2 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 2, a_BlockZ);
-
- if ((BlockY1 != E_BLOCK_SOULSAND) || (BlockY2 != E_BLOCK_SOULSAND))
- {
- return false;
- }
-
- a_WorldInterface.DoWithBlockEntityAt(a_BlockX - 1, a_BlockY, a_BlockZ, CallbackA);
- a_WorldInterface.DoWithBlockEntityAt(a_BlockX + 1, a_BlockY, a_BlockZ, CallbackB);
-
- BLOCKTYPE Block1 = a_ChunkInterface.GetBlock(a_BlockX - 1, a_BlockY - 1, a_BlockZ);
- BLOCKTYPE Block2 = a_ChunkInterface.GetBlock(a_BlockX + 1, a_BlockY - 1, a_BlockZ);
-
- if ((Block1 == E_BLOCK_SOULSAND) && (Block2 == E_BLOCK_SOULSAND) && CallbackA.IsWither() && CallbackB.IsWither())
- {
- a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0);
- a_ChunkInterface.FastSetBlock(a_BlockX + 1, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0);
- a_ChunkInterface.FastSetBlock(a_BlockX - 1, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0);
- a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0);
-
- // Block entities
- a_ChunkInterface.SetBlock(a_BlockX + 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
- a_ChunkInterface.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
- a_ChunkInterface.SetBlock(a_BlockX - 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
-
- // Spawn the wither:
- a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, mtWither);
-
- // Award Achievement
- a_WorldInterface.ForEachPlayer(PlayerCallback);
-
- return true;
- }
-
- CallbackA.Reset();
- CallbackB.Reset();
-
- a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ - 1, CallbackA);
- a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ + 1, CallbackB);
-
- Block1 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ - 1);
- Block2 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ + 1);
-
- if ((Block1 == E_BLOCK_SOULSAND) && (Block2 == E_BLOCK_SOULSAND) && CallbackA.IsWither() && CallbackB.IsWither())
- {
- a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0);
- a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ + 1, E_BLOCK_AIR, 0);
- a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ - 1, E_BLOCK_AIR, 0);
- a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0);
-
- // Block entities
- a_ChunkInterface.SetBlock(a_BlockX, a_BlockY, a_BlockZ + 1, E_BLOCK_AIR, 0);
- a_ChunkInterface.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
- a_ChunkInterface.SetBlock(a_BlockX, a_BlockY, a_BlockZ - 1, E_BLOCK_AIR, 0);
-
- // Spawn the wither:
- a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, mtWither);
-
- // Award Achievement
- a_WorldInterface.ForEachPlayer(PlayerCallback);
-
- return true;
- }
-
- return false;
- }
-
- virtual void OnPlacedByPlayer(
- 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,
- BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
- ) override
- {
- class cCallback : public cBlockEntityCallback
- {
- cPlayer * m_Player;
- NIBBLETYPE m_OldBlockMeta;
- NIBBLETYPE m_NewBlockMeta;
-
- virtual bool Item(cBlockEntity * a_BlockEntity)
- {
- if (a_BlockEntity->GetBlockType() != E_BLOCK_HEAD)
- {
- return false;
- }
- cMobHeadEntity * MobHeadEntity = static_cast(a_BlockEntity);
-
- int Rotation = 0;
- if (m_NewBlockMeta == 1)
- {
- Rotation = (int) floor(m_Player->GetYaw() * 16.0F / 360.0F + 0.5) & 0xF;
- }
-
- MobHeadEntity->SetType(static_cast(m_OldBlockMeta));
- MobHeadEntity->SetRotation(static_cast(Rotation));
- MobHeadEntity->GetWorld()->BroadcastBlockEntity(MobHeadEntity->GetPosX(), MobHeadEntity->GetPosY(), MobHeadEntity->GetPosZ());
- return false;
- }
-
- public:
- cCallback (cPlayer * a_CBPlayer, NIBBLETYPE a_OldBlockMeta, NIBBLETYPE a_NewBlockMeta) :
- m_Player(a_CBPlayer),
- m_OldBlockMeta(a_OldBlockMeta),
- m_NewBlockMeta(a_NewBlockMeta)
- {}
- };
- cCallback Callback(a_Player, a_BlockMeta, static_cast(a_BlockFace));
-
- a_BlockMeta = (NIBBLETYPE)a_BlockFace;
- a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ, Callback);
- a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, a_BlockMeta);
-
- if (a_BlockMeta == SKULL_TYPE_WITHER)
- {
- static const Vector3i Coords[] =
- {
- Vector3i( 0, 0, 0),
- Vector3i( 1, 0, 0),
- Vector3i(-1, 0, 0),
- Vector3i( 0, 0, 1),
- Vector3i( 0, 0, -1),
- };
- for (size_t i = 0; i < ARRAYCOUNT(Coords); ++i)
- {
- if (TrySpawnWither(a_ChunkInterface, a_WorldInterface, a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z))
- {
- break;
- }
- } // for i - Coords[]
- }
- }
} ;
diff --git a/src/Blocks/BlockPumpkin.h b/src/Blocks/BlockPumpkin.h
index 275d1422a..af00fbe8e 100644
--- a/src/Blocks/BlockPumpkin.h
+++ b/src/Blocks/BlockPumpkin.h
@@ -17,70 +17,6 @@ public:
}
- virtual void OnPlacedByPlayer(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, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override
- {
- // Check whether the pumpkin is a part of a golem or a snowman
-
- if (a_BlockY < 2)
- {
- // The pumpkin is too low for a golem / snowman
- return;
- }
-
- BLOCKTYPE BlockY1 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ);
- BLOCKTYPE BlockY2 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 2, a_BlockZ);
-
- // Check for a snow golem:
- if ((BlockY1 == E_BLOCK_SNOW_BLOCK) && (BlockY2 == E_BLOCK_SNOW_BLOCK))
- {
- a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
- a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0);
- a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0);
- a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, mtSnowGolem);
- return;
- }
-
- // Check for an iron golem. First check only the body and legs, since those are the same for both orientations:
- if ((BlockY1 != E_BLOCK_IRON_BLOCK) || (BlockY2 != E_BLOCK_IRON_BLOCK))
- {
- // One of the blocks is not an iron, no chance of a golem here
- return;
- }
-
- // Now check both orientations for hands:
- if (
- (a_ChunkInterface.GetBlock(a_BlockX + 1, a_BlockY - 1, a_BlockZ) == E_BLOCK_IRON_BLOCK) &&
- (a_ChunkInterface.GetBlock(a_BlockX - 1, a_BlockY - 1, a_BlockZ) == E_BLOCK_IRON_BLOCK)
- )
- {
- // Remove the iron blocks:
- a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
- a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0);
- a_ChunkInterface.FastSetBlock(a_BlockX + 1, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0);
- a_ChunkInterface.FastSetBlock(a_BlockX - 1, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0);
- a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0);
-
- // Spawn the golem:
- a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, mtIronGolem);
- }
- else if (
- (a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ + 1) == E_BLOCK_IRON_BLOCK) &&
- (a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ - 1) == E_BLOCK_IRON_BLOCK)
- )
- {
- // Remove the iron blocks:
- a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
- a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0);
- a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ + 1, E_BLOCK_AIR, 0);
- a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ - 1, E_BLOCK_AIR, 0);
- a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0);
-
- // Spawn the golem:
- a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, mtIronGolem);
- }
- }
-
-
virtual bool GetPlacementBlockTypeMeta(
cChunkInterface & a_ChunkInterface, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
diff --git a/src/Blocks/BlockSignPost.h b/src/Blocks/BlockSignPost.h
index d97501651..99c000633 100644
--- a/src/Blocks/BlockSignPost.h
+++ b/src/Blocks/BlockSignPost.h
@@ -53,17 +53,6 @@ public:
}
- virtual void OnPlacedByPlayer(
- 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,
- BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
- ) override
- {
- a_Player->GetClientHandle()->SendEditSign(a_BlockX, a_BlockY, a_BlockZ);
- }
-
-
virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override
{
return (a_Meta + 4) & 0x0f;
diff --git a/src/Blocks/BlockWallSign.h b/src/Blocks/BlockWallSign.h
index 0abe9c52c..b6599d033 100644
--- a/src/Blocks/BlockWallSign.h
+++ b/src/Blocks/BlockWallSign.h
@@ -27,17 +27,6 @@ public:
}
- virtual void OnPlacedByPlayer(
- 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,
- BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
- ) override
- {
- a_Player->GetClientHandle()->SendEditSign(a_BlockX, a_BlockY, a_BlockZ);
- }
-
-
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{
int BlockX = (a_Chunk.GetPosX() * cChunkDef::Width) + a_RelX;
diff --git a/src/Chunk.cpp b/src/Chunk.cpp
index 555e85015..b06eed316 100644
--- a/src/Chunk.cpp
+++ b/src/Chunk.cpp
@@ -49,14 +49,14 @@
////////////////////////////////////////////////////////////////////////////////
// sSetBlock:
-sSetBlock::sSetBlock( int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) // absolute block position
- : x( a_BlockX)
- , y( a_BlockY)
- , z( a_BlockZ)
- , BlockType( a_BlockType)
- , BlockMeta( a_BlockMeta)
-{
- cChunkDef::AbsoluteToRelative(x, y, z, ChunkX, ChunkZ);
+sSetBlock::sSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta):
+ m_RelX(a_BlockX),
+ m_RelY(a_BlockY),
+ m_RelZ(a_BlockZ),
+ m_BlockType(a_BlockType),
+ m_BlockMeta(a_BlockMeta)
+{
+ cChunkDef::AbsoluteToRelative(m_RelX, m_RelY, m_RelZ, m_ChunkX, m_ChunkZ);
}
diff --git a/src/ChunkDef.h b/src/ChunkDef.h
index 8f1d416ad..b62656a58 100644
--- a/src/ChunkDef.h
+++ b/src/ChunkDef.h
@@ -347,18 +347,32 @@ public:
struct sSetBlock
{
- int x, y, z;
- int ChunkX, ChunkZ;
- BLOCKTYPE BlockType;
- NIBBLETYPE BlockMeta;
-
- sSetBlock( int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); // absolute block position
- sSetBlock(int a_ChunkX, int a_ChunkZ, int a_X, int a_Y, int a_Z, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) :
- x(a_X), y(a_Y), z(a_Z),
- ChunkX(a_ChunkX), ChunkZ(a_ChunkZ),
- BlockType(a_BlockType),
- BlockMeta(a_BlockMeta)
- {}
+ int m_RelX, m_RelY, m_RelZ;
+ int m_ChunkX, m_ChunkZ;
+ BLOCKTYPE m_BlockType;
+ NIBBLETYPE m_BlockMeta;
+
+ sSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
+
+ sSetBlock(int a_ChunkX, int a_ChunkZ, int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) :
+ m_RelX(a_RelX), m_RelY(a_RelY), m_RelZ(a_RelZ),
+ m_ChunkX(a_ChunkX), m_ChunkZ(a_ChunkZ),
+ m_BlockType(a_BlockType),
+ m_BlockMeta(a_BlockMeta)
+ {
+ ASSERT((a_RelX >= 0) && (a_RelX < cChunkDef::Width));
+ ASSERT((a_RelZ >= 0) && (a_RelZ < cChunkDef::Width));
+ }
+
+ /** Returns the absolute X coord of the stored block. */
+ int GetX(void) const { return m_RelX + cChunkDef::Width * m_ChunkX; }
+
+ /** Returns the absolute Y coord of the stored block.
+ Is the same as relative Y coords, because there's no Y relativization. */
+ int GetY(void) const { return m_RelY; }
+
+ /** Returns the absolute Z coord of the stored block. */
+ int GetZ(void) const { return m_RelZ + cChunkDef::Width * m_ChunkZ; }
};
typedef std::list sSetBlockList;
@@ -385,6 +399,16 @@ public:
typedef std::list cChunkCoordsList;
typedef std::vector cChunkCoordsVector;
+/** A simple hash function for chunk coords, we assume that chunk coords won't use more than 16 bits, so the hash is almost an identity.
+Used for std::unordered_map */
+template<> struct std::hash
+{
+ size_t operator ()(const cChunkCoords & a_Coords)
+ {
+ return (static_cast(a_Coords.m_ChunkX) << 16) ^ static_cast(a_Coords.m_ChunkZ);
+ }
+};
+
diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp
index 6aff3a754..c8f5aa673 100644
--- a/src/ChunkMap.cpp
+++ b/src/ChunkMap.cpp
@@ -1101,17 +1101,17 @@ void cChunkMap::FastSetBlocks(sSetBlockList & a_BlockList)
// Process all items from a_BlockList, either successfully or by placing into Failed
while (!a_BlockList.empty())
{
- int ChunkX = a_BlockList.front().ChunkX;
- int ChunkZ = a_BlockList.front().ChunkZ;
+ int ChunkX = a_BlockList.front().m_ChunkX;
+ int ChunkZ = a_BlockList.front().m_ChunkZ;
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ);
if ((Chunk != nullptr) && Chunk->IsValid())
{
for (sSetBlockList::iterator itr = a_BlockList.begin(); itr != a_BlockList.end();)
{
- if ((itr->ChunkX == ChunkX) && (itr->ChunkZ == ChunkZ))
+ if ((itr->m_ChunkX == ChunkX) && (itr->m_ChunkZ == ChunkZ))
{
- Chunk->FastSetBlock(itr->x, itr->y, itr->z, itr->BlockType, itr->BlockMeta);
+ Chunk->FastSetBlock(itr->m_RelX, itr->m_RelY, itr->m_RelZ, itr->m_BlockType, itr->m_BlockMeta);
itr = a_BlockList.erase(itr);
}
else
@@ -1125,7 +1125,7 @@ void cChunkMap::FastSetBlocks(sSetBlockList & a_BlockList)
// The chunk is not valid, move all blocks within this chunk to Failed
for (sSetBlockList::iterator itr = a_BlockList.begin(); itr != a_BlockList.end();)
{
- if ((itr->ChunkX == ChunkX) && (itr->ChunkZ == ChunkZ))
+ if ((itr->m_ChunkX == ChunkX) && (itr->m_ChunkZ == ChunkZ))
{
Failed.push_back(*itr);
itr = a_BlockList.erase(itr);
@@ -1146,6 +1146,34 @@ void cChunkMap::FastSetBlocks(sSetBlockList & a_BlockList)
+void cChunkMap::SetBlocks(const sSetBlockVector & a_Blocks)
+{
+ cCSLock lock(m_CSLayers);
+ cChunkPtr chunk = nullptr;
+ int lastChunkX = 0x7fffffff; // Bogus coords so that chunk is updated on first pass
+ int lastChunkZ = 0x7fffffff;
+ for (auto block: a_Blocks)
+ {
+ // Update the chunk, if different from last time:
+ if ((block.m_ChunkX != lastChunkX) || (block.m_ChunkZ != lastChunkZ))
+ {
+ lastChunkX = block.m_ChunkX;
+ lastChunkZ = block.m_ChunkZ;
+ chunk = GetChunk(lastChunkX, lastChunkZ);
+ }
+
+ // If the chunk is valid, set the block:
+ if (chunk != nullptr)
+ {
+ chunk->SetBlock(block.m_RelX, block.m_RelY, block.m_RelZ, block.m_BlockType, block.m_BlockMeta);
+ }
+ } // for block - a_Blocks[]
+}
+
+
+
+
+
void cChunkMap::CollectPickupsByPlayer(cPlayer & a_Player)
{
int BlockX = (int)(a_Player.GetPosX()); // Truncating doesn't matter much; we're scanning entire chunks anyway
@@ -1175,28 +1203,28 @@ void cChunkMap::CollectPickupsByPlayer(cPlayer & a_Player)
BLOCKTYPE cChunkMap::GetBlock(int a_BlockX, int a_BlockY, int a_BlockZ)
{
+ int X = a_BlockX, Y = a_BlockY, Z = a_BlockZ;
+ int ChunkX, ChunkZ;
+ cChunkDef::AbsoluteToRelative(X, Y, Z, ChunkX, ChunkZ);
+
// First check if it isn't queued in the m_FastSetBlockQueue:
{
- int X = a_BlockX, Y = a_BlockY, Z = a_BlockZ;
- int ChunkX, ChunkZ;
- cChunkDef::AbsoluteToRelative(X, Y, Z, ChunkX, ChunkZ);
cCSLock Lock(m_CSFastSetBlock);
for (sSetBlockList::iterator itr = m_FastSetBlockQueue.begin(); itr != m_FastSetBlockQueue.end(); ++itr)
{
- if ((itr->x == X) && (itr->y == Y) && (itr->z == Z) && (itr->ChunkX == ChunkX) && (itr->ChunkZ == ChunkZ))
+ if ((itr->m_RelX == X) && (itr->m_RelY == Y) && (itr->m_RelZ == Z) && (itr->m_ChunkX == ChunkX) && (itr->m_ChunkZ == ChunkZ))
{
- return itr->BlockType;
+ return itr->m_BlockType;
}
} // for itr - m_FastSetBlockQueue[]
}
- int ChunkX, ChunkZ;
- cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ);
-
+
+ // Not in the queue, query the chunk, if loaded:
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunk(ChunkX, ChunkZ);
if ((Chunk != nullptr) && Chunk->IsValid())
{
- return Chunk->GetBlock(a_BlockX, a_BlockY, a_BlockZ);
+ return Chunk->GetBlock(X, Y, Z);
}
return 0;
}
@@ -1207,25 +1235,28 @@ BLOCKTYPE cChunkMap::GetBlock(int a_BlockX, int a_BlockY, int a_BlockZ)
NIBBLETYPE cChunkMap::GetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ)
{
+ int X = a_BlockX, Y = a_BlockY, Z = a_BlockZ;
+ int ChunkX, ChunkZ;
+ cChunkDef::AbsoluteToRelative(X, Y, Z, ChunkX, ChunkZ);
+
// First check if it isn't queued in the m_FastSetBlockQueue:
{
cCSLock Lock(m_CSFastSetBlock);
for (sSetBlockList::iterator itr = m_FastSetBlockQueue.begin(); itr != m_FastSetBlockQueue.end(); ++itr)
{
- if ((itr->x == a_BlockX) && (itr->y == a_BlockY) && (itr->z == a_BlockZ))
+ if ((itr->m_RelX == X) && (itr->m_RelY == Y) && (itr->m_RelZ == Z) && (itr->m_ChunkX == ChunkX) && (itr->m_ChunkZ == ChunkZ))
{
- return itr->BlockMeta;
+ return itr->m_BlockMeta;
}
} // for itr - m_FastSetBlockQueue[]
}
- int ChunkX, ChunkZ;
- cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ);
-
+
+ // Not in the queue, query the chunk, if loaded:
cCSLock Lock(m_CSLayers);
- cChunkPtr Chunk = GetChunk( ChunkX, ChunkZ);
+ cChunkPtr Chunk = GetChunk(ChunkX, ChunkZ);
if ((Chunk != nullptr) && Chunk->IsValid())
{
- return Chunk->GetMeta(a_BlockX, a_BlockY, a_BlockZ);
+ return Chunk->GetMeta(X, Y, Z);
}
return 0;
}
@@ -1373,14 +1404,14 @@ void cChunkMap::ReplaceBlocks(const sSetBlockVector & a_Blocks, BLOCKTYPE a_Filt
cCSLock Lock(m_CSLayers);
for (sSetBlockVector::const_iterator itr = a_Blocks.begin(); itr != a_Blocks.end(); ++itr)
{
- cChunkPtr Chunk = GetChunk(itr->ChunkX, itr->ChunkZ);
+ cChunkPtr Chunk = GetChunk(itr->m_ChunkX, itr->m_ChunkZ);
if ((Chunk == nullptr) || !Chunk->IsValid())
{
continue;
}
- if (Chunk->GetBlock(itr->x, itr->y, itr->z) == a_FilterBlockType)
+ if (Chunk->GetBlock(itr->m_RelX, itr->m_RelY, itr->m_RelZ) == a_FilterBlockType)
{
- Chunk->SetBlock(itr->x, itr->y, itr->z, itr->BlockType, itr->BlockMeta);
+ Chunk->SetBlock(itr->m_RelX, itr->m_RelY, itr->m_RelZ, itr->m_BlockType, itr->m_BlockMeta);
}
}
}
@@ -1394,24 +1425,24 @@ void cChunkMap::ReplaceTreeBlocks(const sSetBlockVector & a_Blocks)
cCSLock Lock(m_CSLayers);
for (sSetBlockVector::const_iterator itr = a_Blocks.begin(); itr != a_Blocks.end(); ++itr)
{
- cChunkPtr Chunk = GetChunk(itr->ChunkX, itr->ChunkZ);
+ cChunkPtr Chunk = GetChunk(itr->m_ChunkX, itr->m_ChunkZ);
if ((Chunk == nullptr) || !Chunk->IsValid())
{
continue;
}
- switch (Chunk->GetBlock(itr->x, itr->y, itr->z))
+ switch (Chunk->GetBlock(itr->m_RelX, itr->m_RelY, itr->m_RelZ))
{
CASE_TREE_OVERWRITTEN_BLOCKS:
{
- Chunk->SetBlock(itr->x, itr->y, itr->z, itr->BlockType, itr->BlockMeta);
+ Chunk->SetBlock(itr->m_RelX, itr->m_RelY, itr->m_RelZ, itr->m_BlockType, itr->m_BlockMeta);
break;
}
case E_BLOCK_LEAVES:
case E_BLOCK_NEW_LEAVES:
{
- if ((itr->BlockType == E_BLOCK_LOG) || (itr->BlockType == E_BLOCK_NEW_LOG))
+ if ((itr->m_BlockType == E_BLOCK_LOG) || (itr->m_BlockType == E_BLOCK_NEW_LOG))
{
- Chunk->SetBlock(itr->x, itr->y, itr->z, itr->BlockType, itr->BlockMeta);
+ Chunk->SetBlock(itr->m_RelX, itr->m_RelY, itr->m_RelZ, itr->m_BlockType, itr->m_BlockMeta);
}
break;
}
@@ -1507,7 +1538,7 @@ bool cChunkMap::GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure)
cCSLock Lock(m_CSLayers);
for (sSetBlockVector::iterator itr = a_Blocks.begin(); itr != a_Blocks.end(); ++itr)
{
- cChunkPtr Chunk = GetChunk(itr->ChunkX, itr->ChunkZ);
+ cChunkPtr Chunk = GetChunk(itr->m_ChunkX, itr->m_ChunkZ);
if ((Chunk == nullptr) || !Chunk->IsValid())
{
if (!a_ContinueOnFailure)
@@ -1517,8 +1548,8 @@ bool cChunkMap::GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure)
res = false;
continue;
}
- itr->BlockType = Chunk->GetBlock(itr->x, itr->y, itr->z);
- itr->BlockMeta = Chunk->GetMeta(itr->x, itr->y, itr->z);
+ itr->m_BlockType = Chunk->GetBlock(itr->m_RelX, itr->m_RelY, itr->m_RelZ);
+ itr->m_BlockMeta = Chunk->GetMeta(itr->m_RelX, itr->m_RelY, itr->m_RelZ);
}
return res;
}
@@ -1527,11 +1558,11 @@ bool cChunkMap::GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure)
-bool cChunkMap::DigBlock(int a_X, int a_Y, int a_Z)
+bool cChunkMap::DigBlock(int a_BlockX, int a_BlockY, int a_BlockZ)
{
- int PosX = a_X, PosY = a_Y, PosZ = a_Z, ChunkX, ChunkZ;
+ int PosX = a_BlockX, PosY = a_BlockY, PosZ = a_BlockZ, ChunkX, ChunkZ;
- cChunkDef::AbsoluteToRelative( PosX, PosY, PosZ, ChunkX, ChunkZ);
+ cChunkDef::AbsoluteToRelative(PosX, PosY, PosZ, ChunkX, ChunkZ);
{
cCSLock Lock(m_CSLayers);
@@ -1542,7 +1573,7 @@ bool cChunkMap::DigBlock(int a_X, int a_Y, int a_Z)
}
DestChunk->SetBlock(PosX, PosY, PosZ, E_BLOCK_AIR, 0);
- m_World->GetSimulatorManager()->WakeUp(a_X, a_Y, a_Z, DestChunk);
+ m_World->GetSimulatorManager()->WakeUp(a_BlockX, a_BlockY, a_BlockZ, DestChunk);
}
return true;
diff --git a/src/ChunkMap.h b/src/ChunkMap.h
index 6a858b06d..fe0bb3733 100644
--- a/src/ChunkMap.h
+++ b/src/ChunkMap.h
@@ -143,7 +143,13 @@ public:
void FastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
void FastSetQueuedBlocks();
- void FastSetBlocks (sSetBlockList & a_BlockList);
+ void FastSetBlocks(sSetBlockList & a_BlockList);
+
+ /** Performs the specified single-block set operations simultaneously, as if SetBlock() was called for each item.
+ Is more efficient than calling SetBlock() multiple times.
+ If the chunk for any of the blocks is not loaded, the set operation is ignored silently. */
+ void SetBlocks(const sSetBlockVector & a_Blocks);
+
void CollectPickupsByPlayer(cPlayer & a_Player);
BLOCKTYPE GetBlock (int a_BlockX, int a_BlockY, int a_BlockZ);
@@ -173,11 +179,20 @@ public:
(Re)sends the chunks to their relevant clients if successful. */
bool SetAreaBiome(int a_MinX, int a_MaxX, int a_MinZ, int a_MaxZ, EMCSBiome a_Biome);
- /** Retrieves block types of the specified blocks. If a chunk is not loaded, doesn't modify the block. Returns true if all blocks were read. */
+ /** Retrieves block types and metas of the specified blocks.
+ If a chunk is not loaded, doesn't modify the block and consults a_ContinueOnFailure whether to process the rest of the array.
+ Returns true if all blocks were read, false if any one failed. */
bool GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure);
- bool DigBlock (int a_X, int a_Y, int a_Z);
- void SendBlockTo(int a_X, int a_Y, int a_Z, cPlayer * a_Player);
+ /** Removes the block at the specified coords and wakes up simulators.
+ Returns false if the chunk is not loaded (and the block is not dug).
+ Returns true if successful. */
+ bool DigBlock(int a_BlockX, int a_BlockY, int a_BlockZ);
+
+ /** Sends the block at the specified coords to the specified player.
+ Uses a blockchange packet to send the block.
+ If the relevant chunk isn't loaded, doesn't do anything. */
+ void SendBlockTo(int a_BlockX, int a_BlockY, int a_BlockZ, cPlayer * a_Player);
/** Compares clients of two chunks, calls the callback accordingly */
void CompareChunkClients(int a_ChunkX1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkZ2, cClientDiffCallback & a_Callback);
diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp
index cb9d34c84..6fe6e99fa 100644
--- a/src/ClientHandle.cpp
+++ b/src/ClientHandle.cpp
@@ -1346,12 +1346,19 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e
if (ItemHandler->IsPlaceable() && (a_BlockFace != BLOCK_FACE_NONE))
{
- HandlePlaceBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, *ItemHandler);
+ if (!ItemHandler->OnPlayerPlace(*World, *m_Player, Equipped, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ))
+ {
+ // Placement failed, bail out
+ return;
+ }
}
else if ((ItemHandler->IsFood() || ItemHandler->IsDrinkable(EquippedDamage)))
{
- if ((m_Player->IsSatiated() || m_Player->IsGameModeCreative()) &&
- ItemHandler->IsFood() && (Equipped.m_ItemType != E_ITEM_GOLDEN_APPLE))
+ if (
+ (m_Player->IsSatiated() || m_Player->IsGameModeCreative()) && // Only creative or hungry players can eat
+ ItemHandler->IsFood() &&
+ (Equipped.m_ItemType != E_ITEM_GOLDEN_APPLE) // Golden apple is a special case, it is used instead of eaten
+ )
{
// The player is satiated or in creative, and trying to eat
return;
@@ -1379,151 +1386,6 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e
-void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, cItemHandler & a_ItemHandler)
-{
- BLOCKTYPE EquippedBlock = (BLOCKTYPE)(m_Player->GetEquippedItem().m_ItemType);
- if (a_BlockFace < 0)
- {
- // Clicked in air
- return;
- }
-
- cWorld * World = m_Player->GetWorld();
-
- BLOCKTYPE ClickedBlock;
- NIBBLETYPE ClickedBlockMeta;
- NIBBLETYPE EquippedBlockDamage = (NIBBLETYPE)(m_Player->GetEquippedItem().m_ItemDamage);
-
- if ((a_BlockY < 0) || (a_BlockY >= cChunkDef::Height))
- {
- // The block is being placed outside the world, ignore this packet altogether (#128)
- return;
- }
-
- World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, ClickedBlock, ClickedBlockMeta);
-
- // Special slab handling - placing a slab onto another slab produces a dblslab instead:
- if (
- cBlockSlabHandler::IsAnySlabType(ClickedBlock) && // Is there a slab already?
- cBlockSlabHandler::IsAnySlabType(EquippedBlock) && // Is the player placing another slab?
- ((ClickedBlockMeta & 0x07) == EquippedBlockDamage) && // Is it the same slab type?
- (
- (a_BlockFace == BLOCK_FACE_TOP) || // Clicking the top of a bottom slab
- (a_BlockFace == BLOCK_FACE_BOTTOM) // Clicking the bottom of a top slab
- )
- )
- {
- // Coordinates at clicked block, which was an eligible slab, and either top or bottom faces were clicked
- // If clicked top face and slab occupies the top voxel, we want a slab to be placed above it (therefore increment Y)
- // Else if clicked bottom face and slab occupies the bottom voxel, decrement Y for the same reason
- // Don't touch coordinates if anything else because a dblslab opportunity is present
- if ((ClickedBlockMeta & 0x08) && (a_BlockFace == BLOCK_FACE_TOP))
- {
- ++a_BlockY;
- }
- else if (!(ClickedBlockMeta & 0x08) && (a_BlockFace == BLOCK_FACE_BOTTOM))
- {
- --a_BlockY;
- }
- World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, ClickedBlock, ClickedBlockMeta);
- }
- else
- {
- // Check if the block ignores build collision (water, grass etc.):
- if (
- BlockHandler(ClickedBlock)->DoesIgnoreBuildCollision() ||
- BlockHandler(ClickedBlock)->DoesIgnoreBuildCollision(m_Player, ClickedBlockMeta)
- )
- {
- cChunkInterface ChunkInterface(World->GetChunkMap());
- BlockHandler(ClickedBlock)->OnDestroyedByPlayer(ChunkInterface, *World, m_Player, a_BlockX, a_BlockY, a_BlockZ);
- }
- else
- {
- AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
-
- if ((a_BlockY < 0) || (a_BlockY >= cChunkDef::Height))
- {
- // The block is being placed outside the world, ignore this packet altogether (#128)
- return;
- }
-
- NIBBLETYPE PlaceMeta;
- BLOCKTYPE PlaceBlock;
- World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, PlaceBlock, PlaceMeta);
-
- // Clicked on side of block, make sure that placement won't be cancelled if there is a slab able to be double slabbed.
- // No need to do combinability (dblslab) checks, client will do that here.
- if (cBlockSlabHandler::IsAnySlabType(PlaceBlock))
- {
- // It's a slab, don't do checks and proceed to double-slabbing
- }
- else
- {
- if (
- !BlockHandler(PlaceBlock)->DoesIgnoreBuildCollision() &&
- !BlockHandler(PlaceBlock)->DoesIgnoreBuildCollision(m_Player, PlaceMeta)
- )
- {
- // Tried to place a block *into* another?
- // Happens when you place a block aiming at side of block with a torch on it or stem beside it
- return;
- }
- }
- }
- }
-
- BLOCKTYPE BlockType;
- NIBBLETYPE BlockMeta;
- if (!a_ItemHandler.GetPlacementBlockTypeMeta(World, m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta))
- {
- // Handler refused the placement, send that information back to the client:
- World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player);
- m_Player->GetInventory().SendEquippedSlot();
- return;
- }
-
- cBlockHandler * NewBlock = BlockHandler(BlockType);
-
- if (cRoot::Get()->GetPluginManager()->CallHookPlayerPlacingBlock(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta))
- {
- // A plugin doesn't agree with placing the block, revert the block on the client:
- World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player);
- m_Player->GetInventory().SendEquippedSlot();
- return;
- }
-
- // The actual block placement:
- World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, BlockType, BlockMeta);
- if (!m_Player->IsGameModeCreative())
- {
- m_Player->GetInventory().RemoveOneEquippedItem();
- }
-
- 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);
-
- AString PlaceSound = cBlockInfo::GetPlaceSound(BlockType);
- float Volume = 1.0f, Pitch = 0.8f;
- if (PlaceSound == "dig.metal")
- {
- Pitch = 1.2f;
- PlaceSound = "dig.stone";
- }
- else if (PlaceSound == "random.anvil_land")
- {
- Volume = 0.65f;
- }
-
- World->BroadcastSoundEffect(PlaceSound, a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5, Volume, Pitch);
-
- cRoot::Get()->GetPluginManager()->CallHookPlayerPlacedBlock(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta);
-}
-
-
-
-
-
void cClientHandle::HandleChat(const AString & a_Message)
{
// We no longer need to postpone message processing, because the messages already arrive in the Tick thread
diff --git a/src/ClientHandle.h b/src/ClientHandle.h
index 25dd250d9..5e10bb52f 100644
--- a/src/ClientHandle.h
+++ b/src/ClientHandle.h
@@ -459,9 +459,6 @@ private:
UInt32 m_ProtocolVersion;
- /** Handles the block placing packet when it is a real block placement (not block-using, item-using or eating) */
- void HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, cItemHandler & a_ItemHandler);
-
/** Returns true if the rate block interactions is within a reasonable limit (bot protection) */
bool CheckBlockInteractionsRate(void);
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index 15920d6cf..7bdd1c6f7 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -2,6 +2,7 @@
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
#include "Player.h"
+#include
#include "../ChatColor.h"
#include "../Server.h"
#include "../UI/Window.h"
@@ -19,6 +20,10 @@
#include "../WorldStorage/StatSerializer.h"
#include "../CompositeChat.h"
+#include "../Blocks/BlockHandler.h"
+#include "../Blocks/BlockSlab.h"
+#include "../Blocks/ChunkInterface.h"
+
#include "../IniFile.h"
#include "json/json.h"
@@ -2168,6 +2173,97 @@ void cPlayer::LoadRank(void)
+bool cPlayer::PlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
+{
+ sSetBlockVector blk{{a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta}};
+ return PlaceBlocks(blk);
+}
+
+
+
+
+
+void cPlayer::SendBlocksAround(int a_BlockX, int a_BlockY, int a_BlockZ, int a_Range)
+{
+ // Collect the coords of all the blocks to send:
+ sSetBlockVector blks;
+ for (int y = a_BlockY - a_Range + 1; y < a_BlockY + a_Range; y++)
+ {
+ for (int z = a_BlockZ - a_Range + 1; z < a_BlockZ + a_Range; z++)
+ {
+ for (int x = a_BlockX - a_Range + 1; x < a_BlockX + a_Range; x++)
+ {
+ blks.emplace_back(x, y, z, E_BLOCK_AIR, 0); // Use fake blocktype, it will get set later on.
+ };
+ };
+ } // for y
+
+ // Get the values of all the blocks:
+ if (!m_World->GetBlocks(blks, false))
+ {
+ LOGD("%s: Cannot query all blocks, not sending an update", __FUNCTION__);
+ return;
+ }
+
+ // Divide the block changes by their respective chunks:
+ std::unordered_map Changes;
+ for (const auto & blk: blks)
+ {
+ Changes[cChunkCoords(blk.m_ChunkX, blk.m_ChunkZ)].push_back(blk);
+ } // for blk - blks[]
+ blks.clear();
+
+ // Send the blocks for each affected chunk:
+ for (auto itr = Changes.cbegin(), end = Changes.cend(); itr != end; ++itr)
+ {
+ m_ClientHandle->SendBlockChanges(itr->first.m_ChunkX, itr->first.m_ChunkZ, itr->second);
+ }
+}
+
+
+
+
+
+bool cPlayer::PlaceBlocks(const sSetBlockVector & a_Blocks)
+{
+ // Call the "placing" hooks; if any fail, abort:
+ cPluginManager * pm = cPluginManager::Get();
+ for (auto blk: a_Blocks)
+ {
+ if (pm->CallHookPlayerPlacingBlock(*this, blk))
+ {
+ // Abort - re-send all the current blocks in the a_Blocks' coords to the client:
+ for (auto blk2: a_Blocks)
+ {
+ m_World->SendBlockTo(blk2.GetX(), blk2.GetY(), blk2.GetZ(), this);
+ }
+ return false;
+ }
+ } // for blk - a_Blocks[]
+
+ // Set the blocks:
+ m_World->SetBlocks(a_Blocks);
+
+ // Notify the blockhandlers:
+ cChunkInterface ChunkInterface(m_World->GetChunkMap());
+ for (auto blk: a_Blocks)
+ {
+ cBlockHandler * newBlock = BlockHandler(blk.m_BlockType);
+ newBlock->OnPlacedByPlayer(ChunkInterface, *m_World, this, blk);
+ }
+
+ // Call the "placed" hooks:
+ for (auto blk: a_Blocks)
+ {
+ pm->CallHookPlayerPlacedBlock(*this, blk);
+ }
+ return true;
+}
+
+
+
+
+
void cPlayer::Detach()
{
super::Detach();
diff --git a/src/Entities/Player.h b/src/Entities/Player.h
index c643aaa8e..33ab5293c 100644
--- a/src/Entities/Player.h
+++ b/src/Entities/Player.h
@@ -440,8 +440,26 @@ public:
Loads the m_Rank, m_Permissions, m_MsgPrefix, m_MsgSuffix and m_MsgNameColorCode members. */
void LoadRank(void);
+ /** Calls the block-placement hook and places the block in the world, unless refused by the hook.
+ If the hook prevents the placement, sends the current block at the specified coords back to the client.
+ Assumes that all the blocks are in currently loaded chunks. */
+ bool PlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
+
+ /** Sends the block in the specified range around the specified coord to the client
+ as a block change packet.
+ The blocks in range (a_BlockX - a_Range, a_BlockX + a_Range) are sent (NY-metric). */
+ void SendBlocksAround(int a_BlockX, int a_BlockY, int a_BlockZ, int a_Range = 1);
+
// tolua_end
+ /** Calls the block placement hooks and places the blocks in the world.
+ First the "placing" hooks for all the blocks are called, then the blocks are placed, and finally
+ the "placed" hooks are called.
+ If the any of the "placing" hooks aborts, none of the blocks are placed and the function returns false.
+ Returns true if all the blocks are placed.
+ Assumes that all the blocks are in currently loaded chunks. */
+ bool PlaceBlocks(const sSetBlockVector & a_Blocks);
+
// cEntity overrides:
virtual bool IsCrouched (void) const { return m_IsCrouched; }
virtual bool IsSprinting(void) const { return m_IsSprinting; }
diff --git a/src/Generating/StructGen.cpp b/src/Generating/StructGen.cpp
index 2f685c808..2d5a73739 100644
--- a/src/Generating/StructGen.cpp
+++ b/src/Generating/StructGen.cpp
@@ -123,18 +123,18 @@ void cStructGenTrees::GenerateSingleTree(
// Check if the generated image fits the terrain. Only the logs are checked:
for (sSetBlockVector::const_iterator itr = TreeLogs.begin(); itr != TreeLogs.end(); ++itr)
{
- if ((itr->ChunkX != a_ChunkX) || (itr->ChunkZ != a_ChunkZ))
+ if ((itr->m_ChunkX != a_ChunkX) || (itr->m_ChunkZ != a_ChunkZ))
{
// Outside the chunk
continue;
}
- if (itr->y >= cChunkDef::Height)
+ if (itr->m_RelY >= 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);
+ BLOCKTYPE Block = a_ChunkDesc.GetBlockType(itr->m_RelX, itr->m_RelY, itr->m_RelZ);
switch (Block)
{
CASE_TREE_ALLOWED_BLOCKS:
@@ -167,14 +167,14 @@ 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) && (itr->y < cChunkDef::Height))
+ if ((itr->m_ChunkX == a_ChunkX) && (itr->m_ChunkZ == a_ChunkZ) && (itr->m_RelY < cChunkDef::Height))
{
// Inside this chunk, integrate into a_ChunkDesc:
- switch (a_ChunkDesc.GetBlockType(itr->x, itr->y, itr->z))
+ switch (a_ChunkDesc.GetBlockType(itr->m_RelX, itr->m_RelY, itr->m_RelZ))
{
case E_BLOCK_LEAVES:
{
- if (itr->BlockType != E_BLOCK_LOG)
+ if (itr->m_BlockType != E_BLOCK_LOG)
{
break;
}
@@ -182,7 +182,7 @@ void cStructGenTrees::ApplyTreeImage(
}
CASE_TREE_OVERWRITTEN_BLOCKS:
{
- a_ChunkDesc.SetBlockTypeMeta(itr->x, itr->y, itr->z, itr->BlockType, itr->BlockMeta);
+ a_ChunkDesc.SetBlockTypeMeta(itr->m_RelX, itr->m_RelY, itr->m_RelZ, itr->m_BlockType, itr->m_BlockMeta);
break;
}
diff --git a/src/Generating/Trees.cpp b/src/Generating/Trees.cpp
index be8b0cd6b..a10e0f4f1 100644
--- a/src/Generating/Trees.cpp
+++ b/src/Generating/Trees.cpp
@@ -403,17 +403,17 @@ void GetLargeAppleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a
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;
+ int X = itr.GetX();
+ int Z = itr.GetZ();
- 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);
+ a_OtherBlocks.push_back(sSetBlock(X, itr.m_RelY - 2, Z, E_BLOCK_LEAVES, E_META_LEAVES_APPLE));
+ PushCoordBlocks(X, itr.m_RelY - 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.m_RelY + 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));
+ PushCoordBlocks(X, itr.m_RelY + 2, Z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
+ a_OtherBlocks.push_back(sSetBlock(X, itr.m_RelY + 2, Z, E_BLOCK_LEAVES, E_META_LEAVES_APPLE));
}
// Trunk:
diff --git a/src/Items/CMakeLists.txt b/src/Items/CMakeLists.txt
index 12a467672..c50ddb372 100644
--- a/src/Items/CMakeLists.txt
+++ b/src/Items/CMakeLists.txt
@@ -10,12 +10,14 @@ SET (SRCS
SET (HDRS
ItemArmor.h
ItemBed.h
+ ItemBigFlower.h
ItemBoat.h
ItemBow.h
ItemBrewingStand.h
ItemBucket.h
ItemCake.h
ItemCauldron.h
+ ItemChest.h
ItemCloth.h
ItemComparator.h
ItemDoor.h
@@ -38,18 +40,21 @@ SET (HDRS
ItemPainting.h
ItemPickaxe.h
ItemPotion.h
+ ItemPumpkin.h
ItemRedstoneDust.h
ItemRedstoneRepeater.h
ItemSapling.h
ItemSeeds.h
ItemShears.h
ItemShovel.h
+ ItemSlab.h
ItemSign.h
ItemSpawnEgg.h
ItemString.h
ItemSugarcane.h
ItemSword.h
- ItemThrowable.h)
+ ItemThrowable.h
+)
if(NOT MSVC)
add_library(Items ${SRCS} ${HDRS})
diff --git a/src/Items/ItemBed.h b/src/Items/ItemBed.h
index 94a14cf16..77d51d744 100644
--- a/src/Items/ItemBed.h
+++ b/src/Items/ItemBed.h
@@ -24,30 +24,36 @@ public:
return true;
}
- virtual bool GetPlacementBlockTypeMeta(
- cWorld * a_World, cPlayer * a_Player,
+
+ virtual bool OnPlayerPlace(
+ cWorld & a_World, cPlayer & a_Player, const cItem & a_EquippedItem,
int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
- int a_CursorX, int a_CursorY, int a_CursorZ,
- BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
+ int a_CursorX, int a_CursorY, int a_CursorZ
) override
{
+ // Can only be placed on the floor:
if (a_BlockFace != BLOCK_FACE_TOP)
{
- // Can only be placed on the floor
return false;
}
+ AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
- a_BlockMeta = cBlockBedHandler::RotationToMetaData(a_Player->GetYaw());
+ // The "foot" block:
+ sSetBlockVector blks;
+ NIBBLETYPE BlockMeta = cBlockBedHandler::RotationToMetaData(a_Player.GetYaw());
+ blks.emplace_back(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_BED, BlockMeta);
- // Check if there is empty space for the foot section:
- Vector3i Direction = cBlockBedHandler::MetaDataToDirection(a_BlockMeta);
- if (a_World->GetBlock(a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z) != E_BLOCK_AIR)
+ // Check if there is empty space for the "head" block:
+ // (Vanilla only allows beds to be placed into air)
+ Vector3i Direction = cBlockBedHandler::MetaDataToDirection(BlockMeta);
+ if (a_World.GetBlock(a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z) != E_BLOCK_AIR)
{
return false;
}
+ blks.emplace_back(a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z, E_BLOCK_BED, BlockMeta | 0x08);
- a_BlockType = E_BLOCK_BED;
- return true;
+ // Place both bed blocks:
+ return a_Player.PlaceBlocks(blks);
}
} ;
diff --git a/src/Items/ItemBigFlower.h b/src/Items/ItemBigFlower.h
new file mode 100644
index 000000000..4341a1a17
--- /dev/null
+++ b/src/Items/ItemBigFlower.h
@@ -0,0 +1,56 @@
+
+// ItemBigFlower.h
+
+// Declares the cItemBigFlower class representing the cItemHandler for big flowers
+
+
+
+
+
+#pragma once
+
+#include "ItemHandler.h"
+
+
+
+
+
+class cItemBigFlowerHandler:
+ public cItemHandler
+{
+ typedef cItemHandler super;
+
+public:
+ cItemBigFlowerHandler(void):
+ super(E_BLOCK_BIG_FLOWER)
+ {
+ }
+
+
+ virtual bool OnPlayerPlace(
+ cWorld & a_World, cPlayer & a_Player, const cItem & a_EquippedItem,
+ int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
+ int a_CursorX, int a_CursorY, int a_CursorZ
+ ) override
+ {
+ // Can only be placed on the floor:
+ if (a_BlockFace != BLOCK_FACE_TOP)
+ {
+ return false;
+ }
+ AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
+
+ // Place both blocks atomically:
+ sSetBlockVector blks;
+ blks.emplace_back(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_BIG_FLOWER, a_EquippedItem.m_ItemDamage & 0x07);
+ if (a_BlockY < cChunkDef::Height - 1)
+ {
+ blks.emplace_back(a_BlockX, a_BlockY + 1, a_BlockZ, E_BLOCK_BIG_FLOWER, (a_EquippedItem.m_ItemDamage & 0x07) | 0x08);
+ }
+ return a_Player.PlaceBlocks(blks);
+ }
+};
+
+
+
+
diff --git a/src/Items/ItemChest.h b/src/Items/ItemChest.h
new file mode 100644
index 000000000..b6579c423
--- /dev/null
+++ b/src/Items/ItemChest.h
@@ -0,0 +1,167 @@
+
+// ItemChest.h
+
+// Declares the cItemChestHandler class representing the cItemHandler descendant responsible for chests
+
+
+
+
+
+#pragma once
+
+#include "ItemHandler.h"
+#include "../Blocks/BlockChest.h"
+
+
+
+
+
+class cItemChestHandler:
+ public cItemHandler
+{
+ typedef cItemHandler super;
+public:
+ cItemChestHandler(int a_ItemType):
+ super(a_ItemType)
+ {
+ }
+
+
+ virtual bool OnPlayerPlace(
+ cWorld & a_World, cPlayer & a_Player, const cItem & a_EquippedItem,
+ int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
+ int a_CursorX, int a_CursorY, int a_CursorZ
+ ) override
+ {
+ if (a_BlockFace < 0)
+ {
+ // Clicked in air
+ return false;
+ }
+
+ if ((a_BlockY < 0) || (a_BlockY >= cChunkDef::Height))
+ {
+ // The clicked block is outside the world, ignore this call altogether (#128)
+ return false;
+ }
+
+ // Check if the block ignores build collision (water, grass etc.):
+ BLOCKTYPE ClickedBlock;
+ NIBBLETYPE ClickedBlockMeta;
+ a_World.GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, ClickedBlock, ClickedBlockMeta);
+ if (
+ BlockHandler(ClickedBlock)->DoesIgnoreBuildCollision() ||
+ BlockHandler(ClickedBlock)->DoesIgnoreBuildCollision(&a_Player, ClickedBlockMeta)
+ )
+ {
+ cChunkInterface ChunkInterface(a_World.GetChunkMap());
+ BlockHandler(ClickedBlock)->OnDestroyedByPlayer(ChunkInterface, a_World, &a_Player, a_BlockX, a_BlockY, a_BlockZ);
+ }
+ else
+ {
+ AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
+
+ if ((a_BlockY < 0) || (a_BlockY >= cChunkDef::Height))
+ {
+ // The block is being placed outside the world, ignore this packet altogether (#128)
+ return false;
+ }
+
+ NIBBLETYPE PlaceMeta;
+ BLOCKTYPE PlaceBlock;
+ a_World.GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, PlaceBlock, PlaceMeta);
+
+ // Clicked on side of block, make sure that placement won't be cancelled if there is a slab able to be double slabbed.
+ // No need to do combinability (dblslab) checks, client will do that here.
+ if (
+ !BlockHandler(PlaceBlock)->DoesIgnoreBuildCollision() &&
+ !BlockHandler(PlaceBlock)->DoesIgnoreBuildCollision(&a_Player, PlaceMeta)
+ )
+ {
+ // Tried to place a block *into* another?
+ // Happens when you place a block aiming at side of block with a torch on it or stem beside it
+ return false;
+ }
+ }
+
+ // Check that there is at most one single neighbor of the same chest type:
+ static const Vector3i CrossCoords[] =
+ {
+ {-1, 0, 0},
+ { 0, 0, -1},
+ { 1, 0, 0},
+ { 0, 0, 1},
+ };
+ int NeighborIdx = -1;
+ for (size_t i = 0; i < ARRAYCOUNT(CrossCoords); i++)
+ {
+ if (a_World.GetBlock(a_BlockX + CrossCoords[i].x, a_BlockY, a_BlockZ + CrossCoords[i].z) != m_ItemType)
+ {
+ continue;
+ }
+ if (NeighborIdx >= 0)
+ {
+ // Can't place here, there are already two neighbors, this would form a 3-block chest
+ return false;
+ }
+ NeighborIdx = static_cast(i);
+
+ // Check that this neighbor is a single chest:
+ int bx = a_BlockX + CrossCoords[i].x;
+ int bz = a_BlockZ + CrossCoords[i].z;
+ for (size_t j = 0; j < ARRAYCOUNT(CrossCoords); j++)
+ {
+ if (a_World.GetBlock(bx + CrossCoords[j].x, a_BlockY, bz + CrossCoords[j].z) == m_ItemType)
+ {
+ return false;
+ }
+ } // for j
+ } // for i
+
+ // If there's no chest neighbor, place the single block chest and bail out:
+ BLOCKTYPE ChestBlockType = static_cast(m_ItemType);
+ if (NeighborIdx < 0)
+ {
+ NIBBLETYPE Meta = cBlockChestHandler::PlayerYawToMetaData(a_Player.GetYaw());
+ return a_Player.PlaceBlock(a_BlockX, a_BlockY, a_BlockZ, ChestBlockType, Meta);
+ }
+
+ // There is a neighbor to which we need to adjust
+ double yaw = a_Player.GetYaw();
+ if ((NeighborIdx == 0) || (NeighborIdx == 2))
+ {
+ // The neighbor is in the X axis, form a X-axis-aligned dblchest:
+ NIBBLETYPE Meta = ((yaw >= -90) && (yaw < 90)) ? E_META_CHEST_FACING_ZM : E_META_CHEST_FACING_ZP;
+
+ // Place the new chest:
+ if (!a_Player.PlaceBlock(a_BlockX, a_BlockY, a_BlockZ, ChestBlockType, Meta))
+ {
+ return false;
+ }
+
+ // Adjust the existing chest:
+ a_World.FastSetBlock(a_BlockX + CrossCoords[NeighborIdx].x, a_BlockY, a_BlockZ + CrossCoords[NeighborIdx].z, ChestBlockType, Meta);
+ return true;
+ }
+
+ // The neighbor is in the Z axis, form a Z-axis-aligned dblchest:
+ NIBBLETYPE Meta = (yaw < 0) ? E_META_CHEST_FACING_XM : E_META_CHEST_FACING_XP;
+
+ // Place the new chest:
+ if (!a_Player.PlaceBlock(a_BlockX, a_BlockY, a_BlockZ, ChestBlockType, Meta))
+ {
+ return false;
+ }
+
+ // Adjust the existing chest:
+ a_World.FastSetBlock(a_BlockX + CrossCoords[NeighborIdx].x, a_BlockY, a_BlockZ + CrossCoords[NeighborIdx].z, ChestBlockType, Meta);
+ return true;
+ }
+
+private:
+ cItemChestHandler(const cItemChestHandler &) = delete;
+};
+
+
+
+
diff --git a/src/Items/ItemDoor.h b/src/Items/ItemDoor.h
index cd5baf44f..dbba26728 100644
--- a/src/Items/ItemDoor.h
+++ b/src/Items/ItemDoor.h
@@ -3,6 +3,7 @@
#include "ItemHandler.h"
#include "../World.h"
+#include "../Blocks/BlockDoor.h"
@@ -18,27 +19,43 @@ public:
}
- virtual bool IsPlaceable(void) override
- {
- return true;
- }
- virtual bool GetPlacementBlockTypeMeta(
- cWorld * a_World, cPlayer * a_Player,
+ virtual bool OnPlayerPlace(
+ cWorld & a_World, cPlayer & a_Player, const cItem & a_EquippedItem,
int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
- int a_CursorX, int a_CursorY, int a_CursorZ,
- BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
+ int a_CursorX, int a_CursorY, int a_CursorZ
) override
{
+ // Vanilla only allows door placement while clicking on the top face of the block below the door:
+ if (a_BlockFace != BLOCK_FACE_NONE)
+ {
+ return false;
+ }
+ AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
+
+ // Door (bottom block) can be placed in Y range of [1, 254]:
+ if ((a_BlockY < 1) || (a_BlockY + 2 >= cChunkDef::Height))
+ {
+ return false;
+ }
+
+ // The door needs a compatible block below it:
+ if ((a_BlockY > 0) && cBlockDoorHandler::CanBeOn(a_World.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ)))
+ {
+ return false;
+ }
+
+ // Get the block type of the door to place:
+ BLOCKTYPE BlockType;
switch (m_ItemType)
{
- case E_ITEM_WOODEN_DOOR: a_BlockType = E_BLOCK_WOODEN_DOOR; break;
- case E_ITEM_IRON_DOOR: a_BlockType = E_BLOCK_IRON_DOOR; break;
- case E_ITEM_SPRUCE_DOOR: a_BlockType = E_BLOCK_SPRUCE_DOOR; break;
- case E_ITEM_BIRCH_DOOR: a_BlockType = E_BLOCK_BIRCH_DOOR; break;
- case E_ITEM_JUNGLE_DOOR: a_BlockType = E_BLOCK_JUNGLE_DOOR; break;
- case E_ITEM_DARK_OAK_DOOR: a_BlockType = E_BLOCK_DARK_OAK_DOOR; break;
- case E_ITEM_ACACIA_DOOR: a_BlockType = E_BLOCK_ACACIA_DOOR; break;
+ case E_ITEM_WOODEN_DOOR: BlockType = E_BLOCK_WOODEN_DOOR; break;
+ case E_ITEM_IRON_DOOR: BlockType = E_BLOCK_IRON_DOOR; break;
+ case E_ITEM_SPRUCE_DOOR: BlockType = E_BLOCK_SPRUCE_DOOR; break;
+ case E_ITEM_BIRCH_DOOR: BlockType = E_BLOCK_BIRCH_DOOR; break;
+ case E_ITEM_JUNGLE_DOOR: BlockType = E_BLOCK_JUNGLE_DOOR; break;
+ case E_ITEM_DARK_OAK_DOOR: BlockType = E_BLOCK_DARK_OAK_DOOR; break;
+ case E_ITEM_ACACIA_DOOR: BlockType = E_BLOCK_ACACIA_DOOR; break;
default:
{
ASSERT(!"Unhandled door type");
@@ -46,14 +63,47 @@ public:
}
}
- cChunkInterface ChunkInterface(a_World->GetChunkMap());
- bool Meta = BlockHandler(a_BlockType)->GetPlacementBlockTypeMeta(
- ChunkInterface, a_Player,
- a_BlockX, a_BlockY, a_BlockZ, a_BlockFace,
- a_CursorX, a_CursorY, a_CursorZ,
- a_BlockType, a_BlockMeta
- );
- return Meta;
+ // Check the two blocks that will get replaced by the door:
+ BLOCKTYPE LowerBlockType = a_World.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ);
+ BLOCKTYPE UpperBlockType = a_World.GetBlock(a_BlockX, a_BlockY + 2, a_BlockZ);
+ if (
+ !cBlockDoorHandler::CanReplaceBlock(LowerBlockType) ||
+ !cBlockDoorHandler::CanReplaceBlock(UpperBlockType))
+ {
+ return false;
+ }
+
+ // Get the coords of the neighboring blocks:
+ NIBBLETYPE LowerBlockMeta = cBlockDoorHandler::PlayerYawToMetaData(a_Player.GetYaw());
+ Vector3i RelDirToOutside = cBlockDoorHandler::GetRelativeDirectionToOutside(LowerBlockMeta);
+ Vector3i LeftNeighborPos = RelDirToOutside;
+ LeftNeighborPos.TurnCCW();
+ LeftNeighborPos.Move(a_BlockX, a_BlockY, a_BlockZ);
+ Vector3i RightNeighborPos = RelDirToOutside;
+ RightNeighborPos.TurnCW();
+ RightNeighborPos.Move(a_BlockX, a_BlockY, a_BlockZ);
+
+ // Decide whether the hinge is on the left (default) or on the right:
+ NIBBLETYPE UpperBlockMeta = 0x08;
+ if (
+ cBlockDoorHandler::IsDoorBlockType(a_World.GetBlock(LeftNeighborPos)) || // The block to the left is a door block
+ cBlockInfo::IsSolid(a_World.GetBlock(RightNeighborPos)) // The block to the right is solid
+ )
+ {
+ UpperBlockMeta = 0x09; // Upper block | hinge on right
+ }
+
+ // Set the blocks:
+ sSetBlockVector blks;
+ blks.emplace_back(a_BlockX, a_BlockY, a_BlockZ, BlockType, LowerBlockMeta);
+ blks.emplace_back(a_BlockX, a_BlockY + 1, a_BlockZ, BlockType, UpperBlockMeta);
+ return a_Player.PlaceBlocks(blks);
+ }
+
+
+ virtual bool IsPlaceable(void) override
+ {
+ return true;
}
} ;
diff --git a/src/Items/ItemDye.h b/src/Items/ItemDye.h
index da978040d..bfcd0bac4 100644
--- a/src/Items/ItemDye.h
+++ b/src/Items/ItemDye.h
@@ -55,25 +55,16 @@ public:
return false;
}
- // Check plugins
- if (cRoot::Get()->GetPluginManager()->CallHookPlayerPlacingBlock(*a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, 0, 0, 0, E_BLOCK_COCOA_POD, BlockMeta))
+ // Place the cocoa pod:
+ if (a_Player->PlaceBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_COCOA_POD, BlockMeta))
{
- a_World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player);
- a_Player->GetInventory().SendEquippedSlot();
- return false;
- }
-
- // Set block and broadcast place sound
- a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_COCOA_POD, BlockMeta);
- a_World->BroadcastSoundEffect("dig.stone", a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5, 1.0f, 0.8f);
-
- // Remove one cocoa pod from the inventory
- if (!a_Player->IsGameModeCreative())
- {
- a_Player->GetInventory().RemoveOneEquippedItem();
+ a_World->BroadcastSoundEffect("dig.stone", a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5, 1.0f, 0.8f);
+ if (a_Player->IsGameModeSurvival())
+ {
+ a_Player->GetInventory().RemoveOneEquippedItem();
+ }
+ return true;
}
- cRoot::Get()->GetPluginManager()->CallHookPlayerPlacedBlock(*a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, 0, 0, 0, E_BLOCK_COCOA_POD, BlockMeta);
- return true;
}
return false;
}
diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp
index 9272a723d..92c55ec62 100644
--- a/src/Items/ItemHandler.cpp
+++ b/src/Items/ItemHandler.cpp
@@ -6,39 +6,43 @@
#include "../Entities/Player.h"
#include "../FastRandom.h"
#include "../BlockInServerPluginInterface.h"
+#include "../Chunk.h"
// Handlers:
#include "ItemArmor.h"
#include "ItemBed.h"
+#include "ItemBigFlower.h"
#include "ItemBoat.h"
#include "ItemBow.h"
#include "ItemBrewingStand.h"
#include "ItemBucket.h"
#include "ItemCake.h"
#include "ItemCauldron.h"
+#include "ItemChest.h"
#include "ItemCloth.h"
#include "ItemComparator.h"
#include "ItemDoor.h"
-#include "ItemMilk.h"
#include "ItemDye.h"
#include "ItemEmptyMap.h"
#include "ItemFishingRod.h"
#include "ItemFlowerPot.h"
#include "ItemFood.h"
#include "ItemGoldenApple.h"
-#include "ItemItemFrame.h"
#include "ItemHoe.h"
+#include "ItemItemFrame.h"
#include "ItemLeaves.h"
#include "ItemLighter.h"
#include "ItemLilypad.h"
#include "ItemMap.h"
+#include "ItemMilk.h"
#include "ItemMinecart.h"
+#include "ItemMobHead.h"
#include "ItemMushroomSoup.h"
#include "ItemNetherWart.h"
#include "ItemPainting.h"
#include "ItemPickaxe.h"
#include "ItemPotion.h"
-#include "ItemThrowable.h"
+#include "ItemPumpkin.h"
#include "ItemRedstoneDust.h"
#include "ItemRedstoneRepeater.h"
#include "ItemSapling.h"
@@ -46,11 +50,12 @@
#include "ItemShears.h"
#include "ItemShovel.h"
#include "ItemSign.h"
-#include "ItemMobHead.h"
+#include "ItemSlab.h"
#include "ItemSpawnEgg.h"
#include "ItemString.h"
#include "ItemSugarcane.h"
#include "ItemSword.h"
+#include "ItemThrowable.h"
#include "../Blocks/BlockHandler.h"
@@ -94,52 +99,58 @@ cItemHandler * cItemHandler::GetItemHandler(int a_ItemType)
-cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType)
+cItemHandler * cItemHandler::CreateItemHandler(int a_ItemType)
{
switch (a_ItemType)
{
default: return new cItemHandler(a_ItemType);
// Single item per handler, alphabetically sorted:
- case E_BLOCK_LEAVES: return new cItemLeavesHandler(a_ItemType);
- case E_BLOCK_NEW_LEAVES: return new cItemLeavesHandler(a_ItemType);
- case E_BLOCK_SAPLING: return new cItemSaplingHandler(a_ItemType);
- case E_BLOCK_WOOL: return new cItemClothHandler(a_ItemType);
- case E_ITEM_BED: return new cItemBedHandler(a_ItemType);
- case E_ITEM_BOAT: return new cItemBoatHandler(a_ItemType);
+ case E_BLOCK_CHEST: return new cItemChestHandler(a_ItemType);
+ case E_BLOCK_LEAVES: return new cItemLeavesHandler(a_ItemType);
+ case E_BLOCK_HEAD: return new cItemMobHeadHandler(a_ItemType);
+ case E_BLOCK_NEW_LEAVES: return new cItemLeavesHandler(a_ItemType);
+ case E_BLOCK_PUMPKIN: return new cItemPumpkinHandler;
+ case E_BLOCK_SAPLING: return new cItemSaplingHandler(a_ItemType);
+ case E_BLOCK_STONE_SLAB: return new cItemSlabHandler(E_BLOCK_STONE_SLAB, E_BLOCK_DOUBLE_STONE_SLAB);
+ case E_BLOCK_TRAPPED_CHEST: return new cItemChestHandler(a_ItemType);
+ case E_BLOCK_WOODEN_SLAB: return new cItemSlabHandler(E_BLOCK_WOODEN_SLAB, E_BLOCK_DOUBLE_WOODEN_SLAB);
+ case E_BLOCK_WOOL: return new cItemClothHandler(a_ItemType);
+ case E_ITEM_BED: return new cItemBedHandler(a_ItemType);
+ case E_ITEM_BOAT: return new cItemBoatHandler(a_ItemType);
case E_ITEM_BOTTLE_O_ENCHANTING: return new cItemBottleOEnchantingHandler();
- case E_ITEM_BOW: return new cItemBowHandler();
- case E_ITEM_BREWING_STAND: return new cItemBrewingStandHandler(a_ItemType);
- case E_ITEM_CAKE: return new cItemCakeHandler(a_ItemType);
- case E_ITEM_CAULDRON: return new cItemCauldronHandler(a_ItemType);
- case E_ITEM_COMPARATOR: return new cItemComparatorHandler(a_ItemType);
- case E_ITEM_DYE: return new cItemDyeHandler(a_ItemType);
- case E_ITEM_EGG: return new cItemEggHandler();
- case E_ITEM_EMPTY_MAP: return new cItemEmptyMapHandler();
- case E_ITEM_ENDER_PEARL: return new cItemEnderPearlHandler();
- case E_ITEM_FIRE_CHARGE: return new cItemLighterHandler(a_ItemType);
- case E_ITEM_FIREWORK_ROCKET: return new cItemFireworkHandler();
- case E_ITEM_FISHING_ROD: return new cItemFishingRodHandler(a_ItemType);
- case E_ITEM_FLINT_AND_STEEL: return new cItemLighterHandler(a_ItemType);
- case E_ITEM_FLOWER_POT: return new cItemFlowerPotHandler(a_ItemType);
- case E_ITEM_GOLDEN_APPLE: return new cItemGoldenAppleHandler();
- case E_BLOCK_LILY_PAD: return new cItemLilypadHandler(a_ItemType);
- case E_ITEM_MAP: return new cItemMapHandler();
- case E_ITEM_MILK: return new cItemMilkHandler();
- case E_ITEM_MUSHROOM_SOUP: return new cItemMushroomSoupHandler(a_ItemType);
- case E_ITEM_ITEM_FRAME: return new cItemItemFrameHandler(a_ItemType);
- case E_ITEM_NETHER_WART: return new cItemNetherWartHandler(a_ItemType);
- case E_ITEM_PAINTING: return new cItemPaintingHandler(a_ItemType);
- case E_ITEM_POTIONS: return new cItemPotionHandler();
- case E_ITEM_REDSTONE_DUST: return new cItemRedstoneDustHandler(a_ItemType);
- case E_ITEM_REDSTONE_REPEATER: return new cItemRedstoneRepeaterHandler(a_ItemType);
- case E_ITEM_SHEARS: return new cItemShearsHandler(a_ItemType);
- case E_ITEM_SIGN: return new cItemSignHandler(a_ItemType);
- case E_ITEM_HEAD: return new cItemMobHeadHandler(a_ItemType);
- case E_ITEM_SNOWBALL: return new cItemSnowballHandler();
- case E_ITEM_SPAWN_EGG: return new cItemSpawnEggHandler(a_ItemType);
- case E_ITEM_STRING: return new cItemStringHandler(a_ItemType);
- case E_ITEM_SUGARCANE: return new cItemSugarcaneHandler(a_ItemType);
+ case E_ITEM_BOW: return new cItemBowHandler();
+ case E_ITEM_BREWING_STAND: return new cItemBrewingStandHandler(a_ItemType);
+ case E_ITEM_CAKE: return new cItemCakeHandler(a_ItemType);
+ case E_ITEM_CAULDRON: return new cItemCauldronHandler(a_ItemType);
+ case E_ITEM_COMPARATOR: return new cItemComparatorHandler(a_ItemType);
+ case E_ITEM_DYE: return new cItemDyeHandler(a_ItemType);
+ case E_ITEM_EGG: return new cItemEggHandler();
+ case E_ITEM_EMPTY_MAP: return new cItemEmptyMapHandler();
+ case E_ITEM_ENDER_PEARL: return new cItemEnderPearlHandler();
+ case E_ITEM_FIRE_CHARGE: return new cItemLighterHandler(a_ItemType);
+ case E_ITEM_FIREWORK_ROCKET: return new cItemFireworkHandler();
+ case E_ITEM_FISHING_ROD: return new cItemFishingRodHandler(a_ItemType);
+ case E_ITEM_FLINT_AND_STEEL: return new cItemLighterHandler(a_ItemType);
+ case E_ITEM_FLOWER_POT: return new cItemFlowerPotHandler(a_ItemType);
+ case E_ITEM_GOLDEN_APPLE: return new cItemGoldenAppleHandler();
+ case E_BLOCK_LILY_PAD: return new cItemLilypadHandler(a_ItemType);
+ case E_ITEM_MAP: return new cItemMapHandler();
+ case E_ITEM_MILK: return new cItemMilkHandler();
+ case E_ITEM_MUSHROOM_SOUP: return new cItemMushroomSoupHandler(a_ItemType);
+ case E_ITEM_ITEM_FRAME: return new cItemItemFrameHandler(a_ItemType);
+ case E_ITEM_NETHER_WART: return new cItemNetherWartHandler(a_ItemType);
+ case E_ITEM_PAINTING: return new cItemPaintingHandler(a_ItemType);
+ case E_ITEM_POTIONS: return new cItemPotionHandler();
+ case E_ITEM_REDSTONE_DUST: return new cItemRedstoneDustHandler(a_ItemType);
+ case E_ITEM_REDSTONE_REPEATER: return new cItemRedstoneRepeaterHandler(a_ItemType);
+ case E_ITEM_SHEARS: return new cItemShearsHandler(a_ItemType);
+ case E_ITEM_SIGN: return new cItemSignHandler(a_ItemType);
+ case E_ITEM_HEAD: return new cItemMobHeadHandler(a_ItemType);
+ case E_ITEM_SNOWBALL: return new cItemSnowballHandler();
+ case E_ITEM_SPAWN_EGG: return new cItemSpawnEggHandler(a_ItemType);
+ case E_ITEM_STRING: return new cItemStringHandler(a_ItemType);
+ case E_ITEM_SUGARCANE: return new cItemSugarcaneHandler(a_ItemType);
case E_ITEM_WOODEN_HOE:
case E_ITEM_STONE_HOE:
@@ -297,6 +308,108 @@ cItemHandler::cItemHandler(int a_ItemType)
+bool cItemHandler::OnPlayerPlace(
+ cWorld & a_World, cPlayer & a_Player, const cItem & a_EquippedItem,
+ int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
+ int a_CursorX, int a_CursorY, int a_CursorZ
+)
+{
+ if (a_BlockFace < 0)
+ {
+ // Clicked in air
+ return false;
+ }
+
+ if ((a_BlockY < 0) || (a_BlockY >= cChunkDef::Height))
+ {
+ // The clicked block is outside the world, ignore this call altogether (#128)
+ return false;
+ }
+
+ BLOCKTYPE ClickedBlock;
+ NIBBLETYPE ClickedBlockMeta;
+
+ a_World.GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, ClickedBlock, ClickedBlockMeta);
+
+ // Check if the block ignores build collision (water, grass etc.):
+ if (
+ BlockHandler(ClickedBlock)->DoesIgnoreBuildCollision() ||
+ BlockHandler(ClickedBlock)->DoesIgnoreBuildCollision(&a_Player, ClickedBlockMeta)
+ )
+ {
+ cChunkInterface ChunkInterface(a_World.GetChunkMap());
+ BlockHandler(ClickedBlock)->OnDestroyedByPlayer(ChunkInterface, a_World, &a_Player, a_BlockX, a_BlockY, a_BlockZ);
+ }
+ else
+ {
+ AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
+
+ if ((a_BlockY < 0) || (a_BlockY >= cChunkDef::Height))
+ {
+ // The block is being placed outside the world, ignore this packet altogether (#128)
+ return false;
+ }
+
+ NIBBLETYPE PlaceMeta;
+ BLOCKTYPE PlaceBlock;
+ a_World.GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, PlaceBlock, PlaceMeta);
+
+ // Clicked on side of block, make sure that placement won't be cancelled if there is a slab able to be double slabbed.
+ // No need to do combinability (dblslab) checks, client will do that here.
+ if (
+ !BlockHandler(PlaceBlock)->DoesIgnoreBuildCollision() &&
+ !BlockHandler(PlaceBlock)->DoesIgnoreBuildCollision(&a_Player, PlaceMeta)
+ )
+ {
+ // Tried to place a block *into* another?
+ // Happens when you place a block aiming at side of block with a torch on it or stem beside it
+ return false;
+ }
+ }
+
+ BLOCKTYPE BlockType;
+ NIBBLETYPE BlockMeta;
+ if (!GetPlacementBlockTypeMeta(&a_World, &a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta))
+ {
+ // Handler refused the placement, send that information back to the client:
+ a_World.SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, &a_Player);
+ a_Player.GetInventory().SendEquippedSlot();
+ return false;
+ }
+
+ if (!a_Player.PlaceBlock(a_BlockX, a_BlockY, a_BlockZ, BlockType, BlockMeta))
+ {
+ // The placement failed, the block has already been re-sent, re-send inventory:
+ a_Player.GetInventory().SendEquippedSlot();
+ return false;
+ }
+
+ AString PlaceSound = cBlockInfo::GetPlaceSound(BlockType);
+ float Volume = 1.0f, Pitch = 0.8f;
+ if (PlaceSound == "dig.metal")
+ {
+ Pitch = 1.2f;
+ PlaceSound = "dig.stone";
+ }
+ else if (PlaceSound == "random.anvil_land")
+ {
+ Volume = 0.65f;
+ }
+
+ a_World.BroadcastSoundEffect(PlaceSound, a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5, Volume, Pitch);
+
+ // Remove the "placed" item:
+ if (a_Player.IsGameModeSurvival())
+ {
+ a_Player.GetInventory().RemoveOneEquippedItem();
+ }
+ return true;
+}
+
+
+
+
+
bool cItemHandler::OnItemUse(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Dir)
{
UNUSED(a_World);
diff --git a/src/Items/ItemHandler.h b/src/Items/ItemHandler.h
index 67c250a97..3ac664798 100644
--- a/src/Items/ItemHandler.h
+++ b/src/Items/ItemHandler.h
@@ -31,10 +31,35 @@ public:
/** Force virtual destructor */
virtual ~cItemHandler() {}
+
+
+ /** Called when the player tries to place the item (right mouse button, IsPlaceable() == true).
+ The default handler uses GetPlacementBlockTypeMeta and places the returned block.
+ Override this function for advanced behavior such as placing multiple blocks.
+ If the block placement is refused inside this call, it will automatically revert the client-side changes.
+ Returns true if the placement succeeded, false if the placement was aborted for any reason. */
+ virtual bool OnPlayerPlace(
+ cWorld & a_World, cPlayer & a_Player, const cItem & a_EquippedItem,
+ int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
+ int a_CursorX, int a_CursorY, int a_CursorZ
+ );
+
+ /** Called when the player right-clicks with this item and IsPlaceable() == true, and OnPlace() is not overridden.
+ This function should provide the block type and meta for the placed block, or refuse the placement.
+ Returns true to allow placement, false to refuse. */
+ virtual bool GetPlacementBlockTypeMeta(
+ cWorld * a_World, cPlayer * a_Player,
+ int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
+ int a_CursorX, int a_CursorY, int a_CursorZ,
+ BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
+ );
+
+
/** Called when the player tries to use the item (right mouse button). Return false to make the item unusable. DEFAULT: False */
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);
+
/** Called when the client sends the SHOOT status in the lclk packet */
virtual void OnItemShoot(cPlayer *, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace)
{
@@ -106,18 +131,8 @@ public:
/** Can the anvil repair this item, when a_Item is the second input? */
virtual bool CanRepairWithRawMaterial(short a_ItemType);
- /** Called before a block is placed into a world.
- The handler should return true to allow placement, false to refuse.
- Also, the handler should set a_BlockType and a_BlockMeta to correct values for the newly placed block.
- */
- virtual bool GetPlacementBlockTypeMeta(
- cWorld * a_World, cPlayer * a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
- int a_CursorX, int a_CursorY, int a_CursorZ,
- BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
- );
-
- /** Returns whether this tool/item can harvest a specific block (e.g. wooden pickaxe can harvest stone, but wood can't) DEFAULT: False */
+ /** Returns whether this tool / item can harvest a specific block (e.g. iron pickaxe can harvest diamond ore, but wooden one can't).
+ Defaults to false unless overridden. */
virtual bool CanHarvestBlock(BLOCKTYPE a_BlockType);
static cItemHandler * GetItemHandler(int a_ItemType);
diff --git a/src/Items/ItemMobHead.h b/src/Items/ItemMobHead.h
index 4c36fe8d8..d962dabae 100644
--- a/src/Items/ItemMobHead.h
+++ b/src/Items/ItemMobHead.h
@@ -3,6 +3,7 @@
#include "ItemHandler.h"
#include "../World.h"
+#include "../BlockEntities/MobHeadEntity.h"
@@ -18,6 +19,266 @@ public:
}
+ virtual bool OnPlayerPlace(
+ cWorld & a_World, cPlayer & a_Player, const cItem & a_EquippedItem,
+ int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
+ int a_CursorX, int a_CursorY, int a_CursorZ
+ ) override
+ {
+ // Cannot place a head at "no face" and from the bottom:
+ if ((a_BlockFace == BLOCK_FACE_NONE) || (a_BlockFace == BLOCK_FACE_BOTTOM))
+ {
+ return true;
+ }
+ AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
+
+ // If the placed head is a wither, try to spawn the wither first:
+ if (a_EquippedItem.m_ItemDamage == E_META_HEAD_WITHER)
+ {
+ if (TrySpawnWitherAround(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ))
+ {
+ return true;
+ }
+ // Wither not created, proceed with regular head placement
+ }
+
+ return PlaceRegularHead(a_World, a_Player, a_EquippedItem, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
+ }
+
+
+ /** Places a regular head block with no mob spawning checking. */
+ bool PlaceRegularHead(
+ cWorld & a_World, cPlayer & a_Player, const cItem & a_EquippedItem,
+ int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace
+ )
+ {
+ // Place the block:
+ if (!a_Player.PlaceBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_HEAD, static_cast(a_EquippedItem.m_ItemType)))
+ {
+ return false;
+ }
+
+ // Use a callback to set the properties of the mob head block entity:
+ class cCallback : public cBlockEntityCallback
+ {
+ cPlayer & m_Player;
+ eMobHeadType m_HeadType;
+ NIBBLETYPE m_BlockMeta;
+
+ virtual bool Item(cBlockEntity * a_BlockEntity)
+ {
+ if (a_BlockEntity->GetBlockType() != E_BLOCK_HEAD)
+ {
+ return false;
+ }
+ cMobHeadEntity * MobHeadEntity = static_cast(a_BlockEntity);
+
+ int Rotation = 0;
+ if (m_BlockMeta == 1)
+ {
+ Rotation = FloorC(m_Player.GetYaw() * 16.0f / 360.0f + 0.5f) & 0x0f;
+ }
+
+ MobHeadEntity->SetType(m_HeadType);
+ MobHeadEntity->SetRotation(static_cast(Rotation));
+ MobHeadEntity->GetWorld()->BroadcastBlockEntity(MobHeadEntity->GetPosX(), MobHeadEntity->GetPosY(), MobHeadEntity->GetPosZ());
+ return false;
+ }
+
+ public:
+ cCallback (cPlayer & a_CBPlayer, eMobHeadType a_HeadType, NIBBLETYPE a_BlockMeta) :
+ m_Player(a_CBPlayer),
+ m_HeadType(a_HeadType),
+ m_BlockMeta(a_BlockMeta)
+ {}
+ };
+ cCallback Callback(a_Player, static_cast(a_EquippedItem.m_ItemType), static_cast(a_BlockFace));
+ a_World.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ, Callback);
+ return true;
+ }
+
+
+ /** Spawns a wither if the wither skull placed at the specified coords completes wither's spawning formula.
+ Returns true if the wither was created. */
+ bool TrySpawnWitherAround(
+ cWorld & a_World, cPlayer & a_Player,
+ int a_BlockX, int a_BlockY, int a_BlockZ
+ )
+ {
+ // No wither can be created at Y < 2 - not enough space for the formula:
+ if (a_BlockY < 2)
+ {
+ return false;
+ }
+
+ // Check for all relevant wither locations:
+ static const Vector3i RelCoords[] =
+ {
+ { 0, 0, 0},
+ { 1, 0, 0},
+ {-1, 0, 0},
+ { 0, 0, 1},
+ { 0, 0, -1},
+ };
+ for (size_t i = 0; i < ARRAYCOUNT(RelCoords); ++i)
+ {
+ if (TrySpawnWitherAt(
+ a_World, a_Player,
+ a_BlockX, a_BlockY, a_BlockZ,
+ RelCoords[i].x, RelCoords[i].z
+ ))
+ {
+ return true;
+ }
+ } // for i - Coords[]
+
+ return false;
+ }
+
+
+ /** Tries to spawn a wither at the specified offset from the placed head block.
+ PlacedHead coords are used to override the block query - at those coords the block is not queried from the world,
+ but assumed to be a head instead.
+ Offset is used to shift the image around the X and Z axis.
+ Returns true iff the wither was created successfully. */
+ bool TrySpawnWitherAt(
+ cWorld & a_World, cPlayer & a_Player,
+ int a_PlacedHeadX, int a_PlacedHeadY, int a_PlacedHeadZ,
+ int a_OffsetX, int a_OffsetZ
+ )
+ {
+ // Image for the wither at the X axis:
+ static const sSetBlock ImageWitherX[] =
+ {
+ {-1, 0, 0, E_BLOCK_HEAD, E_META_HEAD_WITHER},
+ { 0, 0, 0, E_BLOCK_HEAD, E_META_HEAD_WITHER},
+ { 1, 0, 0, E_BLOCK_HEAD, E_META_HEAD_WITHER},
+ {-1, -1, 0, E_BLOCK_SOULSAND, 0},
+ { 0, -1, 0, E_BLOCK_SOULSAND, 0},
+ { 1, -1, 0, E_BLOCK_SOULSAND, 0},
+ {-1, -2, 0, E_BLOCK_AIR, 0},
+ { 0, -2, 0, E_BLOCK_SOULSAND, 0},
+ { 1, -2, 0, E_BLOCK_AIR, 0},
+ };
+
+ // Image for the wither at the Z axis:
+ static const sSetBlock ImageWitherZ[] =
+ {
+ { 0, 0, -1, E_BLOCK_HEAD, E_META_HEAD_WITHER},
+ { 0, 0, 0, E_BLOCK_HEAD, E_META_HEAD_WITHER},
+ { 0, 0, 1, E_BLOCK_HEAD, E_META_HEAD_WITHER},
+ { 0, -1, -1, E_BLOCK_SOULSAND, 0},
+ { 0, -1, 0, E_BLOCK_SOULSAND, 0},
+ { 0, -1, 1, E_BLOCK_SOULSAND, 0},
+ { 0, -2, -1, E_BLOCK_AIR, 0},
+ { 0, -2, 0, E_BLOCK_SOULSAND, 0},
+ { 0, -2, 1, E_BLOCK_AIR, 0},
+ };
+
+ // Try to spawn the wither from each image:
+ return (
+ TrySpawnWitherFromImage(
+ a_World, a_Player, ImageWitherX, ARRAYCOUNT(ImageWitherX),
+ a_PlacedHeadX, a_PlacedHeadY, a_PlacedHeadZ,
+ a_OffsetX, a_OffsetZ
+ ) ||
+ TrySpawnWitherFromImage(
+ a_World, a_Player, ImageWitherZ, ARRAYCOUNT(ImageWitherZ),
+ a_PlacedHeadX, a_PlacedHeadY, a_PlacedHeadZ,
+ a_OffsetX, a_OffsetZ
+ )
+ );
+ }
+
+
+ /** Tries to spawn a wither from the specified image at the specified offset from the placed head block.
+ PlacedHead coords are used to override the block query - at those coords the block is not queried from the world,
+ but assumed to be a head instead.
+ Offset is used to shift the image around the X and Z axis.
+ Returns true iff the wither was created successfully. */
+ bool TrySpawnWitherFromImage(
+ cWorld & a_World, cPlayer & a_Player, const sSetBlock * a_Image, size_t a_ImageCount,
+ int a_PlacedHeadX, int a_PlacedHeadY, int a_PlacedHeadZ,
+ int a_OffsetX, int a_OffsetZ
+ )
+ {
+ // Check each block individually; simultaneously build the SetBlockVector for clearing the blocks:
+ sSetBlockVector AirBlocks;
+ AirBlocks.reserve(a_ImageCount);
+ for (size_t i = 0; i < a_ImageCount; i++)
+ {
+ // Get the absolute coords of the image:
+ int BlockX = a_PlacedHeadX + a_OffsetX + a_Image[i].m_RelX;
+ int BlockY = a_PlacedHeadY + a_Image[i].m_RelY;
+ int BlockZ = a_PlacedHeadZ + a_OffsetZ + a_Image[i].m_RelZ;
+
+ // If the query is for the placed head, short-circuit-evaluate it:
+ if ((BlockX == a_PlacedHeadX) && (BlockY == a_PlacedHeadY) && (BlockZ == a_PlacedHeadZ))
+ {
+ if ((a_Image[i].m_BlockType != E_BLOCK_HEAD) || (a_Image[i].m_BlockMeta != E_META_HEAD_WITHER))
+ {
+ return false; // Didn't match
+ }
+ continue; // Matched, continue checking the rest of the image
+ }
+
+ // Query the world block:
+ BLOCKTYPE BlockType;
+ NIBBLETYPE BlockMeta;
+ if (!a_World.GetBlockTypeMeta(BlockX, BlockY, BlockZ, BlockType, BlockMeta))
+ {
+ // Cannot query block, assume unloaded chunk, fail to spawn the wither
+ return false;
+ }
+
+ // Compare the world block:
+ if ((BlockType != a_Image[i].m_BlockType) || (BlockMeta != a_Image[i].m_BlockMeta))
+ {
+ return false; // Didn't match
+ }
+ // Matched, continue checking
+ } // for i - a_Image
+
+ // All image blocks matched, try place the wither:
+ if (!a_Player.PlaceBlocks(AirBlocks))
+ {
+ return false;
+ }
+
+ // Spawn the wither:
+ int BlockX = a_PlacedHeadX + a_OffsetX;
+ int BlockZ = a_PlacedHeadZ + a_OffsetZ;
+ a_World.SpawnMob(static_cast(BlockX) + 0.5, a_PlacedHeadY - 2, static_cast(BlockZ) + 0.5, mtWither);
+ AwardSpawnWitherAchievement(a_World, BlockX, a_PlacedHeadY - 2, BlockZ);
+ return true;
+ }
+
+
+ /** Awards the achievement to all players close to the specified point. */
+ void AwardSpawnWitherAchievement(cWorld & a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
+ {
+ class cPlayerCallback : public cPlayerListCallback
+ {
+ Vector3f m_Pos;
+
+ virtual bool Item(cPlayer * a_Player)
+ {
+ // If player is close, award achievement:
+ double Dist = (a_Player->GetPosition() - m_Pos).Length();
+ if (Dist < 50.0)
+ {
+ a_Player->AwardAchievement(achSpawnWither);
+ }
+ return false;
+ }
+
+ public:
+ cPlayerCallback(const Vector3f & a_Pos) : m_Pos(a_Pos) {}
+ } PlayerCallback(Vector3f(static_cast(a_BlockX), static_cast(a_BlockY), static_cast(a_BlockZ)));
+ a_World.ForEachPlayer(PlayerCallback);
+ }
+
+
virtual bool IsPlaceable(void) override
{
return true;
diff --git a/src/Items/ItemPumpkin.h b/src/Items/ItemPumpkin.h
new file mode 100644
index 000000000..fa00179d3
--- /dev/null
+++ b/src/Items/ItemPumpkin.h
@@ -0,0 +1,156 @@
+
+// ItemPumpkin.h
+
+// Declares the cItemPumpkinHandler class representing the pumpkin block in its item form
+
+
+
+
+
+#pragma once
+
+#include "ItemHandler.h"
+
+
+
+
+
+class cItemPumpkinHandler:
+ public cItemHandler
+{
+ typedef cItemHandler super;
+
+public:
+ cItemPumpkinHandler(void):
+ super(E_BLOCK_PUMPKIN)
+ {
+ }
+
+
+ virtual bool OnPlayerPlace(
+ cWorld & a_World, cPlayer & a_Player, const cItem & a_EquippedItem,
+ int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
+ int a_CursorX, int a_CursorY, int a_CursorZ
+ ) override
+ {
+ // First try spawning a snow golem or an iron golem:
+ int PlacedBlockX = a_BlockX;
+ int PlacedBlockY = a_BlockY;
+ int PlacedBlockZ = a_BlockZ;
+ AddFaceDirection(PlacedBlockX, PlacedBlockY, PlacedBlockZ, a_BlockFace);
+ if (TrySpawnGolem(a_World, a_Player, PlacedBlockX, PlacedBlockY, PlacedBlockZ))
+ {
+ // The client thinks that they placed the pumpkin, let them know it's been replaced:
+ a_Player.SendBlocksAround(PlacedBlockX, PlacedBlockY, PlacedBlockZ);
+ return true;
+ }
+
+ // No golem at these coords, place the block normally:
+ return super::OnPlayerPlace(a_World, a_Player, a_EquippedItem, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ);
+ }
+
+
+ /** Spawns a snow / iron golem if the shape matches the recipe, supposing that the block placed at the specified coords is a pumpkin.
+ Returns true if the golem blocks are removed (for spawning), false if the recipe is not matched. */
+ bool TrySpawnGolem(cWorld & a_World, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ)
+ {
+ // A golem can't form with a pumpkin below level 2 or above level 255
+ if ((a_BlockY < 2) || (a_BlockY >= cChunkDef::Height))
+ {
+ return false;
+ }
+
+ // Decide which golem to try spawning based on the block below the placed pumpkin:
+ switch (a_World.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ))
+ {
+ case E_BLOCK_SNOW_BLOCK: return TrySpawnSnowGolem(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ);
+ case E_BLOCK_IRON_BLOCK: return TrySpawnIronGolem(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ);
+ default:
+ {
+ // No golem here
+ return false;
+ }
+ }
+ }
+
+
+ /** Spawns a snow golem if the shape matches the recipe, supposing that the block placed at the specified coords is a pumpkin.
+ Returns true if the golem blocks are removed (for spawning), false if the recipe is not matched.
+ Assumes that the block below the specified block has already been checked and is a snow block. */
+ bool TrySpawnSnowGolem(cWorld & a_World, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ)
+ {
+ // Need one more snow block 2 blocks below the pumpkin:
+ if (a_World.GetBlock(a_BlockX, a_BlockY - 2, a_BlockZ) != E_BLOCK_SNOW_BLOCK)
+ {
+ return false;
+ }
+
+ // Try to place air blocks where the original recipe blocks were:
+ sSetBlockVector AirBlocks;
+ AirBlocks.emplace_back(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); // Head
+ AirBlocks.emplace_back(a_BlockX, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0); // Torso
+ AirBlocks.emplace_back(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0); // Legs
+ if (!a_Player.PlaceBlocks(AirBlocks))
+ {
+ return false;
+ }
+
+ // Spawn the golem:
+ a_World.SpawnMob(static_cast(a_BlockX) + 0.5, a_BlockY - 2, static_cast(a_BlockZ) + 0.5, mtSnowGolem);
+ return true;
+ }
+
+
+ /** Spawns an iron golem if the shape matches the recipe, supposing that the block placed at the specified coords is a pumpkin.
+ Returns true if the golem blocks are removed (for spawning), false if the recipe is not matched.
+ Assumes that the block below the specified block has already been checked and is an iron block. */
+ bool TrySpawnIronGolem(cWorld & a_World, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ)
+ {
+ // Need one more iron block 2 blocks below the pumpkin:
+ if (a_World.GetBlock(a_BlockX, a_BlockY - 2, a_BlockZ) != E_BLOCK_IRON_BLOCK)
+ {
+ return false;
+ }
+
+ // Check the two arm directions (X, Z) using a loop over two sets of offset vectors:
+ static const Vector3i ArmOffsets[] =
+ {
+ {1, 0, 0},
+ {0, 0, 1},
+ };
+ for (size_t i = 0; i < ARRAYCOUNT(ArmOffsets); i++)
+ {
+ // If the arm blocks don't match, bail out of this loop repetition:
+ if (
+ (a_World.GetBlock(a_BlockX + ArmOffsets[i].x, a_BlockY - 1, a_BlockZ + ArmOffsets[i].z) != E_BLOCK_IRON_BLOCK) ||
+ (a_World.GetBlock(a_BlockX - ArmOffsets[i].x, a_BlockY - 1, a_BlockZ - ArmOffsets[i].z) != E_BLOCK_IRON_BLOCK)
+ )
+ {
+ continue;
+ }
+
+ // Try to place air blocks where the original recipe blocks were:
+ sSetBlockVector AirBlocks;
+ AirBlocks.emplace_back(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); // Head
+ AirBlocks.emplace_back(a_BlockX, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0); // Torso
+ AirBlocks.emplace_back(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0); // Legs
+ AirBlocks.emplace_back(a_BlockX + ArmOffsets[i].x, a_BlockY - 1, a_BlockZ + ArmOffsets[i].z, E_BLOCK_AIR, 0); // Arm
+ AirBlocks.emplace_back(a_BlockX - ArmOffsets[i].x, a_BlockY - 1, a_BlockZ - ArmOffsets[i].z, E_BLOCK_AIR, 0); // Arm
+ if (!a_Player.PlaceBlocks(AirBlocks))
+ {
+ return false;
+ }
+
+ // Spawn the golem:
+ a_World.SpawnMob(static_cast(a_BlockX) + 0.5, a_BlockY - 2, static_cast(a_BlockZ) + 0.5, mtIronGolem);
+ return true;
+ } // for i - ArmOffsets[]
+
+ // Neither arm offset matched, this thing is not a complete golem
+ return false;
+ }
+};
+
+
+
+
diff --git a/src/Items/ItemSign.h b/src/Items/ItemSign.h
index 0fa0fa0be..dabbdbba1 100644
--- a/src/Items/ItemSign.h
+++ b/src/Items/ItemSign.h
@@ -13,13 +13,33 @@
class cItemSignHandler :
public cItemHandler
{
+ typedef cItemHandler super;
public:
cItemSignHandler(int a_ItemType) :
- cItemHandler(a_ItemType)
+ super(a_ItemType)
{
}
+ virtual bool OnPlayerPlace(
+ cWorld & a_World, cPlayer & a_Player, const cItem & a_EquippedItem,
+ int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
+ int a_CursorX, int a_CursorY, int a_CursorZ
+ )
+ {
+ // If the regular placement doesn't work, do no further processing:
+ if (!super::OnPlayerPlace(a_World, a_Player, a_EquippedItem, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ))
+ {
+ return false;
+ }
+
+ // After successfully placing the sign, open the sign editor for the player:
+ AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
+ a_Player.GetClientHandle()->SendEditSign(a_BlockX, a_BlockY, a_BlockZ);
+ return true;
+ }
+
+
virtual bool IsPlaceable(void) override
{
return true;
diff --git a/src/Items/ItemSlab.h b/src/Items/ItemSlab.h
new file mode 100644
index 000000000..1b68b9d0c
--- /dev/null
+++ b/src/Items/ItemSlab.h
@@ -0,0 +1,93 @@
+
+// ItemSlab.h
+
+// Declares the cItemSlabHandler responsible for handling slabs, when in their item form.
+
+
+
+
+
+#pragma once
+
+#include "ItemHandler.h"
+#include "../Blocks/BlockSlab.h"
+
+
+
+
+
+class cItemSlabHandler:
+ public cItemHandler
+{
+ typedef cItemHandler super;
+
+public:
+
+ /** Creates a new handler for the specified slab item type.
+ Sets the handler to use the specified doubleslab block type for combining self into doubleslabs. */
+ cItemSlabHandler(int a_ItemType, BLOCKTYPE a_DoubleSlabBlockType):
+ super(a_ItemType),
+ m_DoubleSlabBlockType(a_DoubleSlabBlockType)
+ {
+ }
+
+
+ // cItemHandler overrides:
+ virtual bool OnPlayerPlace(
+ cWorld & a_World, cPlayer & a_Player, const cItem & a_EquippedItem,
+ int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
+ int a_CursorX, int a_CursorY, int a_CursorZ
+ ) override
+ {
+ // Special slab handling - placing a slab onto another slab produces a dblslab instead:
+ BLOCKTYPE ClickedBlockType;
+ NIBBLETYPE ClickedBlockMeta;
+ a_World.GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, ClickedBlockType, ClickedBlockMeta);
+ if (
+ (ClickedBlockType == m_ItemType) && // Placing the same slab material
+ (ClickedBlockMeta == a_EquippedItem.m_ItemDamage) // Placing the same slab sub-kind (and existing slab is single)
+ )
+ {
+ // If clicking the top side of a bottom-half slab, combine into a doubleslab:
+ if (
+ (a_BlockFace == BLOCK_FACE_TOP) &&
+ ((ClickedBlockMeta & 0x08) == 0)
+ )
+ {
+ return a_Player.PlaceBlock(a_BlockX, a_BlockY, a_BlockZ, m_DoubleSlabBlockType, ClickedBlockMeta & 0x07);
+ }
+
+ // If clicking the bottom side of a top-half slab, combine into a doubleslab:
+ if (
+ (a_BlockFace == BLOCK_FACE_BOTTOM) &&
+ ((ClickedBlockMeta & 0x08) != 0)
+ )
+ {
+ return a_Player.PlaceBlock(a_BlockX, a_BlockY, a_BlockZ, m_DoubleSlabBlockType, ClickedBlockMeta & 0x07);
+ }
+ }
+
+ // The slabs didn't combine, use the default handler to place the slab:
+ bool res = super::OnPlayerPlace(a_World, a_Player, a_EquippedItem, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ);
+
+ /*
+ The client has a bug when a slab replaces snow and there's a slab above it.
+ The client then combines the slab above, rather than replacing the snow.
+ We send the block above the currently placed block back to the client to fix the bug.
+ Ref.: http://forum.mc-server.org/showthread.php?tid=434&pid=17388#pid17388
+ */
+ if ((a_BlockFace == BLOCK_FACE_TOP) && (a_BlockY < cChunkDef::Height - 1))
+ {
+ a_Player.SendBlocksAround(a_BlockX, a_BlockY + 1, a_BlockZ, 1);
+ }
+ return res;
+ }
+
+protected:
+ /** The block type to use when the slab combines into a doubleslab block. */
+ BLOCKTYPE m_DoubleSlabBlockType;
+};
+
+
+
+
diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp
index 1e33ec433..34103ea5a 100644
--- a/src/Protocol/Protocol17x.cpp
+++ b/src/Protocol/Protocol17x.cpp
@@ -228,8 +228,8 @@ void cProtocol172::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockV
Pkt.WriteInt((int)a_Changes.size() * 4);
for (sSetBlockVector::const_iterator itr = a_Changes.begin(), end = a_Changes.end(); itr != end; ++itr)
{
- unsigned int Coords = itr->y | (itr->z << 8) | (itr->x << 12);
- unsigned int Blocks = itr->BlockMeta | (itr->BlockType << 4);
+ unsigned int Coords = itr->m_RelY | (itr->m_RelZ << 8) | (itr->m_RelX << 12);
+ unsigned int Blocks = itr->m_BlockMeta | (itr->m_BlockType << 4);
Pkt.WriteInt((Coords << 16) | Blocks);
} // for itr - a_Changes[]
}
diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp
index 1a13f4f7c..72827ac47 100644
--- a/src/Protocol/Protocol18x.cpp
+++ b/src/Protocol/Protocol18x.cpp
@@ -207,9 +207,9 @@ void cProtocol180::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockV
Pkt.WriteVarInt((UInt32)a_Changes.size());
for (sSetBlockVector::const_iterator itr = a_Changes.begin(), end = a_Changes.end(); itr != end; ++itr)
{
- short Coords = (short) (itr->y | (itr->z << 8) | (itr->x << 12));
+ short Coords = (short) (itr->m_RelY | (itr->m_RelZ << 8) | (itr->m_RelX << 12));
Pkt.WriteShort(Coords);
- Pkt.WriteVarInt((itr->BlockType & 0xFFF) << 4 | (itr->BlockMeta & 0xF));
+ Pkt.WriteVarInt((itr->m_BlockType & 0xFFF) << 4 | (itr->m_BlockMeta & 0xF));
} // for itr - a_Changes[]
}
diff --git a/src/World.cpp b/src/World.cpp
index ae739a2c3..c08b44f77 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -1463,7 +1463,7 @@ void cWorld::GrowTreeImage(const sSetBlockVector & a_Blocks)
sSetBlockVector b2;
for (sSetBlockVector::const_iterator itr = a_Blocks.begin(); itr != a_Blocks.end(); ++itr)
{
- if (itr->BlockType == E_BLOCK_LOG)
+ if (itr->m_BlockType == E_BLOCK_LOG)
{
b2.push_back(*itr);
}
@@ -1478,7 +1478,7 @@ void cWorld::GrowTreeImage(const sSetBlockVector & a_Blocks)
// Check that at each log's coord there's an block allowed to be overwritten:
for (sSetBlockVector::const_iterator itr = b2.begin(); itr != b2.end(); ++itr)
{
- switch (itr->BlockType)
+ switch (itr->m_BlockType)
{
CASE_TREE_ALLOWED_BLOCKS:
{
@@ -1926,6 +1926,15 @@ void cWorld::SpawnPrimedTNT(double a_X, double a_Y, double a_Z, int a_FuseTicks,
+void cWorld::SetBlocks(const sSetBlockVector & a_Blocks)
+{
+ m_ChunkMap->SetBlocks(a_Blocks);
+}
+
+
+
+
+
void cWorld::ReplaceBlocks(const sSetBlockVector & a_Blocks, BLOCKTYPE a_FilterBlockType)
{
m_ChunkMap->ReplaceBlocks(a_Blocks, a_FilterBlockType);
diff --git a/src/World.h b/src/World.h
index 4f24280a4..2ee33375f 100644
--- a/src/World.h
+++ b/src/World.h
@@ -491,6 +491,11 @@ public:
// tolua_end
+ /** Performs the specified single-block set operations simultaneously, as if SetBlock() was called for each item.
+ Is more efficient than calling SetBlock() multiple times.
+ If the chunk for any of the blocks is not loaded, the set operation is ignored silently. */
+ void SetBlocks(const sSetBlockVector & a_Blocks);
+
/** Replaces world blocks with a_Blocks, if they are of type a_FilterBlockType */
void ReplaceBlocks(const sSetBlockVector & a_Blocks, BLOCKTYPE a_FilterBlockType);
--
cgit v1.2.3
From 9c5463be1e090ff65acdc0c0571788f60ad76478 Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Wed, 24 Dec 2014 07:32:31 +0100
Subject: gcc compilation fix.
---
src/ChunkDef.h | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/ChunkDef.h b/src/ChunkDef.h
index b62656a58..959841ecc 100644
--- a/src/ChunkDef.h
+++ b/src/ChunkDef.h
@@ -399,9 +399,12 @@ public:
typedef std::list cChunkCoordsList;
typedef std::vector cChunkCoordsVector;
+namespace std
+{
+
/** A simple hash function for chunk coords, we assume that chunk coords won't use more than 16 bits, so the hash is almost an identity.
Used for std::unordered_map */
-template<> struct std::hash
+template<> struct hash
{
size_t operator ()(const cChunkCoords & a_Coords)
{
@@ -409,6 +412,8 @@ template<> struct std::hash
}
};
+} // namespace std
+
--
cgit v1.2.3
From 63de5f8a555e3bd4b9309792e3a9c0dcb9e8f4b6 Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Wed, 24 Dec 2014 08:38:37 +0100
Subject: Replaced a std::hash specialization with explicit type.
std::hash is problematic in gcc / clang, one has a class, the other a struct.
---
src/ChunkDef.h | 10 +++-------
src/Entities/Player.cpp | 2 +-
2 files changed, 4 insertions(+), 8 deletions(-)
diff --git a/src/ChunkDef.h b/src/ChunkDef.h
index 959841ecc..2bfa2949c 100644
--- a/src/ChunkDef.h
+++ b/src/ChunkDef.h
@@ -399,21 +399,17 @@ public:
typedef std::list cChunkCoordsList;
typedef std::vector cChunkCoordsVector;
-namespace std
-{
-
/** A simple hash function for chunk coords, we assume that chunk coords won't use more than 16 bits, so the hash is almost an identity.
Used for std::unordered_map */
-template<> struct hash
+class cChunkCoordsHash
{
- size_t operator ()(const cChunkCoords & a_Coords)
+public:
+ size_t operator () (const cChunkCoords & a_Coords) const
{
return (static_cast(a_Coords.m_ChunkX) << 16) ^ static_cast(a_Coords.m_ChunkZ);
}
};
-} // namespace std
-
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index 7bdd1c6f7..1d5cc6554 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -2206,7 +2206,7 @@ void cPlayer::SendBlocksAround(int a_BlockX, int a_BlockY, int a_BlockZ, int a_R
}
// Divide the block changes by their respective chunks:
- std::unordered_map Changes;
+ std::unordered_map Changes;
for (const auto & blk: blks)
{
Changes[cChunkCoords(blk.m_ChunkX, blk.m_ChunkZ)].push_back(blk);
--
cgit v1.2.3
From e09348c05d188979c490a9a22d39a1203cacc797 Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Wed, 24 Dec 2014 09:13:58 +0100
Subject: ByteBuffer: SingleThreadAccessChecker is request-only.
It slows the server down way too much, so it can't be turned on by default.
---
src/ByteBuffer.cpp | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/src/ByteBuffer.cpp b/src/ByteBuffer.cpp
index 080176dcd..b441d61ca 100644
--- a/src/ByteBuffer.cpp
+++ b/src/ByteBuffer.cpp
@@ -13,6 +13,15 @@
+/** When defined, each access to a cByteBuffer object is checked whether it's done in the same thread.
+cByteBuffer assumes that it is not used by multiple threads at once, this macro adds a runtime check for that.
+Unfortunately it is very slow, so it is disabled even for regular DEBUG builds. */
+// #define DEBUG_SINGLE_THREAD_ACCESS
+
+
+
+
+
// Try to determine endianness:
#if ( \
defined(__i386__) || defined(__alpha__) || \
@@ -109,7 +118,7 @@ public:
-#ifdef _DEBUG
+#ifdef DEBUG_SINGLE_THREAD_ACCESS
/** 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.
--
cgit v1.2.3
From f07784b92f9e402706afce148ecc50430832ae16 Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Wed, 24 Dec 2014 19:44:15 +0100
Subject: Fixed redstone dust placement on upside-down slabs.
---
src/Items/ItemRedstoneDust.h | 37 ++++++++++++++++++++++++++++++++++++-
1 file changed, 36 insertions(+), 1 deletion(-)
diff --git a/src/Items/ItemRedstoneDust.h b/src/Items/ItemRedstoneDust.h
index a2289239c..6d5fb521f 100644
--- a/src/Items/ItemRedstoneDust.h
+++ b/src/Items/ItemRedstoneDust.h
@@ -27,7 +27,20 @@ public:
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{
- if (!cBlockInfo::FullyOccupiesVoxel(a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ))) // Some solid blocks, such as cocoa beans, are not suitable for dust
+ // Check if coords are out of range:
+ if ((a_BlockY <= 0) || (a_BlockY >= cChunkDef::Height))
+ {
+ return false;
+ }
+
+ // Check the block below, if it supports dust on top of it:
+ BLOCKTYPE BlockType;
+ NIBBLETYPE BlockMeta;
+ if (!a_World->GetBlockTypeMeta(a_BlockX, a_BlockY - 1, a_BlockZ, BlockType, BlockMeta))
+ {
+ return false;
+ }
+ if (!IsBlockTypeUnderSuitable(BlockType, BlockMeta))
{
return false;
}
@@ -36,6 +49,28 @@ public:
a_BlockMeta = 0;
return true;
}
+
+
+ /** Returns true if the specified block type / meta is suitable to have redstone dust on top of it. */
+ static bool IsBlockTypeUnderSuitable(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
+ {
+ if (cBlockInfo::FullyOccupiesVoxel(a_BlockType))
+ {
+ return true;
+ }
+
+ switch (a_BlockType)
+ {
+ case E_BLOCK_NEW_STONE_SLAB:
+ case E_BLOCK_WOODEN_SLAB:
+ case E_BLOCK_STONE_SLAB:
+ {
+ // Slabs can support redstone if they're upside down:
+ return ((a_BlockMeta & 0x08) != 0);
+ }
+ }
+ return false;
+ }
} ;
--
cgit v1.2.3
From 5609d76ed7d8026b3bcaeb02fb42bd9ba2f27c96 Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Wed, 24 Dec 2014 20:02:51 +0100
Subject: APIDump: Updated the player block placement documentation.
The hooks now have fewer parameters but are called on all player-placed blocks (#1618).
---
MCServer/Plugins/APIDump/APIDesc.lua | 2 ++
MCServer/Plugins/APIDump/Hooks/OnPlayerPlacedBlock.lua | 10 +++++-----
MCServer/Plugins/APIDump/Hooks/OnPlayerPlacingBlock.lua | 10 +++++-----
src/Entities/Player.h | 3 ++-
4 files changed, 14 insertions(+), 11 deletions(-)
diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua
index ba3763724..b2c7108e9 100644
--- a/MCServer/Plugins/APIDump/APIDesc.lua
+++ b/MCServer/Plugins/APIDump/APIDesc.lua
@@ -1840,7 +1840,9 @@ a_Player:OpenWindow(Window);
MoveToWorld = { Params = "WorldName", Return = "bool", Return = "Moves the player to the specified world. Returns true if successful." },
OpenWindow = { Params = "{{cWindow|Window}}", Return = "", Notes = "Opens the specified UI window for the player." },
PermissionMatches = { Params = "Permission, Template", Return = "bool", Notes = "(STATIC) Returns true if the specified permission matches the specified template. The template may contain wildcards." },
+ PlaceBlock = { Params = "BlockX, BlockY, BlockZ, BlockType, BlockMeta", Return = "bool", Notes = "Places a block while impersonating the player. The {{OnPlayerPlacingBlock|HOOK_PLAYER_PLACING_BLOCK}} hook is called before the placement, and if it succeeds, the block is placed and the {{OnPlayerPlacedBlock|HOOK_PLAYER_PLACED_BLOCK}} hook is called. Returns true iff the block is successfully placed. Assumes that the block is in a currently loaded chunk." },
Respawn = { Params = "", Return = "", Notes = "Restores the health, extinguishes fire, makes visible and sends the Respawn packet." },
+ SendBlocksAround = { Params = "BlockX, BlockY, BlockZ, [Range]", Return = "", Notes = "Sends all the world's blocks in Range from the specified coords to the player, as a BlockChange packet. Range defaults to 1 (only one block sent)." },
SendMessage = { Params = "Message", Return = "", Notes = "Sends the specified message to the player." },
SendMessageFailure = { Params = "Message", Return = "", Notes = "Prepends Rose [INFO] / colours entire text (depending on ShouldUseChatPrefixes()) and sends message to player. For a command that failed to run because of insufficient permissions, etc." },
SendMessageFatal = { Params = "Message", Return = "", Notes = "Prepends Red [FATAL] / colours entire text (depending on ShouldUseChatPrefixes()) and sends message to player. For something serious, such as a plugin crash, etc." },
diff --git a/MCServer/Plugins/APIDump/Hooks/OnPlayerPlacedBlock.lua b/MCServer/Plugins/APIDump/Hooks/OnPlayerPlacedBlock.lua
index 54888a6db..6445a76b4 100644
--- a/MCServer/Plugins/APIDump/Hooks/OnPlayerPlacedBlock.lua
+++ b/MCServer/Plugins/APIDump/Hooks/OnPlayerPlacedBlock.lua
@@ -12,7 +12,11 @@ return
Use the {{cPlayer}}:GetWorld() function to get the world to which the block belongs.
See also the {{OnPlayerPlacingBlock|HOOK_PLAYER_PLACING_BLOCK}} hook for a similar hook called
- before the placement.
+ before the placement.
+
+ If the client action results in multiple blocks being placed (such as a bed or a door), each separate
+ block is reported through this hook. All the blocks are already present in the world before the first
+ instance of this hook is called.
]],
Params =
{
@@ -20,10 +24,6 @@ return
{ Name = "BlockX", Type = "number", Notes = "X-coord of the block" },
{ Name = "BlockY", Type = "number", Notes = "Y-coord of the block" },
{ Name = "BlockZ", Type = "number", Notes = "Z-coord of the block" },
- { Name = "BlockFace", Type = "number", Notes = "Face of the existing block upon which the player interacted. One of the BLOCK_FACE_ constants" },
- { Name = "CursorX", Type = "number", Notes = "X-coord of the cursor within the block face (0 .. 15)" },
- { Name = "CursorY", Type = "number", Notes = "Y-coord of the cursor within the block face (0 .. 15)" },
- { Name = "CursorZ", Type = "number", Notes = "Z-coord of the cursor within the block face (0 .. 15)" },
{ Name = "BlockType", Type = "BLOCKTYPE", Notes = "The block type of the block" },
{ Name = "BlockMeta", Type = "NIBBLETYPE", Notes = "The block meta of the block" },
},
diff --git a/MCServer/Plugins/APIDump/Hooks/OnPlayerPlacingBlock.lua b/MCServer/Plugins/APIDump/Hooks/OnPlayerPlacingBlock.lua
index 2a928390b..4241a09aa 100644
--- a/MCServer/Plugins/APIDump/Hooks/OnPlayerPlacingBlock.lua
+++ b/MCServer/Plugins/APIDump/Hooks/OnPlayerPlacingBlock.lua
@@ -15,7 +15,11 @@ return
Use the {{cPlayer}}:GetWorld() function to get the world to which the block belongs.
See also the {{OnPlayerPlacedBlock|HOOK_PLAYER_PLACED_BLOCK}} hook for a similar hook called after
- the placement.
+ the placement.
+
+ If the client action results in multiple blocks being placed (such as a bed or a door), each separate
+ block is reported through this hook and only if all of them succeed, all the blocks are placed. If
+ any one of the calls are refused by the plugin, all the blocks are refused and reverted on the client.
]],
Params =
{
@@ -23,10 +27,6 @@ return
{ Name = "BlockX", Type = "number", Notes = "X-coord of the block" },
{ Name = "BlockY", Type = "number", Notes = "Y-coord of the block" },
{ Name = "BlockZ", Type = "number", Notes = "Z-coord of the block" },
- { Name = "BlockFace", Type = "number", Notes = "Face of the existing block upon which the player is interacting. One of the BLOCK_FACE_ constants" },
- { Name = "CursorX", Type = "number", Notes = "X-coord of the cursor within the block face (0 .. 15)" },
- { Name = "CursorY", Type = "number", Notes = "Y-coord of the cursor within the block face (0 .. 15)" },
- { Name = "CursorZ", Type = "number", Notes = "Z-coord of the cursor within the block face (0 .. 15)" },
{ Name = "BlockType", Type = "BLOCKTYPE", Notes = "The block type of the block" },
{ Name = "BlockMeta", Type = "NIBBLETYPE", Notes = "The block meta of the block" },
},
diff --git a/src/Entities/Player.h b/src/Entities/Player.h
index 33ab5293c..b94d2659e 100644
--- a/src/Entities/Player.h
+++ b/src/Entities/Player.h
@@ -442,7 +442,8 @@ public:
/** Calls the block-placement hook and places the block in the world, unless refused by the hook.
If the hook prevents the placement, sends the current block at the specified coords back to the client.
- Assumes that all the blocks are in currently loaded chunks. */
+ Assumes that the block is in a currently loaded chunk.
+ Returns true if the block is successfully placed. */
bool PlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
/** Sends the block in the specified range around the specified coord to the client
--
cgit v1.2.3
From 081e7ddd028d9382bd52c2b117dae6b6f84225e5 Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Thu, 25 Dec 2014 00:34:54 +0100
Subject: cIsThread: Fixed a race condition on thread start.
---
src/OSSupport/IsThread.cpp | 18 ++++++++++++++++--
src/OSSupport/IsThread.h | 19 ++++++++++++++-----
2 files changed, 30 insertions(+), 7 deletions(-)
diff --git a/src/OSSupport/IsThread.cpp b/src/OSSupport/IsThread.cpp
index 94bed1f56..55e96b622 100644
--- a/src/OSSupport/IsThread.cpp
+++ b/src/OSSupport/IsThread.cpp
@@ -68,11 +68,22 @@ cIsThread::~cIsThread()
+void cIsThread::DoExecute(void)
+{
+ m_evtStart.Wait();
+ Execute();
+}
+
+
+
+
+
bool cIsThread::Start(void)
{
try
{
- m_Thread = std::thread(&cIsThread::Execute, this);
+ // Initialize the thread:
+ m_Thread = std::thread(&cIsThread::DoExecute, this);
#if defined (_MSC_VER) && defined(_DEBUG)
if (!m_ThreadName.empty())
@@ -81,9 +92,12 @@ bool cIsThread::Start(void)
}
#endif
+ // Notify the thread that initialization is complete and it can run its code safely:
+ m_evtStart.Set();
+
return true;
}
- catch (std::system_error & a_Exception)
+ catch (const std::system_error & a_Exception)
{
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;
diff --git a/src/OSSupport/IsThread.h b/src/OSSupport/IsThread.h
index 131c6950e..f642c8724 100644
--- a/src/OSSupport/IsThread.h
+++ b/src/OSSupport/IsThread.h
@@ -25,23 +25,28 @@ In the descending class' constructor call the Start() method to start the thread
class cIsThread
{
protected:
- /// This is the main thread entrypoint
+ /** This is the main thread entrypoint.
+ This function, overloaded by the descendants, is called in the new thread. */
virtual void Execute(void) = 0;
- /// The overriden Execute() method should check this value periodically and terminate if this is true
+ /** The overriden Execute() method should check this value periodically and terminate if this is true. */
volatile bool m_ShouldTerminate;
+private:
+ /** Wrapper for Execute() that waits for the initialization event, to prevent race conditions in thread initialization. */
+ void DoExecute(void);
+
public:
cIsThread(const AString & a_ThreadName);
virtual ~cIsThread();
- /// Starts the thread; returns without waiting for the actual start
+ /** Starts the thread; returns without waiting for the actual start. */
bool Start(void);
- /// Signals the thread to terminate and waits until it's finished
+ /** Signals the thread to terminate and waits until it's finished. */
void Stop(void);
- /// Waits for the thread to finish. Doesn't signalize the ShouldTerminate flag
+ /** Waits for the thread to finish. Doesn't signalize the ShouldTerminate flag. */
bool Wait(void);
/** Returns true if the thread calling this function is the thread contained within this object. */
@@ -50,6 +55,10 @@ public:
protected:
AString m_ThreadName;
std::thread m_Thread;
+
+ /** The event that is used to wait with the thread's execution until the thread object is fully initialized.
+ This prevents the IsCurrentThread() call to fail because of a race-condition. */
+ cEvent m_evtStart;
} ;
--
cgit v1.2.3
From f59740b262bf5259225ab4d6cd2537bead2a12a5 Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Thu, 25 Dec 2014 00:36:01 +0100
Subject: APIDump: Added details about client handle in OnServerPing hook.
---
MCServer/Plugins/APIDump/Hooks/OnServerPing.lua | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/MCServer/Plugins/APIDump/Hooks/OnServerPing.lua b/MCServer/Plugins/APIDump/Hooks/OnServerPing.lua
index 76b6d1517..430465786 100644
--- a/MCServer/Plugins/APIDump/Hooks/OnServerPing.lua
+++ b/MCServer/Plugins/APIDump/Hooks/OnServerPing.lua
@@ -7,7 +7,10 @@ return
Desc = [[
A plugin may implement an OnServerPing() function and register it as a Hook to process pings from
clients in the server server list. It can change the logged in players and player capacity, as well
- as the server description and the favicon, that are displayed to the client in the server list.
+ as the server description and the favicon, that are displayed to the client in the server list.
+
+ The client handle already has its protocol version assigned to it, so the plugin can check that; however,
+ there's no username associated with the client yet, and no player object.
]],
Params = {
{ Name = "ClientHandle", Type = "{{cClientHandle}}", Notes = "The client handle that pinged the server" },
--
cgit v1.2.3
From 3da6e4374e72e86930a24441c2b26f8eb582c723 Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Thu, 25 Dec 2014 00:44:09 +0100
Subject: Fixed basic style.
---
src/Mobs/Guardian.cpp | 2 +-
src/Mobs/Monster.cpp | 2 +-
src/Simulator/FloodyFluidSimulator.cpp | 2 +-
src/Simulator/IncrementalRedstoneSimulator.cpp | 88 ++++++++++++++++++++------
4 files changed, 71 insertions(+), 23 deletions(-)
diff --git a/src/Mobs/Guardian.cpp b/src/Mobs/Guardian.cpp
index d69ee1683..15908d801 100644
--- a/src/Mobs/Guardian.cpp
+++ b/src/Mobs/Guardian.cpp
@@ -28,7 +28,7 @@ void cGuardian::GetDrops(cItems & a_Drops, cEntity * a_Killer)
}
AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_PRISMARINE_SHARD);
AddRandomDropItem(a_Drops, 0, 1 + LootingLevel, E_ITEM_RAW_FISH);
- AddRandomDropItem(a_Drops, 0, 1 + LootingLevel, E_ITEM_PRISMARINE_CRYSTALS); // ToDo: Prismarine Crystals only drop if the raw fish drop is 0
+ AddRandomDropItem(a_Drops, 0, 1 + LootingLevel, E_ITEM_PRISMARINE_CRYSTALS); // TODO: Prismarine Crystals only drop if the raw fish drop is 0
}
diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp
index a02ea357e..425c80bf4 100644
--- a/src/Mobs/Monster.cpp
+++ b/src/Mobs/Monster.cpp
@@ -846,7 +846,7 @@ cMonster::eFamily cMonster::FamilyFromType(eMonsterType a_Type)
case mtEnderman: return mfHostile;
case mtGhast: return mfHostile;
case mtGiant: return mfNoSpawn;
- case mtGuardian: return mfWater; // Just because they have special spawning conditions. If Watertemples have been added, this needs to be edited!
+ case mtGuardian: return mfWater; // Just because they have special spawning conditions. If Watertemples have been added, this needs to be edited!
case mtHorse: return mfPassive;
case mtIronGolem: return mfPassive;
case mtMagmaCube: return mfHostile;
diff --git a/src/Simulator/FloodyFluidSimulator.cpp b/src/Simulator/FloodyFluidSimulator.cpp
index 37d58307b..bcd083294 100644
--- a/src/Simulator/FloodyFluidSimulator.cpp
+++ b/src/Simulator/FloodyFluidSimulator.cpp
@@ -105,7 +105,7 @@ void cFloodyFluidSimulator::SimulateBlock(cChunk * a_Chunk, int a_RelX, int a_Re
}
// Spread to the neighbors:
if (SpreadFurther && (NewMeta < 8))
- {
+ {
SpreadXZ(a_Chunk, a_RelX, a_RelY, a_RelZ, NewMeta);
}
// If source creation is on, check for it here:
diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp
index 544a0689d..7ff499eb5 100644
--- a/src/Simulator/IncrementalRedstoneSimulator.cpp
+++ b/src/Simulator/IncrementalRedstoneSimulator.cpp
@@ -93,7 +93,7 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
), SimulatedPlayerToggleableBlocks.end());
- auto & RepeatersDelayList = ((cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData())->m_RepeatersDelayList;
+ auto & RepeatersDelayList = ((cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData())->m_RepeatersDelayList;
RepeatersDelayList.erase(std::remove_if(RepeatersDelayList.begin(), RepeatersDelayList.end(), [RelX, a_BlockY, RelZ, Block](const sRepeatersDelayList & itr)
{
return itr.a_RelBlockPos.Equals(Vector3i(RelX, a_BlockY, RelZ)) && (Block != E_BLOCK_REDSTONE_REPEATER_ON) && (Block != E_BLOCK_REDSTONE_REPEATER_OFF);
@@ -1488,62 +1488,92 @@ bool cIncrementalRedstoneSimulator::IsRepeaterPowered(int a_RelBlockX, int a_Rel
for (const auto & itr : *m_PoweredBlocks)
{
- if (!itr.a_BlockPos.Equals(Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ))) { continue; }
+ if (!itr.a_BlockPos.Equals(Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ)))
+ {
+ continue;
+ }
switch (a_Meta & 0x3)
{
case 0x0:
{
// Flip the coords to check the back of the repeater
- if (itr.a_SourcePos.Equals(AdjustRelativeCoords(Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1)))) { return true; }
+ if (itr.a_SourcePos.Equals(AdjustRelativeCoords(Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1))))
+ {
+ return true;
+ }
break;
}
case 0x1:
{
- if (itr.a_SourcePos.Equals(AdjustRelativeCoords(Vector3i(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ)))) { return true; }
+ if (itr.a_SourcePos.Equals(AdjustRelativeCoords(Vector3i(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ))))
+ {
+ return true;
+ }
break;
}
case 0x2:
{
- if (itr.a_SourcePos.Equals(AdjustRelativeCoords(Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1)))) { return true; }
+ if (itr.a_SourcePos.Equals(AdjustRelativeCoords(Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1))))
+ {
+ return true;
+ }
break;
}
case 0x3:
{
- if (itr.a_SourcePos.Equals(AdjustRelativeCoords(Vector3i(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ)))) { return true; }
+ if (itr.a_SourcePos.Equals(AdjustRelativeCoords(Vector3i(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ))))
+ {
+ return true;
+ }
break;
}
}
- }
+ } // for itr - m_PoweredBlocks[]
for (const auto & itr : *m_LinkedPoweredBlocks)
{
- if (!itr.a_BlockPos.Equals(Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ))) { continue; }
+ if (!itr.a_BlockPos.Equals(Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ)))
+ {
+ continue;
+ }
switch (a_Meta & 0x3)
{
case 0x0:
{
- if (itr.a_MiddlePos.Equals(AdjustRelativeCoords(Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1)))) { return true; }
+ if (itr.a_MiddlePos.Equals(AdjustRelativeCoords(Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1))))
+ {
+ return true;
+ }
break;
}
case 0x1:
{
- if (itr.a_MiddlePos.Equals(AdjustRelativeCoords(Vector3i(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ)))) { return true; }
+ if (itr.a_MiddlePos.Equals(AdjustRelativeCoords(Vector3i(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ))))
+ {
+ return true;
+ }
break;
}
case 0x2:
{
- if (itr.a_MiddlePos.Equals(AdjustRelativeCoords(Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1)))) { return true; }
+ if (itr.a_MiddlePos.Equals(AdjustRelativeCoords(Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1))))
+ {
+ return true;
+ }
break;
}
case 0x3:
{
- if (itr.a_MiddlePos.Equals(AdjustRelativeCoords(Vector3i(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ)))) { return true; }
+ if (itr.a_MiddlePos.Equals(AdjustRelativeCoords(Vector3i(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ))))
+ {
+ return true;
+ }
break;
}
}
- }
+ } // for itr - m_LinkedPoweredBlocks[]
return false; // Couldn't find power source behind repeater
}
@@ -1559,10 +1589,13 @@ bool cIncrementalRedstoneSimulator::IsRepeaterLocked(int a_RelBlockX, int a_RelB
case 0x0:
case 0x2:
{
- // Check if eastern(right) neighbor is a powered on repeater who is facing us
+ // Check if eastern (right) neighbor is a powered on repeater who is facing us
BLOCKTYPE Block = 0;
NIBBLETYPE OtherRepeaterDir = 0;
- if (m_Chunk->UnboundedRelGetBlock(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, Block, OtherRepeaterDir) && (Block == E_BLOCK_REDSTONE_REPEATER_ON)) // Is right neighbor a powered repeater?
+ if (
+ m_Chunk->UnboundedRelGetBlock(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, Block, OtherRepeaterDir) &&
+ (Block == E_BLOCK_REDSTONE_REPEATER_ON)
+ )
{
if ((OtherRepeaterDir & 0x03) == 0x3)
{
@@ -1571,7 +1604,10 @@ bool cIncrementalRedstoneSimulator::IsRepeaterLocked(int a_RelBlockX, int a_RelB
}
// Check if western(left) neighbor is a powered on repeater who is facing us
- if (m_Chunk->UnboundedRelGetBlock(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, Block, OtherRepeaterDir) && (Block == E_BLOCK_REDSTONE_REPEATER_ON))
+ if (
+ m_Chunk->UnboundedRelGetBlock(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, Block, OtherRepeaterDir) &&
+ (Block == E_BLOCK_REDSTONE_REPEATER_ON)
+ )
{
if ((OtherRepeaterDir & 0x03) == 0x1)
{
@@ -1590,7 +1626,10 @@ bool cIncrementalRedstoneSimulator::IsRepeaterLocked(int a_RelBlockX, int a_RelB
BLOCKTYPE Block = 0;
NIBBLETYPE OtherRepeaterDir = 0;
- if (m_Chunk->UnboundedRelGetBlock(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, Block, OtherRepeaterDir) && (Block == E_BLOCK_REDSTONE_REPEATER_ON))
+ if (
+ m_Chunk->UnboundedRelGetBlock(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, Block, OtherRepeaterDir) &&
+ (Block == E_BLOCK_REDSTONE_REPEATER_ON)
+ )
{
if ((OtherRepeaterDir & 0x30) == 0x00)
{
@@ -1599,7 +1638,10 @@ bool cIncrementalRedstoneSimulator::IsRepeaterLocked(int a_RelBlockX, int a_RelB
}
// Check if northern(up) neighbor is a powered on repeater who is facing us
- if (m_Chunk->UnboundedRelGetBlock(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, Block, OtherRepeaterDir) && (Block == E_BLOCK_REDSTONE_REPEATER_ON))
+ if (
+ m_Chunk->UnboundedRelGetBlock(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, Block, OtherRepeaterDir) &&
+ (Block == E_BLOCK_REDSTONE_REPEATER_ON)
+ )
{
if ((OtherRepeaterDir & 0x03) == 0x02)
{
@@ -1625,7 +1667,10 @@ bool cIncrementalRedstoneSimulator::IsPistonPowered(int a_RelBlockX, int a_RelBl
for (const auto & itr : *m_PoweredBlocks)
{
- if (!itr.a_BlockPos.Equals(Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ))) { continue; }
+ if (!itr.a_BlockPos.Equals(Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ)))
+ {
+ continue;
+ }
int X = a_RelBlockX, Z = a_RelBlockZ;
AddFaceDirection(X, a_RelBlockY, Z, Face);
@@ -1638,7 +1683,10 @@ bool cIncrementalRedstoneSimulator::IsPistonPowered(int a_RelBlockX, int a_RelBl
for (const auto & itr : *m_LinkedPoweredBlocks)
{
- if (!itr.a_BlockPos.Equals(Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ))) { continue; }
+ if (!itr.a_BlockPos.Equals(Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ)))
+ {
+ continue;
+ }
int X = a_RelBlockX, Z = a_RelBlockZ;
AddFaceDirection(X, a_RelBlockY, Z, Face);
--
cgit v1.2.3
From 1af621046652b4b79672342a2c40748cac8137cb Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Thu, 25 Dec 2014 00:51:24 +0100
Subject: Fixed forgotten big flower handler.
---
src/Items/ItemHandler.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp
index 92c55ec62..621cf9501 100644
--- a/src/Items/ItemHandler.cpp
+++ b/src/Items/ItemHandler.cpp
@@ -106,8 +106,10 @@ cItemHandler * cItemHandler::CreateItemHandler(int a_ItemType)
default: return new cItemHandler(a_ItemType);
// Single item per handler, alphabetically sorted:
+ case E_BLOCK_BIG_FLOWER: return new cItemBigFlowerHandler;
case E_BLOCK_CHEST: return new cItemChestHandler(a_ItemType);
case E_BLOCK_LEAVES: return new cItemLeavesHandler(a_ItemType);
+ case E_BLOCK_LILY_PAD: return new cItemLilypadHandler(a_ItemType);
case E_BLOCK_HEAD: return new cItemMobHeadHandler(a_ItemType);
case E_BLOCK_NEW_LEAVES: return new cItemLeavesHandler(a_ItemType);
case E_BLOCK_PUMPKIN: return new cItemPumpkinHandler;
@@ -134,7 +136,6 @@ cItemHandler * cItemHandler::CreateItemHandler(int a_ItemType)
case E_ITEM_FLINT_AND_STEEL: return new cItemLighterHandler(a_ItemType);
case E_ITEM_FLOWER_POT: return new cItemFlowerPotHandler(a_ItemType);
case E_ITEM_GOLDEN_APPLE: return new cItemGoldenAppleHandler();
- case E_BLOCK_LILY_PAD: return new cItemLilypadHandler(a_ItemType);
case E_ITEM_MAP: return new cItemMapHandler();
case E_ITEM_MILK: return new cItemMilkHandler();
case E_ITEM_MUSHROOM_SOUP: return new cItemMushroomSoupHandler(a_ItemType);
--
cgit v1.2.3
From 9e478c6f29702002c227dc06c0a1f49d1568de53 Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Thu, 25 Dec 2014 01:00:51 +0100
Subject: Fixed door placement.
---
src/Blocks/BlockDoor.h | 3 ++-
src/Items/ItemDoor.h | 4 ++--
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/Blocks/BlockDoor.h b/src/Blocks/BlockDoor.h
index 334519077..53f84b553 100644
--- a/src/Blocks/BlockDoor.h
+++ b/src/Blocks/BlockDoor.h
@@ -117,7 +117,8 @@ public:
static bool CanBeOn(BLOCKTYPE a_BlockType)
{
// Vanilla refuses to place doors on transparent blocks
- return !cBlockInfo::IsTransparent(a_BlockType);
+ // We need to keep the door compatible with itself, otherwise the top half drops while the bottom half stays
+ return !cBlockInfo::IsTransparent(a_BlockType) || IsDoorBlockType(a_BlockType);
}
diff --git a/src/Items/ItemDoor.h b/src/Items/ItemDoor.h
index dbba26728..dacf286e5 100644
--- a/src/Items/ItemDoor.h
+++ b/src/Items/ItemDoor.h
@@ -27,7 +27,7 @@ public:
) override
{
// Vanilla only allows door placement while clicking on the top face of the block below the door:
- if (a_BlockFace != BLOCK_FACE_NONE)
+ if (a_BlockFace != BLOCK_FACE_TOP)
{
return false;
}
@@ -40,7 +40,7 @@ public:
}
// The door needs a compatible block below it:
- if ((a_BlockY > 0) && cBlockDoorHandler::CanBeOn(a_World.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ)))
+ if ((a_BlockY > 0) && !cBlockDoorHandler::CanBeOn(a_World.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ)))
{
return false;
}
--
cgit v1.2.3
From 7d35e84578488769c4ee515568bd5f9ed7ef0dac Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Thu, 25 Dec 2014 08:47:35 +0100
Subject: Fixed tools compilation.
Fixes errors introduced in 081e7ddd028d9382bd52c2b117dae6b6f84225e5.
---
Tools/MCADefrag/CMakeLists.txt | 2 ++
Tools/MCADefrag/Globals.h | 1 +
Tools/ProtoProxy/CMakeLists.txt | 2 ++
3 files changed, 5 insertions(+)
diff --git a/Tools/MCADefrag/CMakeLists.txt b/Tools/MCADefrag/CMakeLists.txt
index 82e048671..700310edc 100644
--- a/Tools/MCADefrag/CMakeLists.txt
+++ b/Tools/MCADefrag/CMakeLists.txt
@@ -53,6 +53,7 @@ source_group("Shared" FILES ${SHARED_SRC} ${SHARED_HDR})
set(SHARED_OSS_SRC
../../src/OSSupport/CriticalSection.cpp
+ ../../src/OSSupport/Event.cpp
../../src/OSSupport/File.cpp
../../src/OSSupport/IsThread.cpp
../../src/OSSupport/StackTrace.cpp
@@ -60,6 +61,7 @@ set(SHARED_OSS_SRC
set(SHARED_OSS_HDR
../../src/OSSupport/CriticalSection.h
+ ../../src/OSSupport/Event.h
../../src/OSSupport/File.h
../../src/OSSupport/IsThread.h
../../src/OSSupport/StackTrace.h
diff --git a/Tools/MCADefrag/Globals.h b/Tools/MCADefrag/Globals.h
index 288069599..f13a06566 100644
--- a/Tools/MCADefrag/Globals.h
+++ b/Tools/MCADefrag/Globals.h
@@ -201,6 +201,7 @@ typedef unsigned char Byte;
// Common headers (without macros):
#include "StringUtils.h"
#include "OSSupport/CriticalSection.h"
+#include "OSSupport/Event.h"
#include "OSSupport/IsThread.h"
#include "OSSupport/File.h"
diff --git a/Tools/ProtoProxy/CMakeLists.txt b/Tools/ProtoProxy/CMakeLists.txt
index cca0c1b8b..132a14f78 100644
--- a/Tools/ProtoProxy/CMakeLists.txt
+++ b/Tools/ProtoProxy/CMakeLists.txt
@@ -55,12 +55,14 @@ set(SHARED_HDR
)
set(SHARED_OSS_SRC
../../src/OSSupport/CriticalSection.cpp
+ ../../src/OSSupport/Event.cpp
../../src/OSSupport/File.cpp
../../src/OSSupport/IsThread.cpp
../../src/OSSupport/StackTrace.cpp
)
set(SHARED_OSS_HDR
../../src/OSSupport/CriticalSection.h
+ ../../src/OSSupport/Event.h
../../src/OSSupport/File.h
../../src/OSSupport/IsThread.h
../../src/OSSupport/StackTrace.h
--
cgit v1.2.3
From ff65e77c577370862a0e6bc7de3c968308c92aa5 Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Thu, 25 Dec 2014 08:49:47 +0100
Subject: Added basic style checking to Travis builds.
---
CIbuild.sh | 1 +
1 file changed, 1 insertion(+)
diff --git a/CIbuild.sh b/CIbuild.sh
index 5d95f88a6..6e54187ac 100755
--- a/CIbuild.sh
+++ b/CIbuild.sh
@@ -7,6 +7,7 @@ export MCSERVER_BUILD_ID=$TRAVIS_JOB_NUMBER
export MCSERVER_BUILD_DATETIME=`date`
cmake . -DBUILD_TOOLS=1 -DSELF_TEST=1;
+lua src/CheckBasicStyle.lua
make -j 2;
make -j 2 test;
cd MCServer/;
--
cgit v1.2.3
From e8c8aca7791a598244aa9dcc9a0992d2c249652d Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Thu, 25 Dec 2014 08:59:28 +0100
Subject: Travis: Added lua installation before build.
---
.travis.yml | 3 +++
1 file changed, 3 insertions(+)
diff --git a/.travis.yml b/.travis.yml
index 26e74c1b2..84b963a89 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,9 @@ before_install:
install:
# g++4.8 and clang
- sudo apt-get install -qq g++-4.8
+
+ # lua, needed for style checking and possibly later on for bindings generation
+ - sudo apt-get install -qq lua5.1
# g++4.8
- if [ "$CXX" == "g++" ]; then export CXX="g++-4.8"; export CC="gcc-4.8"; fi
--
cgit v1.2.3
From f5005fd2f8abf39387ec86e39db9d3421a03ad37 Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Thu, 25 Dec 2014 09:11:25 +0100
Subject: Travis style check in the right folder.
---
CIbuild.sh | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/CIbuild.sh b/CIbuild.sh
index 6e54187ac..755dc7daa 100755
--- a/CIbuild.sh
+++ b/CIbuild.sh
@@ -7,7 +7,9 @@ export MCSERVER_BUILD_ID=$TRAVIS_JOB_NUMBER
export MCSERVER_BUILD_DATETIME=`date`
cmake . -DBUILD_TOOLS=1 -DSELF_TEST=1;
-lua src/CheckBasicStyle.lua
+cd src
+lua CheckBasicStyle.lua
+cd ..
make -j 2;
make -j 2 test;
cd MCServer/;
--
cgit v1.2.3
From eddbce64be8af048581afb0db85a27dd50af26a6 Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Thu, 25 Dec 2014 17:15:19 +0100
Subject: MobHeads: fixed regular head placement.
---
src/Items/ItemMobHead.h | 24 ++++++++++++++++++++++--
1 file changed, 22 insertions(+), 2 deletions(-)
diff --git a/src/Items/ItemMobHead.h b/src/Items/ItemMobHead.h
index d962dabae..ac905275a 100644
--- a/src/Items/ItemMobHead.h
+++ b/src/Items/ItemMobHead.h
@@ -53,7 +53,7 @@ public:
)
{
// Place the block:
- if (!a_Player.PlaceBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_HEAD, static_cast(a_EquippedItem.m_ItemType)))
+ if (!a_Player.PlaceBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_HEAD, BlockFaceToBlockMeta(a_BlockFace)))
{
return false;
}
@@ -92,7 +92,7 @@ public:
m_BlockMeta(a_BlockMeta)
{}
};
- cCallback Callback(a_Player, static_cast(a_EquippedItem.m_ItemType), static_cast(a_BlockFace));
+ cCallback Callback(a_Player, static_cast(a_EquippedItem.m_ItemDamage), static_cast(a_BlockFace));
a_World.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ, Callback);
return true;
}
@@ -279,6 +279,26 @@ public:
}
+ /** Converts the block face of the placement (which face of the block was clicked to place the head)
+ into the block's metadata value. */
+ static NIBBLETYPE BlockFaceToBlockMeta(int a_BlockFace)
+ {
+ switch (a_BlockFace)
+ {
+ case BLOCK_FACE_TOP: return 0x01; // On ground (rotation provided in block entity)
+ case BLOCK_FACE_XM: return 0x04; // west wall, facing east
+ case BLOCK_FACE_XP: return 0x05; // east wall, facing west
+ case BLOCK_FACE_ZM: return 0x02; // north wall, facing south
+ case BLOCK_FACE_ZP: return 0x03; // south wall, facing north
+ default:
+ {
+ ASSERT(!"Unhandled block face");
+ return 0;
+ }
+ }
+ }
+
+
virtual bool IsPlaceable(void) override
{
return true;
--
cgit v1.2.3
From 9e4528793ac49d9b1e61bfa02dd472c875ed6e99 Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Thu, 25 Dec 2014 17:15:37 +0100
Subject: ProtoProxy: Log block change packet details.
---
Tools/ProtoProxy/Connection.cpp | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Tools/ProtoProxy/Connection.cpp b/Tools/ProtoProxy/Connection.cpp
index 468529124..d42afb7ba 100644
--- a/Tools/ProtoProxy/Connection.cpp
+++ b/Tools/ProtoProxy/Connection.cpp
@@ -1392,6 +1392,9 @@ bool cConnection::HandleServerBlockChange(void)
HANDLE_SERVER_PACKET_READ(ReadVarInt, UInt32, BlockType);
HANDLE_SERVER_PACKET_READ(ReadChar, char, BlockMeta);
Log("Received a PACKET_BLOCK_CHANGE from the server");
+ Log(" Pos = {%d, %d, %d}", BlockX, BlockY, BlockZ);
+ Log(" BlockType = %d (0x%x", BlockType, BlockType);
+ Log(" BlockMeta = %d", BlockMeta);
COPY_TO_CLIENT();
return true;
}
--
cgit v1.2.3
From 19ff14752eca260e2dfcbf4e8aa3cb11a044383d Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Thu, 25 Dec 2014 20:41:27 +0100
Subject: MobHead: Fixed wither spawning.
---
src/Items/ItemMobHead.h | 53 +++++++++++++++++++++++++++++++++++++------------
1 file changed, 40 insertions(+), 13 deletions(-)
diff --git a/src/Items/ItemMobHead.h b/src/Items/ItemMobHead.h
index ac905275a..8780f7e4b 100644
--- a/src/Items/ItemMobHead.h
+++ b/src/Items/ItemMobHead.h
@@ -150,9 +150,9 @@ public:
// Image for the wither at the X axis:
static const sSetBlock ImageWitherX[] =
{
- {-1, 0, 0, E_BLOCK_HEAD, E_META_HEAD_WITHER},
- { 0, 0, 0, E_BLOCK_HEAD, E_META_HEAD_WITHER},
- { 1, 0, 0, E_BLOCK_HEAD, E_META_HEAD_WITHER},
+ {-1, 0, 0, E_BLOCK_HEAD, 0},
+ { 0, 0, 0, E_BLOCK_HEAD, 0},
+ { 1, 0, 0, E_BLOCK_HEAD, 0},
{-1, -1, 0, E_BLOCK_SOULSAND, 0},
{ 0, -1, 0, E_BLOCK_SOULSAND, 0},
{ 1, -1, 0, E_BLOCK_SOULSAND, 0},
@@ -164,9 +164,9 @@ public:
// Image for the wither at the Z axis:
static const sSetBlock ImageWitherZ[] =
{
- { 0, 0, -1, E_BLOCK_HEAD, E_META_HEAD_WITHER},
- { 0, 0, 0, E_BLOCK_HEAD, E_META_HEAD_WITHER},
- { 0, 0, 1, E_BLOCK_HEAD, E_META_HEAD_WITHER},
+ { 0, 0, -1, E_BLOCK_HEAD, 0},
+ { 0, 0, 0, E_BLOCK_HEAD, 0},
+ { 0, 0, 1, E_BLOCK_HEAD, 0},
{ 0, -1, -1, E_BLOCK_SOULSAND, 0},
{ 0, -1, 0, E_BLOCK_SOULSAND, 0},
{ 0, -1, 1, E_BLOCK_SOULSAND, 0},
@@ -208,14 +208,14 @@ public:
for (size_t i = 0; i < a_ImageCount; i++)
{
// Get the absolute coords of the image:
- int BlockX = a_PlacedHeadX + a_OffsetX + a_Image[i].m_RelX;
- int BlockY = a_PlacedHeadY + a_Image[i].m_RelY;
- int BlockZ = a_PlacedHeadZ + a_OffsetZ + a_Image[i].m_RelZ;
+ int BlockX = a_PlacedHeadX + a_OffsetX + a_Image[i].GetX();
+ int BlockY = a_PlacedHeadY + a_Image[i].GetY();
+ int BlockZ = a_PlacedHeadZ + a_OffsetZ + a_Image[i].GetZ();
// If the query is for the placed head, short-circuit-evaluate it:
if ((BlockX == a_PlacedHeadX) && (BlockY == a_PlacedHeadY) && (BlockZ == a_PlacedHeadZ))
{
- if ((a_Image[i].m_BlockType != E_BLOCK_HEAD) || (a_Image[i].m_BlockMeta != E_META_HEAD_WITHER))
+ if (a_Image[i].m_BlockType != E_BLOCK_HEAD)
{
return false; // Didn't match
}
@@ -232,14 +232,41 @@ public:
}
// Compare the world block:
- if ((BlockType != a_Image[i].m_BlockType) || (BlockMeta != a_Image[i].m_BlockMeta))
+ if (BlockType != a_Image[i].m_BlockType)
{
- return false; // Didn't match
+ return false;
+ }
+
+ // If it is a mob head, check the correct head type using the block entity:
+ if (BlockType == E_BLOCK_HEAD)
+ {
+ class cHeadCallback: public cBlockEntityCallback
+ {
+ virtual bool Item(cBlockEntity * a_Entity) override
+ {
+ ASSERT(a_Entity->GetBlockType() == E_BLOCK_HEAD);
+ cMobHeadEntity * MobHead = static_cast(a_Entity);
+ m_IsWitherHead = (MobHead->GetType() == SKULL_TYPE_WITHER);
+ return true;
+ }
+ public:
+ cHeadCallback(void):
+ m_IsWitherHead(false)
+ {
+ }
+ bool m_IsWitherHead;
+ } callback;
+ a_World.DoWithBlockEntityAt(BlockX, BlockY, BlockZ, callback);
+ if (!callback.m_IsWitherHead)
+ {
+ return false;
+ }
}
// Matched, continue checking
+ AirBlocks.emplace_back(BlockX, BlockY, BlockZ, E_BLOCK_AIR, 0);
} // for i - a_Image
- // All image blocks matched, try place the wither:
+ // All image blocks matched, try replace the image with air blocks:
if (!a_Player.PlaceBlocks(AirBlocks))
{
return false;
--
cgit v1.2.3
From dcdecc0ca7f6df567e94d55c9373667da7338172 Mon Sep 17 00:00:00 2001
From: worktycho
Date: Fri, 26 Dec 2014 14:27:26 +0000
Subject: Add make as a required program for *nix
---
COMPILING.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/COMPILING.md b/COMPILING.md
index 731d64653..34b1e976f 100644
--- a/COMPILING.md
+++ b/COMPILING.md
@@ -69,9 +69,9 @@ After doing so, run the command `xcodebuild lib/polarssl/POLARSSL.xcodeproj` in
## Linux, FreeBSD etc. ##
-Install git, cmake and gcc or clang, using your platform's package manager:
+Install git, make, cmake and gcc or clang, using your platform's package manager:
```
-sudo apt-get install git cmake gcc g++
+sudo apt-get install git make cmake gcc g++
```
### Getting the sources ###
--
cgit v1.2.3
From b621fb511f5048968434475e4ebc7f4d012626aa Mon Sep 17 00:00:00 2001
From: tonibm19
Date: Mon, 29 Dec 2014 20:21:57 +0100
Subject: Added player count to webadmin
Now it shows the number of online players near the memory use
---
MCServer/webadmin/template.lua | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/MCServer/webadmin/template.lua b/MCServer/webadmin/template.lua
index 4d3934da8..416657c4b 100644
--- a/MCServer/webadmin/template.lua
+++ b/MCServer/webadmin/template.lua
@@ -52,12 +52,21 @@ end
+function GetTotalPlayers()
+ Players=0
+ local EachPlayer = function(Player)
+ Players = Players + 1
+ end
+ cRoot:Get():ForEachPlayer(EachPlayer)
+ return Players
+end
function ShowPage(WebAdmin, TemplateRequest)
SiteContent = {}
local BaseURL = WebAdmin:GetBaseURL(TemplateRequest.Request.Path)
local Title = "MCServer WebAdmin"
+ local NumPlayers = GetTotalPlayers()
local MemoryUsageKiB = cRoot:GetPhysicalRAMUsage()
local NumChunks = cRoot:Get():GetTotalChunkCount()
local PluginPage = WebAdmin:GetPage(TemplateRequest.Request)
@@ -102,6 +111,7 @@ function ShowPage(WebAdmin, TemplateRequest)
--
cgit v1.2.3
From 48b0f4daa4fe190e48b2d2652a79c3f2c14c31b5 Mon Sep 17 00:00:00 2001
From: tonibm19
Date: Tue, 30 Dec 2014 10:31:16 +0100
Subject: Use cRoot:Get():GetServer():GetNumPlayers() instead of a custom
function.
---
MCServer/webadmin/template.lua | 10 +---------
1 file changed, 1 insertion(+), 9 deletions(-)
diff --git a/MCServer/webadmin/template.lua b/MCServer/webadmin/template.lua
index 416657c4b..6ea7b69bc 100644
--- a/MCServer/webadmin/template.lua
+++ b/MCServer/webadmin/template.lua
@@ -52,21 +52,13 @@ end
-function GetTotalPlayers()
- Players=0
- local EachPlayer = function(Player)
- Players = Players + 1
- end
- cRoot:Get():ForEachPlayer(EachPlayer)
- return Players
-end
function ShowPage(WebAdmin, TemplateRequest)
SiteContent = {}
local BaseURL = WebAdmin:GetBaseURL(TemplateRequest.Request.Path)
local Title = "MCServer WebAdmin"
- local NumPlayers = GetTotalPlayers()
+ local NumPlayers = cRoot:Get():GetServer():GetNumPlayers()
local MemoryUsageKiB = cRoot:GetPhysicalRAMUsage()
local NumChunks = cRoot:Get():GetTotalChunkCount()
local PluginPage = WebAdmin:GetPage(TemplateRequest.Request)
--
cgit v1.2.3
From 35a3a1b9f4fd52b37106271964157fc3b7a9ee84 Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Sat, 3 Jan 2015 22:20:30 +0100
Subject: cByteBuffer: Improved SingleThreadAccessChecker performance.
But it's still poor and unusable for regular testing.
---
src/ByteBuffer.cpp | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/ByteBuffer.cpp b/src/ByteBuffer.cpp
index b441d61ca..e1e5867a9 100644
--- a/src/ByteBuffer.cpp
+++ b/src/ByteBuffer.cpp
@@ -131,7 +131,7 @@ public:
{
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
+ (*a_ThreadID == m_EmptyThreadID) // ... or by no thread at all
);
// Mark as being used by this thread:
@@ -147,8 +147,13 @@ public:
protected:
/** Points to the storage used for ID of the thread using the object. */
std::thread::id * m_ThreadID;
+
+ /** The value of an unassigned thread ID, used to speed up checking. */
+ static std::thread::id m_EmptyThreadID;
};
+ std::thread::id cSingleThreadAccessChecker::m_EmptyThreadID;
+
#define CHECK_THREAD cSingleThreadAccessChecker Checker(&m_ThreadID);
#else
--
cgit v1.2.3
From 06c2669cf6b03feb15990004087e882ac846b061 Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Sat, 3 Jan 2015 22:23:49 +0100
Subject: Protocols: Ignore garbage data at the end of PluginMessage packets.
Fixes #1692.
---
src/Protocol/Protocol17x.cpp | 11 +++++++++++
src/Protocol/Protocol18x.cpp | 10 ++++++++++
2 files changed, 21 insertions(+)
diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp
index 34103ea5a..4e985355a 100644
--- a/src/Protocol/Protocol17x.cpp
+++ b/src/Protocol/Protocol17x.cpp
@@ -2242,6 +2242,7 @@ void cProtocol172::HandleVanillaPluginMessage(cByteBuffer & a_ByteBuffer, const
{
if (a_Channel == "MC|AdvCdm")
{
+ size_t BeginningSpace = a_ByteBuffer.GetReadableSpace();
HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Mode);
switch (Mode)
{
@@ -2265,6 +2266,16 @@ void cProtocol172::HandleVanillaPluginMessage(cByteBuffer & a_ByteBuffer, const
return;
}
} // switch (Mode)
+
+ // Read the remainder of the packet (Vanilla sometimes sends bogus data at the end of the packet; #1692):
+ size_t BytesRead = BeginningSpace - a_ByteBuffer.GetReadableSpace();
+ if (BytesRead < static_cast(a_PayloadLength))
+ {
+ LOGD("Protocol 1.7: Skipping garbage data at the end of a vanilla MC|AdvCdm packet, %u bytes",
+ a_PayloadLength - BytesRead
+ );
+ a_ByteBuffer.SkipRead(a_PayloadLength - BytesRead);
+ }
return;
}
else if (a_Channel == "MC|Brand")
diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp
index 72827ac47..21b098735 100644
--- a/src/Protocol/Protocol18x.cpp
+++ b/src/Protocol/Protocol18x.cpp
@@ -2331,6 +2331,16 @@ void cProtocol180::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer)
if (Channel.substr(0, 3) == "MC|")
{
HandleVanillaPluginMessage(a_ByteBuffer, Channel);
+
+ // Skip any unread data (vanilla sometimes sends garbage at the end of a packet; #1692):
+ if (a_ByteBuffer.GetReadableSpace() > 1)
+ {
+ LOGD("Protocol 1.8: Skipping garbage data at the end of a vanilla PluginMessage packet, %u bytes",
+ a_ByteBuffer.GetReadableSpace() - 1
+ );
+ a_ByteBuffer.SkipRead(a_ByteBuffer.GetReadableSpace() - 1);
+ }
+
return;
}
--
cgit v1.2.3
From 7d13a2a77a030a4f458ac01a51f8a4216a4a44b4 Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Sat, 3 Jan 2015 22:39:55 +0100
Subject: Fixed Linux compilation.
---
src/Protocol/Protocol17x.cpp | 2 +-
src/Protocol/Protocol18x.cpp | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp
index 4e985355a..dac1ebde8 100644
--- a/src/Protocol/Protocol17x.cpp
+++ b/src/Protocol/Protocol17x.cpp
@@ -2272,7 +2272,7 @@ void cProtocol172::HandleVanillaPluginMessage(cByteBuffer & a_ByteBuffer, const
if (BytesRead < static_cast(a_PayloadLength))
{
LOGD("Protocol 1.7: Skipping garbage data at the end of a vanilla MC|AdvCdm packet, %u bytes",
- a_PayloadLength - BytesRead
+ static_cast(a_PayloadLength - BytesRead)
);
a_ByteBuffer.SkipRead(a_PayloadLength - BytesRead);
}
diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp
index 21b098735..3c4e049bd 100644
--- a/src/Protocol/Protocol18x.cpp
+++ b/src/Protocol/Protocol18x.cpp
@@ -2336,7 +2336,7 @@ void cProtocol180::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer)
if (a_ByteBuffer.GetReadableSpace() > 1)
{
LOGD("Protocol 1.8: Skipping garbage data at the end of a vanilla PluginMessage packet, %u bytes",
- a_ByteBuffer.GetReadableSpace() - 1
+ static_cast(a_ByteBuffer.GetReadableSpace() - 1)
);
a_ByteBuffer.SkipRead(a_ByteBuffer.GetReadableSpace() - 1);
}
--
cgit v1.2.3
From 52d307e3b01b733e925d51d0367995813bb283b2 Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Fri, 9 Jan 2015 20:38:25 +0100
Subject: CMake: Check libs in submodules before configuring.
This provides an early error message when someone forgets to init / update submodules.
---
CMakeLists.txt | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d4e9d41e8..493cecdb3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -95,6 +95,14 @@ set(SQLITECPP_BUILD_EXAMPLES OFF CACHE BOOL "Build examples."
set(SQLITECPP_BUILD_TESTS OFF CACHE BOOL "Build and run tests." FORCE)
set(SQLITECPP_INTERNAL_SQLITE OFF CACHE BOOL "Add the internal SQLite3 source to the project." FORCE)
+# Check that the libraries are present:
+if (NOT EXISTS ${CMAKE_SOURCE_DIR}/lib/SQLiteCpp/CMakeLists.txt)
+ message(FATAL_ERROR "SQLiteCpp is missing in folder lib/SQLiteCpp. Have you initialized the submodules / downloaded the extra libraries?")
+endif()
+if (NOT EXISTS ${CMAKE_SOURCE_DIR}/lib/polarssl/CMakeLists.txt)
+ message(FATAL_ERROR "PolarSSL is missing in folder lib/polarssl. Have you initialized the submodules / downloaded the extra libraries?")
+endif()
+
# Include all the libraries:
add_subdirectory(lib/jsoncpp/)
add_subdirectory(lib/zlib/)
--
cgit v1.2.3
From 4f75b94c99eeb1642a5ec46144542bfcd18af934 Mon Sep 17 00:00:00 2001
From: Tycho
Date: Sun, 11 Jan 2015 01:54:18 +0000
Subject: Created new type cTickTime and rewrote cWorld::TickThread to use it
---
src/Globals.h | 3 +++
src/World.cpp | 11 +++++------
2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/src/Globals.h b/src/Globals.h
index 61f500db9..b8e9ec7ed 100644
--- a/src/Globals.h
+++ b/src/Globals.h
@@ -419,6 +419,8 @@ std::unique_ptr make_unique(Args&&... args)
return std::unique_ptr(new T(args...));
}
+// a tick is 50 ms
+using cTickTime = std::chrono::duration>>;
#ifndef TOLUA_TEMPLATE_BIND
#define TOLUA_TEMPLATE_BIND(x)
@@ -436,3 +438,4 @@ std::unique_ptr make_unique(Args&&... args)
+
diff --git a/src/World.cpp b/src/World.cpp
index c08b44f77..2dd03497b 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -233,8 +233,7 @@ cWorld::cTickThread::cTickThread(cWorld & a_World) :
void cWorld::cTickThread::Execute(void)
{
auto LastTime = std::chrono::steady_clock::now();
- static const auto msPerTick = std::chrono::milliseconds(50);
- auto TickTime = std::chrono::steady_clock::duration(50);
+ auto TickTime = std::chrono::duration_cast(cTickTime(1));
while (!m_ShouldTerminate)
{
@@ -242,12 +241,12 @@ void cWorld::cTickThread::Execute(void)
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;
+ TickTime = std::chrono::duration_cast(std::chrono::steady_clock::now() - NowTime);
- if (TickTime < msPerTick)
+ if (TickTime < cTickTime(1))
{
- // Stretch tick time until it's at least msPerTick
- std::this_thread::sleep_for(msPerTick - TickTime);
+ // Stretch tick time until it's at least 1 tick
+ std::this_thread::sleep_for(cTickTime(1) - TickTime);
}
LastTime = NowTime;
--
cgit v1.2.3
From 2a9664d6ca8aa9eb4f554301e4d9b0ec33b465ce Mon Sep 17 00:00:00 2001
From: Tycho
Date: Sun, 11 Jan 2015 21:12:26 +0000
Subject: Initial convertion of a_Dt to std::chrono also refactored
cWorld::m_WorldAge and cWorld::m_TimeOfDay
---
src/Bindings/LuaState.cpp | 7 +++
src/Bindings/LuaState.h | 1 +
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/BlockEntities/BeaconEntity.cpp | 2 +-
src/BlockEntities/BeaconEntity.h | 2 +-
src/BlockEntities/BlockEntity.h | 2 +-
src/BlockEntities/CommandBlockEntity.cpp | 2 +-
src/BlockEntities/CommandBlockEntity.h | 2 +-
src/BlockEntities/DropSpenserEntity.cpp | 2 +-
src/BlockEntities/DropSpenserEntity.h | 2 +-
src/BlockEntities/FurnaceEntity.cpp | 2 +-
src/BlockEntities/FurnaceEntity.h | 2 +-
src/BlockEntities/HopperEntity.cpp | 2 +-
src/BlockEntities/HopperEntity.h | 2 +-
src/BlockEntities/MobSpawnerEntity.cpp | 2 +-
src/BlockEntities/MobSpawnerEntity.h | 2 +-
src/Chunk.cpp | 2 +-
src/Chunk.h | 2 +-
src/ChunkMap.cpp | 4 +-
src/ChunkMap.h | 4 +-
src/Entities/ArrowEntity.cpp | 6 +-
src/Entities/ArrowEntity.h | 2 +-
src/Entities/Boat.cpp | 2 +-
src/Entities/Boat.h | 2 +-
src/Entities/EnderCrystal.cpp | 2 +-
src/Entities/EnderCrystal.h | 2 +-
src/Entities/Entity.cpp | 26 ++++-----
src/Entities/Entity.h | 4 +-
src/Entities/ExpOrb.cpp | 4 +-
src/Entities/ExpOrb.h | 2 +-
src/Entities/FallingBlock.cpp | 4 +-
src/Entities/FallingBlock.h | 2 +-
src/Entities/FireworkEntity.cpp | 8 +--
src/Entities/FireworkEntity.h | 4 +-
src/Entities/Floater.cpp | 2 +-
src/Entities/Floater.h | 2 +-
src/Entities/HangingEntity.h | 2 +-
src/Entities/Minecart.cpp | 10 ++--
src/Entities/Minecart.h | 4 +-
src/Entities/Painting.cpp | 2 +-
src/Entities/Painting.h | 2 +-
src/Entities/Pawn.cpp | 2 +-
src/Entities/Pawn.h | 2 +-
src/Entities/Pickup.cpp | 6 +-
src/Entities/Pickup.h | 2 +-
src/Entities/Player.cpp | 2 +-
src/Entities/Player.h | 4 +-
src/Entities/ProjectileEntity.cpp | 4 +-
src/Entities/ProjectileEntity.h | 4 +-
src/Entities/SplashPotionEntity.h | 2 +-
src/Entities/TNTEntity.cpp | 2 +-
src/Entities/TNTEntity.h | 2 +-
src/Entities/ThrownEggEntity.cpp | 2 +-
src/Entities/ThrownEggEntity.h | 2 +-
src/Entities/ThrownEnderPearlEntity.cpp | 2 +-
src/Entities/ThrownEnderPearlEntity.h | 2 +-
src/Entities/ThrownSnowballEntity.cpp | 2 +-
src/Entities/ThrownSnowballEntity.h | 2 +-
src/Globals.h | 1 +
src/Mobs/AggressiveMonster.cpp | 6 +-
src/Mobs/AggressiveMonster.h | 4 +-
src/Mobs/Blaze.cpp | 4 +-
src/Mobs/Blaze.h | 2 +-
src/Mobs/CaveSpider.cpp | 4 +-
src/Mobs/CaveSpider.h | 4 +-
src/Mobs/Chicken.cpp | 2 +-
src/Mobs/Chicken.h | 2 +-
src/Mobs/Creeper.cpp | 4 +-
src/Mobs/Creeper.h | 4 +-
src/Mobs/Enderman.cpp | 2 +-
src/Mobs/Enderman.h | 2 +-
src/Mobs/Ghast.cpp | 4 +-
src/Mobs/Ghast.h | 2 +-
src/Mobs/Guardian.cpp | 2 +-
src/Mobs/Guardian.h | 2 +-
src/Mobs/Horse.cpp | 2 +-
src/Mobs/Horse.h | 2 +-
src/Mobs/Monster.cpp | 12 ++--
src/Mobs/Monster.h | 2 +-
src/Mobs/PassiveMonster.cpp | 2 +-
src/Mobs/PassiveMonster.h | 2 +-
src/Mobs/Pig.cpp | 2 +-
src/Mobs/Pig.h | 2 +-
src/Mobs/Sheep.cpp | 2 +-
src/Mobs/Sheep.h | 2 +-
src/Mobs/Skeleton.cpp | 4 +-
src/Mobs/Skeleton.h | 2 +-
src/Mobs/Slime.cpp | 2 +-
src/Mobs/Slime.h | 2 +-
src/Mobs/SnowGolem.cpp | 2 +-
src/Mobs/SnowGolem.h | 2 +-
src/Mobs/Squid.cpp | 2 +-
src/Mobs/Squid.h | 2 +-
src/Mobs/Villager.cpp | 2 +-
src/Mobs/Villager.h | 2 +-
src/Mobs/Wither.cpp | 2 +-
src/Mobs/Wither.h | 2 +-
src/Mobs/Wolf.cpp | 4 +-
src/Mobs/Wolf.h | 4 +-
src/Simulator/DelayedFluidSimulator.cpp | 2 +-
src/Simulator/DelayedFluidSimulator.h | 2 +-
src/Simulator/FireSimulator.cpp | 4 +-
src/Simulator/FireSimulator.h | 2 +-
src/Simulator/IncrementalRedstoneSimulator.cpp | 2 +-
src/Simulator/IncrementalRedstoneSimulator.h | 2 +-
src/Simulator/NoopRedstoneSimulator.h | 2 +-
src/Simulator/SandSimulator.cpp | 2 +-
src/Simulator/SandSimulator.h | 2 +-
src/Simulator/Simulator.h | 2 +-
src/Simulator/SimulatorManager.cpp | 2 +-
src/Simulator/SimulatorManager.h | 2 +-
src/World.cpp | 79 ++++++++++++--------------
src/World.h | 28 +++++----
117 files changed, 221 insertions(+), 221 deletions(-)
diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp
index 2f5d173fd..4bc9906ee 100644
--- a/src/Bindings/LuaState.cpp
+++ b/src/Bindings/LuaState.cpp
@@ -839,6 +839,13 @@ void cLuaState::Push(void * a_Ptr)
m_NumCurrentFunctionArgs += 1;
}
+void cLuaState::Push(std::chrono::milliseconds a_Value)
+{
+ ASSERT(IsValid());
+
+ tolua_pushnumber(m_LuaState, a_Value.count());
+ m_NumCurrentFunctionArgs += 1;
+}
diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h
index c13e36188..7ac4120e1 100644
--- a/src/Bindings/LuaState.h
+++ b/src/Bindings/LuaState.h
@@ -217,6 +217,7 @@ public:
void Push(Vector3d * a_Vector);
void Push(Vector3i * a_Vector);
void Push(void * a_Ptr);
+ void Push(std::chrono::milliseconds a_time);
/** Retrieve value at a_StackPos, if it is a valid bool. If not, a_Value is unchanged */
void GetStackValue(int a_StackPos, bool & a_Value);
diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h
index b5944e9cb..6210dbed4 100644
--- a/src/Bindings/Plugin.h
+++ b/src/Bindings/Plugin.h
@@ -104,7 +104,7 @@ public:
virtual bool OnWeatherChanged (cWorld & a_World) = 0;
virtual bool OnWeatherChanging (cWorld & a_World, eWeather & a_NewWeather) = 0;
virtual bool OnWorldStarted (cWorld & a_World) = 0;
- virtual bool OnWorldTick (cWorld & a_World, float a_Dt, int a_LastTickDurationMSec) = 0;
+ virtual bool OnWorldTick (cWorld & a_World, std::chrono::milliseconds a_Dt, std::chrono::milliseconds a_LastTickDurationMSec) = 0;
/** Handles the command split into a_Split, issued by player a_Player.
Command permissions have already been checked.
diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp
index cc3146610..500913e76 100644
--- a/src/Bindings/PluginLua.cpp
+++ b/src/Bindings/PluginLua.cpp
@@ -1430,7 +1430,7 @@ bool cPluginLua::OnWorldStarted(cWorld & a_World)
-bool cPluginLua::OnWorldTick(cWorld & a_World, float a_Dt, int a_LastTickDurationMSec)
+bool cPluginLua::OnWorldTick(cWorld & a_World, std::chrono::milliseconds a_Dt, std::chrono::milliseconds a_LastTickDurationMSec)
{
cCSLock Lock(m_CriticalSection);
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_WORLD_TICK];
diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h
index ad3f82b42..f443f5fc0 100644
--- a/src/Bindings/PluginLua.h
+++ b/src/Bindings/PluginLua.h
@@ -128,7 +128,7 @@ public:
virtual bool OnWeatherChanged (cWorld & a_World) override;
virtual bool OnWeatherChanging (cWorld & a_World, eWeather & a_NewWeather) override;
virtual bool OnWorldStarted (cWorld & a_World) override;
- virtual bool OnWorldTick (cWorld & a_World, float a_Dt, int a_LastTickDurationMSec) override;
+ virtual bool OnWorldTick (cWorld & a_World, std::chrono::milliseconds a_Dt, std::chrono::milliseconds a_LastTickDurationMSec) override;
virtual bool HandleCommand(const AStringVector & a_Split, cPlayer & a_Player) override;
diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp
index fad0a36d2..58faf54d3 100644
--- a/src/Bindings/PluginManager.cpp
+++ b/src/Bindings/PluginManager.cpp
@@ -1394,7 +1394,7 @@ bool cPluginManager::CallHookWorldStarted(cWorld & a_World)
-bool cPluginManager::CallHookWorldTick(cWorld & a_World, float a_Dt, int a_LastTickDurationMSec)
+bool cPluginManager::CallHookWorldTick(cWorld & a_World, std::chrono::milliseconds a_Dt, std::chrono::milliseconds a_LastTickDurationMSec)
{
FIND_HOOK(HOOK_WORLD_TICK);
VERIFY_HOOK;
diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h
index d4b82376a..7b35e92c4 100644
--- a/src/Bindings/PluginManager.h
+++ b/src/Bindings/PluginManager.h
@@ -237,7 +237,7 @@ public:
bool CallHookWeatherChanged (cWorld & a_World);
bool CallHookWeatherChanging (cWorld & a_World, eWeather & a_NewWeather);
bool CallHookWorldStarted (cWorld & a_World);
- bool CallHookWorldTick (cWorld & a_World, float a_Dt, int a_LastTickDurationMSec);
+ bool CallHookWorldTick (cWorld & a_World, std::chrono::milliseconds a_Dt, std::chrono::milliseconds a_LastTickDurationMSec);
bool DisablePlugin(const AString & a_PluginName); // tolua_export
bool LoadPlugin (const AString & a_PluginName); // tolua_export
diff --git a/src/BlockEntities/BeaconEntity.cpp b/src/BlockEntities/BeaconEntity.cpp
index 409f2937c..37ce7a8ab 100644
--- a/src/BlockEntities/BeaconEntity.cpp
+++ b/src/BlockEntities/BeaconEntity.cpp
@@ -266,7 +266,7 @@ void cBeaconEntity::GiveEffects(void)
-bool cBeaconEntity::Tick(float a_Dt, cChunk & a_Chunk)
+bool cBeaconEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
// Update the beacon every 4 seconds
if ((GetWorld()->GetWorldAge() % 80) == 0)
diff --git a/src/BlockEntities/BeaconEntity.h b/src/BlockEntities/BeaconEntity.h
index bc27e92b0..4f723c617 100644
--- a/src/BlockEntities/BeaconEntity.h
+++ b/src/BlockEntities/BeaconEntity.h
@@ -30,7 +30,7 @@ public:
// cBlockEntity overrides:
virtual void SendTo(cClientHandle & a_Client) override;
- virtual bool Tick(float a_Dt, cChunk & a_Chunk) override;
+ virtual bool Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
virtual void UsedBy(cPlayer * a_Player) override;
/** Modify the beacon level. (It is needed to load the beacon corectly) */
diff --git a/src/BlockEntities/BlockEntity.h b/src/BlockEntities/BlockEntity.h
index 056a88721..85f75a523 100644
--- a/src/BlockEntities/BlockEntity.h
+++ b/src/BlockEntities/BlockEntity.h
@@ -110,7 +110,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(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
UNUSED(a_Dt);
return false;
diff --git a/src/BlockEntities/CommandBlockEntity.cpp b/src/BlockEntities/CommandBlockEntity.cpp
index b7f938ffd..13c2637dc 100644
--- a/src/BlockEntities/CommandBlockEntity.cpp
+++ b/src/BlockEntities/CommandBlockEntity.cpp
@@ -125,7 +125,7 @@ void cCommandBlockEntity::SetRedstonePower(bool a_IsPowered)
-bool cCommandBlockEntity::Tick(float a_Dt, cChunk & a_Chunk)
+bool cCommandBlockEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
UNUSED(a_Dt);
UNUSED(a_Chunk);
diff --git a/src/BlockEntities/CommandBlockEntity.h b/src/BlockEntities/CommandBlockEntity.h
index d8ac054f0..c525ebc26 100644
--- a/src/BlockEntities/CommandBlockEntity.h
+++ b/src/BlockEntities/CommandBlockEntity.h
@@ -33,7 +33,7 @@ public:
/// Creates a new empty command block entity
cCommandBlockEntity(int a_X, int a_Y, int a_Z, cWorld * a_World);
- virtual bool Tick(float a_Dt, cChunk & a_Chunk) override;
+ virtual bool Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
virtual void SendTo(cClientHandle & a_Client) override;
virtual void UsedBy(cPlayer * a_Player) override;
diff --git a/src/BlockEntities/DropSpenserEntity.cpp b/src/BlockEntities/DropSpenserEntity.cpp
index 3f98836e7..5e98506f1 100644
--- a/src/BlockEntities/DropSpenserEntity.cpp
+++ b/src/BlockEntities/DropSpenserEntity.cpp
@@ -125,7 +125,7 @@ void cDropSpenserEntity::SetRedstonePower(bool a_IsPowered)
-bool cDropSpenserEntity::Tick(float a_Dt, cChunk & a_Chunk)
+bool cDropSpenserEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
UNUSED(a_Dt);
if (!m_ShouldDropSpense)
diff --git a/src/BlockEntities/DropSpenserEntity.h b/src/BlockEntities/DropSpenserEntity.h
index 6c23a402f..83500addb 100644
--- a/src/BlockEntities/DropSpenserEntity.h
+++ b/src/BlockEntities/DropSpenserEntity.h
@@ -47,7 +47,7 @@ public:
virtual ~cDropSpenserEntity();
// cBlockEntity overrides:
- virtual bool Tick(float a_Dt, cChunk & a_Chunk) override;
+ virtual bool Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
virtual void SendTo(cClientHandle & a_Client) override;
virtual void UsedBy(cPlayer * a_Player) override;
diff --git a/src/BlockEntities/FurnaceEntity.cpp b/src/BlockEntities/FurnaceEntity.cpp
index d2ec2bd1e..cc5a00af7 100644
--- a/src/BlockEntities/FurnaceEntity.cpp
+++ b/src/BlockEntities/FurnaceEntity.cpp
@@ -90,7 +90,7 @@ bool cFurnaceEntity::ContinueCooking(void)
-bool cFurnaceEntity::Tick(float a_Dt, cChunk & a_Chunk)
+bool cFurnaceEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
UNUSED(a_Dt);
diff --git a/src/BlockEntities/FurnaceEntity.h b/src/BlockEntities/FurnaceEntity.h
index fbe9d6c75..8b3ba3e36 100644
--- a/src/BlockEntities/FurnaceEntity.h
+++ b/src/BlockEntities/FurnaceEntity.h
@@ -42,7 +42,7 @@ public:
// cBlockEntity overrides:
virtual void SendTo(cClientHandle & a_Client) override;
- virtual bool Tick(float a_Dt, cChunk & a_Chunk) override;
+ virtual bool Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
virtual void UsedBy(cPlayer * a_Player) override;
virtual void Destroy() override
{
diff --git a/src/BlockEntities/HopperEntity.cpp b/src/BlockEntities/HopperEntity.cpp
index fe3fb85c4..c2d6cabbb 100644
--- a/src/BlockEntities/HopperEntity.cpp
+++ b/src/BlockEntities/HopperEntity.cpp
@@ -54,7 +54,7 @@ bool cHopperEntity::GetOutputBlockPos(NIBBLETYPE a_BlockMeta, int & a_OutputX, i
-bool cHopperEntity::Tick(float a_Dt, cChunk & a_Chunk)
+bool cHopperEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
UNUSED(a_Dt);
Int64 CurrentTick = a_Chunk.GetWorld()->GetWorldAge();
diff --git a/src/BlockEntities/HopperEntity.h b/src/BlockEntities/HopperEntity.h
index da65aa671..af99c526d 100644
--- a/src/BlockEntities/HopperEntity.h
+++ b/src/BlockEntities/HopperEntity.h
@@ -48,7 +48,7 @@ protected:
Int64 m_LastMoveItemsOutTick;
// cBlockEntity overrides:
- virtual bool Tick(float a_Dt, cChunk & a_Chunk) override;
+ virtual bool Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
virtual void SendTo(cClientHandle & a_Client) override;
virtual void UsedBy(cPlayer * a_Player) override;
diff --git a/src/BlockEntities/MobSpawnerEntity.cpp b/src/BlockEntities/MobSpawnerEntity.cpp
index a7d29638a..9b3f605f9 100644
--- a/src/BlockEntities/MobSpawnerEntity.cpp
+++ b/src/BlockEntities/MobSpawnerEntity.cpp
@@ -73,7 +73,7 @@ void cMobSpawnerEntity::UpdateActiveState(void)
-bool cMobSpawnerEntity::Tick(float a_Dt, cChunk & a_Chunk)
+bool cMobSpawnerEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
// Update the active flag every 5 seconds
if ((m_World->GetWorldAge() % 100) == 0)
diff --git a/src/BlockEntities/MobSpawnerEntity.h b/src/BlockEntities/MobSpawnerEntity.h
index 594b5301e..b572e6657 100644
--- a/src/BlockEntities/MobSpawnerEntity.h
+++ b/src/BlockEntities/MobSpawnerEntity.h
@@ -29,7 +29,7 @@ public:
virtual void SendTo(cClientHandle & a_Client) override;
virtual void UsedBy(cPlayer * a_Player) override;
- virtual bool Tick(float a_Dt, cChunk & a_Chunk) override;
+ virtual bool Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
// tolua_begin
diff --git a/src/Chunk.cpp b/src/Chunk.cpp
index b06eed316..979492b46 100644
--- a/src/Chunk.cpp
+++ b/src/Chunk.cpp
@@ -601,7 +601,7 @@ void cChunk::SpawnMobs(cMobSpawner& a_MobSpawner)
-void cChunk::Tick(float a_Dt)
+void cChunk::Tick(std::chrono::milliseconds a_Dt)
{
BroadcastPendingBlockChanges();
diff --git a/src/Chunk.h b/src/Chunk.h
index 6f4ac5cac..1ce862371 100644
--- a/src/Chunk.h
+++ b/src/Chunk.h
@@ -160,7 +160,7 @@ public:
/** Try to Spawn Monsters inside chunk */
void SpawnMobs(cMobSpawner& a_MobSpawner);
- void Tick(float a_Dt);
+ void Tick(std::chrono::milliseconds a_Dt);
/** Ticks a single block. Used by cWorld::TickQueuedBlocks() to tick the queued blocks */
void TickBlock(int a_RelX, int a_RelY, int a_RelZ);
diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp
index c8f5aa673..2dd04f801 100644
--- a/src/ChunkMap.cpp
+++ b/src/ChunkMap.cpp
@@ -2720,7 +2720,7 @@ void cChunkMap::SpawnMobs(cMobSpawner& a_MobSpawner)
-void cChunkMap::Tick(float a_Dt)
+void cChunkMap::Tick(std::chrono::milliseconds a_Dt)
{
cCSLock Lock(m_CSLayers);
for (cChunkLayerList::iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr)
@@ -2948,7 +2948,7 @@ void cChunkMap::cChunkLayer::SpawnMobs(cMobSpawner& a_MobSpawner)
-void cChunkMap::cChunkLayer::Tick(float a_Dt)
+void cChunkMap::cChunkLayer::Tick(std::chrono::milliseconds a_Dt)
{
for (size_t i = 0; i < ARRAYCOUNT(m_Chunks); i++)
{
diff --git a/src/ChunkMap.h b/src/ChunkMap.h
index fe0bb3733..f08d02337 100644
--- a/src/ChunkMap.h
+++ b/src/ChunkMap.h
@@ -348,7 +348,7 @@ public:
/** Try to Spawn Monsters inside all Chunks */
void SpawnMobs(cMobSpawner& a_MobSpawner);
- void Tick(float a_Dt);
+ void Tick(std::chrono::milliseconds a_Dt);
/** Ticks a single block. Used by cWorld::TickQueuedBlocks() to tick the queued blocks */
void TickBlock(int a_BlockX, int a_BlockY, int a_BlockZ);
@@ -415,7 +415,7 @@ private:
/** Try to Spawn Monsters inside all Chunks */
void SpawnMobs(cMobSpawner& a_MobSpawner);
- void Tick(float a_Dt);
+ void Tick(std::chrono::milliseconds a_Dt);
void RemoveClient(cClientHandle * a_Client);
diff --git a/src/Entities/ArrowEntity.cpp b/src/Entities/ArrowEntity.cpp
index 30f18f677..2ec825ddb 100644
--- a/src/Entities/ArrowEntity.cpp
+++ b/src/Entities/ArrowEntity.cpp
@@ -174,10 +174,10 @@ void cArrowEntity::CollectedBy(cPlayer & a_Dest)
-void cArrowEntity::Tick(float a_Dt, cChunk & a_Chunk)
+void cArrowEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
super::Tick(a_Dt, a_Chunk);
- m_Timer += a_Dt;
+ m_Timer += a_Dt.count();
if (m_bIsCollected)
{
@@ -209,7 +209,7 @@ void cArrowEntity::Tick(float a_Dt, cChunk & a_Chunk)
}
else
{
- m_HitGroundTimer += a_Dt;
+ m_HitGroundTimer += a_Dt.count();
}
}
diff --git a/src/Entities/ArrowEntity.h b/src/Entities/ArrowEntity.h
index 436ec0293..8c92049b0 100644
--- a/src/Entities/ArrowEntity.h
+++ b/src/Entities/ArrowEntity.h
@@ -103,6 +103,6 @@ protected:
virtual void OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) override;
virtual void OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) override;
virtual void CollectedBy(cPlayer & a_Player) override;
- virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
+ virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
}; // tolua_export
diff --git a/src/Entities/Boat.cpp b/src/Entities/Boat.cpp
index 953213bca..6d8b4ef31 100644
--- a/src/Entities/Boat.cpp
+++ b/src/Entities/Boat.cpp
@@ -91,7 +91,7 @@ void cBoat::OnRightClicked(cPlayer & a_Player)
-void cBoat::Tick(float a_Dt, cChunk & a_Chunk)
+void cBoat::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
super::Tick(a_Dt, a_Chunk);
BroadcastMovementUpdate();
diff --git a/src/Entities/Boat.h b/src/Entities/Boat.h
index 8de88d165..a873ff822 100644
--- a/src/Entities/Boat.h
+++ b/src/Entities/Boat.h
@@ -27,7 +27,7 @@ public:
virtual void SpawnOn(cClientHandle & a_ClientHandle) override;
virtual void OnRightClicked(cPlayer & a_Player) override;
virtual bool DoTakeDamage(TakeDamageInfo & TDI) override;
- virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
+ virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
virtual void HandleSpeedFromAttachee(float a_Forward, float a_Sideways) override;
cBoat(double a_X, double a_Y, double a_Z);
diff --git a/src/Entities/EnderCrystal.cpp b/src/Entities/EnderCrystal.cpp
index 30df2c110..7a911d4db 100644
--- a/src/Entities/EnderCrystal.cpp
+++ b/src/Entities/EnderCrystal.cpp
@@ -29,7 +29,7 @@ void cEnderCrystal::SpawnOn(cClientHandle & a_ClientHandle)
-void cEnderCrystal::Tick(float a_Dt, cChunk & a_Chunk)
+void cEnderCrystal::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
UNUSED(a_Dt);
// No further processing (physics e.t.c.) is needed
diff --git a/src/Entities/EnderCrystal.h b/src/Entities/EnderCrystal.h
index c98c3b681..8f7e2e9b9 100644
--- a/src/Entities/EnderCrystal.h
+++ b/src/Entities/EnderCrystal.h
@@ -23,7 +23,7 @@ private:
// cEntity overrides:
virtual void SpawnOn(cClientHandle & a_ClientHandle) override;
- virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
+ virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
virtual void KilledBy(TakeDamageInfo & a_TDI) override;
}; // tolua_export
diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp
index 54b9f2a20..c64d94528 100644
--- a/src/Entities/Entity.cpp
+++ b/src/Entities/Entity.cpp
@@ -772,7 +772,7 @@ void cEntity::SetHealth(int a_Health)
-void cEntity::Tick(float a_Dt, cChunk & a_Chunk)
+void cEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
m_TicksAlive++;
@@ -841,7 +841,7 @@ void cEntity::Tick(float a_Dt, cChunk & a_Chunk)
-void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
+void cEntity::HandlePhysics(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
int BlockX = POSX_TOINT;
int BlockY = POSY_TOINT;
@@ -851,15 +851,15 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
GET_AND_VERIFY_CURRENT_CHUNK(NextChunk, BlockX, BlockZ)
// TODO Add collision detection with entities.
- a_Dt /= 1000; // Convert from msec to sec
+ auto DtSec = std::chrono::duration_cast>(a_Dt);
Vector3d NextPos = Vector3d(GetPosX(), GetPosY(), GetPosZ());
Vector3d NextSpeed = Vector3d(GetSpeedX(), GetSpeedY(), GetSpeedZ());
if ((BlockY >= cChunkDef::Height) || (BlockY < 0))
{
// Outside of the world
- AddSpeedY(m_Gravity * a_Dt);
- AddPosition(GetSpeed() * a_Dt);
+ AddSpeedY(m_Gravity * DtSec.count());
+ AddPosition(GetSpeed() * DtSec.count());
return;
}
@@ -930,8 +930,8 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
float fallspeed;
if (IsBlockWater(BlockIn))
{
- fallspeed = m_Gravity * a_Dt / 3; // Fall 3x slower in water
- ApplyFriction(NextSpeed, 0.7, a_Dt);
+ fallspeed = m_Gravity * DtSec.count() / 3; // Fall 3x slower in water
+ ApplyFriction(NextSpeed, 0.7, DtSec.count());
}
else if (BlockIn == E_BLOCK_COBWEB)
{
@@ -941,13 +941,13 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
else
{
// Normal gravity
- fallspeed = m_Gravity * a_Dt;
+ fallspeed = m_Gravity * DtSec.count();
}
NextSpeed.y += fallspeed;
}
else
{
- ApplyFriction(NextSpeed, 0.7, a_Dt);
+ ApplyFriction(NextSpeed, 0.7, DtSec.count());
}
// Adjust X and Z speed for COBWEB temporary. This speed modification should be handled inside block handlers since we
@@ -1002,14 +1002,14 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
{
cTracer Tracer(GetWorld());
// Distance traced is an integer, so we round up from the distance we should go (Speed * Delta), else we will encounter collision detection failurse
- int DistanceToTrace = (int)(ceil((NextSpeed * a_Dt).SqrLength()) * 2);
+ int DistanceToTrace = (int)(ceil((NextSpeed * DtSec.count()).SqrLength()) * 2);
bool HasHit = Tracer.Trace(NextPos, NextSpeed, DistanceToTrace);
if (HasHit)
{
// Oh noez! We hit something: verify that the (hit position - current) was smaller or equal to the (position that we should travel without obstacles - current)
// This is because previously, we traced with a length that was rounded up (due to integer limitations), and in the case that something was hit, we don't want to overshoot our projected movement
- if ((Tracer.RealHit - NextPos).SqrLength() <= (NextSpeed * a_Dt).SqrLength())
+ if ((Tracer.RealHit - NextPos).SqrLength() <= (NextSpeed * DtSec.count()).SqrLength())
{
// 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.
@@ -1044,13 +1044,13 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
// and that this piece of software will come to be hailed as the epitome of performance and functionality in C++, never before seen, and of such a like that will never
// be henceforth seen again in the time of programmers and man alike
// &sensationalist>
- NextPos += (NextSpeed * a_Dt);
+ NextPos += (NextSpeed * DtSec.count());
}
}
else
{
// We didn't hit anything, so move =]
- NextPos += (NextSpeed * a_Dt);
+ NextPos += (NextSpeed * DtSec.count());
}
}
diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h
index af545fe4a..de9b88dfb 100644
--- a/src/Entities/Entity.h
+++ b/src/Entities/Entity.h
@@ -326,10 +326,10 @@ public:
// tolua_end
- virtual void Tick(float a_Dt, cChunk & a_Chunk);
+ virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk);
/// Handles the physics of the entity - updates position based on speed, updates speed based on environment
- virtual void HandlePhysics(float a_Dt, cChunk & a_Chunk);
+ virtual void HandlePhysics(std::chrono::milliseconds a_Dt, cChunk & a_Chunk);
/// Updates the state related to this entity being on fire
virtual void TickBurning(cChunk & a_Chunk);
diff --git a/src/Entities/ExpOrb.cpp b/src/Entities/ExpOrb.cpp
index 751308661..9767f96ca 100644
--- a/src/Entities/ExpOrb.cpp
+++ b/src/Entities/ExpOrb.cpp
@@ -42,7 +42,7 @@ void cExpOrb::SpawnOn(cClientHandle & a_Client)
-void cExpOrb::Tick(float a_Dt, cChunk & a_Chunk)
+void cExpOrb::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
cPlayer * a_ClosestPlayer(m_World->FindClosestPlayer(Vector3f(GetPosition()), 5));
if (a_ClosestPlayer != nullptr)
@@ -69,7 +69,7 @@ void cExpOrb::Tick(float a_Dt, cChunk & a_Chunk)
}
HandlePhysics(a_Dt, a_Chunk);
- m_Timer += a_Dt;
+ m_Timer += a_Dt.count();
if (m_Timer >= 1000 * 60 * 5) // 5 minutes
{
Destroy(true);
diff --git a/src/Entities/ExpOrb.h b/src/Entities/ExpOrb.h
index bdb9a5b19..e12e3c504 100644
--- a/src/Entities/ExpOrb.h
+++ b/src/Entities/ExpOrb.h
@@ -22,7 +22,7 @@ public:
cExpOrb(const Vector3d & a_Pos, int a_Reward);
// Override functions
- virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
+ virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
virtual void SpawnOn(cClientHandle & a_Client) override;
/** Returns the number of ticks that this entity has existed */
diff --git a/src/Entities/FallingBlock.cpp b/src/Entities/FallingBlock.cpp
index 111c5fa84..75105a0cd 100644
--- a/src/Entities/FallingBlock.cpp
+++ b/src/Entities/FallingBlock.cpp
@@ -31,7 +31,7 @@ void cFallingBlock::SpawnOn(cClientHandle & a_ClientHandle)
-void cFallingBlock::Tick(float a_Dt, cChunk & a_Chunk)
+void cFallingBlock::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
// GetWorld()->BroadcastTeleportEntity(*this); // Test position
@@ -82,7 +82,7 @@ void cFallingBlock::Tick(float a_Dt, cChunk & a_Chunk)
return;
}
- float MilliDt = a_Dt * 0.001f;
+ float MilliDt = a_Dt.count() * 0.001f;
AddSpeedY(MilliDt * -9.8f);
AddPosition(GetSpeed() * MilliDt);
diff --git a/src/Entities/FallingBlock.h b/src/Entities/FallingBlock.h
index c20fe8eb9..884938f4d 100644
--- a/src/Entities/FallingBlock.h
+++ b/src/Entities/FallingBlock.h
@@ -30,7 +30,7 @@ public:
// cEntity overrides:
virtual void SpawnOn(cClientHandle & a_ClientHandle) override;
- virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
+ virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
private:
BLOCKTYPE m_BlockType;
diff --git a/src/Entities/FireworkEntity.cpp b/src/Entities/FireworkEntity.cpp
index 68d02640a..9dc7850a7 100644
--- a/src/Entities/FireworkEntity.cpp
+++ b/src/Entities/FireworkEntity.cpp
@@ -19,7 +19,7 @@ cFireworkEntity::cFireworkEntity(cEntity * a_Creator, double a_X, double a_Y, do
-void cFireworkEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
+void cFireworkEntity::HandlePhysics(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
int RelX = POSX_TOINT - a_Chunk.GetPosX() * cChunkDef::Width;
int RelZ = POSZ_TOINT - a_Chunk.GetPosZ() * cChunkDef::Width;
@@ -28,7 +28,7 @@ void cFireworkEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
if ((PosY < 0) || (PosY >= cChunkDef::Height))
{
AddSpeedY(1);
- AddPosition(GetSpeed() * (a_Dt / 1000));
+ AddPosition(GetSpeed() * (a_Dt.count() / 1000));
return;
}
@@ -53,14 +53,14 @@ void cFireworkEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
}
AddSpeedY(1);
- AddPosition(GetSpeed() * (a_Dt / 1000));
+ AddPosition(GetSpeed() * (a_Dt.count() / 1000));
}
-void cFireworkEntity::Tick(float a_Dt, cChunk & a_Chunk)
+void cFireworkEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
super::Tick(a_Dt, a_Chunk);
diff --git a/src/Entities/FireworkEntity.h b/src/Entities/FireworkEntity.h
index 300ec571e..c0a38a943 100644
--- a/src/Entities/FireworkEntity.h
+++ b/src/Entities/FireworkEntity.h
@@ -49,8 +49,8 @@ public:
protected:
// cProjectileEntity overrides:
- virtual void HandlePhysics(float a_Dt, cChunk & a_Chunk) override;
- virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
+ virtual void HandlePhysics(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
+ virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
private:
diff --git a/src/Entities/Floater.cpp b/src/Entities/Floater.cpp
index 5fe6a1238..cf8dd6c6f 100644
--- a/src/Entities/Floater.cpp
+++ b/src/Entities/Floater.cpp
@@ -125,7 +125,7 @@ void cFloater::SpawnOn(cClientHandle & a_Client)
-void cFloater::Tick(float a_Dt, cChunk & a_Chunk)
+void cFloater::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
HandlePhysics(a_Dt, a_Chunk);
if (IsBlockWater(m_World->GetBlock((int) GetPosX(), (int) GetPosY(), (int) GetPosZ())) && m_World->GetBlockMeta((int) GetPosX(), (int) GetPosY(), (int) GetPosZ()) == 0)
diff --git a/src/Entities/Floater.h b/src/Entities/Floater.h
index 96d77ac82..d5715f89e 100644
--- a/src/Entities/Floater.h
+++ b/src/Entities/Floater.h
@@ -21,7 +21,7 @@ public:
cFloater(double a_X, double a_Y, double a_Z, Vector3d a_Speed, int a_PlayerID, int a_CountDownTime);
virtual void SpawnOn(cClientHandle & a_Client) override;
- virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
+ virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
// tolua_begin
bool CanPickup(void) const { return m_CanPickupItem; }
diff --git a/src/Entities/HangingEntity.h b/src/Entities/HangingEntity.h
index 67146a20b..d1ef79a68 100644
--- a/src/Entities/HangingEntity.h
+++ b/src/Entities/HangingEntity.h
@@ -43,7 +43,7 @@ public:
private:
virtual void SpawnOn(cClientHandle & a_ClientHandle) override;
- virtual void Tick(float a_Dt, cChunk & a_Chunk) override {}
+ virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override {}
eBlockFace m_Facing;
diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp
index fac4f0714..552d70de7 100644
--- a/src/Entities/Minecart.cpp
+++ b/src/Entities/Minecart.cpp
@@ -111,7 +111,7 @@ void cMinecart::SpawnOn(cClientHandle & a_ClientHandle)
-void cMinecart::HandlePhysics(float a_Dt, cChunk & a_Chunk)
+void cMinecart::HandlePhysics(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
if (IsDestroyed()) // Mainly to stop detector rails triggering again after minecart is dead
{
@@ -165,19 +165,19 @@ void cMinecart::HandlePhysics(float a_Dt, cChunk & a_Chunk)
switch (InsideType)
{
- case E_BLOCK_RAIL: HandleRailPhysics(InsideMeta, a_Dt); break;
+ case E_BLOCK_RAIL: HandleRailPhysics(InsideMeta, a_Dt.count()); break;
case E_BLOCK_ACTIVATOR_RAIL: break;
case E_BLOCK_POWERED_RAIL: HandlePoweredRailPhysics(InsideMeta); break;
case E_BLOCK_DETECTOR_RAIL:
{
- HandleDetectorRailPhysics(InsideMeta, a_Dt);
+ HandleDetectorRailPhysics(InsideMeta, a_Dt.count());
WasDetectorRail = true;
break;
}
default: VERIFY(!"Unhandled rail type despite checking if block was rail!"); break;
}
- AddPosition(GetSpeed() * (a_Dt / 1000)); // Commit changes; as we use our own engine when on rails, this needs to be done, whereas it is normally in Entity.cpp
+ AddPosition(GetSpeed() * (a_Dt.count() / 1000)); // Commit changes; as we use our own engine when on rails, this needs to be done, whereas it is normally in Entity.cpp
}
else
{
@@ -1213,7 +1213,7 @@ void cMinecartWithFurnace::OnRightClicked(cPlayer & a_Player)
-void cMinecartWithFurnace::Tick(float a_Dt, cChunk & a_Chunk)
+void cMinecartWithFurnace::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
super::Tick(a_Dt, a_Chunk);
diff --git a/src/Entities/Minecart.h b/src/Entities/Minecart.h
index f7d0d5dda..1c6f4a6c4 100644
--- a/src/Entities/Minecart.h
+++ b/src/Entities/Minecart.h
@@ -38,7 +38,7 @@ public:
// cEntity overrides:
virtual void SpawnOn(cClientHandle & a_ClientHandle) override;
- virtual void HandlePhysics(float a_Dt, cChunk & a_Chunk) override;
+ virtual void HandlePhysics(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
virtual bool DoTakeDamage(TakeDamageInfo & TDI) override;
virtual void Destroyed() override;
@@ -171,7 +171,7 @@ public:
// cEntity overrides:
virtual void OnRightClicked(cPlayer & a_Player) override;
- virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
+ virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
// Set functions.
void SetIsFueled(bool a_IsFueled, int a_FueledTimeLeft = -1) {m_IsFueled = a_IsFueled; m_FueledTimeLeft = a_FueledTimeLeft;}
diff --git a/src/Entities/Painting.cpp b/src/Entities/Painting.cpp
index 1aa6da0a1..6f6277f28 100644
--- a/src/Entities/Painting.cpp
+++ b/src/Entities/Painting.cpp
@@ -31,7 +31,7 @@ void cPainting::SpawnOn(cClientHandle & a_Client)
-void cPainting::Tick(float a_Dt, cChunk & a_Chunk)
+void cPainting::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
UNUSED(a_Dt);
UNUSED(a_Chunk);
diff --git a/src/Entities/Painting.h b/src/Entities/Painting.h
index 078270b42..6e8a382fc 100644
--- a/src/Entities/Painting.h
+++ b/src/Entities/Painting.h
@@ -31,7 +31,7 @@ public:
private:
virtual void SpawnOn(cClientHandle & a_Client) override;
- virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
+ virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
virtual void GetDrops(cItems & a_Items, cEntity * a_Killer) override;
virtual void KilledBy(TakeDamageInfo & a_TDI) override
{
diff --git a/src/Entities/Pawn.cpp b/src/Entities/Pawn.cpp
index fc8ca3d47..baf8a2f3b 100644
--- a/src/Entities/Pawn.cpp
+++ b/src/Entities/Pawn.cpp
@@ -19,7 +19,7 @@ cPawn::cPawn(eEntityType a_EntityType, double a_Width, double a_Height) :
-void cPawn::Tick(float a_Dt, cChunk & a_Chunk)
+void cPawn::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
// Iterate through this entity's applied effects
for (tEffectMap::iterator iter = m_EntityEffects.begin(); iter != m_EntityEffects.end();)
diff --git a/src/Entities/Pawn.h b/src/Entities/Pawn.h
index d50bcd8af..e3e99651d 100644
--- a/src/Entities/Pawn.h
+++ b/src/Entities/Pawn.h
@@ -20,7 +20,7 @@ public:
cPawn(eEntityType a_EntityType, double a_Width, double a_Height);
- virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
+ virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
virtual void KilledBy(TakeDamageInfo & a_TDI) override;
// tolua_begin
diff --git a/src/Entities/Pickup.cpp b/src/Entities/Pickup.cpp
index e5e28446d..accb42a63 100644
--- a/src/Entities/Pickup.cpp
+++ b/src/Entities/Pickup.cpp
@@ -110,12 +110,12 @@ void cPickup::SpawnOn(cClientHandle & a_Client)
-void cPickup::Tick(float a_Dt, cChunk & a_Chunk)
+void cPickup::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
super::Tick(a_Dt, a_Chunk);
BroadcastMovementUpdate(); // Notify clients of position
- m_Timer += a_Dt;
+ m_Timer += a_Dt.count();
if (!m_bCollected)
{
@@ -142,7 +142,7 @@ void cPickup::Tick(float a_Dt, cChunk & a_Chunk)
{
m_bCollected = true;
m_Timer = 0; // We have to reset the timer.
- m_Timer += a_Dt; // In case we have to destroy the pickup in the same tick.
+ m_Timer += a_Dt.count(); // In case we have to destroy the pickup in the same tick.
if (m_Timer > 500.f)
{
Destroy(true);
diff --git a/src/Entities/Pickup.h b/src/Entities/Pickup.h
index d1176a7cf..67f2756ca 100644
--- a/src/Entities/Pickup.h
+++ b/src/Entities/Pickup.h
@@ -34,7 +34,7 @@ public:
bool CollectedBy(cPlayer & a_Dest); // tolua_export
- virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
+ virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
/** Returns the number of ticks that this entity has existed */
int GetAge(void) const { return static_cast(m_Timer / 50); } // tolua_export
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index 1d5cc6554..1ca131375 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -191,7 +191,7 @@ void cPlayer::SpawnOn(cClientHandle & a_Client)
-void cPlayer::Tick(float a_Dt, cChunk & a_Chunk)
+void cPlayer::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
if (m_ClientHandle != nullptr)
{
diff --git a/src/Entities/Player.h b/src/Entities/Player.h
index b94d2659e..d3ed46db6 100644
--- a/src/Entities/Player.h
+++ b/src/Entities/Player.h
@@ -46,9 +46,9 @@ public:
virtual void SpawnOn(cClientHandle & a_Client) override;
- virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
+ virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
- virtual void HandlePhysics(float a_Dt, cChunk &) override { UNUSED(a_Dt); }
+ virtual void HandlePhysics(std::chrono::milliseconds a_Dt, cChunk &) override { UNUSED(a_Dt); }
/** Returns the curently equipped weapon; empty item if none */
virtual cItem GetEquippedWeapon(void) const override { return m_Inventory.GetEquippedItem(); }
diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp
index 1768714f8..4f20bfae6 100644
--- a/src/Entities/ProjectileEntity.cpp
+++ b/src/Entities/ProjectileEntity.cpp
@@ -331,7 +331,7 @@ AString cProjectileEntity::GetMCAClassName(void) const
-void cProjectileEntity::Tick(float a_Dt, cChunk & a_Chunk)
+void cProjectileEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
super::Tick(a_Dt, a_Chunk);
@@ -346,7 +346,7 @@ void cProjectileEntity::Tick(float a_Dt, cChunk & a_Chunk)
-void cProjectileEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
+void cProjectileEntity::HandlePhysics(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
if (m_IsInGround)
{
diff --git a/src/Entities/ProjectileEntity.h b/src/Entities/ProjectileEntity.h
index 2a98e31c7..93e442d8c 100644
--- a/src/Entities/ProjectileEntity.h
+++ b/src/Entities/ProjectileEntity.h
@@ -118,8 +118,8 @@ protected:
bool m_IsInGround;
// cEntity overrides:
- virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
- virtual void HandlePhysics(float a_Dt, cChunk & a_Chunk) override;
+ virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
+ virtual void HandlePhysics(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
virtual void SpawnOn(cClientHandle & a_Client) override;
} ; // tolua_export
diff --git a/src/Entities/SplashPotionEntity.h b/src/Entities/SplashPotionEntity.h
index 9302d8292..264dc0eb9 100644
--- a/src/Entities/SplashPotionEntity.h
+++ b/src/Entities/SplashPotionEntity.h
@@ -58,7 +58,7 @@ protected:
// cProjectileEntity overrides:
virtual void OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) override;
virtual void OnHitEntity (cEntity & a_EntityHit, const Vector3d & a_HitPos) override;
- virtual void Tick (float a_Dt, cChunk & a_Chunk) override
+ virtual void Tick (std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override
{
if (m_DestroyTimer > 0)
{
diff --git a/src/Entities/TNTEntity.cpp b/src/Entities/TNTEntity.cpp
index 53af446cc..a89d2f300 100644
--- a/src/Entities/TNTEntity.cpp
+++ b/src/Entities/TNTEntity.cpp
@@ -50,7 +50,7 @@ void cTNTEntity::Explode(void)
-void cTNTEntity::Tick(float a_Dt, cChunk & a_Chunk)
+void cTNTEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
super::Tick(a_Dt, a_Chunk);
BroadcastMovementUpdate();
diff --git a/src/Entities/TNTEntity.h b/src/Entities/TNTEntity.h
index 48503cf76..9f894338e 100644
--- a/src/Entities/TNTEntity.h
+++ b/src/Entities/TNTEntity.h
@@ -21,7 +21,7 @@ public:
// cEntity overrides:
virtual void SpawnOn(cClientHandle & a_ClientHandle) override;
- virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
+ virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
// tolua_begin
diff --git a/src/Entities/ThrownEggEntity.cpp b/src/Entities/ThrownEggEntity.cpp
index 24c946a9c..e9ef29239 100644
--- a/src/Entities/ThrownEggEntity.cpp
+++ b/src/Entities/ThrownEggEntity.cpp
@@ -44,7 +44,7 @@ void cThrownEggEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_Hit
-void cThrownEggEntity::Tick(float a_Dt, cChunk & a_Chunk)
+void cThrownEggEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
if (m_DestroyTimer > 0)
{
diff --git a/src/Entities/ThrownEggEntity.h b/src/Entities/ThrownEggEntity.h
index 6ffedf5b5..620927c5d 100644
--- a/src/Entities/ThrownEggEntity.h
+++ b/src/Entities/ThrownEggEntity.h
@@ -35,7 +35,7 @@ protected:
// cProjectileEntity overrides:
virtual void OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) override;
virtual void OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) override;
- virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
+ virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
// Randomly decides whether to spawn a chicken where the egg lands.
void TrySpawnChicken(const Vector3d & a_HitPos);
diff --git a/src/Entities/ThrownEnderPearlEntity.cpp b/src/Entities/ThrownEnderPearlEntity.cpp
index 8f1b62934..f01cdc18c 100644
--- a/src/Entities/ThrownEnderPearlEntity.cpp
+++ b/src/Entities/ThrownEnderPearlEntity.cpp
@@ -46,7 +46,7 @@ void cThrownEnderPearlEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d
-void cThrownEnderPearlEntity::Tick(float a_Dt, cChunk & a_Chunk)
+void cThrownEnderPearlEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
if (m_DestroyTimer > 0)
{
diff --git a/src/Entities/ThrownEnderPearlEntity.h b/src/Entities/ThrownEnderPearlEntity.h
index 475ebde87..94f3ab5cb 100644
--- a/src/Entities/ThrownEnderPearlEntity.h
+++ b/src/Entities/ThrownEnderPearlEntity.h
@@ -35,7 +35,7 @@ protected:
// cProjectileEntity overrides:
virtual void OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) override;
virtual void OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) override;
- virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
+ virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
/** Teleports the creator where the ender pearl lands */
void TeleportCreator(const Vector3d & a_HitPos);
diff --git a/src/Entities/ThrownSnowballEntity.cpp b/src/Entities/ThrownSnowballEntity.cpp
index 88e39d22e..24db1e7ee 100644
--- a/src/Entities/ThrownSnowballEntity.cpp
+++ b/src/Entities/ThrownSnowballEntity.cpp
@@ -48,7 +48,7 @@ void cThrownSnowballEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d &
-void cThrownSnowballEntity::Tick(float a_Dt, cChunk & a_Chunk)
+void cThrownSnowballEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
if (m_DestroyTimer > 0)
{
diff --git a/src/Entities/ThrownSnowballEntity.h b/src/Entities/ThrownSnowballEntity.h
index f806996cc..391b0c40b 100644
--- a/src/Entities/ThrownSnowballEntity.h
+++ b/src/Entities/ThrownSnowballEntity.h
@@ -35,7 +35,7 @@ protected:
// cProjectileEntity overrides:
virtual void OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) override;
virtual void OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) override;
- virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
+ virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
private:
diff --git a/src/Globals.h b/src/Globals.h
index b8e9ec7ed..f0726454b 100644
--- a/src/Globals.h
+++ b/src/Globals.h
@@ -421,6 +421,7 @@ std::unique_ptr make_unique(Args&&... args)
// a tick is 50 ms
using cTickTime = std::chrono::duration>>;
+using cTickTimeLong = std::chrono::duration;
#ifndef TOLUA_TEMPLATE_BIND
#define TOLUA_TEMPLATE_BIND(x)
diff --git a/src/Mobs/AggressiveMonster.cpp b/src/Mobs/AggressiveMonster.cpp
index 7ca7a9d66..b9e80c01d 100644
--- a/src/Mobs/AggressiveMonster.cpp
+++ b/src/Mobs/AggressiveMonster.cpp
@@ -61,7 +61,7 @@ void cAggressiveMonster::EventSeePlayer(cEntity * a_Entity)
-void cAggressiveMonster::Tick(float a_Dt, cChunk & a_Chunk)
+void cAggressiveMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
super::Tick(a_Dt, a_Chunk);
@@ -93,9 +93,9 @@ void cAggressiveMonster::Tick(float a_Dt, cChunk & a_Chunk)
-void cAggressiveMonster::Attack(float a_Dt)
+void cAggressiveMonster::Attack(std::chrono::milliseconds a_Dt)
{
- m_AttackInterval += a_Dt * m_AttackRate;
+ m_AttackInterval += a_Dt.count() * m_AttackRate;
if ((m_Target == nullptr) || (m_AttackInterval < 3.0))
{
diff --git a/src/Mobs/AggressiveMonster.h b/src/Mobs/AggressiveMonster.h
index 2549ba2d3..932915055 100644
--- a/src/Mobs/AggressiveMonster.h
+++ b/src/Mobs/AggressiveMonster.h
@@ -16,11 +16,11 @@ public:
cAggressiveMonster(const AString & a_ConfigName, eMonsterType a_MobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height);
- virtual void Tick (float a_Dt, cChunk & a_Chunk) override;
+ virtual void Tick (std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
virtual void InStateChasing(float a_Dt) override;
virtual void EventSeePlayer(cEntity *) override;
- virtual void Attack(float a_Dt);
+ virtual void Attack(std::chrono::milliseconds a_Dt);
protected:
/** Whether this mob's destination is the same as its target's position. */
diff --git a/src/Mobs/Blaze.cpp b/src/Mobs/Blaze.cpp
index 1fa9d2c37..172ccd071 100644
--- a/src/Mobs/Blaze.cpp
+++ b/src/Mobs/Blaze.cpp
@@ -30,9 +30,9 @@ void cBlaze::GetDrops(cItems & a_Drops, cEntity * a_Killer)
-void cBlaze::Attack(float a_Dt)
+void cBlaze::Attack(std::chrono::milliseconds a_Dt)
{
- m_AttackInterval += a_Dt * m_AttackRate;
+ m_AttackInterval += a_Dt.count() * m_AttackRate;
if ((m_Target != nullptr) && (m_AttackInterval > 3.0))
{
diff --git a/src/Mobs/Blaze.h b/src/Mobs/Blaze.h
index e2a4ad9f1..493953a14 100644
--- a/src/Mobs/Blaze.h
+++ b/src/Mobs/Blaze.h
@@ -18,5 +18,5 @@ public:
CLASS_PROTODEF(cBlaze)
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override;
- virtual void Attack(float a_Dt) override;
+ virtual void Attack(std::chrono::milliseconds a_Dt) override;
} ;
diff --git a/src/Mobs/CaveSpider.cpp b/src/Mobs/CaveSpider.cpp
index 045b47e73..fa530db82 100644
--- a/src/Mobs/CaveSpider.cpp
+++ b/src/Mobs/CaveSpider.cpp
@@ -16,7 +16,7 @@ cCaveSpider::cCaveSpider(void) :
-void cCaveSpider::Tick(float a_Dt, cChunk & a_Chunk)
+void cCaveSpider::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
super::Tick(a_Dt, a_Chunk);
@@ -27,7 +27,7 @@ void cCaveSpider::Tick(float a_Dt, cChunk & a_Chunk)
-void cCaveSpider::Attack(float a_Dt)
+void cCaveSpider::Attack(std::chrono::milliseconds a_Dt)
{
super::Attack(a_Dt);
diff --git a/src/Mobs/CaveSpider.h b/src/Mobs/CaveSpider.h
index 494ba1360..d3e56fd2b 100644
--- a/src/Mobs/CaveSpider.h
+++ b/src/Mobs/CaveSpider.h
@@ -16,8 +16,8 @@ public:
CLASS_PROTODEF(cCaveSpider)
- virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
- virtual void Attack(float a_Dt) override;
+ virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
+ virtual void Attack(std::chrono::milliseconds a_Dt) 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 634867cfa..b2b21d4ae 100644
--- a/src/Mobs/Chicken.cpp
+++ b/src/Mobs/Chicken.cpp
@@ -18,7 +18,7 @@ cChicken::cChicken(void) :
-void cChicken::Tick(float a_Dt, cChunk & a_Chunk)
+void cChicken::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
super::Tick(a_Dt, a_Chunk);
diff --git a/src/Mobs/Chicken.h b/src/Mobs/Chicken.h
index 07b921884..9349187c6 100644
--- a/src/Mobs/Chicken.h
+++ b/src/Mobs/Chicken.h
@@ -17,7 +17,7 @@ public:
CLASS_PROTODEF(cChicken)
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override;
- virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
+ virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
virtual const cItem GetFollowedItem(void) const override { return cItem(E_ITEM_SEEDS); }
diff --git a/src/Mobs/Creeper.cpp b/src/Mobs/Creeper.cpp
index a073224cf..c4ae47f2f 100644
--- a/src/Mobs/Creeper.cpp
+++ b/src/Mobs/Creeper.cpp
@@ -23,7 +23,7 @@ cCreeper::cCreeper(void) :
-void cCreeper::Tick(float a_Dt, cChunk & a_Chunk)
+void cCreeper::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
super::Tick(a_Dt, a_Chunk);
@@ -119,7 +119,7 @@ bool cCreeper::DoTakeDamage(TakeDamageInfo & a_TDI)
-void cCreeper::Attack(float a_Dt)
+void cCreeper::Attack(std::chrono::milliseconds a_Dt)
{
UNUSED(a_Dt);
diff --git a/src/Mobs/Creeper.h b/src/Mobs/Creeper.h
index bf3272e22..1827c416e 100644
--- a/src/Mobs/Creeper.h
+++ b/src/Mobs/Creeper.h
@@ -19,8 +19,8 @@ public:
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;
+ virtual void Attack(std::chrono::milliseconds a_Dt) override;
+ virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
virtual void OnRightClicked(cPlayer & a_Player) override;
bool IsBlowing(void) const {return m_bIsBlowing; }
diff --git a/src/Mobs/Enderman.cpp b/src/Mobs/Enderman.cpp
index 56ea10245..42c33884a 100644
--- a/src/Mobs/Enderman.cpp
+++ b/src/Mobs/Enderman.cpp
@@ -186,7 +186,7 @@ bool cEnderman::CheckLight()
-void cEnderman::Tick(float a_Dt, cChunk & a_Chunk)
+void cEnderman::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
super::Tick(a_Dt, a_Chunk);
diff --git a/src/Mobs/Enderman.h b/src/Mobs/Enderman.h
index 28bbceb84..8ccbf2ce7 100644
--- a/src/Mobs/Enderman.h
+++ b/src/Mobs/Enderman.h
@@ -21,7 +21,7 @@ public:
virtual void CheckEventSeePlayer(void) override;
virtual void CheckEventLostPlayer(void) override;
virtual void EventLosePlayer(void) override;
- virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
+ virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
bool IsScreaming(void) const {return m_bIsScreaming; }
BLOCKTYPE GetCarriedBlock(void) const {return CarriedBlock; }
diff --git a/src/Mobs/Ghast.cpp b/src/Mobs/Ghast.cpp
index fc8de8362..ea0295102 100644
--- a/src/Mobs/Ghast.cpp
+++ b/src/Mobs/Ghast.cpp
@@ -32,9 +32,9 @@ void cGhast::GetDrops(cItems & a_Drops, cEntity * a_Killer)
-void cGhast::Attack(float a_Dt)
+void cGhast::Attack(std::chrono::milliseconds a_Dt)
{
- m_AttackInterval += a_Dt * m_AttackRate;
+ m_AttackInterval += a_Dt.count() * m_AttackRate;
if ((m_Target != nullptr) && (m_AttackInterval > 3.0))
{
diff --git a/src/Mobs/Ghast.h b/src/Mobs/Ghast.h
index a28940a01..431edaf6d 100644
--- a/src/Mobs/Ghast.h
+++ b/src/Mobs/Ghast.h
@@ -18,7 +18,7 @@ public:
CLASS_PROTODEF(cGhast)
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override;
- virtual void Attack(float a_Dt) override;
+ virtual void Attack(std::chrono::milliseconds a_Dt) override;
bool IsCharging(void) const {return false; }
} ;
diff --git a/src/Mobs/Guardian.cpp b/src/Mobs/Guardian.cpp
index 15908d801..5eb30785b 100644
--- a/src/Mobs/Guardian.cpp
+++ b/src/Mobs/Guardian.cpp
@@ -35,7 +35,7 @@ void cGuardian::GetDrops(cItems & a_Drops, cEntity * a_Killer)
-void cGuardian::Tick(float a_Dt, cChunk & a_Chunk)
+void cGuardian::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
// We must first process current location, and only then tick, otherwise we risk processing a location in a chunk
// that is not where the entity currently resides (FS #411)
diff --git a/src/Mobs/Guardian.h b/src/Mobs/Guardian.h
index 50c034036..6bc17947c 100644
--- a/src/Mobs/Guardian.h
+++ b/src/Mobs/Guardian.h
@@ -15,7 +15,7 @@ class cGuardian :
public:
cGuardian();
- virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
+ virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
CLASS_PROTODEF(cGuardian)
diff --git a/src/Mobs/Horse.cpp b/src/Mobs/Horse.cpp
index d92f0d023..5b4c78bfc 100644
--- a/src/Mobs/Horse.cpp
+++ b/src/Mobs/Horse.cpp
@@ -30,7 +30,7 @@ cHorse::cHorse(int Type, int Color, int Style, int TameTimes) :
-void cHorse::Tick(float a_Dt, cChunk & a_Chunk)
+void cHorse::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
super::Tick(a_Dt, a_Chunk);
diff --git a/src/Mobs/Horse.h b/src/Mobs/Horse.h
index 4c644e512..be283705e 100644
--- a/src/Mobs/Horse.h
+++ b/src/Mobs/Horse.h
@@ -18,7 +18,7 @@ public:
CLASS_PROTODEF(cHorse)
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override;
- virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
+ virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
virtual void OnRightClicked(cPlayer & a_Player) override;
bool IsSaddled (void) const {return m_bIsSaddled; }
diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp
index 425c80bf4..30bbd0ff2 100644
--- a/src/Mobs/Monster.cpp
+++ b/src/Mobs/Monster.cpp
@@ -252,14 +252,14 @@ bool cMonster::ReachedFinalDestination()
-void cMonster::Tick(float a_Dt, cChunk & a_Chunk)
+void cMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
super::Tick(a_Dt, a_Chunk);
if (m_Health <= 0)
{
// The mob is dead, but we're still animating the "puff" they leave when they die
- m_DestroyTimer += a_Dt / 1000;
+ m_DestroyTimer += a_Dt.count() / 1000;
if (m_DestroyTimer > 1)
{
Destroy(true);
@@ -275,8 +275,6 @@ void cMonster::Tick(float a_Dt, cChunk & a_Chunk)
// Burning in daylight
HandleDaylightBurning(a_Chunk);
- a_Dt /= 1000;
-
if (m_bMovingToDestination)
{
if (m_bOnGround)
@@ -347,18 +345,18 @@ void cMonster::Tick(float a_Dt, cChunk & a_Chunk)
case IDLE:
{
// If enemy passive we ignore checks for player visibility
- InStateIdle(a_Dt);
+ InStateIdle(std::chrono::duration_cast(a_Dt).count());
break;
}
case CHASING:
{
// If we do not see a player anymore skip chasing action
- InStateChasing(a_Dt);
+ InStateChasing(std::chrono::duration_cast(a_Dt).count());
break;
}
case ESCAPING:
{
- InStateEscaping(a_Dt);
+ InStateEscaping(std::chrono::duration_cast(a_Dt).count());
break;
}
diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h
index fb1bc550d..5752a2040 100644
--- a/src/Mobs/Monster.h
+++ b/src/Mobs/Monster.h
@@ -52,7 +52,7 @@ public:
virtual void SpawnOn(cClientHandle & a_ClientHandle) override;
- virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
+ virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
virtual bool DoTakeDamage(TakeDamageInfo & a_TDI) override;
diff --git a/src/Mobs/PassiveMonster.cpp b/src/Mobs/PassiveMonster.cpp
index 1048616d0..012ca9949 100644
--- a/src/Mobs/PassiveMonster.cpp
+++ b/src/Mobs/PassiveMonster.cpp
@@ -35,7 +35,7 @@ bool cPassiveMonster::DoTakeDamage(TakeDamageInfo & a_TDI)
-void cPassiveMonster::Tick(float a_Dt, cChunk & a_Chunk)
+void cPassiveMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
super::Tick(a_Dt, a_Chunk);
diff --git a/src/Mobs/PassiveMonster.h b/src/Mobs/PassiveMonster.h
index 9221d9a6e..2ed2cd21d 100644
--- a/src/Mobs/PassiveMonster.h
+++ b/src/Mobs/PassiveMonster.h
@@ -15,7 +15,7 @@ class cPassiveMonster :
public:
cPassiveMonster(const AString & a_ConfigName, eMonsterType a_MobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height);
- virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
+ virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
/// When hit by someone, run away
virtual bool DoTakeDamage(TakeDamageInfo & a_TDI) override;
diff --git a/src/Mobs/Pig.cpp b/src/Mobs/Pig.cpp
index 1e4c35acd..edd4d9de4 100644
--- a/src/Mobs/Pig.cpp
+++ b/src/Mobs/Pig.cpp
@@ -80,7 +80,7 @@ void cPig::OnRightClicked(cPlayer & a_Player)
-void cPig::Tick(float a_Dt, cChunk & a_Chunk)
+void cPig::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
super::Tick(a_Dt, a_Chunk);
diff --git a/src/Mobs/Pig.h b/src/Mobs/Pig.h
index 0e026933a..0fe4b4fed 100644
--- a/src/Mobs/Pig.h
+++ b/src/Mobs/Pig.h
@@ -22,7 +22,7 @@ public:
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;
+ virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
virtual const cItem GetFollowedItem(void) const override { return cItem(E_ITEM_CARROT); }
diff --git a/src/Mobs/Sheep.cpp b/src/Mobs/Sheep.cpp
index c46404391..e4d1760e0 100644
--- a/src/Mobs/Sheep.cpp
+++ b/src/Mobs/Sheep.cpp
@@ -84,7 +84,7 @@ void cSheep::OnRightClicked(cPlayer & a_Player)
-void cSheep::Tick(float a_Dt, cChunk & a_Chunk)
+void cSheep::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
super::Tick(a_Dt, a_Chunk);
int PosX = POSX_TOINT;
diff --git a/src/Mobs/Sheep.h b/src/Mobs/Sheep.h
index 16d5fddd3..b6c99ac2a 100644
--- a/src/Mobs/Sheep.h
+++ b/src/Mobs/Sheep.h
@@ -24,7 +24,7 @@ public:
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;
+ virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
virtual const cItem GetFollowedItem(void) const override { return cItem(E_ITEM_WHEAT); }
diff --git a/src/Mobs/Skeleton.cpp b/src/Mobs/Skeleton.cpp
index da5ddc670..dd59d6454 100644
--- a/src/Mobs/Skeleton.cpp
+++ b/src/Mobs/Skeleton.cpp
@@ -67,9 +67,9 @@ void cSkeleton::MoveToPosition(const Vector3d & a_Position)
-void cSkeleton::Attack(float a_Dt)
+void cSkeleton::Attack(std::chrono::milliseconds a_Dt)
{
- m_AttackInterval += a_Dt * m_AttackRate;
+ m_AttackInterval += a_Dt.count() * m_AttackRate;
if ((m_Target != nullptr) && (m_AttackInterval > 3.0))
{
diff --git a/src/Mobs/Skeleton.h b/src/Mobs/Skeleton.h
index cd1c6c3f0..9c49c52fb 100644
--- a/src/Mobs/Skeleton.h
+++ b/src/Mobs/Skeleton.h
@@ -19,7 +19,7 @@ public:
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 Attack(std::chrono::milliseconds a_Dt) override;
virtual void SpawnOn(cClientHandle & a_ClientHandle) override;
virtual bool IsUndead(void) override { return true; }
diff --git a/src/Mobs/Slime.cpp b/src/Mobs/Slime.cpp
index 1c68c5189..e42501e47 100644
--- a/src/Mobs/Slime.cpp
+++ b/src/Mobs/Slime.cpp
@@ -46,7 +46,7 @@ void cSlime::GetDrops(cItems & a_Drops, cEntity * a_Killer)
-void cSlime::Attack(float a_Dt)
+void cSlime::Attack(std::chrono::milliseconds a_Dt)
{
if (m_Size > 1)
{
diff --git a/src/Mobs/Slime.h b/src/Mobs/Slime.h
index a177a279c..29605992d 100644
--- a/src/Mobs/Slime.h
+++ b/src/Mobs/Slime.h
@@ -20,7 +20,7 @@ public:
// cAggressiveMonster overrides:
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override;
- virtual void Attack(float a_Dt) override;
+ virtual void Attack(std::chrono::milliseconds a_Dt) override;
virtual void KilledBy(TakeDamageInfo & a_TDI) override;
int GetSize(void) const { return m_Size; }
diff --git a/src/Mobs/SnowGolem.cpp b/src/Mobs/SnowGolem.cpp
index 8c4178beb..e1510b203 100644
--- a/src/Mobs/SnowGolem.cpp
+++ b/src/Mobs/SnowGolem.cpp
@@ -27,7 +27,7 @@ void cSnowGolem::GetDrops(cItems & a_Drops, cEntity * a_Killer)
-void cSnowGolem::Tick(float a_Dt, cChunk & a_Chunk)
+void cSnowGolem::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
super::Tick(a_Dt, a_Chunk);
if (IsBiomeNoDownfall(m_World->GetBiomeAt((int) floor(GetPosX()), (int) floor(GetPosZ()))))
diff --git a/src/Mobs/SnowGolem.h b/src/Mobs/SnowGolem.h
index f036b1867..9c95e21c5 100644
--- a/src/Mobs/SnowGolem.h
+++ b/src/Mobs/SnowGolem.h
@@ -17,7 +17,7 @@ public:
CLASS_PROTODEF(cSnowGolem)
- virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
+ virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) 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 59ee963ae..3c508b65f 100644
--- a/src/Mobs/Squid.cpp
+++ b/src/Mobs/Squid.cpp
@@ -33,7 +33,7 @@ void cSquid::GetDrops(cItems & a_Drops, cEntity * a_Killer)
-void cSquid::Tick(float a_Dt, cChunk & a_Chunk)
+void cSquid::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
// We must first process current location, and only then tick, otherwise we risk processing a location in a chunk
// that is not where the entity currently resides (FS #411)
diff --git a/src/Mobs/Squid.h b/src/Mobs/Squid.h
index a46d738c6..7e944a17e 100644
--- a/src/Mobs/Squid.h
+++ b/src/Mobs/Squid.h
@@ -15,7 +15,7 @@ class cSquid :
public:
cSquid();
- virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
+ virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
CLASS_PROTODEF(cSquid)
diff --git a/src/Mobs/Villager.cpp b/src/Mobs/Villager.cpp
index 963595347..6f647ac18 100644
--- a/src/Mobs/Villager.cpp
+++ b/src/Mobs/Villager.cpp
@@ -51,7 +51,7 @@ bool cVillager::DoTakeDamage(TakeDamageInfo & a_TDI)
-void cVillager::Tick(float a_Dt, cChunk & a_Chunk)
+void cVillager::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
super::Tick(a_Dt, a_Chunk);
diff --git a/src/Mobs/Villager.h b/src/Mobs/Villager.h
index d3a38dbf0..2de79295c 100644
--- a/src/Mobs/Villager.h
+++ b/src/Mobs/Villager.h
@@ -31,7 +31,7 @@ public:
// cEntity overrides
virtual bool DoTakeDamage(TakeDamageInfo & a_TDI) override;
- virtual void Tick (float a_Dt, cChunk & a_Chunk) override;
+ virtual void Tick (std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
// cVillager functions
/** return true if the given blocktype are: crops, potatoes or carrots.*/
diff --git a/src/Mobs/Wither.cpp b/src/Mobs/Wither.cpp
index 578b47995..6ef81ce1b 100644
--- a/src/Mobs/Wither.cpp
+++ b/src/Mobs/Wither.cpp
@@ -66,7 +66,7 @@ bool cWither::DoTakeDamage(TakeDamageInfo & a_TDI)
-void cWither::Tick(float a_Dt, cChunk & a_Chunk)
+void cWither::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
super::Tick(a_Dt, a_Chunk);
diff --git a/src/Mobs/Wither.h b/src/Mobs/Wither.h
index a20fed3d3..9e333c7fa 100644
--- a/src/Mobs/Wither.h
+++ b/src/Mobs/Wither.h
@@ -28,7 +28,7 @@ public:
virtual bool Initialize(cWorld & a_World) 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 Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
virtual void KilledBy(TakeDamageInfo & a_TDI) override;
virtual bool IsUndead(void) override { return true; }
diff --git a/src/Mobs/Wolf.cpp b/src/Mobs/Wolf.cpp
index 4711d5a7a..b3eefdf79 100644
--- a/src/Mobs/Wolf.cpp
+++ b/src/Mobs/Wolf.cpp
@@ -43,7 +43,7 @@ bool cWolf::DoTakeDamage(TakeDamageInfo & a_TDI)
-void cWolf::Attack(float a_Dt)
+void cWolf::Attack(std::chrono::milliseconds a_Dt)
{
UNUSED(a_Dt);
@@ -145,7 +145,7 @@ void cWolf::OnRightClicked(cPlayer & a_Player)
-void cWolf::Tick(float a_Dt, cChunk & a_Chunk)
+void cWolf::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
if (!IsAngry())
{
diff --git a/src/Mobs/Wolf.h b/src/Mobs/Wolf.h
index 7500854f8..73ffb55c2 100644
--- a/src/Mobs/Wolf.h
+++ b/src/Mobs/Wolf.h
@@ -20,9 +20,9 @@ public:
virtual bool DoTakeDamage(TakeDamageInfo & a_TDI) override;
virtual void OnRightClicked(cPlayer & a_Player) override;
- virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
+ virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
virtual void TickFollowPlayer();
- virtual void Attack(float a_Dt) override;
+ virtual void Attack(std::chrono::milliseconds a_Dt) override;
// Get functions
bool IsSitting (void) const { return m_IsSitting; }
diff --git a/src/Simulator/DelayedFluidSimulator.cpp b/src/Simulator/DelayedFluidSimulator.cpp
index dc8dffe2d..0973962b6 100644
--- a/src/Simulator/DelayedFluidSimulator.cpp
+++ b/src/Simulator/DelayedFluidSimulator.cpp
@@ -130,7 +130,7 @@ void cDelayedFluidSimulator::Simulate(float a_Dt)
-void cDelayedFluidSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk)
+void cDelayedFluidSimulator::SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk)
{
void * ChunkDataRaw = (m_FluidBlock == E_BLOCK_WATER) ? a_Chunk->GetWaterSimulatorData() : a_Chunk->GetLavaSimulatorData();
cDelayedFluidSimulatorChunkData * ChunkData = (cDelayedFluidSimulatorChunkData *)ChunkDataRaw;
diff --git a/src/Simulator/DelayedFluidSimulator.h b/src/Simulator/DelayedFluidSimulator.h
index 8a6c26c7a..e3182812d 100644
--- a/src/Simulator/DelayedFluidSimulator.h
+++ b/src/Simulator/DelayedFluidSimulator.h
@@ -56,7 +56,7 @@ public:
// cSimulator overrides:
virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) override;
virtual void Simulate(float a_Dt) override;
- virtual void SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override;
+ virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override;
virtual cFluidSimulatorData * CreateChunkData(void) override { return new cDelayedFluidSimulatorChunkData(m_TickDelay); }
protected:
diff --git a/src/Simulator/FireSimulator.cpp b/src/Simulator/FireSimulator.cpp
index 75ebefcf7..0439ebdca 100644
--- a/src/Simulator/FireSimulator.cpp
+++ b/src/Simulator/FireSimulator.cpp
@@ -88,11 +88,11 @@ cFireSimulator::~cFireSimulator()
-void cFireSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk)
+void cFireSimulator::SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk)
{
cCoordWithIntList & Data = a_Chunk->GetFireSimulatorData();
- int NumMSecs = (int)a_Dt;
+ int NumMSecs = a_Dt.count();
for (cCoordWithIntList::iterator itr = Data.begin(); itr != Data.end();)
{
int x = itr->x;
diff --git a/src/Simulator/FireSimulator.h b/src/Simulator/FireSimulator.h
index 9ccc3ef4f..a40e29565 100644
--- a/src/Simulator/FireSimulator.h
+++ b/src/Simulator/FireSimulator.h
@@ -23,7 +23,7 @@ public:
~cFireSimulator();
virtual void Simulate(float a_Dt) override { UNUSED(a_Dt);} // not used
- virtual void SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override;
+ virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override;
virtual bool IsAllowedBlock(BLOCKTYPE a_BlockType) override;
diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp
index 7ff499eb5..1cc5340dd 100644
--- a/src/Simulator/IncrementalRedstoneSimulator.cpp
+++ b/src/Simulator/IncrementalRedstoneSimulator.cpp
@@ -145,7 +145,7 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
-void cIncrementalRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk)
+void cIncrementalRedstoneSimulator::SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk)
{
m_RedstoneSimulatorChunkData = (cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData();
if (m_RedstoneSimulatorChunkData == nullptr)
diff --git a/src/Simulator/IncrementalRedstoneSimulator.h b/src/Simulator/IncrementalRedstoneSimulator.h
index 3d2962c08..43f0e89d0 100644
--- a/src/Simulator/IncrementalRedstoneSimulator.h
+++ b/src/Simulator/IncrementalRedstoneSimulator.h
@@ -32,7 +32,7 @@ public:
}
virtual void Simulate(float a_Dt) override { UNUSED(a_Dt); } // not used
- virtual void SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override;
+ virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override;
virtual bool IsAllowedBlock(BLOCKTYPE a_BlockType) override { return IsRedstone(a_BlockType); }
virtual void WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) override;
diff --git a/src/Simulator/NoopRedstoneSimulator.h b/src/Simulator/NoopRedstoneSimulator.h
index 4e05529f5..b8c797472 100644
--- a/src/Simulator/NoopRedstoneSimulator.h
+++ b/src/Simulator/NoopRedstoneSimulator.h
@@ -21,7 +21,7 @@ public:
// ~cRedstoneNoopSimulator();
virtual void Simulate(float a_Dt) override { UNUSED(a_Dt);} // not used
- virtual void SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override
+ virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override
{
UNUSED(a_Dt);
UNUSED(a_ChunkX);
diff --git a/src/Simulator/SandSimulator.cpp b/src/Simulator/SandSimulator.cpp
index dfbd3e458..497f81999 100644
--- a/src/Simulator/SandSimulator.cpp
+++ b/src/Simulator/SandSimulator.cpp
@@ -24,7 +24,7 @@ cSandSimulator::cSandSimulator(cWorld & a_World, cIniFile & a_IniFile) :
-void cSandSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk)
+void cSandSimulator::SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk)
{
cSandSimulatorChunkData & ChunkData = a_Chunk->GetSandSimulatorData();
if (ChunkData.empty())
diff --git a/src/Simulator/SandSimulator.h b/src/Simulator/SandSimulator.h
index 93b1de8e2..8fff659ed 100644
--- a/src/Simulator/SandSimulator.h
+++ b/src/Simulator/SandSimulator.h
@@ -18,7 +18,7 @@ public:
// cSimulator overrides:
virtual void Simulate(float a_Dt) override { UNUSED(a_Dt);} // not used
- virtual void SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override;
+ virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override;
virtual bool IsAllowedBlock(BLOCKTYPE a_BlockType) override;
/// Returns true if a falling-able block can start falling through the specified block type
diff --git a/src/Simulator/Simulator.h b/src/Simulator/Simulator.h
index f28a07e35..c8066edfd 100644
--- a/src/Simulator/Simulator.h
+++ b/src/Simulator/Simulator.h
@@ -24,7 +24,7 @@ public:
virtual void Simulate(float a_Dt) = 0;
/// Called in each tick for each chunk, a_Dt is the time passed since the last tick, in msec; direct access to chunk data available
- virtual void SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk)
+ virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk)
{
UNUSED(a_Dt);
UNUSED(a_ChunkX);
diff --git a/src/Simulator/SimulatorManager.cpp b/src/Simulator/SimulatorManager.cpp
index 918bac7a1..e74642fc0 100644
--- a/src/Simulator/SimulatorManager.cpp
+++ b/src/Simulator/SimulatorManager.cpp
@@ -42,7 +42,7 @@ void cSimulatorManager::Simulate(float a_Dt)
-void cSimulatorManager::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk)
+void cSimulatorManager::SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk)
{
// m_Ticks has already been increased in Simulate()
for (cSimulators::iterator itr = m_Simulators.begin(); itr != m_Simulators.end(); ++itr)
diff --git a/src/Simulator/SimulatorManager.h b/src/Simulator/SimulatorManager.h
index 31a709316..b96f6ca84 100644
--- a/src/Simulator/SimulatorManager.h
+++ b/src/Simulator/SimulatorManager.h
@@ -33,7 +33,7 @@ public:
void Simulate(float a_Dt);
- void SimulateChunk(float a_DT, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk);
+ void SimulateChunk(std::chrono::milliseconds a_DT, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk);
void WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk);
diff --git a/src/World.cpp b/src/World.cpp
index 2dd03497b..cd99f2c2d 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -238,9 +238,8 @@ void cWorld::cTickThread::Execute(void)
while (!m_ShouldTerminate)
{
auto NowTime = std::chrono::steady_clock::now();
- auto msec = std::chrono::duration_cast(NowTime - LastTime).count();
- auto LastTickMsec = std::chrono::duration_cast>(TickTime).count();
- m_World.Tick(static_cast(msec), LastTickMsec);
+ auto WaitTime = std::chrono::duration_cast(NowTime - LastTime);
+ m_World.Tick(WaitTime, TickTime);
TickTime = std::chrono::duration_cast(std::chrono::steady_clock::now() - NowTime);
if (TickTime < cTickTime(1))
@@ -273,8 +272,6 @@ cWorld::cWorld(const AString & a_WorldName, eDimension a_Dimension, const AStrin
m_Dimension(a_Dimension),
m_IsSpawnExplicitlySet(false),
m_IsDaylightCycleEnabled(true),
- m_WorldAgeSecs(0),
- m_TimeOfDaySecs(0),
m_WorldAge(0),
m_TimeOfDay(0),
m_LastTimeUpdate(0),
@@ -617,7 +614,7 @@ void cWorld::Start(void)
InitialiseGeneratorDefaults(IniFile);
InitialiseAndLoadMobSpawningValues(IniFile);
- SetTimeOfDay(IniFile.GetValueSetI("General", "TimeInTicks", m_TimeOfDay));
+ SetTimeOfDay(IniFile.GetValueSetI("General", "TimeInTicks", GetTimeOfDay()));
m_ChunkMap = make_unique(this);
@@ -644,10 +641,10 @@ void cWorld::Start(void)
m_TickThread.Start();
// Init of the spawn monster time (as they are supposed to have different spawn rate)
- m_LastSpawnMonster.insert(std::map::value_type(cMonster::mfHostile, 0));
- m_LastSpawnMonster.insert(std::map::value_type(cMonster::mfPassive, 0));
- m_LastSpawnMonster.insert(std::map::value_type(cMonster::mfAmbient, 0));
- m_LastSpawnMonster.insert(std::map::value_type(cMonster::mfWater, 0));
+ m_LastSpawnMonster.insert(std::map::value_type(cMonster::mfHostile, cTickTimeLong(0)));
+ m_LastSpawnMonster.insert(std::map::value_type(cMonster::mfPassive, cTickTimeLong(0)));
+ m_LastSpawnMonster.insert(std::map::value_type(cMonster::mfAmbient, cTickTimeLong(0)));
+ m_LastSpawnMonster.insert(std::map::value_type(cMonster::mfWater, cTickTimeLong(0)));
m_MapManager.LoadMapData();
@@ -838,7 +835,7 @@ void cWorld::Stop(void)
IniFile.SetValueB("Mechanics", "UseChatPrefixes", m_bUseChatPrefixes);
IniFile.SetValueB("General", "IsDaylightCycleEnabled", m_IsDaylightCycleEnabled);
IniFile.SetValueI("General", "Weather", (int)m_Weather);
- IniFile.SetValueI("General", "TimeInTicks", m_TimeOfDay);
+ IniFile.SetValueI("General", "TimeInTicks", GetTimeOfDay());
IniFile.WriteFile(m_IniFileName);
m_TickThread.Stop();
@@ -852,7 +849,7 @@ void cWorld::Stop(void)
-void cWorld::Tick(float a_Dt, int a_LastTickDurationMSec)
+void cWorld::Tick(std::chrono::milliseconds a_Dt, std::chrono::milliseconds a_LastTickDurationMSec)
{
// Call the plugins
cPluginManager::Get()->CallHookWorldTick(*this, a_Dt, a_LastTickDurationMSec);
@@ -868,30 +865,27 @@ void cWorld::Tick(float a_Dt, int a_LastTickDurationMSec)
SetChunkData(**itr);
} // for itr - SetChunkDataQueue[]
- m_WorldAgeSecs += (double)a_Dt / 1000.0;
- m_WorldAge = (Int64)(m_WorldAgeSecs * 20.0);
+ m_WorldAge += a_Dt;
if (m_IsDaylightCycleEnabled)
{
// We need sub-tick precision here, that's why we store the time in seconds and calculate ticks off of it
- m_TimeOfDaySecs += (double)a_Dt / 1000.0;
+ m_TimeOfDay += a_Dt;
// Wrap time of day each 20 minutes (1200 seconds)
- if (m_TimeOfDaySecs > 1200.0)
+ if (m_TimeOfDay > std::chrono::minutes(20))
{
- m_TimeOfDaySecs -= 1200.0;
+ m_TimeOfDay -= std::chrono::minutes(20);
}
- m_TimeOfDay = static_cast(m_TimeOfDaySecs * 20.0);
-
// Updates the sky darkness based on current time of day
UpdateSkyDarkness();
// Broadcast time update every 40 ticks (2 seconds)
- if (m_LastTimeUpdate < m_WorldAge - 40)
+ if (m_LastTimeUpdate < m_WorldAge - cTickTime(40))
{
BroadcastTimeUpdate();
- m_LastTimeUpdate = m_WorldAge;
+ m_LastTimeUpdate = std::chrono::duration_cast(m_WorldAge);
}
}
@@ -911,23 +905,23 @@ void cWorld::Tick(float a_Dt, int a_LastTickDurationMSec)
m_ChunkMap->Tick(a_Dt);
- TickClients(a_Dt);
+ TickClients(a_Dt.count());
TickQueuedBlocks();
TickQueuedTasks();
TickScheduledTasks();
- GetSimulatorManager()->Simulate(a_Dt);
+ GetSimulatorManager()->Simulate(a_Dt.count());
- TickWeather(a_Dt);
+ TickWeather(a_Dt.count());
m_ChunkMap->FastSetQueuedBlocks();
- if (m_WorldAge - m_LastSave > 60 * 5 * 20) // Save each 5 minutes
+ if (m_WorldAge - m_LastSave > std::chrono::minutes(5)) // Save each 5 minutes
{
SaveAllChunks();
}
- if (m_WorldAge - m_LastUnload > 10 * 20) // Unload every 10 seconds
+ if (m_WorldAge - m_LastUnload > std::chrono::minutes(5)) // Unload every 10 seconds
{
UnloadUnusedChunks();
}
@@ -973,7 +967,7 @@ void cWorld::TickWeather(float a_Dt)
-void cWorld::TickMobs(float a_Dt)
+void cWorld::TickMobs(std::chrono::milliseconds a_Dt)
{
// _X 2013_10_22: This is a quick fix for #283 - the world needs to be locked while ticking mobs
cWorld::cLock Lock(*this);
@@ -994,7 +988,7 @@ void cWorld::TickMobs(float a_Dt)
for (size_t i = 0; i < ARRAYCOUNT(AllFamilies); i++)
{
cMonster::eFamily Family = AllFamilies[i];
- int SpawnDelay = cMonster::GetSpawnDelay(Family);
+ cTickTime SpawnDelay = cTickTime(cMonster::GetSpawnDelay(Family));
if (
(m_LastSpawnMonster[Family] > m_WorldAge - SpawnDelay) || // Not reached the needed ticks before the next round
MobCensus.IsCapped(Family)
@@ -1002,7 +996,7 @@ void cWorld::TickMobs(float a_Dt)
{
continue;
}
- m_LastSpawnMonster[Family] = m_WorldAge;
+ m_LastSpawnMonster[Family] = std::chrono::duration_cast(m_WorldAge);
cMobSpawner Spawner(Family, m_AllowedMobs);
if (Spawner.CanSpawnAnything())
{
@@ -1066,7 +1060,7 @@ void cWorld::TickScheduledTasks(void)
// Move all the due tasks from m_ScheduledTasks into Tasks:
for (auto itr = m_ScheduledTasks.begin(); itr != m_ScheduledTasks.end();) // Cannot use range-basd for, we're modifying the container
{
- if ((*itr)->m_TargetTick < WorldAge)
+ if ((*itr)->m_TargetTick < std::chrono::duration_cast(WorldAge).count())
{
auto next = itr;
++next;
@@ -1141,7 +1135,7 @@ void cWorld::TickClients(float a_Dt)
void cWorld::UpdateSkyDarkness(void)
{
- int TempTime = (int)m_TimeOfDay;
+ int TempTime = std::chrono::duration_cast(m_TimeOfDay).count();
if (TempTime <= TIME_SUNSET)
{
m_SkyDarkness = 0;
@@ -1422,14 +1416,15 @@ void cWorld::GrowTreeFromSapling(int a_X, int a_Y, int a_Z, NIBBLETYPE a_Sapling
{
cNoise Noise(m_Generator.GetSeed());
sSetBlockVector Logs, Other;
+ auto WorldAge = (int)(std::chrono::duration_cast(m_WorldAge).count() & 0xffffffff);
switch (a_SaplingMeta & 0x07)
{
- case E_META_SAPLING_APPLE: GetAppleTreeImage (a_X, a_Y, a_Z, Noise, (int)(m_WorldAge & 0xffffffff), Logs, Other); break;
- case E_META_SAPLING_BIRCH: GetBirchTreeImage (a_X, a_Y, a_Z, Noise, (int)(m_WorldAge & 0xffffffff), Logs, Other); break;
- case E_META_SAPLING_CONIFER: GetConiferTreeImage(a_X, a_Y, a_Z, Noise, (int)(m_WorldAge & 0xffffffff), Logs, Other); break;
- case E_META_SAPLING_JUNGLE: GetJungleTreeImage (a_X, a_Y, a_Z, Noise, (int)(m_WorldAge & 0xffffffff), Logs, Other); break;
- case E_META_SAPLING_ACACIA: GetAcaciaTreeImage (a_X, a_Y, a_Z, Noise, (int)(m_WorldAge & 0xffffffff), Logs, Other); break;
- case E_META_SAPLING_DARK_OAK: GetDarkoakTreeImage(a_X, a_Y, a_Z, Noise, (int)(m_WorldAge & 0xffffffff), Logs, Other); break;
+ case E_META_SAPLING_APPLE: GetAppleTreeImage (a_X, a_Y, a_Z, Noise, WorldAge, Logs, Other); break;
+ case E_META_SAPLING_BIRCH: GetBirchTreeImage (a_X, a_Y, a_Z, Noise, WorldAge, Logs, Other); break;
+ case E_META_SAPLING_CONIFER: GetConiferTreeImage(a_X, a_Y, a_Z, Noise, WorldAge, Logs, Other); break;
+ case E_META_SAPLING_JUNGLE: GetJungleTreeImage (a_X, a_Y, a_Z, Noise, WorldAge, Logs, Other); break;
+ case E_META_SAPLING_ACACIA: GetAcaciaTreeImage (a_X, a_Y, a_Z, Noise, WorldAge, Logs, Other); break;
+ case E_META_SAPLING_DARK_OAK: GetDarkoakTreeImage(a_X, a_Y, a_Z, Noise, WorldAge, Logs, Other); break;
}
Other.insert(Other.begin(), Logs.begin(), Logs.end());
Logs.clear();
@@ -1444,7 +1439,7 @@ void cWorld::GrowTreeByBiome(int a_X, int a_Y, int a_Z)
{
cNoise Noise(m_Generator.GetSeed());
sSetBlockVector Logs, Other;
- GetTreeImageByBiome(a_X, a_Y, a_Z, Noise, (int)(m_WorldAge & 0xffffffff), GetBiomeAt(a_X, a_Z), Logs, Other);
+ GetTreeImageByBiome(a_X, a_Y, a_Z, Noise, (int)(std::chrono::duration_cast(m_WorldAge).count() & 0xffffffff), GetBiomeAt(a_X, a_Z), Logs, Other);
Other.insert(Other.begin(), Logs.begin(), Logs.end());
Logs.clear();
GrowTreeImage(Other);
@@ -2405,7 +2400,7 @@ void cWorld::BroadcastTimeUpdate(const cClientHandle * a_Exclude)
{
continue;
}
- ch->SendTimeUpdate(m_WorldAge, m_TimeOfDay, m_IsDaylightCycleEnabled);
+ ch->SendTimeUpdate(std::chrono::duration_cast(m_WorldAge).count(), std::chrono::duration_cast(m_TimeOfDay).count(), m_IsDaylightCycleEnabled);
}
}
@@ -2607,7 +2602,7 @@ bool cWorld::HasChunkAnyClients(int a_ChunkX, int a_ChunkZ) const
void cWorld::UnloadUnusedChunks(void)
{
- m_LastUnload = m_WorldAge;
+ m_LastUnload = std::chrono::duration_cast(m_WorldAge);
m_ChunkMap->UnloadUnusedChunks();
}
@@ -3083,7 +3078,7 @@ bool cWorld::ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunk
void cWorld::SaveAllChunks(void)
{
- m_LastSave = m_WorldAge;
+ m_LastSave = std::chrono::duration_cast(m_WorldAge);
m_ChunkMap->SaveAllChunks();
}
@@ -3112,7 +3107,7 @@ void cWorld::QueueTask(std::unique_ptr a_Task)
void cWorld::ScheduleTask(int a_DelayTicks, cTask * a_Task)
{
- Int64 TargetTick = a_DelayTicks + m_WorldAge;
+ Int64 TargetTick = a_DelayTicks + std::chrono::duration_cast(m_WorldAge).count();
// Insert the task into the list of scheduled tasks, ordered by its target tick
cCSLock Lock(m_CSScheduledTasks);
diff --git a/src/World.h b/src/World.h
index 2ee33375f..4e5c9bceb 100644
--- a/src/World.h
+++ b/src/World.h
@@ -157,8 +157,8 @@ public:
BroadcastTimeUpdate();
}
- virtual Int64 GetWorldAge (void) const override { return m_WorldAge; }
- virtual int GetTimeOfDay(void) const override { return m_TimeOfDay; }
+ virtual Int64 GetWorldAge (void) const override { return std::chrono::duration_cast(m_WorldAge).count(); }
+ virtual int GetTimeOfDay(void) const override { return std::chrono::duration_cast(m_TimeOfDay).count(); }
void SetTicksUntilWeatherChange(int a_WeatherInterval)
{
@@ -167,8 +167,7 @@ public:
virtual void SetTimeOfDay(int a_TimeOfDay) override
{
- m_TimeOfDay = a_TimeOfDay;
- m_TimeOfDaySecs = (double)a_TimeOfDay / 20.0;
+ m_TimeOfDay = cTickTime(a_TimeOfDay);
UpdateSkyDarkness();
BroadcastTimeUpdate();
}
@@ -913,15 +912,14 @@ private:
bool m_BroadcastDeathMessages;
bool m_BroadcastAchievementMessages;
- bool m_IsDaylightCycleEnabled;
- double m_WorldAgeSecs; // World age, in seconds. Is only incremented, cannot be set by plugins.
- double m_TimeOfDaySecs; // Time of day in seconds. Can be adjusted. Is wrapped to zero each day.
- Int64 m_WorldAge; // World age in ticks, calculated off of m_WorldAgeSecs
- int m_TimeOfDay; // Time in ticks, calculated off of m_TimeOfDaySecs
- Int64 m_LastTimeUpdate; // The tick in which the last time update has been sent.
- Int64 m_LastUnload; // The last WorldAge (in ticks) in which unloading was triggerred
- Int64 m_LastSave; // The last WorldAge (in ticks) in which save-all was triggerred
- std::map m_LastSpawnMonster; // The last WorldAge (in ticks) in which a monster was spawned (for each megatype of monster) // MG TODO : find a way to optimize without creating unmaintenability (if mob IDs are becoming unrowed)
+ bool m_IsDaylightCycleEnabled;
+ // std::chrono::milliseconds is guaranteed to be good for 292 years by the standard.
+ std::chrono::milliseconds m_WorldAge;
+ std::chrono::milliseconds m_TimeOfDay;
+ cTickTimeLong m_LastTimeUpdate; // The tick in which the last time update has been sent.
+ cTickTimeLong m_LastUnload; // The last WorldAge (in ticks) in which unloading was triggerred
+ cTickTimeLong m_LastSave; // The last WorldAge (in ticks) in which save-all was triggerred
+ std::map m_LastSpawnMonster; // The last WorldAge (in ticks) in which a monster was spawned (for each megatype of monster) // MG TODO : find a way to optimize without creating unmaintenability (if mob IDs are becoming unrowed)
NIBBLETYPE m_SkyDarkness;
@@ -1051,13 +1049,13 @@ private:
cWorld(const AString & a_WorldName, eDimension a_Dimension = dimOverworld, const AString & a_OverworldName = "");
virtual ~cWorld();
- void Tick(float a_Dt, int a_LastTickDurationMSec);
+ void Tick(std::chrono::milliseconds a_Dt, std::chrono::milliseconds a_LastTickDurationMSec);
/** Handles the weather in each tick */
void TickWeather(float a_Dt);
/** Handles the mob spawning/moving/destroying each tick */
- void TickMobs(float a_Dt);
+ void TickMobs(std::chrono::milliseconds a_Dt);
/** Executes all tasks queued onto the tick thread */
void TickQueuedTasks(void);
--
cgit v1.2.3
From acc2dcbbc3e08ddae654b8c64d735f93207c297a Mon Sep 17 00:00:00 2001
From: Tycho
Date: Sun, 11 Jan 2015 21:53:20 +0000
Subject: Fix trailing whitespace
---
src/World.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/World.h b/src/World.h
index 4e5c9bceb..1f58ddbb7 100644
--- a/src/World.h
+++ b/src/World.h
@@ -912,7 +912,7 @@ private:
bool m_BroadcastDeathMessages;
bool m_BroadcastAchievementMessages;
- bool m_IsDaylightCycleEnabled;
+ bool m_IsDaylightCycleEnabled;
// std::chrono::milliseconds is guaranteed to be good for 292 years by the standard.
std::chrono::milliseconds m_WorldAge;
std::chrono::milliseconds m_TimeOfDay;
--
cgit v1.2.3
From d6f042da4a4d296ab9be18884996f0d88dd23c39 Mon Sep 17 00:00:00 2001
From: Tycho
Date: Fri, 16 Jan 2015 13:13:23 +0000
Subject: Converted ArrowEntityTiers to std::chrono
---
src/Entities/ArrowEntity.cpp | 10 +++++-----
src/Entities/ArrowEntity.h | 4 ++--
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/src/Entities/ArrowEntity.cpp b/src/Entities/ArrowEntity.cpp
index 2ec825ddb..0fbbfb681 100644
--- a/src/Entities/ArrowEntity.cpp
+++ b/src/Entities/ArrowEntity.cpp
@@ -177,17 +177,17 @@ void cArrowEntity::CollectedBy(cPlayer & a_Dest)
void cArrowEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
super::Tick(a_Dt, a_Chunk);
- m_Timer += a_Dt.count();
+ m_Timer += a_Dt;
if (m_bIsCollected)
{
- if (m_Timer > 500.f) // 0.5 seconds
+ if (m_Timer > std::chrono::milliseconds(500))
{
Destroy();
return;
}
}
- else if (m_Timer > 1000 * 60 * 5) // 5 minutes
+ else if (m_Timer > std::chrono::minutes(5))
{
Destroy();
return;
@@ -202,14 +202,14 @@ void cArrowEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
if (!m_HasTeleported) // Sent a teleport already, don't do again
{
- if (m_HitGroundTimer > 500.f) // Send after half a second, could be less, but just in case
+ if (m_HitGroundTimer > std::chrono::milliseconds(500))
{
m_World->BroadcastTeleportEntity(*this);
m_HasTeleported = true;
}
else
{
- m_HitGroundTimer += a_Dt.count();
+ m_HitGroundTimer += a_Dt;
}
}
diff --git a/src/Entities/ArrowEntity.h b/src/Entities/ArrowEntity.h
index 8c92049b0..2ecc16d1c 100644
--- a/src/Entities/ArrowEntity.h
+++ b/src/Entities/ArrowEntity.h
@@ -85,10 +85,10 @@ protected:
bool m_IsCritical;
/** Timer for pickup collection animation or five minute timeout */
- float m_Timer;
+ std::chrono::milliseconds m_Timer;
/** Timer for client arrow position confirmation via TeleportEntity */
- float m_HitGroundTimer;
+ std::chrono::milliseconds m_HitGroundTimer;
// Whether the arrow has already been teleported into the proper position in the ground.
bool m_HasTeleported;
--
cgit v1.2.3
From 7562a381c004470dfa8f0f94cd00f92d3c413f74 Mon Sep 17 00:00:00 2001
From: Tycho
Date: Fri, 16 Jan 2015 13:27:10 +0000
Subject: Converted cExpOrbEntity to std::chrono
---
src/Entities/ExpOrb.cpp | 8 ++++----
src/Entities/ExpOrb.h | 6 +++---
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/src/Entities/ExpOrb.cpp b/src/Entities/ExpOrb.cpp
index 9767f96ca..db7f6f2c8 100644
--- a/src/Entities/ExpOrb.cpp
+++ b/src/Entities/ExpOrb.cpp
@@ -8,7 +8,7 @@
cExpOrb::cExpOrb(double a_X, double a_Y, double a_Z, int a_Reward)
: cEntity(etExpOrb, a_X, a_Y, a_Z, 0.98, 0.98)
, m_Reward(a_Reward)
- , m_Timer(0.f)
+ , m_Timer(0)
{
SetMaxHealth(5);
SetHealth(5);
@@ -21,7 +21,7 @@ cExpOrb::cExpOrb(double a_X, double a_Y, double a_Z, int a_Reward)
cExpOrb::cExpOrb(const Vector3d & a_Pos, int a_Reward)
: cEntity(etExpOrb, a_Pos.x, a_Pos.y, a_Pos.z, 0.98, 0.98)
, m_Reward(a_Reward)
- , m_Timer(0.f)
+ , m_Timer(0)
{
SetMaxHealth(5);
SetHealth(5);
@@ -69,8 +69,8 @@ void cExpOrb::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
}
HandlePhysics(a_Dt, a_Chunk);
- m_Timer += a_Dt.count();
- if (m_Timer >= 1000 * 60 * 5) // 5 minutes
+ m_Timer += a_Dt;
+ if (m_Timer >= std::chrono::minutes(5))
{
Destroy(true);
}
diff --git a/src/Entities/ExpOrb.h b/src/Entities/ExpOrb.h
index e12e3c504..9aac4f748 100644
--- a/src/Entities/ExpOrb.h
+++ b/src/Entities/ExpOrb.h
@@ -26,10 +26,10 @@ public:
virtual void SpawnOn(cClientHandle & a_Client) override;
/** Returns the number of ticks that this entity has existed */
- int GetAge(void) const { return (int)(m_Timer / 50); } // tolua_export
+ int GetAge(void) const { return std::chrono::duration_cast(m_Timer).count(); } // tolua_export
/** Set the number of ticks that this entity has existed */
- void SetAge(int a_Age) { m_Timer = (float)(a_Age * 50); } // tolua_export
+ void SetAge(int a_Age) { m_Timer = cTickTime(a_Age); } // tolua_export
/** Get the exp amount */
int GetReward(void) const { return m_Reward; } // tolua_export
@@ -41,5 +41,5 @@ protected:
int m_Reward;
/** The number of ticks that the entity has existed / timer between collect and destroy; in msec */
- float m_Timer;
+ std::chrono::milliseconds m_Timer;
} ; // tolua_export
--
cgit v1.2.3
From 8dc9cf0c769b46dd3a97440f76cae4d83b52348e Mon Sep 17 00:00:00 2001
From: Tycho
Date: Fri, 16 Jan 2015 13:42:44 +0000
Subject: Converted MinecartEntity to std::chrono
---
src/Entities/Minecart.cpp | 10 +++++-----
src/Entities/Minecart.h | 6 +++---
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp
index 552d70de7..a906c9767 100644
--- a/src/Entities/Minecart.cpp
+++ b/src/Entities/Minecart.cpp
@@ -165,12 +165,12 @@ void cMinecart::HandlePhysics(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
switch (InsideType)
{
- case E_BLOCK_RAIL: HandleRailPhysics(InsideMeta, a_Dt.count()); break;
+ case E_BLOCK_RAIL: HandleRailPhysics(InsideMeta, a_Dt); break;
case E_BLOCK_ACTIVATOR_RAIL: break;
case E_BLOCK_POWERED_RAIL: HandlePoweredRailPhysics(InsideMeta); break;
case E_BLOCK_DETECTOR_RAIL:
{
- HandleDetectorRailPhysics(InsideMeta, a_Dt.count());
+ HandleDetectorRailPhysics(InsideMeta, a_Dt);
WasDetectorRail = true;
break;
}
@@ -205,7 +205,7 @@ void cMinecart::HandlePhysics(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
-void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt)
+void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, std::chrono::milliseconds a_Dt)
{
/*
NOTE: Please bear in mind that taking away from negatives make them even more negative,
@@ -565,7 +565,7 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta)
-void cMinecart::HandleDetectorRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt)
+void cMinecart::HandleDetectorRailPhysics(NIBBLETYPE a_RailMeta, std::chrono::milliseconds a_Dt)
{
m_World->SetBlockMeta(m_DetectorRailPosition, a_RailMeta | 0x08);
@@ -576,7 +576,7 @@ void cMinecart::HandleDetectorRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt)
-void cMinecart::HandleActivatorRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt)
+void cMinecart::HandleActivatorRailPhysics(NIBBLETYPE a_RailMeta, std::chrono::milliseconds a_Dt)
{
HandleRailPhysics(a_RailMeta & 0x07, a_Dt);
}
diff --git a/src/Entities/Minecart.h b/src/Entities/Minecart.h
index 1c6f4a6c4..898776e71 100644
--- a/src/Entities/Minecart.h
+++ b/src/Entities/Minecart.h
@@ -56,7 +56,7 @@ protected:
/** Handles physics on normal rails
For each tick, slow down on flat rails, speed up or slow down on ascending/descending rails (depending on direction), and turn on curved rails
*/
- void HandleRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt);
+ void HandleRailPhysics(NIBBLETYPE a_RailMeta, std::chrono::milliseconds a_Dt);
/** Handles powered rail physics
Each tick, speed up or slow down cart, depending on metadata of rail (powered or not)
@@ -66,10 +66,10 @@ protected:
/** Handles detector rail activation
Activates detector rails when a minecart is on them. Calls HandleRailPhysics() for physics simulations
*/
- void HandleDetectorRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt);
+ void HandleDetectorRailPhysics(NIBBLETYPE a_RailMeta, std::chrono::milliseconds a_Dt);
/** Handles activator rails - placeholder for future implementation */
- void HandleActivatorRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt);
+ void HandleActivatorRailPhysics(NIBBLETYPE a_RailMeta, std::chrono::milliseconds a_Dt);
/** Snaps a mincecart to a rail's axis, resetting its speed
For curved rails, it changes the cart's direction as well as snapping it to axis */
--
cgit v1.2.3
From 05c40db060809612e6d0bb3bee596c4c95ce758d Mon Sep 17 00:00:00 2001
From: Tycho
Date: Fri, 16 Jan 2015 13:49:22 +0000
Subject: Converted cPickupEntity to std::chrono
---
src/Entities/Pickup.cpp | 18 +++++++++---------
src/Entities/Pickup.h | 6 +++---
2 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/src/Entities/Pickup.cpp b/src/Entities/Pickup.cpp
index accb42a63..9f2609894 100644
--- a/src/Entities/Pickup.cpp
+++ b/src/Entities/Pickup.cpp
@@ -86,7 +86,7 @@ protected:
cPickup::cPickup(double a_PosX, double a_PosY, double a_PosZ, const cItem & a_Item, bool IsPlayerCreated, float a_SpeedX /* = 0.f */, float a_SpeedY /* = 0.f */, float a_SpeedZ /* = 0.f */)
: cEntity(etPickup, a_PosX, a_PosY, a_PosZ, 0.2, 0.2)
- , m_Timer(0.f)
+ , m_Timer(0)
, m_Item(a_Item)
, m_bCollected(false)
, m_bIsPlayerCreated(IsPlayerCreated)
@@ -115,7 +115,7 @@ void cPickup::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
super::Tick(a_Dt, a_Chunk);
BroadcastMovementUpdate(); // Notify clients of position
- m_Timer += a_Dt.count();
+ m_Timer += a_Dt;
if (!m_bCollected)
{
@@ -141,9 +141,9 @@ void cPickup::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
)
{
m_bCollected = true;
- m_Timer = 0; // We have to reset the timer.
- m_Timer += a_Dt.count(); // In case we have to destroy the pickup in the same tick.
- if (m_Timer > 500.f)
+ m_Timer = std::chrono::milliseconds(0); // We have to reset the timer.
+ m_Timer += a_Dt; // In case we have to destroy the pickup in the same tick.
+ if (m_Timer > std::chrono::milliseconds(500))
{
Destroy(true);
return;
@@ -167,14 +167,14 @@ void cPickup::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
}
else
{
- if (m_Timer > 500.f) // 0.5 second
+ if (m_Timer > std::chrono::milliseconds(500)) // 0.5 second
{
Destroy(true);
return;
}
}
- if (m_Timer > 1000 * 60 * 5) // 5 minutes
+ if (m_Timer > std::chrono::minutes(5)) // 5 minutes
{
Destroy(true);
return;
@@ -200,7 +200,7 @@ bool cPickup::CollectedBy(cPlayer & a_Dest)
}
// Two seconds if player created the pickup (vomiting), half a second if anything else
- if (m_Timer < (m_bIsPlayerCreated ? 2000.f : 500.f))
+ if (m_Timer < (m_bIsPlayerCreated ? std::chrono::seconds(2) : std::chrono::milliseconds(500)))
{
// LOG("Pickup %d cannot be collected by \"%s\", because it is not old enough.", m_UniqueID, a_Dest->GetName().c_str());
return false; // Not old enough
@@ -234,7 +234,7 @@ bool cPickup::CollectedBy(cPlayer & a_Dest)
// All of the pickup has been collected, schedule the pickup for destroying
m_bCollected = true;
}
- m_Timer = 0;
+ m_Timer = std::chrono::milliseconds(0);
return true;
}
diff --git a/src/Entities/Pickup.h b/src/Entities/Pickup.h
index 67f2756ca..ed5949f37 100644
--- a/src/Entities/Pickup.h
+++ b/src/Entities/Pickup.h
@@ -37,10 +37,10 @@ public:
virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
/** Returns the number of ticks that this entity has existed */
- int GetAge(void) const { return static_cast(m_Timer / 50); } // tolua_export
+ int GetAge(void) const { return std::chrono::duration_cast(m_Timer).count(); } // tolua_export
/** Set the number of ticks that this entity has existed */
- void SetAge(int a_Age) { m_Timer = static_cast(a_Age * 50); } // tolua_export
+ void SetAge(int a_Age) { m_Timer = cTickTime(a_Age); } // tolua_export
/** Returns true if the pickup has already been collected */
bool IsCollected(void) const { return m_bCollected; } // tolua_export
@@ -51,7 +51,7 @@ public:
private:
/** The number of ticks that the entity has existed / timer between collect and destroy; in msec */
- float m_Timer;
+ std::chrono::milliseconds m_Timer;
cItem m_Item;
--
cgit v1.2.3
From bfe1960191e902013b5ac75e8a3a487496d63bb9 Mon Sep 17 00:00:00 2001
From: Tycho
Date: Fri, 16 Jan 2015 14:38:21 +0000
Subject: Converted Monster to std::chrono
---
src/Mobs/AggressiveMonster.cpp | 2 +-
src/Mobs/AggressiveMonster.h | 2 +-
src/Mobs/Monster.cpp | 22 +++++++++++-----------
src/Mobs/Monster.h | 10 +++++-----
4 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/src/Mobs/AggressiveMonster.cpp b/src/Mobs/AggressiveMonster.cpp
index b9e80c01d..72317d66b 100644
--- a/src/Mobs/AggressiveMonster.cpp
+++ b/src/Mobs/AggressiveMonster.cpp
@@ -22,7 +22,7 @@ cAggressiveMonster::cAggressiveMonster(const AString & a_ConfigName, eMonsterTyp
// What to do if in Chasing State
-void cAggressiveMonster::InStateChasing(float a_Dt)
+void cAggressiveMonster::InStateChasing(std::chrono::milliseconds a_Dt)
{
super::InStateChasing(a_Dt);
diff --git a/src/Mobs/AggressiveMonster.h b/src/Mobs/AggressiveMonster.h
index 932915055..f64c1103f 100644
--- a/src/Mobs/AggressiveMonster.h
+++ b/src/Mobs/AggressiveMonster.h
@@ -17,7 +17,7 @@ public:
cAggressiveMonster(const AString & a_ConfigName, eMonsterType a_MobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height);
virtual void Tick (std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
- virtual void InStateChasing(float a_Dt) override;
+ virtual void InStateChasing(std::chrono::milliseconds a_Dt) override;
virtual void EventSeePlayer(cEntity *) override;
virtual void Attack(std::chrono::milliseconds a_Dt);
diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp
index 30bbd0ff2..6e07bfbb6 100644
--- a/src/Mobs/Monster.cpp
+++ b/src/Mobs/Monster.cpp
@@ -259,8 +259,8 @@ void cMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
if (m_Health <= 0)
{
// The mob is dead, but we're still animating the "puff" they leave when they die
- m_DestroyTimer += a_Dt.count() / 1000;
- if (m_DestroyTimer > 1)
+ m_DestroyTimer += a_Dt;
+ if (m_DestroyTimer > std::chrono::seconds(1))
{
Destroy(true);
}
@@ -345,18 +345,18 @@ void cMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
case IDLE:
{
// If enemy passive we ignore checks for player visibility
- InStateIdle(std::chrono::duration_cast(a_Dt).count());
+ InStateIdle(a_Dt);
break;
}
case CHASING:
{
// If we do not see a player anymore skip chasing action
- InStateChasing(std::chrono::duration_cast(a_Dt).count());
+ InStateChasing(a_Dt);
break;
}
case ESCAPING:
{
- InStateEscaping(std::chrono::duration_cast(a_Dt).count());
+ InStateEscaping(a_Dt);
break;
}
@@ -555,7 +555,7 @@ void cMonster::KilledBy(TakeDamageInfo & a_TDI)
{
m_World->SpawnExperienceOrb(GetPosX(), GetPosY(), GetPosZ(), Reward);
}
- m_DestroyTimer = 0;
+ m_DestroyTimer = std::chrono::milliseconds(0);
}
@@ -638,7 +638,7 @@ void cMonster::EventLosePlayer(void)
-void cMonster::InStateIdle(float a_Dt)
+void cMonster::InStateIdle(std::chrono::milliseconds a_Dt)
{
if (m_bMovingToDestination)
{
@@ -647,11 +647,11 @@ void cMonster::InStateIdle(float a_Dt)
m_IdleInterval += a_Dt;
- if (m_IdleInterval > 1)
+ if (m_IdleInterval > std::chrono::seconds(1))
{
// At this interval the results are predictable
int rem = m_World->GetTickRandomNumber(6) + 1;
- m_IdleInterval -= 1; // So nothing gets dropped when the server hangs for a few seconds
+ m_IdleInterval -= std::chrono::seconds(1); // So nothing gets dropped when the server hangs for a few seconds
Vector3d Dist;
Dist.x = (double)m_World->GetTickRandomNumber(10) - 5;
@@ -678,7 +678,7 @@ void cMonster::InStateIdle(float a_Dt)
// What to do if in Chasing State
// This state should always be defined in each child class
-void cMonster::InStateChasing(float a_Dt)
+void cMonster::InStateChasing(std::chrono::milliseconds a_Dt)
{
UNUSED(a_Dt);
}
@@ -688,7 +688,7 @@ void cMonster::InStateChasing(float a_Dt)
// What to do if in Escaping State
-void cMonster::InStateEscaping(float a_Dt)
+void cMonster::InStateEscaping(std::chrono::milliseconds a_Dt)
{
UNUSED(a_Dt);
diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h
index 5752a2040..21ed0c25a 100644
--- a/src/Mobs/Monster.h
+++ b/src/Mobs/Monster.h
@@ -80,9 +80,9 @@ public:
virtual void EventLosePlayer(void);
virtual void CheckEventLostPlayer(void);
- virtual void InStateIdle (float a_Dt);
- virtual void InStateChasing (float a_Dt);
- virtual void InStateEscaping(float a_Dt);
+ virtual void InStateIdle (std::chrono::milliseconds a_Dt);
+ virtual void InStateChasing (std::chrono::milliseconds a_Dt);
+ virtual void InStateEscaping(std::chrono::milliseconds a_Dt);
int GetAttackRate() { return static_cast(m_AttackRate); }
void SetAttackRate(float a_AttackRate) { m_AttackRate = a_AttackRate; }
@@ -217,8 +217,8 @@ protected:
/* =========================== */
- float m_IdleInterval;
- float m_DestroyTimer;
+ std::chrono::milliseconds m_IdleInterval;
+ std::chrono::milliseconds m_DestroyTimer;
eMonsterType m_MobType;
AString m_CustomName;
--
cgit v1.2.3
From 2ce2741968e861d10acfe1e7b012ec2448accdc7 Mon Sep 17 00:00:00 2001
From: Kirill Kirilenko
Date: Fri, 16 Jan 2015 18:42:19 +0300
Subject: Fixed CppCheck: (performance) Function parameter should be passed by
reference.
---
src/Bindings/PluginManager.cpp | 4 ++--
src/Bindings/PluginManager.h | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp
index fad0a36d2..6fb9a5acb 100644
--- a/src/Bindings/PluginManager.cpp
+++ b/src/Bindings/PluginManager.cpp
@@ -771,7 +771,7 @@ bool cPluginManager::CallHookPlayerFoodLevelChange(cPlayer & a_Player, int a_New
-bool cPluginManager::CallHookPlayerFished(cPlayer & a_Player, const cItems a_Reward)
+bool cPluginManager::CallHookPlayerFished(cPlayer & a_Player, const cItems & a_Reward)
{
FIND_HOOK(HOOK_PLAYER_FISHED);
VERIFY_HOOK;
@@ -847,7 +847,7 @@ bool cPluginManager::CallHookPlayerLeftClick(cPlayer & a_Player, int a_BlockX, i
-bool cPluginManager::CallHookPlayerMoving(cPlayer & a_Player, const Vector3d a_OldPosition, const Vector3d a_NewPosition)
+bool cPluginManager::CallHookPlayerMoving(cPlayer & a_Player, const Vector3d & a_OldPosition, const Vector3d & a_NewPosition)
{
FIND_HOOK(HOOK_PLAYER_MOVING);
VERIFY_HOOK;
diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h
index d4b82376a..576430964 100644
--- a/src/Bindings/PluginManager.h
+++ b/src/Bindings/PluginManager.h
@@ -203,12 +203,12 @@ public:
bool CallHookPlayerBrokenBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
bool CallHookPlayerDestroyed (cPlayer & a_Player);
bool CallHookPlayerEating (cPlayer & a_Player);
- bool CallHookPlayerFished (cPlayer & a_Player, const cItems a_Reward);
+ bool CallHookPlayerFished (cPlayer & a_Player, const cItems & a_Reward);
bool CallHookPlayerFishing (cPlayer & a_Player, cItems a_Reward);
bool CallHookPlayerFoodLevelChange (cPlayer & a_Player, int a_NewFoodLevel);
bool CallHookPlayerJoined (cPlayer & a_Player);
bool CallHookPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status);
- bool CallHookPlayerMoving (cPlayer & a_Player, const Vector3d a_OldPosition, const Vector3d a_NewPosition);
+ bool CallHookPlayerMoving (cPlayer & a_Player, const Vector3d & a_OldPosition, const Vector3d & a_NewPosition);
bool CallHookPlayerPlacedBlock (cPlayer & a_Player, const sSetBlock & a_BlockChange);
bool CallHookPlayerPlacingBlock (cPlayer & a_Player, const sSetBlock & a_BlockChange);
bool CallHookPlayerRightClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ);
--
cgit v1.2.3
From 3dc994f9dca109c0d039d6ba39480eaf67d7cc57 Mon Sep 17 00:00:00 2001
From: Kirill Kirilenko
Date: Sat, 17 Jan 2015 15:12:14 +0300
Subject: Fixed CppCheck: (performance) Possible inefficient checking for
emptiness.
---
src/LightingThread.cpp | 2 +-
src/MobProximityCounter.cpp | 2 +-
src/OSSupport/Queue.h | 4 ++--
src/Server.cpp | 2 +-
4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/LightingThread.cpp b/src/LightingThread.cpp
index ced95d4e1..effde03d0 100644
--- a/src/LightingThread.cpp
+++ b/src/LightingThread.cpp
@@ -197,7 +197,7 @@ void cLightingThread::Execute(void)
{
{
cCSLock Lock(m_CS);
- if (m_Queue.size() == 0)
+ if (m_Queue.empty())
{
cCSUnlock Unlock(Lock);
m_evtItemAdded.Wait();
diff --git a/src/MobProximityCounter.cpp b/src/MobProximityCounter.cpp
index 82ba771ff..cfd52440b 100644
--- a/src/MobProximityCounter.cpp
+++ b/src/MobProximityCounter.cpp
@@ -50,7 +50,7 @@ cMobProximityCounter::sIterablePair cMobProximityCounter::getMobWithinThosesDist
a_DistanceMin *= a_DistanceMin;// this is because is use square distance
a_DistanceMax *= a_DistanceMax;
- if (m_DistanceToMonster.size() <= 0)
+ if (m_DistanceToMonster.empty())
{
convertMaps();
}
diff --git a/src/OSSupport/Queue.h b/src/OSSupport/Queue.h
index 82f221453..afbde1b0d 100644
--- a/src/OSSupport/Queue.h
+++ b/src/OSSupport/Queue.h
@@ -86,7 +86,7 @@ public:
bool TryDequeueItem(ItemType & item)
{
cCSLock Lock(m_CS);
- if (m_Contents.size() == 0)
+ if (m_Contents.empty())
{
return false;
}
@@ -101,7 +101,7 @@ public:
ItemType DequeueItem(void)
{
cCSLock Lock(m_CS);
- while (m_Contents.size() == 0)
+ while (m_Contents.empty())
{
cCSUnlock Unlock(Lock);
m_evtAdded.Wait();
diff --git a/src/Server.cpp b/src/Server.cpp
index 3eaf6e096..4dbe59ac6 100644
--- a/src/Server.cpp
+++ b/src/Server.cpp
@@ -764,7 +764,7 @@ void cServer::cNotifyWriteThread::Execute(void)
while (!m_ShouldTerminate)
{
cCSLock Lock(m_CS);
- while (m_Clients.size() == 0)
+ while (m_Clients.empty())
{
cCSUnlock Unlock(Lock);
m_Event.Wait();
--
cgit v1.2.3
From 41f30edcf77521630b7f69d3e94338e6ab2f821f Mon Sep 17 00:00:00 2001
From: Kirill Kirilenko
Date: Sat, 17 Jan 2015 16:00:12 +0300
Subject: Fixed CppCheck: (performance) Prefer prefix ++/-- operators for
non-primitive types.
---
src/Root.cpp | 2 +-
src/SetChunkData.cpp | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/Root.cpp b/src/Root.cpp
index 8951bafe6..eaacf3608 100644
--- a/src/Root.cpp
+++ b/src/Root.cpp
@@ -639,7 +639,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++)
+ for (WorldMap::iterator itr = m_WorldsByName.begin(); itr != m_WorldsByName.end(); ++itr)
{
if (itr->second->DoWithPlayerByUUID(a_PlayerUUID, a_Callback))
{
diff --git a/src/SetChunkData.cpp b/src/SetChunkData.cpp
index e335176a8..5a0bea980 100644
--- a/src/SetChunkData.cpp
+++ b/src/SetChunkData.cpp
@@ -132,7 +132,7 @@ void cSetChunkData::RemoveInvalidBlockEntities(void)
ItemTypeToString(WorldBlockType).c_str(), WorldBlockType
);
cBlockEntityList::iterator itr2 = itr;
- itr2++;
+ ++itr2;
delete *itr;
m_BlockEntities.erase(itr);
itr = itr2;
--
cgit v1.2.3
From 6758c1d2a15c789e232c8a3f7b51f23b66efd6e1 Mon Sep 17 00:00:00 2001
From: worktycho
Date: Sat, 17 Jan 2015 22:24:25 +0000
Subject: correct comment to say milliseconds
---
src/World.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/World.cpp b/src/World.cpp
index cd99f2c2d..46488d58b 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -869,7 +869,7 @@ void cWorld::Tick(std::chrono::milliseconds a_Dt, std::chrono::milliseconds a_La
if (m_IsDaylightCycleEnabled)
{
- // We need sub-tick precision here, that's why we store the time in seconds and calculate ticks off of it
+ // We need sub-tick precision here, that's why we store the time in milliseconds and calculate ticks off of it
m_TimeOfDay += a_Dt;
// Wrap time of day each 20 minutes (1200 seconds)
--
cgit v1.2.3
From e211aafaa45b0e4a12e9c50ee445377077ea8172 Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Sun, 18 Jan 2015 11:02:17 +0100
Subject: Fixed type-conversion warnings.
---
src/Bindings/LuaState.cpp | 2 +-
src/Entities/Entity.cpp | 8 ++++----
src/Entities/FireworkEntity.cpp | 4 ++--
src/Entities/Minecart.cpp | 2 +-
4 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp
index 4bc9906ee..01d3ac687 100644
--- a/src/Bindings/LuaState.cpp
+++ b/src/Bindings/LuaState.cpp
@@ -843,7 +843,7 @@ void cLuaState::Push(std::chrono::milliseconds a_Value)
{
ASSERT(IsValid());
- tolua_pushnumber(m_LuaState, a_Value.count());
+ tolua_pushnumber(m_LuaState, static_cast(a_Value.count()));
m_NumCurrentFunctionArgs += 1;
}
diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp
index c64d94528..c51a27961 100644
--- a/src/Entities/Entity.cpp
+++ b/src/Entities/Entity.cpp
@@ -927,11 +927,11 @@ void cEntity::HandlePhysics(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
if (!m_bOnGround)
{
- float fallspeed;
+ double fallspeed;
if (IsBlockWater(BlockIn))
{
fallspeed = m_Gravity * DtSec.count() / 3; // Fall 3x slower in water
- ApplyFriction(NextSpeed, 0.7, DtSec.count());
+ ApplyFriction(NextSpeed, 0.7, static_cast(DtSec.count()));
}
else if (BlockIn == E_BLOCK_COBWEB)
{
@@ -943,11 +943,11 @@ void cEntity::HandlePhysics(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
// Normal gravity
fallspeed = m_Gravity * DtSec.count();
}
- NextSpeed.y += fallspeed;
+ NextSpeed.y += static_cast(fallspeed);
}
else
{
- ApplyFriction(NextSpeed, 0.7, DtSec.count());
+ ApplyFriction(NextSpeed, 0.7, static_cast(DtSec.count()));
}
// Adjust X and Z speed for COBWEB temporary. This speed modification should be handled inside block handlers since we
diff --git a/src/Entities/FireworkEntity.cpp b/src/Entities/FireworkEntity.cpp
index 9dc7850a7..32eaf669a 100644
--- a/src/Entities/FireworkEntity.cpp
+++ b/src/Entities/FireworkEntity.cpp
@@ -28,7 +28,7 @@ void cFireworkEntity::HandlePhysics(std::chrono::milliseconds a_Dt, cChunk & a_C
if ((PosY < 0) || (PosY >= cChunkDef::Height))
{
AddSpeedY(1);
- AddPosition(GetSpeed() * (a_Dt.count() / 1000));
+ AddPosition(GetSpeed() * (static_cast(a_Dt.count()) / 1000));
return;
}
@@ -53,7 +53,7 @@ void cFireworkEntity::HandlePhysics(std::chrono::milliseconds a_Dt, cChunk & a_C
}
AddSpeedY(1);
- AddPosition(GetSpeed() * (a_Dt.count() / 1000));
+ AddPosition(GetSpeed() * (static_cast(a_Dt.count()) / 1000));
}
diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp
index a906c9767..776f957f4 100644
--- a/src/Entities/Minecart.cpp
+++ b/src/Entities/Minecart.cpp
@@ -177,7 +177,7 @@ void cMinecart::HandlePhysics(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
default: VERIFY(!"Unhandled rail type despite checking if block was rail!"); break;
}
- AddPosition(GetSpeed() * (a_Dt.count() / 1000)); // Commit changes; as we use our own engine when on rails, this needs to be done, whereas it is normally in Entity.cpp
+ AddPosition(GetSpeed() * (static_cast(a_Dt.count()) / 1000)); // Commit changes; as we use our own engine when on rails, this needs to be done, whereas it is normally in Entity.cpp
}
else
{
--
cgit v1.2.3
From 83ed6a2c1b4da2e4a3467090e56eebb2d3e48a30 Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Sun, 18 Jan 2015 11:25:16 +0100
Subject: Fixed type conversion warnings.
---
src/Simulator/FireSimulator.cpp | 2 +-
src/World.cpp | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/Simulator/FireSimulator.cpp b/src/Simulator/FireSimulator.cpp
index 0439ebdca..8456ed11d 100644
--- a/src/Simulator/FireSimulator.cpp
+++ b/src/Simulator/FireSimulator.cpp
@@ -92,7 +92,7 @@ void cFireSimulator::SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX,
{
cCoordWithIntList & Data = a_Chunk->GetFireSimulatorData();
- int NumMSecs = a_Dt.count();
+ int NumMSecs = static_cast(a_Dt.count());
for (cCoordWithIntList::iterator itr = Data.begin(); itr != Data.end();)
{
int x = itr->x;
diff --git a/src/World.cpp b/src/World.cpp
index 46488d58b..eb76abc2c 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -905,14 +905,14 @@ void cWorld::Tick(std::chrono::milliseconds a_Dt, std::chrono::milliseconds a_La
m_ChunkMap->Tick(a_Dt);
- TickClients(a_Dt.count());
+ TickClients(static_cast(a_Dt.count()));
TickQueuedBlocks();
TickQueuedTasks();
TickScheduledTasks();
- GetSimulatorManager()->Simulate(a_Dt.count());
+ GetSimulatorManager()->Simulate(static_cast(a_Dt.count()));
- TickWeather(a_Dt.count());
+ TickWeather(static_cast(a_Dt.count()));
m_ChunkMap->FastSetQueuedBlocks();
--
cgit v1.2.3
From b1c58b7b5282ac22287be81d7600bc9580cfdf39 Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Sun, 18 Jan 2015 15:10:05 +0100
Subject: cWorld: Fixed a type warning.
---
src/World.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/World.h b/src/World.h
index 1f58ddbb7..e7519dab8 100644
--- a/src/World.h
+++ b/src/World.h
@@ -803,7 +803,7 @@ public:
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)); }
+ int GetTickRandomNumber(int a_Range) { return (int)(m_TickRand.randInt(a_Range)); }
/** Appends all usernames starting with a_Text (case-insensitive) into Results */
void TabCompleteUserName(const AString & a_Text, AStringVector & a_Results);
--
cgit v1.2.3
From 45b1d5ff78e23b3de9cbee1e247e2f275b77e9d9 Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Sun, 18 Jan 2015 18:01:24 +0100
Subject: Fixed various warnings.
---
src/HTTPServer/HTTPMessage.cpp | 2 +-
src/Items/ItemBucket.h | 12 ++++++------
src/OSSupport/StackTrace.cpp | 2 +-
3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/HTTPServer/HTTPMessage.cpp b/src/HTTPServer/HTTPMessage.cpp
index f6c0204ae..d59ca438e 100644
--- a/src/HTTPServer/HTTPMessage.cpp
+++ b/src/HTTPServer/HTTPMessage.cpp
@@ -55,7 +55,7 @@ void cHTTPMessage::AddHeader(const AString & a_Key, const AString & a_Value)
}
else if (Key == "content-length")
{
- m_ContentLength = atoi(m_Headers[Key].c_str());
+ m_ContentLength = static_cast(atol(m_Headers[Key].c_str()));
}
}
diff --git a/src/Items/ItemBucket.h b/src/Items/ItemBucket.h
index 3a533958f..871db821c 100644
--- a/src/Items/ItemBucket.h
+++ b/src/Items/ItemBucket.h
@@ -199,16 +199,16 @@ public:
Vector3i m_Pos;
BLOCKTYPE m_ReplacedBlock;
- virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, char a_EntryFace) override
+ virtual bool OnNextBlock(int a_CBBlockX, int a_CBBlockY, int a_CBBlockZ, BLOCKTYPE a_CBBlockType, NIBBLETYPE a_CBBlockMeta, char a_CBEntryFace) override
{
- if (a_BlockType != E_BLOCK_AIR)
+ if (a_CBBlockType != E_BLOCK_AIR)
{
- m_ReplacedBlock = a_BlockType;
- if (!cFluidSimulator::CanWashAway(a_BlockType) && !IsBlockLiquid(a_BlockType))
+ m_ReplacedBlock = a_CBBlockType;
+ if (!cFluidSimulator::CanWashAway(a_CBBlockType) && !IsBlockLiquid(a_CBBlockType))
{
- AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, (eBlockFace)a_EntryFace); // Was an unwashawayable block, can't overwrite it!
+ AddFaceDirection(a_CBBlockX, a_CBBlockY, a_CBBlockZ, (eBlockFace)a_CBEntryFace); // Was an unwashawayable block, can't overwrite it!
}
- m_Pos.Set(a_BlockX, a_BlockY, a_BlockZ); // (Block could be washed away, replace it)
+ m_Pos.Set(a_CBBlockX, a_CBBlockY, a_CBBlockZ); // (Block could be washed away, replace it)
return true; // Abort tracing
}
return false;
diff --git a/src/OSSupport/StackTrace.cpp b/src/OSSupport/StackTrace.cpp
index a56568457..015a53ba0 100644
--- a/src/OSSupport/StackTrace.cpp
+++ b/src/OSSupport/StackTrace.cpp
@@ -34,7 +34,7 @@ void PrintStackTrace(void)
// 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));
+ int numItems = backtrace(stackTrace, ARRAYCOUNT(stackTrace));
backtrace_symbols_fd(stackTrace, numItems, STDERR_FILENO);
#endif
}
--
cgit v1.2.3
From 5ac3a23586d746eae27fb2375cfd0696d512704b Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Sun, 18 Jan 2015 22:43:35 +0100
Subject: Fixed warnings in 1.7 protocol.
---
src/ClientHandle.cpp | 4 +-
src/ClientHandle.h | 4 +-
src/Protocol/Protocol17x.cpp | 233 +++++++++++++++++++++++--------------------
3 files changed, 131 insertions(+), 110 deletions(-)
diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp
index 6fe6e99fa..387cc4628 100644
--- a/src/ClientHandle.cpp
+++ b/src/ClientHandle.cpp
@@ -1445,7 +1445,7 @@ void cClientHandle::HandlePlayerMoveLook(double a_PosX, double a_PosY, double a_
-void cClientHandle::HandleAnimation(char a_Animation)
+void cClientHandle::HandleAnimation(int a_Animation)
{
if (cPluginManager::Get()->CallHookPlayerAnimation(*m_Player, a_Animation))
{
@@ -2832,7 +2832,7 @@ void cClientHandle::PacketUnknown(UInt32 a_PacketType)
-void cClientHandle::PacketError(unsigned char a_PacketType)
+void cClientHandle::PacketError(UInt32 a_PacketType)
{
LOGERROR("Protocol error while parsing packet type 0x%02x; disconnecting client \"%s\"", a_PacketType, m_Username.c_str());
SendDisconnect("Protocol error");
diff --git a/src/ClientHandle.h b/src/ClientHandle.h
index 5e10bb52f..03ae38cfd 100644
--- a/src/ClientHandle.h
+++ b/src/ClientHandle.h
@@ -251,10 +251,10 @@ public:
// Calls that cProtocol descendants use to report state:
void PacketBufferFull(void);
void PacketUnknown(UInt32 a_PacketType);
- void PacketError(unsigned char a_PacketType);
+ void PacketError(UInt32 a_PacketType);
// Calls that cProtocol descendants use for handling packets:
- void HandleAnimation(char a_Animation);
+ void HandleAnimation(int a_Animation);
/** Called when the protocol receives a MC|ItemName plugin message, indicating that the player named
an item in the anvil UI. */
diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp
index dac1ebde8..169367949 100644
--- a/src/Protocol/Protocol17x.cpp
+++ b/src/Protocol/Protocol17x.cpp
@@ -174,10 +174,10 @@ void cProtocol172::SendBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, cha
cPacketizer Pkt(*this, 0x24); // Block Action packet
Pkt.WriteInt(a_BlockX);
- Pkt.WriteShort(a_BlockY);
+ Pkt.WriteShort(static_cast(a_BlockY));
Pkt.WriteInt(a_BlockZ);
- Pkt.WriteByte(a_Byte1);
- Pkt.WriteByte(a_Byte2);
+ Pkt.WriteByte(static_cast(a_Byte1));
+ Pkt.WriteByte(static_cast(a_Byte2));
Pkt.WriteVarInt(a_BlockType);
}
@@ -190,7 +190,7 @@ void cProtocol172::SendBlockBreakAnim(int a_EntityID, int a_BlockX, int a_BlockY
ASSERT(m_State == 3); // In game mode?
cPacketizer Pkt(*this, 0x25); // Block Break Animation packet
- Pkt.WriteVarInt(a_EntityID);
+ Pkt.WriteVarInt(static_cast(a_EntityID));
Pkt.WriteInt(a_BlockX);
Pkt.WriteInt(a_BlockY);
Pkt.WriteInt(a_BlockZ);
@@ -204,10 +204,11 @@ void cProtocol172::SendBlockBreakAnim(int a_EntityID, int a_BlockX, int a_BlockY
void cProtocol172::SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{
ASSERT(m_State == 3); // In game mode?
+ ASSERT((a_BlockY >= 0) && (a_BlockY < 256));
cPacketizer Pkt(*this, 0x23); // Block Change packet
Pkt.WriteInt(a_BlockX);
- Pkt.WriteByte(a_BlockY);
+ Pkt.WriteByte(static_cast(a_BlockY));
Pkt.WriteInt(a_BlockZ);
Pkt.WriteVarInt(a_BlockType);
Pkt.WriteByte(a_BlockMeta);
@@ -228,8 +229,8 @@ void cProtocol172::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockV
Pkt.WriteInt((int)a_Changes.size() * 4);
for (sSetBlockVector::const_iterator itr = a_Changes.begin(), end = a_Changes.end(); itr != end; ++itr)
{
- unsigned int Coords = itr->m_RelY | (itr->m_RelZ << 8) | (itr->m_RelX << 12);
- unsigned int Blocks = itr->m_BlockMeta | (itr->m_BlockType << 4);
+ int Coords = itr->m_RelY | (itr->m_RelZ << 8) | (itr->m_RelX << 12);
+ int Blocks = static_cast(itr->m_BlockMeta | (itr->m_BlockType << 4));
Pkt.WriteInt((Coords << 16) | Blocks);
} // for itr - a_Changes[]
}
@@ -352,11 +353,13 @@ void cProtocol172::SendEditSign(int a_BlockX, int a_BlockY, int a_BlockZ)
void cProtocol172::SendEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration)
{
ASSERT(m_State == 3); // In game mode?
+ ASSERT((a_EffectID >= 0) && (a_EffectID < 256));
+ ASSERT((a_Amplifier >= 0) && (a_Amplifier < 256));
cPacketizer Pkt(*this, 0x1D); // Entity Effect packet
Pkt.WriteInt(a_Entity.GetUniqueID());
- Pkt.WriteByte(a_EffectID);
- Pkt.WriteByte(a_Amplifier);
+ Pkt.WriteByte(static_cast(a_EffectID));
+ Pkt.WriteByte(static_cast(a_Amplifier));
Pkt.WriteShort(a_Duration);
}
@@ -438,9 +441,9 @@ void cProtocol172::SendEntityRelMove(const cEntity & a_Entity, char a_RelX, char
cPacketizer Pkt(*this, 0x15); // Entity Relative Move packet
Pkt.WriteInt(a_Entity.GetUniqueID());
- Pkt.WriteByte(a_RelX);
- Pkt.WriteByte(a_RelY);
- Pkt.WriteByte(a_RelZ);
+ Pkt.WriteChar(a_RelX);
+ Pkt.WriteChar(a_RelY);
+ Pkt.WriteChar(a_RelZ);
}
@@ -453,9 +456,9 @@ void cProtocol172::SendEntityRelMoveLook(const cEntity & a_Entity, char a_RelX,
cPacketizer Pkt(*this, 0x17); // Entity Look And Relative Move packet
Pkt.WriteInt(a_Entity.GetUniqueID());
- Pkt.WriteByte(a_RelX);
- Pkt.WriteByte(a_RelY);
- Pkt.WriteByte(a_RelZ);
+ Pkt.WriteChar(a_RelX);
+ Pkt.WriteChar(a_RelY);
+ Pkt.WriteChar(a_RelZ);
Pkt.WriteByteAngle(a_Entity.GetYaw());
Pkt.WriteByteAngle(a_Entity.GetPitch());
}
@@ -537,9 +540,9 @@ void cProtocol172::SendHealth(void)
cPacketizer Pkt(*this, 0x06); // Update Health packet
cPlayer * Player = m_Client->GetPlayer();
- Pkt.WriteFloat((float)Player->GetHealth());
- Pkt.WriteShort(Player->GetFoodLevel());
- Pkt.WriteFloat((float)Player->GetFoodSaturationLevel());
+ Pkt.WriteFloat(static_cast(Player->GetHealth()));
+ Pkt.WriteShort(static_cast(Player->GetFoodLevel()));
+ Pkt.WriteFloat(static_cast(Player->GetFoodSaturationLevel()));
}
@@ -584,10 +587,10 @@ void cProtocol172::SendLogin(const cPlayer & a_Player, const cWorld & a_World)
cServer * Server = cRoot::Get()->GetServer();
cPacketizer Pkt(*this, 0x01); // Join Game packet
Pkt.WriteInt(a_Player.GetUniqueID());
- Pkt.WriteByte((Byte)a_Player.GetEffectiveGameMode() | (Server->IsHardcore() ? 0x08 : 0)); // Hardcore flag bit 4
- Pkt.WriteChar((char)a_World.GetDimension());
+ Pkt.WriteByte(static_cast(a_Player.GetEffectiveGameMode()) | (Server->IsHardcore() ? 0x08 : 0)); // Hardcore flag bit 4
+ Pkt.WriteChar(static_cast(a_World.GetDimension()));
Pkt.WriteByte(2); // TODO: Difficulty (set to Normal)
- Pkt.WriteByte(std::min(Server->GetMaxPlayers(), 60));
+ Pkt.WriteByte(static_cast(std::min(Server->GetMaxPlayers(), 60)));
Pkt.WriteString("default"); // Level type - wtf?
}
m_LastSentDimension = a_World.GetDimension();
@@ -595,9 +598,9 @@ void cProtocol172::SendLogin(const cPlayer & a_Player, const cWorld & a_World)
// Send the spawn position:
{
cPacketizer Pkt(*this, 0x05); // Spawn Position packet
- Pkt.WriteInt((int)a_World.GetSpawnX());
- Pkt.WriteInt((int)a_World.GetSpawnY());
- Pkt.WriteInt((int)a_World.GetSpawnZ());
+ Pkt.WriteInt(static_cast(a_World.GetSpawnX()));
+ Pkt.WriteInt(static_cast(a_World.GetSpawnY()));
+ Pkt.WriteInt(static_cast(a_World.GetSpawnZ()));
}
// Send player abilities:
@@ -629,11 +632,11 @@ void cProtocol172::SendPaintingSpawn(const cPainting & a_Painting)
ASSERT(m_State == 3); // In game mode?
cPacketizer Pkt(*this, 0x10); // Spawn Painting packet
- Pkt.WriteVarInt(a_Painting.GetUniqueID());
+ Pkt.WriteVarInt(static_cast(a_Painting.GetUniqueID()));
Pkt.WriteString(a_Painting.GetName().c_str());
- Pkt.WriteInt((int)a_Painting.GetPosX());
- Pkt.WriteInt((int)a_Painting.GetPosY());
- Pkt.WriteInt((int)a_Painting.GetPosZ());
+ Pkt.WriteInt(static_cast(a_Painting.GetPosX()));
+ Pkt.WriteInt(static_cast(a_Painting.GetPosY()));
+ Pkt.WriteInt(static_cast(a_Painting.GetPosZ()));
Pkt.WriteInt(a_Painting.GetDirection());
}
@@ -644,19 +647,19 @@ void cProtocol172::SendPaintingSpawn(const cPainting & a_Painting)
void cProtocol172::SendMapColumn(int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length, unsigned int m_Scale)
{
ASSERT(m_State == 3); // In game mode?
+ ASSERT(a_Length + 3 <= USHRT_MAX);
+ ASSERT((a_X >= 0) && (a_X < 256));
+ ASSERT((a_Y >= 0) && (a_Y < 256));
cPacketizer Pkt(*this, 0x34);
- Pkt.WriteVarInt(a_ID);
- Pkt.WriteShort (3 + a_Length);
+ Pkt.WriteVarInt(static_cast(a_ID));
+ Pkt.WriteShort (static_cast(3 + a_Length));
Pkt.WriteByte(0);
- Pkt.WriteByte(a_X);
- Pkt.WriteByte(a_Y);
+ Pkt.WriteByte(static_cast(a_X));
+ Pkt.WriteByte(static_cast(a_Y));
- for (unsigned int i = 0; i < a_Length; ++i)
- {
- Pkt.WriteByte(a_Colors[i]);
- }
+ Pkt.WriteBuf(reinterpret_cast(a_Colors), a_Length);
}
@@ -666,18 +669,21 @@ void cProtocol172::SendMapColumn(int a_ID, int a_X, int a_Y, const Byte * a_Colo
void cProtocol172::SendMapDecorators(int a_ID, const cMapDecoratorList & a_Decorators, unsigned int m_Scale)
{
ASSERT(m_State == 3); // In game mode?
+ ASSERT(1 + 3 * a_Decorators.size() < USHRT_MAX);
cPacketizer Pkt(*this, 0x34);
- Pkt.WriteVarInt(a_ID);
- Pkt.WriteShort ((short)(1 + (3 * a_Decorators.size())));
+ Pkt.WriteVarInt(static_cast(a_ID));
+ Pkt.WriteShort (static_cast(1 + (3 * a_Decorators.size())));
Pkt.WriteByte(1);
for (cMapDecoratorList::const_iterator it = a_Decorators.begin(); it != a_Decorators.end(); ++it)
{
- Pkt.WriteByte((it->GetType() << 4) | (it->GetRot() & 0xf));
- Pkt.WriteByte(it->GetPixelX());
- Pkt.WriteByte(it->GetPixelZ());
+ ASSERT((it->GetPixelX() >= 0) && (it->GetPixelX() < 256));
+ ASSERT((it->GetPixelZ() >= 0) && (it->GetPixelZ() < 256));
+ Pkt.WriteByte(static_cast((it->GetType() << 4) | static_cast(it->GetRot() & 0xf)));
+ Pkt.WriteByte(static_cast(it->GetPixelX()));
+ Pkt.WriteByte(static_cast(it->GetPixelZ()));
}
}
@@ -688,13 +694,14 @@ void cProtocol172::SendMapDecorators(int a_ID, const cMapDecoratorList & a_Decor
void cProtocol172::SendMapInfo(int a_ID, unsigned int a_Scale)
{
ASSERT(m_State == 3); // In game mode?
+ ASSERT((a_Scale >= 0) && (a_Scale < 256));
cPacketizer Pkt(*this, 0x34);
- Pkt.WriteVarInt(a_ID);
+ Pkt.WriteVarInt(static_cast(a_ID));
Pkt.WriteShort (2);
Pkt.WriteByte(2);
- Pkt.WriteByte(a_Scale);
+ Pkt.WriteByte(static_cast(a_Scale));
}
@@ -707,7 +714,7 @@ void cProtocol172::SendPickupSpawn(const cPickup & a_Pickup)
{
cPacketizer Pkt(*this, 0x0e); // Spawn Object packet
- Pkt.WriteVarInt(a_Pickup.GetUniqueID());
+ Pkt.WriteVarInt(static_cast(a_Pickup.GetUniqueID()));
Pkt.WriteByte(2); // Type = Pickup
Pkt.WriteFPInt(a_Pickup.GetPosX());
Pkt.WriteFPInt(a_Pickup.GetPosY());
@@ -763,7 +770,7 @@ void cProtocol172::SendEntityAnimation(const cEntity & a_Entity, char a_Animatio
ASSERT(m_State == 3); // In game mode?
cPacketizer Pkt(*this, 0x0b); // Animation packet
- Pkt.WriteVarInt(a_Entity.GetUniqueID());
+ Pkt.WriteVarInt(static_cast(a_Entity.GetUniqueID()));
Pkt.WriteChar(a_Animation);
}
@@ -865,7 +872,7 @@ void cProtocol172::SendPlayerMaxSpeed(void)
{
Pkt.WriteShort(1); // Modifier count
Pkt.WriteInt64(0x662a6b8dda3e4c1c);
- Pkt.WriteInt64(0x881396ea6097278d); // UUID of the modifier
+ Pkt.WriteInt64(static_cast(0x881396ea6097278d)); // UUID of the modifier
Pkt.WriteDouble(Player->GetSprintingMaxSpeed() - Player->GetNormalMaxSpeed());
Pkt.WriteByte(2);
}
@@ -960,10 +967,11 @@ void cProtocol172::SendPluginMessage(const AString & a_Channel, const AString &
void cProtocol172::SendRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID)
{
ASSERT(m_State == 3); // In game mode?
+ ASSERT((a_EffectID >= 0) && (a_EffectID < 256));
cPacketizer Pkt(*this, 0x1e);
Pkt.WriteInt(a_Entity.GetUniqueID());
- Pkt.WriteByte(a_EffectID);
+ Pkt.WriteByte(static_cast(a_EffectID));
}
@@ -1009,13 +1017,14 @@ void cProtocol172::SendExperience (void)
void cProtocol172::SendExperienceOrb(const cExpOrb & a_ExpOrb)
{
ASSERT(m_State == 3); // In game mode?
+ ASSERT((a_ExpOrb.GetReward() >= 0) && (a_ExpOrb.GetReward() < SHRT_MAX));
cPacketizer Pkt(*this, 0x11);
- Pkt.WriteVarInt(a_ExpOrb.GetUniqueID());
+ Pkt.WriteVarInt(static_cast(a_ExpOrb.GetUniqueID()));
Pkt.WriteFPInt(a_ExpOrb.GetPosX());
Pkt.WriteFPInt(a_ExpOrb.GetPosY());
Pkt.WriteFPInt(a_ExpOrb.GetPosZ());
- Pkt.WriteShort(a_ExpOrb.GetReward());
+ Pkt.WriteShort(static_cast(a_ExpOrb.GetReward()));
}
@@ -1060,7 +1069,7 @@ void cProtocol172::SendDisplayObjective(const AString & a_Objective, cScoreboard
ASSERT(m_State == 3); // In game mode?
cPacketizer Pkt(*this, 0x3d);
- Pkt.WriteByte((int) a_Display);
+ Pkt.WriteByte(static_cast(a_Display));
Pkt.WriteString(a_Objective);
}
@@ -1074,11 +1083,11 @@ void cProtocol172::SendSoundEffect(const AString & a_SoundName, double a_X, doub
cPacketizer Pkt(*this, 0x29); // Sound Effect packet
Pkt.WriteString(a_SoundName);
- Pkt.WriteInt((int)(a_X * 8.0));
- Pkt.WriteInt((int)(a_Y * 8.0));
- Pkt.WriteInt((int)(a_Z * 8.0));
+ Pkt.WriteInt(static_cast(a_X * 8.0));
+ Pkt.WriteInt(static_cast(a_Y * 8.0));
+ Pkt.WriteInt(static_cast(a_Z * 8.0));
Pkt.WriteFloat(a_Volume);
- Pkt.WriteByte((Byte)(a_Pitch * 63));
+ Pkt.WriteByte(static_cast(a_Pitch * 63));
}
@@ -1088,11 +1097,12 @@ void cProtocol172::SendSoundEffect(const AString & a_SoundName, double a_X, doub
void cProtocol172::SendSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data)
{
ASSERT(m_State == 3); // In game mode?
+ ASSERT((a_SrcY >= 0) && (a_SrcY < 256));
cPacketizer Pkt(*this, 0x28); // Effect packet
Pkt.WriteInt(a_EffectID);
Pkt.WriteInt(a_SrcX);
- Pkt.WriteByte(a_SrcY);
+ Pkt.WriteByte(static_cast(a_SrcY));
Pkt.WriteInt(a_SrcZ);
Pkt.WriteInt(a_Data);
Pkt.WriteBool(false);
@@ -1107,17 +1117,17 @@ void cProtocol172::SendSpawnFallingBlock(const cFallingBlock & a_FallingBlock)
ASSERT(m_State == 3); // In game mode?
cPacketizer Pkt(*this, 0x0e); // Spawn Object packet
- Pkt.WriteVarInt(a_FallingBlock.GetUniqueID());
+ Pkt.WriteVarInt(static_cast(a_FallingBlock.GetUniqueID()));
Pkt.WriteByte(70); // Falling block
Pkt.WriteFPInt(a_FallingBlock.GetPosX());
Pkt.WriteFPInt(a_FallingBlock.GetPosY());
Pkt.WriteFPInt(a_FallingBlock.GetPosZ());
Pkt.WriteByteAngle(a_FallingBlock.GetYaw());
Pkt.WriteByteAngle(a_FallingBlock.GetPitch());
- Pkt.WriteInt(((int)a_FallingBlock.GetBlockType()) | (((int)a_FallingBlock.GetBlockMeta()) << 16)); // Or 0x10
- Pkt.WriteShort((short)(a_FallingBlock.GetSpeedX() * 400));
- Pkt.WriteShort((short)(a_FallingBlock.GetSpeedY() * 400));
- Pkt.WriteShort((short)(a_FallingBlock.GetSpeedZ() * 400));
+ Pkt.WriteInt((static_cast(a_FallingBlock.GetBlockType()) | ((static_cast(a_FallingBlock.GetBlockMeta()) << 16))));
+ Pkt.WriteShort(static_cast(a_FallingBlock.GetSpeedX() * 400));
+ Pkt.WriteShort(static_cast(a_FallingBlock.GetSpeedY() * 400));
+ Pkt.WriteShort(static_cast(a_FallingBlock.GetSpeedZ() * 400));
}
@@ -1129,7 +1139,7 @@ void cProtocol172::SendSpawnMob(const cMonster & a_Mob)
ASSERT(m_State == 3); // In game mode?
cPacketizer Pkt(*this, 0x0f); // Spawn Mob packet
- Pkt.WriteVarInt(a_Mob.GetUniqueID());
+ Pkt.WriteVarInt(static_cast(a_Mob.GetUniqueID()));
Pkt.WriteByte((Byte)a_Mob.GetMobType());
Pkt.WriteFPInt(a_Mob.GetPosX());
Pkt.WriteFPInt(a_Mob.GetPosY());
@@ -1137,9 +1147,9 @@ void cProtocol172::SendSpawnMob(const cMonster & a_Mob)
Pkt.WriteByteAngle(a_Mob.GetPitch());
Pkt.WriteByteAngle(a_Mob.GetHeadYaw());
Pkt.WriteByteAngle(a_Mob.GetYaw());
- Pkt.WriteShort((short)(a_Mob.GetSpeedX() * 400));
- Pkt.WriteShort((short)(a_Mob.GetSpeedY() * 400));
- Pkt.WriteShort((short)(a_Mob.GetSpeedZ() * 400));
+ Pkt.WriteShort(static_cast(a_Mob.GetSpeedX() * 400));
+ Pkt.WriteShort(static_cast(a_Mob.GetSpeedY() * 400));
+ Pkt.WriteShort(static_cast(a_Mob.GetSpeedZ() * 400));
Pkt.WriteEntityMetadata(a_Mob);
Pkt.WriteByte(0x7f); // Metadata terminator
}
@@ -1153,8 +1163,8 @@ void cProtocol172::SendSpawnObject(const cEntity & a_Entity, char a_ObjectType,
ASSERT(m_State == 3); // In game mode?
cPacketizer Pkt(*this, 0xe); // Spawn Object packet
- Pkt.WriteVarInt(a_Entity.GetUniqueID());
- Pkt.WriteByte(a_ObjectType);
+ Pkt.WriteVarInt(static_cast(a_Entity.GetUniqueID()));
+ Pkt.WriteChar(a_ObjectType);
Pkt.WriteFPInt(a_Entity.GetPosX());
Pkt.WriteFPInt(a_Entity.GetPosY());
Pkt.WriteFPInt(a_Entity.GetPosZ());
@@ -1163,9 +1173,9 @@ void cProtocol172::SendSpawnObject(const cEntity & a_Entity, char a_ObjectType,
Pkt.WriteInt(a_ObjectData);
if (a_ObjectData != 0)
{
- Pkt.WriteShort((short)(a_Entity.GetSpeedX() * 400));
- Pkt.WriteShort((short)(a_Entity.GetSpeedY() * 400));
- Pkt.WriteShort((short)(a_Entity.GetSpeedZ() * 400));
+ Pkt.WriteShort(static_cast(a_Entity.GetSpeedX() * 400));
+ Pkt.WriteShort(static_cast(a_Entity.GetSpeedY() * 400));
+ Pkt.WriteShort(static_cast(a_Entity.GetSpeedZ() * 400));
}
}
@@ -1178,8 +1188,8 @@ void cProtocol172::SendSpawnVehicle(const cEntity & a_Vehicle, char a_VehicleTyp
ASSERT(m_State == 3); // In game mode?
cPacketizer Pkt(*this, 0xe); // Spawn Object packet
- Pkt.WriteVarInt(a_Vehicle.GetUniqueID());
- Pkt.WriteByte(a_VehicleType);
+ Pkt.WriteVarInt(static_cast(a_Vehicle.GetUniqueID()));
+ Pkt.WriteChar(a_VehicleType);
Pkt.WriteFPInt(a_Vehicle.GetPosX());
Pkt.WriteFPInt(a_Vehicle.GetPosY());
Pkt.WriteFPInt(a_Vehicle.GetPosZ());
@@ -1188,9 +1198,9 @@ void cProtocol172::SendSpawnVehicle(const cEntity & a_Vehicle, char a_VehicleTyp
Pkt.WriteInt(a_VehicleSubType);
if (a_VehicleSubType != 0)
{
- Pkt.WriteShort((short)(a_Vehicle.GetSpeedX() * 400));
- Pkt.WriteShort((short)(a_Vehicle.GetSpeedY() * 400));
- Pkt.WriteShort((short)(a_Vehicle.GetSpeedZ() * 400));
+ Pkt.WriteShort(static_cast(a_Vehicle.GetSpeedX() * 400));
+ Pkt.WriteShort(static_cast(a_Vehicle.GetSpeedY() * 400));
+ Pkt.WriteShort(static_cast(a_Vehicle.GetSpeedZ() * 400));
}
}
@@ -1211,7 +1221,7 @@ void cProtocol172::SendStatistics(const cStatManager & a_Manager)
const AString & StatName = cStatInfo::GetName((eStatistic) i);
Pkt.WriteString(StatName);
- Pkt.WriteVarInt(Value);
+ Pkt.WriteVarInt(static_cast(Value));
}
}
@@ -1224,7 +1234,7 @@ void cProtocol172::SendTabCompletionResults(const AStringVector & a_Results)
ASSERT(m_State == 3); // In game mode?
cPacketizer Pkt(*this, 0x3a); // Tab-Complete packet
- Pkt.WriteVarInt((int)a_Results.size());
+ Pkt.WriteVarInt(static_cast(a_Results.size()));
for (AStringVector::const_iterator itr = a_Results.begin(), end = a_Results.end(); itr != end; ++itr)
{
@@ -1309,7 +1319,7 @@ void cProtocol172::SendUpdateBlockEntity(cBlockEntity & a_BlockEntity)
cPacketizer Pkt(*this, 0x35); // Update tile entity packet
Pkt.WriteInt(a_BlockEntity.GetPosX());
- Pkt.WriteShort(a_BlockEntity.GetPosY());
+ Pkt.WriteShort(static_cast(a_BlockEntity.GetPosY()));
Pkt.WriteInt(a_BlockEntity.GetPosZ());
Byte Action = 0;
@@ -1389,7 +1399,7 @@ void cProtocol172::SendWholeInventory(const cWindow & a_Window)
cPacketizer Pkt(*this, 0x30); // Window Items packet
Pkt.WriteChar(a_Window.GetWindowID());
- Pkt.WriteShort(a_Window.GetNumSlots());
+ Pkt.WriteShort(static_cast(a_Window.GetNumSlots()));
cItems Slots;
a_Window.GetSlots(*(m_Client->GetPlayer()), Slots);
for (cItems::const_iterator itr = Slots.begin(), end = Slots.end(); itr != end; ++itr)
@@ -1426,9 +1436,9 @@ void cProtocol172::SendWindowOpen(const cWindow & a_Window)
cPacketizer Pkt(*this, 0x2d);
Pkt.WriteChar(a_Window.GetWindowID());
- Pkt.WriteChar(a_Window.GetWindowType());
+ Pkt.WriteChar(static_cast(a_Window.GetWindowType()));
Pkt.WriteString(a_Window.GetWindowTitle());
- Pkt.WriteChar(a_Window.GetNumNonInventorySlots());
+ Pkt.WriteChar(static_cast(a_Window.GetNumNonInventorySlots()));
Pkt.WriteBool(true);
if (a_Window.GetWindowType() == cWindow::wtAnimalChest)
{
@@ -1505,7 +1515,7 @@ void cProtocol172::AddReceivedData(const char * a_Data, size_t a_Size)
break;
}
cByteBuffer bb(PacketLen + 1);
- VERIFY(m_ReceivedData.ReadToByteBuffer(bb, (int)PacketLen));
+ VERIFY(m_ReceivedData.ReadToByteBuffer(bb, static_cast(PacketLen)));
m_ReceivedData.CommitRead();
UInt32 PacketType;
@@ -1748,8 +1758,14 @@ void cProtocol172::HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffe
{
short EncKeyLength, EncNonceLength;
a_ByteBuffer.ReadBEShort(EncKeyLength);
+ if ((EncKeyLength < 0) || (EncKeyLength > MAX_ENC_LEN))
+ {
+ LOGD("Invalid Encryption Key length: %d. Kicking client.", EncKeyLength);
+ m_Client->Kick("Invalid EncKeyLength");
+ return;
+ }
AString EncKey;
- if (!a_ByteBuffer.ReadString(EncKey, EncKeyLength))
+ if (!a_ByteBuffer.ReadString(EncKey, static_cast(EncKeyLength)))
{
return;
}
@@ -1757,15 +1773,15 @@ void cProtocol172::HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffe
{
return;
}
- AString EncNonce;
- if (!a_ByteBuffer.ReadString(EncNonce, EncNonceLength))
+ if ((EncNonceLength < 0) || (EncNonceLength > MAX_ENC_LEN))
{
+ LOGD("Invalid Encryption Nonce length: %d. Kicking client.", EncNonceLength);
+ m_Client->Kick("Invalid EncNonceLength");
return;
}
- if ((EncKeyLength > MAX_ENC_LEN) || (EncNonceLength > MAX_ENC_LEN))
+ AString EncNonce;
+ if (!a_ByteBuffer.ReadString(EncNonce, static_cast(EncNonceLength)))
{
- LOGD("Too long encryption");
- m_Client->Kick("Hacked client");
return;
}
@@ -1854,7 +1870,7 @@ void cProtocol172::HandlePacketAnimation(cByteBuffer & a_ByteBuffer)
void cProtocol172::HandlePacketBlockDig(cByteBuffer & a_ByteBuffer)
{
- HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Status);
+ HANDLE_READ(a_ByteBuffer, ReadChar, char, Status);
HANDLE_READ(a_ByteBuffer, ReadBEInt, int, BlockX);
HANDLE_READ(a_ByteBuffer, ReadByte, Byte, BlockY);
HANDLE_READ(a_ByteBuffer, ReadBEInt, int, BlockZ);
@@ -2072,7 +2088,7 @@ void cProtocol172::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer)
if (Length + 1 != (int)a_ByteBuffer.GetReadableSpace())
{
LOGD("Invalid plugin message packet, payload length doesn't match packet length (exp %d, got %d)",
- (int)a_ByteBuffer.GetReadableSpace() - 1, Length
+ static_cast(a_ByteBuffer.GetReadableSpace()) - 1, Length
);
return;
}
@@ -2086,7 +2102,7 @@ void cProtocol172::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer)
// Read the plugin message and relay to clienthandle:
AString Data;
- if (!a_ByteBuffer.ReadString(Data, Length))
+ if (!a_ByteBuffer.ReadString(Data, static_cast(Length)))
{
return;
}
@@ -2274,7 +2290,7 @@ void cProtocol172::HandleVanillaPluginMessage(cByteBuffer & a_ByteBuffer, const
LOGD("Protocol 1.7: Skipping garbage data at the end of a vanilla MC|AdvCdm packet, %u bytes",
static_cast(a_PayloadLength - BytesRead)
);
- a_ByteBuffer.SkipRead(a_PayloadLength - BytesRead);
+ a_ByteBuffer.SkipRead(static_cast(a_PayloadLength) - BytesRead);
}
return;
}
@@ -2282,7 +2298,7 @@ void cProtocol172::HandleVanillaPluginMessage(cByteBuffer & a_ByteBuffer, const
{
// Read the client's brand:
AString Brand;
- if (a_ByteBuffer.ReadString(Brand, a_PayloadLength))
+ if (a_ByteBuffer.ReadString(Brand, static_cast(a_PayloadLength)))
{
m_Client->SetClientBrand(Brand);
}
@@ -2301,7 +2317,7 @@ void cProtocol172::HandleVanillaPluginMessage(cByteBuffer & a_ByteBuffer, const
else if (a_Channel == "MC|ItemName")
{
AString ItemName;
- if (a_ByteBuffer.ReadString(ItemName, a_PayloadLength))
+ if (a_ByteBuffer.ReadString(ItemName, static_cast(a_PayloadLength)))
{
m_Client->HandleAnvilItemName(ItemName);
}
@@ -2317,7 +2333,7 @@ void cProtocol172::HandleVanillaPluginMessage(cByteBuffer & a_ByteBuffer, const
// Read the payload and send it through to the clienthandle:
AString Message;
- VERIFY(a_ByteBuffer.ReadString(Message, a_PayloadLength));
+ VERIFY(a_ByteBuffer.ReadString(Message, static_cast(a_PayloadLength)));
m_Client->HandlePluginMessage(a_Channel, Message);
}
@@ -2377,7 +2393,7 @@ bool cProtocol172::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item)
// Read the metadata
AString Metadata;
- if (!a_ByteBuffer.ReadString(Metadata, MetadataLength))
+ if (!a_ByteBuffer.ReadString(Metadata, static_cast(MetadataLength)))
{
return false;
}
@@ -2546,7 +2562,7 @@ void cProtocol172::cPacketizer::WriteItem(const cItem & a_Item)
}
WriteShort(ItemType);
- WriteByte (a_Item.m_ItemCount);
+ WriteChar (a_Item.m_ItemCount);
WriteShort(a_Item.m_ItemDamage);
if (a_Item.m_Enchantments.IsEmpty() && a_Item.IsBothNameAndLoreEmpty() && (a_Item.m_ItemType != E_ITEM_FIREWORK_ROCKET) && (a_Item.m_ItemType != E_ITEM_FIREWORK_STAR))
@@ -2706,7 +2722,7 @@ void cProtocol172::cPacketizer::WriteBlockEntity(const cBlockEntity & a_BlockEnt
void cProtocol172::cPacketizer::WriteByteAngle(double a_Angle)
{
- WriteByte((char)(255 * a_Angle / 360));
+ WriteChar(static_cast(255 * a_Angle / 360));
}
@@ -2849,7 +2865,7 @@ void cProtocol172::cPacketizer::WriteMobMetadata(const cMonster & a_Mob)
case mtCreeper:
{
WriteByte(0x10);
- WriteByte(((const cCreeper &)a_Mob).IsBlowing() ? 1 : -1);
+ WriteByte(((const cCreeper &)a_Mob).IsBlowing() ? 1 : 0);
WriteByte(0x11);
WriteByte(((const cCreeper &)a_Mob).IsCharged() ? 1 : 0);
break;
@@ -2918,15 +2934,14 @@ void cProtocol172::cPacketizer::WriteMobMetadata(const cMonster & a_Mob)
WriteByte(0x13);
WriteByte(Wolf.IsBegging() ? 1 : 0);
WriteByte(0x14);
- WriteByte(Wolf.GetCollarColor());
+ WriteByte(static_cast(Wolf.GetCollarColor()));
break;
}
case mtSheep:
{
WriteByte(0x10);
- Byte SheepMetadata = 0;
- SheepMetadata = ((const cSheep &)a_Mob).GetFurColor();
+ Byte SheepMetadata = static_cast(((const cSheep &)a_Mob).GetFurColor() & 0x0f);
if (((const cSheep &)a_Mob).IsSheared())
{
SheepMetadata |= 0x10;
@@ -2963,7 +2978,7 @@ void cProtocol172::cPacketizer::WriteMobMetadata(const cMonster & a_Mob)
case mtWither:
{
WriteByte(0x54); // Int at index 20
- WriteInt(((const cWither &)a_Mob).GetWitherInvulnerableTicks());
+ WriteInt(static_cast(((const cWither &)a_Mob).GetWitherInvulnerableTicks()));
WriteByte(0x66); // Float at index 6
WriteFloat((float)(a_Mob.GetHealth()));
break;
@@ -2972,14 +2987,14 @@ void cProtocol172::cPacketizer::WriteMobMetadata(const cMonster & a_Mob)
case mtSlime:
{
WriteByte(0x10);
- WriteByte(((const cSlime &)a_Mob).GetSize());
+ WriteByte(static_cast(((const cSlime &)a_Mob).GetSize()));
break;
}
case mtMagmaCube:
{
WriteByte(0x10);
- WriteByte(((const cMagmaCube &)a_Mob).GetSize());
+ WriteByte(static_cast(((const cMagmaCube &)a_Mob).GetSize()));
break;
}
@@ -3018,7 +3033,7 @@ void cProtocol172::cPacketizer::WriteMobMetadata(const cMonster & a_Mob)
WriteByte(0x50); // Int at index 16
WriteInt(Flags);
WriteByte(0x13); // Byte at index 19
- WriteByte(Horse.GetHorseType());
+ WriteByte(static_cast(Horse.GetHorseType()));
WriteByte(0x54); // Int at index 20
int Appearance = 0;
Appearance = Horse.GetHorseColor();
@@ -3028,6 +3043,12 @@ void cProtocol172::cPacketizer::WriteMobMetadata(const cMonster & a_Mob)
WriteInt(Horse.GetHorseArmour());
break;
}
+
+ default:
+ {
+ // No data to send for this mob
+ break;
+ }
} // switch (a_Mob.GetType())
// Custom name:
@@ -3080,7 +3101,7 @@ void cProtocol176::SendPlayerSpawn(const cPlayer & a_Player)
{
// Called to spawn another player for the client
cPacketizer Pkt(*this, 0x0c); // Spawn Player packet
- Pkt.WriteVarInt(a_Player.GetUniqueID());
+ Pkt.WriteVarInt(static_cast(a_Player.GetUniqueID()));
Pkt.WriteString(cMojangAPI::MakeUUIDDashed(a_Player.GetClientHandle()->GetUUID()));
if (a_Player.HasCustomName())
{
--
cgit v1.2.3
From 2df8e4863f2047862700c0f3096c03859caff2d9 Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Tue, 20 Jan 2015 23:52:53 +0100
Subject: Fixed warnings in FastNBT.cpp.
---
src/WorldStorage/FastNBT.cpp | 79 ++++++++++++++++++++++----------------------
1 file changed, 40 insertions(+), 39 deletions(-)
diff --git a/src/WorldStorage/FastNBT.cpp b/src/WorldStorage/FastNBT.cpp
index aaef2fdfe..033a07601 100644
--- a/src/WorldStorage/FastNBT.cpp
+++ b/src/WorldStorage/FastNBT.cpp
@@ -109,7 +109,7 @@ bool cParsedNBT::ReadCompound(void)
ASSERT(m_Tags.size() > 0);
// Reads the latest tag as a compound
- int ParentIdx = (int)m_Tags.size() - 1;
+ size_t ParentIdx = m_Tags.size() - 1;
int PrevSibling = -1;
for (;;)
{
@@ -120,10 +120,10 @@ bool cParsedNBT::ReadCompound(void)
{
break;
}
- m_Tags.push_back(cFastNBTTag(TagType, ParentIdx, PrevSibling));
+ m_Tags.push_back(cFastNBTTag(TagType, static_cast(ParentIdx), PrevSibling));
if (PrevSibling >= 0)
{
- m_Tags[PrevSibling].m_NextSibling = (int)m_Tags.size() - 1;
+ m_Tags[static_cast(PrevSibling)].m_NextSibling = (int)m_Tags.size() - 1;
}
else
{
@@ -155,20 +155,21 @@ bool cParsedNBT::ReadList(eTagType a_ChildrenType)
}
// Read items:
- int ParentIdx = (int)m_Tags.size() - 1;
+ ASSERT(m_Tags.size() > 0);
+ size_t ParentIdx = m_Tags.size() - 1;
int PrevSibling = -1;
for (int i = 0; i < Count; i++)
{
- m_Tags.push_back(cFastNBTTag(a_ChildrenType, ParentIdx, PrevSibling));
+ m_Tags.push_back(cFastNBTTag(a_ChildrenType, static_cast(ParentIdx), PrevSibling));
if (PrevSibling >= 0)
{
- m_Tags[PrevSibling].m_NextSibling = (int)m_Tags.size() - 1;
+ m_Tags[static_cast(PrevSibling)].m_NextSibling = static_cast(m_Tags.size()) - 1;
}
else
{
- m_Tags[ParentIdx].m_FirstChild = (int)m_Tags.size() - 1;
+ m_Tags[ParentIdx].m_FirstChild = static_cast(m_Tags.size()) - 1;
}
- PrevSibling = (int)m_Tags.size() - 1;
+ PrevSibling = static_cast(m_Tags.size()) - 1;
RETURN_FALSE_IF_FALSE(ReadTag());
} // for (i)
m_Tags[ParentIdx].m_LastChild = PrevSibling;
@@ -217,16 +218,16 @@ bool cParsedNBT::ReadTag(void)
return false;
}
NEEDBYTES(len);
- Tag.m_DataLength = len;
+ Tag.m_DataLength = static_cast(len);
Tag.m_DataStart = m_Pos;
- m_Pos += len;
+ m_Pos += static_cast(len);
return true;
}
case TAG_List:
{
NEEDBYTES(1);
- eTagType ItemType = (eTagType)m_Data[m_Pos];
+ eTagType ItemType = static_cast(m_Data[m_Pos]);
m_Pos++;
RETURN_FALSE_IF_FALSE(ReadList(ItemType));
return true;
@@ -250,9 +251,9 @@ bool cParsedNBT::ReadTag(void)
}
len *= 4;
NEEDBYTES(len);
- Tag.m_DataLength = len;
+ Tag.m_DataLength = static_cast(len);
Tag.m_DataStart = m_Pos;
- m_Pos += len;
+ m_Pos += static_cast(len);
return true;
}
@@ -276,7 +277,7 @@ int cParsedNBT::FindChildByName(int a_Tag, const char * a_Name, size_t a_NameLen
{
return -1;
}
- if (m_Tags[a_Tag].m_Type != TAG_Compound)
+ if (m_Tags[static_cast(a_Tag)].m_Type != TAG_Compound)
{
return -1;
}
@@ -285,11 +286,11 @@ int cParsedNBT::FindChildByName(int a_Tag, const char * a_Name, size_t a_NameLen
{
a_NameLength = strlen(a_Name);
}
- for (int Child = m_Tags[a_Tag].m_FirstChild; Child != -1; Child = m_Tags[Child].m_NextSibling)
+ for (int Child = m_Tags[static_cast(a_Tag)].m_FirstChild; Child != -1; Child = m_Tags[static_cast(Child)].m_NextSibling)
{
if (
- (m_Tags[Child].m_NameLength == a_NameLength) &&
- (memcmp(m_Data + m_Tags[Child].m_NameStart, a_Name, a_NameLength) == 0)
+ (m_Tags[static_cast(Child)].m_NameLength == a_NameLength) &&
+ (memcmp(m_Data + m_Tags[static_cast(Child)].m_NameStart, a_Name, a_NameLength) == 0)
)
{
return Child;
@@ -413,7 +414,7 @@ void cFastNBTWriter::EndList(void)
ASSERT(m_Stack[m_CurrentStack].m_Type == TAG_List);
// Update the list count:
- SetBEInt((char *)(m_Result.c_str() + m_Stack[m_CurrentStack].m_Pos), m_Stack[m_CurrentStack].m_Count);
+ SetBEInt(const_cast(m_Result.c_str() + m_Stack[m_CurrentStack].m_Pos), m_Stack[m_CurrentStack].m_Count);
--m_CurrentStack;
}
@@ -425,7 +426,7 @@ void cFastNBTWriter::EndList(void)
void cFastNBTWriter::AddByte(const AString & a_Name, unsigned char a_Value)
{
TagCommon(a_Name, TAG_Byte);
- m_Result.push_back(a_Value);
+ m_Result.push_back(static_cast(a_Value));
}
@@ -435,8 +436,8 @@ void cFastNBTWriter::AddByte(const AString & a_Name, unsigned char a_Value)
void cFastNBTWriter::AddShort(const AString & a_Name, Int16 a_Value)
{
TagCommon(a_Name, TAG_Short);
- Int16 Value = htons(a_Value);
- m_Result.append((const char *)&Value, 2);
+ UInt16 Value = htons(a_Value);
+ m_Result.append(reinterpret_cast(&Value), 2);
}
@@ -446,8 +447,8 @@ void cFastNBTWriter::AddShort(const AString & a_Name, Int16 a_Value)
void cFastNBTWriter::AddInt(const AString & a_Name, Int32 a_Value)
{
TagCommon(a_Name, TAG_Int);
- Int32 Value = htonl(a_Value);
- m_Result.append((const char *)&Value, 4);
+ UInt32 Value = htonl(a_Value);
+ m_Result.append(reinterpret_cast(&Value), 4);
}
@@ -457,8 +458,8 @@ void cFastNBTWriter::AddInt(const AString & a_Name, Int32 a_Value)
void cFastNBTWriter::AddLong(const AString & a_Name, Int64 a_Value)
{
TagCommon(a_Name, TAG_Long);
- Int64 Value = HostToNetwork8(&a_Value);
- m_Result.append((const char *)&Value, 8);
+ UInt64 Value = HostToNetwork8(&a_Value);
+ m_Result.append(reinterpret_cast(&Value), 8);
}
@@ -468,8 +469,8 @@ void cFastNBTWriter::AddLong(const AString & a_Name, Int64 a_Value)
void cFastNBTWriter::AddFloat(const AString & a_Name, float a_Value)
{
TagCommon(a_Name, TAG_Float);
- Int32 Value = HostToNetwork4(&a_Value);
- m_Result.append((const char *)&Value, 4);
+ UInt32 Value = HostToNetwork4(&a_Value);
+ m_Result.append(reinterpret_cast(&Value), 4);
}
@@ -479,8 +480,8 @@ void cFastNBTWriter::AddFloat(const AString & a_Name, float a_Value)
void cFastNBTWriter::AddDouble(const AString & a_Name, double a_Value)
{
TagCommon(a_Name, TAG_Double);
- Int64 Value = HostToNetwork8(&a_Value);
- m_Result.append((const char *)&Value, 8);
+ UInt64 Value = HostToNetwork8(&a_Value);
+ m_Result.append(reinterpret_cast(&Value), 8);
}
@@ -490,8 +491,8 @@ void cFastNBTWriter::AddDouble(const AString & a_Name, double a_Value)
void cFastNBTWriter::AddString(const AString & a_Name, const AString & a_Value)
{
TagCommon(a_Name, TAG_String);
- Int16 len = htons((short)(a_Value.size()));
- m_Result.append((const char *)&len, 2);
+ UInt16 len = htons(static_cast(a_Value.size()));
+ m_Result.append(reinterpret_cast(&len), 2);
m_Result.append(a_Value.c_str(), a_Value.size());
}
@@ -502,8 +503,8 @@ void cFastNBTWriter::AddString(const AString & a_Name, const AString & a_Value)
void cFastNBTWriter::AddByteArray(const AString & a_Name, const char * a_Value, size_t a_NumElements)
{
TagCommon(a_Name, TAG_ByteArray);
- u_long len = htonl((u_long)a_NumElements);
- m_Result.append((const char *)&len, 4);
+ u_long len = htonl(static_cast(a_NumElements));
+ m_Result.append(reinterpret_cast(&len), 4);
m_Result.append(a_Value, a_NumElements);
}
@@ -514,18 +515,18 @@ void cFastNBTWriter::AddByteArray(const AString & a_Name, const char * a_Value,
void cFastNBTWriter::AddIntArray(const AString & a_Name, const int * a_Value, size_t a_NumElements)
{
TagCommon(a_Name, TAG_IntArray);
- u_long len = htonl((u_long)a_NumElements);
+ u_long len = htonl(static_cast(a_NumElements));
size_t cap = m_Result.capacity();
size_t size = m_Result.length();
if ((cap - size) < (4 + a_NumElements * 4))
{
m_Result.reserve(size + 4 + (a_NumElements * 4));
}
- m_Result.append((const char *)&len, 4);
+ m_Result.append(reinterpret_cast(&len), 4);
for (size_t i = 0; i < a_NumElements; i++)
{
- int Element = htonl(a_Value[i]);
- m_Result.append((const char *)&Element, 4);
+ UInt32 Element = htonl(a_Value[i]);
+ m_Result.append(reinterpret_cast(&Element), 4);
}
}
@@ -545,8 +546,8 @@ void cFastNBTWriter::Finish(void)
void cFastNBTWriter::WriteString(const char * a_Data, UInt16 a_Length)
{
- Int16 Len = htons(a_Length);
- m_Result.append((const char *)&Len, 2);
+ UInt16 Len = htons(a_Length);
+ m_Result.append(reinterpret_cast(&Len), 2);
m_Result.append(a_Data, a_Length);
}
--
cgit v1.2.3
From b3335518302014d20cf4b8c9a08f851cec07c809 Mon Sep 17 00:00:00 2001
From: Matyas Dolak
Date: Wed, 21 Jan 2015 11:24:32 +0100
Subject: ProtoProxy: Fixed warnings in Connection.cpp.
---
Tools/ProtoProxy/Connection.cpp | 38 +++++++++++++++++++++++---------------
Tools/ProtoProxy/Connection.h | 2 +-
2 files changed, 24 insertions(+), 16 deletions(-)
diff --git a/Tools/ProtoProxy/Connection.cpp b/Tools/ProtoProxy/Connection.cpp
index d42afb7ba..1f88f4b6e 100644
--- a/Tools/ProtoProxy/Connection.cpp
+++ b/Tools/ProtoProxy/Connection.cpp
@@ -141,8 +141,14 @@ typedef unsigned char Byte;
+// fwd declarations, to avoid clang warnings:
+AString PrintableAbsIntTriplet(int a_X, int a_Y, int a_Z, double a_Divisor = 32);
-AString PrintableAbsIntTriplet(int a_X, int a_Y, int a_Z, double a_Divisor = 32)
+
+
+
+
+AString PrintableAbsIntTriplet(int a_X, int a_Y, int a_Z, double a_Divisor)
{
return Printf("<%d, %d, %d> ~ {%.02f, %.02f, %.02f}",
a_X, a_Y, a_Z,
@@ -298,7 +304,7 @@ void cConnection::Log(const char * a_Format, ...)
-void cConnection::DataLog(const void * a_Data, int a_Size, const char * a_Format, ...)
+void cConnection::DataLog(const void * a_Data, size_t a_Size, const char * a_Format, ...)
{
va_list args;
va_start(args, a_Format);
@@ -359,14 +365,14 @@ bool cConnection::ConnectToServer(void)
bool cConnection::RelayFromServer(void)
{
char Buffer[64 KiB];
- int res = recv(m_ServerSocket, Buffer, sizeof(Buffer), 0);
+ int res = static_cast(recv(m_ServerSocket, Buffer, sizeof(Buffer), 0)); // recv returns int on windows, ssize_t on linux
if (res <= 0)
{
Log("Server closed the socket: %d; %d; aborting connection", res, SocketError);
return false;
}
- DataLog(Buffer, res, "Received %d bytes from the SERVER", res);
+ DataLog(Buffer, static_cast(res), "Received %d bytes from the SERVER", res);
switch (m_ServerState)
{
@@ -377,15 +383,15 @@ bool cConnection::RelayFromServer(void)
}
case csEncryptedUnderstood:
{
- m_ServerDecryptor.ProcessData((Byte *)Buffer, (Byte *)Buffer, res);
+ m_ServerDecryptor.ProcessData(reinterpret_cast(Buffer), reinterpret_cast(Buffer), static_cast(res));
DataLog(Buffer, res, "Decrypted %d bytes from the SERVER", res);
return DecodeServersPackets(Buffer, res);
}
case csEncryptedUnknown:
{
- m_ServerDecryptor.ProcessData((Byte *)Buffer, (Byte *)Buffer, res);
+ m_ServerDecryptor.ProcessData(reinterpret_cast(Buffer), reinterpret_cast(Buffer), static_cast(res));
DataLog(Buffer, res, "Decrypted %d bytes from the SERVER", res);
- return CLIENTSEND(Buffer, res);
+ return CLIENTSEND(Buffer, static_cast(res));
}
}
ASSERT(!"Unhandled server state while relaying from server");
@@ -399,7 +405,7 @@ bool cConnection::RelayFromServer(void)
bool cConnection::RelayFromClient(void)
{
char Buffer[64 KiB];
- int res = recv(m_ClientSocket, Buffer, sizeof(Buffer), 0);
+ int res = static_cast(recv(m_ClientSocket, Buffer, sizeof(Buffer), 0)); // recv returns int on Windows, ssize_t on Linux
if (res <= 0)
{
Log("Client closed the socket: %d; %d; aborting connection", res, SocketError);
@@ -422,8 +428,8 @@ bool cConnection::RelayFromClient(void)
case csEncryptedUnknown:
{
DataLog(Buffer, res, "Decrypted %d bytes from the CLIENT", res);
- m_ServerEncryptor.ProcessData((Byte *)Buffer, (Byte *)Buffer, res);
- return SERVERSEND(Buffer, res);
+ m_ServerEncryptor.ProcessData(reinterpret_cast(Buffer), reinterpret_cast(Buffer), static_cast(res));
+ return SERVERSEND(Buffer, static_cast(res));
}
}
ASSERT(!"Unhandled server state while relaying from client");
@@ -446,9 +452,9 @@ double cConnection::GetRelativeTime(void)
bool cConnection::SendData(SOCKET a_Socket, const char * a_Data, size_t a_Size, const char * a_Peer)
{
- DataLog(a_Data, a_Size, "Sending data to %s, %u bytes", a_Peer, (unsigned)a_Size);
+ DataLog(a_Data, a_Size, "Sending data to %s, %u bytes", a_Peer, static_cast(a_Size));
- int res = send(a_Socket, a_Data, (int)a_Size, 0);
+ int res = send(a_Socket, a_Data, a_Size, 0); // Windows uses int for a_Size, Linux uses size_t; but Windows doesn't complain
if (res <= 0)
{
Log("%s closed the socket: %d, %d; aborting connection", a_Peer, res, SocketError);
@@ -511,7 +517,7 @@ bool cConnection::SendEncryptedData(SOCKET a_Socket, cAesCfb128Encryptor & a_Enc
bool cConnection::DecodeClientsPackets(const char * a_Data, int a_Size)
{
- if (!m_ClientBuffer.Write(a_Data, a_Size))
+ if (!m_ClientBuffer.Write(a_Data, static_cast(a_Size)))
{
Log("Too much queued data for the server, aborting connection");
return false;
@@ -529,10 +535,12 @@ bool cConnection::DecodeClientsPackets(const char * a_Data, int a_Size)
break;
}
UInt32 PacketType, PacketReadSoFar;
- PacketReadSoFar = m_ClientBuffer.GetReadableSpace();
+ PacketReadSoFar = static_cast