1
0

Merge remote-tracking branch 'origin/customnames'

This commit is contained in:
madmaxoft 2014-01-17 10:44:23 +01:00
commit ed1d336614
38 changed files with 201 additions and 115 deletions

View File

@ -307,7 +307,7 @@ void cFurnaceEntity::OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum)
/// Updates the current recipe, based on the current input /// Updates the current recipe, based on the current input
void cFurnaceEntity::UpdateInput(void) void cFurnaceEntity::UpdateInput(void)
{ {
if (!m_Contents.GetSlot(fsInput).IsStackableWith(m_LastInput)) if (!m_Contents.GetSlot(fsInput).IsEqual(m_LastInput))
{ {
// The input is different from what we had before, reset the cooking time // The input is different from what we had before, reset the cooking time
m_TimeCooked = 0; m_TimeCooked = 0;
@ -417,7 +417,7 @@ bool cFurnaceEntity::CanCookInputToOutput(void) const
return true; return true;
} }
if (!m_Contents.GetSlot(fsOutput).IsStackableWith(*m_CurrentRecipe->Out)) if (!m_Contents.GetSlot(fsOutput).IsEqual(*m_CurrentRecipe->Out))
{ {
// The output slot is blocked with something that cannot be stacked with the recipe's output // The output slot is blocked with something that cannot be stacked with the recipe's output
return false; return false;

View File

@ -407,7 +407,7 @@ bool cHopperEntity::MoveItemsFromSlot(cBlockEntityWithItems & a_Entity, int a_Sl
m_Contents.SetSlot(i, One); m_Contents.SetSlot(i, One);
return true; return true;
} }
else if (m_Contents.GetSlot(i).IsStackableWith(One)) else if (m_Contents.GetSlot(i).IsEqual(One))
{ {
if (cPluginManager::Get()->CallHookHopperPullingItem(*m_World, *this, i, a_Entity, a_SlotNum)) if (cPluginManager::Get()->CallHookHopperPullingItem(*m_World, *this, i, a_Entity, a_SlotNum))
{ {
@ -544,7 +544,7 @@ bool cHopperEntity::MoveItemsToSlot(cBlockEntityWithItems & a_Entity, int a_DstS
} }
for (int i = 0; i < ContentsWidth * ContentsHeight; i++) for (int i = 0; i < ContentsWidth * ContentsHeight; i++)
{ {
if (m_Contents.GetSlot(i).IsStackableWith(DestSlot)) if (m_Contents.GetSlot(i).IsEqual(DestSlot))
{ {
if (cPluginManager::Get()->CallHookHopperPushingItem(*m_World, *this, i, a_Entity, a_DstSlotNum)) if (cPluginManager::Get()->CallHookHopperPushingItem(*m_World, *this, i, a_Entity, a_DstSlotNum))
{ {

View File

@ -42,7 +42,7 @@ public:
{ {
return false; return false;
} }
double rot = a_Player->GetRotation(); double rot = a_Player->GetRot().x;
if ( if (
(Area.GetRelBlockType(0, 0, 1) == E_BLOCK_CHEST) || (Area.GetRelBlockType(0, 0, 1) == E_BLOCK_CHEST) ||
(Area.GetRelBlockType(2, 0, 1) == E_BLOCK_CHEST) (Area.GetRelBlockType(2, 0, 1) == E_BLOCK_CHEST)
@ -80,7 +80,7 @@ public:
return; return;
} }
double rot = a_Player->GetRotation(); double rot = a_Player->GetRot().x;
// Choose meta from player rotation, choose only between 2 or 3 // Choose meta from player rotation, choose only between 2 or 3
NIBBLETYPE NewMeta = ((rot >= -90) && (rot < 90)) ? 2 : 3; NIBBLETYPE NewMeta = ((rot >= -90) && (rot < 90)) ? 2 : 3;
if ( if (

View File

@ -53,7 +53,7 @@ public:
) override ) override
{ {
a_BlockType = m_BlockType; a_BlockType = m_BlockType;
a_BlockMeta = cBlockRedstoneRepeaterHandler::RepeaterRotationToMetaData(a_Player->GetRotation()); a_BlockMeta = cBlockRedstoneRepeaterHandler::RepeaterRotationToMetaData(a_Player->GetRot().x);
return true; return true;
} }

View File

@ -42,7 +42,7 @@ public:
} }
a_BlockType = m_BlockType; a_BlockType = m_BlockType;
a_BlockMeta = PlayerYawToMetaData(a_Player->GetRotation()); a_BlockMeta = PlayerYawToMetaData(a_Player->GetRot().x);
return true; return true;
} }

View File

@ -31,7 +31,7 @@ public:
a_BlockType = m_BlockType; a_BlockType = m_BlockType;
// FIXME: Do not use cPiston class for dispenser placement! // FIXME: Do not use cPiston class for dispenser placement!
a_BlockMeta = cPiston::RotationPitchToMetaData(a_Player->GetRotation(), a_Player->GetPitch()); a_BlockMeta = cPiston::RotationPitchToMetaData(a_Player->GetRot().x, a_Player->GetPitch());
return true; return true;
} }
} ; } ;

View File

@ -30,7 +30,7 @@ public:
) override ) override
{ {
a_BlockType = m_BlockType; a_BlockType = m_BlockType;
a_BlockMeta = RotationToMetaData(a_Player->GetRotation()); a_BlockMeta = RotationToMetaData(a_Player->GetRot().x);
return true; return true;
} }

View File

@ -25,7 +25,7 @@ public:
) override ) override
{ {
a_BlockType = m_BlockType; a_BlockType = m_BlockType;
a_BlockMeta = PlayerYawToMetaData(a_Player->GetRotation()); a_BlockMeta = PlayerYawToMetaData(a_Player->GetRot().x);
return true; return true;
} }
@ -33,7 +33,7 @@ public:
virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override
{ {
NIBBLETYPE OldMetaData = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); NIBBLETYPE OldMetaData = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
NIBBLETYPE NewMetaData = PlayerYawToMetaData(a_Player->GetRotation()); NIBBLETYPE NewMetaData = PlayerYawToMetaData(a_Player->GetRot().x);
OldMetaData ^= 4; // Toggle the gate OldMetaData ^= 4; // Toggle the gate
if ((OldMetaData & 1) == (NewMetaData & 1)) if ((OldMetaData & 1) == (NewMetaData & 1))
{ {

View File

@ -35,7 +35,7 @@ public:
a_BlockType = m_BlockType; a_BlockType = m_BlockType;
// FIXME: Do not use cPiston class for furnace placement! // FIXME: Do not use cPiston class for furnace placement!
a_BlockMeta = cPiston::RotationPitchToMetaData(a_Player->GetRotation(), 0); a_BlockMeta = cPiston::RotationPitchToMetaData(a_Player->GetRot().x, 0);
return true; return true;
} }

View File

@ -60,7 +60,7 @@ bool cBlockPistonHandler::GetPlacementBlockTypeMeta(
) )
{ {
a_BlockType = m_BlockType; a_BlockType = m_BlockType;
a_BlockMeta = cPiston::RotationPitchToMetaData(a_Player->GetRotation(), a_Player->GetPitch()); a_BlockMeta = cPiston::RotationPitchToMetaData(a_Player->GetRot().x, a_Player->GetPitch());
return true; return true;
} }

