Skip to content

Commit

Permalink
Allow spell circles to access player inventory (#734)
Browse files Browse the repository at this point in the history
  • Loading branch information
SamsTheNerd authored Nov 12, 2024
2 parents a23088e + 74621d3 commit 8b3e267
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 95 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.phys.Vec3;
Expand Down Expand Up @@ -360,11 +361,88 @@ public InteractionHand getOtherHand() {
*/
protected abstract List<ItemStack> getUsableStacks(StackDiscoveryMode mode);

protected List<ItemStack> getUsableStacksForPlayer(StackDiscoveryMode mode, @Nullable InteractionHand castingHand, ServerPlayer caster) {
return switch (mode) {
case QUERY -> {
var out = new ArrayList<ItemStack>();

if (castingHand == null) {
var mainhand = caster.getItemInHand(InteractionHand.MAIN_HAND);
if (!mainhand.isEmpty()) {
out.add(mainhand);
}

var offhand = caster.getItemInHand(InteractionHand.OFF_HAND);
if (!offhand.isEmpty()) {
out.add(offhand);
}
} else {
var offhand = caster.getItemInHand(HexUtils.otherHand(castingHand));
if (!offhand.isEmpty()) {
out.add(offhand);
}
}

// If we're casting from the main hand, try to pick from the slot one to the right of the selected slot
// Otherwise, scan the hotbar left to right
var anchorSlot = castingHand != InteractionHand.OFF_HAND
? (caster.getInventory().selected + 1) % 9
: 0;


for (int delta = 0; delta < 9; delta++) {
var slot = (anchorSlot + delta) % 9;
out.add(caster.getInventory().getItem(slot));
}

yield out;
}
case EXTRACTION -> {
// https://wiki.vg/Inventory is WRONG
// slots 0-8 are the hotbar
// for what purpose i cannot imagine
// http://redditpublic.com/images/b/b2/Items_slot_number.png looks right
// and offhand is 150 Inventory.java:464
var out = new ArrayList<ItemStack>();

// First, the inventory backwards
// We use inv.items here to get the main inventory, but not offhand or armor
Inventory inv = caster.getInventory();
for (int i = inv.items.size() - 1; i >= 0; i--) {
if (i != inv.selected) {
out.add(inv.items.get(i));
}
}

// then the offhand, then the selected hand
out.addAll(inv.offhand);
out.add(inv.getSelected());

yield out;
}
};
}

/**
* Get the primary/secondary item stacks this env can use (i.e. main hand and offhand for the player).
*/
protected abstract List<HeldItemInfo> getPrimaryStacks();

protected List<HeldItemInfo> getPrimaryStacksForPlayer(InteractionHand castingHand, ServerPlayer caster) {
var primaryItem = caster.getItemInHand(castingHand);

if (primaryItem.isEmpty())
primaryItem = ItemStack.EMPTY.copy();

var secondaryItem = caster.getItemInHand(HexUtils.otherHand(castingHand));

if (secondaryItem.isEmpty())
secondaryItem = ItemStack.EMPTY.copy();

return List.of(new HeldItemInfo(secondaryItem, HexUtils.otherHand(castingHand)), new HeldItemInfo(primaryItem,
castingHand));
}

/**
* Return the slot from which to take blocks and items.
*/
Expand Down Expand Up @@ -463,6 +541,38 @@ public boolean withdrawItem(Predicate<ItemStack> stackOk, int count, boolean act
*/
public abstract boolean replaceItem(Predicate<ItemStack> stackOk, ItemStack replaceWith, @Nullable InteractionHand hand);


public boolean replaceItemForPlayer(Predicate<ItemStack> stackOk, ItemStack replaceWith, @Nullable InteractionHand hand, ServerPlayer caster) {
if (caster == null)
return false;

if (hand != null && stackOk.test(caster.getItemInHand(hand))) {
caster.setItemInHand(hand, replaceWith);
return true;
}

Inventory inv = caster.getInventory();
for (int i = inv.items.size() - 1; i >= 0; i--) {
if (i != inv.selected) {
if (stackOk.test(inv.items.get(i))) {
inv.setItem(i, replaceWith);
return true;
}
}
}

if (stackOk.test(caster.getItemInHand(getOtherHand()))) {
caster.setItemInHand(getOtherHand(), replaceWith);
return true;
}
if (stackOk.test(caster.getItemInHand(getCastingHand()))) {
caster.setItemInHand(getCastingHand(), replaceWith);
return true;
}

return false;
}

/**
* The order/mode stacks should be discovered in
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,18 +166,27 @@ public InteractionHand getCastingHand() {
}

@Override
// TODO: Could do something like get items in inventories adjacent to the circle?
protected List<ItemStack> getUsableStacks(StackDiscoveryMode mode) {
return new ArrayList<>(); // TODO: Could do something like get items in inventories adjacent to the circle?
if (this.getCaster() != null)
return getUsableStacksForPlayer(mode, null, this.getCaster());
return new ArrayList<>();
}

@Override
// TODO: Adjacent inv!
protected List<HeldItemInfo> getPrimaryStacks() {
return List.of(); // TODO: Adjacent inv!
if (this.getCaster() != null)
return getPrimaryStacksForPlayer(InteractionHand.OFF_HAND, this.getCaster());
return List.of();
}

@Override
// TODO: Adjacent inv!
public boolean replaceItem(Predicate<ItemStack> stackOk, ItemStack replaceWith, @Nullable InteractionHand hand) {
return false; // TODO: Adjacent inv!
if (this.getCaster() != null)
return replaceItemForPlayer(stackOk, replaceWith, hand, this.getCaster());
return false;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,106 +70,17 @@ public void postExecution(CastResult result) {

@Override
protected List<ItemStack> getUsableStacks(StackDiscoveryMode mode) {
return switch (mode) {
case QUERY -> {
var out = new ArrayList<ItemStack>();

var offhand = this.caster.getItemInHand(HexUtils.otherHand(this.castingHand));
if (!offhand.isEmpty()) {
out.add(offhand);
}

// If we're casting from the main hand, try to pick from the slot one to the right of the selected slot
// Otherwise, scan the hotbar left to right
var anchorSlot = this.castingHand == InteractionHand.MAIN_HAND
? (this.caster.getInventory().selected + 1) % 9
: 0;


for (int delta = 0; delta < 9; delta++) {
var slot = (anchorSlot + delta) % 9;
out.add(this.caster.getInventory().getItem(slot));
}

yield out;
}
case EXTRACTION -> {
// https://wiki.vg/Inventory is WRONG
// slots 0-8 are the hotbar
// for what purpose i cannot imagine
// http://redditpublic.com/images/b/b2/Items_slot_number.png looks right
// and offhand is 150 Inventory.java:464
var out = new ArrayList<ItemStack>();

// First, the inventory backwards
// We use inv.items here to get the main inventory, but not offhand or armor
Inventory inv = this.caster.getInventory();
for (int i = inv.items.size() - 1; i >= 0; i--) {
if (i != inv.selected) {
out.add(inv.items.get(i));
}
}

// then the offhand, then the selected hand
out.addAll(inv.offhand);
out.add(inv.getSelected());

yield out;
}
};
return getUsableStacksForPlayer(mode, castingHand, caster);
}

@Override
protected List<HeldItemInfo> getPrimaryStacks() {
var primaryItem = this.caster.getItemInHand(this.castingHand);

if (primaryItem.isEmpty())
primaryItem = ItemStack.EMPTY.copy();

return List.of(new HeldItemInfo(getAlternateItem(), this.getOtherHand()), new HeldItemInfo(primaryItem,
this.castingHand));
}

ItemStack getAlternateItem() {
var otherHand = HexUtils.otherHand(this.castingHand);
var stack = this.caster.getItemInHand(otherHand);
if (stack.isEmpty()) {
return ItemStack.EMPTY.copy();
} else {
return stack;
}
return getPrimaryStacksForPlayer(this.castingHand, this.caster);
}

@Override
public boolean replaceItem(Predicate<ItemStack> stackOk, ItemStack replaceWith, @Nullable InteractionHand hand) {
if (caster == null)
return false;

if (hand != null && stackOk.test(caster.getItemInHand(hand))) {
caster.setItemInHand(hand, replaceWith);
return true;
}

Inventory inv = this.caster.getInventory();
for (int i = inv.items.size() - 1; i >= 0; i--) {
if (i != inv.selected) {
if (stackOk.test(inv.items.get(i))) {
inv.setItem(i, replaceWith);
return true;
}
}
}

if (stackOk.test(caster.getItemInHand(getOtherHand()))) {
caster.setItemInHand(getOtherHand(), replaceWith);
return true;
}
if (stackOk.test(caster.getItemInHand(getCastingHand()))) {
caster.setItemInHand(getCastingHand(), replaceWith);
return true;
}

return false;
return replaceItemForPlayer(stackOk, replaceWith, hand, this.caster);
}

@Override
Expand Down

0 comments on commit 8b3e267

Please sign in to comment.