summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/BlockID.h1
-rw-r--r--src/Items/ItemSpawnEgg.h1
-rw-r--r--src/MobSpawner.cpp6
-rw-r--r--src/Mobs/CMakeLists.txt2
-rw-r--r--src/Mobs/Guardian.cpp65
-rw-r--r--src/Mobs/Guardian.h31
-rw-r--r--src/Mobs/IncludeAllMonsters.h1
-rw-r--r--src/Mobs/Monster.cpp4
-rw-r--r--src/Mobs/Monster.h2
-rw-r--r--src/Mobs/MonsterTypes.h1
-rw-r--r--src/WorldStorage/NBTChunkSerializer.cpp2
-rwxr-xr-xsrc/WorldStorage/WSSAnvil.cpp24
-rwxr-xr-xsrc/WorldStorage/WSSAnvil.h1
13 files changed, 140 insertions, 1 deletions
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..d69ee1683
--- /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.875, 0.8)
+{
+}
+
+
+
+
+
+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..3d174677c 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 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;
@@ -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 bbe9e0471..0d716cca3 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/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<cGuardian> 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);