View File

@ -86,7 +86,7 @@ public:
) override ) override
{ {
a_BlockType = m_BlockType; a_BlockType = m_BlockType;
a_BlockMeta = PlayerYawToMetaData(a_Player->GetRotation()); a_BlockMeta = PlayerYawToMetaData(a_Player->GetRot().x);
return true; return true;
} }

View File

@ -25,7 +25,7 @@ public:
) override ) override
{ {
a_BlockType = m_BlockType; a_BlockType = m_BlockType;
a_BlockMeta = RepeaterRotationToMetaData(a_Player->GetRotation()); a_BlockMeta = RepeaterRotationToMetaData(a_Player->GetRot().x);
return true; return true;
} }

View File

@ -26,7 +26,7 @@ public:
) override ) override
{ {
a_BlockType = m_BlockType; a_BlockType = m_BlockType;
a_BlockMeta = RotationToMetaData(a_Player->GetRotation()); a_BlockMeta = RotationToMetaData(a_Player->GetRot().x);
switch (a_BlockFace) switch (a_BlockFace)
{ {
case BLOCK_FACE_TOP: break; case BLOCK_FACE_TOP: break;

View File

@ -629,6 +629,17 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, ch
return; return;
} }
case DIG_STATUS_DROP_STACK:
{
if (PlgMgr->CallHookPlayerTossingItem(*m_Player))
{
// A plugin doesn't agree with the tossing. The plugin itself is responsible for handling the consequences (possible inventory mismatch)
return;
}
m_Player->TossItem(false, 64); // Toss entire slot - if there aren't enough items, the maximum will be ejected
return;
}
default: default:
{ {
ASSERT(!"Unhandled DIG_STATUS"); ASSERT(!"Unhandled DIG_STATUS");
@ -1026,7 +1037,7 @@ void cClientHandle::HandlePlayerLook(float a_Rotation, float a_Pitch, bool a_IsO
return; return;
} }
m_Player->SetRotation (a_Rotation); m_Player->SetYaw (a_Rotation);
m_Player->SetHeadYaw (a_Rotation); m_Player->SetHeadYaw (a_Rotation);
m_Player->SetPitch (a_Pitch); m_Player->SetPitch (a_Pitch);
m_Player->SetTouchGround(a_IsOnGround); m_Player->SetTouchGround(a_IsOnGround);
@ -1058,7 +1069,7 @@ void cClientHandle::HandlePlayerMoveLook(double a_PosX, double a_PosY, double a_
m_Player->SetStance (a_Stance); m_Player->SetStance (a_Stance);
m_Player->SetTouchGround(a_IsOnGround); m_Player->SetTouchGround(a_IsOnGround);
m_Player->SetHeadYaw (a_Rotation); m_Player->SetHeadYaw (a_Rotation);
m_Player->SetRotation (a_Rotation); m_Player->SetYaw (a_Rotation);
m_Player->SetPitch (a_Pitch); m_Player->SetPitch (a_Pitch);
} }

View File

@ -85,6 +85,7 @@ enum
DIG_STATUS_STARTED = 0, DIG_STATUS_STARTED = 0,
DIG_STATUS_CANCELLED = 1, DIG_STATUS_CANCELLED = 1,
DIG_STATUS_FINISHED = 2, DIG_STATUS_FINISHED = 2,
DIG_STATUS_DROP_STACK= 3,
DIG_STATUS_DROP_HELD = 4, DIG_STATUS_DROP_HELD = 4,
DIG_STATUS_SHOOT_EAT = 5, DIG_STATUS_SHOOT_EAT = 5,
} ; } ;

View File

