|
19 | 19 | import net.minecraft.world.InteractionHand; |
20 | 20 | import net.minecraft.world.entity.Entity; |
21 | 21 | import net.minecraft.world.entity.LivingEntity; |
| 22 | +import net.minecraft.world.entity.player.Inventory; |
22 | 23 | import net.minecraft.world.entity.player.Player; |
23 | 24 | import net.minecraft.world.item.ItemStack; |
24 | 25 | import net.minecraft.world.phys.Vec3; |
@@ -360,11 +361,88 @@ public InteractionHand getOtherHand() { |
360 | 361 | */ |
361 | 362 | protected abstract List<ItemStack> getUsableStacks(StackDiscoveryMode mode); |
362 | 363 |
|
| 364 | + protected List<ItemStack> getUsableStacksForPlayer(StackDiscoveryMode mode, @Nullable InteractionHand castingHand, ServerPlayer caster) { |
| 365 | + return switch (mode) { |
| 366 | + case QUERY -> { |
| 367 | + var out = new ArrayList<ItemStack>(); |
| 368 | + |
| 369 | + if (castingHand == null) { |
| 370 | + var mainhand = caster.getItemInHand(InteractionHand.MAIN_HAND); |
| 371 | + if (!mainhand.isEmpty()) { |
| 372 | + out.add(mainhand); |
| 373 | + } |
| 374 | + |
| 375 | + var offhand = caster.getItemInHand(InteractionHand.OFF_HAND); |
| 376 | + if (!offhand.isEmpty()) { |
| 377 | + out.add(offhand); |
| 378 | + } |
| 379 | + } else { |
| 380 | + var offhand = caster.getItemInHand(HexUtils.otherHand(castingHand)); |
| 381 | + if (!offhand.isEmpty()) { |
| 382 | + out.add(offhand); |
| 383 | + } |
| 384 | + } |
| 385 | + |
| 386 | + // If we're casting from the main hand, try to pick from the slot one to the right of the selected slot |
| 387 | + // Otherwise, scan the hotbar left to right |
| 388 | + var anchorSlot = castingHand != InteractionHand.OFF_HAND |
| 389 | + ? (caster.getInventory().selected + 1) % 9 |
| 390 | + : 0; |
| 391 | + |
| 392 | + |
| 393 | + for (int delta = 0; delta < 9; delta++) { |
| 394 | + var slot = (anchorSlot + delta) % 9; |
| 395 | + out.add(caster.getInventory().getItem(slot)); |
| 396 | + } |
| 397 | + |
| 398 | + yield out; |
| 399 | + } |
| 400 | + case EXTRACTION -> { |
| 401 | + // https://wiki.vg/Inventory is WRONG |
| 402 | + // slots 0-8 are the hotbar |
| 403 | + // for what purpose i cannot imagine |
| 404 | + // http://redditpublic.com/images/b/b2/Items_slot_number.png looks right |
| 405 | + // and offhand is 150 Inventory.java:464 |
| 406 | + var out = new ArrayList<ItemStack>(); |
| 407 | + |
| 408 | + // First, the inventory backwards |
| 409 | + // We use inv.items here to get the main inventory, but not offhand or armor |
| 410 | + Inventory inv = caster.getInventory(); |
| 411 | + for (int i = inv.items.size() - 1; i >= 0; i--) { |
| 412 | + if (i != inv.selected) { |
| 413 | + out.add(inv.items.get(i)); |
| 414 | + } |
| 415 | + } |
| 416 | + |
| 417 | + // then the offhand, then the selected hand |
| 418 | + out.addAll(inv.offhand); |
| 419 | + out.add(inv.getSelected()); |
| 420 | + |
| 421 | + yield out; |
| 422 | + } |
| 423 | + }; |
| 424 | + } |
| 425 | + |
363 | 426 | /** |
364 | 427 | * Get the primary/secondary item stacks this env can use (i.e. main hand and offhand for the player). |
365 | 428 | */ |
366 | 429 | protected abstract List<HeldItemInfo> getPrimaryStacks(); |
367 | 430 |
|
| 431 | + protected List<HeldItemInfo> getPrimaryStacksForPlayer(InteractionHand castingHand, ServerPlayer caster) { |
| 432 | + var primaryItem = caster.getItemInHand(castingHand); |
| 433 | + |
| 434 | + if (primaryItem.isEmpty()) |
| 435 | + primaryItem = ItemStack.EMPTY.copy(); |
| 436 | + |
| 437 | + var secondaryItem = caster.getItemInHand(HexUtils.otherHand(castingHand)); |
| 438 | + |
| 439 | + if (secondaryItem.isEmpty()) |
| 440 | + secondaryItem = ItemStack.EMPTY.copy(); |
| 441 | + |
| 442 | + return List.of(new HeldItemInfo(secondaryItem, HexUtils.otherHand(castingHand)), new HeldItemInfo(primaryItem, |
| 443 | + castingHand)); |
| 444 | + } |
| 445 | + |
368 | 446 | /** |
369 | 447 | * Return the slot from which to take blocks and items. |
370 | 448 | */ |
@@ -463,6 +541,38 @@ public boolean withdrawItem(Predicate<ItemStack> stackOk, int count, boolean act |
463 | 541 | */ |
464 | 542 | public abstract boolean replaceItem(Predicate<ItemStack> stackOk, ItemStack replaceWith, @Nullable InteractionHand hand); |
465 | 543 |
|
| 544 | + |
| 545 | + public boolean replaceItemForPlayer(Predicate<ItemStack> stackOk, ItemStack replaceWith, @Nullable InteractionHand hand, ServerPlayer caster) { |
| 546 | + if (caster == null) |
| 547 | + return false; |
| 548 | + |
| 549 | + if (hand != null && stackOk.test(caster.getItemInHand(hand))) { |
| 550 | + caster.setItemInHand(hand, replaceWith); |
| 551 | + return true; |
| 552 | + } |
| 553 | + |
| 554 | + Inventory inv = caster.getInventory(); |
| 555 | + for (int i = inv.items.size() - 1; i >= 0; i--) { |
| 556 | + if (i != inv.selected) { |
| 557 | + if (stackOk.test(inv.items.get(i))) { |
| 558 | + inv.setItem(i, replaceWith); |
| 559 | + return true; |
| 560 | + } |
| 561 | + } |
| 562 | + } |
| 563 | + |
| 564 | + if (stackOk.test(caster.getItemInHand(getOtherHand()))) { |
| 565 | + caster.setItemInHand(getOtherHand(), replaceWith); |
| 566 | + return true; |
| 567 | + } |
| 568 | + if (stackOk.test(caster.getItemInHand(getCastingHand()))) { |
| 569 | + caster.setItemInHand(getCastingHand(), replaceWith); |
| 570 | + return true; |
| 571 | + } |
| 572 | + |
| 573 | + return false; |
| 574 | + } |
| 575 | + |
466 | 576 | /** |
467 | 577 | * The order/mode stacks should be discovered in |
468 | 578 | */ |
|
0 commit comments