diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/WSSAnvil.cpp | 64 | ||||
-rw-r--r-- | source/WSSAnvil.h | 1 | ||||
-rw-r--r-- | source/WSSCompact.cpp | 24 | ||||
-rw-r--r-- | source/blocks/Block.cpp | 3 | ||||
-rw-r--r-- | source/blocks/BlockNote.h | 13 | ||||
-rw-r--r-- | source/cChunk.cpp | 15 | ||||
-rw-r--r-- | source/cNoteEntity.cpp | 148 | ||||
-rw-r--r-- | source/cNoteEntity.h | 52 | ||||
-rw-r--r-- | source/cSignEntity.h | 3 |
9 files changed, 316 insertions, 7 deletions
diff --git a/source/WSSAnvil.cpp b/source/WSSAnvil.cpp index ac755907a..44b5f7faa 100644 --- a/source/WSSAnvil.cpp +++ b/source/WSSAnvil.cpp @@ -11,6 +11,7 @@ #include "cChestEntity.h" #include "cFurnaceEntity.h" #include "cSignEntity.h" +#include "cNoteEntity.h" #include "cItem.h" #include "StringCompression.h" #include "cEntity.h" @@ -147,6 +148,14 @@ protected: m_Writer.EndCompound(); } + void AddNoteEntity(cNoteEntity * a_Note) + { + m_Writer.BeginCompound(""); + AddBasicTileEntity(a_Note, "Music"); + m_Writer.AddByte("note", a_Note->GetPitch()); + m_Writer.EndCompound(); + } + virtual bool LightIsValid(bool a_IsLightValid) override { @@ -184,6 +193,7 @@ protected: case E_BLOCK_FURNACE: AddFurnaceEntity((cFurnaceEntity *)a_Entity); break; case E_BLOCK_SIGN_POST: case E_BLOCK_WALLSIGN: AddSignEntity ((cSignEntity *) a_Entity); break; + case E_BLOCK_NOTE_BLOCK: AddNoteEntity ((cNoteEntity *) a_Entity); break; default: { ASSERT(!"Unhandled block entity saved into Anvil"); @@ -648,6 +658,10 @@ void cWSSAnvil::LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntities, con { LoadSignFromNBT(a_BlockEntities, a_NBT, Child); } + else if (strncmp(a_NBT.GetData(sID), "Music", a_NBT.GetDataLength(sID)) == 0) + { + LoadNoteFromNBT(a_BlockEntities, a_NBT, Child); + } // TODO: Other block entities } // for Child - tag children } @@ -778,17 +792,57 @@ void cWSSAnvil::LoadSignFromNBT(cBlockEntityList & a_BlockEntities, const cParse return; } std::auto_ptr<cSignEntity> Sign(new cSignEntity(E_BLOCK_SIGN_POST, x, y, z, m_World)); - int Text1 = a_NBT.FindChildByName(a_TagIdx, "Text1"); - if (Text1 >= 0) + + int currentLine = a_NBT.FindChildByName(a_TagIdx, "Text1"); + if (currentLine >= 0) + { + Sign->SetLine(0, a_NBT.GetString(currentLine)); + } + + currentLine = a_NBT.FindChildByName(a_TagIdx, "Text2"); + if (currentLine >= 0) + { + Sign->SetLine(1, a_NBT.GetString(currentLine)); + } + + currentLine = a_NBT.FindChildByName(a_TagIdx, "Text3"); + if (currentLine >= 0) { - Sign->SetLine(0, a_NBT.GetString(Text1)); + Sign->SetLine(2, a_NBT.GetString(currentLine)); } + + currentLine = a_NBT.FindChildByName(a_TagIdx, "Text4"); + if (currentLine >= 0) + { + Sign->SetLine(3, a_NBT.GetString(currentLine)); + } + a_BlockEntities.push_back(Sign.release()); } +void cWSSAnvil::LoadNoteFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx) +{ + ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); + int x, y, z; + if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z)) + { + return; + } + std::auto_ptr<cNoteEntity> Note(new cNoteEntity(x, y, z, m_World)); + int note = a_NBT.FindChildByName(a_TagIdx, "note"); + if (note >= 0) + { + Note->SetPitch(a_NBT.GetByte(note)); + } + a_BlockEntities.push_back(Note.release()); +} + + + + bool cWSSAnvil::GetBlockEntityNBTPos(const cParsedNBT & a_NBT, int a_TagIdx, int & a_X, int & a_Y, int & a_Z) { @@ -1003,3 +1057,7 @@ unsigned cWSSAnvil::cMCAFile::FindFreeLocation(int a_LocalX, int a_LocalZ, const } // for i - m_Header[] return MaxLocation >> 8; } + + + + diff --git a/source/WSSAnvil.h b/source/WSSAnvil.h index a88a67374..18e3ce8ad 100644 --- a/source/WSSAnvil.h +++ b/source/WSSAnvil.h @@ -111,6 +111,7 @@ protected: void LoadChestFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadFurnaceFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadSignFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); + void LoadNoteFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); /// Helper function for extracting the X, Y, and Z int subtags of a NBT compound; returns true if successful bool GetBlockEntityNBTPos(const cParsedNBT & a_NBT, int a_TagIdx, int & a_X, int & a_Y, int & a_Z); diff --git a/source/WSSCompact.cpp b/source/WSSCompact.cpp index 406b55d38..a47c62dcb 100644 --- a/source/WSSCompact.cpp +++ b/source/WSSCompact.cpp @@ -12,6 +12,7 @@ #include "cChestEntity.h" #include "cSignEntity.h" #include "cFurnaceEntity.h" +#include "cNoteEntity.h" #include "BlockID.h" @@ -73,7 +74,8 @@ void cJsonChunkSerializer::BlockEntity(cBlockEntity * a_BlockEntity) case E_BLOCK_FURNACE: SaveInto = "Furnaces"; break; case E_BLOCK_SIGN_POST: SaveInto = "Signs"; break; case E_BLOCK_WALLSIGN: SaveInto = "Signs"; break; - + case E_BLOCK_NOTE_BLOCK: SaveInto = "Notes"; break; + default: { ASSERT(!"Unhandled blocktype in BlockEntities list while saving to JSON"); @@ -316,6 +318,26 @@ void cWSSCompact::LoadEntitiesFromJson(Json::Value & a_Value, cEntityList & a_En } } // for itr - AllSigns[] } + + // Load note blocks + Json::Value AllNotes = a_Value.get("Notes", Json::nullValue); + if( !AllNotes.empty() ) + { + for( Json::Value::iterator itr = AllNotes.begin(); itr != AllNotes.end(); ++itr ) + { + Json::Value & Note = *itr; + cNoteEntity * NoteEntity = new cNoteEntity(0, 0, 0, a_World); + if ( !NoteEntity->LoadFromJson( Note ) ) + { + LOGERROR("ERROR READING NOTE BLOCK FROM JSON!" ); + delete NoteEntity; + } + else + { + a_BlockEntities.push_back( NoteEntity ); + } + } // for itr - AllNotes[] + } } diff --git a/source/blocks/Block.cpp b/source/blocks/Block.cpp index 400727e80..2fa1ba718 100644 --- a/source/blocks/Block.cpp +++ b/source/blocks/Block.cpp @@ -38,6 +38,7 @@ #include "BlockMelon.h"
#include "BlockIce.h"
#include "BlockOre.h"
+#include "BlockNote.h"
bool cBlockHandler::m_HandlerInitialized = false;
cBlockHandler *cBlockHandler::m_BlockHandler[256];
@@ -158,6 +159,8 @@ cBlockHandler *cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockID) return new cBlockStoneHandler(a_BlockID);
case E_BLOCK_MELON:
return new cBlockMelonHandler(a_BlockID);
+ case E_BLOCK_NOTE_BLOCK:
+ return new cBlockNoteHandler(a_BlockID);
default:
return new cBlockHandler(a_BlockID);
break;
diff --git a/source/blocks/BlockNote.h b/source/blocks/BlockNote.h new file mode 100644 index 000000000..2c439f623 --- /dev/null +++ b/source/blocks/BlockNote.h @@ -0,0 +1,13 @@ +#pragma once
+#include "Block.h"
+#include "BlockEntity.h"
+
+class cBlockNoteHandler : public cBlockEntityHandler
+{
+public:
+ cBlockNoteHandler(BLOCKTYPE a_BlockID)
+ : cBlockEntityHandler(a_BlockID)
+ {
+ }
+
+};
diff --git a/source/cChunk.cpp b/source/cChunk.cpp index 8fb4570ae..c479a7bc3 100644 --- a/source/cChunk.cpp +++ b/source/cChunk.cpp @@ -17,6 +17,7 @@ #include "cChestEntity.h" #include "cFurnaceEntity.h" #include "cSignEntity.h" +#include "cNoteEntity.h" #include "cTorch.h" #include "cLadder.h" #include "cPickup.h" @@ -962,6 +963,15 @@ void cChunk::CreateBlockEntities(void) } break; } + + case E_BLOCK_NOTE_BLOCK: + { + if (!HasBlockEntityAt(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width)) + { + m_BlockEntities.push_back(new cNoteEntity(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width, m_World) ); + } + break; + } } // switch (BlockType) } // for y } // for z @@ -1087,6 +1097,11 @@ void cChunk::SetBlock( int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType AddBlockEntity( new cSignEntity( (ENUM_BLOCK_ID)a_BlockType, WorldPos.x, WorldPos.y, WorldPos.z, m_World) ); break; } + case E_BLOCK_NOTE_BLOCK: + { + AddBlockEntity(new cNoteEntity(WorldPos.x, WorldPos.y, WorldPos.z, m_World)); + break; + } } // switch (a_BlockType) } diff --git a/source/cNoteEntity.cpp b/source/cNoteEntity.cpp new file mode 100644 index 000000000..4feb9223c --- /dev/null +++ b/source/cNoteEntity.cpp @@ -0,0 +1,148 @@ +
+#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
+
+#include "cNoteEntity.h"
+#include "cWorld.h"
+#include <json/json.h>
+
+
+cNoteEntity::cNoteEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World)
+ : cBlockEntity(E_BLOCK_NOTE_BLOCK, a_BlockX, a_BlockY, a_BlockZ, a_World)
+ , m_Pitch( 0 )
+{
+}
+
+
+
+
+
+cNoteEntity::~cNoteEntity()
+{
+}
+
+
+
+
+
+void cNoteEntity::UsedBy( cPlayer * a_Player )
+{
+ IncrementPitch();
+ MakeSound();
+}
+
+
+
+
+
+void cNoteEntity::MakeSound( void )
+{
+ char instrument;
+ switch (m_World->GetBlock(m_PosX, m_PosY - 1, m_PosZ))
+ {
+ case E_BLOCK_PLANKS:
+ case E_BLOCK_LOG:
+ case E_BLOCK_NOTE_BLOCK:
+ {
+ // TODO: add other wood-based blocks if needed
+ instrument = E_INST_DOUBLE_BASS;
+ break;
+ }
+
+ case E_BLOCK_SAND:
+ case E_BLOCK_GRAVEL:
+ case E_BLOCK_SOULSAND:
+ {
+ instrument = E_INST_SNARE_DRUM;
+ break;
+ }
+
+ case E_BLOCK_GLASS:
+ case E_BLOCK_GLASS_PANE:
+ case E_BLOCK_GLOWSTONE:
+ {
+ instrument = E_INST_CLICKS;
+ break;
+ }
+
+ case E_BLOCK_STONE:
+ case E_BLOCK_STONE_BRICKS:
+ case E_BLOCK_COBBLESTONE:
+ case E_BLOCK_OBSIDIAN:
+ case E_BLOCK_NETHERRACK:
+ case E_BLOCK_BRICK:
+ case E_BLOCK_NETHER_BRICK:
+ {
+ // TODO: add other stone-based blocks if needed
+ instrument = E_INST_BASS_DRUM;
+ break;
+ }
+
+ default:
+ {
+ instrument = E_INST_HARP_PIANO;
+ break;
+ }
+ }
+
+ m_World->BroadcastBlockAction(m_PosX, m_PosY, m_PosZ, instrument, m_Pitch);
+}
+
+
+
+
+
+char cNoteEntity::GetPitch( void )
+{
+ return m_Pitch;
+}
+
+
+
+
+
+void cNoteEntity::SetPitch( char a_Pitch )
+{
+ m_Pitch = a_Pitch % 25;
+}
+
+
+
+
+
+void cNoteEntity::IncrementPitch( void )
+{
+ SetPitch( m_Pitch + 1 );
+}
+
+
+
+
+
+bool cNoteEntity::LoadFromJson( const Json::Value & a_Value )
+{
+
+ m_PosX = a_Value.get("x", 0).asInt();
+ m_PosY = a_Value.get("y", 0).asInt();
+ m_PosZ = a_Value.get("z", 0).asInt();
+
+ m_Pitch = (char)a_Value.get("p", 0).asInt();
+
+ return true;
+}
+
+
+
+
+
+void cNoteEntity::SaveToJson( Json::Value & a_Value )
+{
+ a_Value["x"] = m_PosX;
+ a_Value["y"] = m_PosY;
+ a_Value["z"] = m_PosZ;
+
+ a_Value["p"] = m_Pitch;
+}
+
+
+
+
diff --git a/source/cNoteEntity.h b/source/cNoteEntity.h new file mode 100644 index 000000000..fad1f8f06 --- /dev/null +++ b/source/cNoteEntity.h @@ -0,0 +1,52 @@ +
+#pragma once
+
+#include "cBlockEntity.h"
+
+
+namespace Json
+{
+ class Value;
+}
+
+
+
+
+
+enum ENUM_NOTE_INSTRUMENTS
+{
+ E_INST_HARP_PIANO = 0,
+ E_INST_DOUBLE_BASS = 1,
+ E_INST_SNARE_DRUM = 2,
+ E_INST_CLICKS = 3,
+ E_INST_BASS_DRUM = 4
+};
+
+
+
+
+
+class cNoteEntity :
+ public cBlockEntity
+{
+public:
+ 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;
+
+ char GetPitch( void );
+ void SetPitch( char a_Pitch );
+ void IncrementPitch( void );
+ void MakeSound( void );
+ virtual void UsedBy( cPlayer * a_Player ) override;
+ virtual void SendTo(cClientHandle & a_Client) override { };
+
+private:
+ unsigned char m_Pitch;
+};
+
+
+
+
diff --git a/source/cSignEntity.h b/source/cSignEntity.h index 8d9cd5016..4066d5070 100644 --- a/source/cSignEntity.h +++ b/source/cSignEntity.h @@ -13,9 +13,6 @@ namespace Json } - - - class cSignEntity : public cBlockEntity { |