@ -263,16 +263,16 @@ void cEntity::TakeDamage(eDamageType a_DamageType, cEntity * a_Attacker, int a_R
void cEntity::SetRotationFromSpeed(void) void cEntity::SetYawFromSpeed(void)
{ {
const double EPS = 0.0000001; const double EPS = 0.0000001;
if ((abs(m_Speed.x) < EPS) && (abs(m_Speed.z) < EPS)) if ((abs(m_Speed.x) < EPS) && (abs(m_Speed.z) < EPS))
{ {
// atan2() may overflow or is undefined, pick any number // atan2() may overflow or is undefined, pick any number
SetRotation(0); SetYaw(0);
return; return;
} }
SetRotation(atan2(m_Speed.x, m_Speed.z) * 180 / PI); SetYaw(atan2(m_Speed.x, m_Speed.z) * 180 / PI);
} }

View File

@ -155,7 +155,6 @@ public:
double GetPosY (void) const { return m_Pos.y; } double GetPosY (void) const { return m_Pos.y; }
double GetPosZ (void) const { return m_Pos.z; } double GetPosZ (void) const { return m_Pos.z; }
const Vector3d & GetRot (void) const { return m_Rot; } const Vector3d & GetRot (void) const { return m_Rot; }
double GetRotation (void) const { return m_Rot.x; } // OBSOLETE, use GetYaw() instead
double GetYaw (void) const { return m_Rot.x; } double GetYaw (void) const { return m_Rot.x; }
double GetPitch (void) const { return m_Rot.y; } double GetPitch (void) const { return m_Rot.y; }
double GetRoll (void) const { return m_Rot.z; } double GetRoll (void) const { return m_Rot.z; }
@ -178,7 +177,6 @@ public:
void SetPosition(double a_PosX, double a_PosY, double a_PosZ); void SetPosition(double a_PosX, double a_PosY, double a_PosZ);
void SetPosition(const Vector3d & a_Pos) { SetPosition(a_Pos.x, a_Pos.y, a_Pos.z); } void SetPosition(const Vector3d & a_Pos) { SetPosition(a_Pos.x, a_Pos.y, a_Pos.z); }
void SetRot (const Vector3f & a_Rot); void SetRot (const Vector3f & a_Rot);
void SetRotation(double a_Rotation) { SetYaw(a_Rotation); } // OBSOLETE, use SetYaw() instead
void SetYaw (double a_Yaw); void SetYaw (double a_Yaw);
void SetPitch (double a_Pitch); void SetPitch (double a_Pitch);
void SetRoll (double a_Roll); void SetRoll (double a_Roll);
@ -223,7 +221,7 @@ public:
void SetGravity(float a_Gravity) { m_Gravity = a_Gravity; } void SetGravity(float a_Gravity) { m_Gravity = a_Gravity; }
/// Sets the rotation to match the speed vector (entity goes "face-forward") /// Sets the rotation to match the speed vector (entity goes "face-forward")
void SetRotationFromSpeed(void); void SetYawFromSpeed(void);
/// Sets the pitch to match the speed vector (entity gies "face-forward") /// Sets the pitch to match the speed vector (entity gies "face-forward")
void SetPitchFromSpeed(void); void SetPitchFromSpeed(void);

View File

@ -148,7 +148,7 @@ void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt)
{ {
case E_META_RAIL_ZM_ZP: // NORTHSOUTH case E_META_RAIL_ZM_ZP: // NORTHSOUTH
{ {
SetRotation(270); SetYaw(270);
SetPosY(floor(GetPosY()) + 0.55); SetPosY(floor(GetPosY()) + 0.55);
SetSpeedY(0); // Don't move vertically as on ground SetSpeedY(0); // Don't move vertically as on ground
SetSpeedX(0); // Correct diagonal movement from curved rails SetSpeedX(0); // Correct diagonal movement from curved rails
@ -172,7 +172,7 @@ void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt)
} }
case E_META_RAIL_XM_XP: // EASTWEST case E_META_RAIL_XM_XP: // EASTWEST
{ {
SetRotation(180); SetYaw(180);
SetPosY(floor(GetPosY()) + 0.55); SetPosY(floor(GetPosY()) + 0.55);
SetSpeedY(0); SetSpeedY(0);
SetSpeedZ(0); SetSpeedZ(0);
@ -194,7 +194,7 @@ void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt)
} }
case E_META_RAIL_ASCEND_ZM: // ASCEND NORTH case E_META_RAIL_ASCEND_ZM: // ASCEND NORTH
{ {
SetRotation(270); SetYaw(270);
SetSpeedX(0); SetSpeedX(0);
if (GetSpeedZ() >= 0) if (GetSpeedZ() >= 0)
@ -216,7 +216,7 @@ void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt)
} }
case E_META_RAIL_ASCEND_ZP: // ASCEND SOUTH case E_META_RAIL_ASCEND_ZP: // ASCEND SOUTH
{ {
SetRotation(270); SetYaw(270);
SetSpeedX(0); SetSpeedX(0);
if (GetSpeedZ() > 0) if (GetSpeedZ() > 0)
@ -238,7 +238,7 @@ void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt)
} }
case E_META_RAIL_ASCEND_XM: // ASCEND EAST case E_META_RAIL_ASCEND_XM: // ASCEND EAST
{ {
SetRotation(180); SetYaw(180);
SetSpeedZ(0); SetSpeedZ(0);
if (GetSpeedX() >= 0) if (GetSpeedX() >= 0)
@ -258,7 +258,7 @@ void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt)
} }
case E_META_RAIL_ASCEND_XP: // ASCEND WEST case E_META_RAIL_ASCEND_XP: // ASCEND WEST
{ {
SetRotation(180); SetYaw(180);
SetSpeedZ(0); SetSpeedZ(0);
if (GetSpeedX() > 0) if (GetSpeedX() > 0)
@ -278,7 +278,7 @@ void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt)
} }
case E_META_RAIL_CURVED_ZM_XM: // Ends pointing NORTH and WEST case E_META_RAIL_CURVED_ZM_XM: // Ends pointing NORTH and WEST
{ {
SetRotation(315); // Set correct rotation server side SetYaw(315); // Set correct rotation server side
SetPosY(floor(GetPosY()) + 0.55); // Levitate dat cart SetPosY(floor(GetPosY()) + 0.55); // Levitate dat cart
if (TestBlockCollision(a_RailMeta)) return; if (TestBlockCollision(a_RailMeta)) return;
@ -303,7 +303,7 @@ void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt)
} }
case E_META_RAIL_CURVED_ZM_XP: // Curved NORTH EAST case E_META_RAIL_CURVED_ZM_XP: // Curved NORTH EAST
{ {
SetRotation(225); SetYaw(225);
SetPosY(floor(GetPosY()) + 0.55); SetPosY(floor(GetPosY()) + 0.55);
if (TestBlockCollision(a_RailMeta)) return; if (TestBlockCollision(a_RailMeta)) return;
@ -326,7 +326,7 @@ void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt)
} }
case E_META_RAIL_CURVED_ZP_XM: // Curved SOUTH WEST case E_META_RAIL_CURVED_ZP_XM: // Curved SOUTH WEST
{ {
SetRotation(135); SetYaw(135);
SetPosY(floor(GetPosY()) + 0.55); SetPosY(floor(GetPosY()) + 0.55);
if (TestBlockCollision(a_RailMeta)) return; if (TestBlockCollision(a_RailMeta)) return;
@ -349,7 +349,7 @@ void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt)
} }
case E_META_RAIL_CURVED_ZP_XP: // Curved SOUTH EAST case E_META_RAIL_CURVED_ZP_XP: // Curved SOUTH EAST
{ {
SetRotation(45); SetYaw(45);
SetPosY(floor(GetPosY()) + 0.55); SetPosY(floor(GetPosY()) + 0.55);
if (TestBlockCollision(a_RailMeta)) return; if (TestBlockCollision(a_RailMeta)) return;
@ -398,7 +398,7 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta)
{ {
case E_META_RAIL_ZM_ZP: // NORTHSOUTH case E_META_RAIL_ZM_ZP: // NORTHSOUTH
{ {
SetRotation(270); SetYaw(270);
SetPosY(floor(GetPosY()) + 0.55); SetPosY(floor(GetPosY()) + 0.55);
SetSpeedY(0); SetSpeedY(0);
SetSpeedX(0); SetSpeedX(0);
@ -420,7 +420,7 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta)
} }
case E_META_RAIL_XM_XP: // EASTWEST case E_META_RAIL_XM_XP: // EASTWEST
{ {
SetRotation(180); SetYaw(180);
SetPosY(floor(GetPosY()) + 0.55); SetPosY(floor(GetPosY()) + 0.55);
SetSpeedY(0); SetSpeedY(0);
SetSpeedZ(0); SetSpeedZ(0);

View File

@ -1382,16 +1382,21 @@ void cPlayer::TossItem(
cItem DroppedItem(GetInventory().GetEquippedItem()); cItem DroppedItem(GetInventory().GetEquippedItem());
if (!DroppedItem.IsEmpty()) if (!DroppedItem.IsEmpty())
{ {
if (GetInventory().RemoveOneEquippedItem()) char NewAmount = a_Amount;
if (NewAmount > GetInventory().GetEquippedItem().m_ItemCount)
{ {
DroppedItem.m_ItemCount = 1; // RemoveItem decreases the count, so set it to 1 again NewAmount = GetInventory().GetEquippedItem().m_ItemCount; // Drop only what's there
Drops.push_back(DroppedItem);
} }
GetInventory().GetHotbarGrid().ChangeSlotCount(GetInventory().GetEquippedSlotNum() /* Returns hotbar subslot, which HotbarGrid takes */, -a_Amount);
DroppedItem.m_ItemCount = NewAmount;
Drops.push_back(DroppedItem);
} }
} }
} }
double vX = 0, vY = 0, vZ = 0; double vX = 0, vY = 0, vZ = 0;
EulerToVector(-GetRotation(), GetPitch(), vZ, vX, vY); EulerToVector(-GetRot().x, GetPitch(), vZ, vX, vY);
vY = -vY * 2 + 1.f; vY = -vY * 2 + 1.f;
m_World->SpawnItemPickups(Drops, GetPosX(), GetEyeHeight(), GetPosZ(), vX * 3, vY * 3, vZ * 3, true); // 'true' because created by player m_World->SpawnItemPickups(Drops, GetPosX(), GetEyeHeight(), GetPosZ(), vX * 3, vY * 3, vZ * 3, true); // 'true' because created by player
} }
@ -1523,7 +1528,7 @@ bool cPlayer::LoadFromDisk()
Json::Value & JSON_PlayerRotation = root["rotation"]; Json::Value & JSON_PlayerRotation = root["rotation"];
if (JSON_PlayerRotation.size() == 3) if (JSON_PlayerRotation.size() == 3)
{ {
SetRotation ((float)JSON_PlayerRotation[(unsigned int)0].asDouble()); SetYaw ((float)JSON_PlayerRotation[(unsigned int)0].asDouble());
SetPitch ((float)JSON_PlayerRotation[(unsigned int)1].asDouble()); SetPitch ((float)JSON_PlayerRotation[(unsigned int)1].asDouble());
SetRoll ((float)JSON_PlayerRotation[(unsigned int)2].asDouble()); SetRoll ((float)JSON_PlayerRotation[(unsigned int)2].asDouble());
} }
@ -1586,7 +1591,7 @@ bool cPlayer::SaveToDisk()
JSON_PlayerPosition.append(Json::Value(GetPosZ())); JSON_PlayerPosition.append(Json::Value(GetPosZ()));
Json::Value JSON_PlayerRotation; Json::Value JSON_PlayerRotation;
JSON_PlayerRotation.append(Json::Value(GetRotation())); JSON_PlayerRotation.append(Json::Value(GetRot().x));
JSON_PlayerRotation.append(Json::Value(GetPitch())); JSON_PlayerRotation.append(Json::Value(GetPitch()));
JSON_PlayerRotation.append(Json::Value(GetRoll())); JSON_PlayerRotation.append(Json::Value(GetRoll()));

View File

@ -206,7 +206,7 @@ cProjectileEntity::cProjectileEntity(eKind a_Kind, cEntity * a_Creator, const Ve
m_IsInGround(false) m_IsInGround(false)
{ {
SetSpeed(a_Speed); SetSpeed(a_Speed);
SetRotationFromSpeed(); SetYawFromSpeed();
SetPitchFromSpeed(); SetPitchFromSpeed();
} }
@ -350,7 +350,7 @@ void cProjectileEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
NewSpeed.y += m_Gravity / 20; NewSpeed.y += m_Gravity / 20;
NewSpeed *= TracerCallback.GetSlowdownCoeff(); NewSpeed *= TracerCallback.GetSlowdownCoeff();
SetSpeed(NewSpeed); SetSpeed(NewSpeed);
SetRotationFromSpeed(); SetYawFromSpeed();
SetPitchFromSpeed(); SetPitchFromSpeed();
// DEBUG: // DEBUG:
@ -358,7 +358,7 @@ void cProjectileEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
m_UniqueID, m_UniqueID,
GetPosX(), GetPosY(), GetPosZ(), GetPosX(), GetPosY(), GetPosZ(),
GetSpeedX(), GetSpeedY(), GetSpeedZ(), GetSpeedX(), GetSpeedY(), GetSpeedZ(),
GetRotation(), GetPitch() GetRot().x, GetPitch()
); );
} }
@ -369,7 +369,7 @@ void cProjectileEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
void cProjectileEntity::SpawnOn(cClientHandle & a_Client) void cProjectileEntity::SpawnOn(cClientHandle & a_Client)
{ {
// Default spawning - use the projectile kind to spawn an object: // Default spawning - use the projectile kind to spawn an object:
a_Client.SendSpawnObject(*this, m_ProjectileKind, 12, ANGLE_TO_PROTO(GetRotation()), ANGLE_TO_PROTO(GetPitch())); a_Client.SendSpawnObject(*this, m_ProjectileKind, 12, ANGLE_TO_PROTO(GetRot().x), ANGLE_TO_PROTO(GetPitch()));
a_Client.SendEntityMetadata(*this); a_Client.SendEntityMetadata(*this);
} }
@ -402,11 +402,11 @@ cArrowEntity::cArrowEntity(cEntity * a_Creator, double a_X, double a_Y, double a
{ {
SetSpeed(a_Speed); SetSpeed(a_Speed);
SetMass(0.1); SetMass(0.1);
SetRotationFromSpeed(); SetYawFromSpeed();
SetPitchFromSpeed(); SetPitchFromSpeed();
LOGD("Created arrow %d with speed {%.02f, %.02f, %.02f} and rot {%.02f, %.02f}", LOGD("Created arrow %d with speed {%.02f, %.02f, %.02f} and rot {%.02f, %.02f}",
m_UniqueID, GetSpeedX(), GetSpeedY(), GetSpeedZ(), m_UniqueID, GetSpeedX(), GetSpeedY(), GetSpeedZ(),
GetRotation(), GetPitch() GetRot().x, GetPitch()
); );
} }

View File

@ -83,7 +83,7 @@ int cInventory::HowManyCanFit(const cItem & a_ItemStack, int a_BeginSlotNum, int
{ {
NumLeft -= MaxStack; NumLeft -= MaxStack;
} }
else if (Slot.IsStackableWith(a_ItemStack)) else if (Slot.IsEqual(a_ItemStack))
{ {
NumLeft -= MaxStack - Slot.m_ItemCount; NumLeft -= MaxStack - Slot.m_ItemCount;
} }

View File

@ -91,28 +91,6 @@ bool cItem::DamageItem(short a_Amount)
bool cItem::IsStackableWith(const cItem & a_OtherStack) const
{
if (a_OtherStack.m_ItemType != m_ItemType)
{
return false;
}
if (a_OtherStack.m_ItemDamage != m_ItemDamage)
{
return false;
}
if (a_OtherStack.m_Enchantments != m_Enchantments)
{
return false;
}
return true;
}
bool cItem::IsFullStack(void) const bool cItem::IsFullStack(void) const
{ {
return (m_ItemCount >= ItemHandler(m_ItemType)->GetMaxStackSize()); return (m_ItemCount >= ItemHandler(m_ItemType)->GetMaxStackSize());
@ -153,6 +131,14 @@ void cItem::GetJson(Json::Value & a_OutValue) const
{ {
a_OutValue["ench"] = Enchantments; a_OutValue["ench"] = Enchantments;
} }
if (!IsCustomNameEmpty())
{
a_OutValue["Name"] = m_CustomName;
}
if (!IsLoreEmpty())
{
a_OutValue["Lore"] = m_Lore;
}
} }
} }
@ -169,6 +155,8 @@ void cItem::FromJson(const Json::Value & a_Value)
m_ItemDamage = (short)a_Value.get("Health", -1 ).asInt(); m_ItemDamage = (short)a_Value.get("Health", -1 ).asInt();
m_Enchantments.Clear(); m_Enchantments.Clear();
m_Enchantments.AddFromString(a_Value.get("ench", "").asString()); m_Enchantments.AddFromString(a_Value.get("ench", "").asString());
m_CustomName = a_Value.get("Name", "").asString();
m_Lore = a_Value.get("Lore", "").asString();
} }
} }

