summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandrew <xdotftw@gmail.com>2014-03-25 09:32:58 +0100
committerandrew <xdotftw@gmail.com>2014-03-25 09:32:58 +0100
commit0fe1e50ffc744d861744e4aa4905e1b4b15e10fd (patch)
tree20bb1e5c88cf412a3b3edb2608c4aedb6c1e5497
parentMinor fixes (diff)
downloadcuberite-0fe1e50ffc744d861744e4aa4905e1b4b15e10fd.tar
cuberite-0fe1e50ffc744d861744e4aa4905e1b4b15e10fd.tar.gz
cuberite-0fe1e50ffc744d861744e4aa4905e1b4b15e10fd.tar.bz2
cuberite-0fe1e50ffc744d861744e4aa4905e1b4b15e10fd.tar.lz
cuberite-0fe1e50ffc744d861744e4aa4905e1b4b15e10fd.tar.xz
cuberite-0fe1e50ffc744d861744e4aa4905e1b4b15e10fd.tar.zst
cuberite-0fe1e50ffc744d861744e4aa4905e1b4b15e10fd.zip
-rw-r--r--src/Blocks/BlockMobHead.h82
-rw-r--r--src/Mobs/Wither.cpp16
-rw-r--r--src/Mobs/Wither.h3
-rw-r--r--src/Protocol/Protocol125.cpp8
-rw-r--r--src/Protocol/Protocol17x.cpp10
5 files changed, 116 insertions, 3 deletions
diff --git a/src/Blocks/BlockMobHead.h b/src/Blocks/BlockMobHead.h
index 6aa01f986..9935c2496 100644
--- a/src/Blocks/BlockMobHead.h
+++ b/src/Blocks/BlockMobHead.h
@@ -22,14 +22,90 @@ public:
a_Pickups.push_back(cItem(E_ITEM_HEAD, 1, 0));
}
- bool TrySpawnWither(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
+ bool TrySpawnWither(cChunkInterface & a_ChunkInterface, cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
{
if (a_BlockY < 2)
{
return false;
}
+
+ class cCallback : public cMobHeadCallback
+ {
+ bool m_IsWither;
+
+ virtual bool Item (cMobHeadEntity * a_MobHeadEntity)
+ {
+ m_IsWither = (a_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;
+
+ 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;
+ }
- // TODO 2014-03-24 xdot
+ a_World->DoWithMobHeadAt(a_BlockX - 1, a_BlockY, a_BlockZ, CallbackA);
+ a_World->DoWithMobHeadAt(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_World->SetBlock(a_BlockX + 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
+ a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
+ a_World->SetBlock(a_BlockX - 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
+
+ // Spawn the wither:
+ a_World->SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither);
+
+ return true;
+ }
+
+ CallbackA.Reset();
+ CallbackB.Reset();
+
+ a_World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ - 1, CallbackA);
+ a_World->DoWithMobHeadAt(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_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ + 1, E_BLOCK_AIR, 0);
+ a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
+ a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ - 1, E_BLOCK_AIR, 0);
+
+ // Spawn the wither:
+ a_World->SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither);
+
+ return true;
+ }
return false;
}
@@ -75,7 +151,7 @@ public:
World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, Callback);
a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, a_BlockMeta);
- TrySpawnWither(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ);
+ TrySpawnWither(a_ChunkInterface, World, a_BlockX, a_BlockY, a_BlockZ);
}
} ;
diff --git a/src/Mobs/Wither.cpp b/src/Mobs/Wither.cpp
index 0e42194ac..790f127f2 100644
--- a/src/Mobs/Wither.cpp
+++ b/src/Mobs/Wither.cpp
@@ -21,6 +21,15 @@ cWither::cWither(void) :
+bool cWither::IsArmored(void) const
+{
+ return GetHealth() <= (GetMaxHealth() / 2);
+}
+
+
+
+
+
void cWither::DoTakeDamage(TakeDamageInfo & a_TDI)
{
if (a_TDI.DamageType == dtDrowning)
@@ -33,6 +42,11 @@ void cWither::DoTakeDamage(TakeDamageInfo & a_TDI)
return;
}
+ if (IsArmored() && (a_TDI.DamageType == dtRangedAttack))
+ {
+ return;
+ }
+
super::DoTakeDamage(a_TDI);
}
@@ -60,6 +74,8 @@ void cWither::Tick(float a_Dt, cChunk & a_Chunk)
Heal(10);
}
}
+
+ m_World->BroadcastEntityMetadata(*this);
}
diff --git a/src/Mobs/Wither.h b/src/Mobs/Wither.h
index d09e3607a..52666a190 100644
--- a/src/Mobs/Wither.h
+++ b/src/Mobs/Wither.h
@@ -20,6 +20,9 @@ public:
unsigned int GetNumInvulnerableTicks(void) const { return m_InvulnerableTicks; }
void SetNumInvulnerableTicks(unsigned int a_Ticks) { m_InvulnerableTicks = a_Ticks; }
+
+ /** Returns whether the wither is invulnerable to arrows. */
+ bool IsArmored(void) const;
// cEntity overrides
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override;
diff --git a/src/Protocol/Protocol125.cpp b/src/Protocol/Protocol125.cpp
index 69f4934d8..d8b340350 100644
--- a/src/Protocol/Protocol125.cpp
+++ b/src/Protocol/Protocol125.cpp
@@ -1972,6 +1972,14 @@ void cProtocol125::WriteMobMetadata(const cMonster & a_Mob)
WriteByte(((const cWitch &)a_Mob).IsAngry() ? 1 : 0); // Aggravated? Doesn't seem to do anything
break;
}
+ case cMonster::mtWither:
+ {
+ WriteByte(0x54); // Int at index 20
+ WriteInt(((const cWither &)a_Mob).GetNumInvulnerableTicks());
+ WriteByte(0x66); // Float at index 6
+ WriteFloat((float)(a_Mob.GetHealth()));
+ break;
+ }
case cMonster::mtSlime:
case cMonster::mtMagmaCube:
{
diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp
index 721ed349e..c678fc9a0 100644
--- a/src/Protocol/Protocol17x.cpp
+++ b/src/Protocol/Protocol17x.cpp
@@ -2535,6 +2535,7 @@ void cProtocol172::cPacketizer::WriteEntityMetadata(const cEntity & a_Entity)
WriteByte(Frame.GetRotation());
break;
}
+ default: break;
}
}
@@ -2659,6 +2660,15 @@ void cProtocol172::cPacketizer::WriteMobMetadata(const cMonster & a_Mob)
WriteByte(((const cWitch &)a_Mob).IsAngry() ? 1 : 0);
break;
}
+
+ case cMonster::mtWither:
+ {
+ WriteByte(0x54); // Int at index 20
+ WriteInt(((const cWither &)a_Mob).GetNumInvulnerableTicks());
+ WriteByte(0x66); // Float at index 6
+ WriteFloat((float)(a_Mob.GetHealth()));
+ break;
+ }
case cMonster::mtSlime:
{