diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Bindings/ManualBindings.cpp | 29 | ||||
-rw-r--r-- | src/BlockEntities/DropSpenserEntity.h | 11 | ||||
-rw-r--r-- | src/BlockEntities/NoteEntity.h | 13 | ||||
-rw-r--r-- | src/BlockEntities/RedstonePoweredEntity.h | 13 | ||||
-rw-r--r-- | src/BlockInfo.cpp | 1 | ||||
-rw-r--r-- | src/Chunk.cpp | 35 | ||||
-rw-r--r-- | src/Chunk.h | 6 | ||||
-rw-r--r-- | src/ClientHandle.cpp | 8 | ||||
-rw-r--r-- | src/Entities/EnderCrystal.cpp | 6 | ||||
-rw-r--r-- | src/Items/ItemHandler.cpp | 2 | ||||
-rw-r--r-- | src/Simulator/IncrementalRedstoneSimulator.cpp | 26 |
11 files changed, 124 insertions, 26 deletions
diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 5563fb14a..f50bdd7de 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -82,6 +82,33 @@ static int lua_do_error(lua_State* L, const char * a_pFormat, ...) // Lua bound functions with special return types +static int tolua_Clamp(lua_State * tolua_S) +{ + cLuaState LuaState(tolua_S); + int NumArgs = lua_gettop(LuaState); + if (NumArgs != 3) + { + return lua_do_error(LuaState, "Error in function call '#funcname#': Requires 3 arguments, got %i", NumArgs); + } + + if (!lua_isnumber(LuaState, 1) || !lua_isnumber(LuaState, 2) || !lua_isnumber(LuaState, 3)) + { + return lua_do_error(LuaState, "Error in function call '#funcname#': Expected a number for parameters #1, #2 and #3"); + } + + lua_Number Number = tolua_tonumber(LuaState, 1, 0); + lua_Number Min = tolua_tonumber(LuaState, 2, 0); + lua_Number Max = tolua_tonumber(LuaState, 3, 0); + + lua_Number Result = Clamp(Number, Min, Max); + LuaState.Push(Result); + return 1; +} + + + + + static int tolua_StringSplit(lua_State * tolua_S) { cLuaState LuaState(tolua_S); @@ -480,7 +507,6 @@ static int tolua_DoWithXYZ(lua_State* tolua_S) int ItemX = ((int)tolua_tonumber(tolua_S, 2, 0)); int ItemY = ((int)tolua_tonumber(tolua_S, 3, 0)); int ItemZ = ((int)tolua_tonumber(tolua_S, 4, 0)); - LOG("x %i y %i z %i", ItemX, ItemY, ItemZ); if (!lua_isfunction( tolua_S, 5)) { return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a function for parameter #4"); @@ -3103,6 +3129,7 @@ static int tolua_cCompositeChat_UnderlineUrls(lua_State * tolua_S) void ManualBindings::Bind(lua_State * tolua_S) { tolua_beginmodule(tolua_S, NULL); + tolua_function(tolua_S, "Clamp", tolua_Clamp); tolua_function(tolua_S, "StringSplit", tolua_StringSplit); tolua_function(tolua_S, "StringSplitAndTrim", tolua_StringSplitAndTrim); tolua_function(tolua_S, "LOG", tolua_LOG); diff --git a/src/BlockEntities/DropSpenserEntity.h b/src/BlockEntities/DropSpenserEntity.h index 9f58d0b07..be56447aa 100644 --- a/src/BlockEntities/DropSpenserEntity.h +++ b/src/BlockEntities/DropSpenserEntity.h @@ -11,7 +11,7 @@ #pragma once #include "BlockEntityWithItems.h" - +#include "RedstonePoweredEntity.h" @@ -31,6 +31,9 @@ class cServer; // tolua_begin class cDropSpenserEntity : public cBlockEntityWithItems + // tolua_end + , public cRedstonePoweredEntity + // tolua_begin { typedef cBlockEntityWithItems super; @@ -64,10 +67,10 @@ public: /// Sets the dropspenser to dropspense an item in the next tick void Activate(void); - /// Sets the internal redstone power flag to "on" or "off", depending on the parameter. Calls Activate() if appropriate - void SetRedstonePower(bool a_IsPowered); - // tolua_end + + /// Sets the internal redstone power flag to "on" or "off", depending on the parameter. Calls Activate() if appropriate + virtual void SetRedstonePower(bool a_IsPowered) override; protected: bool m_ShouldDropSpense; ///< If true, the dropspenser will dropspense an item in the next tick diff --git a/src/BlockEntities/NoteEntity.h b/src/BlockEntities/NoteEntity.h index e8497da3e..f538de060 100644 --- a/src/BlockEntities/NoteEntity.h +++ b/src/BlockEntities/NoteEntity.h @@ -2,6 +2,7 @@ #pragma once #include "BlockEntity.h" +#include "RedstonePoweredEntity.h" namespace Json @@ -30,6 +31,9 @@ enum ENUM_NOTE_INSTRUMENTS class cNoteEntity : public cBlockEntity + // tolua_end + , public cRedstonePoweredEntity + // tolua_begin { typedef cBlockEntity super; public: @@ -38,6 +42,7 @@ public: /// Creates a new note entity. a_World may be NULL cNoteEntity(int a_X, int a_Y, int a_Z, cWorld * a_World); + virtual ~cNoteEntity() {} bool LoadFromJson(const Json::Value & a_Value); virtual void SaveToJson(Json::Value & a_Value) override; @@ -53,6 +58,14 @@ public: virtual void UsedBy(cPlayer * a_Player) override; virtual void SendTo(cClientHandle &) override {} + + virtual void SetRedstonePower(bool a_Value) + { + if (a_Value) + { + MakeSound(); + } + } static const char * GetClassStatic(void) { return "cNoteEntity"; } diff --git a/src/BlockEntities/RedstonePoweredEntity.h b/src/BlockEntities/RedstonePoweredEntity.h new file mode 100644 index 000000000..f11df4fc4 --- /dev/null +++ b/src/BlockEntities/RedstonePoweredEntity.h @@ -0,0 +1,13 @@ + +#pragma once + +// Interface class representing a blockEntity that responds to redstone +class cRedstonePoweredEntity +{ +public: + + virtual ~cRedstonePoweredEntity() {}; + + /// Sets the internal redstone power flag to "on" or "off", depending on the parameter. Calls Activate() if appropriate + virtual void SetRedstonePower(bool a_IsPowered) = 0; +}; diff --git a/src/BlockInfo.cpp b/src/BlockInfo.cpp index 4bc3fbbdc..a59229f87 100644 --- a/src/BlockInfo.cpp +++ b/src/BlockInfo.cpp @@ -294,6 +294,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_OneHitDig = true; a_Info[E_BLOCK_LILY_PAD ].m_OneHitDig = true; a_Info[E_BLOCK_MELON_STEM ].m_OneHitDig = true; + a_Info[E_BLOCK_NETHER_WART ].m_OneHitDig = true; a_Info[E_BLOCK_POTATOES ].m_OneHitDig = true; a_Info[E_BLOCK_PUMPKIN_STEM ].m_OneHitDig = true; a_Info[E_BLOCK_REDSTONE_REPEATER_OFF].m_OneHitDig = true; diff --git a/src/Chunk.cpp b/src/Chunk.cpp index cd7dc698c..a79a485a6 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -2127,6 +2127,41 @@ bool cChunk::DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBloc +bool cChunk::DoWithRedstonePoweredEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cRedstonePoweredCallback & a_Callback) +{ + // The blockentity list is locked by the parent chunkmap's CS + for (cBlockEntityList::iterator itr = m_BlockEntities.begin(), itr2 = itr; itr != m_BlockEntities.end(); itr = itr2) + { + ++itr2; + if (((*itr)->GetPosX() != a_BlockX) || ((*itr)->GetPosY() != a_BlockY) || ((*itr)->GetPosZ() != a_BlockZ)) + { + continue; + } + switch ((*itr)->GetBlockType()) + { + case E_BLOCK_DROPPER: + case E_BLOCK_DISPENSER: + case E_BLOCK_NOTE_BLOCK: + break; + default: + // There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out + return false; + } + + if (a_Callback.Item((cRedstonePoweredEntity *)*itr)) + { + return false; + } + return true; + } // for itr - m_BlockEntitites[] + + // Not found: + return false; +} + + + + bool cChunk::DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCallback & a_Callback) { // The blockentity list is locked by the parent chunkmap's CS diff --git a/src/Chunk.h b/src/Chunk.h index 5cde3f08f..813a8b13f 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -43,6 +43,7 @@ class cBlockArea; class cFluidSimulatorData; class cMobCensus; class cMobSpawner; +class cRedstonePoweredEntity; typedef std::list<cClientHandle *> cClientHandleList; typedef cItemCallback<cEntity> cEntityCallback; @@ -54,6 +55,7 @@ typedef cItemCallback<cNoteEntity> cNoteBlockCallback; typedef cItemCallback<cCommandBlockEntity> cCommandBlockCallback; typedef cItemCallback<cMobHeadEntity> cMobHeadCallback; typedef cItemCallback<cFlowerPotEntity> cFlowerPotCallback; +typedef cItemCallback<cRedstonePoweredEntity> cRedstonePoweredCallback; @@ -237,7 +239,9 @@ public: /** 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 */ bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback); // Lua-acessible - + + /** Calls the callback for the redstone powered entity at the specified coords; returns false if there's no redstone powered entity at those coords, true if found */ + bool DoWithRedstonePoweredEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cRedstonePoweredCallback & a_Callback); /** Calls the callback for the beacon at the specified coords; returns false if there's no beacon at those coords, true if found */ bool DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCallback & a_Callback); // Lua-acessible diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 72257028a..3e046f38d 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -920,6 +920,10 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, eB ) { m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); + if (cBlockInfo::GetHandler(m_Player->GetWorld()->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ))->IsClickedThrough()) + { + m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY + 1, a_BlockZ, m_Player); + } return; } @@ -928,6 +932,10 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, eB { // A plugin doesn't agree with the action, replace the block on the client and quit: m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); + if (cBlockInfo::GetHandler(m_Player->GetWorld()->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ))->IsClickedThrough()) + { + m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY + 1, a_BlockZ, m_Player); + } return; } diff --git a/src/Entities/EnderCrystal.cpp b/src/Entities/EnderCrystal.cpp index bf86a6c42..c17bb608e 100644 --- a/src/Entities/EnderCrystal.cpp +++ b/src/Entities/EnderCrystal.cpp @@ -32,9 +32,6 @@ void cEnderCrystal::SpawnOn(cClientHandle & a_ClientHandle) void cEnderCrystal::Tick(float a_Dt, cChunk & a_Chunk) { UNUSED(a_Dt); - - a_Chunk.SetBlock(POSX_TOINT, POSY_TOINT, POSZ_TOINT, E_BLOCK_FIRE, 0); - // No further processing (physics e.t.c.) is needed } @@ -49,6 +46,9 @@ void cEnderCrystal::KilledBy(TakeDamageInfo & a_TDI) m_World->DoExplosionAt(6.0, GetPosX(), GetPosY(), GetPosZ(), true, esEnderCrystal, this); Destroy(); + + m_World->SetBlock(POSX_TOINT, POSY_TOINT, POSZ_TOINT, E_BLOCK_BEDROCK, 0); + m_World->SetBlock(POSX_TOINT, POSY_TOINT + 1, POSZ_TOINT, E_BLOCK_FIRE, 0); } diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp index 1c1e3b5b9..bceedaf69 100644 --- a/src/Items/ItemHandler.cpp +++ b/src/Items/ItemHandler.cpp @@ -66,7 +66,7 @@ cItemHandler * cItemHandler::m_ItemHandler[2268]; cItemHandler * cItemHandler::GetItemHandler(int a_ItemType) { - if ((a_ItemType < 0) || ((unsigned long)a_ItemType >= ARRAYCOUNT(m_ItemHandler))) + if ((a_ItemType < 0) || ((size_t)a_ItemType >= ARRAYCOUNT(m_ItemHandler))) { // Either nothing (-1), or bad value, both cases should return the air handler if (a_ItemType < -1) diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index c1a2fcaae..7b3a2c2fa 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -3,11 +3,9 @@ #include "IncrementalRedstoneSimulator.h" #include "BoundingBox.h" -#include "../BlockEntities/DropSpenserEntity.h" -#include "../BlockEntities/NoteEntity.h" +#include "../BlockEntities/RedstonePoweredEntity.h" #include "../BlockEntities/ChestEntity.h" #include "../BlockEntities/CommandBlockEntity.h" -#include "../Entities/TNTEntity.h" #include "../Entities/Pickup.h" #include "../Blocks/BlockTorch.h" #include "../Blocks/BlockDoor.h" @@ -842,13 +840,13 @@ void cIncrementalRedstoneSimulator::HandlePiston(int a_RelBlockX, int a_RelBlock void cIncrementalRedstoneSimulator::HandleDropSpenser(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) { class cSetPowerToDropSpenser : - public cDropSpenserCallback + public cRedstonePoweredCallback { bool m_IsPowered; public: cSetPowerToDropSpenser(bool a_IsPowered) : m_IsPowered(a_IsPowered) {} - virtual bool Item(cDropSpenserEntity * a_DropSpenser) override + virtual bool Item(cRedstonePoweredEntity * a_DropSpenser) override { a_DropSpenser->SetRedstonePower(m_IsPowered); return false; @@ -857,7 +855,7 @@ void cIncrementalRedstoneSimulator::HandleDropSpenser(int a_RelBlockX, int a_Rel int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; - m_Chunk->DoWithDropSpenserAt(BlockX, a_RelBlockY, BlockZ, DrSpSP); + m_Chunk->DoWithRedstonePoweredEntityAt(BlockX, a_RelBlockY, BlockZ, DrSpSP); } @@ -1034,25 +1032,21 @@ void cIncrementalRedstoneSimulator::HandleNoteBlock(int a_RelBlockX, int a_RelBl if (!AreCoordsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true)) { class cSetPowerToNoteBlock : - public cNoteBlockCallback + public cRedstonePoweredCallback { - bool m_IsPowered; public: - cSetPowerToNoteBlock(bool a_IsPowered) : m_IsPowered(a_IsPowered) {} + cSetPowerToNoteBlock() {} - virtual bool Item(cNoteEntity * a_NoteBlock) override + virtual bool Item(cRedstonePoweredEntity * a_NoteBlock) override { - if (m_IsPowered) - { - a_NoteBlock->MakeSound(); - } + a_NoteBlock->SetRedstonePower(true); return false; } - } NoteBlockSP(m_bAreCoordsPowered); + } NoteBlockSP; int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; - m_Chunk->DoWithNoteBlockAt(BlockX, a_RelBlockY, BlockZ, NoteBlockSP); + m_Chunk->DoWithRedstonePoweredEntityAt(BlockX, a_RelBlockY, BlockZ, NoteBlockSP); SetPlayerToggleableBlockAsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true); } } |