summaryrefslogtreecommitdiffstats
path: root/src/Mobs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Mobs')
-rw-r--r--src/Mobs/CMakeLists.txt6
-rw-r--r--src/Mobs/IncludeAllMonsters.h1
-rw-r--r--src/Mobs/Monster.cpp20
-rw-r--r--src/Mobs/MonsterTypes.h36
-rw-r--r--src/Mobs/Villager.cpp32
-rw-r--r--src/Mobs/Villager.h4
-rw-r--r--src/Mobs/Zombie.cpp6
-rw-r--r--src/Mobs/Zombie.h10
-rw-r--r--src/Mobs/ZombieVillager.cpp87
-rw-r--r--src/Mobs/ZombieVillager.h33
10 files changed, 207 insertions, 28 deletions
diff --git a/src/Mobs/CMakeLists.txt b/src/Mobs/CMakeLists.txt
index 15456595c..579ba8938 100644
--- a/src/Mobs/CMakeLists.txt
+++ b/src/Mobs/CMakeLists.txt
@@ -36,7 +36,8 @@ SET (SRCS
WitherSkeleton.cpp
Wolf.cpp
Zombie.cpp
- ZombiePigman.cpp)
+ ZombiePigman.cpp
+ ZombieVillager.cpp)
SET (HDRS
AggressiveMonster.h
@@ -78,7 +79,8 @@ SET (HDRS
WitherSkeleton.h
Wolf.h
Zombie.h
- ZombiePigman.h)
+ ZombiePigman.h
+ ZombieVillager.h)
if(NOT MSVC)
add_library(Mobs ${SRCS} ${HDRS})
diff --git a/src/Mobs/IncludeAllMonsters.h b/src/Mobs/IncludeAllMonsters.h
index 17a9dfacd..afb79c97c 100644
--- a/src/Mobs/IncludeAllMonsters.h
+++ b/src/Mobs/IncludeAllMonsters.h
@@ -30,3 +30,4 @@
#include "Wolf.h"
#include "Zombie.h"
#include "ZombiePigman.h"
+#include "ZombieVillager.h"
diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp
index 5e3026a57..d20afa589 100644
--- a/src/Mobs/Monster.cpp
+++ b/src/Mobs/Monster.cpp
@@ -69,6 +69,7 @@ static const struct
{mtWolf, "wolf", "Wolf", "wolf"},
{mtZombie, "zombie", "Zombie", "zombie"},
{mtZombiePigman, "zombiepigman", "PigZombie", "zombie_pigman"},
+ {mtZombieVillager, "zombievillager", "ZombieVillager", "zombie_villager"},
} ;
@@ -662,6 +663,7 @@ void cMonster::KilledBy(TakeDamageInfo & a_TDI)
case mtWitherSkeleton:
case mtZombie:
case mtZombiePigman:
+ case mtZombieVillager:
case mtSlime:
case mtMagmaCube:
{
@@ -1078,6 +1080,7 @@ cMonster::eFamily cMonster::FamilyFromType(eMonsterType a_Type)
case mtWolf: return mfPassive;
case mtZombie: return mfHostile;
case mtZombiePigman: return mfHostile;
+ case mtZombieVillager: return mfHostile;
default:
{
@@ -1176,17 +1179,7 @@ std::unique_ptr<cMonster> cMonster::NewMonsterFromType(eMonsterType a_MobType)
{
return cpp14::make_unique<cSlime>(1 << Random.RandInt(2)); // Size 1, 2 or 4
}
- case mtVillager:
- {
- int VillagerType = Random.RandInt(6);
- if (VillagerType == 6)
- {
- // Give farmers a better chance of spawning
- VillagerType = 0;
- }
-
- return cpp14::make_unique<cVillager>(static_cast<cVillager::eVillagerType>(VillagerType));
- }
+ case mtVillager: return cpp14::make_unique<cVillager>(cVillager::GetRandomProfession());
case mtHorse:
{
// Horses take a type (species), a colour, and a style (dots, stripes, etc.)
@@ -1203,7 +1196,10 @@ std::unique_ptr<cMonster> cMonster::NewMonsterFromType(eMonsterType a_MobType)
return cpp14::make_unique<cHorse>(HorseType, HorseColor, HorseStyle, HorseTameTimes);
}
-
+ case mtZombieVillager:
+ {
+ return cpp14::make_unique<cZombieVillager>(cVillager::GetRandomProfession());
+ }
case mtBat: return cpp14::make_unique<cBat>();
case mtBlaze: return cpp14::make_unique<cBlaze>();
case mtCaveSpider: return cpp14::make_unique<cCaveSpider>();
diff --git a/src/Mobs/MonsterTypes.h b/src/Mobs/MonsterTypes.h
index 7a864fda4..6d3c57852 100644
--- a/src/Mobs/MonsterTypes.h
+++ b/src/Mobs/MonsterTypes.h
@@ -11,6 +11,7 @@ enum eMonsterType
{
mtInvalidType = -1,
+<<<<<<< HEAD
mtBat,
mtBlaze,
mtCaveSpider,
@@ -43,6 +44,41 @@ enum eMonsterType
mtWolf,
mtZombie,
mtZombiePigman,
+=======
+ mtBat = E_META_SPAWN_EGG_BAT,
+ mtBlaze = E_META_SPAWN_EGG_BLAZE,
+ mtCaveSpider = E_META_SPAWN_EGG_CAVE_SPIDER,
+ mtChicken = E_META_SPAWN_EGG_CHICKEN,
+ mtCow = E_META_SPAWN_EGG_COW,
+ mtCreeper = E_META_SPAWN_EGG_CREEPER,
+ mtEnderDragon = E_META_SPAWN_EGG_ENDER_DRAGON,
+ 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,
+ 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,
+ mtSlime = E_META_SPAWN_EGG_SLIME,
+ mtSnowGolem = E_META_SPAWN_EGG_SNOW_GOLEM,
+ mtSpider = E_META_SPAWN_EGG_SPIDER,
+ mtSquid = E_META_SPAWN_EGG_SQUID,
+ mtVillager = E_META_SPAWN_EGG_VILLAGER,
+ mtWitch = E_META_SPAWN_EGG_WITCH,
+ mtWither = E_META_SPAWN_EGG_WITHER,
+ mtWolf = E_META_SPAWN_EGG_WOLF,
+ mtZombie = E_META_SPAWN_EGG_ZOMBIE,
+ mtZombiePigman = E_META_SPAWN_EGG_ZOMBIE_PIGMAN,
+ mtZombieVillager = E_META_SPAWN_EGG_ZOMBIE_VILLAGER,
+ mtMax = 120, // This is just a hotfix for https://forum.cuberite.org/thread-1616.html. Tolua is too bad to find the highest value, so this is needed.
+>>>>>>> Add Zombie Villagers
} ;
// tolua_end
diff --git a/src/Mobs/Villager.cpp b/src/Mobs/Villager.cpp
index 9558ba536..eca8ed2b6 100644
--- a/src/Mobs/Villager.cpp
+++ b/src/Mobs/Villager.cpp
@@ -107,6 +107,26 @@ void cVillager::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
+
+void cVillager::KilledBy(TakeDamageInfo & a_TDI)
+{
+ super::KilledBy(a_TDI);
+
+ // TODO: 0% chance on Easy, 50% chance on Normal and 100% chance on Hard
+ if (GetRandomProvider().RandBool(0.5) && (a_TDI.Attacker != nullptr) && (a_TDI.Attacker->IsMob()))
+ {
+ eMonsterType MonsterType = (static_cast<cMonster *>(a_TDI.Attacker)->GetMobType());
+ if ((MonsterType == mtZombie) || (MonsterType == mtZombieVillager))
+ {
+ m_World->SpawnMob(GetPosX(), GetPosY(), GetPosZ(), mtZombieVillager, false);
+ }
+ }
+}
+
+
+
+
+
////////////////////////////////////////////////////////////////////////////////
// Farmer functions:
@@ -203,7 +223,17 @@ bool cVillager::IsBlockFarmable(BLOCKTYPE a_BlockType)
{
return true;
}
+ default: return false;
}
- return false;
}
+
+
+
+
+cVillager::eVillagerType cVillager::GetRandomProfession()
+{
+ int Profession = GetRandomProvider().RandInt(cVillager::eVillagerType::vtMax - 1);
+
+ return static_cast<cVillager::eVillagerType>(Profession);
+}
diff --git a/src/Mobs/Villager.h b/src/Mobs/Villager.h
index b9a0b7675..2d6644193 100644
--- a/src/Mobs/Villager.h
+++ b/src/Mobs/Villager.h
@@ -29,9 +29,13 @@ public:
CLASS_PROTODEF(cVillager)
+ /** Returns a random Profession. */
+ static eVillagerType GetRandomProfession();
+
// cEntity overrides
virtual bool DoTakeDamage(TakeDamageInfo & a_TDI) override;
virtual void Tick (std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
+ virtual void KilledBy (TakeDamageInfo & a_TDI) override;
// cVillager functions
/** return true if the given blocktype are: crops, potatoes or carrots. */
diff --git a/src/Mobs/Zombie.cpp b/src/Mobs/Zombie.cpp
index 451255ed2..02c1efa86 100644
--- a/src/Mobs/Zombie.cpp
+++ b/src/Mobs/Zombie.cpp
@@ -9,10 +9,8 @@
-cZombie::cZombie(bool a_IsVillagerZombie) :
- super("Zombie", mtZombie, "entity.zombie.hurt", "entity.zombie.death", "entity.zombie.ambient", 0.6, 1.8),
- m_IsVillagerZombie(a_IsVillagerZombie),
- m_IsConverting(false)
+cZombie::cZombie() :
+ super("Zombie", mtZombie, "entity.zombie.hurt", "entity.zombie.death", "entity.zombie.ambient", 0.6, 1.8)
{
}
diff --git a/src/Mobs/Zombie.h b/src/Mobs/Zombie.h
index 47a9f1904..20f59a627 100644
--- a/src/Mobs/Zombie.h
+++ b/src/Mobs/Zombie.h
@@ -12,21 +12,13 @@ class cZombie :
typedef cAggressiveMonster super;
public:
- cZombie(bool a_IsVillagerZombie);
+ cZombie();
CLASS_PROTODEF(cZombie)
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override;
virtual bool IsUndead(void) override { return true; }
- bool IsVillagerZombie(void) const { return m_IsVillagerZombie; }
- bool IsConverting (void) const { return m_IsConverting; }
-
-private:
-
- bool m_IsVillagerZombie;
- bool m_IsConverting;
-
} ;
diff --git a/src/Mobs/ZombieVillager.cpp b/src/Mobs/ZombieVillager.cpp
new file mode 100644
index 000000000..9d17e6038
--- /dev/null
+++ b/src/Mobs/ZombieVillager.cpp
@@ -0,0 +1,87 @@
+
+#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
+
+#include "ZombieVillager.h"
+#include "../World.h"
+#include "../LineBlockTracer.h"
+#include "../Entities/Player.h"
+
+
+
+
+
+cZombieVillager::cZombieVillager(cVillager::eVillagerType a_Profession) :
+ super("ZombieVillager", mtZombieVillager, "entity.zombie_villager.hurt", "entity.zombie_villager.death", "entity.ambient", 0.6, 1.8),
+ m_ConversionTime(-1),
+ m_Profession(a_Profession)
+{
+ SetBurnsInDaylight(true);
+}
+
+
+
+
+
+void cZombieVillager::GetDrops(cItems & a_Drops, cEntity * a_Killer)
+{
+ unsigned int LootingLevel = 0;
+ if (a_Killer != nullptr)
+ {
+ LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting);
+ }
+ AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_ROTTEN_FLESH);
+ cItems RareDrops;
+ RareDrops.Add(cItem(E_ITEM_IRON));
+ RareDrops.Add(cItem(E_ITEM_CARROT));
+ RareDrops.Add(cItem(E_ITEM_POTATO));
+ AddRandomRareDropItem(a_Drops, RareDrops, LootingLevel);
+ AddRandomArmorDropItem(a_Drops, LootingLevel);
+ AddRandomWeaponDropItem(a_Drops, LootingLevel);
+}
+
+
+
+
+
+void cZombieVillager::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
+{
+ super::Tick(a_Dt, a_Chunk);
+ if (!IsTicking())
+ {
+ // The base class tick destroyed us
+ return;
+ }
+
+ LOGD("Conversion time: %d", m_ConversionTime);
+
+ if (m_ConversionTime == 0)
+ {
+ m_World->BroadcastSoundEffect("entity.zombie_villager.cure", GetPosition(), 1.0f, 1.0f);
+ Destroy();
+ m_World->SpawnMob(GetPosX(), GetPosY(), GetPosZ(), mtVillager, false);
+ }
+ else if (m_ConversionTime > 0)
+ {
+ m_ConversionTime--;
+ }
+}
+
+
+
+
+
+void cZombieVillager::OnRightClicked(cPlayer & a_Player)
+{
+ super::OnRightClicked(a_Player);
+
+ const cItem & EquippedItem = a_Player.GetEquippedItem();
+ if ((EquippedItem.m_ItemType == E_ITEM_GOLDEN_APPLE) && GetEntityEffect(cEntityEffect::effWeakness) != nullptr)
+ {
+ if (!a_Player.IsGameModeCreative())
+ {
+ a_Player.GetInventory().RemoveOneEquippedItem();
+ }
+
+ m_ConversionTime = 6000;
+ }
+}
diff --git a/src/Mobs/ZombieVillager.h b/src/Mobs/ZombieVillager.h
new file mode 100644
index 000000000..c4c4ae3d1
--- /dev/null
+++ b/src/Mobs/ZombieVillager.h
@@ -0,0 +1,33 @@
+#pragma once
+
+#include "AggressiveMonster.h"
+#include "Villager.h"
+
+
+
+
+
+class cZombieVillager :
+ public cAggressiveMonster
+{
+ typedef cAggressiveMonster super;
+
+public:
+ cZombieVillager(cVillager::eVillagerType a_Profession);
+
+ CLASS_PROTODEF(cZombieVillager)
+
+ virtual void GetDrops (cItems & a_Drops, cEntity * a_Killer = nullptr) override;
+ virtual void Tick (std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
+ virtual void OnRightClicked (cPlayer & a_Player) override;
+ virtual bool IsUndead (void) override { return true; }
+
+ int ConversionTime (void) const { return m_ConversionTime; }
+ cVillager::eVillagerType GetProfession (void) const { return m_Profession; }
+
+private:
+
+ int m_ConversionTime;
+ cVillager::eVillagerType m_Profession;
+
+} ;