Skip to content

Fix/issue 512 item dropping action#513

Open
GabrielaGavi wants to merge 2 commits intoObsidianMC:1.21.xfrom
GabrielaGavi:fix/issue-512-item-dropping-action
Open

Fix/issue 512 item dropping action#513
GabrielaGavi wants to merge 2 commits intoObsidianMC:1.21.xfrom
GabrielaGavi:fix/issue-512-item-dropping-action

Conversation

@GabrielaGavi
Copy link

@GabrielaGavi GabrielaGavi commented Mar 12, 2026

Updated the item drop flow so it now uses the actual stack amount the player is holding, instead of relying on a fixed value in the stack-drop action. I also adjusted DropItem() to compute a safe drop amount before spawning the entity, so the dropped item and the inventory update stay in sync.

Another important change was creating the dropped entity item from a separate ItemStack instance (with the drop amount), instead of reusing the same in-inventory object reference. This avoids side effects when the inventory count is reduced right after spawning the dropped entity.

Finally, the inventory slot update packet flow remains the same, but now it reflects the corrected drop/removal behavior more consistently from the player’s point of view.

PS: I really enjoyed your project! :)

Summary by CodeRabbit

  • Bug Fixes
    • Fixed item dropping to properly validate that a player is holding an item before allowing drops. Items can no longer be dropped when the player's hand is empty.
    • Corrected the number of items dropped to match the actual held item count instead of using an incorrect fixed amount.

@coderabbitai
Copy link

coderabbitai bot commented Mar 12, 2026

Walkthrough

The PR modifies item drop handling in the PlayerActionPacket to add validation checks ensuring a held item exists before dropping and uses the actual held item count instead of a fixed value for the drop amount.

Changes

Cohort / File(s) Summary
Item Drop Validation
Obsidian/Net/Packets/Play/Serverbound/PlayerActionPacket.cs
Added guard clauses to DropItemStack and DropItem methods to validate held item existence and air status. Updated drop logic to use held item count instead of fixed 64-item drop amount.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 A rabbit hops through packets with glee,
Checking for items—what will they be?
No more drops of fixed sixty-four,
Just the true count in your paw, nothing more!
Guard clauses dancing, validation's the key,
Safe item drops, as precise as can be! 🥕✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Fix/issue 512 item dropping action' directly relates to the main change: fixing item drop behavior in the PlayerActionPacket to use the actual held item stack amount instead of a fixed value.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 01e72645ea

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

