1
0

Split TossItem into three Toss functions (Held, Equipped and Pickup)

This commit is contained in:
Mike Hunsinger 2014-01-23 00:27:39 -07:00
parent 9c93ab15ab
commit 41b05416c7
5 changed files with 105 additions and 60 deletions

View File

@ -5,7 +5,7 @@ return
CalledWhen = "A player is tossing an item. Plugin may override / refuse.",
DefaultFnName = "OnPlayerTossingItem", -- also used as pagename
Desc = [[
This hook is called when a {{cPlayer|player}} has tossed an item (Q keypress). The
This hook is called when a {{cPlayer|player}} has tossed an item. The
{{cPickup|pickup}} has not been spawned yet. Plugins may disallow the tossing, but in that case they
need to clean up - the player's client already thinks the item has been tossed so the
{{cInventory|inventory}} needs to be re-sent to the player.</p>
@ -18,8 +18,9 @@ return
},
Returns = [[
If the function returns false or no value, other plugins' callbacks are called and finally MCServer
creates the pickup for the item and tosses it, using {{cPlayer}}:TossItem. If the function returns
true, no other callbacks are called for this event and MCServer doesn't toss the item.
creates the pickup for the item and tosses it, using {{cPlayer}}:TossHeldItem, {{cPlayer}}:TossEquippedItem,
or {{cPlayer}}:TossPickup. If the function returns true, no other callbacks are called for this event
and MCServer doesn't toss the item.
]],
}, -- HOOK_PLAYER_TOSSING_ITEM
}

View File

@ -658,7 +658,8 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, ch
// 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);
m_Player->TossEquippedItem();
return;
}
@ -713,7 +714,7 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, ch
// 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
m_Player->TossEquippedItem(64); // Toss entire slot - if there aren't enough items, the maximum will be ejected
return;
}

View File

