diff --git a/src/main/java/carpet/mixins/ContainerMixin.java b/src/main/java/carpet/mixins/ContainerMixin.java index ea1b83fb..22d4c174 100644 --- a/src/main/java/carpet/mixins/ContainerMixin.java +++ b/src/main/java/carpet/mixins/ContainerMixin.java @@ -5,6 +5,7 @@ import net.minecraft.container.Container; import net.minecraft.container.Slot; import net.minecraft.container.SlotActionType; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -16,10 +17,14 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.util.List; @Mixin(Container.class) -public class ContainerMixin +public abstract class ContainerMixin { @Shadow @Final public List slotList; - + + @Shadow public abstract ItemStack onSlotClick(int int_1, int int_2, SlotActionType slotActionType_1, PlayerEntity playerEntity_1); + + @Shadow public abstract void sendContentUpdates(); + @Inject( method = "onSlotClick", at = @At(value = "HEAD"), cancellable = true) private void onThrowClick( int int_1, @@ -33,47 +38,20 @@ public class ContainerMixin { ItemStack itemStack_1 = ItemStack.EMPTY; Slot slot_4 = slotList.get(int_1); - if (slot_4 != null && slot_4.canTakeItems(playerEntity_1)) + if (slot_4 != null && slot_4.hasStack() && slot_4.canTakeItems(playerEntity_1)) { if(int_1 == 0 && int_2 == 1) { - ItemStack itemStackDropAll = dropAllCrafting(playerEntity_1, int_1, slotList); - while (!itemStackDropAll.isEmpty() && ItemStack.areItemsEqual(slot_4.getStack(), itemStackDropAll)) + Item craftedItem = slot_4.getStack().getItem(); + while(slot_4.hasStack() && slot_4.getStack().getItem() == craftedItem) { - itemStack_1 = itemStackDropAll.copy(); - itemStackDropAll = dropAllCrafting(playerEntity_1, int_1, slotList); + this.onSlotClick(int_1, 0, SlotActionType.THROW, playerEntity_1); } + this.sendContentUpdates(); cir.setReturnValue(itemStack_1); cir.cancel(); } } } } - - private ItemStack dropAllCrafting(PlayerEntity playerIn, int index, List invSlotParam) - { - ItemStack itemstack = ItemStack.EMPTY; - Slot slot = invSlotParam.get(index); - if (slot != null && slot.hasStack()) - { - ItemStack itemstack1 = slot.getStack(); - itemstack = itemstack1.copy(); - if (index == 0) - { - playerIn.dropItem(itemstack, true); - itemstack1.setCount(0); - slot.onStackChanged(itemstack1, itemstack); - } - if (itemstack.getCount() == itemstack1.getCount()) - { - return ItemStack.EMPTY; - } - ItemStack itemstack2 = slot.onTakeItem(playerIn, itemstack1); - if (index == 0) - { - playerIn.dropItem(itemstack2, false); - } - } - return itemstack; - } } diff --git a/src/main/java/carpet/script/CarpetExpression.java b/src/main/java/carpet/script/CarpetExpression.java index bd4a2504..a44f7fd3 100644 --- a/src/main/java/carpet/script/CarpetExpression.java +++ b/src/main/java/carpet/script/CarpetExpression.java @@ -366,6 +366,23 @@ public class CarpetExpression * block(0,0,0) == block('bedrock') => 1 * block('hopper[facing=north]{Items:[{Slot:1b,id:"minecraft:slime_ball",Count:16b}]}') => hopper * + *

Retrieving a block with block function has also a side-effect of evaluating its current state and data. + * so if you use it later it will reflect block state and data of the block that was when block was called, rather than + * when it was used. Block values passed in various places like scan functions, etc, are not fully evaluated + * unless its properties are needed. This means that if the block at the location changes before its queried in the program + * this might result in getting the later state, which might not be desired. Consider the following example:

+ *
+     * set(10,10,10,'stone');
+     * scan(10,10,10,0,0,0, b = _);
+     * set(10,10,10,'air');
+     * print(b); // 'air', block was remembered 'lazily', and evaluated by `print`, when it was already set to air
+     *
+     * set(10,10,10,'stone');
+     * scan(10,10,10,0,0,0, b = block(_));
+     * set(10,10,10,'air');
+     * print(b); // 'stone', block was evaluated 'eagerly' but call to `block`
+     *
+     * 
*

