Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
3710d423ac
@ -2020,6 +2020,7 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage);
|
|||||||
SetMaxPlayers = { Params = "number", Notes = "Sets the max amount of players who can join." },
|
SetMaxPlayers = { Params = "number", Notes = "Sets the max amount of players who can join." },
|
||||||
GetNumPlayers = { Return = "number", Notes = "Returns the amount of players online." },
|
GetNumPlayers = { Return = "number", Notes = "Returns the amount of players online." },
|
||||||
GetServerID = { Return = "string", Notes = "Returns the ID of the server?" },
|
GetServerID = { Return = "string", Notes = "Returns the ID of the server?" },
|
||||||
|
IsHardcore = { Params = "", Return = "bool", Notes = "Returns true if the server is hardcore (players get banned on death)." },
|
||||||
},
|
},
|
||||||
Constants =
|
Constants =
|
||||||
{
|
{
|
||||||
|
@ -2205,8 +2205,8 @@ bool cConnection::HandleServerSpawnNamedEntity(void)
|
|||||||
CreateHexDump(HexDump, Metadata.data(), Metadata.size(), 32);
|
CreateHexDump(HexDump, Metadata.data(), Metadata.size(), 32);
|
||||||
Log("Received a PACKET_SPAWN_NAMED_ENTITY from the server:");
|
Log("Received a PACKET_SPAWN_NAMED_ENTITY from the server:");
|
||||||
Log(" EntityID = %u (0x%x)", EntityID, EntityID);
|
Log(" EntityID = %u (0x%x)", EntityID, EntityID);
|
||||||
Log(" UUID = %s", EntityUUID.c_str());
|
Log(" UUID = \"%s\"", EntityUUID.c_str());
|
||||||
Log(" Name = %s", EntityName.c_str());
|
Log(" Name = \"%s\"", EntityName.c_str());
|
||||||
Log(" Pos = %s", PrintableAbsIntTriplet(PosX, PosY, PosZ).c_str());
|
Log(" Pos = %s", PrintableAbsIntTriplet(PosX, PosY, PosZ).c_str());
|
||||||
Log(" Rotation = <yaw %d, pitch %d>", Yaw, Pitch);
|
Log(" Rotation = <yaw %d, pitch %d>", Yaw, Pitch);
|
||||||
Log(" CurrentItem = %d", CurrentItem);
|
Log(" CurrentItem = %d", CurrentItem);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
** Lua binding: AllToLua
|
** Lua binding: AllToLua
|
||||||
** Generated automatically by tolua++-1.0.92 on 11/09/13 19:50:08.
|
** Generated automatically by tolua++-1.0.92 on 11/10/13 18:40:47.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __cplusplus
|
#ifndef __cplusplus
|
||||||
@ -15845,6 +15845,38 @@ static int tolua_AllToLua_cItem_IsFullStack00(lua_State* tolua_S)
|
|||||||
}
|
}
|
||||||
#endif //#ifndef TOLUA_DISABLE
|
#endif //#ifndef TOLUA_DISABLE
|
||||||
|
|
||||||
|
/* method: GetMaxStackSize of class cItem */
|
||||||
|
#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_GetMaxStackSize00
|
||||||
|
static int tolua_AllToLua_cItem_GetMaxStackSize00(lua_State* tolua_S)
|
||||||
|
{
|
||||||
|
#ifndef TOLUA_RELEASE
|
||||||
|
tolua_Error tolua_err;
|
||||||
|
if (
|
||||||
|
!tolua_isusertype(tolua_S,1,"const cItem",0,&tolua_err) ||
|
||||||
|
!tolua_isnoobj(tolua_S,2,&tolua_err)
|
||||||
|
)
|
||||||
|
goto tolua_lerror;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
const cItem* self = (const cItem*) tolua_tousertype(tolua_S,1,0);
|
||||||
|
#ifndef TOLUA_RELEASE
|
||||||
|
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetMaxStackSize'", NULL);
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
char tolua_ret = (char) self->GetMaxStackSize();
|
||||||
|
tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
#ifndef TOLUA_RELEASE
|
||||||
|
tolua_lerror:
|
||||||
|
tolua_error(tolua_S,"#ferror in function 'GetMaxStackSize'.",&tolua_err);
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif //#ifndef TOLUA_DISABLE
|
||||||
|
|
||||||
/* get function: m_ItemType of class cItem */
|
/* get function: m_ItemType of class cItem */
|
||||||
#ifndef TOLUA_DISABLE_tolua_get_cItem_m_ItemType
|
#ifndef TOLUA_DISABLE_tolua_get_cItem_m_ItemType
|
||||||
static int tolua_get_cItem_m_ItemType(lua_State* tolua_S)
|
static int tolua_get_cItem_m_ItemType(lua_State* tolua_S)
|
||||||
@ -30521,6 +30553,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
|
|||||||
tolua_function(tolua_S,"IsDamageable",tolua_AllToLua_cItem_IsDamageable00);
|
tolua_function(tolua_S,"IsDamageable",tolua_AllToLua_cItem_IsDamageable00);
|
||||||
tolua_function(tolua_S,"IsStackableWith",tolua_AllToLua_cItem_IsStackableWith00);
|
tolua_function(tolua_S,"IsStackableWith",tolua_AllToLua_cItem_IsStackableWith00);
|
||||||
tolua_function(tolua_S,"IsFullStack",tolua_AllToLua_cItem_IsFullStack00);
|
tolua_function(tolua_S,"IsFullStack",tolua_AllToLua_cItem_IsFullStack00);
|
||||||
|
tolua_function(tolua_S,"GetMaxStackSize",tolua_AllToLua_cItem_GetMaxStackSize00);
|
||||||
tolua_variable(tolua_S,"m_ItemType",tolua_get_cItem_m_ItemType,tolua_set_cItem_m_ItemType);
|
tolua_variable(tolua_S,"m_ItemType",tolua_get_cItem_m_ItemType,tolua_set_cItem_m_ItemType);
|
||||||
tolua_variable(tolua_S,"m_ItemCount",tolua_get_cItem_m_ItemCount,tolua_set_cItem_m_ItemCount);
|
tolua_variable(tolua_S,"m_ItemCount",tolua_get_cItem_m_ItemCount,tolua_set_cItem_m_ItemCount);
|
||||||
tolua_variable(tolua_S,"m_ItemDamage",tolua_get_cItem_m_ItemDamage,tolua_set_cItem_m_ItemDamage);
|
tolua_variable(tolua_S,"m_ItemDamage",tolua_get_cItem_m_ItemDamage,tolua_set_cItem_m_ItemDamage);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
** Lua binding: AllToLua
|
** Lua binding: AllToLua
|
||||||
** Generated automatically by tolua++-1.0.92 on 11/09/13 19:50:08.
|
** Generated automatically by tolua++-1.0.92 on 11/10/13 18:40:47.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Exported function */
|
/* Exported function */
|
||||||
|
@ -122,6 +122,15 @@ bool cItem::IsFullStack(void) const
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
char cItem::GetMaxStackSize(void) const
|
||||||
|
{
|
||||||
|
return ItemHandler(m_ItemType)->GetMaxStackSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// Returns the cItemHandler responsible for this item type
|
/// Returns the cItemHandler responsible for this item type
|
||||||
cItemHandler * cItem::GetHandler(void) const
|
cItemHandler * cItem::GetHandler(void) const
|
||||||
{
|
{
|
||||||
|
@ -133,6 +133,9 @@ public:
|
|||||||
/// 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;
|
||||||
|
|
||||||
|
/// Returns the maximum amount of stacked items of this type.
|
||||||
|
char GetMaxStackSize(void) const;
|
||||||
|
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
||||||
/// Returns the cItemHandler responsible for this item type
|
/// Returns the cItemHandler responsible for this item type
|
||||||
|
@ -33,7 +33,6 @@ void cSheep::GetDrops(cItems & a_Drops, cEntity * a_Killer)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cSheep::OnRightClicked(cPlayer & a_Player)
|
void cSheep::OnRightClicked(cPlayer & a_Player)
|
||||||
{
|
{
|
||||||
if ((a_Player.GetEquippedItem().m_ItemType == E_ITEM_SHEARS) && (!m_IsSheared))
|
if ((a_Player.GetEquippedItem().m_ItemType == E_ITEM_SHEARS) && (!m_IsSheared))
|
||||||
@ -51,9 +50,13 @@ void cSheep::OnRightClicked(cPlayer & a_Player)
|
|||||||
Drops.push_back(cItem(E_BLOCK_WOOL, NumDrops, m_WoolColor));
|
Drops.push_back(cItem(E_BLOCK_WOOL, NumDrops, m_WoolColor));
|
||||||
m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY(), GetPosZ(), 10);
|
m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY(), GetPosZ(), 10);
|
||||||
}
|
}
|
||||||
|
if ((a_Player.GetEquippedItem().m_ItemType == E_ITEM_DYE) && (m_WoolColor != 15 - a_Player.GetEquippedItem().m_ItemDamage))
|
||||||
|
{
|
||||||
|
m_WoolColor = 15 - a_Player.GetEquippedItem().m_ItemDamage;
|
||||||
|
if (!a_Player.IsGameModeCreative())
|
||||||
|
{
|
||||||
|
a_Player.GetInventory().RemoveOneEquippedItem();
|
||||||
|
}
|
||||||
|
m_World->BroadcastEntityMetadata(*this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,10 +11,12 @@
|
|||||||
|
|
||||||
cWolf::cWolf(void) :
|
cWolf::cWolf(void) :
|
||||||
super("Wolf", mtWolf, "mob.wolf.hurt", "mob.wolf.death", 0.6, 0.8),
|
super("Wolf", mtWolf, "mob.wolf.hurt", "mob.wolf.death", 0.6, 0.8),
|
||||||
m_bIsAngry(false),
|
m_IsAngry(false),
|
||||||
m_bIsTame(false),
|
m_IsTame(false),
|
||||||
m_bIsSitting(false),
|
m_IsSitting(false),
|
||||||
m_bIsBegging(false)
|
m_IsBegging(false),
|
||||||
|
m_Owner(""),
|
||||||
|
m_CollarColor(14)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,9 +27,9 @@ cWolf::cWolf(void) :
|
|||||||
void cWolf::DoTakeDamage(TakeDamageInfo & a_TDI)
|
void cWolf::DoTakeDamage(TakeDamageInfo & a_TDI)
|
||||||
{
|
{
|
||||||
super::DoTakeDamage(a_TDI);
|
super::DoTakeDamage(a_TDI);
|
||||||
if (!m_bIsTame)
|
if (!m_IsTame)
|
||||||
{
|
{
|
||||||
m_bIsAngry = true;
|
m_IsAngry = true;
|
||||||
}
|
}
|
||||||
m_World->BroadcastEntityMetadata(*this); // Broadcast health and possibly angry face
|
m_World->BroadcastEntityMetadata(*this); // Broadcast health and possibly angry face
|
||||||
}
|
}
|
||||||
@ -38,7 +40,7 @@ void cWolf::DoTakeDamage(TakeDamageInfo & a_TDI)
|
|||||||
|
|
||||||
void cWolf::OnRightClicked(cPlayer & a_Player)
|
void cWolf::OnRightClicked(cPlayer & a_Player)
|
||||||
{
|
{
|
||||||
if ((!m_bIsTame) && (!m_bIsAngry))
|
if (!IsTame() && !IsAngry())
|
||||||
{
|
{
|
||||||
if (a_Player.GetEquippedItem().m_ItemType == E_ITEM_BONE)
|
if (a_Player.GetEquippedItem().m_ItemType == E_ITEM_BONE)
|
||||||
{
|
{
|
||||||
@ -47,10 +49,11 @@ void cWolf::OnRightClicked(cPlayer & a_Player)
|
|||||||
a_Player.GetInventory().RemoveOneEquippedItem();
|
a_Player.GetInventory().RemoveOneEquippedItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_World->GetTickRandomNumber(10) == 5)
|
if (m_World->GetTickRandomNumber(7) == 0)
|
||||||
{
|
{
|
||||||
SetMaxHealth(20);
|
SetMaxHealth(20);
|
||||||
m_bIsTame = true;
|
SetIsTame(true);
|
||||||
|
SetOwner(a_Player.GetName());
|
||||||
m_World->BroadcastEntityStatus(*this, ENTITY_STATUS_WOLF_TAMED);
|
m_World->BroadcastEntityStatus(*this, ENTITY_STATUS_WOLF_TAMED);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -59,15 +62,26 @@ void cWolf::OnRightClicked(cPlayer & a_Player)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (m_bIsTame)
|
else if (IsTame())
|
||||||
{
|
{
|
||||||
if (m_bIsSitting)
|
if (a_Player.GetName() == m_Owner) // Is the player the owner of the dog?
|
||||||
{
|
{
|
||||||
m_bIsSitting = false;
|
if (a_Player.GetEquippedItem().m_ItemType == E_ITEM_DYE)
|
||||||
|
{
|
||||||
|
m_CollarColor = 15 - a_Player.GetEquippedItem().m_ItemDamage;
|
||||||
|
if (!a_Player.IsGameModeCreative())
|
||||||
|
{
|
||||||
|
a_Player.GetInventory().RemoveOneEquippedItem();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (IsSitting())
|
||||||
|
{
|
||||||
|
SetIsSitting(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_bIsSitting = true;
|
SetIsSitting(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,3 +91,92 @@ void cWolf::OnRightClicked(cPlayer & a_Player)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cWolf::Tick(float a_Dt, cChunk & a_Chunk)
|
||||||
|
{
|
||||||
|
if (!IsAngry())
|
||||||
|
{
|
||||||
|
cMonster::Tick(a_Dt, a_Chunk);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
super::Tick(a_Dt, a_Chunk);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsSitting())
|
||||||
|
{
|
||||||
|
m_bMovingToDestination = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
cPlayer * a_Closest_Player = FindClosestPlayer();
|
||||||
|
if (a_Closest_Player != NULL)
|
||||||
|
{
|
||||||
|
switch (a_Closest_Player->GetEquippedItem().m_ItemType)
|
||||||
|
{
|
||||||
|
case E_ITEM_BONE:
|
||||||
|
case E_ITEM_RAW_BEEF:
|
||||||
|
case E_ITEM_STEAK:
|
||||||
|
case E_ITEM_RAW_CHICKEN:
|
||||||
|
case E_ITEM_COOKED_CHICKEN:
|
||||||
|
case E_ITEM_ROTTEN_FLESH:
|
||||||
|
{
|
||||||
|
if (!IsBegging())
|
||||||
|
{
|
||||||
|
SetIsBegging(true);
|
||||||
|
m_World->BroadcastEntityMetadata(*this);
|
||||||
|
}
|
||||||
|
Vector3f a_NewDestination = a_Closest_Player->GetPosition();
|
||||||
|
a_NewDestination.y = a_NewDestination.y + 1; // Look at the head of the player, not his feet.
|
||||||
|
m_Destination = Vector3f(a_NewDestination);
|
||||||
|
m_bMovingToDestination = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
if (IsBegging())
|
||||||
|
{
|
||||||
|
SetIsBegging(false);
|
||||||
|
m_World->BroadcastEntityMetadata(*this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class cCallback :
|
||||||
|
public cPlayerListCallback
|
||||||
|
{
|
||||||
|
virtual bool Item(cPlayer * Player) override
|
||||||
|
{
|
||||||
|
OwnerCoords = Player->GetPosition();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
Vector3f OwnerCoords;
|
||||||
|
} Callback;
|
||||||
|
m_World->DoWithPlayer(m_Owner, Callback);
|
||||||
|
Vector3f OwnerCoords = Callback.OwnerCoords;
|
||||||
|
|
||||||
|
if (IsTame())
|
||||||
|
{
|
||||||
|
if (m_Owner != "")
|
||||||
|
{
|
||||||
|
double Distance = (OwnerCoords - GetPosition()).Length();
|
||||||
|
if (Distance < 3)
|
||||||
|
{
|
||||||
|
m_bMovingToDestination = false;
|
||||||
|
}
|
||||||
|
else if ((Distance > 30) && (!IsSitting()))
|
||||||
|
{
|
||||||
|
TeleportToCoords(OwnerCoords.x, OwnerCoords.y, OwnerCoords.z);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_Destination = OwnerCoords;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "PassiveAggressiveMonster.h"
|
#include "PassiveAggressiveMonster.h"
|
||||||
|
#include "../Entities/Entity.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -19,19 +20,32 @@ public:
|
|||||||
|
|
||||||
virtual void DoTakeDamage(TakeDamageInfo & a_TDI) override;
|
virtual void DoTakeDamage(TakeDamageInfo & a_TDI) override;
|
||||||
virtual void OnRightClicked(cPlayer & a_Player) override;
|
virtual void OnRightClicked(cPlayer & a_Player) override;
|
||||||
|
virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
|
||||||
|
|
||||||
bool IsSitting(void) const { return m_bIsSitting; }
|
// Get functions
|
||||||
bool IsTame(void) const { return m_bIsTame; }
|
bool IsSitting (void) const { return m_IsSitting; }
|
||||||
bool IsBegging(void) const { return m_bIsBegging; }
|
bool IsTame (void) const { return m_IsTame; }
|
||||||
bool IsAngry(void) const { return m_bIsAngry; }
|
bool IsBegging (void) const { return m_IsBegging; }
|
||||||
|
bool IsAngry (void) const { return m_IsAngry; }
|
||||||
|
AString GetOwner (void) const { return m_Owner; }
|
||||||
|
int GetCollarColor(void) const { return m_CollarColor; }
|
||||||
|
|
||||||
private:
|
// Set functions
|
||||||
|
void SetIsSitting (bool a_IsSitting) { m_IsSitting = a_IsSitting; }
|
||||||
|
void SetIsTame (bool a_IsTame) { m_IsTame = a_IsTame; }
|
||||||
|
void SetIsBegging (bool a_IsBegging) { m_IsBegging = a_IsBegging; }
|
||||||
|
void SetIsAngry (bool a_IsAngry) { m_IsAngry = a_IsAngry; }
|
||||||
|
void SetOwner (AString a_NewOwner) { m_Owner = a_NewOwner; }
|
||||||
|
void SetCollarColor(int a_CollarColor) { m_CollarColor = a_CollarColor; }
|
||||||
|
|
||||||
bool m_bIsSitting;
|
protected:
|
||||||
bool m_bIsTame;
|
|
||||||
bool m_bIsBegging;
|
|
||||||
bool m_bIsAngry;
|
|
||||||
|
|
||||||
|
bool m_IsSitting;
|
||||||
|
bool m_IsTame;
|
||||||
|
bool m_IsBegging;
|
||||||
|
bool m_IsAngry;
|
||||||
|
AString m_Owner;
|
||||||
|
int m_CollarColor;
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
@ -215,7 +215,7 @@ void cProtocol172::SendDestroyEntity(const cEntity & a_Entity)
|
|||||||
void cProtocol172::SendDisconnect(const AString & a_Reason)
|
void cProtocol172::SendDisconnect(const AString & a_Reason)
|
||||||
{
|
{
|
||||||
cPacketizer Pkt(*this, 0x40);
|
cPacketizer Pkt(*this, 0x40);
|
||||||
Pkt.WriteString(a_Reason);
|
Pkt.WriteString(EscapeString(a_Reason));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -490,7 +490,7 @@ void cProtocol172::SendPlayerAbilities(void)
|
|||||||
void cProtocol172::SendPlayerAnimation(const cPlayer & a_Player, char a_Animation)
|
void cProtocol172::SendPlayerAnimation(const cPlayer & a_Player, char a_Animation)
|
||||||
{
|
{
|
||||||
cPacketizer Pkt(*this, 0x0b); // Animation packet
|
cPacketizer Pkt(*this, 0x0b); // Animation packet
|
||||||
Pkt.WriteInt(a_Player.GetUniqueID());
|
Pkt.WriteVarInt(a_Player.GetUniqueID());
|
||||||
Pkt.WriteChar(a_Animation);
|
Pkt.WriteChar(a_Animation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -503,7 +503,7 @@ void cProtocol172::SendPlayerListItem(const cPlayer & a_Player, bool a_IsOnline)
|
|||||||
cPacketizer Pkt(*this, 0x38); // Playerlist Item packet
|
cPacketizer Pkt(*this, 0x38); // Playerlist Item packet
|
||||||
Pkt.WriteString(a_Player.GetName());
|
Pkt.WriteString(a_Player.GetName());
|
||||||
Pkt.WriteBool(a_IsOnline);
|
Pkt.WriteBool(a_IsOnline);
|
||||||
Pkt.WriteShort(a_Player.GetClientHandle()->GetPing());
|
Pkt.WriteShort(a_IsOnline ? a_Player.GetClientHandle()->GetPing() : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -564,7 +564,7 @@ void cProtocol172::SendPlayerSpawn(const cPlayer & a_Player)
|
|||||||
{
|
{
|
||||||
// Called to spawn another player for the client
|
// Called to spawn another player for the client
|
||||||
cPacketizer Pkt(*this, 0x0c); // Spawn Player packet
|
cPacketizer Pkt(*this, 0x0c); // Spawn Player packet
|
||||||
Pkt.WriteInt(a_Player.GetUniqueID());
|
Pkt.WriteVarInt(a_Player.GetUniqueID());
|
||||||
Pkt.WriteString(Printf("%d", a_Player.GetUniqueID())); // TODO: Proper UUID
|
Pkt.WriteString(Printf("%d", a_Player.GetUniqueID())); // TODO: Proper UUID
|
||||||
Pkt.WriteString(a_Player.GetName());
|
Pkt.WriteString(a_Player.GetName());
|
||||||
Pkt.WriteFPInt(a_Player.GetPosX());
|
Pkt.WriteFPInt(a_Player.GetPosX());
|
||||||
@ -615,11 +615,9 @@ void cProtocol172::SendSoundParticleEffect(int a_EffectID, int a_SrcX, int a_Src
|
|||||||
{
|
{
|
||||||
cPacketizer Pkt(*this, 0x28); // Effect packet
|
cPacketizer Pkt(*this, 0x28); // Effect packet
|
||||||
Pkt.WriteInt(a_EffectID);
|
Pkt.WriteInt(a_EffectID);
|
||||||
Pkt.WriteInt(a_SrcX);
|
Pkt.WriteInt(a_SrcX / 8);
|
||||||
// TODO: Check if this is really an int
|
Pkt.WriteByte(a_SrcY / 8);
|
||||||
// wiki.vg says it's a byte, but that wouldn't cover the entire range needed (Y location * 8 = 0..2048)
|
Pkt.WriteInt(a_SrcZ / 8);
|
||||||
Pkt.WriteInt(a_SrcY);
|
|
||||||
Pkt.WriteInt(a_SrcZ);
|
|
||||||
Pkt.WriteInt(a_Data);
|
Pkt.WriteInt(a_Data);
|
||||||
Pkt.WriteBool(false);
|
Pkt.WriteBool(false);
|
||||||
}
|
}
|
||||||
@ -1754,6 +1752,8 @@ void cProtocol172::cPacketizer::WriteMobMetadata(const cMonster & a_Mob)
|
|||||||
WriteFloat((float)(a_Mob.GetHealth()));
|
WriteFloat((float)(a_Mob.GetHealth()));
|
||||||
WriteByte(0x13);
|
WriteByte(0x13);
|
||||||
WriteByte(Wolf.IsBegging() ? 1 : 0);
|
WriteByte(Wolf.IsBegging() ? 1 : 0);
|
||||||
|
WriteByte(0x14);
|
||||||
|
WriteByte(Wolf.GetCollarColor());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -547,10 +547,10 @@ bool cRoot::FindAndDoWithPlayer(const AString & a_PlayerName, cPlayerListCallbac
|
|||||||
}
|
}
|
||||||
if (Rating == NameLength) // Perfect match
|
if (Rating == NameLength) // Perfect match
|
||||||
{
|
{
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cCallback (const AString & a_PlayerName, cPlayerListCallback & a_Callback)
|
cCallback (const AString & a_PlayerName, cPlayerListCallback & a_Callback)
|
||||||
|
@ -50,16 +50,21 @@ void cSlotArea::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickA
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((a_ClickAction == caShiftLeftClick) || (a_ClickAction == caShiftRightClick))
|
switch (a_ClickAction)
|
||||||
{
|
{
|
||||||
if (!a_Player.IsDraggingItem())
|
case caShiftLeftClick:
|
||||||
|
case caShiftRightClick:
|
||||||
{
|
{
|
||||||
ShiftClicked(a_Player, a_SlotNum, a_ClickedItem);
|
ShiftClicked(a_Player, a_SlotNum, a_ClickedItem);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LOGD("Shift clicked, but the player is dragging an item: %s", ItemToFullString(a_Player.GetDraggingItem()).c_str());
|
|
||||||
|
case caDblClick:
|
||||||
|
{
|
||||||
|
DblClicked(a_Player, a_SlotNum);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cItem Slot(*GetSlot(a_SlotNum, a_Player));
|
cItem Slot(*GetSlot(a_SlotNum, a_Player));
|
||||||
if (!Slot.IsSameType(a_ClickedItem))
|
if (!Slot.IsSameType(a_ClickedItem))
|
||||||
@ -182,6 +187,36 @@ void cSlotArea::ShiftClicked(cPlayer & a_Player, int a_SlotNum, const cItem & a_
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cSlotArea::DblClicked(cPlayer & a_Player, int a_SlotNum)
|
||||||
|
{
|
||||||
|
cItem & Dragging = a_Player.GetDraggingItem();
|
||||||
|
if (Dragging.IsEmpty())
|
||||||
|
{
|
||||||
|
// Move the item in the dblclicked slot into hand:
|
||||||
|
Dragging = *GetSlot(a_SlotNum, a_Player);
|
||||||
|
cItem EmptyItem;
|
||||||
|
SetSlot(a_SlotNum, a_Player, EmptyItem);
|
||||||
|
}
|
||||||
|
if (Dragging.IsEmpty())
|
||||||
|
{
|
||||||
|
LOGD("%s DblClicked with an empty hand over empty slot, ignoring", a_Player.GetName().c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add as many items from the surrounding area into hand as possible:
|
||||||
|
// First skip full stacks, then if there's still space, process full stacks as well:
|
||||||
|
if (!m_ParentWindow.CollectItemsToHand(Dragging, *this, a_Player, false))
|
||||||
|
{
|
||||||
|
m_ParentWindow.CollectItemsToHand(Dragging, *this, a_Player, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_ParentWindow.BroadcastWholeWindow(); // We need to broadcast, in case the window was a chest opened by multiple players
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cSlotArea::DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_Apply, bool a_KeepEmptySlots)
|
void cSlotArea::DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_Apply, bool a_KeepEmptySlots)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < m_NumSlots; i++)
|
for (int i = 0; i < m_NumSlots; i++)
|
||||||
@ -220,6 +255,39 @@ void cSlotArea::DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cSlotArea::CollectItemsToHand(cItem & a_Dragging, cPlayer & a_Player, bool a_CollectFullStacks)
|
||||||
|
{
|
||||||
|
int NumSlots = GetNumSlots();
|
||||||
|
for (int i = 0; i < NumSlots; i++)
|
||||||
|
{
|
||||||
|
const cItem & SlotItem = *GetSlot(i, a_Player);
|
||||||
|
if (!SlotItem.IsStackableWith(a_Dragging))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int ToMove = a_Dragging.GetMaxStackSize() - a_Dragging.m_ItemCount;
|
||||||
|
if (ToMove > SlotItem.m_ItemCount)
|
||||||
|
{
|
||||||
|
ToMove = SlotItem.m_ItemCount;
|
||||||
|
}
|
||||||
|
a_Dragging.m_ItemCount += ToMove;
|
||||||
|
cItem NewSlot(SlotItem);
|
||||||
|
NewSlot.m_ItemCount -= ToMove;
|
||||||
|
SetSlot(i, a_Player, NewSlot);
|
||||||
|
if (!NewSlot.IsEmpty())
|
||||||
|
{
|
||||||
|
// There are leftovers in the slot, so a_Dragging must be full
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} // for i - Slots[]
|
||||||
|
// a_Dragging may be full if there were exactly the number of items needed to fill it
|
||||||
|
return a_Dragging.IsFullStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// cSlotAreaChest:
|
// cSlotAreaChest:
|
||||||
|
|
||||||
|
@ -40,9 +40,12 @@ public:
|
|||||||
/// Called when a player clicks in the window. Parameters taken from the click packet.
|
/// Called when a player clicks in the window. Parameters taken from the click packet.
|
||||||
virtual void Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem);
|
virtual void Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem);
|
||||||
|
|
||||||
/// Called from Clicked if it is a valid shiftclick
|
/// Called from Clicked when the action is a shiftclick (left or right)
|
||||||
virtual void ShiftClicked(cPlayer & a_Player, int a_SlotNum, const cItem & a_ClickedItem);
|
virtual void ShiftClicked(cPlayer & a_Player, int a_SlotNum, const cItem & a_ClickedItem);
|
||||||
|
|
||||||
|
/// Called from Clicked when the action is a caDblClick
|
||||||
|
virtual void DblClicked(cPlayer & a_Player, int a_SlotNum);
|
||||||
|
|
||||||
/// Called when a new player opens the same parent window. The window already tracks the player. CS-locked.
|
/// Called when a new player opens the same parent window. The window already tracks the player. CS-locked.
|
||||||
virtual void OnPlayerAdded(cPlayer & a_Player) {} ;
|
virtual void OnPlayerAdded(cPlayer & a_Player) {} ;
|
||||||
|
|
||||||
@ -57,6 +60,12 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual void DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots);
|
virtual void DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots);
|
||||||
|
|
||||||
|
/// Called on DblClicking to collect all stackable items into hand.
|
||||||
|
/// The items are accumulated in a_Dragging and removed from the slots immediately.
|
||||||
|
/// If a_CollectFullStacks is false, slots with full stacks are skipped while collecting.
|
||||||
|
/// Returns true if full stack has been collected in a_Dragging, false if there's space remaining to fill.
|
||||||
|
virtual bool CollectItemsToHand(cItem & a_Dragging, cPlayer & a_Player, bool a_CollectFullStacks);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int m_NumSlots;
|
int m_NumSlots;
|
||||||
cWindow & m_ParentWindow;
|
cWindow & m_ParentWindow;
|
||||||
|
@ -386,6 +386,51 @@ void cWindow::DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, cSlotArea
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cWindow::CollectItemsToHand(cItem & a_Dragging, cSlotArea & a_Area, cPlayer & a_Player, bool a_CollectFullStacks)
|
||||||
|
{
|
||||||
|
// First ask the slot areas from a_Area till the end of list:
|
||||||
|
bool ShouldCollect = false;
|
||||||
|
for (cSlotAreas::iterator itr = m_SlotAreas.begin(), end = m_SlotAreas.end(); itr != end; ++itr)
|
||||||
|
{
|
||||||
|
if (&a_Area == *itr)
|
||||||
|
{
|
||||||
|
ShouldCollect = true;
|
||||||
|
}
|
||||||
|
if (!ShouldCollect)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((*itr)->CollectItemsToHand(a_Dragging, a_Player, a_CollectFullStacks))
|
||||||
|
{
|
||||||
|
// a_Dragging is full
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// a_Dragging still not full, ask slot areas before a_Area in the list:
|
||||||
|
for (cSlotAreas::iterator itr = m_SlotAreas.begin(), end = m_SlotAreas.end(); itr != end; ++itr)
|
||||||
|
{
|
||||||
|
if (*itr == &a_Area)
|
||||||
|
{
|
||||||
|
// All areas processed
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((*itr)->CollectItemsToHand(a_Dragging, a_Player, a_CollectFullStacks))
|
||||||
|
{
|
||||||
|
// a_Dragging is full
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Shouldn't reach here
|
||||||
|
// a_Area is expected to be part of m_SlotAreas[], so the "return false" in the loop above should have returned already
|
||||||
|
ASSERT(!"This branch should not be reached");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cWindow::SendSlot(cPlayer & a_Player, cSlotArea * a_SlotArea, int a_RelativeSlotNum)
|
void cWindow::SendSlot(cPlayer & a_Player, cSlotArea * a_SlotArea, int a_RelativeSlotNum)
|
||||||
{
|
{
|
||||||
int SlotBase = 0;
|
int SlotBase = 0;
|
||||||
|
@ -156,6 +156,12 @@ public:
|
|||||||
*/
|
*/
|
||||||
void DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, cSlotArea * a_ExcludeArea, bool a_ShouldApply);
|
void DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, cSlotArea * a_ExcludeArea, bool a_ShouldApply);
|
||||||
|
|
||||||
|
/// Called on DblClicking to collect all stackable items from all areas into hand, starting with the specified area.
|
||||||
|
/// The items are accumulated in a_Dragging and removed from the SlotAreas immediately.
|
||||||
|
/// If a_CollectFullStacks is false, slots with full stacks in the area are skipped while collecting.
|
||||||
|
/// Returns true if full stack has been collected, false if there's space remaining to fill.
|
||||||
|
bool CollectItemsToHand(cItem & a_Dragging, cSlotArea & a_Area, cPlayer & a_Player, bool a_CollectFullStacks);
|
||||||
|
|
||||||
/// Used by cSlotAreas to send individual slots to clients, a_RelativeSlotNum is the slot number relative to a_SlotArea
|
/// Used by cSlotAreas to send individual slots to clients, a_RelativeSlotNum is the slot number relative to a_SlotArea
|
||||||
void SendSlot(cPlayer & a_Player, cSlotArea * a_SlotArea, int a_RelativeSlotNum);
|
void SendSlot(cPlayer & a_Player, cSlotArea * a_SlotArea, int a_RelativeSlotNum);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user