@ -1342,59 +1342,68 @@ AString cPlayer::GetColor(void) const
void cPlayer::TossItem(
bool a_bDraggingItem,
char a_Amount /* = 1 */,
short a_CreateType /* = 0 */,
short a_CreateHealth /* = 0 */
)
void cPlayer::TossEquippedItem(char a_Amount)
{
cItems Drops;
if (a_CreateType != 0)
{
// Just create item without touching the inventory (used in creative mode)
Drops.push_back(cItem(a_CreateType, a_Amount, a_CreateHealth));
}
else
{
// Drop an item from the inventory:
if (a_bDraggingItem)
{
cItem & Item = GetDraggingItem();
if (!Item.IsEmpty())
{
char OriginalItemAmount = Item.m_ItemCount;
Item.m_ItemCount = std::min(OriginalItemAmount, a_Amount);
Drops.push_back(Item);
if (OriginalItemAmount > a_Amount)
{
Item.m_ItemCount = OriginalItemAmount - (char)a_Amount;
}
else
{
Item.Empty();
}
}
}
else
{
// Else drop equipped item
cItem DroppedItem(GetInventory().GetEquippedItem());
if (!DroppedItem.IsEmpty())
{
char NewAmount = a_Amount;
if (NewAmount > GetInventory().GetEquippedItem().m_ItemCount)
{
NewAmount = GetInventory().GetEquippedItem().m_ItemCount; // Drop only what's there
}
cItem DroppedItem(GetInventory().GetEquippedItem());
if (!DroppedItem.IsEmpty())
{
char NewAmount = a_Amount;
if (NewAmount > GetInventory().GetEquippedItem().m_ItemCount)
{
NewAmount = GetInventory().GetEquippedItem().m_ItemCount; // Drop only what's there
}
GetInventory().GetHotbarGrid().ChangeSlotCount(GetInventory().GetEquippedSlotNum() /* Returns hotbar subslot, which HotbarGrid takes */, -a_Amount);
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;
EulerToVector(-GetYaw(), GetPitch(), vZ, vX, vY);
vY = -vY * 2 + 1.f;
m_World->SpawnItemPickups(Drops, GetPosX(), GetEyeHeight(), GetPosZ(), vX * 3, vY * 3, vZ * 3, true); // 'true' because created by player
}
void cPlayer::TossHeldItem(char a_Amount)
{
cItems Drops;
cItem & Item = GetDraggingItem();
if (!Item.IsEmpty())
{
char OriginalItemAmount = Item.m_ItemCount;
Item.m_ItemCount = std::min(OriginalItemAmount, a_Amount);
Drops.push_back(Item);
if (OriginalItemAmount > a_Amount)
{
Item.m_ItemCount = OriginalItemAmount - a_Amount;
}
else
{
Item.Empty();
}
}
double vX = 0, vY = 0, vZ = 0;
EulerToVector(-GetYaw(), GetPitch(), vZ, vX, vY);
vY = -vY * 2 + 1.f;
m_World->SpawnItemPickups(Drops, GetPosX(), GetEyeHeight(), GetPosZ(), vX * 3, vY * 3, vZ * 3, true); // 'true' because created by player
}
void cPlayer::TossPickup(const cItem & a_Item)
{
cItems Drops;
Drops.push_back(a_Item);
DroppedItem.m_ItemCount = NewAmount;
Drops.push_back(DroppedItem);
}
}
}
double vX = 0, vY = 0, vZ = 0;
EulerToVector(-GetYaw(), GetPitch(), vZ, vX, vY);
vY = -vY * 2 + 1.f;

View File

@ -214,7 +214,14 @@ public:
/// Returns the full color code to use for this player, based on their primary group or set in m_Color
AString GetColor(void) const;
void TossItem(bool a_bDraggingItem, char a_Amount = 1, short a_CreateType = 0, short a_CreateHealth = 0);
// tosses the item in the selected hotbar slot
void TossEquippedItem(char a_Amount = 1);
// tosses the item held in hand (when in UI windows)
void TossHeldItem(char a_Amount = 1);
// tosses a pickup newly created from a_Item
void TossPickup(const cItem & a_Item);
/// Heals the player by the specified amount of HPs (positive only); sends health update
void Heal(int a_Health);

View File

@ -13,7 +13,8 @@
#include "../BlockEntities/DropSpenserEntity.h"
#include "../BlockEntities/EnderChestEntity.h"
#include "../BlockEntities/HopperEntity.h"
#include "../Root.h"
#include "../Bindings/PluginManager.h"
@ -169,6 +170,8 @@ void cWindow::Clicked(
const cItem & a_ClickedItem
)
{
cPluginManager * PlgMgr = cRoot::Get()->GetPluginManager();
if (a_WindowID != m_WindowID)
{
LOGWARNING("%s: Wrong window ID (exp %d, got %d) received from \"%s\"; ignoring click.", __FUNCTION__, m_WindowID, a_WindowID, a_Player.GetName().c_str());
@ -179,14 +182,36 @@ void cWindow::Clicked(
{
case caRightClickOutside:
{
if (PlgMgr->CallHookPlayerTossingItem(a_Player))
{
// A plugin doesn't agree with the tossing. The plugin itself is responsible for handling the consequences (possible inventory mismatch)
return;
}
if (a_Player.IsGameModeCreative())
{
a_Player.TossPickup(a_ClickedItem);
}
// Toss one of the dragged items:
a_Player.TossItem(true);
a_Player.TossHeldItem();
return;
}
case caLeftClickOutside:
{
if (PlgMgr->CallHookPlayerTossingItem(a_Player))
{
// A plugin doesn't agree with the tossing. The plugin itself is responsible for handling the consequences (possible inventory mismatch)
return;
}
if (a_Player.IsGameModeCreative())
{
a_Player.TossPickup(a_ClickedItem);
}
// Toss all dragged items:
a_Player.TossItem(true, a_Player.GetDraggingItem().m_ItemCount);
a_Player.TossHeldItem(a_Player.GetDraggingItem().m_ItemCount);
return;
}
case caLeftClickOutsideHoldNothing:
@ -259,11 +284,13 @@ void cWindow::OpenedByPlayer(cPlayer & a_Player)
bool cWindow::ClosedByPlayer(cPlayer & a_Player, bool a_CanRefuse)
{
cPluginManager * PlgMgr = cRoot::Get()->GetPluginManager();
// Checks whether the player is still holding an item
if (a_Player.IsDraggingItem())
{
LOGD("Player holds item! Dropping it...");
a_Player.TossItem(true, a_Player.GetDraggingItem().m_ItemCount);
LOGD("Player holds item! Dropping it...");
a_Player.TossHeldItem(a_Player.GetDraggingItem().m_ItemCount);
}
cClientHandle * ClientHandle = a_Player.GetClientHandle();