mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-12-03 17:37:59 +01:00
Add new advancements
This commit is contained in:
parent
1a3655d244
commit
77e662bb85
12 changed files with 319 additions and 38 deletions
|
@ -1,13 +1,8 @@
|
|||
package com.minelittlepony.unicopia.advancement;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
|
||||
|
@ -32,19 +27,10 @@ public class CustomEventCriterion extends AbstractCriterion<CustomEventCriterion
|
|||
|
||||
@Override
|
||||
protected Conditions conditionsFromJson(JsonObject json, LootContextPredicate playerPredicate, AdvancementEntityPredicateDeserializer deserializer) {
|
||||
|
||||
Set<Race> races = new HashSet<>();
|
||||
|
||||
if (json.has("race")) {
|
||||
json.get("race").getAsJsonArray().forEach(el -> {
|
||||
races.add(Race.fromName(el.getAsString(), Race.EARTH));
|
||||
});
|
||||
}
|
||||
|
||||
return new Conditions(
|
||||
playerPredicate,
|
||||
JsonHelper.getString(json, "event"),
|
||||
races,
|
||||
RacePredicate.fromJson(json.get("race")),
|
||||
json.has("flying") ? json.get("flying").getAsBoolean() : null,
|
||||
JsonHelper.getInt(json, "repeats", 0)
|
||||
);
|
||||
|
@ -67,13 +53,13 @@ public class CustomEventCriterion extends AbstractCriterion<CustomEventCriterion
|
|||
public static class Conditions extends AbstractCriterionConditions {
|
||||
private final String event;
|
||||
|
||||
private final Set<Race> races;
|
||||
private final RacePredicate races;
|
||||
|
||||
private final Boolean flying;
|
||||
|
||||
private final int repeatCount;
|
||||
|
||||
public Conditions(LootContextPredicate playerPredicate, String event, Set<Race> races, Boolean flying, int repeatCount) {
|
||||
public Conditions(LootContextPredicate playerPredicate, String event, RacePredicate races, Boolean flying, int repeatCount) {
|
||||
super(ID, playerPredicate);
|
||||
this.event = event;
|
||||
this.races = races;
|
||||
|
@ -83,7 +69,7 @@ public class CustomEventCriterion extends AbstractCriterion<CustomEventCriterion
|
|||
|
||||
public boolean test(String event, int count, ServerPlayerEntity player) {
|
||||
return this.event.equalsIgnoreCase(event)
|
||||
&& (races.isEmpty() || races.contains(Pony.of(player).getSpecies()))
|
||||
&& races.test(player)
|
||||
&& (flying == null || flying == Pony.of(player).getPhysics().isFlying())
|
||||
&& (repeatCount <= 0 || (count > 0 && count % repeatCount == 0));
|
||||
}
|
||||
|
@ -92,11 +78,7 @@ public class CustomEventCriterion extends AbstractCriterion<CustomEventCriterion
|
|||
public JsonObject toJson(AdvancementEntityPredicateSerializer serializer) {
|
||||
JsonObject json = super.toJson(serializer);
|
||||
json.addProperty("event", event);
|
||||
if (!races.isEmpty()) {
|
||||
JsonArray arr = new JsonArray();
|
||||
races.forEach(r -> arr.add(Race.REGISTRY.getId(r).toString()));
|
||||
json.add("race", arr);
|
||||
}
|
||||
json.add("race", races.toJson());
|
||||
if (flying != null) {
|
||||
json.addProperty("flying", flying);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
package com.minelittlepony.unicopia.advancement;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.util.JsonHelper;
|
||||
|
||||
public record RacePredicate(Set<Race> include, Set<Race> exclude) implements Predicate<ServerPlayerEntity> {
|
||||
public static final RacePredicate EMPTY = new RacePredicate(Set.of(), Set.of());
|
||||
|
||||
public static RacePredicate fromJson(JsonElement json) {
|
||||
if (json == null || json.isJsonNull()) {
|
||||
return EMPTY;
|
||||
}
|
||||
|
||||
if (json.isJsonArray()) {
|
||||
return of(getRaces(json.getAsJsonArray()), Set.of());
|
||||
}
|
||||
|
||||
JsonObject root = JsonHelper.asObject(json, "race");
|
||||
return of(getRaces(root, "include"), getRaces(root, "exclude"));
|
||||
}
|
||||
|
||||
private static RacePredicate of(Set<Race> include, Set<Race> exclude) {
|
||||
if (include.isEmpty() && exclude.isEmpty()) {
|
||||
return EMPTY;
|
||||
}
|
||||
return new RacePredicate(include, exclude);
|
||||
}
|
||||
|
||||
private static @Nullable Set<Race> getRaces(JsonObject json, String field) {
|
||||
return json.has(field) ? getRaces(JsonHelper.getArray(json, field)) : Set.of();
|
||||
}
|
||||
|
||||
private static Set<Race> getRaces(JsonArray array) {
|
||||
return array.asList()
|
||||
.stream()
|
||||
.map(el -> Race.fromName(el.getAsString(), Race.EARTH))
|
||||
.distinct()
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(ServerPlayerEntity player) {
|
||||
Race race = Pony.of(player).getSpecies();
|
||||
return (include.isEmpty() || include.contains(race)) && !(!exclude.isEmpty() && exclude.contains(race));
|
||||
}
|
||||
|
||||
public JsonObject toJson() {
|
||||
JsonObject json = new JsonObject();
|
||||
if (!include.isEmpty()) {
|
||||
JsonArray arr = new JsonArray();
|
||||
include.forEach(r -> arr.add(Race.REGISTRY.getId(r).toString()));
|
||||
json.add("include", arr);
|
||||
}
|
||||
if (!exclude.isEmpty()) {
|
||||
JsonArray arr = new JsonArray();
|
||||
exclude.forEach(r -> arr.add(Race.REGISTRY.getId(r).toString()));
|
||||
json.add("exclude", arr);
|
||||
}
|
||||
return json;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
package com.minelittlepony.unicopia.advancement;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
|
||||
import net.fabricmc.fabric.api.util.TriState;
|
||||
import net.minecraft.advancement.criterion.AbstractCriterion;
|
||||
import net.minecraft.advancement.criterion.AbstractCriterionConditions;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.predicate.entity.AdvancementEntityPredicateDeserializer;
|
||||
import net.minecraft.predicate.entity.AdvancementEntityPredicateSerializer;
|
||||
import net.minecraft.predicate.entity.LootContextPredicate;
|
||||
import net.minecraft.predicate.item.ItemPredicate;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.JsonHelper;
|
||||
import net.minecraft.util.TypeFilter;
|
||||
|
||||
public class SendViaDragonBreathScrollCriterion extends AbstractCriterion<SendViaDragonBreathScrollCriterion.Conditions> {
|
||||
private static final Identifier ID = Unicopia.id("send_dragon_breath");
|
||||
|
||||
@Override
|
||||
public Identifier getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Conditions conditionsFromJson(JsonObject json, LootContextPredicate playerPredicate, AdvancementEntityPredicateDeserializer deserializer) {
|
||||
return new Conditions(playerPredicate,
|
||||
ItemPredicate.fromJson(json.get("item")),
|
||||
JsonHelper.getBoolean(json, "is_receiving_end", false),
|
||||
json.has("recipient_name") ? Optional.of(JsonHelper.getString(json, "recipient_name")) : Optional.empty(),
|
||||
json.has("recipient_present") ? TriState.of(JsonHelper.getBoolean(json, "recipient_present")) : TriState.DEFAULT,
|
||||
json.has("counter") ? Optional.of(JsonHelper.getString(json, "counter")) : Optional.empty(),
|
||||
RacePredicate.fromJson(json.get("race"))
|
||||
);
|
||||
}
|
||||
|
||||
public void triggerSent(PlayerEntity player, ItemStack payload, String recipient, BiConsumer<String, Integer> counterCallback) {
|
||||
if (player instanceof ServerPlayerEntity spe) {
|
||||
trigger(spe, c -> {
|
||||
if (c.test(spe, payload, recipient, false)) {
|
||||
c.counter.ifPresent(counter -> {
|
||||
counterCallback.accept(counter, Pony.of(spe).getAdvancementProgress().compute(counter, (key, i) -> i == null ? 1 : i + 1));
|
||||
});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void triggerReceived(LivingEntity recipient, ItemStack payload) {
|
||||
if (recipient instanceof ServerPlayerEntity spe) {
|
||||
trigger(spe, c -> c.test(spe, payload, recipient.getDisplayName().getString(), true));
|
||||
}
|
||||
}
|
||||
|
||||
public static class Conditions extends AbstractCriterionConditions {
|
||||
private final ItemPredicate item;
|
||||
private final boolean isReceivingEnd;
|
||||
private final Optional<String> recipientName;
|
||||
private final TriState recipientPresent;
|
||||
private final Optional<String> counter;
|
||||
private final RacePredicate races;
|
||||
|
||||
public Conditions(LootContextPredicate playerPredicate, ItemPredicate item, boolean isReceivingEnd, Optional<String> recipient, TriState recipientPresent, Optional<String> counter, RacePredicate races) {
|
||||
super(ID, playerPredicate);
|
||||
this.item = item;
|
||||
this.isReceivingEnd = isReceivingEnd;
|
||||
this.recipientName = recipient;
|
||||
this.recipientPresent = recipientPresent;
|
||||
this.counter = counter;
|
||||
this.races = races;
|
||||
}
|
||||
|
||||
public boolean test(ServerPlayerEntity player, ItemStack payload, String recipient, boolean receiving) {
|
||||
return isReceivingEnd == receiving
|
||||
&& races.test(player)
|
||||
&& item.test(payload)
|
||||
&& recipientName.map(expectedRecipientname -> recipient.equalsIgnoreCase(expectedRecipientname)).orElse(true)
|
||||
&& (recipientPresent == TriState.DEFAULT || isRecipientAbsent(player.getServerWorld(), recipient) != recipientPresent.get());
|
||||
}
|
||||
|
||||
private boolean isRecipientAbsent(ServerWorld world, String recipient) {
|
||||
return world.getEntitiesByType(TypeFilter.instanceOf(LivingEntity.class), e -> e.hasCustomName() && e.getCustomName().getString().equalsIgnoreCase(recipient)).isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject toJson(AdvancementEntityPredicateSerializer serializer) {
|
||||
JsonObject json = super.toJson(serializer);
|
||||
json.add("item", item.toJson());
|
||||
json.add("race", races.toJson());
|
||||
recipientName.ifPresent(recipient -> json.addProperty("recipient_name", recipient));
|
||||
if (recipientPresent != TriState.DEFAULT) {
|
||||
json.addProperty("recipient_present", recipientPresent.getBoxed());
|
||||
}
|
||||
counter.ifPresent(counter -> json.addProperty("counter", counter));
|
||||
return json;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ import net.minecraft.advancement.criterion.Criteria;
|
|||
public interface UCriteria {
|
||||
CustomEventCriterion CUSTOM_EVENT = Criteria.register(new CustomEventCriterion());
|
||||
RaceChangeCriterion PLAYER_CHANGE_RACE = Criteria.register(new RaceChangeCriterion());
|
||||
SendViaDragonBreathScrollCriterion SEND_DRAGON_BREATH = Criteria.register(new SendViaDragonBreathScrollCriterion());
|
||||
|
||||
CustomEventCriterion.Trigger LOOK_INTO_SUN = CUSTOM_EVENT.createTrigger("look_into_sun");
|
||||
CustomEventCriterion.Trigger WEAR_SHADES = CUSTOM_EVENT.createTrigger("wear_shades");
|
||||
|
@ -16,8 +17,6 @@ public interface UCriteria {
|
|||
CustomEventCriterion.Trigger SPOOK_MOB = CUSTOM_EVENT.createTrigger("spook_mob");
|
||||
CustomEventCriterion.Trigger SHED_FEATHER = CUSTOM_EVENT.createTrigger("shed_feather");
|
||||
CustomEventCriterion.Trigger THROW_MUFFIN = CUSTOM_EVENT.createTrigger("throw_muffin");
|
||||
CustomEventCriterion.Trigger SEND_OATS = CUSTOM_EVENT.createTrigger("send_oats");
|
||||
CustomEventCriterion.Trigger RECEIVE_OATS = CUSTOM_EVENT.createTrigger("receive_oats");
|
||||
CustomEventCriterion.Trigger BREAK_WINDOW = CUSTOM_EVENT.createTrigger("break_window");
|
||||
CustomEventCriterion.Trigger KILL_PHANTOM_WHILE_FLYING = CUSTOM_EVENT.createTrigger("kill_phantom_while_flying");
|
||||
CustomEventCriterion.Trigger USE_CONSUMPTION = CUSTOM_EVENT.createTrigger("use_consumption");
|
||||
|
|
|
@ -447,10 +447,7 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
|
|||
itemEntity.setPosition(randomPos);
|
||||
itemEntity.getWorld().spawnEntity(itemEntity);
|
||||
entity.getWorld().playSoundFromEntity(null, entity, USounds.ITEM_DRAGON_BREATH_ARRIVE, entity.getSoundCategory(), 1, 1);
|
||||
|
||||
if (item == UItems.OATS && entity instanceof PlayerEntity player) {
|
||||
UCriteria.RECEIVE_OATS.trigger(player);
|
||||
}
|
||||
UCriteria.SEND_DRAGON_BREATH.triggerReceived(entity, payload.copy());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -5,10 +5,12 @@ import java.util.UUID;
|
|||
import com.minelittlepony.unicopia.USounds;
|
||||
import com.minelittlepony.unicopia.advancement.UCriteria;
|
||||
import com.minelittlepony.unicopia.server.world.DragonBreathStore;
|
||||
import com.minelittlepony.unicopia.server.world.UnicopiaWorldProperties;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.TypedActionResult;
|
||||
import net.minecraft.world.World;
|
||||
|
@ -30,10 +32,15 @@ public class DragonBreathScrollItem extends Item {
|
|||
|
||||
stack.split(1);
|
||||
if (!world.isClient) {
|
||||
if (payload.getItem() == UItems.OATS) {
|
||||
UCriteria.SEND_OATS.trigger(player);
|
||||
}
|
||||
DragonBreathStore.get(world).put(stack.getName().getString(), payload.split(1));
|
||||
String recipient = stack.getName().getString();
|
||||
UCriteria.SEND_DRAGON_BREATH.triggerSent(player, payload, recipient, (counterName, count) -> {
|
||||
if (count == 1 && "dings_on_celestias_head".equals(counterName)) {
|
||||
UnicopiaWorldProperties properties = UnicopiaWorldProperties.forWorld((ServerWorld)world);
|
||||
properties.setTangentalSkyAngle(properties.getTangentalSkyAngle() + 15);
|
||||
player.playSound(USounds.Vanilla.BLOCK_ANVIL_HIT, 0.3F, 1);
|
||||
}
|
||||
});
|
||||
DragonBreathStore.get(world).put(recipient, payload.split(1));
|
||||
}
|
||||
player.playSound(USounds.ITEM_DRAGON_BREATH_SCROLL_USE, 1, 1);
|
||||
return TypedActionResult.consume(stack);
|
||||
|
|
|
@ -892,6 +892,11 @@
|
|||
"advancements.unicopia.extra_spooky.title": "Extra Spooky",
|
||||
"advancements.unicopia.extra_spooky.description": "Spook a mob so hard it drops a brick",
|
||||
|
||||
"advancements.unicopia.sweet_sweet_revenge.title": "Sweet Sweet Revenge",
|
||||
"advancements.unicopia.sweet_sweet_revenge.description": "Get Celestia back for burning your eyes",
|
||||
"advancements.unicopia.blasphemy.title": "Blasphemy!",
|
||||
"advancements.unicopia.blasphemy.description": "Ding Celestia on the noggin. Oops!",
|
||||
|
||||
"advancements.unicopia.earth_route.title": "Path of the Pony",
|
||||
"advancements.unicopia.earth_route.description": "Join the Apple Clan",
|
||||
"advancements.unicopia.sticks_and_stones.title": "Sticks and Stones",
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"parent": "minecraft:recipes/root",
|
||||
"rewards": {
|
||||
"recipes": [
|
||||
"unicopia:pineapple_crown"
|
||||
]
|
||||
},
|
||||
"criteria": {
|
||||
"has_ingredients": {
|
||||
"trigger": "minecraft:inventory_changed",
|
||||
"conditions": {
|
||||
"items": [
|
||||
{ "items": [ "unicopia:pineapple" ] }
|
||||
]
|
||||
}
|
||||
},
|
||||
"has_the_recipe": {
|
||||
"trigger": "minecraft:recipe_unlocked",
|
||||
"conditions": {
|
||||
"recipe": "unicopia:pineapple_crown"
|
||||
}
|
||||
}
|
||||
},
|
||||
"requirements": [
|
||||
[
|
||||
"has_ingredients",
|
||||
"has_the_recipe"
|
||||
]
|
||||
]
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
"parent": "unicopia:unicopia/bat/praise_the_sun",
|
||||
"display": {
|
||||
"icon": {
|
||||
"item": "minecraft:anvil"
|
||||
},
|
||||
"title": {
|
||||
"translate": "advancements.unicopia.sweet_sweet_revenge.title"
|
||||
},
|
||||
"description": {
|
||||
"translate": "advancements.unicopia.sweet_sweet_revenge.description"
|
||||
},
|
||||
"frame": "task",
|
||||
"show_toast": true,
|
||||
"announce_to_chat": true,
|
||||
"hidden": true
|
||||
},
|
||||
"criteria": {
|
||||
"ding_sun": {
|
||||
"trigger": "unicopia:send_dragon_breath",
|
||||
"conditions": {
|
||||
"item": {
|
||||
"tag": "unicopia:is_delivered_aggressively"
|
||||
},
|
||||
"recipient_name": "princess celestia",
|
||||
"recipient_present": false,
|
||||
"counter": "dings_on_celestias_head",
|
||||
"race": {
|
||||
"include": [ "unicopia:bat" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"requirements": [
|
||||
[ "ding_sun" ]
|
||||
]
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
"parent": "unicopia:unicopia/earth/earth_route",
|
||||
"display": {
|
||||
"icon": {
|
||||
"item": "minecraft:anvil"
|
||||
},
|
||||
"title": {
|
||||
"translate": "advancements.unicopia.blasphemy.title"
|
||||
},
|
||||
"description": {
|
||||
"translate": "advancements.unicopia.blasphemy.description"
|
||||
},
|
||||
"frame": "task",
|
||||
"show_toast": true,
|
||||
"announce_to_chat": true,
|
||||
"hidden": true
|
||||
},
|
||||
"criteria": {
|
||||
"ding_sun": {
|
||||
"trigger": "unicopia:send_dragon_breath",
|
||||
"conditions": {
|
||||
"item": {
|
||||
"tag": "unicopia:is_delivered_aggressively"
|
||||
},
|
||||
"recipient_name": "princess celestia",
|
||||
"recipient_present": false,
|
||||
"counter": "dings_on_celestias_head",
|
||||
"race": {
|
||||
"exclude": [ "unicopia:bat" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"requirements": [
|
||||
[ "ding_sun" ]
|
||||
]
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"parent": "unicopia:unicopia/root/earth/earth_route",
|
||||
"parent": "unicopia:unicopia/earth/earth_route",
|
||||
"display": {
|
||||
"icon": {
|
||||
"item": "unicopia:pinecone"
|
|
@ -17,15 +17,20 @@
|
|||
},
|
||||
"criteria": {
|
||||
"send_oats": {
|
||||
"trigger": "unicopia:custom",
|
||||
"trigger": "unicopia:send_dragon_breath",
|
||||
"conditions": {
|
||||
"event": "send_oats"
|
||||
"item": {
|
||||
"items": [ "unicopia:oats", "unicopia:imported_oats" ]
|
||||
}
|
||||
}
|
||||
},
|
||||
"receive_oats": {
|
||||
"trigger": "unicopia:custom",
|
||||
"trigger": "unicopia:send_dragon_breath",
|
||||
"conditions": {
|
||||
"event": "receive_oats"
|
||||
"item": {
|
||||
"items": [ "unicopia:oats", "unicopia:imported_oats" ]
|
||||
},
|
||||
"is_receiving_end": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue