From 6ad8553a3a9095bd5a8c25085fa0bb209d411048 Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Sun, 26 Aug 2012 17:50:42 +0000 Subject: Added basic noteblocks, finished sign storage in Anvil (patch contributed by l0udPL) http://forum.mc-server.org/showthread.php?tid=528 git-svn-id: http://mc-server.googlecode.com/svn/trunk@793 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/WSSAnvil.cpp | 64 +++++++++++++++++++- source/WSSAnvil.h | 1 + source/WSSCompact.cpp | 24 +++++++- source/blocks/Block.cpp | 3 + source/blocks/BlockNote.h | 13 ++++ source/cChunk.cpp | 15 +++++ source/cNoteEntity.cpp | 148 ++++++++++++++++++++++++++++++++++++++++++++++ source/cNoteEntity.h | 52 ++++++++++++++++ source/cSignEntity.h | 3 - 9 files changed, 316 insertions(+), 7 deletions(-) create mode 100644 source/blocks/BlockNote.h create mode 100644 source/cNoteEntity.cpp create mode 100644 source/cNoteEntity.h (limited to 'source') 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 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 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 + + +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 { -- cgit v1.2.3