finish logic for entity ingrs

This commit is contained in:
petrak@ 2022-12-28 14:11:28 -05:00
parent 2acf7920b5
commit c3ebba18f0
14 changed files with 797 additions and 696 deletions

View file

@ -8,7 +8,7 @@ import at.petrak.hexcasting.api.utils.TAU
import at.petrak.hexcasting.api.utils.getValue import at.petrak.hexcasting.api.utils.getValue
import at.petrak.hexcasting.api.utils.setValue import at.petrak.hexcasting.api.utils.setValue
import at.petrak.hexcasting.api.utils.weakMapped import at.petrak.hexcasting.api.utils.weakMapped
import at.petrak.hexcasting.common.recipe.ingredient.brainsweep.BrainsweepIngredient import at.petrak.hexcasting.common.recipe.ingredient.brainsweep.BrainsweepeeIngredient
import com.mojang.blaze3d.systems.RenderSystem import com.mojang.blaze3d.systems.RenderSystem
import com.mojang.blaze3d.vertex.DefaultVertexFormat import com.mojang.blaze3d.vertex.DefaultVertexFormat
import com.mojang.blaze3d.vertex.PoseStack import com.mojang.blaze3d.vertex.PoseStack
@ -422,7 +422,7 @@ fun transferMsToGl(ms: PoseStack, toRun: Runnable) {
private var villager: Villager? by weakMapped(Villager::level) private var villager: Villager? by weakMapped(Villager::level)
fun prepareVillagerForRendering(ingredient: BrainsweepIngredient, level: Level): Villager { fun prepareVillagerForRendering(ingredient: BrainsweepeeIngredient, level: Level): Villager {
throw NotImplementedError() throw NotImplementedError()
/* /*
val minLevel: Int = ingredient.minLevel() val minLevel: Int = ingredient.minLevel()

View file

@ -2,7 +2,7 @@ package at.petrak.hexcasting.common.recipe;
import at.petrak.hexcasting.common.recipe.ingredient.StateIngredient; import at.petrak.hexcasting.common.recipe.ingredient.StateIngredient;
import at.petrak.hexcasting.common.recipe.ingredient.StateIngredientHelper; import at.petrak.hexcasting.common.recipe.ingredient.StateIngredientHelper;
import at.petrak.hexcasting.common.recipe.ingredient.brainsweep.BrainsweepIngredient; import at.petrak.hexcasting.common.recipe.ingredient.brainsweep.BrainsweepeeIngredient;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
@ -24,7 +24,7 @@ import org.jetbrains.annotations.NotNull;
public record BrainsweepRecipe( public record BrainsweepRecipe(
ResourceLocation id, ResourceLocation id,
StateIngredient blockIn, StateIngredient blockIn,
BrainsweepIngredient entityIn, BrainsweepeeIngredient entityIn,
int mediaCost, int mediaCost,
BlockState result BlockState result
) implements Recipe<Container> { ) implements Recipe<Container> {
@ -86,7 +86,7 @@ public record BrainsweepRecipe(
@Override @Override
public @NotNull BrainsweepRecipe fromJson(ResourceLocation recipeID, JsonObject json) { public @NotNull BrainsweepRecipe fromJson(ResourceLocation recipeID, JsonObject json) {
var blockIn = StateIngredientHelper.deserialize(GsonHelper.getAsJsonObject(json, "blockIn")); var blockIn = StateIngredientHelper.deserialize(GsonHelper.getAsJsonObject(json, "blockIn"));
var villagerIn = BrainsweepIngredient.deserialize(GsonHelper.getAsJsonObject(json, "entityIn")); var villagerIn = BrainsweepeeIngredient.deserialize(GsonHelper.getAsJsonObject(json, "entityIn"));
var cost = GsonHelper.getAsInt(json, "cost"); var cost = GsonHelper.getAsInt(json, "cost");
var result = StateIngredientHelper.readBlockState(GsonHelper.getAsJsonObject(json, "result")); var result = StateIngredientHelper.readBlockState(GsonHelper.getAsJsonObject(json, "result"));
return new BrainsweepRecipe(recipeID, blockIn, villagerIn, cost, result); return new BrainsweepRecipe(recipeID, blockIn, villagerIn, cost, result);
@ -103,7 +103,7 @@ public record BrainsweepRecipe(
@Override @Override
public @NotNull BrainsweepRecipe fromNetwork(ResourceLocation recipeID, FriendlyByteBuf buf) { public @NotNull BrainsweepRecipe fromNetwork(ResourceLocation recipeID, FriendlyByteBuf buf) {
var blockIn = StateIngredientHelper.read(buf); var blockIn = StateIngredientHelper.read(buf);
var villagerIn = BrainsweepIngredient.read(buf); var villagerIn = BrainsweepeeIngredient.read(buf);
var cost = buf.readVarInt(); var cost = buf.readVarInt();
var result = Block.stateById(buf.readVarInt()); var result = Block.stateById(buf.readVarInt());
return new BrainsweepRecipe(recipeID, blockIn, villagerIn, cost, result); return new BrainsweepRecipe(recipeID, blockIn, villagerIn, cost, result);

View file

@ -1,52 +0,0 @@
package at.petrak.hexcasting.common.recipe.ingredient.brainsweep;
import com.google.gson.JsonObject;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.GsonHelper;
import net.minecraft.util.StringRepresentable;
import net.minecraft.world.entity.Entity;
import java.util.List;
public abstract class BrainsweepIngredient {
public abstract boolean test(Entity entity, ServerLevel level);
public abstract List<Component> getTooltip(boolean advanced);
public abstract JsonObject serialize();
public abstract void write(FriendlyByteBuf buf);
public abstract Entity exampleEntity(ClientLevel level);
public static BrainsweepIngredient read(FriendlyByteBuf buf) {
var type = buf.readVarInt();
return switch (Type.values()[type]) {
case VILLAGER -> VillagerBrainsweepIngredient.read(buf);
case ENTITY -> EntityBrainsweepIngredient.read(buf);
};
}
public static BrainsweepIngredient deserialize(JsonObject json) {
var typestr = GsonHelper.getAsString(json, "type");
var type = Type.valueOf(typestr);
return switch (type) {
case VILLAGER -> VillagerBrainsweepIngredient.deserialize(json);
case ENTITY -> EntityBrainsweepIngredient.deserialize(json);
};
}
public enum Type implements StringRepresentable {
VILLAGER,
ENTITY;
@Override
public String getSerializedName() {
return this.toString();
}
}
}

View file

@ -0,0 +1,67 @@
package at.petrak.hexcasting.common.recipe.ingredient.brainsweep;
import com.google.gson.JsonObject;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.GsonHelper;
import net.minecraft.util.StringRepresentable;
import net.minecraft.world.entity.Entity;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Locale;
// Partially based on:
// https://github.com/SlimeKnights/Mantle/blob/1.18.2/src/main/java/slimeknights/mantle/recipe/ingredient/EntityIngredient.java
// Licensed under MIT
public abstract class BrainsweepeeIngredient {
public abstract boolean test(Entity entity, ServerLevel level);
public abstract List<Component> getTooltip(boolean advanced);
public abstract JsonObject serialize();
public abstract void write(FriendlyByteBuf buf);
/**
* For the benefit of showing to the client, return an example of the entity.
* <p>
* Can return null in case someone did something stupid with a recipe
*/
@Nullable
public abstract Entity exampleEntity(ClientLevel level);
public static BrainsweepeeIngredient read(FriendlyByteBuf buf) {
var type = buf.readVarInt();
return switch (Type.values()[type]) {
case VILLAGER -> VillagerIngredient.read(buf);
case ENTITY_TYPE -> EntityTypeIngredient.read(buf);
case ENTITY_TAG -> EntityTagIngredient.read(buf);
};
}
public static BrainsweepeeIngredient deserialize(JsonObject json) {
var typestr = GsonHelper.getAsString(json, "type");
var type = Type.valueOf(typestr.toUpperCase(Locale.ROOT));
return switch (type) {
case VILLAGER -> VillagerIngredient.deserialize(json);
case ENTITY_TYPE -> EntityTypeIngredient.deserialize(json);
case ENTITY_TAG -> EntityTagIngredient.deserialize(json);
};
}
// TODO: make this a registry?
public enum Type implements StringRepresentable {
VILLAGER,
ENTITY_TYPE,
ENTITY_TAG;
@Override
public String getSerializedName() {
return this.name().toLowerCase(Locale.ROOT);
}
}
}

View file

@ -1,71 +0,0 @@
package at.petrak.hexcasting.common.recipe.ingredient.brainsweep;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import net.minecraft.advancements.critereon.EntityPredicate;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
import java.util.List;
// Code based on:
// https://github.com/SlimeKnights/Mantle/blob/1.18.2/src/main/java/slimeknights/mantle/recipe/ingredient/EntityIngredient.java
// Licensed under MIT
public class EntityBrainsweepIngredient extends BrainsweepIngredient {
public static final Gson GSON = new GsonBuilder().create();
public final EntityPredicate requirements;
// Just tell the player what it is you want
public final Component tooltip;
public EntityBrainsweepIngredient(EntityPredicate requirements, Component tooltip) {
this.requirements = requirements;
this.tooltip = tooltip;
}
@Override
public boolean test(Entity entity, ServerLevel level) {
return this.requirements.matches(level, null, entity);
}
@Override
public List<Component> getTooltip(boolean advanced) {
return List.of(this.tooltip);
}
@Override
public JsonObject serialize() {
var obj = new JsonObject();
obj.addProperty("type", "entity");
obj.add("requirements", this.requirements.serializeToJson());
obj.addProperty("tooltip", Component.Serializer.toJson(this.tooltip));
return obj;
}
@Override
public void write(FriendlyByteBuf buf) {
buf.writeVarInt(Type.ENTITY.ordinal());
buf.writeUtf(this.requirements.serializeToJson().toString());
buf.writeUtf(Component.Serializer.toJson(this.tooltip));
}
public static EntityBrainsweepIngredient deserialize(JsonObject obj) {
var reqs = EntityPredicate.fromJson(obj.get("requirements"));
var tooltip = Component.Serializer.fromJson(obj.get("tooltip"));
return new EntityBrainsweepIngredient(reqs, tooltip);
}
public static EntityBrainsweepIngredient read(FriendlyByteBuf buf) {
var reqsObj = GSON.fromJson(buf.readUtf(), JsonElement.class);
var reqs = EntityPredicate.fromJson(reqsObj);
var tooltip = Component.Serializer.fromJson(buf.readUtf());
return new EntityBrainsweepIngredient(reqs, tooltip);
}
}

View file

@ -0,0 +1,89 @@
package at.petrak.hexcasting.common.recipe.ingredient.brainsweep;
import com.google.gson.JsonObject;
import net.minecraft.ChatFormatting;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.resources.language.I18n;
import net.minecraft.core.Registry;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.tags.TagKey;
import net.minecraft.util.GsonHelper;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import java.util.ArrayList;
import java.util.List;
public class EntityTagIngredient extends BrainsweepeeIngredient {
public final TagKey<EntityType<?>> entityTypeTag;
public EntityTagIngredient(TagKey<EntityType<?>> tag) {
this.entityTypeTag = tag;
}
@Override
public boolean test(Entity entity, ServerLevel level) {
return entity.getType().is(this.entityTypeTag);
}
@Override
public List<Component> getTooltip(boolean advanced) {
String key = "tag."
+ this.entityTypeTag.location().getNamespace()
+ "."
+ this.entityTypeTag.location().getPath().replace('/', '.');
boolean moddersDidAGoodJob = I18n.exists(key);
var out = new ArrayList<Component>();
out.add(moddersDidAGoodJob
? Component.translatable(key)
: Component.literal("#" + entityTypeTag));
if (advanced && moddersDidAGoodJob) {
out.add(Component.literal("#" + entityTypeTag).withStyle(ChatFormatting.DARK_GRAY));
}
return out;
}
@Override
public Entity exampleEntity(ClientLevel level) {
var someEntityTys = Registry.ENTITY_TYPE.getTagOrEmpty(this.entityTypeTag).iterator();
if (someEntityTys.hasNext()) {
var someTy = someEntityTys.next();
return someTy.value().create(level);
} else {
return null;
}
}
@Override
public JsonObject serialize() {
var obj = new JsonObject();
obj.addProperty("type", Type.ENTITY_TAG.getSerializedName());
obj.addProperty("tag", this.entityTypeTag.location().toString());
return obj;
}
@Override
public void write(FriendlyByteBuf buf) {
buf.writeVarInt(Type.ENTITY_TAG.ordinal());
buf.writeResourceLocation(this.entityTypeTag.location());
}
public static EntityTagIngredient deserialize(JsonObject obj) {
var typeLoc = ResourceLocation.tryParse(GsonHelper.getAsString(obj, "entityType"));
var type = TagKey.create(Registry.ENTITY_TYPE_REGISTRY, typeLoc);
return new EntityTagIngredient(type);
}
public static EntityTagIngredient read(FriendlyByteBuf buf) {
var typeLoc = buf.readResourceLocation();
var type = TagKey.create(Registry.ENTITY_TYPE_REGISTRY, typeLoc);
return new EntityTagIngredient(type);
}
}

View file

@ -0,0 +1,67 @@
package at.petrak.hexcasting.common.recipe.ingredient.brainsweep;
import com.google.gson.JsonObject;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.core.Registry;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.GsonHelper;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import java.util.List;
public class EntityTypeIngredient extends BrainsweepeeIngredient {
public final EntityType<?> entityType;
public EntityTypeIngredient(EntityType<?> entityType) {
this.entityType = entityType;
}
@Override
public boolean test(Entity entity, ServerLevel level) {
// entity types are singletons
return entity.getType() == this.entityType;
}
@Override
public List<Component> getTooltip(boolean advanced) {
return List.of(this.entityType.getDescription());
}
@Override
public Entity exampleEntity(ClientLevel level) {
return this.entityType.create(level);
}
@Override
public JsonObject serialize() {
var obj = new JsonObject();
obj.addProperty("type", Type.ENTITY_TYPE.getSerializedName());
obj.addProperty("entityType", Registry.ENTITY_TYPE.getKey(this.entityType).toString());
return obj;
}
@Override
public void write(FriendlyByteBuf buf) {
buf.writeVarInt(Type.ENTITY_TYPE.ordinal());
buf.writeVarInt(Registry.ENTITY_TYPE.getId(this.entityType));
}
public static EntityTypeIngredient deserialize(JsonObject obj) {
var typeLoc = ResourceLocation.tryParse(GsonHelper.getAsString(obj, "entityType"));
if (!Registry.ENTITY_TYPE.containsKey(typeLoc)) {
throw new IllegalArgumentException("unknown entity type " + typeLoc);
}
return new EntityTypeIngredient(Registry.ENTITY_TYPE.get(typeLoc));
}
public static EntityTypeIngredient read(FriendlyByteBuf buf) {
var tyId = buf.readVarInt();
return new EntityTypeIngredient(Registry.ENTITY_TYPE.byId(tyId));
}
}

View file

@ -1,200 +0,0 @@
package at.petrak.hexcasting.common.recipe.ingredient.brainsweep;
import at.petrak.hexcasting.xplat.IXplatAbstractions;
import com.google.gson.JsonObject;
import net.minecraft.ChatFormatting;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.core.Registry;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.GsonHelper;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.npc.Villager;
import net.minecraft.world.entity.npc.VillagerProfession;
import net.minecraft.world.entity.npc.VillagerType;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* Special case for villagers so we can have biome/profession/level reqs
*/
public class VillagerBrainsweepIngredient extends BrainsweepIngredient {
public final @Nullable ResourceLocation profession;
public final @Nullable ResourceLocation biome;
public final int minLevel;
public VillagerBrainsweepIngredient(
@Nullable ResourceLocation profession,
@Nullable ResourceLocation biome, // aka their "type"
int minLevel
) {
this.profession = profession;
this.biome = biome;
this.minLevel = minLevel;
}
@Override
public boolean test(Entity entity, ServerLevel level) {
if (!(entity instanceof Villager villager)) return false;
var data = villager.getVillagerData();
ResourceLocation profID = IXplatAbstractions.INSTANCE.getID(data.getProfession());
return (this.profession == null || this.profession.equals(profID))
&& (this.biome == null || this.biome.equals(Registry.VILLAGER_TYPE.getKey(data.getType())))
&& this.minLevel <= data.getLevel();
}
@Override
public Entity exampleEntity(ClientLevel level) {
var type = this.biome == null
? VillagerType.PLAINS
: Registry.VILLAGER_TYPE.get(this.biome);
var out = new Villager(EntityType.VILLAGER, level, type);
var profession = this.profession == null
? VillagerProfession.TOOLSMITH
: Registry.VILLAGER_PROFESSION.get(this.profession);
out.getVillagerData().setProfession(profession);
out.getVillagerData().setLevel(Math.max(this.minLevel, 1));
return out;
}
@Override
public List<Component> getTooltip(boolean advanced) {
List<Component> tooltip = new ArrayList<>();
tooltip.add(name());
if (advanced) {
if (minLevel >= 5) {
tooltip.add(Component.translatable("hexcasting.tooltip.brainsweep.level", 5)
.withStyle(ChatFormatting.DARK_GRAY));
} else if (minLevel > 1) {
tooltip.add(Component.translatable("hexcasting.tooltip.brainsweep.min_level", minLevel)
.withStyle(ChatFormatting.DARK_GRAY));
}
if (biome != null) {
tooltip.add(Component.literal(biome.toString()).withStyle(ChatFormatting.DARK_GRAY));
}
ResourceLocation displayId = Objects.requireNonNullElseGet(profession,
() -> Registry.ENTITY_TYPE.getKey(EntityType.VILLAGER));
tooltip.add(Component.literal(displayId.toString()).withStyle(ChatFormatting.DARK_GRAY));
}
tooltip.add(getModNameComponent());
return tooltip;
}
public Component name() {
MutableComponent component = Component.literal("");
boolean addedAny = false;
if (minLevel >= 5) {
component.append(Component.translatable("merchant.level.5"));
addedAny = true;
} else if (minLevel > 1) {
component.append(Component.translatable("merchant.level." + minLevel));
addedAny = true;
} else if (profession != null) {
component.append(Component.translatable("merchant.level.1"));
addedAny = true;
}
if (biome != null) {
if (addedAny) {
component.append(" ");
}
component.append(Component.translatable("biome.minecraft." + biome.getPath()));
addedAny = true;
}
if (profession != null) {
// We've for sure added something
component.append(" ");
component.append(Component.translatable("entity.minecraft.villager." + profession.getPath()));
} else {
if (addedAny) {
component.append(" ");
}
component.append(EntityType.VILLAGER.getDescription());
}
return component;
}
public Component getModNameComponent() {
String namespace = profession == null ? "minecraft" : profession.getNamespace();
String mod = IXplatAbstractions.INSTANCE.getModName(namespace);
return Component.literal(mod).withStyle(ChatFormatting.BLUE, ChatFormatting.ITALIC);
}
@Override
public JsonObject serialize() {
var obj = new JsonObject();
if (this.profession != null) {
obj.addProperty("profession", this.profession.toString());
}
if (this.biome != null) {
obj.addProperty("biome", this.biome.toString());
}
obj.addProperty("minLevel", this.minLevel);
return obj;
}
@Override
public void write(FriendlyByteBuf buf) {
if (this.profession != null) {
buf.writeVarInt(1);
buf.writeResourceLocation(this.profession);
} else {
buf.writeVarInt(0);
}
if (this.biome != null) {
buf.writeVarInt(1);
buf.writeResourceLocation(this.biome);
} else {
buf.writeVarInt(0);
}
buf.writeInt(this.minLevel);
}
public static VillagerBrainsweepIngredient deserialize(JsonObject json) {
ResourceLocation profession = null;
if (json.has("profession") && !json.get("profession").isJsonNull()) {
profession = new ResourceLocation(GsonHelper.getAsString(json, "profession"));
}
ResourceLocation biome = null;
if (json.has("biome") && !json.get("biome").isJsonNull()) {
biome = new ResourceLocation(GsonHelper.getAsString(json, "biome"));
}
int minLevel = GsonHelper.getAsInt(json, "minLevel");
int cost = GsonHelper.getAsInt(json, "cost");
return new VillagerBrainsweepIngredient(profession, biome, minLevel);
}
public static VillagerBrainsweepIngredient read(FriendlyByteBuf buf) {
ResourceLocation profession = null;
var hasProfession = buf.readVarInt();
if (hasProfession != 0) {
profession = buf.readResourceLocation();
}
ResourceLocation biome = null;
var hasBiome = buf.readVarInt();
if (hasBiome != 0) {
biome = buf.readResourceLocation();
}
int minLevel = buf.readInt();
return new VillagerBrainsweepIngredient(profession, biome, minLevel);
}
}

View file

@ -0,0 +1,202 @@
package at.petrak.hexcasting.common.recipe.ingredient.brainsweep;
import at.petrak.hexcasting.xplat.IXplatAbstractions;
import com.google.gson.JsonObject;
import net.minecraft.ChatFormatting;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.core.Registry;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.GsonHelper;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.npc.Villager;
import net.minecraft.world.entity.npc.VillagerProfession;
import net.minecraft.world.entity.npc.VillagerType;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* Special case for villagers so we can have biome/profession/level reqs
*/
public class VillagerIngredient extends BrainsweepeeIngredient {
public final @Nullable ResourceLocation profession;
public final @Nullable ResourceLocation biome;
public final int minLevel;
public VillagerIngredient(
@Nullable ResourceLocation profession,
@Nullable ResourceLocation biome, // aka their "type"
int minLevel
) {
this.profession = profession;
this.biome = biome;
this.minLevel = minLevel;
}
@Override
public boolean test(Entity entity, ServerLevel level) {
if (!(entity instanceof Villager villager)) return false;
var data = villager.getVillagerData();
ResourceLocation profID = IXplatAbstractions.INSTANCE.getID(data.getProfession());
return (this.profession == null || this.profession.equals(profID))
&& (this.biome == null || this.biome.equals(Registry.VILLAGER_TYPE.getKey(data.getType())))
&& this.minLevel <= data.getLevel();
}
@Override
public Entity exampleEntity(ClientLevel level) {
var type = this.biome == null
? VillagerType.PLAINS
: Registry.VILLAGER_TYPE.get(this.biome);
var out = new Villager(EntityType.VILLAGER, level, type);
var profession = this.profession == null
? VillagerProfession.TOOLSMITH
: Registry.VILLAGER_PROFESSION.get(this.profession);
out.getVillagerData().setProfession(profession);
out.getVillagerData().setLevel(Math.max(this.minLevel, 1));
return out;
}
@Override
public List<Component> getTooltip(boolean advanced) {
List<Component> tooltip = new ArrayList<>();
tooltip.add(name());
if (advanced) {
if (minLevel >= 5) {
tooltip.add(Component.translatable("hexcasting.tooltip.brainsweep.level", 5)
.withStyle(ChatFormatting.DARK_GRAY));
} else if (minLevel > 1) {
tooltip.add(Component.translatable("hexcasting.tooltip.brainsweep.min_level", minLevel)
.withStyle(ChatFormatting.DARK_GRAY));
}
if (biome != null) {
tooltip.add(Component.literal(biome.toString()).withStyle(ChatFormatting.DARK_GRAY));
}
ResourceLocation displayId = Objects.requireNonNullElseGet(profession,
() -> Registry.ENTITY_TYPE.getKey(EntityType.VILLAGER));
tooltip.add(Component.literal(displayId.toString()).withStyle(ChatFormatting.DARK_GRAY));
}
tooltip.add(getModNameComponent());
return tooltip;
}
public Component name() {
MutableComponent component = Component.literal("");
boolean addedAny = false;
if (minLevel >= 5) {
component.append(Component.translatable("merchant.level.5"));
addedAny = true;
} else if (minLevel > 1) {
component.append(Component.translatable("merchant.level." + minLevel));
addedAny = true;
} else if (profession != null) {
component.append(Component.translatable("merchant.level.1"));
addedAny = true;
}
if (biome != null) {
if (addedAny) {
component.append(" ");
}
component.append(Component.translatable("biome.minecraft." + biome.getPath()));
addedAny = true;
}
if (profession != null) {
// We've for sure added something
component.append(" ");
component.append(Component.translatable("entity.minecraft.villager." + profession.getPath()));
} else {
if (addedAny) {
component.append(" ");
}
component.append(EntityType.VILLAGER.getDescription());
}
return component;
}
public Component getModNameComponent() {
String namespace = profession == null ? "minecraft" : profession.getNamespace();
String mod = IXplatAbstractions.INSTANCE.getModName(namespace);
return Component.literal(mod).withStyle(ChatFormatting.BLUE, ChatFormatting.ITALIC);
}
@Override
public JsonObject serialize() {
var obj = new JsonObject();
obj.addProperty("type", Type.VILLAGER.getSerializedName());
if (this.profession != null) {
obj.addProperty("profession", this.profession.toString());
}
if (this.biome != null) {
obj.addProperty("biome", this.biome.toString());
}
obj.addProperty("minLevel", this.minLevel);
return obj;
}
@Override
public void write(FriendlyByteBuf buf) {
if (this.profession != null) {
buf.writeVarInt(1);
buf.writeResourceLocation(this.profession);
} else {
buf.writeVarInt(0);
}
if (this.biome != null) {
buf.writeVarInt(1);
buf.writeResourceLocation(this.biome);
} else {
buf.writeVarInt(0);
}
buf.writeInt(this.minLevel);
}
public static VillagerIngredient deserialize(JsonObject json) {
ResourceLocation profession = null;
if (json.has("profession") && !json.get("profession").isJsonNull()) {
profession = new ResourceLocation(GsonHelper.getAsString(json, "profession"));
}
ResourceLocation biome = null;
if (json.has("biome") && !json.get("biome").isJsonNull()) {
biome = new ResourceLocation(GsonHelper.getAsString(json, "biome"));
}
int minLevel = GsonHelper.getAsInt(json, "minLevel");
int cost = GsonHelper.getAsInt(json, "cost");
return new VillagerIngredient(profession, biome, minLevel);
}
public static VillagerIngredient read(FriendlyByteBuf buf) {
ResourceLocation profession = null;
var hasProfession = buf.readVarInt();
if (hasProfession != 0) {
profession = buf.readResourceLocation();
}
ResourceLocation biome = null;
var hasBiome = buf.readVarInt();
if (hasBiome != 0) {
biome = buf.readResourceLocation();
}
int minLevel = buf.readInt();
return new VillagerIngredient(profession, biome, minLevel);
}
}

View file

@ -3,7 +3,6 @@ package at.petrak.hexcasting.datagen.recipe
import at.petrak.hexcasting.api.HexAPI import at.petrak.hexcasting.api.HexAPI
import at.petrak.hexcasting.api.advancements.OvercastTrigger import at.petrak.hexcasting.api.advancements.OvercastTrigger
import at.petrak.hexcasting.api.misc.MediaConstants import at.petrak.hexcasting.api.misc.MediaConstants
import at.petrak.hexcasting.api.mod.HexItemTags
import at.petrak.hexcasting.common.items.ItemStaff import at.petrak.hexcasting.common.items.ItemStaff
import at.petrak.hexcasting.common.items.colorizer.ItemPrideColorizer import at.petrak.hexcasting.common.items.colorizer.ItemPrideColorizer
import at.petrak.hexcasting.common.lib.HexBlocks import at.petrak.hexcasting.common.lib.HexBlocks
@ -11,7 +10,7 @@ import at.petrak.hexcasting.common.lib.HexItems
import at.petrak.hexcasting.common.recipe.SealFocusRecipe import at.petrak.hexcasting.common.recipe.SealFocusRecipe
import at.petrak.hexcasting.common.recipe.SealSpellbookRecipe import at.petrak.hexcasting.common.recipe.SealSpellbookRecipe
import at.petrak.hexcasting.common.recipe.ingredient.StateIngredientHelper import at.petrak.hexcasting.common.recipe.ingredient.StateIngredientHelper
import at.petrak.hexcasting.common.recipe.ingredient.brainsweep.VillagerBrainsweepIngredient import at.petrak.hexcasting.common.recipe.ingredient.brainsweep.VillagerIngredient
import at.petrak.hexcasting.datagen.IXplatConditionsBuilder import at.petrak.hexcasting.datagen.IXplatConditionsBuilder
import at.petrak.hexcasting.datagen.IXplatIngredients import at.petrak.hexcasting.datagen.IXplatIngredients
import at.petrak.hexcasting.datagen.recipe.builders.BrainsweepRecipeBuilder import at.petrak.hexcasting.datagen.recipe.builders.BrainsweepRecipeBuilder
@ -352,37 +351,37 @@ class HexplatRecipes(
.unlockedBy("enlightenment", enlightenment).save(recipes) .unlockedBy("enlightenment", enlightenment).save(recipes)
BrainsweepRecipeBuilder(StateIngredientHelper.of(Blocks.AMETHYST_BLOCK), BrainsweepRecipeBuilder(StateIngredientHelper.of(Blocks.AMETHYST_BLOCK),
VillagerBrainsweepIngredient(null, null, 3), VillagerIngredient(null, null, 3),
Blocks.BUDDING_AMETHYST.defaultBlockState(), MediaConstants.CRYSTAL_UNIT * 10) Blocks.BUDDING_AMETHYST.defaultBlockState(), MediaConstants.CRYSTAL_UNIT * 10)
.unlockedBy("enlightenment", enlightenment) .unlockedBy("enlightenment", enlightenment)
.save(recipes, modLoc("brainsweep/budding_amethyst")) .save(recipes, modLoc("brainsweep/budding_amethyst"))
BrainsweepRecipeBuilder(StateIngredientHelper.of(HexBlocks.EMPTY_IMPETUS), BrainsweepRecipeBuilder(StateIngredientHelper.of(HexBlocks.EMPTY_IMPETUS),
VillagerBrainsweepIngredient(ResourceLocation("toolsmith"), null, 2), VillagerIngredient(ResourceLocation("toolsmith"), null, 2),
HexBlocks.IMPETUS_RIGHTCLICK.defaultBlockState(), MediaConstants.CRYSTAL_UNIT * 10) HexBlocks.IMPETUS_RIGHTCLICK.defaultBlockState(), MediaConstants.CRYSTAL_UNIT * 10)
.unlockedBy("enlightenment", enlightenment) .unlockedBy("enlightenment", enlightenment)
.save(recipes, modLoc("brainsweep/impetus_rightclick")) .save(recipes, modLoc("brainsweep/impetus_rightclick"))
BrainsweepRecipeBuilder(StateIngredientHelper.of(HexBlocks.EMPTY_IMPETUS), BrainsweepRecipeBuilder(StateIngredientHelper.of(HexBlocks.EMPTY_IMPETUS),
VillagerBrainsweepIngredient(ResourceLocation("fletcher"), null, 2), VillagerIngredient(ResourceLocation("fletcher"), null, 2),
HexBlocks.IMPETUS_LOOK.defaultBlockState(), MediaConstants.CRYSTAL_UNIT * 10) HexBlocks.IMPETUS_LOOK.defaultBlockState(), MediaConstants.CRYSTAL_UNIT * 10)
.unlockedBy("enlightenment", enlightenment) .unlockedBy("enlightenment", enlightenment)
.save(recipes, modLoc("brainsweep/impetus_look")) .save(recipes, modLoc("brainsweep/impetus_look"))
BrainsweepRecipeBuilder(StateIngredientHelper.of(HexBlocks.EMPTY_IMPETUS), BrainsweepRecipeBuilder(StateIngredientHelper.of(HexBlocks.EMPTY_IMPETUS),
VillagerBrainsweepIngredient(ResourceLocation("cleric"), null, 2), VillagerIngredient(ResourceLocation("cleric"), null, 2),
HexBlocks.IMPETUS_STOREDPLAYER.defaultBlockState(), MediaConstants.CRYSTAL_UNIT * 10) HexBlocks.IMPETUS_STOREDPLAYER.defaultBlockState(), MediaConstants.CRYSTAL_UNIT * 10)
.unlockedBy("enlightenment", enlightenment) .unlockedBy("enlightenment", enlightenment)
.save(recipes, modLoc("brainsweep/impetus_storedplayer")) .save(recipes, modLoc("brainsweep/impetus_storedplayer"))
BrainsweepRecipeBuilder(StateIngredientHelper.of(HexBlocks.EMPTY_DIRECTRIX), BrainsweepRecipeBuilder(StateIngredientHelper.of(HexBlocks.EMPTY_DIRECTRIX),
VillagerBrainsweepIngredient(ResourceLocation("mason"), null, 1), VillagerIngredient(ResourceLocation("mason"), null, 1),
HexBlocks.DIRECTRIX_REDSTONE.defaultBlockState(), MediaConstants.CRYSTAL_UNIT * 10) HexBlocks.DIRECTRIX_REDSTONE.defaultBlockState(), MediaConstants.CRYSTAL_UNIT * 10)
.unlockedBy("enlightenment", enlightenment) .unlockedBy("enlightenment", enlightenment)
.save(recipes, modLoc("brainsweep/directrix_redstone")) .save(recipes, modLoc("brainsweep/directrix_redstone"))
BrainsweepRecipeBuilder(StateIngredientHelper.of(HexBlocks.AKASHIC_LIGATURE), BrainsweepRecipeBuilder(StateIngredientHelper.of(HexBlocks.AKASHIC_LIGATURE),
VillagerBrainsweepIngredient(ResourceLocation("librarian"), null, 5), VillagerIngredient(ResourceLocation("librarian"), null, 5),
HexBlocks.AKASHIC_RECORD.defaultBlockState(), MediaConstants.CRYSTAL_UNIT * 10) HexBlocks.AKASHIC_RECORD.defaultBlockState(), MediaConstants.CRYSTAL_UNIT * 10)
.unlockedBy("enlightenment", enlightenment) .unlockedBy("enlightenment", enlightenment)
.save(recipes, modLoc("brainsweep/akashic_record")) .save(recipes, modLoc("brainsweep/akashic_record"))

View file

@ -3,7 +3,7 @@ package at.petrak.hexcasting.datagen.recipe.builders;
import at.petrak.hexcasting.common.recipe.HexRecipeStuffRegistry; import at.petrak.hexcasting.common.recipe.HexRecipeStuffRegistry;
import at.petrak.hexcasting.common.recipe.ingredient.StateIngredient; import at.petrak.hexcasting.common.recipe.ingredient.StateIngredient;
import at.petrak.hexcasting.common.recipe.ingredient.StateIngredientHelper; import at.petrak.hexcasting.common.recipe.ingredient.StateIngredientHelper;
import at.petrak.hexcasting.common.recipe.ingredient.brainsweep.BrainsweepIngredient; import at.petrak.hexcasting.common.recipe.ingredient.brainsweep.BrainsweepeeIngredient;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import net.minecraft.advancements.Advancement; import net.minecraft.advancements.Advancement;
import net.minecraft.advancements.AdvancementRewards; import net.minecraft.advancements.AdvancementRewards;
@ -22,13 +22,13 @@ import java.util.function.Consumer;
public class BrainsweepRecipeBuilder implements RecipeBuilder { public class BrainsweepRecipeBuilder implements RecipeBuilder {
private final StateIngredient blockIn; private final StateIngredient blockIn;
private final BrainsweepIngredient villagerIn; private final BrainsweepeeIngredient villagerIn;
private final int mediaCost; private final int mediaCost;
private final BlockState result; private final BlockState result;
private final Advancement.Builder advancement; private final Advancement.Builder advancement;
public BrainsweepRecipeBuilder(StateIngredient blockIn, BrainsweepIngredient villagerIn, BlockState result, public BrainsweepRecipeBuilder(StateIngredient blockIn, BrainsweepeeIngredient villagerIn, BlockState result,
int mediaCost) { int mediaCost) {
this.blockIn = blockIn; this.blockIn = blockIn;
this.villagerIn = villagerIn; this.villagerIn = villagerIn;
@ -70,7 +70,7 @@ public class BrainsweepRecipeBuilder implements RecipeBuilder {
new ResourceLocation(pRecipeId.getNamespace(), "recipes/brainsweep/" + pRecipeId.getPath()))); new ResourceLocation(pRecipeId.getNamespace(), "recipes/brainsweep/" + pRecipeId.getPath())));
} }
public record Result(ResourceLocation id, StateIngredient blockIn, BrainsweepIngredient villagerIn, public record Result(ResourceLocation id, StateIngredient blockIn, BrainsweepeeIngredient villagerIn,
int mediaCost, BlockState result, Advancement.Builder advancement, int mediaCost, BlockState result, Advancement.Builder advancement,
ResourceLocation advancementId) implements FinishedRecipe { ResourceLocation advancementId) implements FinishedRecipe {
@Override @Override

View file

@ -2,8 +2,8 @@ package at.petrak.hexcasting.interop.patchouli;
import at.petrak.hexcasting.common.recipe.BrainsweepRecipe; import at.petrak.hexcasting.common.recipe.BrainsweepRecipe;
import at.petrak.hexcasting.common.recipe.HexRecipeStuffRegistry; import at.petrak.hexcasting.common.recipe.HexRecipeStuffRegistry;
import at.petrak.hexcasting.common.recipe.ingredient.brainsweep.EntityBrainsweepIngredient; import at.petrak.hexcasting.common.recipe.ingredient.brainsweep.EntityTypeIngredient;
import at.petrak.hexcasting.common.recipe.ingredient.brainsweep.VillagerBrainsweepIngredient; import at.petrak.hexcasting.common.recipe.ingredient.brainsweep.VillagerIngredient;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
@ -49,7 +49,7 @@ public class BrainsweepProcessor implements IComponentProcessor {
} }
case "entity" -> { case "entity" -> {
if (this.recipe.entityIn() instanceof VillagerBrainsweepIngredient villager) { if (this.recipe.entityIn() instanceof VillagerIngredient villager) {
var profession = Objects.requireNonNullElse(villager.profession, var profession = Objects.requireNonNullElse(villager.profession,
new ResourceLocation("toolsmith")); new ResourceLocation("toolsmith"));
var biome = Objects.requireNonNullElse(villager.biome, var biome = Objects.requireNonNullElse(villager.biome,
@ -59,7 +59,7 @@ public class BrainsweepProcessor implements IComponentProcessor {
"minecraft:villager{VillagerData:{profession:'%s',type:'%s',level:%d}}", "minecraft:villager{VillagerData:{profession:'%s',type:'%s',level:%d}}",
profession, biome, level); profession, biome, level);
return IVariable.wrap(iHatePatchouli); return IVariable.wrap(iHatePatchouli);
} else if (this.recipe.entityIn() instanceof EntityBrainsweepIngredient entity) { } else if (this.recipe.entityIn() instanceof EntityTypeIngredient entity) {
// TODO // TODO
return IVariable.wrap("minecraft:chicken"); return IVariable.wrap("minecraft:chicken");
} else { } else {

View file

@ -4,7 +4,7 @@ import at.petrak.hexcasting.client.ClientTickCounter;
import at.petrak.hexcasting.client.RenderLib; import at.petrak.hexcasting.client.RenderLib;
import at.petrak.hexcasting.client.shader.FakeBufferSource; import at.petrak.hexcasting.client.shader.FakeBufferSource;
import at.petrak.hexcasting.client.shader.HexRenderTypes; import at.petrak.hexcasting.client.shader.HexRenderTypes;
import at.petrak.hexcasting.common.recipe.ingredient.brainsweep.BrainsweepIngredient; import at.petrak.hexcasting.common.recipe.ingredient.brainsweep.BrainsweepeeIngredient;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import dev.emi.emi.api.render.EmiRender; import dev.emi.emi.api.render.EmiRender;
@ -35,20 +35,20 @@ import static at.petrak.hexcasting.client.RenderLib.renderEntity;
public class BrainsweepeeEmiStack extends EmiStack { public class BrainsweepeeEmiStack extends EmiStack {
private final VillagerEntry entry; private final VillagerEntry entry;
public final BrainsweepIngredient ingredient; public final BrainsweepeeIngredient ingredient;
public final boolean mindless; public final boolean mindless;
private final ResourceLocation id; private final ResourceLocation id;
public BrainsweepeeEmiStack(BrainsweepIngredient villager) { public BrainsweepeeEmiStack(BrainsweepeeIngredient villager) {
this(villager, false); this(villager, false);
} }
public BrainsweepeeEmiStack(BrainsweepIngredient villager, boolean mindless) { public BrainsweepeeEmiStack(BrainsweepeeIngredient villager, boolean mindless) {
this(villager, mindless, 1); this(villager, mindless, 1);
} }
public BrainsweepeeEmiStack(BrainsweepIngredient villager, boolean mindless, long amount) { public BrainsweepeeEmiStack(BrainsweepeeIngredient villager, boolean mindless, long amount) {
entry = new VillagerEntry(new VillagerVariant(villager, mindless)); entry = new VillagerEntry(new VillagerVariant(villager, mindless));
this.ingredient = villager; this.ingredient = villager;
this.mindless = mindless; this.mindless = mindless;
@ -65,11 +65,11 @@ public class BrainsweepeeEmiStack extends EmiStack {
.collect(Collectors.toSet()); .collect(Collectors.toSet());
} }
public static EmiIngredient atLevelOrHigher(BrainsweepIngredient ingredient, boolean remainder) { public static EmiIngredient atLevelOrHigher(BrainsweepeeIngredient ingredient, boolean remainder) {
if (ingredient.profession() == null) { if (ingredient.profession() == null) {
return EmiIngredient.of(Registry.VILLAGER_PROFESSION.stream() return EmiIngredient.of(Registry.VILLAGER_PROFESSION.stream()
.filter(it -> matchingStatesForProfession(it).isEmpty()) .filter(it -> matchingStatesForProfession(it).isEmpty())
.map(it -> atLevelOrHigher(new BrainsweepIngredient(Registry.VILLAGER_PROFESSION.getKey(it), .map(it -> atLevelOrHigher(new BrainsweepeeIngredient(Registry.VILLAGER_PROFESSION.getKey(it),
ingredient.biome(), ingredient.minLevel()), true)) ingredient.biome(), ingredient.minLevel()), true))
.toList()); .toList());
} }

View file

@ -1,7 +1,7 @@
package at.petrak.hexcasting.fabric.interop.emi; package at.petrak.hexcasting.fabric.interop.emi;
import at.petrak.hexcasting.common.recipe.ingredient.brainsweep.BrainsweepIngredient; import at.petrak.hexcasting.common.recipe.ingredient.brainsweep.BrainsweepeeIngredient;
public record VillagerVariant(BrainsweepIngredient ingredient, boolean mindless) { public record VillagerVariant(BrainsweepeeIngredient ingredient, boolean mindless) {
// NO-OP // NO-OP
} }