Skip to content

Commit

Permalink
Implement 3 new advancements to take advantage of tool stat predicates
Browse files Browse the repository at this point in the history
Netherite Tier is a simple stat in set check, usng the harvest tiers stat
One shot is a stat minimum check
Perfect aim checks for an exact stat value, the maximum value
Also update the abilities advancement for new abilities
  • Loading branch information
KnightMiner committed Dec 29, 2023
1 parent 3350452 commit 4d809a3
Show file tree
Hide file tree
Showing 10 changed files with 480 additions and 60 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"parent": "tconstruct:tools/tinker_tool",
"parent": "tconstruct:tools/netherite_tier",
"display": {
"icon": {
"item": "tconstruct:manyullyn_ingot"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"parent": "tconstruct:tools/tinker_tool",
"display": {
"icon": {
"item": "minecraft:netherite_ingot"
},
"title": {
"translate": "advancements.tconstruct.tools.netherite_tier.title"
},
"description": {
"translate": "advancements.tconstruct.tools.netherite_tier.description"
},
"frame": "goal",
"show_toast": true,
"announce_to_chat": true,
"hidden": false
},
"criteria": {
"harvest_level": {
"trigger": "minecraft:inventory_changed",
"conditions": {
"items": [
{
"type": "tconstruct:tool_stack",
"predicate": {
"type": "tconstruct:stat_in_set",
"stat": "tconstruct:harvest_tier",
"values": [
"minecraft:netherite"
]
}
}
]
}
}
},
"requirements": [
[
"harvest_level"
]
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"parent": "tconstruct:tools/tinker_tool",
"display": {
"icon": {
"item": "minecraft:zombie_head"
},
"title": {
"translate": "advancements.tconstruct.tools.one_shot.title"
},
"description": {
"translate": "advancements.tconstruct.tools.one_shot.description"
},
"frame": "goal",
"show_toast": true,
"announce_to_chat": true,
"hidden": false
},
"criteria": {
"damage": {
"trigger": "minecraft:inventory_changed",
"conditions": {
"items": [
{
"type": "tconstruct:tool_stack",
"predicate": {
"type": "tconstruct:stat_in_range",
"stat": "tconstruct:attack_damage",
"min": 20.0
}
}
]
}
}
},
"requirements": [
[
"damage"
]
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"parent": "tconstruct:tools/tinker_tool",
"display": {
"icon": {
"item": "minecraft:target"
},
"title": {
"translate": "advancements.tconstruct.tools.perfect_aim.title"
},
"description": {
"translate": "advancements.tconstruct.tools.perfect_aim.description"
},
"frame": "goal",
"show_toast": true,
"announce_to_chat": true,
"hidden": false
},
"criteria": {
"accuracy": {
"trigger": "minecraft:inventory_changed",
"conditions": {
"items": [
{
"type": "tconstruct:tool_stack",
"predicate": {
"type": "tconstruct:stat_in_range",
"stat": "tconstruct:accuracy",
"min": 1.0,
"max": 1.0
}
}
]
}
}
},
"requirements": [
[
"accuracy"
]
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.Tiers;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.material.Fluid;
Expand All @@ -49,12 +50,15 @@
import slimeknights.tconstruct.library.json.predicate.tool.HasModifierPredicate;
import slimeknights.tconstruct.library.json.predicate.tool.HasModifierPredicate.ModifierCheck;
import slimeknights.tconstruct.library.json.predicate.tool.ItemToolPredicate;
import slimeknights.tconstruct.library.json.predicate.tool.StatInSetPredicate;
import slimeknights.tconstruct.library.json.predicate.tool.ToolContextPredicate;
import slimeknights.tconstruct.library.json.predicate.tool.ToolStackItemPredicate;
import slimeknights.tconstruct.library.materials.definition.MaterialId;
import slimeknights.tconstruct.library.modifiers.ModifierId;
import slimeknights.tconstruct.library.modifiers.util.LazyModifier;
import slimeknights.tconstruct.library.tools.nbt.MaterialIdNBT;
import slimeknights.tconstruct.library.tools.stat.StatPredicate;
import slimeknights.tconstruct.library.tools.stat.ToolStats;
import slimeknights.tconstruct.library.utils.NBTTags;
import slimeknights.tconstruct.shared.TinkerCommons;
import slimeknights.tconstruct.shared.TinkerMaterials;
Expand Down Expand Up @@ -111,7 +115,14 @@ protected void generate() {
builder.addCriterion("crafted_block", hasItem(TinkerTables.tinkerStation)));
Advancement tinkerTool = builder(TinkerTools.pickaxe.get().getRenderTool(), resource("tools/tinker_tool"), tinkerStation, FrameType.TASK, builder ->
builder.addCriterion("crafted_tool", hasTag(TinkerTags.Items.MULTIPART_TOOL)));
builder(TinkerMaterials.manyullyn.getIngot(), resource("tools/material_master"), tinkerTool, FrameType.CHALLENGE, builder -> {
Advancement harvestLevel = builder(Items.NETHERITE_INGOT, resource("tools/netherite_tier"), tinkerTool, FrameType.GOAL, builder ->
builder.addCriterion("harvest_level", InventoryChangeTrigger.TriggerInstance.hasItems(new ToolStackItemPredicate(new StatInSetPredicate<>(ToolStats.HARVEST_TIER, Tiers.NETHERITE)))));
builder(Items.TARGET, resource("tools/perfect_aim"), tinkerTool, FrameType.GOAL, builder ->
builder.addCriterion("accuracy", InventoryChangeTrigger.TriggerInstance.hasItems(new ToolStackItemPredicate(new StatPredicate(ToolStats.ACCURACY, 1, 1)))));
// note that attack damage gets +1 from player attributes, so 20 is actually 21 damage with the tool
builder(Items.ZOMBIE_HEAD, resource("tools/one_shot"), tinkerTool, FrameType.GOAL, builder ->
builder.addCriterion("damage", InventoryChangeTrigger.TriggerInstance.hasItems(new ToolStackItemPredicate(new StatPredicate(ToolStats.ATTACK_DAMAGE, 20, Float.POSITIVE_INFINITY)))));
builder(TinkerMaterials.manyullyn.getIngot(), resource("tools/material_master"), harvestLevel, FrameType.CHALLENGE, builder -> {
Consumer<MaterialId> with = id -> builder.addCriterion(id.getPath(), InventoryChangeTrigger.TriggerInstance.hasItems(new ToolStackItemPredicate(new HasMaterialPredicate(id))));
// tier 1
with.accept(MaterialIds.wood);
Expand Down Expand Up @@ -242,24 +253,32 @@ protected void generate() {
// general
with.accept(ModifierIds.gilded);
with.accept(ModifierIds.luck);
with.accept(ModifierIds.reach);
withL.accept(TinkerModifiers.unbreakable);
// armor
withL.accept(TinkerModifiers.protection);
// helmet
with.accept(ModifierIds.aquaAffinity);
withL.accept(TinkerModifiers.slurping);
withL.accept(TinkerModifiers.zoom);
// chestplate
withL.accept(TinkerModifiers.ambidextrous);
with.accept(ModifierIds.reach);
with.accept(ModifierIds.strength);
// leggings
with.accept(ModifierIds.pockets);
with.accept(ModifierIds.toolBelt);
withL.accept(TinkerModifiers.wetting);
// boots
withL.accept(TinkerModifiers.bouncy);
withL.accept(TinkerModifiers.doubleJump);
withL.accept(TinkerModifiers.flamewake);
withL.accept(TinkerModifiers.frostWalker);
withL.accept(TinkerModifiers.longFall);
withL.accept(TinkerModifiers.pathMaker);
withL.accept(TinkerModifiers.plowing);
with.accept(ModifierIds.pockets);
withL.accept(TinkerModifiers.slurping);
withL.accept(TinkerModifiers.snowdrift);
with.accept(ModifierIds.strength);
with.accept(ModifierIds.toolBelt);
withL.accept(TinkerModifiers.ambidextrous);
withL.accept(TinkerModifiers.zoom);
withL.accept(TinkerModifiers.longFall);
// shield
withL.accept(TinkerModifiers.boundless);
withL.accept(TinkerModifiers.reflecting);
// harvest
withL.accept(TinkerModifiers.autosmelt);
Expand All @@ -273,6 +292,12 @@ protected void generate() {
withL.accept(TinkerModifiers.pathing);
withL.accept(TinkerModifiers.stripping);
withL.accept(TinkerModifiers.tilling);
// staff
withL.accept(TinkerModifiers.bonking);
withL.accept(TinkerModifiers.flinging);
withL.accept(TinkerModifiers.spitting);
withL.accept(TinkerModifiers.springing);
withL.accept(TinkerModifiers.warping);
// weapon
withL.accept(TinkerModifiers.dualWielding);
withL.accept(TinkerModifiers.melting);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package slimeknights.tconstruct.library.json.predicate.tool;

import com.google.common.collect.ImmutableSet;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.util.GsonHelper;
import slimeknights.mantle.data.GenericLoaderRegistry.IGenericLoader;
import slimeknights.mantle.data.predicate.IJsonPredicate;
import slimeknights.mantle.util.JsonHelper;
import slimeknights.tconstruct.library.tools.nbt.IToolContext;
import slimeknights.tconstruct.library.tools.stat.IToolStat;
import slimeknights.tconstruct.library.tools.stat.ToolStats;

import java.util.Set;

/**
* Predicate which checks if a stat is in the given set of values
* @param <T> Stat type
* @param stat Stat to check
* @param values Set of values to match
* @see slimeknights.tconstruct.library.tools.stat.StatPredicate
*/
public record StatInSetPredicate<T>(IToolStat<T> stat, Set<T> values) implements ToolContextPredicate {
public StatInSetPredicate(IToolStat<T> stat, T value) {
this(stat, Set.of(value));
}

@Override
public boolean matches(IToolContext tool) {
return values.contains(tool.getStats().get(stat));
}

@Override
public IGenericLoader<? extends IJsonPredicate<IToolContext>> getLoader() {
return LOADER;
}

public static final IGenericLoader<StatInSetPredicate<?>> LOADER = new IGenericLoader<>() {
@Override
public StatInSetPredicate<?> deserialize(JsonObject json) {
return deserialize(json, ToolStats.fromJson(GsonHelper.getAsString(json, "stat")));
}

/** Handles generics for the set parsing */
private static <T> StatInSetPredicate<T> deserialize(JsonObject json, IToolStat<T> stat) {
Set<T> values = ImmutableSet.copyOf(JsonHelper.parseList(json, "values", (element, key) -> stat.deserialize(element)));
return new StatInSetPredicate<>(stat, values);
}

@Override
public void serialize(StatInSetPredicate<?> object, JsonObject json) {
json.addProperty("stat", object.stat.getName().toString());
serializeSet(object, json);
}

/** Handles generics for the set serializing */
private static <T> void serializeSet(StatInSetPredicate<T> object, JsonObject json) {
JsonArray array = new JsonArray();
for (T value : object.values) {
array.add(object.stat.serialize(value));
}
json.add("values", array);
}

@Override
public StatInSetPredicate<?> fromNetwork(FriendlyByteBuf buffer) {
return fromNetwork(buffer, ToolStats.fromNetwork(buffer));
}

/** Handles generics for the set reading */
private static <T> StatInSetPredicate<T> fromNetwork(FriendlyByteBuf buffer, IToolStat<T> stat) {
ImmutableSet.Builder<T> builder = ImmutableSet.builder();
int max = buffer.readVarInt();
for (int i = 0; i < max; i++) {
builder.add(stat.fromNetwork(buffer));
}
return new StatInSetPredicate<>(stat, builder.build());
}

@Override
public void toNetwork(StatInSetPredicate<?> object, FriendlyByteBuf buffer) {
buffer.writeUtf(object.stat.toString());
setToNetwork(object, buffer);
}

/** Handles generics for the set writing */
private static <T> void setToNetwork(StatInSetPredicate<T> object, FriendlyByteBuf buffer) {
buffer.writeVarInt(object.values.size());
for (T value : object.values) {
object.stat.toNetwork(buffer, value);
}
}
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@
import java.util.function.Predicate;

/**
* Predicate to check if a tool has the given stat.
* TODO 1.19: move to {@link slimeknights.tconstruct.library.json.predicate.tool}
* Predicate to check if a tool has the given stat within the range.
* TODO 1.19: move to {@link slimeknights.tconstruct.library.json.predicate.tool} as {@code StatInRangePredicate}
* @see slimeknights.tconstruct.library.json.predicate.tool.StatInSetPredicate
*/
public record StatPredicate(INumericToolStat<?> stat, float min, float max) implements Predicate<StatsNBT>, ToolContextPredicate {

Expand Down
2 changes: 2 additions & 0 deletions src/main/java/slimeknights/tconstruct/tools/TinkerTools.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import slimeknights.tconstruct.library.json.predicate.tool.HasModifierPredicate;
import slimeknights.tconstruct.library.json.predicate.tool.HasStatTypePredicate;
import slimeknights.tconstruct.library.json.predicate.tool.ItemToolPredicate;
import slimeknights.tconstruct.library.json.predicate.tool.StatInSetPredicate;
import slimeknights.tconstruct.library.json.predicate.tool.ToolContextPredicate;
import slimeknights.tconstruct.library.json.predicate.tool.ToolStackItemPredicate;
import slimeknights.tconstruct.library.modifiers.TinkerHooks;
Expand Down Expand Up @@ -225,6 +226,7 @@ void registerRecipeSerializers(RegistryEvent.Register<RecipeSerializer<?>> event
ToolContextPredicate.LOADER.register(TConstruct.getResource("has_upgrades"), ToolContextPredicate.HAS_UPGRADES.getLoader());
ToolContextPredicate.LOADER.register(TConstruct.getResource("has_modifier"), HasModifierPredicate.LOADER);
ToolContextPredicate.LOADER.register(TConstruct.getResource("stat_in_range"), StatPredicate.LOADER);
ToolContextPredicate.LOADER.register(TConstruct.getResource("stat_in_set"), StatInSetPredicate.LOADER);
ToolContextPredicate.LOADER.register(TConstruct.getResource("has_material"), HasMaterialPredicate.LOADER);
ToolContextPredicate.LOADER.register(TConstruct.getResource("has_stat_type"), HasStatTypePredicate.LOADER);
}
Expand Down
6 changes: 6 additions & 0 deletions src/main/resources/assets/tconstruct/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -2890,6 +2890,12 @@
"advancements.tconstruct.tools.glass_cannon.description": "Create a tool that does over 20 damage with at most 100 durability",
"advancements.tconstruct.tools.tool_smith.title": "Tool Smith",
"advancements.tconstruct.tools.tool_smith.description": "Create one of every default small tool",
"advancements.tconstruct.tools.netherite_tier.title": "Netherite Tier",
"advancements.tconstruct.tools.netherite_tier.description": "Create a tool with the netherite harvest tier",
"advancements.tconstruct.tools.perfect_aim.title": "Perfect Aim",
"advancements.tconstruct.tools.perfect_aim.description": "Create a bow with 1.0 accuracy",
"advancements.tconstruct.tools.one_shot.title": "One Shot",
"advancements.tconstruct.tools.one_shot.description": "Create a melee weapon that can kill zombies in a single non-critical attack (21 damage or more)",
"advancements.tconstruct.tools.material_master.title": "Material Master",
"advancements.tconstruct.tools.material_master.description": "Use each default material at least once",

Expand Down

0 comments on commit 4d809a3

Please sign in to comment.