-
Notifications
You must be signed in to change notification settings - Fork 83
Roll-max multiple item fix #495
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -43,34 +43,58 @@ public ItemCommand(GameSession session, ItemMetadataStorage itemStorage) : base( | |||||||||||||||||||||||||||||||||||
| private void Handle(InvocationContext ctx, int itemId, int amount, int rarity, bool drop, bool rollMax) { | ||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||
| rarity = Math.Clamp(rarity, 1, MAX_RARITY); | ||||||||||||||||||||||||||||||||||||
| Item? item = session.Field.ItemDrop.CreateItem(itemId, rarity, rollMax: rollMax); | ||||||||||||||||||||||||||||||||||||
| if (item == null) { | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| Item? firstItem = session.Field.ItemDrop.CreateItem(itemId, rarity, rollMax: rollMax); | ||||||||||||||||||||||||||||||||||||
| if (firstItem == null) { | ||||||||||||||||||||||||||||||||||||
| ctx.Console.Error.WriteLine($"Invalid Item: {itemId}"); | ||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| if (!item.IsCurrency()) { | ||||||||||||||||||||||||||||||||||||
| if (item.Metadata.Property.SlotMax == 0) { | ||||||||||||||||||||||||||||||||||||
| ctx.Console.Error.WriteLine($"{itemId} has SlotMax of 0, ignoring..."); | ||||||||||||||||||||||||||||||||||||
| amount = Math.Clamp(amount, 1, int.MaxValue); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| item.Amount = amount; | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| if (drop && session.Field != null) { | ||||||||||||||||||||||||||||||||||||
| FieldItem fieldItem = session.Field.SpawnItem(session.Player, item); | ||||||||||||||||||||||||||||||||||||
| session.Field.Broadcast(FieldPacket.DropItem(fieldItem)); | ||||||||||||||||||||||||||||||||||||
| } else if (!session.Item.Inventory.Add(item, true)) { | ||||||||||||||||||||||||||||||||||||
| session.Item.Inventory.Discard(item); | ||||||||||||||||||||||||||||||||||||
| ctx.Console.Error.WriteLine($"Failed to add item:{item.Id} to inventory"); | ||||||||||||||||||||||||||||||||||||
| ctx.ExitCode = 1; | ||||||||||||||||||||||||||||||||||||
| if (firstItem.IsCurrency()) { | ||||||||||||||||||||||||||||||||||||
| firstItem.Amount = amount; | ||||||||||||||||||||||||||||||||||||
| ProcessSingleItem(ctx, firstItem, drop); | ||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||
|
Comment on lines
+53
to
56
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Validate
-if (firstItem.IsCurrency()) {
- firstItem.Amount = amount;
+if (firstItem.IsCurrency()) {
+ if (amount <= 0) {
+ ctx.Console.Error.WriteLine("Amount must be positive.");
+ ctx.ExitCode = 1;
+ return;
+ }
+ firstItem.Amount = amount;🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| bool isNonStackable = firstItem.Metadata.Property.SlotMax == 0; | ||||||||||||||||||||||||||||||||||||
| if (isNonStackable) { | ||||||||||||||||||||||||||||||||||||
| ctx.Console.Error.WriteLine($"{itemId} has SlotMax of 0, ignoring..."); | ||||||||||||||||||||||||||||||||||||
| amount = Math.Clamp(amount, 1, int.MaxValue); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| // For non-stackable items or when rollMax is enabled, create individual items | ||||||||||||||||||||||||||||||||||||
| if (isNonStackable || (rollMax && amount > 1)) { | ||||||||||||||||||||||||||||||||||||
| ProcessSingleItem(ctx, firstItem, drop); | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| for (int i = 1; i < amount; i++) { | ||||||||||||||||||||||||||||||||||||
| Item? additionalItem = session.Field.ItemDrop.CreateItem(itemId, rarity, rollMax: rollMax); | ||||||||||||||||||||||||||||||||||||
| if (additionalItem == null) { | ||||||||||||||||||||||||||||||||||||
| ctx.Console.Error.WriteLine($"Failed to create additional item {i + 1}/{amount}"); | ||||||||||||||||||||||||||||||||||||
| continue; | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| ProcessSingleItem(ctx, additionalItem, drop); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||
|
Comment on lines
+66
to
+78
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Error propagation from When - ctx.ExitCode = 0;
+ // Preserve a non-zero exit code set by ProcessSingleItem
+ if (ctx.ExitCode == 0)
+ ctx.ExitCode = 0; // success only if no previous failureOr simply delete line 83 and rely on the default exit code (0) unless an error was signalled.
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||
| firstItem.Amount = amount; | ||||||||||||||||||||||||||||||||||||
| ProcessSingleItem(ctx, firstItem, drop); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| ctx.ExitCode = 0; | ||||||||||||||||||||||||||||||||||||
| } catch (SystemException ex) { | ||||||||||||||||||||||||||||||||||||
| ctx.Console.Error.WriteLine(ex.Message); | ||||||||||||||||||||||||||||||||||||
| ctx.ExitCode = 1; | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| private void ProcessSingleItem(InvocationContext ctx, Item item, bool drop) { | ||||||||||||||||||||||||||||||||||||
| if (drop && session.Field != null) { | ||||||||||||||||||||||||||||||||||||
| FieldItem fieldItem = session.Field.SpawnItem(session.Player, item); | ||||||||||||||||||||||||||||||||||||
| session.Field.Broadcast(FieldPacket.DropItem(fieldItem)); | ||||||||||||||||||||||||||||||||||||
| } else if (!session.Item.Inventory.Add(item, true)) { | ||||||||||||||||||||||||||||||||||||
| session.Item.Inventory.Discard(item); | ||||||||||||||||||||||||||||||||||||
| ctx.Console.Error.WriteLine($"Failed to add item:{item.Id} to inventory"); | ||||||||||||||||||||||||||||||||||||
| ctx.ExitCode = 1; | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
Comment on lines
+91
to
+98
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Early-exit after inventory failure to prevent partial success confusion. If adding to inventory fails, the command keeps processing subsequent items, producing a mix of success & failure with a single exit code. - session.Item.Inventory.Discard(item);
- ctx.Console.Error.WriteLine($"Failed to add item:{item.Id} to inventory");
- ctx.ExitCode = 1;
+ session.Item.Inventory.Discard(item);
+ ctx.Console.Error.WriteLine($"Failed to add item:{item.Id} to inventory");
+ ctx.ExitCode = 1;
+ return; // stop further processing📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possible
NullReferenceExceptionwhensession.Fieldis null.session.Field.ItemDrop.CreateItem(...)dereferencessession.Fieldunconditionally.While the command is usually executed in-field, a GM can trigger it from a lobby / loading screen, making
session.Fieldnull and crashing the server.📝 Committable suggestion
🤖 Prompt for AI Agents