That's one heck of a commit you've got there...
I may have got a bit behind with version control. A lot behind, in fact. Maybe I'll go back and split this sometime - then again, I probably won't. But hey, at least it's here!
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
package electroblob.wizardry.advancement;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.advancements.ICriterionTrigger;
|
||||
import net.minecraft.advancements.PlayerAdvancements;
|
||||
import net.minecraft.advancements.critereon.AbstractCriterionInstance;
|
||||
import net.minecraft.advancements.critereon.ItemPredicate;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/** Advancement trigger for things done in the arcane workbench. The majority of any
|
||||
* ICriterionTrigger class is just boilerplate, and this is no exception. */
|
||||
public class ArcaneWorkbenchTrigger implements ICriterionTrigger<ArcaneWorkbenchTrigger.Instance> {
|
||||
|
||||
private final ResourceLocation id;
|
||||
private final Map<PlayerAdvancements, ArcaneWorkbenchTrigger.Listeners> listeners = Maps.newHashMap();
|
||||
|
||||
public ArcaneWorkbenchTrigger(ResourceLocation id){
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public ResourceLocation getId(){
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void addListener(PlayerAdvancements advancements, Listener<ArcaneWorkbenchTrigger.Instance> listener){
|
||||
|
||||
ArcaneWorkbenchTrigger.Listeners listeners = this.listeners.get(advancements);
|
||||
|
||||
if(listeners == null){
|
||||
listeners = new ArcaneWorkbenchTrigger.Listeners(advancements);
|
||||
this.listeners.put(advancements, listeners);
|
||||
}
|
||||
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
public void removeListener(PlayerAdvancements advancements, Listener<ArcaneWorkbenchTrigger.Instance> listener){
|
||||
|
||||
ArcaneWorkbenchTrigger.Listeners listeners = this.listeners.get(advancements);
|
||||
|
||||
if(listeners != null){
|
||||
listeners.remove(listener);
|
||||
|
||||
if(listeners.isEmpty()){
|
||||
this.listeners.remove(advancements);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void removeAllListeners(PlayerAdvancements advancements){
|
||||
this.listeners.remove(advancements);
|
||||
}
|
||||
|
||||
public ArcaneWorkbenchTrigger.Instance deserializeInstance(JsonObject json, JsonDeserializationContext context){
|
||||
return new ArcaneWorkbenchTrigger.Instance(this.id, ItemPredicate.deserialize(json.get("item")));
|
||||
}
|
||||
|
||||
public void trigger(EntityPlayerMP player, ItemStack stack){
|
||||
|
||||
ArcaneWorkbenchTrigger.Listeners listeners = this.listeners.get(player.getAdvancements());
|
||||
|
||||
if(listeners != null){
|
||||
listeners.trigger(stack);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Instance extends AbstractCriterionInstance {
|
||||
|
||||
private final ItemPredicate item;
|
||||
|
||||
public Instance(ResourceLocation criterionIn, ItemPredicate item){
|
||||
super(criterionIn);
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
public boolean test(ItemStack stack){
|
||||
return this.item.test(stack);
|
||||
}
|
||||
}
|
||||
|
||||
static class Listeners {
|
||||
|
||||
private final PlayerAdvancements playerAdvancements;
|
||||
private final Set<Listener<ArcaneWorkbenchTrigger.Instance>> listeners = Sets.newHashSet();
|
||||
|
||||
public Listeners(PlayerAdvancements advancements){
|
||||
this.playerAdvancements = advancements;
|
||||
}
|
||||
|
||||
public boolean isEmpty(){
|
||||
return this.listeners.isEmpty();
|
||||
}
|
||||
|
||||
public void add(Listener<ArcaneWorkbenchTrigger.Instance> listener){
|
||||
this.listeners.add(listener);
|
||||
}
|
||||
|
||||
public void remove(Listener<ArcaneWorkbenchTrigger.Instance> listener){
|
||||
this.listeners.remove(listener);
|
||||
}
|
||||
|
||||
public void trigger(ItemStack stack){
|
||||
|
||||
List<Listener<ArcaneWorkbenchTrigger.Instance>> list = null;
|
||||
|
||||
for(Listener<ArcaneWorkbenchTrigger.Instance> listener : this.listeners){
|
||||
|
||||
if(listener.getCriterionInstance().test(stack)){
|
||||
|
||||
if(list == null){
|
||||
list = Lists.newArrayList();
|
||||
}
|
||||
|
||||
list.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
if(list != null){
|
||||
for(Listener<ArcaneWorkbenchTrigger.Instance> listener : list){
|
||||
listener.grantCriterion(this.playerAdvancements);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package electroblob.wizardry.advancement;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.SetMultimap;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonObject;
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import net.minecraft.advancements.ICriterionInstance;
|
||||
import net.minecraft.advancements.ICriterionTrigger;
|
||||
import net.minecraft.advancements.PlayerAdvancements;
|
||||
import net.minecraft.advancements.critereon.AbstractCriterionInstance;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
/**
|
||||
* This class implements a generic custom advancement trigger that can be fired from any point in
|
||||
* the code. This replaces the achievement system in instances where the JSON advancement descriptions
|
||||
* cannot properly capture the advancement-worthy events. Where possible, advancement conditions
|
||||
* should be triggered by JSON descriptions and vanilla advancement triggers.
|
||||
*
|
||||
* @author 12foo
|
||||
* @since 4.1.0
|
||||
*/
|
||||
public class CustomAdvancementTrigger implements ICriterionTrigger<CustomAdvancementTrigger.Instance> {
|
||||
|
||||
private final ResourceLocation id;
|
||||
private final SetMultimap<PlayerAdvancements, Listener<? extends ICriterionInstance>> listeners = HashMultimap.create();
|
||||
|
||||
/**
|
||||
* This is a dummy criterion instance that does nothing on its own (but it is bound to this
|
||||
* trigger, and via listeners to the player). We later fire this manually when we want the
|
||||
* advancement to happen.
|
||||
*/
|
||||
public static class Instance extends AbstractCriterionInstance {
|
||||
public Instance(ResourceLocation triggerId) {
|
||||
super(triggerId);
|
||||
}
|
||||
}
|
||||
|
||||
public CustomAdvancementTrigger(String name) {
|
||||
super();
|
||||
id = new ResourceLocation(Wizardry.MODID, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(PlayerAdvancements playerAdvancementsIn, Listener<Instance> listener) {
|
||||
listeners.put(playerAdvancementsIn, listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(PlayerAdvancements playerAdvancementsIn, Listener<Instance> listener) {
|
||||
listeners.remove(playerAdvancementsIn, listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAllListeners(PlayerAdvancements playerAdvancementsIn) {
|
||||
listeners.removeAll(playerAdvancementsIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instance deserializeInstance(JsonObject json, JsonDeserializationContext context) {
|
||||
// Every time a trigger with this name is deserialized from the JSON, we just return a new
|
||||
// dummy criterion instance.
|
||||
return new CustomAdvancementTrigger.Instance(id);
|
||||
}
|
||||
|
||||
public void triggerFor(EntityPlayer player) {
|
||||
// Fire our dummy criterion manually on all advancements of the player, thereby granting
|
||||
// the ones that match it.
|
||||
if (player instanceof EntityPlayerMP) {
|
||||
final PlayerAdvancements advances = ((EntityPlayerMP) player).getAdvancements();
|
||||
listeners.get(advances).forEach((listener) -> listener.grantCriterion(advances));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
package electroblob.wizardry.advancement;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonObject;
|
||||
import electroblob.wizardry.spell.Spell;
|
||||
import net.minecraft.advancements.ICriterionTrigger;
|
||||
import net.minecraft.advancements.PlayerAdvancements;
|
||||
import net.minecraft.advancements.critereon.AbstractCriterionInstance;
|
||||
import net.minecraft.advancements.critereon.ItemPredicate;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/** Advancement trigger which is triggered when a spell is cast. The majority of any
|
||||
* ICriterionTrigger class is just boilerplate, and this is no exception. */
|
||||
public class SpellCastTrigger implements ICriterionTrigger<SpellCastTrigger.Instance> {
|
||||
|
||||
private final ResourceLocation id;
|
||||
private final Map<PlayerAdvancements, SpellCastTrigger.Listeners> listeners = Maps.newHashMap();
|
||||
|
||||
public SpellCastTrigger(ResourceLocation id){
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public ResourceLocation getId(){
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void addListener(PlayerAdvancements advancements, Listener<SpellCastTrigger.Instance> listener){
|
||||
|
||||
SpellCastTrigger.Listeners listeners = this.listeners.get(advancements);
|
||||
|
||||
if(listeners == null){
|
||||
listeners = new SpellCastTrigger.Listeners(advancements);
|
||||
this.listeners.put(advancements, listeners);
|
||||
}
|
||||
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
public void removeListener(PlayerAdvancements advancements, Listener<SpellCastTrigger.Instance> listener){
|
||||
|
||||
SpellCastTrigger.Listeners listeners = this.listeners.get(advancements);
|
||||
|
||||
if(listeners != null){
|
||||
listeners.remove(listener);
|
||||
|
||||
if(listeners.isEmpty()){
|
||||
this.listeners.remove(advancements);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void removeAllListeners(PlayerAdvancements advancements){
|
||||
this.listeners.remove(advancements);
|
||||
}
|
||||
|
||||
public SpellCastTrigger.Instance deserializeInstance(JsonObject json, JsonDeserializationContext context){
|
||||
return new SpellCastTrigger.Instance(this.id, SpellPredicate.deserialize(json.get("spell")),
|
||||
ItemPredicate.deserialize(json.get("item")));
|
||||
}
|
||||
|
||||
public void trigger(EntityPlayerMP player, Spell spell, ItemStack stack){
|
||||
|
||||
SpellCastTrigger.Listeners listeners = this.listeners.get(player.getAdvancements());
|
||||
|
||||
if(listeners != null){
|
||||
listeners.trigger(spell, stack);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Instance extends AbstractCriterionInstance {
|
||||
|
||||
private final SpellPredicate spell;
|
||||
private final ItemPredicate item;
|
||||
|
||||
public Instance(ResourceLocation criterion, SpellPredicate spell, ItemPredicate item){
|
||||
super(criterion);
|
||||
this.spell = spell;
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
public boolean test(Spell spell, ItemStack stack){
|
||||
return this.spell.test(spell) && item.test(stack);
|
||||
}
|
||||
}
|
||||
|
||||
static class Listeners {
|
||||
|
||||
private final PlayerAdvancements playerAdvancements;
|
||||
private final Set<Listener<SpellCastTrigger.Instance>> listeners = Sets.newHashSet();
|
||||
|
||||
public Listeners(PlayerAdvancements advancements){
|
||||
this.playerAdvancements = advancements;
|
||||
}
|
||||
|
||||
public boolean isEmpty(){
|
||||
return this.listeners.isEmpty();
|
||||
}
|
||||
|
||||
public void add(Listener<SpellCastTrigger.Instance> listener){
|
||||
this.listeners.add(listener);
|
||||
}
|
||||
|
||||
public void remove(Listener<SpellCastTrigger.Instance> listener){
|
||||
this.listeners.remove(listener);
|
||||
}
|
||||
|
||||
public void trigger(Spell spell, ItemStack stack){
|
||||
|
||||
List<Listener<SpellCastTrigger.Instance>> list = null;
|
||||
|
||||
for(Listener<SpellCastTrigger.Instance> listener : this.listeners){
|
||||
|
||||
if(listener.getCriterionInstance().test(spell, stack)){
|
||||
|
||||
if(list == null){
|
||||
list = Lists.newArrayList();
|
||||
}
|
||||
|
||||
list.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
if(list != null){
|
||||
for(Listener<SpellCastTrigger.Instance> listener : list){
|
||||
listener.grantCriterion(this.playerAdvancements);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
package electroblob.wizardry.advancement;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import electroblob.wizardry.event.DiscoverSpellEvent;
|
||||
import electroblob.wizardry.spell.Spell;
|
||||
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.util.JsonUtils;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/** Advancement trigger that is triggered when a spell is discovered. The majority of any
|
||||
* ICriterionTrigger class is just boilerplate, and this is no exception. */
|
||||
public class SpellDiscoveryTrigger implements ICriterionTrigger<SpellDiscoveryTrigger.Instance> {
|
||||
|
||||
private final ResourceLocation id;
|
||||
private final Map<PlayerAdvancements, SpellDiscoveryTrigger.Listeners> listeners = Maps.newHashMap();
|
||||
|
||||
public SpellDiscoveryTrigger(ResourceLocation id){
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public ResourceLocation getId(){
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void addListener(PlayerAdvancements advancements, Listener<SpellDiscoveryTrigger.Instance> listener){
|
||||
|
||||
SpellDiscoveryTrigger.Listeners listeners = this.listeners.get(advancements);
|
||||
|
||||
if(listeners == null){
|
||||
listeners = new SpellDiscoveryTrigger.Listeners(advancements);
|
||||
this.listeners.put(advancements, listeners);
|
||||
}
|
||||
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
public void removeListener(PlayerAdvancements advancements, Listener<SpellDiscoveryTrigger.Instance> listener){
|
||||
|
||||
SpellDiscoveryTrigger.Listeners listeners = this.listeners.get(advancements);
|
||||
|
||||
if(listeners != null){
|
||||
listeners.remove(listener);
|
||||
|
||||
if(listeners.isEmpty()){
|
||||
this.listeners.remove(advancements);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void removeAllListeners(PlayerAdvancements advancements){
|
||||
this.listeners.remove(advancements);
|
||||
}
|
||||
|
||||
public SpellDiscoveryTrigger.Instance deserializeInstance(JsonObject json, JsonDeserializationContext context){
|
||||
|
||||
String s = JsonUtils.getString(json, "source");
|
||||
DiscoverSpellEvent.Source source = DiscoverSpellEvent.Source.byName(s);
|
||||
if(source == null) throw new JsonSyntaxException("No such spell discovery source: " + s);
|
||||
return new SpellDiscoveryTrigger.Instance(this.id, SpellPredicate.deserialize(json.get("spell")), source);
|
||||
}
|
||||
|
||||
public void trigger(EntityPlayerMP player, Spell spell, DiscoverSpellEvent.Source source){
|
||||
|
||||
SpellDiscoveryTrigger.Listeners listeners = this.listeners.get(player.getAdvancements());
|
||||
|
||||
if(listeners != null){
|
||||
listeners.trigger(spell, source);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Instance extends AbstractCriterionInstance {
|
||||
|
||||
private final SpellPredicate spell;
|
||||
private final DiscoverSpellEvent.Source source;
|
||||
|
||||
public Instance(ResourceLocation criterion, SpellPredicate spell, DiscoverSpellEvent.Source source){
|
||||
super(criterion);
|
||||
this.spell = spell;
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public boolean test(Spell spell, DiscoverSpellEvent.Source source){
|
||||
return this.spell.test(spell) && source == this.source;
|
||||
}
|
||||
}
|
||||
|
||||
static class Listeners {
|
||||
|
||||
private final PlayerAdvancements playerAdvancements;
|
||||
private final Set<Listener<SpellDiscoveryTrigger.Instance>> listeners = Sets.newHashSet();
|
||||
|
||||
public Listeners(PlayerAdvancements advancements){
|
||||
this.playerAdvancements = advancements;
|
||||
}
|
||||
|
||||
public boolean isEmpty(){
|
||||
return this.listeners.isEmpty();
|
||||
}
|
||||
|
||||
public void add(Listener<SpellDiscoveryTrigger.Instance> listener){
|
||||
this.listeners.add(listener);
|
||||
}
|
||||
|
||||
public void remove(Listener<SpellDiscoveryTrigger.Instance> listener){
|
||||
this.listeners.remove(listener);
|
||||
}
|
||||
|
||||
public void trigger(Spell spell, DiscoverSpellEvent.Source source){
|
||||
|
||||
List<Listener<SpellDiscoveryTrigger.Instance>> list = null;
|
||||
|
||||
for(Listener<SpellDiscoveryTrigger.Instance> listener : this.listeners){
|
||||
|
||||
if(listener.getCriterionInstance().test(spell, source)){
|
||||
|
||||
if(list == null){
|
||||
list = Lists.newArrayList();
|
||||
}
|
||||
|
||||
list.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
if(list != null){
|
||||
for(Listener<SpellDiscoveryTrigger.Instance> listener : list){
|
||||
listener.grantCriterion(this.playerAdvancements);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package electroblob.wizardry.advancement;
|
||||
|
||||
import com.google.common.collect.Streams;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import electroblob.wizardry.constants.Element;
|
||||
import electroblob.wizardry.constants.Tier;
|
||||
import electroblob.wizardry.spell.Spell;
|
||||
import net.minecraft.util.JsonUtils;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Arrays;
|
||||
|
||||
/** Predicate used by advancement triggers to match spells. */
|
||||
public class SpellPredicate {
|
||||
|
||||
public static final SpellPredicate ANY = new SpellPredicate();
|
||||
private final Spell spell;
|
||||
private final Tier[] tiers;
|
||||
private final Element[] elements;
|
||||
|
||||
public SpellPredicate(){
|
||||
this.spell = null;
|
||||
this.tiers = Tier.values();
|
||||
this.elements = Element.values();
|
||||
}
|
||||
|
||||
public SpellPredicate(@Nullable Spell spell, Tier[] tiers, Element[] elements){
|
||||
this.spell = spell;
|
||||
this.tiers = tiers;
|
||||
this.elements = elements;
|
||||
}
|
||||
|
||||
public boolean test(Spell spell){
|
||||
|
||||
if(this.spell != null && spell != this.spell){
|
||||
return false;
|
||||
}else if(!Arrays.asList(this.tiers).contains(spell.getTier())){
|
||||
return false;
|
||||
}else if(!Arrays.asList(this.elements).contains(spell.getElement())){
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static SpellPredicate deserialize(@Nullable JsonElement element){
|
||||
|
||||
if(element != null && !element.isJsonNull()){
|
||||
|
||||
JsonObject jsonobject = JsonUtils.getJsonObject(element, "spell");
|
||||
|
||||
Spell spell = null;
|
||||
|
||||
if(jsonobject.has("spell")){
|
||||
|
||||
String s = JsonUtils.getString(jsonobject, "spell");
|
||||
spell = Spell.get(s);
|
||||
|
||||
if(spell == null){
|
||||
throw new JsonSyntaxException("Unknown spell id '" + s + "'");
|
||||
}
|
||||
}
|
||||
|
||||
Tier[] tiers = Tier.values();
|
||||
|
||||
if(jsonobject.has("tiers")){
|
||||
try{
|
||||
JsonArray array = JsonUtils.getJsonArray(jsonobject, "tiers");
|
||||
tiers = Streams.stream(array)
|
||||
.map(je -> Tier.fromName(JsonUtils.getString(je, "element of array tiers")))
|
||||
.toArray(Tier[]::new);
|
||||
}catch(IllegalArgumentException e){
|
||||
throw new JsonSyntaxException("Incorrect spell predicate value", e);
|
||||
}
|
||||
}
|
||||
|
||||
Element[] elements = Element.values();
|
||||
|
||||
if(jsonobject.has("elements")){
|
||||
try{
|
||||
JsonArray array = JsonUtils.getJsonArray(jsonobject, "elements");
|
||||
elements = Streams.stream(array)
|
||||
.map(je -> Element.fromName(JsonUtils.getString(je, "element of array elements")))
|
||||
.toArray(Element[]::new);
|
||||
}catch(IllegalArgumentException e){
|
||||
throw new JsonSyntaxException("Incorrect spell predicate value", e);
|
||||
}
|
||||
}
|
||||
|
||||
return new SpellPredicate(spell, tiers, elements);
|
||||
|
||||
}else{
|
||||
return ANY;
|
||||
}
|
||||
}
|
||||
|
||||
public static SpellPredicate[] deserializeArray(@Nullable JsonElement element){
|
||||
|
||||
if(element != null && !element.isJsonNull()){
|
||||
|
||||
JsonArray jsonarray = JsonUtils.getJsonArray(element, "spells");
|
||||
SpellPredicate[] predicates = new SpellPredicate[jsonarray.size()];
|
||||
|
||||
for(int i = 0; i < predicates.length; ++i){
|
||||
predicates[i] = deserialize(jsonarray.get(i));
|
||||
}
|
||||
|
||||
return predicates;
|
||||
|
||||
}else{
|
||||
return new SpellPredicate[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
package electroblob.wizardry.advancement;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonObject;
|
||||
import electroblob.wizardry.worldgen.WorldGenSurfaceStructure;
|
||||
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.util.JsonUtils;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.world.WorldServer;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/** Copied from PositionTrigger and modified to work with wizardry's structures. The majority of any
|
||||
* ICriterionTrigger class is just boilerplate, and this is no exception. */
|
||||
public class StructureTrigger implements ICriterionTrigger<StructureTrigger.Instance> {
|
||||
|
||||
private final ResourceLocation id;
|
||||
private final Map<PlayerAdvancements, StructureTrigger.Listeners> listeners = Maps.newHashMap();
|
||||
|
||||
public StructureTrigger(ResourceLocation id){
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public ResourceLocation getId(){
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void addListener(PlayerAdvancements advancements, Listener<StructureTrigger.Instance> listener){
|
||||
|
||||
StructureTrigger.Listeners listeners = this.listeners.get(advancements);
|
||||
|
||||
if(listeners == null){
|
||||
listeners = new StructureTrigger.Listeners(advancements);
|
||||
this.listeners.put(advancements, listeners);
|
||||
}
|
||||
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
public void removeListener(PlayerAdvancements advancements, Listener<StructureTrigger.Instance> listener){
|
||||
|
||||
StructureTrigger.Listeners listeners = this.listeners.get(advancements);
|
||||
|
||||
if(listeners != null){
|
||||
listeners.remove(listener);
|
||||
|
||||
if(listeners.isEmpty()){
|
||||
this.listeners.remove(advancements);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void removeAllListeners(PlayerAdvancements advancements){
|
||||
this.listeners.remove(advancements);
|
||||
}
|
||||
|
||||
public StructureTrigger.Instance deserializeInstance(JsonObject json, JsonDeserializationContext context){
|
||||
return new StructureTrigger.Instance(this.id, JsonUtils.getString(json, "structure_type"));
|
||||
}
|
||||
|
||||
public void trigger(EntityPlayerMP player){
|
||||
|
||||
StructureTrigger.Listeners listeners = this.listeners.get(player.getAdvancements());
|
||||
|
||||
if(listeners != null){
|
||||
listeners.trigger(player.getServerWorld(), player.posX, player.posY, player.posZ);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Instance extends AbstractCriterionInstance {
|
||||
|
||||
private final WorldGenSurfaceStructure structureType;
|
||||
|
||||
public Instance(ResourceLocation criterionIn, String name){
|
||||
super(criterionIn);
|
||||
this.structureType = WorldGenSurfaceStructure.byName(name);
|
||||
}
|
||||
|
||||
public boolean test(WorldServer world, double x, double y, double z){
|
||||
return structureType.isInsideStructure(world, x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
static class Listeners {
|
||||
|
||||
private final PlayerAdvancements playerAdvancements;
|
||||
private final Set<Listener<StructureTrigger.Instance>> listeners = Sets.newHashSet();
|
||||
|
||||
public Listeners(PlayerAdvancements advancements){
|
||||
this.playerAdvancements = advancements;
|
||||
}
|
||||
|
||||
public boolean isEmpty(){
|
||||
return this.listeners.isEmpty();
|
||||
}
|
||||
|
||||
public void add(Listener<StructureTrigger.Instance> listener){
|
||||
this.listeners.add(listener);
|
||||
}
|
||||
|
||||
public void remove(Listener<StructureTrigger.Instance> listener){
|
||||
this.listeners.remove(listener);
|
||||
}
|
||||
|
||||
public void trigger(WorldServer world, double x, double y, double z){
|
||||
|
||||
List<Listener<StructureTrigger.Instance>> list = null;
|
||||
|
||||
for(Listener<StructureTrigger.Instance> listener : this.listeners){
|
||||
|
||||
if(listener.getCriterionInstance().test(world, x, y, z)){
|
||||
|
||||
if(list == null){
|
||||
list = Lists.newArrayList();
|
||||
}
|
||||
|
||||
list.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
if(list != null){
|
||||
for(Listener<StructureTrigger.Instance> listener : list){
|
||||
listener.grantCriterion(this.playerAdvancements);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user