View File

@ -36,7 +36,9 @@ public:
cItem(void) : cItem(void) :
m_ItemType(E_ITEM_EMPTY), m_ItemType(E_ITEM_EMPTY),
m_ItemCount(0), m_ItemCount(0),
m_ItemDamage(0) m_ItemDamage(0),
m_CustomName(""),
m_Lore("")
{ {
} }
@ -46,12 +48,16 @@ public:
short a_ItemType, short a_ItemType,
char a_ItemCount = 1, char a_ItemCount = 1,
short a_ItemDamage = 0, short a_ItemDamage = 0,
const AString & a_Enchantments = "" const AString & a_Enchantments = "",
const AString & a_CustomName = "",
const AString & a_Lore = ""
) : ) :
m_ItemType (a_ItemType), m_ItemType (a_ItemType),
m_ItemCount (a_ItemCount), m_ItemCount (a_ItemCount),
m_ItemDamage (a_ItemDamage), m_ItemDamage (a_ItemDamage),
m_Enchantments(a_Enchantments) m_Enchantments(a_Enchantments),
m_CustomName (a_CustomName),
m_Lore (a_Lore)
{ {
if (!IsValidItem(m_ItemType)) if (!IsValidItem(m_ItemType))
{ {
@ -69,7 +75,9 @@ public:
m_ItemType (a_CopyFrom.m_ItemType), m_ItemType (a_CopyFrom.m_ItemType),
m_ItemCount (a_CopyFrom.m_ItemCount), m_ItemCount (a_CopyFrom.m_ItemCount),
m_ItemDamage (a_CopyFrom.m_ItemDamage), m_ItemDamage (a_CopyFrom.m_ItemDamage),
m_Enchantments(a_CopyFrom.m_Enchantments) m_Enchantments(a_CopyFrom.m_Enchantments),
m_CustomName (a_CopyFrom.m_CustomName),
m_Lore (a_CopyFrom.m_Lore)
{ {
} }
@ -80,6 +88,8 @@ public:
m_ItemCount = 0; m_ItemCount = 0;
m_ItemDamage = 0; m_ItemDamage = 0;
m_Enchantments.Clear(); m_Enchantments.Clear();
m_CustomName = "";
m_Lore = "";
} }
@ -96,13 +106,16 @@ public:
return ((m_ItemType <= 0) || (m_ItemCount <= 0)); return ((m_ItemType <= 0) || (m_ItemCount <= 0));
} }
/* Returns true if this itemstack can stack with the specified stack (types match, enchantments etc.) ItemCounts are ignored!
*/
bool IsEqual(const cItem & a_Item) const bool IsEqual(const cItem & a_Item) const
{ {
return ( return (
IsSameType(a_Item) && IsSameType(a_Item) &&
(m_ItemDamage == a_Item.m_ItemDamage) && (m_ItemDamage == a_Item.m_ItemDamage) &&
(m_Enchantments == a_Item.m_Enchantments) (m_Enchantments == a_Item.m_Enchantments) &&
(m_CustomName == a_Item.m_CustomName) &&
(m_Lore == a_Item.m_Lore)
); );
} }
@ -111,7 +124,16 @@ public:
{ {
return (m_ItemType == a_Item.m_ItemType) || (IsEmpty() && a_Item.IsEmpty()); return (m_ItemType == a_Item.m_ItemType) || (IsEmpty() && a_Item.IsEmpty());
} }
bool IsBothNameAndLoreEmpty(void) const
{
return (m_CustomName.empty() && m_Lore.empty());
}
bool IsCustomNameEmpty(void) const { return (m_CustomName.empty()); }
bool IsLoreEmpty(void) const { return (m_Lore.empty()); }
/// Returns a copy of this item with m_ItemCount set to 1. Useful to preserve enchantments etc. on stacked items /// Returns a copy of this item with m_ItemCount set to 1. Useful to preserve enchantments etc. on stacked items
cItem CopyOne(void) const; cItem CopyOne(void) const;
@ -127,9 +149,6 @@ public:
inline bool IsDamageable(void) const { return (GetMaxDamage() > 0); } inline bool IsDamageable(void) const { return (GetMaxDamage() > 0); }
/// Returns true if this itemstack can stack with the specified stack (types match, enchantments etc.) ItemCounts are ignored!
bool IsStackableWith(const cItem & a_OtherStack) const;
/// Returns true if the item is stacked up to its maximum stacking. /// Returns true if the item is stacked up to its maximum stacking.
bool IsFullStack(void) const; bool IsFullStack(void) const;
@ -155,6 +174,8 @@ public:
short m_ItemType; short m_ItemType;
char m_ItemCount; char m_ItemCount;
short m_ItemDamage; short m_ItemDamage;
AString m_CustomName;
AString m_Lore;
cEnchantments m_Enchantments; cEnchantments m_Enchantments;
}; };
// tolua_end // tolua_end

View File

@ -226,7 +226,7 @@ int cItemGrid::HowManyCanFit(const cItem & a_ItemStack, bool a_AllowNewStacks)
NumLeft -= MaxStack; NumLeft -= MaxStack;
} }
} }
else if (m_Slots[i].IsStackableWith(a_ItemStack)) else if (m_Slots[i].IsEqual(a_ItemStack))
{ {
NumLeft -= MaxStack - m_Slots[i].m_ItemCount; NumLeft -= MaxStack - m_Slots[i].m_ItemCount;
} }
@ -275,7 +275,7 @@ int cItemGrid::AddItem(cItem & a_ItemStack, bool a_AllowNewStacks, int a_Priorit
(a_PrioritarySlot != -1) && (a_PrioritarySlot != -1) &&
( (
m_Slots[a_PrioritarySlot].IsEmpty() || m_Slots[a_PrioritarySlot].IsEmpty() ||
m_Slots[a_PrioritarySlot].IsStackableWith(a_ItemStack) m_Slots[a_PrioritarySlot].IsEqual(a_ItemStack)
) )
) )
{ {
@ -285,7 +285,7 @@ int cItemGrid::AddItem(cItem & a_ItemStack, bool a_AllowNewStacks, int a_Priorit
// Scan existing stacks: // Scan existing stacks:
for (int i = m_NumSlots - 1; i >= 0; i--) for (int i = m_NumSlots - 1; i >= 0; i--)
{ {
if (m_Slots[i].IsStackableWith(a_ItemStack)) if (m_Slots[i].IsEqual(a_ItemStack))
{ {
NumLeft -= AddItemToSlot(a_ItemStack, i, NumLeft, MaxStack); NumLeft -= AddItemToSlot(a_ItemStack, i, NumLeft, MaxStack);
} }
@ -438,7 +438,7 @@ int cItemGrid::HowManyItems(const cItem & a_Item)
int res = 0; int res = 0;
for (int i = 0; i < m_NumSlots; i++) for (int i = 0; i < m_NumSlots; i++)
{ {
if (m_Slots[i].IsStackableWith(a_Item)) if (m_Slots[i].IsEqual(a_Item))
{ {
res += m_Slots[i].m_ItemCount; res += m_Slots[i].m_ItemCount;
} }

View File

@ -37,7 +37,7 @@ public:
return false; return false;
} }
a_BlockMeta = cBlockBedHandler::RotationToMetaData(a_Player->GetRotation()); a_BlockMeta = cBlockBedHandler::RotationToMetaData(a_Player->GetRot().x);
// Check if there is empty space for the foot section: // Check if there is empty space for the foot section:
Vector3i Direction = cBlockBedHandler::MetaDataToDirection(a_BlockMeta); Vector3i Direction = cBlockBedHandler::MetaDataToDirection(a_BlockMeta);

View File

@ -30,7 +30,7 @@ public:
) override ) override
{ {
a_BlockType = E_BLOCK_INACTIVE_COMPARATOR; a_BlockType = E_BLOCK_INACTIVE_COMPARATOR;
a_BlockMeta = cBlockRedstoneRepeaterHandler::RepeaterRotationToMetaData(a_Player->GetRotation()); a_BlockMeta = cBlockRedstoneRepeaterHandler::RepeaterRotationToMetaData(a_Player->GetRot().x);
return true; return true;
} }
} ; } ;

View File

@ -30,7 +30,7 @@ public:
) override ) override
{ {
a_BlockType = E_BLOCK_REDSTONE_REPEATER_OFF; a_BlockType = E_BLOCK_REDSTONE_REPEATER_OFF;
a_BlockMeta = cBlockRedstoneRepeaterHandler::RepeaterRotationToMetaData(a_Player->GetRotation()); a_BlockMeta = cBlockRedstoneRepeaterHandler::RepeaterRotationToMetaData(a_Player->GetRot().x);
return true; return true;
} }
} ; } ;

View File

@ -34,7 +34,7 @@ public:
{ {
if (a_BlockFace == BLOCK_FACE_TOP) if (a_BlockFace == BLOCK_FACE_TOP)
{ {
a_BlockMeta = cBlockSignHandler::RotationToMetaData(a_Player->GetRotation()); a_BlockMeta = cBlockSignHandler::RotationToMetaData(a_Player->GetRot().x);
a_BlockType = E_BLOCK_SIGN_POST; a_BlockType = E_BLOCK_SIGN_POST;
} }
else else

View File

@ -208,7 +208,7 @@ void cMonster::Tick(float a_Dt, cChunk & a_Chunk)
Distance.Normalize(); Distance.Normalize();
VectorToEuler( Distance.x, Distance.y, Distance.z, Rotation, Pitch ); VectorToEuler( Distance.x, Distance.y, Distance.z, Rotation, Pitch );
SetHeadYaw (Rotation); SetHeadYaw (Rotation);
SetRotation( Rotation ); SetYaw( Rotation );
SetPitch( -Pitch ); SetPitch( -Pitch );
} }

View File

