From b18f6637b6c58db20353cd3e77584b646ab36b5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Beltr=C3=A1n?= Date: Mon, 21 Aug 2017 10:46:41 +0200 Subject: Fully implemented leashes (#3798) --- src/Blocks/BlockFence.h | 62 ++++++++++++++++++++++++++++++++++++++++++++- src/Blocks/WorldInterface.h | 5 ++++ 2 files changed, 66 insertions(+), 1 deletion(-) (limited to 'src/Blocks') diff --git a/src/Blocks/BlockFence.h b/src/Blocks/BlockFence.h index 736466e99..2f2d4e46d 100644 --- a/src/Blocks/BlockFence.h +++ b/src/Blocks/BlockFence.h @@ -3,7 +3,10 @@ #include "BlockHandler.h" #include "../BoundingBox.h" - +#include "../EffectID.h" +#include "Entities/LeashKnot.h" +#include "BoundingBox.h" +#include "../Mobs/PassiveMonster.h" @@ -72,6 +75,63 @@ public: return PlacementBox; } + + virtual bool OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override + { + auto LeashKnot = cLeashKnot::FindKnotAtPos(*a_Player.GetWorld(), { a_BlockX, a_BlockY, a_BlockZ }); + auto KnotAlreadyExists = (LeashKnot != nullptr); + + if (KnotAlreadyExists) + { + // Check leashed nearby mobs to leash them to the knot + LeashKnot->TiePlayersLeashedMobs(a_Player, KnotAlreadyExists); + } + // New knot? needs to init and produce sound effect + else + { + auto NewLeashKnot = cpp14::make_unique(a_BlockFace, a_BlockX, a_BlockY, a_BlockZ); + auto NewLeashKnotPtr = NewLeashKnot.get(); + + NewLeashKnotPtr->TiePlayersLeashedMobs(a_Player, KnotAlreadyExists); + + // Only put the knot in the world if any mob has been leashed to + if (NewLeashKnotPtr->HasAnyMobLeashed()) + { + if (!NewLeashKnotPtr->Initialize(std::move(NewLeashKnot), *a_Player.GetWorld())) + { + return false; + } + a_Player.GetWorld()->BroadcastSoundEffect("entity.leashknot.place", a_Player.GetPosX(), a_Player.GetPosY(), a_Player.GetPosZ(), 1, 1); + } + else + { + return false; + } + } + + return true; + } + + virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override + { + a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player); + } + + virtual bool IsUseable(void) override + { + return true; + } + + virtual void OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ) + { + auto LeashKnot = cLeashKnot::FindKnotAtPos(a_WorldInterface, { a_BlockX, a_BlockY, a_BlockZ }); + + if (LeashKnot != nullptr) + { + LeashKnot->SetShouldSelfDestroy(); + } + } + }; diff --git a/src/Blocks/WorldInterface.h b/src/Blocks/WorldInterface.h index 1300ffe8c..0c92a64e5 100644 --- a/src/Blocks/WorldInterface.h +++ b/src/Blocks/WorldInterface.h @@ -53,6 +53,11 @@ public: /** Calls the callback for each player in the list; returns true if all players processed, false if the callback aborted by returning true */ virtual bool ForEachPlayer(cItemCallback & a_Callback) = 0; + /** Calls the callback for each entity that has a nonempty intersection with the specified boundingbox. + Returns true if all entities processed, false if the callback aborted by returning true. + If any chunk in the box is missing, ignores the entities in that chunk silently. */ + virtual bool ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback & a_Callback) = 0; + virtual void SetTimeOfDay(int a_TimeOfDay) = 0; /** Returns true if it is raining, stormy or snowing at the specified location. This takes into account biomes. */ -- cgit v1.2.3