1
0

Merge pull request #809 from Howaner/BlockEntitys

More entity saving.
This commit is contained in:
Mattes D 2014-03-16 21:43:33 +01:00
commit dc77cbfdc4
19 changed files with 512 additions and 99 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View 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);
}

View 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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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())
{

View File

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

View File

@ -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:

View File

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

View File

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

View File

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