possibly impl arbitrary brainsweeps. i don't know. i'm in offline mode
This commit is contained in:
parent
30701702c7
commit
7c00cbaec8
18 changed files with 439 additions and 423 deletions
|
@ -13,9 +13,9 @@ import net.minecraft.core.BlockPos
|
|||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.entity.Entity
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.Mob
|
||||
import net.minecraft.world.entity.decoration.ArmorStand
|
||||
import net.minecraft.world.entity.item.ItemEntity
|
||||
import net.minecraft.world.entity.npc.Villager
|
||||
import net.minecraft.world.phys.Vec3
|
||||
import java.util.function.DoubleUnaryOperator
|
||||
import kotlin.math.abs
|
||||
|
@ -99,14 +99,14 @@ fun List<Iota>.getPlayer(idx: Int, argc: Int = 0): ServerPlayer {
|
|||
throw MishapInvalidIota.ofType(x, if (argc == 0) idx else argc - (idx + 1), "entity.player")
|
||||
}
|
||||
|
||||
fun List<Iota>.getVillager(idx: Int, argc: Int = 0): Villager {
|
||||
fun List<Iota>.getMob(idx: Int, argc: Int = 0): Mob {
|
||||
val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) }
|
||||
if (x is EntityIota) {
|
||||
val e = x.entity
|
||||
if (e is Villager)
|
||||
if (e is Mob)
|
||||
return e
|
||||
}
|
||||
throw MishapInvalidIota.ofType(x, if (argc == 0) idx else argc - (idx + 1), "entity.villager")
|
||||
throw MishapInvalidIota.ofType(x, if (argc == 0) idx else argc - (idx + 1), "entity.mob")
|
||||
}
|
||||
|
||||
fun List<Iota>.getLivingEntityButNotArmorStand(idx: Int, argc: Int = 0): LivingEntity {
|
||||
|
@ -216,7 +216,7 @@ fun List<Iota>.getPositiveIntUnderInclusive(idx: Int, max: Int, argc: Int = 0):
|
|||
if (x is DoubleIota) {
|
||||
val double = x.double
|
||||
val rounded = double.roundToInt()
|
||||
if (abs(double - rounded) <= DoubleIota.TOLERANCE && rounded in 0 .. max) {
|
||||
if (abs(double - rounded) <= DoubleIota.TOLERANCE && rounded in 0..max) {
|
||||
return rounded
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,22 +2,22 @@ package at.petrak.hexcasting.api.spell.mishaps
|
|||
|
||||
import at.petrak.hexcasting.api.misc.FrozenColorizer
|
||||
import at.petrak.hexcasting.api.misc.HexDamageSources
|
||||
import at.petrak.hexcasting.api.spell.iota.Iota
|
||||
import at.petrak.hexcasting.api.spell.ParticleSpray
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import net.minecraft.world.entity.npc.Villager
|
||||
import at.petrak.hexcasting.api.spell.iota.Iota
|
||||
import net.minecraft.world.entity.Mob
|
||||
import net.minecraft.world.item.DyeColor
|
||||
|
||||
class MishapAlreadyBrainswept(val villager: Villager) : Mishap() {
|
||||
class MishapAlreadyBrainswept(val mob: Mob) : Mishap() {
|
||||
override fun accentColor(ctx: CastingContext, errorCtx: Context): FrozenColorizer =
|
||||
dyeColor(DyeColor.GREEN)
|
||||
|
||||
override fun execute(ctx: CastingContext, errorCtx: Context, stack: MutableList<Iota>) {
|
||||
villager.hurt(HexDamageSources.overcastDamageFrom(ctx.caster), villager.health)
|
||||
mob.hurt(HexDamageSources.overcastDamageFrom(ctx.caster), mob.health)
|
||||
}
|
||||
|
||||
override fun particleSpray(ctx: CastingContext) =
|
||||
ParticleSpray.burst(villager.eyePosition, 1.0)
|
||||
ParticleSpray.burst(mob.eyePosition, 1.0)
|
||||
|
||||
override fun errorMessage(ctx: CastingContext, errorCtx: Context) =
|
||||
error("already_brainswept")
|
||||
|
|
|
@ -3,19 +3,19 @@ package at.petrak.hexcasting.api.spell.mishaps
|
|||
import at.petrak.hexcasting.api.misc.FrozenColorizer
|
||||
import at.petrak.hexcasting.api.misc.HexDamageSources
|
||||
import at.petrak.hexcasting.api.spell.ParticleSpray
|
||||
import at.petrak.hexcasting.api.spell.iota.Iota
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.api.spell.iota.Iota
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.world.entity.npc.Villager
|
||||
import net.minecraft.world.entity.Mob
|
||||
import net.minecraft.world.item.DyeColor
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class MishapBadBrainsweep(val villager: Villager, val pos: BlockPos) : Mishap() {
|
||||
class MishapBadBrainsweep(val mob: Mob, val pos: BlockPos) : Mishap() {
|
||||
override fun accentColor(ctx: CastingContext, errorCtx: Context): FrozenColorizer =
|
||||
dyeColor(DyeColor.GREEN)
|
||||
|
||||
override fun execute(ctx: CastingContext, errorCtx: Context, stack: MutableList<Iota>) {
|
||||
trulyHurt(villager, HexDamageSources.overcastDamageFrom(ctx.caster), villager.health)
|
||||
trulyHurt(mob, HexDamageSources.overcastDamageFrom(ctx.caster), mob.health)
|
||||
}
|
||||
|
||||
override fun particleSpray(ctx: CastingContext): ParticleSpray {
|
||||
|
|
|
@ -1,19 +1,20 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.spells.great
|
||||
|
||||
import at.petrak.hexcasting.api.misc.MediaConstants
|
||||
import at.petrak.hexcasting.api.mod.HexConfig
|
||||
import at.petrak.hexcasting.api.spell.*
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.api.spell.iota.Iota
|
||||
import at.petrak.hexcasting.api.spell.mishaps.MishapAlreadyBrainswept
|
||||
import at.petrak.hexcasting.api.spell.mishaps.MishapBadBrainsweep
|
||||
import at.petrak.hexcasting.common.misc.Brainsweeping
|
||||
import at.petrak.hexcasting.common.recipe.BrainsweepRecipe
|
||||
import at.petrak.hexcasting.common.recipe.HexRecipeStuffRegistry
|
||||
import at.petrak.hexcasting.ktxt.tellWitnessesThatIWasMurdered
|
||||
import at.petrak.hexcasting.mixin.accessor.AccessorLivingEntity
|
||||
import at.petrak.hexcasting.xplat.IXplatAbstractions
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.sounds.SoundEvents
|
||||
import net.minecraft.sounds.SoundSource
|
||||
import net.minecraft.world.entity.Mob
|
||||
import net.minecraft.world.entity.npc.Villager
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
@ -30,12 +31,12 @@ object OpBrainsweep : SpellAction {
|
|||
args: List<Iota>,
|
||||
ctx: CastingContext
|
||||
): Triple<RenderedSpell, Int, List<ParticleSpray>>? {
|
||||
val sacrifice = args.getVillager(0, argc)
|
||||
val sacrifice = args.getMob(0, argc)
|
||||
val pos = args.getBlockPos(1, argc)
|
||||
ctx.assertVecInRange(pos)
|
||||
ctx.assertEntityInRange(sacrifice)
|
||||
|
||||
if (Brainsweeping.isBrainswept(sacrifice))
|
||||
if (IXplatAbstractions.INSTANCE.isBrainswept(sacrifice))
|
||||
throw MishapAlreadyBrainswept(sacrifice)
|
||||
|
||||
val state = ctx.world.getBlockState(pos)
|
||||
|
@ -45,12 +46,12 @@ object OpBrainsweep : SpellAction {
|
|||
|
||||
val recman = ctx.world.recipeManager
|
||||
val recipes = recman.getAllRecipesFor(HexRecipeStuffRegistry.BRAINSWEEP_TYPE)
|
||||
val recipe = recipes.find { it.matches(state, sacrifice) }
|
||||
val recipe = recipes.find { it.matches(state, sacrifice, ctx.world) }
|
||||
?: throw MishapBadBrainsweep(sacrifice, pos)
|
||||
|
||||
return Triple(
|
||||
Spell(pos, state, sacrifice, recipe),
|
||||
10 * MediaConstants.CRYSTAL_UNIT,
|
||||
recipe.mediaCost,
|
||||
listOf(ParticleSpray.cloud(sacrifice.position(), 1.0), ParticleSpray.burst(Vec3.atCenterOf(pos), 0.3, 100))
|
||||
)
|
||||
}
|
||||
|
@ -58,18 +59,20 @@ object OpBrainsweep : SpellAction {
|
|||
private data class Spell(
|
||||
val pos: BlockPos,
|
||||
val state: BlockState,
|
||||
val sacrifice: Villager,
|
||||
val sacrifice: Mob,
|
||||
val recipe: BrainsweepRecipe
|
||||
) : RenderedSpell {
|
||||
override fun cast(ctx: CastingContext) {
|
||||
ctx.world.setBlockAndUpdate(pos, BrainsweepRecipe.copyProperties(state, recipe.result))
|
||||
|
||||
Brainsweeping.brainsweep(sacrifice)
|
||||
if (HexConfig.server().doVillagersTakeOffenseAtMindMurder()) {
|
||||
IXplatAbstractions.INSTANCE.brainsweep(sacrifice)
|
||||
if (sacrifice is Villager && HexConfig.server().doVillagersTakeOffenseAtMindMurder()) {
|
||||
sacrifice.tellWitnessesThatIWasMurdered(ctx.caster)
|
||||
}
|
||||
|
||||
ctx.world.playSound(null, sacrifice, SoundEvents.VILLAGER_DEATH, SoundSource.AMBIENT, 0.8f, 1f)
|
||||
val sound = (sacrifice as AccessorLivingEntity).`hex$getDeathSound`()
|
||||
if (sound != null)
|
||||
ctx.world.playSound(null, sacrifice, sound, SoundSource.AMBIENT, 0.8f, 1f)
|
||||
ctx.world.playSound(null, sacrifice, SoundEvents.PLAYER_LEVELUP, SoundSource.AMBIENT, 0.5f, 0.8f)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,43 +6,24 @@ import net.minecraft.world.InteractionResult;
|
|||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.Mob;
|
||||
import net.minecraft.world.entity.npc.Villager;
|
||||
import net.minecraft.world.entity.npc.VillagerDataHolder;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.entity.raid.Raider;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.EntityHitResult;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class Brainsweeping {
|
||||
// Keeping these functions in Brainsweeping just so we have to change less code
|
||||
public static void brainsweep(Mob entity) {
|
||||
if (isValidTarget(entity)) {
|
||||
IXplatAbstractions.INSTANCE.brainsweep(entity);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isBrainswept(Mob entity) {
|
||||
return isValidTarget(entity) && IXplatAbstractions.INSTANCE.isBrainswept(entity);
|
||||
}
|
||||
|
||||
// TODO: make this a tag
|
||||
public static boolean isValidTarget(Mob mob) {
|
||||
return mob instanceof VillagerDataHolder || mob instanceof Raider;
|
||||
}
|
||||
|
||||
public static InteractionResult tradeWithVillager(Player player, Level world, InteractionHand hand, Entity entity,
|
||||
@Nullable EntityHitResult hitResult) {
|
||||
if (entity instanceof Villager v && IXplatAbstractions.INSTANCE.isBrainswept(v)) {
|
||||
public static InteractionResult interactWithBrainswept(Player player, Level world, InteractionHand hand,
|
||||
Entity entity, @Nullable EntityHitResult hitResult) {
|
||||
if (entity instanceof Mob mob && IXplatAbstractions.INSTANCE.isBrainswept(mob)) {
|
||||
return InteractionResult.FAIL;
|
||||
}
|
||||
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
|
||||
public static InteractionResult copyBrainsweepFromVillager(LivingEntity original, LivingEntity outcome) {
|
||||
public static InteractionResult copyBrainsweepPostTransformation(LivingEntity original, LivingEntity outcome) {
|
||||
if (original instanceof Mob mOriginal && outcome instanceof Mob mOutcome
|
||||
&& IXplatAbstractions.INSTANCE.isBrainswept(mOriginal) && Brainsweeping.isValidTarget(mOutcome)) {
|
||||
&& IXplatAbstractions.INSTANCE.isBrainswept(mOriginal)) {
|
||||
IXplatAbstractions.INSTANCE.brainsweep(mOutcome);
|
||||
}
|
||||
return InteractionResult.PASS;
|
||||
|
|
|
@ -6,9 +6,10 @@ import at.petrak.hexcasting.common.recipe.ingredient.brainsweep.BrainsweepIngred
|
|||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.entity.npc.Villager;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.crafting.Recipe;
|
||||
import net.minecraft.world.item.crafting.RecipeSerializer;
|
||||
|
@ -23,11 +24,12 @@ import org.jetbrains.annotations.NotNull;
|
|||
public record BrainsweepRecipe(
|
||||
ResourceLocation id,
|
||||
StateIngredient blockIn,
|
||||
BrainsweepIngredient villagerIn,
|
||||
BrainsweepIngredient entityIn,
|
||||
int mediaCost,
|
||||
BlockState result
|
||||
) implements Recipe<Container> {
|
||||
public boolean matches(BlockState blockIn, Villager villagerIn) {
|
||||
return this.blockIn.test(blockIn) && this.villagerIn.test(villagerIn);
|
||||
public boolean matches(BlockState blockIn, Entity victim, ServerLevel level) {
|
||||
return this.blockIn.test(blockIn) && this.entityIn.test(victim, level);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -84,15 +86,17 @@ public record BrainsweepRecipe(
|
|||
@Override
|
||||
public @NotNull BrainsweepRecipe fromJson(ResourceLocation recipeID, JsonObject json) {
|
||||
var blockIn = StateIngredientHelper.deserialize(GsonHelper.getAsJsonObject(json, "blockIn"));
|
||||
var villagerIn = BrainsweepIngredient.deserialize(GsonHelper.getAsJsonObject(json, "villagerIn"));
|
||||
var villagerIn = BrainsweepIngredient.deserialize(GsonHelper.getAsJsonObject(json, "entityIn"));
|
||||
var cost = GsonHelper.getAsInt(json, "cost");
|
||||
var result = StateIngredientHelper.readBlockState(GsonHelper.getAsJsonObject(json, "result"));
|
||||
return new BrainsweepRecipe(recipeID, blockIn, villagerIn, result);
|
||||
return new BrainsweepRecipe(recipeID, blockIn, villagerIn, cost, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toNetwork(FriendlyByteBuf buf, BrainsweepRecipe recipe) {
|
||||
recipe.blockIn.write(buf);
|
||||
recipe.villagerIn.write(buf);
|
||||
recipe.entityIn.write(buf);
|
||||
buf.writeVarInt(recipe.mediaCost);
|
||||
buf.writeVarInt(Block.getId(recipe.result));
|
||||
}
|
||||
|
||||
|
@ -100,8 +104,9 @@ public record BrainsweepRecipe(
|
|||
public @NotNull BrainsweepRecipe fromNetwork(ResourceLocation recipeID, FriendlyByteBuf buf) {
|
||||
var blockIn = StateIngredientHelper.read(buf);
|
||||
var villagerIn = BrainsweepIngredient.read(buf);
|
||||
var cost = buf.readVarInt();
|
||||
var result = Block.stateById(buf.readVarInt());
|
||||
return new BrainsweepRecipe(recipeID, blockIn, villagerIn, result);
|
||||
return new BrainsweepRecipe(recipeID, blockIn, villagerIn, cost, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,14 +3,16 @@ package at.petrak.hexcasting.common.recipe.ingredient.brainsweep;
|
|||
import com.google.gson.JsonObject;
|
||||
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;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public abstract class BrainsweepIngredient implements Predicate<Entity> {
|
||||
public abstract class BrainsweepIngredient {
|
||||
public abstract boolean test(Entity entity, ServerLevel level);
|
||||
|
||||
public abstract List<Component> getTooltip(boolean advanced);
|
||||
|
||||
public abstract JsonObject serialize();
|
||||
|
@ -21,8 +23,7 @@ public abstract class BrainsweepIngredient implements Predicate<Entity> {
|
|||
var type = buf.readVarInt();
|
||||
return switch (Type.values()[type]) {
|
||||
case VILLAGER -> VillagerBrainsweepIngredient.read(buf);
|
||||
case ENTITY -> {
|
||||
}
|
||||
case ENTITY -> EntityBrainsweepIngredient.read(buf);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -31,7 +32,7 @@ public abstract class BrainsweepIngredient implements Predicate<Entity> {
|
|||
var type = Type.valueOf(typestr);
|
||||
return switch (type) {
|
||||
case VILLAGER -> VillagerBrainsweepIngredient.deserialize(json);
|
||||
case ENTITY -> null;
|
||||
case ENTITY -> EntityBrainsweepIngredient.deserialize(json);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,30 +1,35 @@
|
|||
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.DeserializationContext;
|
||||
import net.minecraft.advancements.critereon.EntityPredicate;
|
||||
import net.minecraft.advancements.critereon.SerializationContext;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
|
||||
|
||||
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 final EntityPredicate.Composite requirements;
|
||||
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;
|
||||
|
||||
protected EntityBrainsweepIngredient(EntityPredicate.Composite requirements, Component tooltip) {
|
||||
super();
|
||||
public EntityBrainsweepIngredient(EntityPredicate requirements, Component tooltip) {
|
||||
this.requirements = requirements;
|
||||
this.tooltip = tooltip;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(Entity entity) {
|
||||
return false;
|
||||
public boolean test(Entity entity, ServerLevel level) {
|
||||
return this.requirements.matches(level, null, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -35,17 +40,32 @@ public class EntityBrainsweepIngredient extends BrainsweepIngredient {
|
|||
@Override
|
||||
public JsonObject serialize() {
|
||||
var obj = new JsonObject();
|
||||
obj.add("requirements", this.requirements.toJson(SerializationContext.INSTANCE));
|
||||
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.Composite.fromJson(obj, "requirements", DeserializationContext)
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ 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;
|
||||
|
@ -26,19 +27,18 @@ public class VillagerBrainsweepIngredient extends BrainsweepIngredient {
|
|||
private final @Nullable ResourceLocation biome;
|
||||
private final int minLevel;
|
||||
|
||||
protected VillagerBrainsweepIngredient(
|
||||
public VillagerBrainsweepIngredient(
|
||||
@Nullable ResourceLocation profession,
|
||||
@Nullable ResourceLocation biome, // aka their "type"
|
||||
int minLevel
|
||||
) {
|
||||
super();
|
||||
this.profession = profession;
|
||||
this.biome = biome;
|
||||
this.minLevel = minLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(Entity entity) {
|
||||
public boolean test(Entity entity, ServerLevel level) {
|
||||
if (!(entity instanceof Villager villager)) return false;
|
||||
|
||||
var data = villager.getVillagerData();
|
||||
|
@ -153,14 +153,15 @@ public class VillagerBrainsweepIngredient extends BrainsweepIngredient {
|
|||
|
||||
public static VillagerBrainsweepIngredient deserialize(JsonObject json) {
|
||||
ResourceLocation profession = null;
|
||||
if (json.has("profession")) {
|
||||
if (json.has("profession") && !json.get("profession").isJsonNull()) {
|
||||
profession = new ResourceLocation(GsonHelper.getAsString(json, "profession"));
|
||||
}
|
||||
ResourceLocation biome = null;
|
||||
if (json.has("biome")) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package at.petrak.hexcasting.datagen.recipe
|
|||
|
||||
import at.petrak.hexcasting.api.HexAPI
|
||||
import at.petrak.hexcasting.api.advancements.OvercastTrigger
|
||||
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.colorizer.ItemPrideColorizer
|
||||
|
@ -10,7 +11,7 @@ import at.petrak.hexcasting.common.lib.HexItems
|
|||
import at.petrak.hexcasting.common.recipe.SealFocusRecipe
|
||||
import at.petrak.hexcasting.common.recipe.SealSpellbookRecipe
|
||||
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.VillagerBrainsweepIngredient
|
||||
import at.petrak.hexcasting.datagen.IXplatConditionsBuilder
|
||||
import at.petrak.hexcasting.datagen.IXplatIngredients
|
||||
import at.petrak.hexcasting.datagen.recipe.builders.BrainsweepRecipeBuilder
|
||||
|
@ -351,38 +352,38 @@ class HexplatRecipes(
|
|||
.unlockedBy("enlightenment", enlightenment).save(recipes)
|
||||
|
||||
BrainsweepRecipeBuilder(StateIngredientHelper.of(Blocks.AMETHYST_BLOCK),
|
||||
BrainsweepIngredient(null, null, 3),
|
||||
Blocks.BUDDING_AMETHYST.defaultBlockState())
|
||||
VillagerBrainsweepIngredient(null, null, 3),
|
||||
Blocks.BUDDING_AMETHYST.defaultBlockState(), MediaConstants.CRYSTAL_UNIT * 10)
|
||||
.unlockedBy("enlightenment", enlightenment)
|
||||
.save(recipes, modLoc("brainsweep/budding_amethyst"))
|
||||
|
||||
BrainsweepRecipeBuilder(StateIngredientHelper.of(HexBlocks.EMPTY_IMPETUS),
|
||||
BrainsweepIngredient(ResourceLocation("toolsmith"), null, 2),
|
||||
HexBlocks.IMPETUS_RIGHTCLICK.defaultBlockState())
|
||||
VillagerBrainsweepIngredient(ResourceLocation("toolsmith"), null, 2),
|
||||
HexBlocks.IMPETUS_RIGHTCLICK.defaultBlockState(), MediaConstants.CRYSTAL_UNIT * 10)
|
||||
.unlockedBy("enlightenment", enlightenment)
|
||||
.save(recipes, modLoc("brainsweep/impetus_rightclick"))
|
||||
|
||||
BrainsweepRecipeBuilder(StateIngredientHelper.of(HexBlocks.EMPTY_IMPETUS),
|
||||
BrainsweepIngredient(ResourceLocation("fletcher"), null, 2),
|
||||
HexBlocks.IMPETUS_LOOK.defaultBlockState())
|
||||
VillagerBrainsweepIngredient(ResourceLocation("fletcher"), null, 2),
|
||||
HexBlocks.IMPETUS_LOOK.defaultBlockState(), MediaConstants.CRYSTAL_UNIT * 10)
|
||||
.unlockedBy("enlightenment", enlightenment)
|
||||
.save(recipes, modLoc("brainsweep/impetus_look"))
|
||||
|
||||
BrainsweepRecipeBuilder(StateIngredientHelper.of(HexBlocks.EMPTY_IMPETUS),
|
||||
BrainsweepIngredient(ResourceLocation("cleric"), null, 2),
|
||||
HexBlocks.IMPETUS_STOREDPLAYER.defaultBlockState())
|
||||
VillagerBrainsweepIngredient(ResourceLocation("cleric"), null, 2),
|
||||
HexBlocks.IMPETUS_STOREDPLAYER.defaultBlockState(), MediaConstants.CRYSTAL_UNIT * 10)
|
||||
.unlockedBy("enlightenment", enlightenment)
|
||||
.save(recipes, modLoc("brainsweep/impetus_storedplayer"))
|
||||
|
||||
BrainsweepRecipeBuilder(StateIngredientHelper.of(HexBlocks.EMPTY_DIRECTRIX),
|
||||
BrainsweepIngredient(ResourceLocation("mason"), null, 1),
|
||||
HexBlocks.DIRECTRIX_REDSTONE.defaultBlockState())
|
||||
VillagerBrainsweepIngredient(ResourceLocation("mason"), null, 1),
|
||||
HexBlocks.DIRECTRIX_REDSTONE.defaultBlockState(), MediaConstants.CRYSTAL_UNIT * 10)
|
||||
.unlockedBy("enlightenment", enlightenment)
|
||||
.save(recipes, modLoc("brainsweep/directrix_redstone"))
|
||||
|
||||
BrainsweepRecipeBuilder(StateIngredientHelper.of(HexBlocks.AKASHIC_LIGATURE),
|
||||
BrainsweepIngredient(ResourceLocation("librarian"), null, 5),
|
||||
HexBlocks.AKASHIC_RECORD.defaultBlockState())
|
||||
VillagerBrainsweepIngredient(ResourceLocation("librarian"), null, 5),
|
||||
HexBlocks.AKASHIC_RECORD.defaultBlockState(), MediaConstants.CRYSTAL_UNIT * 10)
|
||||
.unlockedBy("enlightenment", enlightenment)
|
||||
.save(recipes, modLoc("brainsweep/akashic_record"))
|
||||
|
||||
|
|
|
@ -21,16 +21,19 @@ import org.jetbrains.annotations.Nullable;
|
|||
import java.util.function.Consumer;
|
||||
|
||||
public class BrainsweepRecipeBuilder implements RecipeBuilder {
|
||||
private StateIngredient blockIn;
|
||||
private BrainsweepIngredient villagerIn;
|
||||
private final StateIngredient blockIn;
|
||||
private final BrainsweepIngredient villagerIn;
|
||||
private final int mediaCost;
|
||||
private final BlockState result;
|
||||
|
||||
private final Advancement.Builder advancement;
|
||||
|
||||
public BrainsweepRecipeBuilder(StateIngredient blockIn, BrainsweepIngredient villagerIn, BlockState result) {
|
||||
public BrainsweepRecipeBuilder(StateIngredient blockIn, BrainsweepIngredient villagerIn, BlockState result,
|
||||
int mediaCost) {
|
||||
this.blockIn = blockIn;
|
||||
this.villagerIn = villagerIn;
|
||||
this.result = result;
|
||||
this.mediaCost = mediaCost;
|
||||
this.advancement = Advancement.Builder.advancement();
|
||||
}
|
||||
|
||||
|
@ -62,18 +65,19 @@ public class BrainsweepRecipeBuilder implements RecipeBuilder {
|
|||
.requirements(RequirementsStrategy.OR);
|
||||
pFinishedRecipeConsumer.accept(new Result(
|
||||
pRecipeId,
|
||||
this.blockIn, this.villagerIn, this.result,
|
||||
this.blockIn, this.villagerIn, this.mediaCost, this.result,
|
||||
this.advancement,
|
||||
new ResourceLocation(pRecipeId.getNamespace(), "recipes/brainsweep/" + pRecipeId.getPath())));
|
||||
}
|
||||
|
||||
public record Result(ResourceLocation id, StateIngredient blockIn, BrainsweepIngredient villagerIn,
|
||||
BlockState result, Advancement.Builder advancement,
|
||||
int mediaCost, BlockState result, Advancement.Builder advancement,
|
||||
ResourceLocation advancementId) implements FinishedRecipe {
|
||||
@Override
|
||||
public void serializeRecipeData(JsonObject json) {
|
||||
json.add("blockIn", this.blockIn.serialize());
|
||||
json.add("villagerIn", this.villagerIn.serialize());
|
||||
json.add("entityIn", this.villagerIn.serialize());
|
||||
json.addProperty("cost", this.mediaCost);
|
||||
json.add("result", StateIngredientHelper.serializeBlockState(this.result));
|
||||
}
|
||||
|
||||
|
|
|
@ -47,11 +47,11 @@ public class BrainsweepProcessor implements IComponentProcessor {
|
|||
}
|
||||
|
||||
case "entity" -> {
|
||||
var profession = Objects.requireNonNullElse(this.recipe.villagerIn().profession(),
|
||||
var profession = Objects.requireNonNullElse(this.recipe.entityIn().profession(),
|
||||
new ResourceLocation("toolsmith"));
|
||||
var biome = Objects.requireNonNullElse(this.recipe.villagerIn().biome(),
|
||||
var biome = Objects.requireNonNullElse(this.recipe.entityIn().biome(),
|
||||
new ResourceLocation("plains"));
|
||||
var level = this.recipe.villagerIn().minLevel();
|
||||
var level = this.recipe.entityIn().minLevel();
|
||||
var iHatePatchouli = String.format(
|
||||
"minecraft:villager{VillagerData:{profession:'%s',type:'%s',level:%d}}",
|
||||
profession, biome, level);
|
||||
|
@ -59,7 +59,7 @@ public class BrainsweepProcessor implements IComponentProcessor {
|
|||
}
|
||||
case "entityTooltip" -> {
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
return IVariable.wrapList(this.recipe.villagerIn()
|
||||
return IVariable.wrapList(this.recipe.entityIn()
|
||||
.getTooltip(mc.options.advancedItemTooltips)
|
||||
.stream()
|
||||
.map(IVariable::from)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package at.petrak.hexcasting.mixin;
|
||||
|
||||
import at.petrak.hexcasting.common.misc.Brainsweeping;
|
||||
import at.petrak.hexcasting.xplat.IXplatAbstractions;
|
||||
import net.minecraft.world.entity.Mob;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
|
@ -13,7 +13,7 @@ public class MixinMob {
|
|||
@Inject(method = "serverAiStep", at = @At("HEAD"), cancellable = true)
|
||||
private void onRegisterBrainGoals(CallbackInfo ci) {
|
||||
var self = (Mob) (Object) this;
|
||||
if (Brainsweeping.isBrainswept(self)) {
|
||||
if (IXplatAbstractions.INSTANCE.isBrainswept(self)) {
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ public class MixinMob {
|
|||
@Inject(method = "playAmbientSound", at = @At("HEAD"), cancellable = true)
|
||||
protected void onPlayAmbientSound(CallbackInfo ci) {
|
||||
var self = (Mob) (Object) this;
|
||||
if (Brainsweeping.isBrainswept(self)) {
|
||||
if (IXplatAbstractions.INSTANCE.isBrainswept(self)) {
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -253,7 +253,7 @@
|
|||
"command.hexcasting.pats.specific.success": "Gave %s with id %s to %s",
|
||||
"command.hexcasting.recalc": "Recalculated patterns",
|
||||
"command.hexcasting.brainsweep": "Brainswept %s",
|
||||
"command.hexcasting.brainsweep.fail.badtype": "%s is not a villager",
|
||||
"command.hexcasting.brainsweep.fail.badtype": "%s is not a mob",
|
||||
"command.hexcasting.brainsweep.fail.already": "%s is already empty",
|
||||
"hexcasting.pattern.unknown": "Unknown pattern resource location %s",
|
||||
"hexcasting.debug.media_withdrawn": "%s - Media withdrawn: %s",
|
||||
|
@ -561,8 +561,8 @@
|
|||
"hexcasting.mishap.bad_block": "Expected %s at %s, but got %s",
|
||||
"hexcasting.mishap.bad_block.sapling": "a sapling",
|
||||
"hexcasting.mishap.bad_block.replaceable": "somewhere to place a block",
|
||||
"hexcasting.mishap.bad_brainsweep": "The %s rejected the villager's mind",
|
||||
"hexcasting.mishap.already_brainswept": "The villager has already been used",
|
||||
"hexcasting.mishap.bad_brainsweep": "The %s rejected the being's mind",
|
||||
"hexcasting.mishap.already_brainswept": "The mind has already been used",
|
||||
"hexcasting.mishap.no_spell_circle": "%s requires a spell circle",
|
||||
"hexcasting.mishap.others_name": "Tried to invade the privacy of %s's soul",
|
||||
"hexcasting.mishap.others_name.self": "Tried to divulge my Name too recklessly",
|
||||
|
@ -714,7 +714,7 @@
|
|||
"hexcasting.entry.mishaps2": "Enlightened Mishaps",
|
||||
"hexcasting.page.mishaps2.1": "I have discovered new and horrifying modes of failure. I must not succumb to them.",
|
||||
"hexcasting.page.mishaps2.bad_mindflay.title": "Inert Mindflay",
|
||||
"hexcasting.page.mishaps2.bad_mindflay": "Attempted to flay the mind of a villager that I have either already used, or of a character not suitable for the target block.$(br2)Causes dark green sparks, and kills the subject. If another villager sees that, I doubt they would look on it favorably.",
|
||||
"hexcasting.page.mishaps2.bad_mindflay": "Attempted to flay the mind of something that I have either already used, or of a character not suitable for the target block.$(br2)Causes dark green sparks, and kills the subject. If a villager sees that, I doubt they would look on it favorably.",
|
||||
"hexcasting.page.mishaps2.no_circle.title": "Lack Spell Circle",
|
||||
"hexcasting.page.mishaps2.no_circle": "Tried to cast an action requiring a spell circle without a spell circle.$(br2)Causes light blue sparks, and upends my inventory onto the ground.",
|
||||
"hexcasting.page.mishaps2.no_record.title": "Lack Akashic Record",
|
||||
|
|
|
@ -63,8 +63,8 @@ object FabricHexInitializer : ModInitializer {
|
|||
}
|
||||
|
||||
fun initListeners() {
|
||||
UseEntityCallback.EVENT.register(Brainsweeping::tradeWithVillager)
|
||||
VillagerConversionCallback.EVENT.register(Brainsweeping::copyBrainsweepFromVillager)
|
||||
UseEntityCallback.EVENT.register(Brainsweeping::interactWithBrainswept)
|
||||
VillagerConversionCallback.EVENT.register(Brainsweeping::copyBrainsweepPostTransformation)
|
||||
AttackBlockCallback.EVENT.register { player, world, _, pos, _ ->
|
||||
// SUCCESS cancels further processing and, on the client, sends a packet to the server.
|
||||
// PASS falls back to further processing.
|
||||
|
|
|
@ -73,7 +73,7 @@ public class HexEMIPlugin implements EmiPlugin {
|
|||
.getAllRecipesFor(HexRecipeStuffRegistry.BRAINSWEEP_TYPE)) {
|
||||
var inputs = EmiIngredient.of(recipe.blockIn().getDisplayedStacks().stream()
|
||||
.map(EmiStack::of).toList());
|
||||
var villagerInput = VillagerEmiStack.atLevelOrHigher(recipe.villagerIn(), true);
|
||||
var villagerInput = VillagerEmiStack.atLevelOrHigher(recipe.entityIn(), true);
|
||||
var output = EmiStack.of(recipe.result().getBlock());
|
||||
registry.addRecipe(new EmiBrainsweepRecipe(inputs, villagerInput, output, recipe.getId()));
|
||||
}
|
||||
|
|
|
@ -159,7 +159,7 @@ public class ForgeHexInitializer {
|
|||
HexAPI.LOGGER.info(PatternRegistry.getPatternCountInfo()));
|
||||
|
||||
evBus.addListener((PlayerInteractEvent.EntityInteract evt) -> {
|
||||
var res = Brainsweeping.tradeWithVillager(
|
||||
var res = Brainsweeping.interactWithBrainswept(
|
||||
evt.getEntity(), evt.getLevel(), evt.getHand(), evt.getTarget(), null);
|
||||
if (res.consumesAction()) {
|
||||
evt.setCanceled(true);
|
||||
|
@ -167,7 +167,7 @@ public class ForgeHexInitializer {
|
|||
}
|
||||
});
|
||||
evBus.addListener((LivingConversionEvent.Post evt) ->
|
||||
Brainsweeping.copyBrainsweepFromVillager(evt.getEntity(), evt.getOutcome()));
|
||||
Brainsweeping.copyBrainsweepPostTransformation(evt.getEntity(), evt.getOutcome()));
|
||||
|
||||
evBus.addListener((LivingEvent.LivingTickEvent evt) -> {
|
||||
OpFlight.INSTANCE.tickDownFlight(evt.getEntity());
|
||||
|
|
|
@ -70,7 +70,7 @@ public class BrainsweepRecipeCategory implements IRecipeCategory<BrainsweepRecip
|
|||
@NotNull IRecipeSlotsView recipeSlotsView, double mouseX, double mouseY) {
|
||||
if (37 <= mouseX && mouseX <= 37 + 26 && 19 <= mouseY && mouseY <= 19 + 48) {
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
return recipe.villagerIn().getTooltip(mc.options.advancedItemTooltips);
|
||||
return recipe.entityIn().getTooltip(mc.options.advancedItemTooltips);
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
|
@ -81,7 +81,7 @@ public class BrainsweepRecipeCategory implements IRecipeCategory<BrainsweepRecip
|
|||
@NotNull PoseStack stack, double mouseX, double mouseY) {
|
||||
ClientLevel level = Minecraft.getInstance().level;
|
||||
if (level != null) {
|
||||
Villager villager = RenderLib.prepareVillagerForRendering(recipe.villagerIn(), level);
|
||||
Villager villager = RenderLib.prepareVillagerForRendering(recipe.entityIn(), level);
|
||||
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
|
|
Loading…
Reference in a new issue