case PlayerActionStatus.DropItemStack:
{
DropItem(player, 64);
var held = player.getHeldItem();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P0 Badge Call GetHeldItem instead of nonexistent getHeldItem

This switch case now calls player.getHeldItem(), but IPlayer only exposes GetHeldItem() (Obsidian.API/_Interfaces/IPlayer.cs:131). In C#, method names are case-sensitive, so this introduces a compile-time failure in PlayerActionPacket and blocks building/running the server until corrected.

Useful? React with 👍 / 👎.

private static void DropItem(IPlayer player, sbyte amountToRemove)
{
var droppedItem = player.GetHeldItem();
var heldItem = player.GetHeldItem();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P0 Badge Keep dropped-item variable name consistent after rename

The method renames droppedItem to heldItem, but the ItemEntity initializer still uses droppedItem, leaving an unresolved identifier in this method. That creates another compile-time error in the packet handler, so the change cannot be built as committed.

Useful? React with 👍 / 👎.

if (held is null or { Type: Material.Air })
break;

DropItem(player, (sbyte)held.Count);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid sbyte overflow when dropping the full held stack

Casting held.Count (an int) to sbyte can overflow for oversized stacks, producing a negative amountToRemove; DropItem then computes a non-positive dropCount and returns without dropping anything. This is reachable because /give accepts arbitrary int amount and stores it directly (Obsidian/Commands/Modules/MainCommandModule.cs:216-231), so stacks above 127 become impossible to drop with the stack-drop action.

Useful? React with 👍 / 👎.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
Obsidian/Net/Packets/Play/Serverbound/PlayerActionPacket.cs (2)

141-141: ⚠️ Potential issue | 🟠 Major

Use dropCount instead of amountToRemove for inventory removal.

The dropCount variable (line 119) computes the safe drop amount as Math.Min(heldItem.Count, amountToRemove). However, line 141 removes amountToRemove from inventory, which could attempt to remove more items than actually dropped or available. This breaks the sync between the dropped entity and inventory update described in the PR objectives.

🐛 Proposed fix
-        player.Inventory.RemoveItem(player.CurrentHeldItemSlot, amountToRemove);
+        player.Inventory.RemoveItem(player.CurrentHeldItemSlot, (sbyte)dropCount);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Obsidian/Net/Packets/Play/Serverbound/PlayerActionPacket.cs` at line 141, The
inventory removal uses amountToRemove but should use the computed safe value
dropCount; in the PlayerActionPacket handling code replace the argument to
player.Inventory.RemoveItem (currently amountToRemove) with dropCount so the
number removed matches Math.Min(heldItem.Count, amountToRemove) and stays in
sync with the dropped entity update (refer to variables dropCount,
amountToRemove, heldItem.Count and the call player.Inventory.RemoveItem).

125-131: ⚠️ Potential issue | 🔴 Critical

Create a new ItemStack for the dropped item to avoid undefined variable and side effects.

Line 128 references undefined variable droppedItem. The held item variable is named heldItem (line 114), and dropCount is available (line 119). The dropped entity should use a new ItemStack instance with dropCount to prevent side effects when the inventory is modified.

🐛 Fix: Create a new ItemStack for the dropped entity
         var loc = new VectorF(player.Position.X, (float)player.HeadY - 0.3f, player.Position.Z);
 
+        var droppedItem = new ItemStack(heldItem.Holder, dropCount);
+
         var item = new ItemEntity
         {
             EntityId = Server.GetNextEntityId(),
             Item = droppedItem,
             World = player.World,
             Position = loc
         };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Obsidian/Net/Packets/Play/Serverbound/PlayerActionPacket.cs` around lines 125
- 131, The code creates an ItemEntity referencing an undefined/incorrect
variable and risks side effects by reusing the held item; in PlayerActionPacket
replace the undefined droppedItem with a newly constructed ItemStack using the
existing heldItem as the item type and dropCount as the quantity, then assign
that new ItemStack to ItemEntity.Item while keeping EntityId =
Server.GetNextEntityId(), World = player.World and Position = loc so the dropped
entity uses an independent stack and the inventory mutations won't affect it.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Obsidian/Net/Packets/Play/Serverbound/PlayerActionPacket.cs`:
- Line 64: The code calls player.getHeldItem() using incorrect casing which will
not match the defined method GetHeldItem(); update the call in
PlayerActionPacket (replace player.getHeldItem() with player.GetHeldItem()) so
it matches the interface/implementation, rebuild to confirm compilation, and
ensure no other incorrect-cased calls to GetHeldItem exist in the same class.

---

Outside diff comments:
In `@Obsidian/Net/Packets/Play/Serverbound/PlayerActionPacket.cs`:
- Line 141: The inventory removal uses amountToRemove but should use the
computed safe value dropCount; in the PlayerActionPacket handling code replace
the argument to player.Inventory.RemoveItem (currently amountToRemove) with
dropCount so the number removed matches Math.Min(heldItem.Count, amountToRemove)
and stays in sync with the dropped entity update (refer to variables dropCount,
amountToRemove, heldItem.Count and the call player.Inventory.RemoveItem).
- Around line 125-131: The code creates an ItemEntity referencing an
undefined/incorrect variable and risks side effects by reusing the held item; in
PlayerActionPacket replace the undefined droppedItem with a newly constructed
ItemStack using the existing heldItem as the item type and dropCount as the
quantity, then assign that new ItemStack to ItemEntity.Item while keeping
EntityId = Server.GetNextEntityId(), World = player.World and Position = loc so
the dropped entity uses an independent stack and the inventory mutations won't
affect it.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 09af9556-11c6-4ab9-9e4d-efa7cac1951a

📥 Commits

Reviewing files that changed from the base of the PR and between fffbb3f and 01e7264.

📒 Files selected for processing (1)
  • Obsidian/Net/Packets/Play/Serverbound/PlayerActionPacket.cs

case PlayerActionStatus.DropItemStack:
{
DropItem(player, 64);
var held = player.getHeldItem();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify which method name exists on IPlayer interface
rg -n 'GetHeldItem|getHeldItem' --type=cs -C2

Repository: ObsidianMC/Obsidian

Length of output: 5254


Method name casing inconsistency: getHeldItem() vs GetHeldItem().

Line 64 uses player.getHeldItem() (lowercase 'g'), but the method is defined as GetHeldItem() with uppercase 'G' in both the interface and implementation. C# is case-sensitive, so this will cause a compilation error.

Fix
-                    var held = player.getHeldItem();
+                    var held = player.GetHeldItem();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
var held = player.getHeldItem();
var held = player.GetHeldItem();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Obsidian/Net/Packets/Play/Serverbound/PlayerActionPacket.cs` at line 64, The
code calls player.getHeldItem() using incorrect casing which will not match the
defined method GetHeldItem(); update the call in PlayerActionPacket (replace
player.getHeldItem() with player.GetHeldItem()) so it matches the
interface/implementation, rebuild to confirm compilation, and ensure no other
incorrect-cased calls to GetHeldItem exist in the same class.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant