Skip to content

Commit

Permalink
Add support for oredict item predicates in advancements, and add a re…
Browse files Browse the repository at this point in the history
…gistry for item predicates (#4188)
  • Loading branch information
Landmaster authored and LexManos committed Aug 9, 2017
1 parent 82d735e commit ee449e4
Show file tree
Hide file tree
Showing 5 changed files with 337 additions and 0 deletions.
@@ -0,0 +1,16 @@
--- ../src-base/minecraft/net/minecraft/advancements/critereon/ItemPredicate.java
+++ ../src-work/minecraft/net/minecraft/advancements/critereon/ItemPredicate.java
@@ -104,6 +104,7 @@
if (p_192492_0_ != null && !p_192492_0_.isJsonNull())
{
JsonObject jsonobject = JsonUtils.func_151210_l(p_192492_0_, "item");
+ if (jsonobject.has("type"))
+ {
+ final ResourceLocation rl = new ResourceLocation(JsonUtils.func_151200_h(jsonobject, "type"));
+ final Map<ResourceLocation, java.util.function.Function<JsonObject, ItemPredicate>> map = net.minecraftforge.advancements.critereon.ItemPredicates.getPredicates();
+ if (map.containsKey(rl)) return map.get(rl).apply(jsonobject);
+ else throw new JsonSyntaxException("There is no ItemPredicate of type "+rl);
+ }
MinMaxBounds minmaxbounds = MinMaxBounds.func_192515_a(jsonobject.get("count"));
MinMaxBounds minmaxbounds1 = MinMaxBounds.func_192515_a(jsonobject.get("durability"));
Integer integer = jsonobject.has("data") ? JsonUtils.func_151203_m(jsonobject, "data") : null;
@@ -0,0 +1,49 @@
/*
* Minecraft Forge
* Copyright (c) 2016.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

package net.minecraftforge.advancements.critereon;

import com.google.gson.JsonObject;
import gnu.trove.map.hash.THashMap;
import net.minecraft.advancements.critereon.ItemPredicate;
import net.minecraft.util.ResourceLocation;

import java.util.Collections;
import java.util.Map;
import java.util.function.Function;

public class ItemPredicates
{
private static final Map<ResourceLocation, Function<JsonObject, ItemPredicate>> predicates = new THashMap<>();

static
{
register(new ResourceLocation("forge:ore_dict"), OredictItemPredicate::new);
}

public static void register(ResourceLocation rl, Function<JsonObject, ItemPredicate> jsonToPredicate)
{
predicates.put(rl, jsonToPredicate);
}

public static Map<ResourceLocation, Function<JsonObject, ItemPredicate>> getPredicates()
{
return Collections.unmodifiableMap(predicates);
}
}
@@ -0,0 +1,50 @@
/*
* Minecraft Forge
* Copyright (c) 2016.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

package net.minecraftforge.advancements.critereon;


import com.google.gson.JsonObject;
import net.minecraft.util.JsonUtils;
import org.apache.commons.lang3.ArrayUtils;

import net.minecraft.advancements.critereon.ItemPredicate;
import net.minecraft.item.ItemStack;
import net.minecraftforge.oredict.OreDictionary;

/**
* An {@link ItemPredicate} that matches oredicts.
*/
public class OredictItemPredicate extends ItemPredicate
{
private final String ore;

public OredictItemPredicate(String ore)
{
this.ore = ore;
}

public OredictItemPredicate(JsonObject jsonObject) { this(JsonUtils.getString(jsonObject, "ore")); }

@Override
public boolean test(ItemStack stack)
{
return !stack.isEmpty() && ArrayUtils.contains(OreDictionary.getOreIDs(stack), OreDictionary.getOreID(ore));
}
}
198 changes: 198 additions & 0 deletions src/test/java/net/minecraftforge/debug/OredictItemPredicateTest.java
@@ -0,0 +1,198 @@
package net.minecraftforge.debug;

import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonObject;
import net.minecraft.advancements.CriteriaTriggers;
import net.minecraft.advancements.ICriterionTrigger;
import net.minecraft.advancements.PlayerAdvancements;
import net.minecraft.advancements.critereon.AbstractCriterionInstance;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
* Most of the real work is in the advancements directory of this mod.
* This mod tests ore-dict advancement triggers.
*/
@Mod.EventBusSubscriber
@Mod(modid = OredictItemPredicateTest.MODID, name = "Oredict Item Predicate Test", version = "1.0", acceptableRemoteVersions = "*")
public class OredictItemPredicateTest
{
public static final String MODID = "oredict_predicate";

static final boolean ENABLED = false;

private static final MethodHandle ctRegister;
static
{
try
{
final Method tmp = CriteriaTriggers.class.getDeclaredMethod("register"/* func_192118_a */, ICriterionTrigger.class);
tmp.setAccessible(true);
ctRegister = MethodHandles.lookup().unreflect(tmp);
}
catch (Throwable e)
{
throw new RuntimeException(e);
}
}

public static final EnabledTrigger ENABLED_TRIGGER;
static
{
try
{
ENABLED_TRIGGER = (EnabledTrigger)(ICriterionTrigger)ctRegister.invokeExact((ICriterionTrigger)new EnabledTrigger());
}
catch (Throwable e)
{
throw new RuntimeException(e);
}
}

// trigger the enabled advancement on player entry
@SubscribeEvent
public static void triggerAdv(EntityJoinWorldEvent event)
{
if (event.getEntity() instanceof EntityPlayerMP)
{
final EntityPlayerMP player = (EntityPlayerMP)event.getEntity();
ENABLED_TRIGGER.trigger(player, player.inventory);
}
}


/**
* Far more work than expected…oh well.
*/
public static class EnabledTrigger implements ICriterionTrigger<EnabledTrigger.Instance>
{
public static final ResourceLocation ID = new ResourceLocation(MODID, "is_enabled");
private final Map<PlayerAdvancements, Listeners> listeners = new HashMap<>();

@Override
public ResourceLocation getId()
{
return ID;
}

@Override
public void addListener(PlayerAdvancements playerAdvancementsIn, Listener<Instance> listener)
{
Listeners listeners = this.listeners.computeIfAbsent(playerAdvancementsIn, Listeners::new);

listeners.add(listener);
}

@Override
public void removeListener(PlayerAdvancements playerAdvancementsIn, Listener<Instance> listener)
{
Listeners listeners = this.listeners.get(playerAdvancementsIn);

if (listeners != null)
{
listeners.remove(listener);

if (listeners.isEmpty())
{
this.listeners.remove(playerAdvancementsIn);
}
}
}

@Override
public void removeAllListeners(PlayerAdvancements playerAdvancementsIn)
{
this.listeners.remove(playerAdvancementsIn);
}

@Override
public Instance deserializeInstance(JsonObject json, JsonDeserializationContext context)
{
return new Instance();
}

public void trigger(EntityPlayerMP player, InventoryPlayer inventory)
{
Listeners listeners = this.listeners.get(player.getAdvancements());

if (listeners != null)
{
listeners.trigger(inventory);
}
}

public static class Instance extends AbstractCriterionInstance
{
public Instance()
{
super(ID);
}
}

static class Listeners
{
private final PlayerAdvancements playerAdvancements;
private final Set<Listener<Instance>> listeners = new HashSet<>();

public Listeners(PlayerAdvancements playerAdvancementsIn)
{
this.playerAdvancements = playerAdvancementsIn;
}

public boolean isEmpty()
{
return this.listeners.isEmpty();
}

public void add(ICriterionTrigger.Listener<Instance> listener)
{
this.listeners.add(listener);
}

public void remove(ICriterionTrigger.Listener<Instance> listener)
{
this.listeners.remove(listener);
}

public void trigger(InventoryPlayer inventory)
{
List<Listener<Instance>> list = null;

for (ICriterionTrigger.Listener<Instance> listener : this.listeners)
{
if (ENABLED)
{
if (list == null)
{
list = new ArrayList<>();
}

list.add(listener);
}
}

if (list != null)
{
for (ICriterionTrigger.Listener<Instance> listener1 : list)
{
listener1.grantCriterion(this.playerAdvancements);
}
}
}
}
}
}
@@ -0,0 +1,24 @@
{
"parent": "minecraft:recipes/root",
"rewards": {
"recipes": [ "minecraft:tnt" ]
},
"criteria": {
"has_wood": {
"trigger": "minecraft:inventory_changed",
"conditions": {
"items": [
{
"type": "forge:ore_dict",
"ore": "plankWood"
}
]
}
},
"mod_enabled": {
"trigger": "oredict_predicate:is_enabled",
"conditions": {}
}
},
"requirements": [["has_wood"], ["mod_enabled"]]
}

0 comments on commit ee449e4

Please sign in to comment.