Replace Achievements with Advancements

- Advancements are now in JSON files, converted by the included migration script.
- WizardryAdvancementTrigger is a generic achievement trigger that can be reused throughout the code to trigger custom advancements not covered by the JSON conditions.
- Plus some other small and obvious fixes.
This commit is contained in:
Philipp Rustemeier
2018-03-14 19:12:13 +01:00
parent 62c2a9e9b8
commit 612bbdb64d
48 changed files with 706 additions and 723 deletions
@@ -0,0 +1,80 @@
package electroblob.wizardry.util;
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.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 3.1.0
*/
public class CustomAdvancementTrigger implements ICriterionTrigger<CustomAdvancementTrigger.Instance> {
private final ResourceLocation id;
private final SetMultimap<PlayerAdvancements, Listener> 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));
}
}
}
@@ -1,7 +1,6 @@
package electroblob.wizardry.util;
import electroblob.wizardry.advancement.AdvancementHelper;
import electroblob.wizardry.advancement.AdvancementHelper.EnumAdvancement;
import electroblob.wizardry.registry.WizardryAdvancementTriggers;
import electroblob.wizardry.util.MagicDamage.DamageType;
import net.minecraft.entity.monster.EntityCreeper;
import net.minecraft.entity.player.EntityPlayer;
@@ -46,7 +45,7 @@ public interface IElementalDamage {
WizardryUtilities.chargeCreeper((EntityCreeper)event.getEntityLiving());
// Gives the player that caused the shock damage the 'It's Gonna Blow' achievement
if(event.getSource().getTrueSource() instanceof EntityPlayer){
AdvancementHelper.grantAdvancement((EntityPlayer)event.getSource().getTrueSource(), EnumAdvancement.charge_creeper);
WizardryAdvancementTriggers.charge_creeper.triggerFor((EntityPlayer)event.getSource().getTrueSource());
}
}
}