summaryrefslogtreecommitdiffstats
path: root/source/Mobs
diff options
context:
space:
mode:
Diffstat (limited to 'source/Mobs')
-rw-r--r--source/Mobs/AggressiveMonster.cpp8
-rw-r--r--source/Mobs/AggressiveMonster.h3
-rw-r--r--source/Mobs/Bat.cpp15
-rw-r--r--source/Mobs/Bat.h7
-rw-r--r--source/Mobs/Blaze.cpp2
-rw-r--r--source/Mobs/Cavespider.cpp2
-rw-r--r--source/Mobs/Chicken.cpp2
-rw-r--r--source/Mobs/Cow.cpp10
-rw-r--r--source/Mobs/Creeper.cpp2
-rw-r--r--source/Mobs/EnderDragon.cpp2
-rw-r--r--source/Mobs/Enderman.cpp2
-rw-r--r--source/Mobs/Ghast.cpp2
-rw-r--r--source/Mobs/Giant.cpp2
-rw-r--r--source/Mobs/Horse.cpp61
-rw-r--r--source/Mobs/IncludeAllMonsters.h29
-rw-r--r--source/Mobs/IronGolem.cpp2
-rw-r--r--source/Mobs/Magmacube.cpp2
-rw-r--r--source/Mobs/Monster.cpp247
-rw-r--r--source/Mobs/Monster.h54
-rw-r--r--source/Mobs/Mooshroom.cpp2
-rw-r--r--source/Mobs/Ocelot.h2
-rw-r--r--source/Mobs/PassiveAggressiveMonster.cpp4
-rw-r--r--source/Mobs/PassiveAggressiveMonster.h2
-rw-r--r--source/Mobs/PassiveMonster.cpp5
-rw-r--r--source/Mobs/PassiveMonster.h3
-rw-r--r--source/Mobs/Pig.cpp6
-rw-r--r--source/Mobs/Sheep.cpp7
-rw-r--r--source/Mobs/Silverfish.h2
-rw-r--r--source/Mobs/Skeleton.cpp2
-rw-r--r--source/Mobs/Slime.cpp2
-rw-r--r--source/Mobs/SnowGolem.cpp2
-rw-r--r--source/Mobs/Spider.cpp2
-rw-r--r--source/Mobs/Squid.cpp3
-rw-r--r--source/Mobs/Squid.h1
-rw-r--r--source/Mobs/Villager.cpp2
-rw-r--r--source/Mobs/Witch.cpp2
-rw-r--r--source/Mobs/Wither.cpp2
-rw-r--r--source/Mobs/Wolf.cpp2
-rw-r--r--source/Mobs/Zombie.cpp2
-rw-r--r--source/Mobs/Zombiepigman.cpp2
40 files changed, 426 insertions, 85 deletions
diff --git a/source/Mobs/AggressiveMonster.cpp b/source/Mobs/AggressiveMonster.cpp
index 2eae772d7..88bd2743a 100644
--- a/source/Mobs/AggressiveMonster.cpp
+++ b/source/Mobs/AggressiveMonster.cpp
@@ -12,8 +12,8 @@
-cAggressiveMonster::cAggressiveMonster(const AString & a_ConfigName, char a_ProtocolMobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height) :
- super(a_ConfigName, a_ProtocolMobType, a_SoundHurt, a_SoundDeath, a_Width, a_Height),
+cAggressiveMonster::cAggressiveMonster(const AString & a_ConfigName, eType a_MobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height) :
+ super(a_ConfigName, a_MobType, a_SoundHurt, a_SoundDeath, a_Width, a_Height),
m_ChaseTime(999999)
{
m_EMPersonality = AGGRESSIVE;
@@ -33,7 +33,7 @@ void cAggressiveMonster::InStateChasing(float a_Dt)
if (m_Target->IsPlayer())
{
cPlayer * Player = (cPlayer *) m_Target;
- if (Player->GetGameMode() == 1)
+ if (Player->IsGameModeCreative())
{
m_EMState = IDLE;
return;
@@ -95,5 +95,3 @@ void cAggressiveMonster::Tick(float a_Dt, cChunk & a_Chunk)
}
-
-
diff --git a/source/Mobs/AggressiveMonster.h b/source/Mobs/AggressiveMonster.h
index 1eff1831e..5a0d93f3d 100644
--- a/source/Mobs/AggressiveMonster.h
+++ b/source/Mobs/AggressiveMonster.h
@@ -13,12 +13,13 @@ class cAggressiveMonster :
typedef cMonster super;
public:
- cAggressiveMonster(const AString & a_ConfigName, char a_ProtocolMobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height);
+ cAggressiveMonster(const AString & a_ConfigName, eType 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 InStateChasing(float a_Dt) override;
virtual void EventSeePlayer(cEntity *) override;
+
protected:
float m_ChaseTime;
diff --git a/source/Mobs/Bat.cpp b/source/Mobs/Bat.cpp
new file mode 100644
index 000000000..b9c82996b
--- /dev/null
+++ b/source/Mobs/Bat.cpp
@@ -0,0 +1,15 @@
+
+#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
+
+#include "Bat.h"
+#include "../Vector3d.h"
+#include "../Chunk.h"
+
+
+cBat::cBat(void) :
+ // TODO: The size is only a guesstimate, measure in vanilla and fix the size values here
+ super("Bat", mtBat, "mob.bat.hurt", "mob.bat.death", 0.7, 0.7)
+{
+}
+
+
diff --git a/source/Mobs/Bat.h b/source/Mobs/Bat.h
index 0b50e06cd..e878d0ee8 100644
--- a/source/Mobs/Bat.h
+++ b/source/Mobs/Bat.h
@@ -13,13 +13,10 @@ class cBat :
typedef cPassiveMonster super;
public:
- cBat(void) :
- super("Bat", 65, "mob.bat.hurt", "mob.bat.death", 0.5, 0.9)
- {
- }
+ cBat(void);
CLASS_PROTODEF(cBat);
-
+
bool IsHanging(void) const {return false; }
} ;
diff --git a/source/Mobs/Blaze.cpp b/source/Mobs/Blaze.cpp
index dbbccf417..74c82c081 100644
--- a/source/Mobs/Blaze.cpp
+++ b/source/Mobs/Blaze.cpp
@@ -9,7 +9,7 @@
cBlaze::cBlaze(void) :
// TODO: The size is only a guesstimate, measure in vanilla and fix the size values here
- super("Blaze", 61, "mob.blaze.hit", "mob.blaze.death", 0.7, 1.8)
+ super("Blaze", mtBlaze, "mob.blaze.hit", "mob.blaze.death", 0.7, 1.8)
{
}
diff --git a/source/Mobs/Cavespider.cpp b/source/Mobs/Cavespider.cpp
index 2d50b391a..aba1ff9f5 100644
--- a/source/Mobs/Cavespider.cpp
+++ b/source/Mobs/Cavespider.cpp
@@ -9,7 +9,7 @@
cCavespider::cCavespider(void) :
- super("Cavespider", 59, "mob.spider.say", "mob.spider.death", 0.7, 0.5)
+ super("Cavespider", mtCaveSpider, "mob.spider.say", "mob.spider.death", 0.7, 0.5)
{
}
diff --git a/source/Mobs/Chicken.cpp b/source/Mobs/Chicken.cpp
index 3da9781d3..434a32f94 100644
--- a/source/Mobs/Chicken.cpp
+++ b/source/Mobs/Chicken.cpp
@@ -14,7 +14,7 @@
cChicken::cChicken(void) :
- super("Chicken", 93, "mob.chicken.hurt", "mob.chicken.hurt", 0.3, 0.4)
+ super("Chicken", mtChicken, "mob.chicken.hurt", "mob.chicken.hurt", 0.3, 0.4)
{
}
diff --git a/source/Mobs/Cow.cpp b/source/Mobs/Cow.cpp
index 431a6916d..9eb74dac2 100644
--- a/source/Mobs/Cow.cpp
+++ b/source/Mobs/Cow.cpp
@@ -2,6 +2,7 @@
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
#include "Cow.h"
+#include "../Entities/Player.h"
@@ -10,7 +11,7 @@
cCow::cCow(void) :
- super("Cow", 92, "mob.cow.hurt", "mob.cow.hurt", 0.9, 1.3)
+ super("Cow", mtCow, "mob.cow.hurt", "mob.cow.hurt", 0.9, 1.3)
{
}
@@ -24,6 +25,10 @@ void cCow::GetDrops(cItems & a_Drops, cEntity * a_Killer)
AddRandomDropItem(a_Drops, 1, 3, IsOnFire() ? E_ITEM_STEAK : E_ITEM_RAW_BEEF);
}
+
+
+
+
void cCow::OnRightClicked(cPlayer & a_Player)
{
if ((a_Player.GetEquippedItem().m_ItemType == E_ITEM_BUCKET))
@@ -31,9 +36,8 @@ void cCow::OnRightClicked(cPlayer & a_Player)
if (!a_Player.IsGameModeCreative())
{
a_Player.GetInventory().RemoveOneEquippedItem();
- a_Player.GetInventory().AddItem(E_ITEM_MILK)
+ a_Player.GetInventory().AddItem(E_ITEM_MILK);
}
-
}
}
diff --git a/source/Mobs/Creeper.cpp b/source/Mobs/Creeper.cpp
index b41b05f42..4e11ae13e 100644
--- a/source/Mobs/Creeper.cpp
+++ b/source/Mobs/Creeper.cpp
@@ -9,7 +9,7 @@
cCreeper::cCreeper(void) :
- super("Creeper", 50, "mob.creeper.say", "mob.creeper.say", 0.6, 1.8),
+ super("Creeper", mtCreeper, "mob.creeper.say", "mob.creeper.say", 0.6, 1.8),
m_bIsBlowing(false),
m_bIsCharged(false)
{
diff --git a/source/Mobs/EnderDragon.cpp b/source/Mobs/EnderDragon.cpp
index 64f2bedfa..acd81cde1 100644
--- a/source/Mobs/EnderDragon.cpp
+++ b/source/Mobs/EnderDragon.cpp
@@ -9,7 +9,7 @@
cEnderDragon::cEnderDragon(void) :
// TODO: Vanilla source says this, but is it right? Dragons fly, they don't stand
- super("EnderDragon", 63, "mob.enderdragon.hit", "mob.enderdragon.end", 16.0, 8.0)
+ super("EnderDragon", mtEnderDragon, "mob.enderdragon.hit", "mob.enderdragon.end", 16.0, 8.0)
{
}
diff --git a/source/Mobs/Enderman.cpp b/source/Mobs/Enderman.cpp
index c0ea3d6aa..a784131e4 100644
--- a/source/Mobs/Enderman.cpp
+++ b/source/Mobs/Enderman.cpp
@@ -8,7 +8,7 @@
cEnderman::cEnderman(void) :
- super("Enderman", 58, "mob.endermen.hit", "mob.endermen.death", 0.5, 2.9),
+ super("Enderman", mtEnderman, "mob.endermen.hit", "mob.endermen.death", 0.5, 2.9),
m_bIsScreaming(false),
CarriedBlock(E_BLOCK_AIR),
CarriedMeta(0)
diff --git a/source/Mobs/Ghast.cpp b/source/Mobs/Ghast.cpp
index 288d0c28a..419c8474d 100644
--- a/source/Mobs/Ghast.cpp
+++ b/source/Mobs/Ghast.cpp
@@ -8,7 +8,7 @@
cGhast::cGhast(void) :
- super("Ghast", 56, "mob.ghast.scream", "mob.ghast.death", 4, 4)
+ super("Ghast", mtGhast, "mob.ghast.scream", "mob.ghast.death", 4, 4)
{
}
diff --git a/source/Mobs/Giant.cpp b/source/Mobs/Giant.cpp
index a02758a43..f41977535 100644
--- a/source/Mobs/Giant.cpp
+++ b/source/Mobs/Giant.cpp
@@ -9,7 +9,7 @@
cGiant::cGiant(void) :
// TODO: The size is only a guesstimate, measure in vanilla and fix the size values here
- super("Giant", 53, "mob.zombie.hurt", "mob.zombie.death", 2.0, 13.5)
+ super("Giant", mtGiant, "mob.zombie.hurt", "mob.zombie.death", 2.0, 13.5)
{
}
diff --git a/source/Mobs/Horse.cpp b/source/Mobs/Horse.cpp
index c2a8f6ed0..d18887ea4 100644
--- a/source/Mobs/Horse.cpp
+++ b/source/Mobs/Horse.cpp
@@ -1,4 +1,3 @@
-
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
#include "Horse.h"
@@ -10,7 +9,7 @@
cHorse::cHorse(int Type, int Color, int Style, int TameTimes) :
- super("Horse", 100, "mob.horse.hit", "mob.horse.death", 1.4, 1.6),
+ super("Horse", mtHorse, "mob.horse.hit", "mob.horse.death", 1.4, 1.6),
m_bHasChest(false),
m_bIsEating(false),
m_bIsRearing(false),
@@ -76,8 +75,12 @@ void cHorse::Tick(float a_Dt, cChunk & a_Chunk)
if (m_RearTickCount == 20)
{
m_bIsRearing = false;
+ m_RearTickCount = 0;
+ }
+ else
+ {
+ m_RearTickCount++;
}
- else { m_RearTickCount++;}
}
m_World->BroadcastEntityMetadata(*this);
@@ -89,35 +92,45 @@ void cHorse::Tick(float a_Dt, cChunk & a_Chunk)
void cHorse::OnRightClicked(cPlayer & a_Player)
{
- if (m_Attachee != NULL)
+ if (!m_bIsSaddled && m_bIsTame)
{
- if (m_Attachee->GetUniqueID() == a_Player.GetUniqueID())
+ if (a_Player.GetEquippedItem().m_ItemType == E_ITEM_SADDLE)
{
- a_Player.Detach();
- return;
+ // Saddle the horse:
+ if (!a_Player.IsGameModeCreative())
+ {
+ a_Player.GetInventory().RemoveOneEquippedItem();
+ }
+ m_bIsSaddled = true;
+ m_World->BroadcastEntityMetadata(*this);
}
-
- if (m_Attachee->IsPlayer())
+ else if (!a_Player.GetEquippedItem().IsEmpty())
{
- return;
+ // The horse doesn't like being hit, make it rear:
+ m_bIsRearing = true;
+ m_RearTickCount = 0;
}
-
- m_Attachee->Detach();
}
-
- m_TameAttemptTimes++;
- a_Player.AttachTo(this);
-
- if (a_Player.GetEquippedItem().m_ItemType == E_ITEM_SADDLE)
+ else
{
- if (!a_Player.IsGameModeCreative())
+ if (m_Attachee != NULL)
{
- a_Player.GetInventory().RemoveOneEquippedItem();
+ if (m_Attachee->GetUniqueID() == a_Player.GetUniqueID())
+ {
+ a_Player.Detach();
+ return;
+ }
+
+ if (m_Attachee->IsPlayer())
+ {
+ return;
+ }
+
+ m_Attachee->Detach();
}
- // Set saddle state & broadcast metadata
- m_bIsSaddled = true;
- m_World->BroadcastEntityMetadata(*this);
+ m_TameAttemptTimes++;
+ a_Player.AttachTo(this);
}
}
@@ -128,6 +141,10 @@ void cHorse::OnRightClicked(cPlayer & a_Player)
void cHorse::GetDrops(cItems & a_Drops, cEntity * a_Killer)
{
AddRandomDropItem(a_Drops, 0, 2, E_ITEM_LEATHER);
+ if (m_bIsSaddled)
+ {
+ a_Drops.push_back(cItem(E_ITEM_SADDLE, 1));
+ }
}
diff --git a/source/Mobs/IncludeAllMonsters.h b/source/Mobs/IncludeAllMonsters.h
new file mode 100644
index 000000000..1b436a11f
--- /dev/null
+++ b/source/Mobs/IncludeAllMonsters.h
@@ -0,0 +1,29 @@
+#include "Bat.h"
+#include "Blaze.h"
+#include "Cavespider.h"
+#include "Chicken.h"
+#include "Cow.h"
+#include "Creeper.h"
+#include "Enderman.h"
+#include "EnderDragon.h"
+#include "Ghast.h"
+#include "Giant.h"
+#include "Horse.h"
+#include "IronGolem.h"
+#include "Magmacube.h"
+#include "Mooshroom.h"
+#include "Ocelot.h"
+#include "Pig.h"
+#include "Sheep.h"
+#include "Silverfish.h"
+#include "Skeleton.h"
+#include "Slime.h"
+#include "SnowGolem.h"
+#include "Spider.h"
+#include "Squid.h"
+#include "Villager.h"
+#include "Witch.h"
+#include "Wither.h"
+#include "Wolf.h"
+#include "Zombie.h"
+#include "Zombiepigman.h"
diff --git a/source/Mobs/IronGolem.cpp b/source/Mobs/IronGolem.cpp
index 42d312c23..47c961098 100644
--- a/source/Mobs/IronGolem.cpp
+++ b/source/Mobs/IronGolem.cpp
@@ -8,7 +8,7 @@
cIronGolem::cIronGolem(void) :
- super("IronGolem", 99, "mob.IronGolem.hit", "mob.IronGolem.death", 1.4, 2.9)
+ super("IronGolem", mtIronGolem, "mob.IronGolem.hit", "mob.IronGolem.death", 1.4, 2.9)
{
}
diff --git a/source/Mobs/Magmacube.cpp b/source/Mobs/Magmacube.cpp
index c72b4831b..86447ff6b 100644
--- a/source/Mobs/Magmacube.cpp
+++ b/source/Mobs/Magmacube.cpp
@@ -8,7 +8,7 @@
cMagmaCube::cMagmaCube(int a_Size) :
- super("MagmaCube", 62, "mob.MagmaCube.big", "mob.MagmaCube.big", 0.6 * a_Size, 0.6 * a_Size),
+ super("MagmaCube", mtMagmaCube, "mob.MagmaCube.big", "mob.MagmaCube.big", 0.6 * a_Size, 0.6 * a_Size),
m_Size(a_Size)
{
}
diff --git a/source/Mobs/Monster.cpp b/source/Mobs/Monster.cpp
index 334229a42..72dfb2583 100644
--- a/source/Mobs/Monster.cpp
+++ b/source/Mobs/Monster.cpp
@@ -1,7 +1,7 @@
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-#include "Monster.h"
+#include "IncludeAllMonsters.h"
#include "../Root.h"
#include "../Server.h"
#include "../ClientHandle.h"
@@ -16,14 +16,56 @@
#include "../Vector3d.h"
#include "../Tracer.h"
#include "../Chunk.h"
+#include "../FastRandom.h"
-// #include "../../iniFile/iniFile.h"
-
-cMonster::cMonster(const AString & a_ConfigName, char a_ProtocolMobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height)
+/** Map for eType <-> string
+Needs to be alpha-sorted by the strings, because binary search is used in StringToMobType()
+The strings need to be lowercase (for more efficient comparisons in StringToMobType())
+*/
+static const struct
+{
+ cMonster::eType m_Type;
+ const char * m_lcName;
+} g_MobTypeNames[] =
+{
+ {cMonster::mtBat, "bat"},
+ {cMonster::mtBlaze, "blaze"},
+ {cMonster::mtCaveSpider, "cavespider"},
+ {cMonster::mtChicken, "chicken"},
+ {cMonster::mtCow, "cow"},
+ {cMonster::mtCreeper, "creeper"},
+ {cMonster::mtEnderman, "enderman"},
+ {cMonster::mtGhast, "ghast"},
+ {cMonster::mtHorse, "horse"},
+ {cMonster::mtMagmaCube, "magmacube"},
+ {cMonster::mtMooshroom, "mooshroom"},
+ {cMonster::mtOcelot, "ocelot"},
+ {cMonster::mtPig, "pig"},
+ {cMonster::mtSheep, "sheep"},
+ {cMonster::mtSilverfish, "silverfish"},
+ {cMonster::mtSkeleton, "skeleton"},
+ {cMonster::mtSlime, "slime"},
+ {cMonster::mtSpider, "spider"},
+ {cMonster::mtSquid, "squid"},
+ {cMonster::mtVillager, "villager"},
+ {cMonster::mtWitch, "witch"},
+ {cMonster::mtWolf, "wolf"},
+ {cMonster::mtZombie, "zombie"},
+ {cMonster::mtZombiePigman, "zombiepigman"},
+} ;
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cMonster:
+
+cMonster::cMonster(const AString & a_ConfigName, eType a_MobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height)
: super(etMonster, a_Width, a_Height)
, m_Target(NULL)
, m_AttackRate(3)
@@ -32,7 +74,7 @@ cMonster::cMonster(const AString & a_ConfigName, char a_ProtocolMobType, const A
, m_DestinationTime( 0 )
, m_DestroyTimer( 0 )
, m_Jump(0)
- , m_MobType(a_ProtocolMobType)
+ , m_MobType(a_MobType)
, m_SoundHurt(a_SoundHurt)
, m_SoundDeath(a_SoundDeath)
, m_EMState(IDLE)
@@ -465,6 +507,189 @@ void cMonster::SetSightDistance(float sd)
+AString cMonster::MobTypeToString(cMonster::eType a_MobType)
+{
+ // Mob types aren't sorted, so we need to search linearly:
+ for (int i = 0; i < ARRAYCOUNT(g_MobTypeNames); i++)
+ {
+ if (g_MobTypeNames[i].m_Type == a_MobType)
+ {
+ return g_MobTypeNames[i].m_lcName;
+ }
+ }
+
+ // Not found:
+ return "";
+}
+
+
+
+
+
+cMonster::eType cMonster::StringToMobType(const AString & a_Name)
+{
+ AString lcName(a_Name);
+ StrToLower(lcName);
+
+ // Binary-search for the lowercase name:
+ int lo = 0, hi = ARRAYCOUNT(g_MobTypeNames) - 1;
+ while (hi - lo > 1)
+ {
+ int mid = (lo + hi) / 2;
+ int res = strcmp(g_MobTypeNames[mid].m_lcName, lcName.c_str());
+ if (res == 0)
+ {
+ return g_MobTypeNames[mid].m_Type;
+ }
+ if (res < 0)
+ {
+ lo = mid;
+ }
+ else
+ {
+ hi = mid;
+ }
+ }
+ // Range has collapsed to at most two elements, compare each:
+ if (strcmp(g_MobTypeNames[lo].m_lcName, lcName.c_str()) == 0)
+ {
+ return g_MobTypeNames[lo].m_Type;
+ }
+ if ((lo != hi) && (strcmp(g_MobTypeNames[hi].m_lcName, lcName.c_str()) == 0))
+ {
+ return g_MobTypeNames[hi].m_Type;
+ }
+
+ // Not found:
+ return mtInvalidType;
+}
+
+
+
+
+
+cMonster::eFamily cMonster::FamilyFromType(eType a_Type)
+{
+ switch (a_Type)
+ {
+ case mtBat: return mfAmbient;
+ case mtBlaze: return mfHostile;
+ case mtCaveSpider: return mfHostile;
+ case mtChicken: return mfPassive;
+ case mtCow: return mfPassive;
+ case mtCreeper: return mfHostile;
+ case mtEnderman: return mfHostile;
+ case mtGhast: return mfHostile;
+ case mtHorse: return mfPassive;
+ case mtMagmaCube: return mfHostile;
+ case mtMooshroom: return mfHostile;
+ case mtOcelot: return mfHostile;
+ case mtPig: return mfPassive;
+ case mtSheep: return mfPassive;
+ case mtSilverfish: return mfHostile;
+ case mtSkeleton: return mfHostile;
+ case mtSlime: return mfHostile;
+ case mtSpider: return mfHostile;
+ case mtSquid: return mfWater;
+ case mtVillager: return mfPassive;
+ case mtWitch: return mfHostile;
+ case mtWolf: return mfHostile;
+ case mtZombie: return mfHostile;
+ case mtZombiePigman: return mfHostile;
+ } ;
+ ASSERT(!"Unhandled mob type");
+ return mfMaxplusone;
+}
+
+
+
+
+
+int cMonster::GetSpawnDelay(cMonster::eFamily a_MobFamily)
+{
+ switch (a_MobFamily)
+ {
+ case mfHostile: return 40;
+ case mfPassive: return 40;
+ case mfAmbient: return 40;
+ case mfWater: return 400;
+ }
+ ASSERT(!"Unhandled mob family");
+ return -1;
+}
+
+
+
+
+
+cMonster * cMonster::NewMonsterFromType(cMonster::eType a_MobType, int a_Size)
+{
+ cFastRandom Random;
+
+ cMonster * toReturn = NULL;
+
+ // unspecified size get rand[1,3] for Monsters that need size
+ switch (a_MobType)
+ {
+ case mtMagmaCube:
+ case mtSlime:
+ {
+ if (a_Size == -1)
+ {
+ a_Size = Random.NextInt(2, a_MobType) + 1;
+ }
+ if ((a_Size <= 0) || (a_Size >= 4))
+ {
+ ASSERT(!"Random for size was supposed to pick in [1..3] and picked outside");
+ a_Size = 1;
+ }
+ break;
+ }
+ default: break;
+ } // switch (a_MobType)
+
+ // Create the mob entity
+ switch (a_MobType)
+ {
+ case mtMagmaCube: toReturn = new cMagmaCube(a_Size); break;
+ case mtSlime: toReturn = new cSlime(a_Size); break;
+ case mtBat: toReturn = new cBat(); break;
+ case mtBlaze: toReturn = new cBlaze(); break;
+ case mtCaveSpider: toReturn = new cCavespider(); break;
+ case mtChicken: toReturn = new cChicken(); break;
+ case mtCow: toReturn = new cCow(); break;
+ case mtCreeper: toReturn = new cCreeper(); break;
+ case mtEnderman: toReturn = new cEnderman(); break;
+ case mtGhast: toReturn = new cGhast(); break;
+ // TODO:
+ // case cMonster::mtHorse: toReturn = new cHorse(); break;
+ case mtMooshroom: toReturn = new cMooshroom(); break;
+ case mtOcelot: toReturn = new cOcelot(); break;
+ case mtPig: toReturn = new cPig(); break;
+ // TODO: Implement sheep color
+ case mtSheep: toReturn = new cSheep(0); break;
+ case mtSilverfish: toReturn = new cSilverfish(); break;
+ // TODO: Implement wither skeleton geration
+ case mtSkeleton: toReturn = new cSkeleton(false); break;
+ case mtSpider: toReturn = new cSpider(); break;
+ case mtSquid: toReturn = new cSquid(); break;
+ case mtVillager: toReturn = new cVillager(cVillager::vtFarmer); break;
+ case mtWitch: toReturn = new cWitch(); break;
+ case mtWolf: toReturn = new cWolf(); break;
+ case mtZombie: toReturn = new cZombie(false); break;
+ case mtZombiePigman: toReturn = new cZombiePigman(); break;
+ default:
+ {
+ ASSERT(!"Unhandled Mob type");
+ }
+ }
+ return toReturn;
+}
+
+
+
+
+
void cMonster::AddRandomDropItem(cItems & a_Drops, unsigned int a_Min, unsigned int a_Max, short a_Item, short a_ItemHealth)
{
MTRand r1;
@@ -493,8 +718,8 @@ void cMonster::HandleDaylightBurning(cChunk & a_Chunk)
return;
}
- int RelX = (int)floor(GetPosX()) - a_Chunk.GetPosX() * cChunkDef::Width;
- int RelZ = (int)floor(GetPosZ()) - a_Chunk.GetPosZ() * cChunkDef::Width;
+ int RelX = (int)floor(GetPosX()) - GetChunkX() * cChunkDef::Width;
+ int RelZ = (int)floor(GetPosZ()) - GetChunkZ() * cChunkDef::Width;
if (
(a_Chunk.GetSkyLight(RelX, RelY, RelZ) == 15) && // In the daylight
(a_Chunk.GetBlock(RelX, RelY, RelZ) != E_BLOCK_SOULSAND) && // Not on soulsand
@@ -510,3 +735,11 @@ void cMonster::HandleDaylightBurning(cChunk & a_Chunk)
+cMonster::eFamily cMonster::GetMobFamily(void) const
+{
+ return FamilyFromType(m_MobType);
+}
+
+
+
+
diff --git a/source/Mobs/Monster.h b/source/Mobs/Monster.h
index d784f2eec..a0002bf4f 100644
--- a/source/Mobs/Monster.h
+++ b/source/Mobs/Monster.h
@@ -26,6 +26,8 @@ public:
/// This identifies individual monster type, as well as their network type-ID
enum eType
{
+ mtInvalidType = -1,
+
mtBat = E_META_SPAWN_EGG_BAT,
mtBlaze = E_META_SPAWN_EGG_BLAZE,
mtCaveSpider = E_META_SPAWN_EGG_CAVE_SPIDER,
@@ -55,19 +57,31 @@ public:
mtWolf = E_META_SPAWN_EGG_WOLF,
mtZombie = E_META_SPAWN_EGG_ZOMBIE,
mtZombiePigman = E_META_SPAWN_EGG_ZOMBIE_PIGMAN,
+ } ;
+
+ enum eFamily
+ {
+ mfHostile = 0, // Spider, Zombies ...
+ mfPassive = 1, // Cows, Pigs
+ mfAmbient = 2, // Bats
+ mfWater = 3, // Squid
+ mfMaxplusone, // Nothing. Be sure this is the last and the others are in order
} ;
// tolua_end
+ enum MState{ATTACKING, IDLE, CHASING, ESCAPING} m_EMState;
+ enum MPersonality{PASSIVE,AGGRESSIVE,COWARDLY} m_EMPersonality;
+
float m_SightDistance;
/** Creates the mob object.
* If a_ConfigName is not empty, the configuration is loaded using GetMonsterConfig()
- * a_ProtocolMobType is the ID of the mob used in the protocol ( http://wiki.vg/Entities#Mobs , 2012_12_22)
+ * a_MobType is the type of the mob (also used in the protocol ( http://wiki.vg/Entities#Mobs , 2012_12_22))
* a_SoundHurt and a_SoundDeath are assigned into m_SoundHurt and m_SoundDeath, respectively
*/
- cMonster(const AString & a_ConfigName, char a_ProtocolMobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height);
+ cMonster(const AString & a_ConfigName, eType a_MobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height);
CLASS_PROTODEF(cMonster);
@@ -82,7 +96,11 @@ public:
virtual void MoveToPosition(const Vector3f & a_Position);
virtual bool ReachedDestination(void);
- char GetMobType(void) const {return m_MobType; }
+ // tolua_begin
+ eType GetMobType(void) const {return m_MobType; }
+ eFamily GetMobFamily(void) const;
+ // tolua_end
+
const char * GetState();
void SetState(const AString & str);
@@ -103,8 +121,6 @@ public:
virtual void Attack(float a_Dt);
- int GetMobType() { return m_MobType; } // tolua_export
-
int GetAttackRate(){return (int)m_AttackRate;}
void SetAttackRate(int ar);
void SetAttackRange(float ar);
@@ -119,9 +135,31 @@ public:
virtual bool IsTame (void) const { return false; }
virtual bool IsSitting (void) const { return false; }
- enum MState{ATTACKING, IDLE, CHASING, ESCAPING} m_EMState;
- enum MPersonality{PASSIVE,AGGRESSIVE,COWARDLY} m_EMPersonality;
+ // tolua_begin
+
+ /// Translates MobType enum to a string, empty string if unknown
+ static AString MobTypeToString(eType a_MobType);
+
+ /// Translates MobType string to the enum, mtInvalidType if not recognized
+ static eType StringToMobType(const AString & a_MobTypeName);
+ /// Returns the mob family based on the type
+ static eFamily FamilyFromType(eType a_MobType);
+
+ /// Returns the spawn delay (number of game ticks between spawn attempts) for the given mob family
+ static int GetSpawnDelay(cMonster::eFamily a_MobFamily);
+
+ // tolua_end
+
+ /** Creates a new object of the specified mob.
+ a_MobType is the type of the mob to be created
+ a_Size is the size (for mobs with size)
+ if a_Size is let to -1 for entities that need size, size will be random
+ asserts and returns null if mob type is not specified
+ asserts if invalid size for mobs that need size
+ */
+ static cMonster * NewMonsterFromType(eType a_MobType, int a_Size = -1);
+
protected:
cEntity * m_Target;
@@ -137,7 +175,7 @@ protected:
float m_DestroyTimer;
float m_Jump;
- char m_MobType;
+ eType m_MobType;
AString m_SoundHurt;
AString m_SoundDeath;
diff --git a/source/Mobs/Mooshroom.cpp b/source/Mobs/Mooshroom.cpp
index 5d2c901ba..940e2db44 100644
--- a/source/Mobs/Mooshroom.cpp
+++ b/source/Mobs/Mooshroom.cpp
@@ -14,7 +14,7 @@
cMooshroom::cMooshroom(void) :
- super("Mooshroom", 96, "mob.cow.hurt", "mob.cow.hurt", 0.9, 1.3)
+ super("Mooshroom", mtMooshroom, "mob.cow.hurt", "mob.cow.hurt", 0.9, 1.3)
{
}
diff --git a/source/Mobs/Ocelot.h b/source/Mobs/Ocelot.h
index 6d24c5672..adb7a1f75 100644
--- a/source/Mobs/Ocelot.h
+++ b/source/Mobs/Ocelot.h
@@ -14,7 +14,7 @@ class cOcelot :
public:
cOcelot(void) :
- super("Ocelot", 98, "mob.cat.hitt", "mob.cat.hitt", 0.6, 0.8)
+ super("Ocelot", mtOcelot, "mob.cat.hitt", "mob.cat.hitt", 0.6, 0.8)
{
}
diff --git a/source/Mobs/PassiveAggressiveMonster.cpp b/source/Mobs/PassiveAggressiveMonster.cpp
index e473137a9..28de65905 100644
--- a/source/Mobs/PassiveAggressiveMonster.cpp
+++ b/source/Mobs/PassiveAggressiveMonster.cpp
@@ -9,8 +9,8 @@
-cPassiveAggressiveMonster::cPassiveAggressiveMonster(const AString & a_ConfigName, char a_ProtocolMobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height) :
- super(a_ConfigName, a_ProtocolMobType, a_SoundHurt, a_SoundDeath, a_Width, a_Height)
+cPassiveAggressiveMonster::cPassiveAggressiveMonster(const AString & a_ConfigName, eType a_MobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height) :
+ super(a_ConfigName, a_MobType, a_SoundHurt, a_SoundDeath, a_Width, a_Height)
{
m_EMPersonality = PASSIVE;
}
diff --git a/source/Mobs/PassiveAggressiveMonster.h b/source/Mobs/PassiveAggressiveMonster.h
index 243dfff38..2c5ef30b1 100644
--- a/source/Mobs/PassiveAggressiveMonster.h
+++ b/source/Mobs/PassiveAggressiveMonster.h
@@ -13,7 +13,7 @@ class cPassiveAggressiveMonster :
typedef cAggressiveMonster super;
public:
- cPassiveAggressiveMonster(const AString & a_ConfigName, char a_ProtocolMobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height);
+ cPassiveAggressiveMonster(const AString & a_ConfigName, eType a_MobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height);
virtual void DoTakeDamage(TakeDamageInfo & a_TDI) override;
} ;
diff --git a/source/Mobs/PassiveMonster.cpp b/source/Mobs/PassiveMonster.cpp
index 7a6140c04..91ceb5a53 100644
--- a/source/Mobs/PassiveMonster.cpp
+++ b/source/Mobs/PassiveMonster.cpp
@@ -9,8 +9,8 @@
-cPassiveMonster::cPassiveMonster(const AString & a_ConfigName, char a_ProtocolMobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height) :
- super(a_ConfigName, a_ProtocolMobType, a_SoundHurt, a_SoundDeath, a_Width, a_Height)
+cPassiveMonster::cPassiveMonster(const AString & a_ConfigName, eType a_MobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height) :
+ super(a_ConfigName, a_MobType, a_SoundHurt, a_SoundDeath, a_Width, a_Height)
{
m_EMPersonality = PASSIVE;
}
@@ -56,3 +56,4 @@ void cPassiveMonster::Tick(float a_Dt, cChunk & a_Chunk)
+
diff --git a/source/Mobs/PassiveMonster.h b/source/Mobs/PassiveMonster.h
index ae0bea3fb..14a6be6b1 100644
--- a/source/Mobs/PassiveMonster.h
+++ b/source/Mobs/PassiveMonster.h
@@ -13,12 +13,13 @@ class cPassiveMonster :
typedef cMonster super;
public:
- cPassiveMonster(const AString & a_ConfigName, char a_ProtocolMobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height);
+ cPassiveMonster(const AString & a_ConfigName, eType 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;
/// When hit by someone, run away
virtual void DoTakeDamage(TakeDamageInfo & a_TDI) override;
+
} ;
diff --git a/source/Mobs/Pig.cpp b/source/Mobs/Pig.cpp
index cd18c087f..0871a38a9 100644
--- a/source/Mobs/Pig.cpp
+++ b/source/Mobs/Pig.cpp
@@ -10,7 +10,7 @@
cPig::cPig(void) :
- super("Pig", 90, "mob.pig.say", "mob.pig.death", 0.9, 0.9),
+ super("Pig", mtPig, "mob.pig.say", "mob.pig.death", 0.9, 0.9),
m_bIsSaddled(false)
{
}
@@ -22,6 +22,10 @@ cPig::cPig(void) :
void cPig::GetDrops(cItems & a_Drops, cEntity * a_Killer)
{
AddRandomDropItem(a_Drops, 1, 3, IsOnFire() ? E_ITEM_COOKED_PORKCHOP : E_ITEM_RAW_PORKCHOP);
+ if (m_bIsSaddled)
+ {
+ a_Drops.push_back(cItem(E_ITEM_SADDLE, 1));
+ }
}
diff --git a/source/Mobs/Sheep.cpp b/source/Mobs/Sheep.cpp
index 440c5c2b9..703482ddb 100644
--- a/source/Mobs/Sheep.cpp
+++ b/source/Mobs/Sheep.cpp
@@ -11,7 +11,7 @@
cSheep::cSheep(int a_Color) :
- super("Sheep", 91, "mob.sheep.say", "mob.sheep.say", 0.6, 1.3),
+ super("Sheep", mtSheep, "mob.sheep.say", "mob.sheep.say", 0.6, 1.3),
m_IsSheared(false),
m_WoolColor(a_Color)
{
@@ -33,6 +33,7 @@ void cSheep::GetDrops(cItems & a_Drops, cEntity * a_Killer)
+
void cSheep::OnRightClicked(cPlayer & a_Player)
{
if ((a_Player.GetEquippedItem().m_ItemType == E_ITEM_SHEARS) && (!m_IsSheared))
@@ -46,7 +47,8 @@ void cSheep::OnRightClicked(cPlayer & a_Player)
}
cItems Drops;
- Drops.push_back(cItem(E_BLOCK_WOOL, 4, m_WoolColor));
+ int NumDrops = m_World->GetTickRandomNumber(2) + 1;
+ Drops.push_back(cItem(E_BLOCK_WOOL, NumDrops, m_WoolColor));
m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY(), GetPosZ(), 10);
}
}
@@ -54,3 +56,4 @@ void cSheep::OnRightClicked(cPlayer & a_Player)
+
diff --git a/source/Mobs/Silverfish.h b/source/Mobs/Silverfish.h
index d632ac169..a6e11c49d 100644
--- a/source/Mobs/Silverfish.h
+++ b/source/Mobs/Silverfish.h
@@ -14,7 +14,7 @@ class cSilverfish :
public:
cSilverfish(void) :
- super("Silverfish", 60, "mob.silverfish.hit", "mob.silverfish.kill", 0.3, 0.7)
+ super("Silverfish", mtSilverfish, "mob.silverfish.hit", "mob.silverfish.kill", 0.3, 0.7)
{
}
diff --git a/source/Mobs/Skeleton.cpp b/source/Mobs/Skeleton.cpp
index 6297b867c..37a724848 100644
--- a/source/Mobs/Skeleton.cpp
+++ b/source/Mobs/Skeleton.cpp
@@ -9,7 +9,7 @@
cSkeleton::cSkeleton(bool IsWither) :
- super("Skeleton", 51, "mob.skeleton.hurt", "mob.skeleton.death", 0.6, 1.8),
+ super("Skeleton", mtSkeleton, "mob.skeleton.hurt", "mob.skeleton.death", 0.6, 1.8),
m_bIsWither(IsWither)
{
SetBurnsInDaylight(true);
diff --git a/source/Mobs/Slime.cpp b/source/Mobs/Slime.cpp
index 7a9487a06..19f376c21 100644
--- a/source/Mobs/Slime.cpp
+++ b/source/Mobs/Slime.cpp
@@ -9,7 +9,7 @@
/// Creates a slime of the specified size; size is 1 .. 3, with 1 being the smallest
cSlime::cSlime(int a_Size) :
- super("Slime", 55, "mob.slime.attack", "mob.slime.attack", 0.6 * a_Size, 0.6 * a_Size),
+ super("Slime", mtSlime, "mob.slime.attack", "mob.slime.attack", 0.6 * a_Size, 0.6 * a_Size),
m_Size(a_Size)
{
}
diff --git a/source/Mobs/SnowGolem.cpp b/source/Mobs/SnowGolem.cpp
index 51125542d..9e199f87e 100644
--- a/source/Mobs/SnowGolem.cpp
+++ b/source/Mobs/SnowGolem.cpp
@@ -8,7 +8,7 @@
cSnowGolem::cSnowGolem(void) :
- super("SnowGolem", 97, "", "", 0.4, 1.8)
+ super("SnowGolem", mtSnowGolem, "", "", 0.4, 1.8)
{
}
diff --git a/source/Mobs/Spider.cpp b/source/Mobs/Spider.cpp
index 2f244cdbc..b19a5dcef 100644
--- a/source/Mobs/Spider.cpp
+++ b/source/Mobs/Spider.cpp
@@ -8,7 +8,7 @@
cSpider::cSpider(void) :
- super("Spider", 52, "mob.spider.say", "mob.spider.death", 1.4, 0.9)
+ super("Spider", mtSpider, "mob.spider.say", "mob.spider.death", 1.4, 0.9)
{
}
diff --git a/source/Mobs/Squid.cpp b/source/Mobs/Squid.cpp
index cb796f5ec..a311108ae 100644
--- a/source/Mobs/Squid.cpp
+++ b/source/Mobs/Squid.cpp
@@ -10,7 +10,7 @@
cSquid::cSquid(void) :
- super("Squid", 94, "", "", 0.95, 0.95)
+ super("Squid", mtSquid, "", "", 0.95, 0.95)
{
}
@@ -54,4 +54,3 @@ void cSquid::Tick(float a_Dt, cChunk & a_Chunk)
-
diff --git a/source/Mobs/Squid.h b/source/Mobs/Squid.h
index 35d7295b3..ad299b95c 100644
--- a/source/Mobs/Squid.h
+++ b/source/Mobs/Squid.h
@@ -20,6 +20,7 @@ public:
CLASS_PROTODEF(cSquid);
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override;
+
} ;
diff --git a/source/Mobs/Villager.cpp b/source/Mobs/Villager.cpp
index 97d6dc3ca..7f89fb6cc 100644
--- a/source/Mobs/Villager.cpp
+++ b/source/Mobs/Villager.cpp
@@ -9,7 +9,7 @@
cVillager::cVillager(eVillagerType VillagerType) :
- super("Villager", 120, "", "", 0.6, 1.8),
+ super("Villager", mtVillager, "", "", 0.6, 1.8),
m_Type(VillagerType)
{
}
diff --git a/source/Mobs/Witch.cpp b/source/Mobs/Witch.cpp
index b29783853..25d27041f 100644
--- a/source/Mobs/Witch.cpp
+++ b/source/Mobs/Witch.cpp
@@ -8,7 +8,7 @@
cWitch::cWitch(void) :
- super("Witch", 66, "", "", 0.6, 1.8)
+ super("Witch", mtWitch, "", "", 0.6, 1.8)
{
}
diff --git a/source/Mobs/Wither.cpp b/source/Mobs/Wither.cpp
index 8b77284c8..c46e0beab 100644
--- a/source/Mobs/Wither.cpp
+++ b/source/Mobs/Wither.cpp
@@ -8,7 +8,7 @@
cWither::cWither(void) :
- super("Wither", 64, "mob.wither.hurt", "mob.wither.death", 0.9, 4.0)
+ super("Wither", mtWither, "mob.wither.hurt", "mob.wither.death", 0.9, 4.0)
{
}
diff --git a/source/Mobs/Wolf.cpp b/source/Mobs/Wolf.cpp
index e76f991dc..2baeb4b7b 100644
--- a/source/Mobs/Wolf.cpp
+++ b/source/Mobs/Wolf.cpp
@@ -10,7 +10,7 @@
cWolf::cWolf(void) :
- super("Wolf", 95, "mob.wolf.hurt", "mob.wolf.death", 0.6, 0.8),
+ super("Wolf", mtWolf, "mob.wolf.hurt", "mob.wolf.death", 0.6, 0.8),
m_bIsAngry(false),
m_bIsTame(false),
m_bIsSitting(false),
diff --git a/source/Mobs/Zombie.cpp b/source/Mobs/Zombie.cpp
index f495fe5ee..1752ec390 100644
--- a/source/Mobs/Zombie.cpp
+++ b/source/Mobs/Zombie.cpp
@@ -9,7 +9,7 @@
cZombie::cZombie(bool IsVillagerZombie) :
- super("Zombie", 54, "mob.zombie.hurt", "mob.zombie.death", 0.6, 1.8),
+ super("Zombie", mtZombie, "mob.zombie.hurt", "mob.zombie.death", 0.6, 1.8),
m_bIsConverting(false),
m_bIsVillagerZombie(IsVillagerZombie)
{
diff --git a/source/Mobs/Zombiepigman.cpp b/source/Mobs/Zombiepigman.cpp
index 1e31a72d9..6ac89ed4c 100644
--- a/source/Mobs/Zombiepigman.cpp
+++ b/source/Mobs/Zombiepigman.cpp
@@ -9,7 +9,7 @@
cZombiePigman::cZombiePigman(void) :
- super("ZombiePigman", 57, "mob.zombiepig.zpighurt", "mob.zombiepig.zpigdeath", 0.6, 1.8)
+ super("ZombiePigman", mtZombiePigman, "mob.zombiepig.zpighurt", "mob.zombiepig.zpigdeath", 0.6, 1.8)
{
}