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.", CalledWhen = "A player is tossing an item. Plugin may override / refuse.",
DefaultFnName = "OnPlayerTossingItem", -- also used as pagename DefaultFnName = "OnPlayerTossingItem", -- also used as pagename
Desc = [[ 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 {{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 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> {{cInventory|inventory}} needs to be re-sent to the player.</p>
@ -18,8 +18,9 @@ return
}, },
Returns = [[ Returns = [[
If the function returns false or no value, other plugins' callbacks are called and finally MCServer 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 creates the pickup for the item and tosses it, using {{cPlayer}}:TossHeldItem, {{cPlayer}}:TossEquippedItem,
true, no other callbacks are called for this event and MCServer doesn't toss the item. 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 }, -- 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) // A plugin doesn't agree with the tossing. The plugin itself is responsible for handling the consequences (possible inventory mismatch)
return; return;
} }
m_Player->TossItem(false);
m_Player->TossEquippedItem();
return; 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) // A plugin doesn't agree with the tossing. The plugin itself is responsible for handling the consequences (possible inventory mismatch)
return; 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; return;
} }

View File

@ -1342,59 +1342,68 @@ AString cPlayer::GetColor(void) const
void cPlayer::TossItem( void cPlayer::TossEquippedItem(char a_Amount)
bool a_bDraggingItem,
char a_Amount /* = 1 */,
short a_CreateType /* = 0 */,
short a_CreateHealth /* = 0 */
)
{ {
cItems Drops; cItems Drops;
if (a_CreateType != 0) cItem DroppedItem(GetInventory().GetEquippedItem());
{ if (!DroppedItem.IsEmpty())
// Just create item without touching the inventory (used in creative mode) {
Drops.push_back(cItem(a_CreateType, a_Amount, a_CreateHealth)); char NewAmount = a_Amount;
} if (NewAmount > GetInventory().GetEquippedItem().m_ItemCount)
else {
{ NewAmount = GetInventory().GetEquippedItem().m_ItemCount; // Drop only what's there
// 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
}
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; double vX = 0, vY = 0, vZ = 0;
EulerToVector(-GetYaw(), GetPitch(), vZ, vX, vY); EulerToVector(-GetYaw(), GetPitch(), vZ, vX, vY);
vY = -vY * 2 + 1.f; 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 /// Returns the full color code to use for this player, based on their primary group or set in m_Color
AString GetColor(void) const; 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 /// Heals the player by the specified amount of HPs (positive only); sends health update
void Heal(int a_Health); void Heal(int a_Health);

View File

@ -13,7 +13,8 @@
#include "../BlockEntities/DropSpenserEntity.h" #include "../BlockEntities/DropSpenserEntity.h"
#include "../BlockEntities/EnderChestEntity.h" #include "../BlockEntities/EnderChestEntity.h"
#include "../BlockEntities/HopperEntity.h" #include "../BlockEntities/HopperEntity.h"
#include "../Root.h"
#include "../Bindings/PluginManager.h"
@ -169,6 +170,8 @@ void cWindow::Clicked(
const cItem & a_ClickedItem const cItem & a_ClickedItem
) )
{ {
cPluginManager * PlgMgr = cRoot::Get()->GetPluginManager();
if (a_WindowID != m_WindowID) 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()); 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: 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: // Toss one of the dragged items:
a_Player.TossItem(true); a_Player.TossHeldItem();
return; return;
} }
case caLeftClickOutside: 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: // Toss all dragged items:
a_Player.TossItem(true, a_Player.GetDraggingItem().m_ItemCount); a_Player.TossHeldItem(a_Player.GetDraggingItem().m_ItemCount);
return; return;
} }
case caLeftClickOutsideHoldNothing: case caLeftClickOutsideHoldNothing:
@ -259,11 +284,13 @@ void cWindow::OpenedByPlayer(cPlayer & a_Player)
bool cWindow::ClosedByPlayer(cPlayer & a_Player, bool a_CanRefuse) bool cWindow::ClosedByPlayer(cPlayer & a_Player, bool a_CanRefuse)
{ {
cPluginManager * PlgMgr = cRoot::Get()->GetPluginManager();
// Checks whether the player is still holding an item // Checks whether the player is still holding an item
if (a_Player.IsDraggingItem()) if (a_Player.IsDraggingItem())
{ {
LOGD("Player holds item! Dropping it..."); LOGD("Player holds item! Dropping it...");
a_Player.TossItem(true, a_Player.GetDraggingItem().m_ItemCount); a_Player.TossHeldItem(a_Player.GetDraggingItem().m_ItemCount);
} }
cClientHandle * ClientHandle = a_Player.GetClientHandle(); cClientHandle * ClientHandle = a_Player.GetClientHandle();