From 85a34fdefacba6f0fbcfd4959f71f122c55409a2 Mon Sep 17 00:00:00 2001
From: gnembon
Date: Thu, 6 Feb 2020 09:33:46 -0400
Subject: [PATCH 1/4] added profile command
---
src/main/java/carpet/CarpetServer.java | 14 ++------
src/main/java/carpet/CarpetSettings.java | 7 ++++
.../java/carpet/commands/ProfileCommand.java | 33 +++++++++++++++++++
.../java/carpet/commands/TickCommand.java | 4 +--
4 files changed, 44 insertions(+), 14 deletions(-)
create mode 100644 src/main/java/carpet/commands/ProfileCommand.java
diff --git a/src/main/java/carpet/CarpetServer.java b/src/main/java/carpet/CarpetServer.java
index 1e55bc6c..b4e47369 100644
--- a/src/main/java/carpet/CarpetServer.java
+++ b/src/main/java/carpet/CarpetServer.java
@@ -5,18 +5,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Random;
-import carpet.commands.CameraModeCommand;
-import carpet.commands.CounterCommand;
-import carpet.commands.DistanceCommand;
-import carpet.commands.DrawCommand;
-import carpet.commands.InfoCommand;
-import carpet.commands.LogCommand;
-import carpet.commands.MobAICommand;
-import carpet.commands.PerimeterInfoCommand;
-import carpet.commands.PlayerCommand;
-import carpet.commands.ScriptCommand;
-import carpet.commands.SpawnCommand;
-import carpet.commands.TickCommand;
+import carpet.commands.*;
import carpet.helpers.TickSpeed;
import carpet.logging.LoggerRegistry;
import carpet.script.CarpetScriptServer;
@@ -89,6 +78,7 @@ public class CarpetServer // static for now - easier to handle all around the co
public static void registerCarpetCommands(CommandDispatcher dispatcher)
{
TickCommand.register(dispatcher);
+ ProfileCommand.register(dispatcher);
CounterCommand.register(dispatcher);
LogCommand.register(dispatcher);
SpawnCommand.register(dispatcher);
diff --git a/src/main/java/carpet/CarpetSettings.java b/src/main/java/carpet/CarpetSettings.java
index f3c22b4c..cfd2795c 100644
--- a/src/main/java/carpet/CarpetSettings.java
+++ b/src/main/java/carpet/CarpetSettings.java
@@ -231,6 +231,13 @@ public class CarpetSettings
@Rule(desc = "Enables /tick command to control game clocks", category = COMMAND)
public static String commandTick = "true";
+ @Rule(
+ desc = "Enables /profile command to monitor game performance",
+ extra = "subset of /tick command capabilities",
+ category = COMMAND
+ )
+ public static String commandProfile = "true";
+
@Rule(desc = "Enables /log command to monitor events via chat and overlays", category = COMMAND)
public static String commandLog = "true";
diff --git a/src/main/java/carpet/commands/ProfileCommand.java b/src/main/java/carpet/commands/ProfileCommand.java
new file mode 100644
index 00000000..6a4dc2f4
--- /dev/null
+++ b/src/main/java/carpet/commands/ProfileCommand.java
@@ -0,0 +1,33 @@
+package carpet.commands;
+
+import carpet.CarpetSettings;
+import carpet.settings.SettingsManager;
+import com.mojang.brigadier.CommandDispatcher;
+import com.mojang.brigadier.builder.LiteralArgumentBuilder;
+import net.minecraft.server.command.ServerCommandSource;
+
+import static carpet.commands.TickCommand.healthEntities;
+import static carpet.commands.TickCommand.healthReport;
+import static com.mojang.brigadier.arguments.IntegerArgumentType.getInteger;
+import static com.mojang.brigadier.arguments.IntegerArgumentType.integer;
+import static net.minecraft.server.command.CommandManager.argument;
+import static net.minecraft.server.command.CommandManager.literal;
+
+public class ProfileCommand
+{
+ public static void register(CommandDispatcher dispatcher)
+ {
+ LiteralArgumentBuilder literalargumentbuilder = literal("profile").
+ requires((player) -> SettingsManager.canUseCommand(player, CarpetSettings.commandProfile)).
+ executes( (c) -> healthReport(c.getSource(), 100)).
+ then(literal("health").
+ executes( (c) -> healthReport(c.getSource(), 100)).
+ then(argument("ticks", integer(20,24000)).
+ executes( (c) -> healthReport(c.getSource(), getInteger(c, "ticks"))))).
+ then(literal("entities").
+ executes((c) -> healthEntities(c.getSource(), 100)).
+ then(argument("ticks", integer(20,24000)).
+ executes((c) -> healthEntities(c.getSource(), getInteger(c, "ticks")))));
+ dispatcher.register(literalargumentbuilder);
+ }
+}
diff --git a/src/main/java/carpet/commands/TickCommand.java b/src/main/java/carpet/commands/TickCommand.java
index b9e47b9a..ac65b7bd 100644
--- a/src/main/java/carpet/commands/TickCommand.java
+++ b/src/main/java/carpet/commands/TickCommand.java
@@ -129,13 +129,13 @@ public class TickCommand
return 1;
}
- private static int healthReport(ServerCommandSource source, int ticks)
+ public static int healthReport(ServerCommandSource source, int ticks)
{
CarpetProfiler.prepare_tick_report(source, ticks);
return 1;
}
- private static int healthEntities(ServerCommandSource source, int ticks)
+ public static int healthEntities(ServerCommandSource source, int ticks)
{
CarpetProfiler.prepare_entity_report(source, ticks);
return 1;
From 73680247f44eb3481e2428b48e4995a4f275643c Mon Sep 17 00:00:00 2001
From: gnembon
Date: Thu, 6 Feb 2020 09:35:08 -0400
Subject: [PATCH 2/4] b
---
gradle.properties | 2 +-
src/main/java/carpet/CarpetSettings.java | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/gradle.properties b/gradle.properties
index b413fb09..603b6ab3 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -9,7 +9,7 @@ org.gradle.jvmargs=-Xmx1G
loader_version=0.7.6+build.181
# Mod Properties
- mod_version = 1.3.9+v200206
+ mod_version = 1.3.9+v200206b
maven_group = carpet
archives_base_name = fabric-carpet
diff --git a/src/main/java/carpet/CarpetSettings.java b/src/main/java/carpet/CarpetSettings.java
index cfd2795c..b07f7195 100644
--- a/src/main/java/carpet/CarpetSettings.java
+++ b/src/main/java/carpet/CarpetSettings.java
@@ -32,7 +32,7 @@ import static carpet.settings.RuleCategory.DISPENSER;
@SuppressWarnings("CanBeFinal")
public class CarpetSettings
{
- public static final String carpetVersion = "1.3.9+v200206";
+ public static final String carpetVersion = "1.3.9+v200206b";
public static final Logger LOG = LogManager.getLogger();
public static boolean skipGenerationChecks = false;
public static boolean impendingFillSkipUpdates = false;
From 67d71e26c101093bebea842367ebd39d261b7e63 Mon Sep 17 00:00:00 2001
From: gnembon
Date: Thu, 6 Feb 2020 16:54:36 -0400
Subject: [PATCH 3/4] destroy rework, needs testing
---
.../java/carpet/script/CarpetExpression.java | 86 ++++++++++++-------
1 file changed, 55 insertions(+), 31 deletions(-)
diff --git a/src/main/java/carpet/script/CarpetExpression.java b/src/main/java/carpet/script/CarpetExpression.java
index 2bb24ce0..218233cf 100644
--- a/src/main/java/carpet/script/CarpetExpression.java
+++ b/src/main/java/carpet/script/CarpetExpression.java
@@ -43,6 +43,15 @@ import net.minecraft.block.CommandBlock;
import net.minecraft.block.JigsawBlock;
import net.minecraft.block.StructureBlock;
import net.minecraft.block.entity.BlockEntity;
+import net.minecraft.enchantment.EnchantmentHelper;
+import net.minecraft.item.BlockItem;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.item.Items;
+import net.minecraft.item.MiningToolItem;
+import net.minecraft.item.ShearsItem;
+import net.minecraft.item.SwordItem;
+import net.minecraft.item.TridentItem;
import net.minecraft.network.packet.s2c.play.ContainerSlotUpdateS2CPacket;
import net.minecraft.network.packet.s2c.play.PlaySoundIdS2CPacket;
import net.minecraft.command.arguments.ItemStackArgument;
@@ -58,10 +67,6 @@ import net.minecraft.entity.SpawnType;
import net.minecraft.entity.decoration.ArmorStandEntity;
import net.minecraft.entity.mob.MobEntity;
import net.minecraft.entity.player.PlayerEntity;
-import net.minecraft.item.BlockItem;
-import net.minecraft.item.Item;
-import net.minecraft.item.ItemStack;
-import net.minecraft.item.Items;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.StringTag;
import net.minecraft.nbt.Tag;
@@ -105,8 +110,6 @@ import net.minecraft.world.chunk.ChunkStatus;
import net.minecraft.world.chunk.WorldChunk;
import net.minecraft.world.dimension.DimensionType;
import net.minecraft.world.gen.ChunkRandom;
-import net.minecraft.loot.context.LootContext;
-import net.minecraft.loot.context.LootContextParameters;
import org.apache.commons.lang3.tuple.Pair;
import java.util.ArrayList;
@@ -1243,8 +1246,10 @@ public class CarpetExpression
if (lv.size() > locator.offset)
how = NumericValue.asNumber(lv.get(locator.offset).evalValue(cc)).getLong();
Item item = Items.DIAMOND_PICKAXE;
+ boolean playerBreak = false;
if (lv.size() > locator.offset+1)
{
+ playerBreak = true;
String itemString = lv.get(locator.offset+1).evalValue(c).getString();
item = Registry.ITEM.get(new Identifier(itemString));
if (item == Items.AIR && !itemString.equals("air")) throw new InternalExpressionException("Incorrect item: "+itemString);
@@ -1258,37 +1263,56 @@ public class CarpetExpression
else
tag = NBTSerializableValue.parseString(tagValue.getString()).getCompoundTag();
}
- world.removeBlock(where, false);
+
+ ItemStack tool = new ItemStack(item, 1);
+ if (tag != null)
+ tool.setTag(tag);
+ if (playerBreak && state.getHardness(world, where) < 0.0) return LazyValue.FALSE;
+ boolean removed = world.removeBlock(where, false);
+ if (!removed) return LazyValue.FALSE;
world.playLevelEvent(null, 2001, where, Block.getRawIdFromState(state));
- // WIP tool still mines everything, and only enchantments count.
- // need to verify the durability changes
- if (how < 0)
+ boolean toolBroke = false;
+ boolean dropLoot = true;
+ if (playerBreak)
{
- Block.dropStack(world, where, new ItemStack(state.getBlock()));
+ boolean isUsingEffectiveTool = state.getMaterial().canBreakByHand() || tool.isEffectiveOn(state);
+ //postMine durability
+ float hardness = state.getHardness(world, where);
+ int damageAmount = 0;
+ if ((item instanceof MiningToolItem && hardness > 0.0) || item instanceof ShearsItem)
+ {
+ damageAmount = 1;
+ }
+ else if (item instanceof TridentItem || item instanceof SwordItem)
+ {
+ damageAmount = 2;
+ }
+ toolBroke = damageAmount>0 && tool.damage(damageAmount, world.getRandom(), null);
+ if (!isUsingEffectiveTool)
+ dropLoot = false;
}
- else
+
+ if (dropLoot)
{
- ItemStack tool = new ItemStack(item, 1);
- if (tag != null)
- tool.setTag(tag);
- if (how > 0)
- tool.addEnchantment(Enchantments.FORTUNE,(int)how);
- else if (how < 0)
- tool.addEnchantment(Enchantments.SILK_TOUCH, 1);
-
- LootContext.Builder lootContext$Builder_1 = (new LootContext.Builder(world)).
- setRandom(world.random).
- put(LootContextParameters.POSITION, where).
- put(LootContextParameters.BLOCK_STATE, state).
- putNullable(LootContextParameters.BLOCK_ENTITY, be).
- putNullable(LootContextParameters.THIS_ENTITY, cc.s.getEntity()).
- put(LootContextParameters.TOOL, tool);
- state.getDroppedStacks(lootContext$Builder_1).forEach((stack) -> Block.dropStack(world, where, stack));
-
- //Block.dropStacks(state, world, where, be, cc.s.getEntity(), tool );
+ if (how < 0 || (tag != null && EnchantmentHelper.getLevel(Enchantments.SILK_TOUCH, tool) > 0))
+ {
+ Block.dropStack(world, where, new ItemStack(state.getBlock()));
+ }
+ else
+ {
+ if (how > 0)
+ tool.addEnchantment(Enchantments.FORTUNE, (int) how);
+ Block.dropStacks(state, world, where, be, null, tool);
+ }
}
- return (c_, t_) -> Value.TRUE;
+ if (!playerBreak)
+ return (c_, t_) -> Value.TRUE;
+ if (toolBroke)
+ return LazyValue.NULL;
+ Value ret = new NBTSerializableValue(tool.getTag());
+ return (_c, _t) -> ret;
+
});
this.expr.addLazyFunction("harvest", -1, (c, t, lv) ->
From c3137203b206b25c3135253526f761dc77f2fb74 Mon Sep 17 00:00:00 2001
From: gnembon
Date: Thu, 6 Feb 2020 21:00:02 -0400
Subject: [PATCH 4/4] reworked destroy
---
.../java/carpet/script/CarpetExpression.java | 90 +++++++++++++++----
1 file changed, 73 insertions(+), 17 deletions(-)
diff --git a/src/main/java/carpet/script/CarpetExpression.java b/src/main/java/carpet/script/CarpetExpression.java
index 218233cf..a579512b 100644
--- a/src/main/java/carpet/script/CarpetExpression.java
+++ b/src/main/java/carpet/script/CarpetExpression.java
@@ -44,6 +44,7 @@ import net.minecraft.block.JigsawBlock;
import net.minecraft.block.StructureBlock;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.enchantment.EnchantmentHelper;
+import net.minecraft.entity.FallingBlockEntity;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
@@ -154,6 +155,7 @@ public class CarpetExpression
private final Expression expr;
Expression getExpr() {return expr;}
private static long tickStart = 0L;
+ private static FallingBlockEntity DUMMY_ENTITY = new FallingBlockEntity(EntityType.FALLING_BLOCK, null);
private static boolean stopAll = false;
@@ -521,9 +523,45 @@ public class CarpetExpression
* Causes a block to tick at position.
* random_tick(pos)
* Causes a random tick at position.
- * destroy(pos), destroy(pos, -1), destroy(pos, <N>)
+ * destroy(pos), destroy(pos, -1), destroy(pos, <N>), destroy(pos, tool, nbt?)
* Destroys the block like it was mined by a player. Add -1 for silk touch, and positive number for fortune level.
- * This function, unlike harvest, will affect all kinds of blocks
+ * If tool is specified, and optionally its nbt, it will use that tool and will attempt to mine the block with this tool.
+ * If called without item context, this function, unlike harvest, will affect all kinds of blocks. If called with item in context,
+ * it will fail to break blocks that cannot be broken by a survival player.
+ * Without item context it returns false if failed to destroy the block and true if block breaking was
+ * successful. In item context, true means that breaking item has no nbt to use, null indicating that
+ * the tool should be considered broken in process, and nbt type value, for a resulting NBT tag on a hypothetical tool.
+ * Its up to the programmer to use that nbt to apply it where it belong
+ *
+ * Here is a sample code that can be used to mine blocks using items in player inventory, without using player context for mining.
+ * Obviously, in this case the use of harvest would be much more applicable:
+ *
+ * mine(x,y,z) ->
+ * (
+ * p = player();
+ * slot = p~'selected_slot';
+ * item_tuple = inventory_get(p, slot);
+ * if (!item_tuple, destroy(x,y,z,'air'); return()); // empty hand, just break with 'air'
+ * l(item, count, tag) = item_tuple;
+ * tag_back = destroy(x,y,z, item, tag);
+ * if (tag_back == false, // failed to break the item
+ * return(tag_back)
+ * );
+ * if (tag_back == true, // block broke, tool has no tag
+ * return(tag_back)
+ * );
+ * if (tag_back == null, //item broke
+ * delete(tag:'Damage');
+ * inventory_set(p, slot, count-1, item, tag);
+ * return(tag_back)
+ * );
+ * if (type(tag_back) == 'nbt', // item didn't break, here is the effective nbt
+ * inventory_set(p, slot, count, item, tag_back);
+ * return(tag_back)
+ * );
+ * print('How did we get here?');
+ * )
+ *
* harvest(player, pos)
* Causes a block to be harvested by a specified player entity. Honors player item enchantments, as well as damages the
* tool if applicable. If the entity is not a valid player, no block gets destroyed. If a player is not allowed to
@@ -1243,25 +1281,40 @@ public class CarpetExpression
BlockPos where = locator.block.getPos();
BlockEntity be = world.getBlockEntity(where);
long how = 0;
- if (lv.size() > locator.offset)
- how = NumericValue.asNumber(lv.get(locator.offset).evalValue(cc)).getLong();
Item item = Items.DIAMOND_PICKAXE;
boolean playerBreak = false;
- if (lv.size() > locator.offset+1)
+ if (lv.size() > locator.offset)
{
- playerBreak = true;
- String itemString = lv.get(locator.offset+1).evalValue(c).getString();
- item = Registry.ITEM.get(new Identifier(itemString));
- if (item == Items.AIR && !itemString.equals("air")) throw new InternalExpressionException("Incorrect item: "+itemString);
+ Value val = lv.get(locator.offset).evalValue(c);
+ if (val instanceof NumericValue)
+ {
+ how = ((NumericValue) val).getLong();
+ }
+ else
+ {
+ playerBreak = true;
+ String itemString = val.getString();
+ item = Registry.ITEM.get(new Identifier(itemString));
+ if (item == Items.AIR && !itemString.equals("air"))
+ throw new InternalExpressionException("Incorrect item: " + itemString);
+ }
}
CompoundTag tag = null;
- if (lv.size() > locator.offset+2)
+ if (lv.size() > locator.offset+1)
{
- Value tagValue = lv.get(locator.offset+2).evalValue(c);
- if (tagValue instanceof NBTSerializableValue)
+ if (!playerBreak) throw new InternalExpressionException("tag is not necessary with 'destroy' with no item");
+ Value tagValue = lv.get(locator.offset+1).evalValue(c);
+ if (tagValue instanceof NullValue)
+ tag = null;
+ else if (tagValue instanceof NBTSerializableValue)
tag = ((NBTSerializableValue) tagValue).getCompoundTag();
else
- tag = NBTSerializableValue.parseString(tagValue.getString()).getCompoundTag();
+ {
+ NBTSerializableValue readTag = NBTSerializableValue.parseString(tagValue.getString());
+ if (readTag == null)
+ throw new InternalExpressionException("Incorrect tag: "+tagValue.getString());
+ tag = readTag.getCompoundTag();
+ }
}
ItemStack tool = new ItemStack(item, 1);
@@ -1277,7 +1330,7 @@ public class CarpetExpression
if (playerBreak)
{
boolean isUsingEffectiveTool = state.getMaterial().canBreakByHand() || tool.isEffectiveOn(state);
- //postMine durability
+ //postMine() durability from item classes
float hardness = state.getHardness(world, where);
int damageAmount = 0;
if ((item instanceof MiningToolItem && hardness > 0.0) || item instanceof ShearsItem)
@@ -1303,14 +1356,17 @@ public class CarpetExpression
{
if (how > 0)
tool.addEnchantment(Enchantments.FORTUNE, (int) how);
- Block.dropStacks(state, world, where, be, null, tool);
+ Block.dropStacks(state, world, where, be, DUMMY_ENTITY, tool);
}
}
- if (!playerBreak)
+ if (!playerBreak) // no tool info - block brokwn
return (c_, t_) -> Value.TRUE;
if (toolBroke)
return LazyValue.NULL;
- Value ret = new NBTSerializableValue(tool.getTag());
+ Tag outtag = tool.getTag();
+ if (outtag == null)
+ return LazyValue.TRUE;
+ Value ret = new NBTSerializableValue(outtag);
return (_c, _t) -> ret;
});