commit
dc77cbfdc4
@ -138,6 +138,12 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
|
||||
break;
|
||||
}
|
||||
|
||||
case E_ITEM_FIRE_CHARGE:
|
||||
{
|
||||
// TODO: Spawn fireball entity
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
DropFromSlot(a_Chunk, a_SlotNum);
|
||||
|
63
src/Blocks/BlockAnvil.h
Normal file
63
src/Blocks/BlockAnvil.h
Normal file
@ -0,0 +1,63 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BlockHandler.h"
|
||||
#include "../World.h"
|
||||
#include "../Entities/Player.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBlockAnvilHandler :
|
||||
public cBlockHandler
|
||||
{
|
||||
public:
|
||||
cBlockAnvilHandler(BLOCKTYPE a_BlockType)
|
||||
: cBlockHandler(a_BlockType)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||
{
|
||||
a_Pickups.push_back(cItem(E_BLOCK_ANVIL, 1, a_BlockMeta >> 2));
|
||||
}
|
||||
|
||||
virtual bool GetPlacementBlockTypeMeta(
|
||||
cChunkInterface & a_ChunkInterface, cPlayer * a_Player,
|
||||
int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
|
||||
int a_CursorX, int a_CursorY, int a_CursorZ,
|
||||
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
|
||||
) override
|
||||
{
|
||||
a_BlockType = m_BlockType;
|
||||
|
||||
int Direction = (int)floor(a_Player->GetYaw() * 4.0 / 360.0 + 0.5) & 0x3;
|
||||
int RawMeta = a_BlockMeta >> 2;
|
||||
|
||||
Direction++;
|
||||
Direction %= 4;
|
||||
switch (Direction)
|
||||
{
|
||||
case 0: a_BlockMeta = 0x2 | RawMeta << 2; break;
|
||||
case 1: a_BlockMeta = 0x3 | RawMeta << 2; break;
|
||||
case 2: a_BlockMeta = 0x0 | RawMeta << 2; break;
|
||||
case 3: a_BlockMeta = 0x1 | RawMeta << 2; break;
|
||||
default:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool IsUseable() override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "../Root.h"
|
||||
#include "../Bindings/PluginManager.h"
|
||||
#include "../Chunk.h"
|
||||
#include "BlockAnvil.h"
|
||||
#include "BlockBed.h"
|
||||
#include "BlockBrewingStand.h"
|
||||
#include "BlockButton.h"
|
||||
@ -86,6 +87,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
|
||||
// Block handlers, alphabetically sorted:
|
||||
case E_BLOCK_ACACIA_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType);
|
||||
case E_BLOCK_ACTIVATOR_RAIL: return new cBlockRailHandler (a_BlockType);
|
||||
case E_BLOCK_ANVIL: return new cBlockAnvilHandler (a_BlockType);
|
||||
case E_BLOCK_BED: return new cBlockBedHandler (a_BlockType);
|
||||
case E_BLOCK_BIRCH_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType);
|
||||
case E_BLOCK_BREWING_STAND: return new cBlockBrewingStandHandler (a_BlockType);
|
||||
|
@ -57,6 +57,9 @@ if (NOT MSVC)
|
||||
Entities/Player.h
|
||||
Entities/ProjectileEntity.h
|
||||
Entities/TNTEntity.h
|
||||
Entities/ExpOrb.h
|
||||
Entities/HangingEntity.h
|
||||
Entities/ItemFrame.h
|
||||
Generating/ChunkDesc.h
|
||||
Group.h
|
||||
Inventory.h
|
||||
|
@ -5,20 +5,26 @@
|
||||
#include "../ClientHandle.h"
|
||||
|
||||
|
||||
cExpOrb::cExpOrb(double a_X, double a_Y, double a_Z, int a_Reward) :
|
||||
cEntity(etExpOrb, a_X, a_Y, a_Z, 0.98, 0.98),
|
||||
m_Reward(a_Reward)
|
||||
cExpOrb::cExpOrb(double a_X, double a_Y, double a_Z, int a_Reward)
|
||||
: cEntity(etExpOrb, a_X, a_Y, a_Z, 0.98, 0.98)
|
||||
, m_Reward(a_Reward)
|
||||
, m_Timer(0.f)
|
||||
{
|
||||
SetMaxHealth(5);
|
||||
SetHealth(5);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cExpOrb::cExpOrb(const Vector3d & a_Pos, int a_Reward) :
|
||||
cEntity(etExpOrb, a_Pos.x, a_Pos.y, a_Pos.z, 0.98, 0.98),
|
||||
m_Reward(a_Reward)
|
||||
cExpOrb::cExpOrb(const Vector3d & a_Pos, int a_Reward)
|
||||
: cEntity(etExpOrb, a_Pos.x, a_Pos.y, a_Pos.z, 0.98, 0.98)
|
||||
, m_Reward(a_Reward)
|
||||
, m_Timer(0.f)
|
||||
{
|
||||
SetMaxHealth(5);
|
||||
SetHealth(5);
|
||||
}
|
||||
|
||||
|
||||
@ -52,7 +58,7 @@ void cExpOrb::Tick(float a_Dt, cChunk & a_Chunk)
|
||||
LOGD("Player %s picked up an ExpOrb. His reward is %i", a_ClosestPlayer->GetName().c_str(), m_Reward);
|
||||
a_ClosestPlayer->DeltaExperience(m_Reward);
|
||||
|
||||
m_World->BroadcastSoundEffect("random.orb", (int)GetPosX() * 8, (int)GetPosY() * 8, (int)GetPosZ() * 8, 0.5f, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64));
|
||||
m_World->BroadcastSoundEffect("random.orb", (int)(GetPosX() * 8), (int)(GetPosY() * 8), (int)(GetPosZ() * 8), 0.5f, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64));
|
||||
|
||||
Destroy();
|
||||
}
|
||||
@ -64,4 +70,10 @@ void cExpOrb::Tick(float a_Dt, cChunk & a_Chunk)
|
||||
BroadcastMovementUpdate();
|
||||
}
|
||||
HandlePhysics(a_Dt, a_Chunk);
|
||||
|
||||
m_Timer += a_Dt;
|
||||
if (m_Timer >= 1000 * 60 * 5) // 5 minutes
|
||||
{
|
||||
Destroy(true);
|
||||
}
|
||||
}
|
||||
|
@ -7,14 +7,17 @@
|
||||
|
||||
|
||||
|
||||
// tolua_begin
|
||||
class cExpOrb :
|
||||
public cEntity
|
||||
{
|
||||
typedef cExpOrb super;
|
||||
|
||||
public:
|
||||
// tolua_end
|
||||
|
||||
CLASS_PROTODEF(cExpOrb);
|
||||
|
||||
|
||||
cExpOrb(double a_X, double a_Y, double a_Z, int a_Reward);
|
||||
cExpOrb(const Vector3d & a_Pos, int a_Reward);
|
||||
|
||||
@ -22,9 +25,21 @@ public:
|
||||
virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
|
||||
virtual void SpawnOn(cClientHandle & a_Client) override;
|
||||
|
||||
// cExpOrb functions
|
||||
int GetReward(void) const { return m_Reward; }
|
||||
/** Returns the number of ticks that this entity has existed */
|
||||
int GetAge(void) const { return (int)(m_Timer / 50); } // tolua_export
|
||||
|
||||
/** Set the number of ticks that this entity has existed */
|
||||
void SetAge(int a_Age) { m_Timer = (float)(a_Age * 50); } // tolua_export
|
||||
|
||||
/** Get the exp amount */
|
||||
int GetReward(void) const { return m_Reward; } // tolua_export
|
||||
|
||||
/** Set the exp amount */
|
||||
void SetReward(int a_Reward) { m_Reward = a_Reward; } // tolua_export
|
||||
|
||||
protected:
|
||||
int m_Reward;
|
||||
} ;
|
||||
|
||||
/** The number of ticks that the entity has existed / timer between collect and destroy; in msec */
|
||||
float m_Timer;
|
||||
} ; // tolua_export
|
53
src/Entities/HangingEntity.cpp
Normal file
53
src/Entities/HangingEntity.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
|
||||
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
||||
|
||||
#include "HangingEntity.h"
|
||||
#include "ClientHandle.h"
|
||||
#include "Player.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cHangingEntity::cHangingEntity(eEntityType a_EntityType, eBlockFace a_BlockFace, double a_X, double a_Y, double a_Z)
|
||||
: cEntity(a_EntityType, a_X, a_Y, a_Z, 0.8, 0.8)
|
||||
, m_BlockFace(a_BlockFace)
|
||||
{
|
||||
SetMaxHealth(1);
|
||||
SetHealth(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cHangingEntity::SpawnOn(cClientHandle & a_ClientHandle)
|
||||
{
|
||||
int Dir = 0;
|
||||
|
||||
// The client uses different values for item frame directions and block faces. Our constants are for the block faces, so we convert them here to item frame faces
|
||||
switch (m_BlockFace)
|
||||
{
|
||||
case BLOCK_FACE_ZP: break; // Initialised to zero
|
||||
case BLOCK_FACE_ZM: Dir = 2; break;
|
||||
case BLOCK_FACE_XM: Dir = 1; break;
|
||||
case BLOCK_FACE_XP: Dir = 3; break;
|
||||
default: ASSERT(!"Unhandled block face when trying to spawn item frame!"); return;
|
||||
}
|
||||
|
||||
if ((Dir == 0) || (Dir == 2)) // Probably a client bug, but two directions are flipped and contrary to the norm, so we do -180
|
||||
{
|
||||
SetYaw((Dir * 90) - 180);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetYaw(Dir * 90);
|
||||
}
|
||||
|
||||
a_ClientHandle.SendSpawnObject(*this, 71, Dir, (Byte)GetYaw(), (Byte)GetPitch());
|
||||
a_ClientHandle.SendEntityMetadata(*this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
49
src/Entities/HangingEntity.h
Normal file
49
src/Entities/HangingEntity.h
Normal file
@ -0,0 +1,49 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Entity.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// tolua_begin
|
||||
class cHangingEntity :
|
||||
public cEntity
|
||||
{
|
||||
// tolua_end
|
||||
typedef cEntity super;
|
||||
|
||||
public:
|
||||
|
||||
CLASS_PROTODEF(cHangingEntity);
|
||||
|
||||
cHangingEntity(eEntityType a_EntityType, eBlockFace a_BlockFace, double a_X, double a_Y, double a_Z);
|
||||
|
||||
/** Returns the orientation from the hanging entity */
|
||||
eBlockFace GetDirection() const { return m_BlockFace; } // tolua_export
|
||||
|
||||
/** Set the orientation from the hanging entity */
|
||||
void SetDirection(eBlockFace a_BlockFace) { m_BlockFace = a_BlockFace; } // tolua_export
|
||||
|
||||
/** Returns the X coord. */
|
||||
int GetTileX() const { return POSX_TOINT; } // tolua_export
|
||||
|
||||
/** Returns the Y coord. */
|
||||
int GetTileY() const { return POSY_TOINT; } // tolua_export
|
||||
|
||||
/** Returns the Z coord. */
|
||||
int GetTileZ() const { return POSZ_TOINT; } // tolua_export
|
||||
|
||||
private:
|
||||
|
||||
virtual void SpawnOn(cClientHandle & a_ClientHandle) override;
|
||||
virtual void Tick(float a_Dt, cChunk & a_Chunk) override {};
|
||||
|
||||
eBlockFace m_BlockFace;
|
||||
|
||||
}; // tolua_export
|
||||
|
||||
|
||||
|
||||
|
@ -10,43 +10,10 @@
|
||||
|
||||
|
||||
cItemFrame::cItemFrame(eBlockFace a_BlockFace, double a_X, double a_Y, double a_Z)
|
||||
: cEntity(etItemFrame, a_X, a_Y, a_Z, 0.8, 0.8),
|
||||
m_BlockFace(a_BlockFace),
|
||||
m_Item(E_BLOCK_AIR),
|
||||
m_Rotation(0)
|
||||
: cHangingEntity(etItemFrame, a_BlockFace, a_X, a_Y, a_Z)
|
||||
, m_Item(E_BLOCK_AIR)
|
||||
, m_Rotation(0)
|
||||
{
|
||||
SetMaxHealth(1);
|
||||
SetHealth(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cItemFrame::SpawnOn(cClientHandle & a_ClientHandle)
|
||||
{
|
||||
int Dir = 0;
|
||||
|
||||
// The client uses different values for item frame directions and block faces. Our constants are for the block faces, so we convert them here to item frame faces
|
||||
switch (m_BlockFace)
|
||||
{
|
||||
case BLOCK_FACE_ZP: break; // Initialised to zero
|
||||
case BLOCK_FACE_ZM: Dir = 2; break;
|
||||
case BLOCK_FACE_XM: Dir = 1; break;
|
||||
case BLOCK_FACE_XP: Dir = 3; break;
|
||||
default: ASSERT(!"Unhandled block face when trying to spawn item frame!"); return;
|
||||
}
|
||||
|
||||
if ((Dir == 0) || (Dir == 2)) // Probably a client bug, but two directions are flipped and contrary to the norm, so we do -180
|
||||
{
|
||||
SetYaw((Dir * 90) - 180);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetYaw(Dir * 90);
|
||||
}
|
||||
|
||||
a_ClientHandle.SendSpawnObject(*this, 71, Dir, (Byte)GetYaw(), (Byte)GetPitch());
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Entity.h"
|
||||
#include "HangingEntity.h"
|
||||
|
||||
|
||||
|
||||
@ -9,10 +9,10 @@
|
||||
|
||||
// tolua_begin
|
||||
class cItemFrame :
|
||||
public cEntity
|
||||
public cHangingEntity
|
||||
{
|
||||
// tolua_end
|
||||
typedef cEntity super;
|
||||
typedef cHangingEntity super;
|
||||
|
||||
public:
|
||||
|
||||
@ -20,18 +20,24 @@ public:
|
||||
|
||||
cItemFrame(eBlockFace a_BlockFace, double a_X, double a_Y, double a_Z);
|
||||
|
||||
const cItem & GetItem(void) { return m_Item; }
|
||||
Byte GetRotation(void) const { return m_Rotation; }
|
||||
/** Returns the item in the frame */
|
||||
const cItem & GetItem(void) { return m_Item; } // tolua_export
|
||||
|
||||
/** Set the item in the frame */
|
||||
void SetItem(cItem & a_Item) { m_Item = a_Item; }; // tolua_export
|
||||
|
||||
/** Returns the rotation from the item in the frame */
|
||||
Byte GetRotation(void) const { return m_Rotation; } // tolua_export
|
||||
|
||||
/** Set the rotation from the item in the frame */
|
||||
void SetRotation(Byte a_Rotation) { m_Rotation = a_Rotation; } // tolua_export
|
||||
|
||||
private:
|
||||
|
||||
virtual void SpawnOn(cClientHandle & a_ClientHandle) override;
|
||||
virtual void OnRightClicked(cPlayer & a_Player) override;
|
||||
virtual void Tick(float a_Dt, cChunk & a_Chunk) override {};
|
||||
virtual void KilledBy(cEntity * a_Killer) override;
|
||||
virtual void GetDrops(cItems & a_Items, cEntity * a_Killer) override;
|
||||
|
||||
eBlockFace m_BlockFace;
|
||||
cItem m_Item;
|
||||
Byte m_Rotation;
|
||||
|
||||
|
@ -82,7 +82,7 @@ cPickup::cPickup(double a_PosX, double a_PosY, double a_PosZ, const cItem & a_It
|
||||
|
||||
void cPickup::SpawnOn(cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendPickupSpawn(*this);
|
||||
a_Client.SendPickupSpawn(*this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -26,31 +26,34 @@ public:
|
||||
CLASS_PROTODEF(cPickup);
|
||||
|
||||
cPickup(double a_PosX, double a_PosY, double a_PosZ, const cItem & a_Item, bool IsPlayerCreated, float a_SpeedX = 0.f, float a_SpeedY = 0.f, float a_SpeedZ = 0.f);
|
||||
|
||||
|
||||
cItem & GetItem(void) {return m_Item; } // tolua_export
|
||||
const cItem & GetItem(void) const {return m_Item; }
|
||||
|
||||
virtual void SpawnOn(cClientHandle & a_ClientHandle) override;
|
||||
|
||||
|
||||
bool CollectedBy(cPlayer * a_Dest); // tolua_export
|
||||
|
||||
virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
|
||||
|
||||
/// Returns the number of ticks that this entity has existed
|
||||
int GetAge(void) const { return (int)(m_Timer / 50); } // tolua_export
|
||||
|
||||
/// Returns true if the pickup has already been collected
|
||||
|
||||
/** Returns the number of ticks that this entity has existed */
|
||||
int GetAge(void) const { return (int)(m_Timer / 50); } // tolua_export
|
||||
|
||||
/** Set the number of ticks that this entity has existed */
|
||||
void SetAge(int a_Age) { m_Timer = (float)(a_Age * 50); } // tolua_export
|
||||
|
||||
/** Returns true if the pickup has already been collected */
|
||||
bool IsCollected(void) const { return m_bCollected; } // tolua_export
|
||||
|
||||
/// Returns true if created by player (i.e. vomiting), used for determining picking-up delay time
|
||||
/** Returns true if created by player (i.e. vomiting), used for determining picking-up delay time */
|
||||
bool IsPlayerCreated(void) const { return m_bIsPlayerCreated; } // tolua_export
|
||||
|
||||
|
||||
private:
|
||||
Vector3d m_ResultingSpeed; //Can be used to modify the resulting speed for the current tick ;)
|
||||
|
||||
Vector3d m_WaterSpeed;
|
||||
|
||||
/// The number of ticks that the entity has existed / timer between collect and destroy; in msec
|
||||
/** The number of ticks that the entity has existed / timer between collect and destroy; in msec */
|
||||
float m_Timer;
|
||||
|
||||
cItem m_Item;
|
||||
|
@ -110,6 +110,7 @@ cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType)
|
||||
case E_ITEM_EGG: return new cItemEggHandler();
|
||||
case E_ITEM_EMPTY_MAP: return new cItemEmptyMapHandler();
|
||||
case E_ITEM_ENDER_PEARL: return new cItemEnderPearlHandler();
|
||||
case E_ITEM_FIRE_CHARGE: return new cItemLighterHandler(a_ItemType);
|
||||
case E_ITEM_FIREWORK_ROCKET: return new cItemFireworkHandler();
|
||||
case E_ITEM_FISHING_ROD: return new cItemFishingRodHandler(a_ItemType);
|
||||
case E_ITEM_FLINT_AND_STEEL: return new cItemLighterHandler(a_ItemType);
|
||||
|
@ -34,7 +34,11 @@ public:
|
||||
if (Block == E_BLOCK_AIR)
|
||||
{
|
||||
cItemFrame * ItemFrame = new cItemFrame(a_Dir, a_BlockX, a_BlockY, a_BlockZ);
|
||||
ItemFrame->Initialize(a_World);
|
||||
if (!ItemFrame->Initialize(a_World))
|
||||
{
|
||||
delete ItemFrame;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!a_Player->IsGameModeCreative())
|
||||
{
|
||||
|
@ -26,7 +26,26 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
a_Player->UseEquippedItem();
|
||||
if (!a_Player->IsGameModeCreative())
|
||||
{
|
||||
switch (m_ItemType)
|
||||
{
|
||||
case E_ITEM_FLINT_AND_STEEL:
|
||||
{
|
||||
a_Player->UseEquippedItem();
|
||||
break;
|
||||
}
|
||||
case E_ITEM_FIRE_CHARGE:
|
||||
{
|
||||
a_Player->GetInventory().RemoveOneEquippedItem();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
ASSERT(!"Unknown Lighter Item!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ))
|
||||
{
|
||||
@ -49,6 +68,7 @@ public:
|
||||
if (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_AIR)
|
||||
{
|
||||
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_FIRE, 0);
|
||||
a_World->BroadcastSoundEffect("fire.ignite", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 1.0F, 1.04F);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,9 @@
|
||||
#include "../Entities/Pickup.h"
|
||||
#include "../Entities/ProjectileEntity.h"
|
||||
#include "../Entities/TNTEntity.h"
|
||||
#include "../Entities/ExpOrb.h"
|
||||
#include "../Entities/HangingEntity.h"
|
||||
#include "../Entities/ItemFrame.h"
|
||||
|
||||
#include "../Mobs/Monster.h"
|
||||
#include "../Mobs/Bat.h"
|
||||
@ -526,8 +529,8 @@ void cNBTChunkSerializer::AddPickupEntity(cPickup * a_Pickup)
|
||||
m_Writer.BeginCompound("");
|
||||
AddBasicEntity(a_Pickup, "Item");
|
||||
AddItem(a_Pickup->GetItem(), -1, "Item");
|
||||
m_Writer.AddShort("Health", a_Pickup->GetHealth());
|
||||
m_Writer.AddShort("Age", a_Pickup->GetAge());
|
||||
m_Writer.AddShort("Health", (Int16)(unsigned char)a_Pickup->GetHealth());
|
||||
m_Writer.AddShort("Age", (Int16)a_Pickup->GetAge());
|
||||
m_Writer.EndCompound();
|
||||
}
|
||||
|
||||
@ -592,6 +595,25 @@ void cNBTChunkSerializer::AddProjectileEntity(cProjectileEntity * a_Projectile)
|
||||
|
||||
|
||||
|
||||
void cNBTChunkSerializer::AddHangingEntity(cHangingEntity * a_Hanging)
|
||||
{
|
||||
m_Writer.AddByte("Direction", (unsigned char)a_Hanging->GetDirection());
|
||||
m_Writer.AddInt("TileX", a_Hanging->GetTileX());
|
||||
m_Writer.AddInt("TileY", a_Hanging->GetTileY());
|
||||
m_Writer.AddInt("TileZ", a_Hanging->GetTileZ());
|
||||
switch (a_Hanging->GetDirection())
|
||||
{
|
||||
case 0: m_Writer.AddByte("Dir", (unsigned char)2); break;
|
||||
case 1: m_Writer.AddByte("Dir", (unsigned char)1); break;
|
||||
case 2: m_Writer.AddByte("Dir", (unsigned char)0); break;
|
||||
case 3: m_Writer.AddByte("Dir", (unsigned char)3); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cNBTChunkSerializer::AddTNTEntity(cTNTEntity * a_TNT)
|
||||
{
|
||||
m_Writer.BeginCompound("");
|
||||
@ -604,6 +626,35 @@ void cNBTChunkSerializer::AddTNTEntity(cTNTEntity * a_TNT)
|
||||
|
||||
|
||||
|
||||
void cNBTChunkSerializer::AddExpOrbEntity(cExpOrb * a_ExpOrb)
|
||||
{
|
||||
m_Writer.BeginCompound("");
|
||||
AddBasicEntity(a_ExpOrb, "XPOrb");
|
||||
m_Writer.AddShort("Health", (Int16)(unsigned char)a_ExpOrb->GetHealth());
|
||||
m_Writer.AddShort("Age", (Int16)a_ExpOrb->GetAge());
|
||||
m_Writer.AddShort("Value", (Int16)a_ExpOrb->GetReward());
|
||||
m_Writer.EndCompound();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cNBTChunkSerializer::AddItemFrameEntity(cItemFrame * a_ItemFrame)
|
||||
{
|
||||
m_Writer.BeginCompound("");
|
||||
AddBasicEntity(a_ItemFrame, "ItemFrame");
|
||||
AddHangingEntity(a_ItemFrame);
|
||||
AddItem(a_ItemFrame->GetItem(), -1, "Item");
|
||||
m_Writer.AddByte("ItemRotation", (unsigned char)a_ItemFrame->GetRotation());
|
||||
m_Writer.AddFloat("ItemDropChance", 1.0F);
|
||||
m_Writer.EndCompound();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cNBTChunkSerializer::AddMinecartChestContents(cMinecartWithChest * a_Minecart)
|
||||
{
|
||||
m_Writer.BeginList("Items", TAG_Compound);
|
||||
@ -684,8 +735,8 @@ void cNBTChunkSerializer::Entity(cEntity * a_Entity)
|
||||
case cEntity::etPickup: AddPickupEntity ((cPickup *) a_Entity); break;
|
||||
case cEntity::etProjectile: AddProjectileEntity ((cProjectileEntity *)a_Entity); break;
|
||||
case cEntity::etTNT: AddTNTEntity ((cTNTEntity *) a_Entity); break;
|
||||
case cEntity::etExpOrb: /* TODO */ break;
|
||||
case cEntity::etItemFrame: /* TODO */ break;
|
||||
case cEntity::etExpOrb: AddExpOrbEntity ((cExpOrb *) a_Entity); break;
|
||||
case cEntity::etItemFrame: AddItemFrameEntity ((cItemFrame *) a_Entity); break;
|
||||
case cEntity::etPainting: /* TODO */ break;
|
||||
case cEntity::etPlayer: return; // Players aren't saved into the world
|
||||
default:
|
||||
|
@ -42,6 +42,9 @@ class cPickup;
|
||||
class cItemGrid;
|
||||
class cProjectileEntity;
|
||||
class cTNTEntity;
|
||||
class cExpOrb;
|
||||
class cHangingEntity;
|
||||
class cItemFrame;
|
||||
|
||||
|
||||
|
||||
@ -108,7 +111,10 @@ protected:
|
||||
void AddMonsterEntity (cMonster * a_Monster);
|
||||
void AddPickupEntity (cPickup * a_Pickup);
|
||||
void AddProjectileEntity (cProjectileEntity * a_Projectile);
|
||||
void AddHangingEntity (cHangingEntity * a_Hanging);
|
||||
void AddTNTEntity (cTNTEntity * a_TNT);
|
||||
void AddExpOrbEntity (cExpOrb * a_ExpOrb);
|
||||
void AddItemFrameEntity (cItemFrame * a_ItemFrame);
|
||||
|
||||
void AddMinecartChestContents(cMinecartWithChest * a_Minecart);
|
||||
|
||||
|
@ -37,6 +37,9 @@
|
||||
#include "../Entities/Pickup.h"
|
||||
#include "../Entities/ProjectileEntity.h"
|
||||
#include "../Entities/TNTEntity.h"
|
||||
#include "../Entities/ExpOrb.h"
|
||||
#include "../Entities/HangingEntity.h"
|
||||
#include "../Entities/ItemFrame.h"
|
||||
|
||||
|
||||
|
||||
@ -1099,6 +1102,18 @@ void cWSSAnvil::LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a
|
||||
{
|
||||
LoadPickupFromNBT(a_Entities, a_NBT, a_EntityTagIdx);
|
||||
}
|
||||
else if (strncmp(a_IDTag, "PrimedTnt", a_IDTagLength) == 0)
|
||||
{
|
||||
LoadTNTFromNBT(a_Entities, a_NBT, a_EntityTagIdx);
|
||||
}
|
||||
else if (strncmp(a_IDTag, "XPOrb", a_IDTagLength) == 0)
|
||||
{
|
||||
LoadExpOrbFromNBT(a_Entities, a_NBT, a_EntityTagIdx);
|
||||
}
|
||||
else if (strncmp(a_IDTag, "ItemFrame", a_IDTagLength) == 0)
|
||||
{
|
||||
LoadItemFrameFromNBT(a_Entities, a_NBT, a_EntityTagIdx);
|
||||
}
|
||||
else if (strncmp(a_IDTag, "Arrow", a_IDTagLength) == 0)
|
||||
{
|
||||
LoadArrowFromNBT(a_Entities, a_NBT, a_EntityTagIdx);
|
||||
@ -1239,10 +1254,6 @@ void cWSSAnvil::LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a
|
||||
{
|
||||
LoadPigZombieFromNBT(a_Entities, a_NBT, a_EntityTagIdx);
|
||||
}
|
||||
else if (strncmp(a_IDTag, "PrimedTnt", a_IDTagLength) == 0)
|
||||
{
|
||||
LoadTNTFromNBT(a_Entities, a_NBT, a_EntityTagIdx);
|
||||
}
|
||||
// TODO: other entities
|
||||
}
|
||||
|
||||
@ -1385,6 +1396,7 @@ void cWSSAnvil::LoadMinecartHFromNBT(cEntityList & a_Entities, const cParsedNBT
|
||||
|
||||
void cWSSAnvil::LoadPickupFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx)
|
||||
{
|
||||
// Load item:
|
||||
int ItemTag = a_NBT.FindChildByName(a_TagIdx, "Item");
|
||||
if ((ItemTag < 0) || (a_NBT.GetType(ItemTag) != TAG_Compound))
|
||||
{
|
||||
@ -1395,11 +1407,27 @@ void cWSSAnvil::LoadPickupFromNBT(cEntityList & a_Entities, const cParsedNBT & a
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::auto_ptr<cPickup> Pickup(new cPickup(0, 0, 0, Item, false)); // Pickup delay doesn't matter, just say false
|
||||
if (!LoadEntityBaseFromNBT(*Pickup.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Load health:
|
||||
int Health = a_NBT.FindChildByName(a_TagIdx, "Health");
|
||||
if (Health > 0)
|
||||
{
|
||||
Pickup->SetHealth((int) (a_NBT.GetShort(Health) & 0xFF));
|
||||
}
|
||||
|
||||
// Load age:
|
||||
int Age = a_NBT.FindChildByName(a_TagIdx, "Age");
|
||||
if (Age > 0)
|
||||
{
|
||||
Pickup->SetAge(a_NBT.GetShort(Age));
|
||||
}
|
||||
|
||||
a_Entities.push_back(Pickup.release());
|
||||
}
|
||||
|
||||
@ -1407,6 +1435,148 @@ void cWSSAnvil::LoadPickupFromNBT(cEntityList & a_Entities, const cParsedNBT & a
|
||||
|
||||
|
||||
|
||||
void cWSSAnvil::LoadTNTFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx)
|
||||
{
|
||||
std::auto_ptr<cTNTEntity> TNT(new cTNTEntity(0.0, 0.0, 0.0, 0));
|
||||
if (!LoadEntityBaseFromNBT(*TNT.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Load Fuse Ticks:
|
||||
int FuseTicks = a_NBT.FindChildByName(a_TagIdx, "Fuse");
|
||||
if (FuseTicks > 0)
|
||||
{
|
||||
TNT->SetFuseTicks((int) a_NBT.GetByte(FuseTicks));
|
||||
}
|
||||
|
||||
a_Entities.push_back(TNT.release());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWSSAnvil::LoadExpOrbFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx)
|
||||
{
|
||||
std::auto_ptr<cExpOrb> ExpOrb(new cExpOrb(0.0, 0.0, 0.0, 0));
|
||||
if (!LoadEntityBaseFromNBT(*ExpOrb.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Load Health:
|
||||
int Health = a_NBT.FindChildByName(a_TagIdx, "Health");
|
||||
if (Health > 0)
|
||||
{
|
||||
ExpOrb->SetHealth((int) (a_NBT.GetShort(Health) & 0xFF));
|
||||
}
|
||||
|
||||
// Load Age:
|
||||
int Age = a_NBT.FindChildByName(a_TagIdx, "Age");
|
||||
if (Age > 0)
|
||||
{
|
||||
ExpOrb->SetAge(a_NBT.GetShort(Age));
|
||||
}
|
||||
|
||||
// Load Reward (Value):
|
||||
int Reward = a_NBT.FindChildByName(a_TagIdx, "Value");
|
||||
if (Reward > 0)
|
||||
{
|
||||
ExpOrb->SetReward(a_NBT.GetShort(Reward));
|
||||
}
|
||||
|
||||
a_Entities.push_back(ExpOrb.release());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWSSAnvil::LoadHangingFromNBT(cHangingEntity & a_Hanging, const cParsedNBT & a_NBT, int a_TagIdx)
|
||||
{
|
||||
int Direction = a_NBT.FindChildByName(a_TagIdx, "Direction");
|
||||
if (Direction > 0)
|
||||
{
|
||||
Direction = (int)a_NBT.GetByte(Direction);
|
||||
if ((Direction < 0) || (Direction > 5))
|
||||
{
|
||||
a_Hanging.SetDirection(BLOCK_FACE_NORTH);
|
||||
}
|
||||
else
|
||||
{
|
||||
a_Hanging.SetDirection(static_cast<eBlockFace>(Direction));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Direction = a_NBT.FindChildByName(a_TagIdx, "Dir");
|
||||
if (Direction > 0)
|
||||
{
|
||||
switch ((int)a_NBT.GetByte(Direction))
|
||||
{
|
||||
case 0: a_Hanging.SetDirection(BLOCK_FACE_NORTH); break;
|
||||
case 1: a_Hanging.SetDirection(BLOCK_FACE_TOP); break;
|
||||
case 2: a_Hanging.SetDirection(BLOCK_FACE_BOTTOM); break;
|
||||
case 3: a_Hanging.SetDirection(BLOCK_FACE_SOUTH); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int TileX = a_NBT.FindChildByName(a_TagIdx, "TileX");
|
||||
int TileY = a_NBT.FindChildByName(a_TagIdx, "TileY");
|
||||
int TileZ = a_NBT.FindChildByName(a_TagIdx, "TileZ");
|
||||
if ((TileX > 0) && (TileY > 0) && (TileZ > 0))
|
||||
{
|
||||
a_Hanging.SetPosition(
|
||||
(double)a_NBT.GetInt(TileX),
|
||||
(double)a_NBT.GetInt(TileY),
|
||||
(double)a_NBT.GetInt(TileZ)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWSSAnvil::LoadItemFrameFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx)
|
||||
{
|
||||
// Load item:
|
||||
int ItemTag = a_NBT.FindChildByName(a_TagIdx, "Item");
|
||||
if ((ItemTag < 0) || (a_NBT.GetType(ItemTag) != TAG_Compound))
|
||||
{
|
||||
return;
|
||||
}
|
||||
cItem Item;
|
||||
if (!LoadItemFromNBT(Item, a_NBT, ItemTag))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::auto_ptr<cItemFrame> ItemFrame(new cItemFrame(BLOCK_FACE_NONE, 0.0, 0.0, 0.0));
|
||||
if (!LoadEntityBaseFromNBT(*ItemFrame.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
}
|
||||
ItemFrame->SetItem(Item);
|
||||
|
||||
LoadHangingFromNBT(*ItemFrame.get(), a_NBT, a_TagIdx);
|
||||
|
||||
// Load Rotation:
|
||||
int Rotation = a_NBT.FindChildByName(a_TagIdx, "ItemRotation");
|
||||
if (Rotation > 0)
|
||||
{
|
||||
ItemFrame->SetRotation((Byte)a_NBT.GetByte(Rotation));
|
||||
}
|
||||
|
||||
a_Entities.push_back(ItemFrame.release());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWSSAnvil::LoadArrowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx)
|
||||
{
|
||||
std::auto_ptr<cArrowEntity> Arrow(new cArrowEntity(NULL, 0, 0, 0, Vector3d(0, 0, 0)));
|
||||
@ -2179,28 +2349,6 @@ void cWSSAnvil::LoadPigZombieFromNBT(cEntityList & a_Entities, const cParsedNBT
|
||||
|
||||
|
||||
|
||||
void cWSSAnvil::LoadTNTFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx)
|
||||
{
|
||||
std::auto_ptr<cTNTEntity> TNT(new cTNTEntity(0.0, 0.0, 0.0, 0));
|
||||
if (!LoadEntityBaseFromNBT(*TNT.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Load Fuse Ticks:
|
||||
int FuseTicks = a_NBT.FindChildByName(a_TagIdx, "Fuse");
|
||||
if (FuseTicks > 0)
|
||||
{
|
||||
TNT->SetFuseTicks((int) a_NBT.GetByte(FuseTicks));
|
||||
}
|
||||
|
||||
a_Entities.push_back(TNT.release());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cWSSAnvil::LoadEntityBaseFromNBT(cEntity & a_Entity, const cParsedNBT & a_NBT, int a_TagIdx)
|
||||
{
|
||||
double Pos[3];
|
||||
|
@ -20,6 +20,7 @@
|
||||
class cItemGrid;
|
||||
|
||||
class cProjectileEntity;
|
||||
class cHangingEntity;
|
||||
|
||||
|
||||
|
||||
@ -149,6 +150,10 @@ protected:
|
||||
void LoadBoatFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
void LoadFallingBlockFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
void LoadPickupFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
void LoadTNTFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
void LoadExpOrbFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
void LoadHangingFromNBT (cHangingEntity & a_Hanging,const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
void LoadItemFrameFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
|
||||
void LoadMinecartRFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
void LoadMinecartCFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
@ -192,7 +197,6 @@ protected:
|
||||
void LoadWolfFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
void LoadZombieFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
void LoadPigZombieFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
void LoadTNTFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
|
||||
/// Loads entity common data from the NBT compound; returns true if successful
|
||||
bool LoadEntityBaseFromNBT(cEntity & a_Entity, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
|
Loading…
Reference in New Issue
Block a user