From d07ef85ee310486c07ce9905ef66c1cb31549617 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 12 Sep 2014 16:41:23 +0200 Subject: [PATCH] Spawn exp if you break a mob spawner. --- src/Blocks/BlockHandler.cpp | 2 ++ src/Blocks/BlockMobSpawner.h | 40 ++++++++++++++++++++++++++++++++++++ src/Blocks/WorldInterface.h | 3 +++ src/Items/ItemPickaxe.h | 1 + src/Protocol/Protocol17x.cpp | 6 +++--- src/World.h | 2 +- 6 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 src/Blocks/BlockMobSpawner.h diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 34925a252..8a8bdd3c8 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -47,6 +47,7 @@ #include "BlockLilypad.h" #include "BlockLever.h" #include "BlockMelon.h" +#include "BlockMobSpawner.h" #include "BlockMushroom.h" #include "BlockMycelium.h" #include "BlockNetherWart.h" @@ -244,6 +245,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) case E_BLOCK_LOG: return new cBlockSidewaysHandler (a_BlockType); case E_BLOCK_MELON: return new cBlockMelonHandler (a_BlockType); case E_BLOCK_MELON_STEM: return new cBlockStemsHandler (a_BlockType); + case E_BLOCK_MOB_SPAWNER: return new cBlockMobSpawnerHandler (a_BlockType); case E_BLOCK_MYCELIUM: return new cBlockMyceliumHandler (a_BlockType); case E_BLOCK_NETHER_BRICK_STAIRS: return new cBlockStairsHandler (a_BlockType); case E_BLOCK_NETHER_PORTAL: return new cBlockPortalHandler (a_BlockType); diff --git a/src/Blocks/BlockMobSpawner.h b/src/Blocks/BlockMobSpawner.h new file mode 100644 index 000000000..a51fbaafc --- /dev/null +++ b/src/Blocks/BlockMobSpawner.h @@ -0,0 +1,40 @@ + +#pragma once + +#include "BlockHandler.h" +#include "../World.h" +#include "../Items/ItemHandler.h" + + + + + +class cBlockMobSpawnerHandler : + public cBlockHandler +{ +public: + cBlockMobSpawnerHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + // No pickups + } + + + virtual void OnDestroyedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override + { + cItemHandler * Handler = a_Player->GetEquippedItem().GetHandler(); + if (a_Player->IsGameModeCreative() || !Handler->CanHarvestBlock(E_BLOCK_MOB_SPAWNER)) + { + return; + } + + cFastRandom Random; + int Reward = 15 + Random.NextInt(15) + Random.NextInt(15); + a_WorldInterface.SpawnExperienceOrb((double)a_BlockX, (double)a_BlockY + 1, (double)a_BlockZ, Reward); + } +} ; diff --git a/src/Blocks/WorldInterface.h b/src/Blocks/WorldInterface.h index b43d011d8..889ef1d87 100644 --- a/src/Blocks/WorldInterface.h +++ b/src/Blocks/WorldInterface.h @@ -35,6 +35,9 @@ public: /** Spawns a mob of the specified type. Returns the mob's EntityID if recognized and spawned, <0 otherwise */ virtual int SpawnMob(double a_PosX, double a_PosY, double a_PosZ, cMonster::eType a_MonsterType) = 0; + /** Spawns an experience orb at the given location with the given reward. It returns the UniqueID of the spawned experience orb. */ + virtual int SpawnExperienceOrb(double a_X, double a_Y, double a_Z, int a_Reward) = 0; + /** Calls the callback for the block entity at the specified coords; returns false if there's no block entity at those coords, true if found */ virtual bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback) = 0; diff --git a/src/Items/ItemPickaxe.h b/src/Items/ItemPickaxe.h index 17fd96822..e0cf5d711 100644 --- a/src/Items/ItemPickaxe.h +++ b/src/Items/ItemPickaxe.h @@ -81,6 +81,7 @@ public: case E_BLOCK_STONE_BRICK_STAIRS: case E_BLOCK_NETHER_BRICK_STAIRS: case E_BLOCK_CAULDRON: + case E_BLOCK_MOB_SPAWNER: { return PickaxeLevel() >= 1; } diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index f24ef320d..f07f6a928 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -1033,9 +1033,9 @@ void cProtocol172::SendExperienceOrb(const cExpOrb & a_ExpOrb) cPacketizer Pkt(*this, 0x11); Pkt.WriteVarInt(a_ExpOrb.GetUniqueID()); - Pkt.WriteInt((int) a_ExpOrb.GetPosX()); - Pkt.WriteInt((int) a_ExpOrb.GetPosY()); - Pkt.WriteInt((int) a_ExpOrb.GetPosZ()); + Pkt.WriteFPInt(a_ExpOrb.GetPosX()); + Pkt.WriteFPInt(a_ExpOrb.GetPosY()); + Pkt.WriteFPInt(a_ExpOrb.GetPosZ()); Pkt.WriteShort(a_ExpOrb.GetReward()); } diff --git a/src/World.h b/src/World.h index 274bd2dcf..0c57e6611 100644 --- a/src/World.h +++ b/src/World.h @@ -469,7 +469,7 @@ public: int SpawnMinecart(double a_X, double a_Y, double a_Z, int a_MinecartType, const cItem & a_Content = cItem(), int a_BlockHeight = 1); /** Spawns an experience orb at the given location with the given reward. It returns the UniqueID of the spawned experience orb. */ - int SpawnExperienceOrb(double a_X, double a_Y, double a_Z, int a_Reward); + virtual int SpawnExperienceOrb(double a_X, double a_Y, double a_Z, int a_Reward) override; /** Spawns a new primed TNT entity at the specified block coords and specified fuse duration. Initial velocity is given based on the relative coefficient provided */ void SpawnPrimedTNT(double a_X, double a_Y, double a_Z, int a_FuseTimeInSec = 80, double a_InitialVelocityCoeff = 1);