@ -354,7 +354,7 @@ void cProtocol125::SendEntityLook(const cEntity & a_Entity)
cCSLock Lock(m_CSPacket); cCSLock Lock(m_CSPacket);
WriteByte(PACKET_ENT_LOOK); WriteByte(PACKET_ENT_LOOK);
WriteInt (a_Entity.GetUniqueID()); WriteInt (a_Entity.GetUniqueID());
WriteByte((char)((a_Entity.GetRotation() / 360.f) * 256)); WriteByte((char)((a_Entity.GetRot().x / 360.f) * 256));
WriteByte((char)((a_Entity.GetPitch() / 360.f) * 256)); WriteByte((char)((a_Entity.GetPitch() / 360.f) * 256));
Flush(); Flush();
} }
@ -423,7 +423,7 @@ void cProtocol125::SendEntityRelMoveLook(const cEntity & a_Entity, char a_RelX,
WriteByte(a_RelX); WriteByte(a_RelX);
WriteByte(a_RelY); WriteByte(a_RelY);
WriteByte(a_RelZ); WriteByte(a_RelZ);
WriteByte((char)((a_Entity.GetRotation() / 360.f) * 256)); WriteByte((char)((a_Entity.GetRot().x / 360.f) * 256));
WriteByte((char)((a_Entity.GetPitch() / 360.f) * 256)); WriteByte((char)((a_Entity.GetPitch() / 360.f) * 256));
Flush(); Flush();
} }
@ -664,7 +664,7 @@ void cProtocol125::SendPlayerMoveLook(void)
WriteDouble(Player->GetStance() + 0.03); // Add a small amount so that the player doesn't start inside a block WriteDouble(Player->GetStance() + 0.03); // Add a small amount so that the player doesn't start inside a block
WriteDouble(Player->GetPosY() + 0.03); // Add a small amount so that the player doesn't start inside a block WriteDouble(Player->GetPosY() + 0.03); // Add a small amount so that the player doesn't start inside a block
WriteDouble(Player->GetPosZ()); WriteDouble(Player->GetPosZ());
WriteFloat ((float)(Player->GetRotation())); WriteFloat ((float)(Player->GetRot().x));
WriteFloat ((float)(Player->GetPitch())); WriteFloat ((float)(Player->GetPitch()));
WriteBool (Player->IsOnGround()); WriteBool (Player->IsOnGround());
Flush(); Flush();
@ -864,7 +864,7 @@ void cProtocol125::SendSpawnVehicle(const cEntity & a_Vehicle, char a_VehicleTyp
WriteInt ((int)(a_Vehicle.GetPosY() * 32)); WriteInt ((int)(a_Vehicle.GetPosY() * 32));
WriteInt ((int)(a_Vehicle.GetPosZ() * 32)); WriteInt ((int)(a_Vehicle.GetPosZ() * 32));
WriteByte ((Byte)((a_Vehicle.GetPitch() / 360.f) * 256)); WriteByte ((Byte)((a_Vehicle.GetPitch() / 360.f) * 256));
WriteByte ((Byte)((a_Vehicle.GetRotation() / 360.f) * 256)); WriteByte ((Byte)((a_Vehicle.GetRot().x / 360.f) * 256));
WriteInt (a_VehicleSubType); WriteInt (a_VehicleSubType);
if (a_VehicleSubType != 0) if (a_VehicleSubType != 0)
{ {
@ -897,7 +897,7 @@ void cProtocol125::SendTeleportEntity(const cEntity & a_Entity)
WriteInt ((int)(floor(a_Entity.GetPosX() * 32))); WriteInt ((int)(floor(a_Entity.GetPosX() * 32)));
WriteInt ((int)(floor(a_Entity.GetPosY() * 32))); WriteInt ((int)(floor(a_Entity.GetPosY() * 32)));
WriteInt ((int)(floor(a_Entity.GetPosZ() * 32))); WriteInt ((int)(floor(a_Entity.GetPosZ() * 32)));
WriteByte ((char)((a_Entity.GetRotation() / 360.f) * 256)); WriteByte ((char)((a_Entity.GetRot().x / 360.f) * 256));
WriteByte ((char)((a_Entity.GetPitch() / 360.f) * 256)); WriteByte ((char)((a_Entity.GetPitch() / 360.f) * 256));
Flush(); Flush();
} }

View File

@ -421,7 +421,7 @@ void cProtocol132::SendSpawnMob(const cMonster & a_Mob)
WriteInt (a_Mob.GetUniqueID()); WriteInt (a_Mob.GetUniqueID());
WriteByte (a_Mob.GetMobType()); WriteByte (a_Mob.GetMobType());
WriteVectorI((Vector3i)(a_Mob.GetPosition() * 32)); WriteVectorI((Vector3i)(a_Mob.GetPosition() * 32));
WriteByte ((Byte)((a_Mob.GetRotation() / 360.f) * 256)); WriteByte ((Byte)((a_Mob.GetRot().x / 360.f) * 256));
WriteByte ((Byte)((a_Mob.GetPitch() / 360.f) * 256)); WriteByte ((Byte)((a_Mob.GetPitch() / 360.f) * 256));
WriteByte ((Byte)((a_Mob.GetHeadYaw() / 360.f) * 256)); WriteByte ((Byte)((a_Mob.GetHeadYaw() / 360.f) * 256));
WriteShort ((short)(a_Mob.GetSpeedX() * 400)); WriteShort ((short)(a_Mob.GetSpeedX() * 400));

View File

@ -250,7 +250,7 @@ void cProtocol146::SendSpawnVehicle(const cEntity & a_Vehicle, char a_VehicleTyp
WriteInt ((int)(a_Vehicle.GetPosY() * 32)); WriteInt ((int)(a_Vehicle.GetPosY() * 32));
WriteInt ((int)(a_Vehicle.GetPosZ() * 32)); WriteInt ((int)(a_Vehicle.GetPosZ() * 32));
WriteByte ((Byte)((a_Vehicle.GetPitch() / 360.f) * 256)); WriteByte ((Byte)((a_Vehicle.GetPitch() / 360.f) * 256));
WriteByte ((Byte)((a_Vehicle.GetRotation() / 360.f) * 256)); WriteByte ((Byte)((a_Vehicle.GetRot().x / 360.f) * 256));
WriteInt (a_VehicleSubType); WriteInt (a_VehicleSubType);
if (a_VehicleSubType != 0) if (a_VehicleSubType != 0)
{ {

View File

@ -1685,7 +1685,7 @@ void cProtocol172::ParseItemMetadata(cItem & a_Item, const AString & a_Metadata)
return; return;
} }
// Load enchantments from the NBT: // Load enchantments and custom display names from the NBT data:
for (int tag = NBT.GetFirstChild(NBT.GetRoot()); tag >= 0; tag = NBT.GetNextSibling(tag)) for (int tag = NBT.GetFirstChild(NBT.GetRoot()); tag >= 0; tag = NBT.GetNextSibling(tag))
{ {
if ( if (
@ -1698,6 +1698,27 @@ void cProtocol172::ParseItemMetadata(cItem & a_Item, const AString & a_Metadata)
{ {
a_Item.m_Enchantments.ParseFromNBT(NBT, tag); a_Item.m_Enchantments.ParseFromNBT(NBT, tag);
} }
else if ((NBT.GetType(tag) == TAG_Compound) && (NBT.GetName(tag) == "display")) // Custom name and lore tag
{
for (int displaytag = NBT.GetFirstChild(tag); displaytag >= 0; displaytag = NBT.GetNextSibling(displaytag))
{
if ((NBT.GetType(displaytag) == TAG_String) && (NBT.GetName(displaytag) == "Name")) // Custon name tag
{
a_Item.m_CustomName = NBT.GetString(displaytag);
}
else if ((NBT.GetType(displaytag) == TAG_List) && (NBT.GetName(displaytag) == "Lore")) // Lore tag
{
AString Lore;
for (int loretag = NBT.GetFirstChild(displaytag); loretag >= 0; loretag = NBT.GetNextSibling(loretag)) // Loop through array of strings
{
AppendPrintf(Lore, "%s`", NBT.GetString(loretag).c_str()); // Append the lore with a newline, used internally by MCS to display a new line in the client; don't forget to c_str ;)
}
a_Item.m_Lore = Lore;
}
}
}
} }
} }
@ -1749,16 +1770,45 @@ void cProtocol172::cPacketizer::WriteItem(const cItem & a_Item)
WriteByte (a_Item.m_ItemCount); WriteByte (a_Item.m_ItemCount);
WriteShort(a_Item.m_ItemDamage); WriteShort(a_Item.m_ItemDamage);
if (a_Item.m_Enchantments.IsEmpty()) if (a_Item.m_Enchantments.IsEmpty() && a_Item.IsBothNameAndLoreEmpty())
{ {
WriteShort(-1); WriteShort(-1);
return; return;
} }
// Send the enchantments: // Send the enchantments and custom names:
cFastNBTWriter Writer; cFastNBTWriter Writer;
const char * TagName = (a_Item.m_ItemType == E_ITEM_BOOK) ? "StoredEnchantments" : "ench"; if (!a_Item.m_Enchantments.IsEmpty())
a_Item.m_Enchantments.WriteToNBTCompound(Writer, TagName); {
const char * TagName = (a_Item.m_ItemType == E_ITEM_BOOK) ? "StoredEnchantments" : "ench";
a_Item.m_Enchantments.WriteToNBTCompound(Writer, TagName);
}
if (!a_Item.IsBothNameAndLoreEmpty())
{
Writer.BeginCompound("display");
if (!a_Item.IsCustomNameEmpty())
{
Writer.AddString("Name", a_Item.m_CustomName.c_str());
}
if (!a_Item.IsLoreEmpty())
{
Writer.BeginList("Lore", TAG_String);
AStringVector Decls = StringSplit(a_Item.m_Lore, "`");
for (AStringVector::const_iterator itr = Decls.begin(), end = Decls.end(); itr != end; ++itr)
{
if (itr->empty())
{
// The decl is empty (two `s), ignore
continue;
}
Writer.AddString("", itr->c_str());
}
Writer.EndList();
}
Writer.EndCompound();
}
Writer.Finish(); Writer.Finish();
AString Compressed; AString Compressed;
CompressStringGZIP(Writer.GetResult().data(), Writer.GetResult().size(), Compressed); CompressStringGZIP(Writer.GetResult().data(), Writer.GetResult().size(), Compressed);

View File

@ -85,10 +85,10 @@ void cSlotArea::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickA
{ {
if (DraggingItem.m_ItemType <= 0) // Empty-handed? if (DraggingItem.m_ItemType <= 0) // Empty-handed?
{ {
DraggingItem = Slot.CopyOne(); // Obtain copy of slot to preserve lore, enchantments, etc.
DraggingItem.m_ItemCount = (char)(((float)Slot.m_ItemCount) / 2.f + 0.5f); DraggingItem.m_ItemCount = (char)(((float)Slot.m_ItemCount) / 2.f + 0.5f);
Slot.m_ItemCount -= DraggingItem.m_ItemCount; Slot.m_ItemCount -= DraggingItem.m_ItemCount;
DraggingItem.m_ItemType = Slot.m_ItemType;
DraggingItem.m_ItemDamage = Slot.m_ItemDamage;
if (Slot.m_ItemCount <= 0) if (Slot.m_ItemCount <= 0)
{ {
@ -101,9 +101,12 @@ void cSlotArea::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickA
cItemHandler * Handler = ItemHandler(Slot.m_ItemType); cItemHandler * Handler = ItemHandler(Slot.m_ItemType);
if ((DraggingItem.m_ItemCount > 0) && (Slot.m_ItemCount < Handler->GetMaxStackSize())) if ((DraggingItem.m_ItemCount > 0) && (Slot.m_ItemCount < Handler->GetMaxStackSize()))
{ {
Slot.m_ItemType = DraggingItem.m_ItemType; char OldSlotCount = Slot.m_ItemCount;
Slot.m_ItemCount++;
Slot.m_ItemDamage = DraggingItem.m_ItemDamage; Slot = DraggingItem.CopyOne(); // See above
OldSlotCount++;
Slot.m_ItemCount = OldSlotCount;
DraggingItem.m_ItemCount--; DraggingItem.m_ItemCount--;
} }
if (DraggingItem.m_ItemCount <= 0) if (DraggingItem.m_ItemCount <= 0)
@ -226,7 +229,7 @@ void cSlotArea::DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_
for (int i = 0; i < m_NumSlots; i++) for (int i = 0; i < m_NumSlots; i++)
{ {
const cItem * Slot = GetSlot(i, a_Player); const cItem * Slot = GetSlot(i, a_Player);
if (!Slot->IsStackableWith(a_ItemStack) && (!Slot->IsEmpty() || a_KeepEmptySlots)) if (!Slot->IsEqual(a_ItemStack) && (!Slot->IsEmpty() || a_KeepEmptySlots))
{ {
// Different items // Different items
continue; continue;
@ -265,7 +268,7 @@ bool cSlotArea::CollectItemsToHand(cItem & a_Dragging, cPlayer & a_Player, bool
for (int i = 0; i < NumSlots; i++) for (int i = 0; i < NumSlots; i++)
{ {
const cItem & SlotItem = *GetSlot(i, a_Player); const cItem & SlotItem = *GetSlot(i, a_Player);
if (!SlotItem.IsStackableWith(a_Dragging)) if (!SlotItem.IsEqual(a_Dragging))
{ {
continue; continue;
} }
@ -908,7 +911,7 @@ void cSlotAreaTemporary::TossItems(cPlayer & a_Player, int a_Begin, int a_End)
} // for i - itr->second[] } // for i - itr->second[]
double vX = 0, vY = 0, vZ = 0; double vX = 0, vY = 0, vZ = 0;
EulerToVector(-a_Player.GetRotation(), a_Player.GetPitch(), vZ, vX, vY); EulerToVector(-a_Player.GetRot().x, a_Player.GetPitch(), vZ, vX, vY);
vY = -vY * 2 + 1.f; vY = -vY * 2 + 1.f;
a_Player.GetWorld()->SpawnItemPickups(Drops, a_Player.GetPosX(), a_Player.GetPosY() + 1.6f, a_Player.GetPosZ(), vX * 3, vY * 3, vZ * 3, true); // 'true' because player created a_Player.GetWorld()->SpawnItemPickups(Drops, a_Player.GetPosX(), a_Player.GetPosY() + 1.6f, a_Player.GetPosZ(), vX * 3, vY * 3, vZ * 3, true); // 'true' because player created
} }

View File

@ -642,7 +642,7 @@ int cWindow::DistributeItemToSlots(cPlayer & a_Player, const cItem & a_Item, int
Area->SetSlot(LocalSlotNum, a_Player, ToStore); Area->SetSlot(LocalSlotNum, a_Player, ToStore);
NumDistributed += ToStore.m_ItemCount; NumDistributed += ToStore.m_ItemCount;
} }
else if (AtSlot.IsStackableWith(a_Item)) else if (AtSlot.IsEqual(a_Item))
{ {
// Occupied, add and cap at MaxStack: // Occupied, add and cap at MaxStack:
int CanStore = std::min(a_NumToEachSlot, (int)MaxStack - AtSlot.m_ItemCount); int CanStore = std::min(a_NumToEachSlot, (int)MaxStack - AtSlot.m_ItemCount);

View File

@ -257,7 +257,7 @@ void cNBTChunkSerializer::AddBasicEntity(cEntity * a_Entity, const AString & a_C
m_Writer.AddDouble("", a_Entity->GetSpeedZ()); m_Writer.AddDouble("", a_Entity->GetSpeedZ());
m_Writer.EndList(); m_Writer.EndList();
m_Writer.BeginList("Rotation", TAG_Double); m_Writer.BeginList("Rotation", TAG_Double);
m_Writer.AddDouble("", a_Entity->GetRotation()); m_Writer.AddDouble("", a_Entity->GetRot().x);
m_Writer.AddDouble("", a_Entity->GetPitch()); m_Writer.AddDouble("", a_Entity->GetPitch());
m_Writer.EndList(); m_Writer.EndList();
} }

View File

@ -1891,7 +1891,7 @@ bool cWSSAnvil::LoadEntityBaseFromNBT(cEntity & a_Entity, const cParsedNBT & a_N
{ {
return false; return false;
} }
a_Entity.SetRotation(Rotation[0]); a_Entity.SetYaw(Rotation[0]);
a_Entity.SetRoll (Rotation[1]); a_Entity.SetRoll (Rotation[1]);
return true; return true;

View File

@ -47,9 +47,18 @@ void NonCtrlHandler(int a_Signal)
case SIGSEGV: case SIGSEGV:
{ {
std::signal(SIGSEGV, SIG_DFL); std::signal(SIGSEGV, SIG_DFL);
LOGWARN("Segmentation fault; MCServer has crashed :("); LOGERROR(" D: | MCServer has encountered an error and needs to close");
LOGERROR("Details | SIGSEGV: Segmentation fault");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
case SIGABRT:
case SIGABRT_COMPAT:
{
std::signal(a_Signal, SIG_DFL);
LOGERROR(" D: | MCServer has encountered an error and needs to close");
LOGERROR("Details | SIGABRT: Server self-terminated due to an internal fault");
break;
}
case SIGTERM: case SIGTERM:
{ {
std::signal(SIGTERM, SIG_IGN); // Server is shutting down, wait for it... std::signal(SIGTERM, SIG_IGN); // Server is shutting down, wait for it...