World Manipulation

*

All the functions below can be used with block value, queried with coord triple, or 3-long list. * All pos in the functions referenced below refer to either method of passing block position

@@ -670,7 +687,10 @@ public class CarpetExpression { throw new InternalExpressionException("Block requires at least one parameter"); } - Value retval = BlockValue.fromParams(cc, lv, 0, true).block; + BlockValue retval = BlockValue.fromParams(cc, lv, 0, true).block; + // fixing block state and data + retval.getBlockState(); + retval.getData(); return (c_, t_) -> retval; }); @@ -2097,7 +2117,8 @@ public class CarpetExpression c.setVariable("_z", (c_, t_) -> new NumericValue(zFinal).bindTo("_z")); Value blockValue = BlockValue.fromCoords(((CarpetContext)c), xFinal,yFinal,zFinal).bindTo("_"); c.setVariable( "_", (cc_, t_c) -> blockValue); - if (expr.evalValue(c, Context.BOOLEAN).getBoolean()) + Value result = expr.evalValue(c, t); + if (t != Context.VOID && result.getBoolean()) { sCount += 1; } @@ -2149,7 +2170,8 @@ public class CarpetExpression c.setVariable("_z", (c_, t_) -> new NumericValue(zFinal).bindTo("_z")); Value blockValue = BlockValue.fromCoords(((CarpetContext)c), xFinal,yFinal,zFinal).bindTo("_"); c.setVariable( "_", (cc_, t_c) -> blockValue); - if (expr.evalValue(c, Context.BOOLEAN).getBoolean()) + Value result = expr.evalValue(c, t); + if (t != Context.VOID && result.getBoolean()) { sCount += 1; } diff --git a/src/main/java/carpet/script/Expression.java b/src/main/java/carpet/script/Expression.java index a0019457..14608707 100644 --- a/src/main/java/carpet/script/Expression.java +++ b/src/main/java/carpet/script/Expression.java @@ -994,8 +994,9 @@ public class Expression implements Cloneable addLazyBinaryOperator(";",precedence.get("nextop;"), true, (c, t, lv1, lv2) -> { - Value v1 = lv1.evalValue(c, Context.VOID); - return lv2; + lv1.evalValue(c, Context.VOID); + Value v2 = lv2.evalValue(c, t); + return (cc, tt) -> v2; }); //assigns const procedure to the lhs, returning its previous value @@ -1053,13 +1054,13 @@ public class Expression implements Cloneable if (lv.get(i).evalValue(c, Context.BOOLEAN).getBoolean()) { //int iFinal = i; - Value ret = lv.get(i+1).evalValue(c); + Value ret = lv.get(i+1).evalValue(c, t); return (cc, tt) -> ret; } } if (lv.size()%2 == 1) { - Value ret = lv.get(lv.size() - 1).evalValue(c); + Value ret = lv.get(lv.size() - 1).evalValue(c, t); return (cc, tt) -> ret; } return (cc, tt) -> Value.NULL; @@ -1746,7 +1747,7 @@ public class Expression implements Cloneable c.setVariable("_",(cc, tt) -> new NumericValue(0).bindTo("_")); while (i new NumericValue(seriously).bindTo("_")); @@ -1777,8 +1778,8 @@ public class Expression implements Cloneable { long whyYouAsk = i; c.setVariable("_", (cc, tt) -> new NumericValue(whyYouAsk).bindTo("_")); - lastOne = expr.evalValue(c); - if (cond != null && cond.evalValue(c).getBoolean()) + lastOne = expr.evalValue(c, t); + if (cond != null && cond.evalValue(c, Context.BOOLEAN).getBoolean()) break; } //revering scope @@ -1817,7 +1818,7 @@ public class Expression implements Cloneable c.setVariable("_", (cc, tt) -> next); c.setVariable("_i", (cc, tt) -> new NumericValue(doYouReally).bindTo("_i")); result.add(expr.evalValue(c)); - if (cond != null && cond.evalValue(c).getBoolean()) + if (cond != null && cond.evalValue(c, Context.BOOLEAN).getBoolean()) { next.boundVariable = var; break; @@ -1861,9 +1862,9 @@ public class Expression implements Cloneable int seriously = i; c.setVariable("_", (cc, tt) -> next); c.setVariable("_i", (cc, tt) -> new NumericValue(seriously).bindTo("_i")); - if(expr.evalValue(c).getBoolean()) + if(expr.evalValue(c, Context.BOOLEAN).getBoolean()) result.add(next); - if (cond != null && cond.evalValue(c).getBoolean()) + if (cond != null && cond.evalValue(c, Context.BOOLEAN).getBoolean()) { next.boundVariable = var; break; @@ -1901,7 +1902,7 @@ public class Expression implements Cloneable int seriously = i; c.setVariable("_", (cc, tt) -> next); c.setVariable("_i", (cc, tt) -> new NumericValue(seriously).bindTo("_i")); - if(expr.evalValue(c).getBoolean()) + if(expr.evalValue(c, Context.BOOLEAN).getBoolean()) { result = next; next.boundVariable = var; @@ -1939,7 +1940,7 @@ public class Expression implements Cloneable int seriously = i; c.setVariable("_", (cc, tt) -> next); c.setVariable("_i", (cc, tt) -> new NumericValue(seriously).bindTo("_i")); - if(!expr.evalValue(c).getBoolean()) + if(!expr.evalValue(c, Context.BOOLEAN).getBoolean()) { result = LazyValue.FALSE; next.boundVariable = var; @@ -1983,9 +1984,10 @@ public class Expression implements Cloneable int seriously = i; c.setVariable("_", (cc, tt) -> next); c.setVariable("_i", (cc, tt) -> new NumericValue(seriously).bindTo("_i")); - if(expr.evalValue(c).getBoolean()) + Value result = expr.evalValue(c, t); + if(t != Context.VOID && result.getBoolean()) successCount++; - if (cond != null && cond.evalValue(c).getBoolean()) + if (cond != null && cond.evalValue(c, Context.BOOLEAN).getBoolean()) { next.boundVariable = var; break; @@ -2033,7 +2035,7 @@ public class Expression implements Cloneable Value promiseWontChangeYou = acc; c.setVariable("_a", (cc, tt) -> promiseWontChangeYou.bindTo("_a")); c.setVariable("_", (cc, tt) -> next); - acc = expr.evalValue(c); + acc = expr.evalValue(c, t); next.boundVariable = var; } //reverting scope diff --git a/src/main/java/carpet/script/LazyValue.java b/src/main/java/carpet/script/LazyValue.java index 8a7d8f43..1cfb32a3 100644 --- a/src/main/java/carpet/script/LazyValue.java +++ b/src/main/java/carpet/script/LazyValue.java @@ -19,6 +19,6 @@ public interface LazyValue Value evalValue(Context c, Integer type); default Value evalValue(Context c){ - return evalValue(c, 0); + return evalValue(c, Context.NONE); } } diff --git a/src/main/java/carpet/script/value/BlockValue.java b/src/main/java/carpet/script/value/BlockValue.java index e943c0b1..7fe8d6cd 100644 --- a/src/main/java/carpet/script/value/BlockValue.java +++ b/src/main/java/carpet/script/value/BlockValue.java @@ -144,8 +144,6 @@ public class BlockValue extends Value } if (v1 instanceof BlockValue) { - ((BlockValue) v1).getBlockState(); - ((BlockValue) v1).getData(); return new LocatorResult(((BlockValue) v1), 1+offset); } if (v1 instanceof ListValue) @@ -256,7 +254,7 @@ public class BlockValue extends Value @Override public Value clone() { - return new BlockValue(blockState, world, pos); + return new BlockValue(blockState, world, pos, data); } @Override diff --git a/src/main/java/carpet/script/value/Value.java b/src/main/java/carpet/script/value/Value.java index 4b529c6a..8faf4c15 100644 --- a/src/main/java/carpet/script/value/Value.java +++ b/src/main/java/carpet/script/value/Value.java @@ -48,6 +48,7 @@ public abstract class Value implements Comparable, Cloneable { // should not happen e.printStackTrace(); + throw new InternalExpressionException("Variable of type "+getTypeString()+" is not cloneable. Tell gnembon about it, this shoudn't happen"); } copy.boundVariable = var; return copy;