1
0

Merge remote-tracking branch 'origin/master' into Ranks

This commit is contained in:
madmaxoft 2014-08-09 14:25:49 +02:00
commit 4b1505f39d
12 changed files with 127 additions and 28 deletions

View File

@ -2760,15 +2760,16 @@ end
Functions = Functions =
{ {
AddFaceDirection = {Params = "BlockX, BlockY, BlockZ, BlockFace, [IsInverse]", Return = "BlockX, BlockY, BlockZ", Notes = "Returns the coords of a block adjacent to the specified block through the specified {{Globals#BlockFaces|face}}"}, AddFaceDirection = {Params = "BlockX, BlockY, BlockZ, BlockFace, [IsInverse]", Return = "BlockX, BlockY, BlockZ", Notes = "Returns the coords of a block adjacent to the specified block through the specified {{Globals#BlockFaces|face}}"},
BlockFaceToString = { Params = "{{Globals#BlockFaces|eBlockFace}}", Return = "string", Notes = "Returns the string representation of the {{Globals#BlockFaces|eBlockFace}} constant. Uses the axis-direction-based names, such as BLOCK_FACE_XP." }, BlockFaceToString = {Params = "{{Globals#BlockFaces|eBlockFace}}", Return = "string", Notes = "Returns the string representation of the {{Globals#BlockFaces|eBlockFace}} constant. Uses the axis-direction-based names, such as BLOCK_FACE_XP." },
BlockStringToType = {Params = "BlockTypeString", Return = "BLOCKTYPE", Notes = "Returns the block type parsed from the given string"}, BlockStringToType = {Params = "BlockTypeString", Return = "BLOCKTYPE", Notes = "Returns the block type parsed from the given string"},
Clamp = {Params = "Number, Min, Max", Return = "number", Notes = "Clamp the number to the specified range."},
ClickActionToString = {Params = "{{Globals#ClickAction|ClickAction}}", Return = "string", Notes = "Returns a string description of the ClickAction enumerated value"}, ClickActionToString = {Params = "{{Globals#ClickAction|ClickAction}}", Return = "string", Notes = "Returns a string description of the ClickAction enumerated value"},
DamageTypeToString = {Params = "{{Globals#DamageType|DamageType}}", Return = "string", Notes = "Converts the {{Globals#DamageType|DamageType}} enumerated value to a string representation "}, DamageTypeToString = {Params = "{{Globals#DamageType|DamageType}}", Return = "string", Notes = "Converts the {{Globals#DamageType|DamageType}} enumerated value to a string representation "},
EscapeString = {Params = "string", Return = "string", Notes = "Returns a copy of the string with all quotes and backslashes escaped by a backslash"}, EscapeString = {Params = "string", Return = "string", Notes = "Returns a copy of the string with all quotes and backslashes escaped by a backslash"},
GetChar = {Params = "String, Pos", Return = "string", Notes = "Returns one character from the string, specified by position "}, GetChar = {Params = "String, Pos", Return = "string", Notes = "Returns one character from the string, specified by position "},
GetIniItemSet = { Params = "IniFile, SectionName, KeyName, DefaultValue", Return = "{{cItem}}", Notes = "Returns the item that has been read from the specified INI file value. If the value is not present in the INI file, the DefaultValue is stored in the file and parsed as the result. Returns empty item if the value cannot be parsed. " }, GetIniItemSet = { Params = "IniFile, SectionName, KeyName, DefaultValue", Return = "{{cItem}}", Notes = "Returns the item that has been read from the specified INI file value. If the value is not present in the INI file, the DefaultValue is stored in the file and parsed as the result. Returns empty item if the value cannot be parsed. " },
GetTime = {Return = "number", Notes = "Returns the current OS time, as a unix time stamp (number of seconds since Jan 1, 1970)"}, GetTime = {Return = "number", Notes = "Returns the current OS time, as a unix time stamp (number of seconds since Jan 1, 1970)"},
IsBiomeNoDownfall = { Params = "Biome", Return = "bool", Notes = "Returns true if the biome is 'dry', that is, there is no precipitation during rains and storms." }, IsBiomeNoDownfall = {Params = "Biome", Return = "bool", Notes = "Returns true if the biome is 'dry', that is, there is no precipitation during rains and storms." },
IsValidBlock = {Params = "BlockType", Return = "bool", Notes = "Returns true if BlockType is a known block type"}, IsValidBlock = {Params = "BlockType", Return = "bool", Notes = "Returns true if BlockType is a known block type"},
IsValidItem = {Params = "ItemType", Return = "bool", Notes = "Returns true if ItemType is a known item type"}, IsValidItem = {Params = "ItemType", Return = "bool", Notes = "Returns true if ItemType is a known item type"},
ItemToFullString = {Params = "{{cItem|cItem}}", Return = "string", Notes = "Returns the string representation of the item, in the format 'ItemTypeText:ItemDamage * Count'"}, ItemToFullString = {Params = "{{cItem|cItem}}", Return = "string", Notes = "Returns the string representation of the item, in the format 'ItemTypeText:ItemDamage * Count'"},

View File

@ -82,6 +82,33 @@ static int lua_do_error(lua_State* L, const char * a_pFormat, ...)
// Lua bound functions with special return types // 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) static int tolua_StringSplit(lua_State * tolua_S)
{ {
cLuaState LuaState(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 ItemX = ((int)tolua_tonumber(tolua_S, 2, 0));
int ItemY = ((int)tolua_tonumber(tolua_S, 3, 0)); int ItemY = ((int)tolua_tonumber(tolua_S, 3, 0));
int ItemZ = ((int)tolua_tonumber(tolua_S, 4, 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)) if (!lua_isfunction( tolua_S, 5))
{ {
return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a function for parameter #4"); 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) void ManualBindings::Bind(lua_State * tolua_S)
{ {
tolua_beginmodule(tolua_S, NULL); tolua_beginmodule(tolua_S, NULL);
tolua_function(tolua_S, "Clamp", tolua_Clamp);
tolua_function(tolua_S, "StringSplit", tolua_StringSplit); tolua_function(tolua_S, "StringSplit", tolua_StringSplit);
tolua_function(tolua_S, "StringSplitAndTrim", tolua_StringSplitAndTrim); tolua_function(tolua_S, "StringSplitAndTrim", tolua_StringSplitAndTrim);
tolua_function(tolua_S, "LOG", tolua_LOG); tolua_function(tolua_S, "LOG", tolua_LOG);

View File

@ -11,7 +11,7 @@
#pragma once #pragma once
#include "BlockEntityWithItems.h" #include "BlockEntityWithItems.h"
#include "RedstonePoweredEntity.h"
@ -31,6 +31,9 @@ class cServer;
// tolua_begin // tolua_begin
class cDropSpenserEntity : class cDropSpenserEntity :
public cBlockEntityWithItems public cBlockEntityWithItems
// tolua_end
, public cRedstonePoweredEntity
// tolua_begin
{ {
typedef cBlockEntityWithItems super; typedef cBlockEntityWithItems super;
@ -64,11 +67,11 @@ public:
/// Sets the dropspenser to dropspense an item in the next tick /// Sets the dropspenser to dropspense an item in the next tick
void Activate(void); 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 // 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: protected:
bool m_ShouldDropSpense; ///< If true, the dropspenser will dropspense an item in the next tick bool m_ShouldDropSpense; ///< If true, the dropspenser will dropspense an item in the next tick
bool m_IsPowered; ///< Set to true when the dropspenser receives redstone power. bool m_IsPowered; ///< Set to true when the dropspenser receives redstone power.

View File

@ -2,6 +2,7 @@
#pragma once #pragma once
#include "BlockEntity.h" #include "BlockEntity.h"
#include "RedstonePoweredEntity.h"
namespace Json namespace Json
@ -30,6 +31,9 @@ enum ENUM_NOTE_INSTRUMENTS
class cNoteEntity : class cNoteEntity :
public cBlockEntity public cBlockEntity
// tolua_end
, public cRedstonePoweredEntity
// tolua_begin
{ {
typedef cBlockEntity super; typedef cBlockEntity super;
public: public:
@ -38,6 +42,7 @@ public:
/// Creates a new note entity. a_World may be NULL /// Creates a new note entity. a_World may be NULL
cNoteEntity(int a_X, int a_Y, int a_Z, cWorld * a_World); cNoteEntity(int a_X, int a_Y, int a_Z, cWorld * a_World);
virtual ~cNoteEntity() {}
bool LoadFromJson(const Json::Value & a_Value); bool LoadFromJson(const Json::Value & a_Value);
virtual void SaveToJson(Json::Value & a_Value) override; virtual void SaveToJson(Json::Value & a_Value) override;
@ -54,6 +59,14 @@ public:
virtual void UsedBy(cPlayer * a_Player) override; virtual void UsedBy(cPlayer * a_Player) override;
virtual void SendTo(cClientHandle &) override {} virtual void SendTo(cClientHandle &) override {}
virtual void SetRedstonePower(bool a_Value)
{
if (a_Value)
{
MakeSound();
}
}
static const char * GetClassStatic(void) { return "cNoteEntity"; } static const char * GetClassStatic(void) { return "cNoteEntity"; }
private: private:

View File

@ -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;
};

View File

@ -294,6 +294,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info)
a_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_OneHitDig = true; a_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_OneHitDig = true;
a_Info[E_BLOCK_LILY_PAD ].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_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_POTATOES ].m_OneHitDig = true;
a_Info[E_BLOCK_PUMPKIN_STEM ].m_OneHitDig = true; a_Info[E_BLOCK_PUMPKIN_STEM ].m_OneHitDig = true;
a_Info[E_BLOCK_REDSTONE_REPEATER_OFF].m_OneHitDig = true; a_Info[E_BLOCK_REDSTONE_REPEATER_OFF].m_OneHitDig = true;

View File

@ -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) 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 // The blockentity list is locked by the parent chunkmap's CS

View File

@ -43,6 +43,7 @@ class cBlockArea;
class cFluidSimulatorData; class cFluidSimulatorData;
class cMobCensus; class cMobCensus;
class cMobSpawner; class cMobSpawner;
class cRedstonePoweredEntity;
typedef std::list<cClientHandle *> cClientHandleList; typedef std::list<cClientHandle *> cClientHandleList;
typedef cItemCallback<cEntity> cEntityCallback; typedef cItemCallback<cEntity> cEntityCallback;
@ -54,6 +55,7 @@ typedef cItemCallback<cNoteEntity> cNoteBlockCallback;
typedef cItemCallback<cCommandBlockEntity> cCommandBlockCallback; typedef cItemCallback<cCommandBlockEntity> cCommandBlockCallback;
typedef cItemCallback<cMobHeadEntity> cMobHeadCallback; typedef cItemCallback<cMobHeadEntity> cMobHeadCallback;
typedef cItemCallback<cFlowerPotEntity> cFlowerPotCallback; typedef cItemCallback<cFlowerPotEntity> cFlowerPotCallback;
typedef cItemCallback<cRedstonePoweredEntity> cRedstonePoweredCallback;
@ -238,6 +240,8 @@ 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 */ /** 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 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 */ /** 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 bool DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCallback & a_Callback); // Lua-acessible

View File

@ -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); 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; 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: // 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); 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; return;
} }

View File

@ -32,9 +32,6 @@ void cEnderCrystal::SpawnOn(cClientHandle & a_ClientHandle)
void cEnderCrystal::Tick(float a_Dt, cChunk & a_Chunk) void cEnderCrystal::Tick(float a_Dt, cChunk & a_Chunk)
{ {
UNUSED(a_Dt); 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 // 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); m_World->DoExplosionAt(6.0, GetPosX(), GetPosY(), GetPosZ(), true, esEnderCrystal, this);
Destroy(); 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);
} }

View File

@ -66,7 +66,7 @@ cItemHandler * cItemHandler::m_ItemHandler[2268];
cItemHandler * cItemHandler::GetItemHandler(int a_ItemType) 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 // Either nothing (-1), or bad value, both cases should return the air handler
if (a_ItemType < -1) if (a_ItemType < -1)

View File

@ -3,11 +3,9 @@
#include "IncrementalRedstoneSimulator.h" #include "IncrementalRedstoneSimulator.h"
#include "BoundingBox.h" #include "BoundingBox.h"
#include "../BlockEntities/DropSpenserEntity.h" #include "../BlockEntities/RedstonePoweredEntity.h"
#include "../BlockEntities/NoteEntity.h"
#include "../BlockEntities/ChestEntity.h" #include "../BlockEntities/ChestEntity.h"
#include "../BlockEntities/CommandBlockEntity.h" #include "../BlockEntities/CommandBlockEntity.h"
#include "../Entities/TNTEntity.h"
#include "../Entities/Pickup.h" #include "../Entities/Pickup.h"
#include "../Blocks/BlockTorch.h" #include "../Blocks/BlockTorch.h"
#include "../Blocks/BlockDoor.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) void cIncrementalRedstoneSimulator::HandleDropSpenser(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ)
{ {
class cSetPowerToDropSpenser : class cSetPowerToDropSpenser :
public cDropSpenserCallback public cRedstonePoweredCallback
{ {
bool m_IsPowered; bool m_IsPowered;
public: public:
cSetPowerToDropSpenser(bool a_IsPowered) : m_IsPowered(a_IsPowered) {} 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); a_DropSpenser->SetRedstonePower(m_IsPowered);
return false; 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 BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX;
int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; 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)) if (!AreCoordsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true))
{ {
class cSetPowerToNoteBlock : class cSetPowerToNoteBlock :
public cNoteBlockCallback public cRedstonePoweredCallback
{ {
bool m_IsPowered;
public: 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->SetRedstonePower(true);
{
a_NoteBlock->MakeSound();
}
return false; return false;
} }
} NoteBlockSP(m_bAreCoordsPowered); } NoteBlockSP;
int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX;
int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; 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); SetPlayerToggleableBlockAsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true);
} }
} }