bang on #419. i'm half-convinced this is a bug in fabric events now?

This commit is contained in:
petrak@ 2023-02-24 11:22:56 -06:00
parent 03e616ad15
commit fae9a2eecd
14 changed files with 135 additions and 37 deletions

View file

@ -2,6 +2,7 @@ package at.petrak.hexcasting.api;
import at.petrak.hexcasting.api.casting.ActionRegistryEntry;
import at.petrak.hexcasting.api.casting.castables.SpecialHandler;
import at.petrak.hexcasting.xplat.IXplatAbstractions;
import com.google.common.base.Suppliers;
import net.minecraft.ChatFormatting;
import net.minecraft.network.chat.Component;
@ -9,10 +10,12 @@ import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.phys.Vec3;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.function.Consumer;
import java.util.function.Supplier;
public interface HexAPI {
@ -87,6 +90,54 @@ public interface HexAPI {
Vec3 getVelocity(T entity);
}
/**
* Register an entity type to have a custom behavior when getting brainswept.
* <p>
* This knocks out the normal behavior; if you want that behavior you should call
*/
default <T extends Mob> void registerCustomBrainsweepingBehavior(EntityType<T> key, Consumer<T> hook) {
}
/**
* The default behavior when an entity gets brainswept.
* <p>
* Something registered with {@link HexAPI#registerCustomBrainsweepingBehavior} doesn't call this automatically;
* you can use this to add things on top of the default behavior
*/
default Consumer<Mob> defaultBrainsweepingBehavior() {
return mob -> {
};
}
/**
* If something special's been returned with {@link HexAPI#registerCustomBrainsweepingBehavior}, return that,
* otherwise return the default behavior
*/
default <T extends Mob> Consumer<T> getBrainsweepBehavior(EntityType<T> mobType) {
return mob -> {
};
}
/**
* Brainsweep (flay the mind of) the given mob.
* <p>
* This ignores the unbrainsweepable tag.
*/
default void brainsweep(Mob mob) {
var type = (EntityType<? extends Mob>) mob.getType();
var behavior = this.getBrainsweepBehavior(type);
var erasedBehavior = (Consumer<Mob>) behavior;
erasedBehavior.accept(mob);
IXplatAbstractions.INSTANCE.setBrainsweepAddlData(mob);
}
default boolean isBrainswept(Mob mob) {
return IXplatAbstractions.INSTANCE.isBrainswept(mob);
}
//
static HexAPI instance() {
return INSTANCE.get();
}

View file

@ -1,10 +1,10 @@
package at.petrak.hexcasting.api.casting.mishaps
import at.petrak.hexcasting.api.misc.FrozenColorizer
import at.petrak.hexcasting.api.misc.HexDamageSources
import at.petrak.hexcasting.api.casting.ParticleSpray
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment
import at.petrak.hexcasting.api.casting.iota.Iota
import at.petrak.hexcasting.api.misc.FrozenColorizer
import at.petrak.hexcasting.api.misc.HexDamageSources
import net.minecraft.core.BlockPos
import net.minecraft.world.entity.Mob
import net.minecraft.world.item.DyeColor
@ -15,7 +15,7 @@ class MishapBadBrainsweep(val mob: Mob, val pos: BlockPos) : Mishap() {
dyeColor(DyeColor.GREEN)
override fun execute(ctx: CastingEnvironment, errorCtx: Context, stack: MutableList<Iota>) {
trulyHurt(mob, HexDamageSources.overcastDamageFrom(ctx.caster), mob.health)
trulyHurt(mob, HexDamageSources.overcastDamageFrom(ctx.caster), 1f)
}
override fun particleSpray(ctx: CastingEnvironment): ParticleSpray {

View file

@ -51,6 +51,8 @@ public class HexTags {
public static final TagKey<EntityType<?>> STICKY_TELEPORTERS = create("sticky_teleporters");
public static final TagKey<EntityType<?>> CANNOT_TELEPORT = create("cannot_teleport");
public static final TagKey<EntityType<?>> NO_BRAINSWEEPING = create("cannot_brainsweep");
public static TagKey<EntityType<?>> create(String name) {
return TagKey.create(Registry.ENTITY_TYPE_REGISTRY, modLoc(name));
}

View file

@ -1,12 +1,16 @@
package at.petrak.hexcasting.common.casting.operators.spells.great
import at.petrak.hexcasting.api.casting.*
import at.petrak.hexcasting.api.casting.ParticleSpray
import at.petrak.hexcasting.api.casting.RenderedSpell
import at.petrak.hexcasting.api.casting.castables.SpellAction
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment
import at.petrak.hexcasting.api.casting.getBlockPos
import at.petrak.hexcasting.api.casting.getMob
import at.petrak.hexcasting.api.casting.iota.Iota
import at.petrak.hexcasting.api.casting.mishaps.MishapAlreadyBrainswept
import at.petrak.hexcasting.api.casting.mishaps.MishapBadBrainsweep
import at.petrak.hexcasting.api.mod.HexConfig
import at.petrak.hexcasting.api.mod.HexTags
import at.petrak.hexcasting.common.recipe.BrainsweepRecipe
import at.petrak.hexcasting.common.recipe.HexRecipeStuffRegistry
import at.petrak.hexcasting.ktxt.tellWitnessesThatIWasMurdered
@ -35,6 +39,9 @@ object OpBrainsweep : SpellAction {
ctx.assertVecInRange(pos)
ctx.assertEntityInRange(sacrifice)
if (sacrifice.type.`is`(HexTags.Entities.NO_BRAINSWEEPING))
throw MishapBadBrainsweep(sacrifice, pos)
if (IXplatAbstractions.INSTANCE.isBrainswept(sacrifice))
throw MishapAlreadyBrainswept(sacrifice)
@ -64,7 +71,7 @@ object OpBrainsweep : SpellAction {
override fun cast(ctx: CastingEnvironment) {
ctx.world.setBlockAndUpdate(pos, BrainsweepRecipe.copyProperties(state, recipe.result))
IXplatAbstractions.INSTANCE.brainsweep(sacrifice)
IXplatAbstractions.INSTANCE.setBrainsweepAddlData(sacrifice)
if (sacrifice is Villager && HexConfig.server().doVillagersTakeOffenseAtMindMurder()) {
sacrifice.tellWitnessesThatIWasMurdered(ctx.caster)
}

View file

@ -1,5 +1,6 @@
package at.petrak.hexcasting.common.command;
import at.petrak.hexcasting.api.HexAPI;
import at.petrak.hexcasting.xplat.IXplatAbstractions;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import net.minecraft.commands.CommandSourceStack;
@ -12,7 +13,7 @@ public class BrainsweepCommand {
public static void add(LiteralArgumentBuilder<CommandSourceStack> cmd) {
cmd.then(Commands.literal("brainsweep")
.requires(dp -> dp.hasPermission(Commands.LEVEL_ADMINS))
.then(Commands.argument("villager", EntityArgument.entity()).executes(ctx -> {
.then(Commands.argument("target", EntityArgument.entity()).executes(ctx -> {
var target = EntityArgument.getEntity(ctx, "target");
if (target instanceof Mob mob) {
if (IXplatAbstractions.INSTANCE.isBrainswept(mob)) {
@ -21,7 +22,7 @@ public class BrainsweepCommand {
mob.getDisplayName()));
return 0;
}
IXplatAbstractions.INSTANCE.brainsweep(mob);
HexAPI.instance().brainsweep(mob);
ctx.getSource().sendSuccess(
Component.translatable("command.hexcasting.brainsweep", mob.getDisplayName()), true);
return 1;

View file

@ -3,17 +3,25 @@ package at.petrak.hexcasting.common.impl;
import at.petrak.hexcasting.api.HexAPI;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.phys.Vec3;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Consumer;
public class HexAPIImpl implements HexAPI {
private static final ConcurrentMap<EntityType<?>, EntityVelocityGetter<?>> SPECIAL_VELOCITIES
= new ConcurrentHashMap<>();
private static final ConcurrentMap<EntityType<?>, Consumer<?>> SPECIAL_BRAINSWEEPS
= new ConcurrentHashMap<>();
public <T extends Entity> void registerSpecialVelocityGetter(EntityType<T> key,
EntityVelocityGetter<T> getter) {
if (SPECIAL_VELOCITIES.containsKey(key)) {
HexAPI.LOGGER.warn("A special velocity getter was already registered to {}, clobbering it!",
key.toString());
}
SPECIAL_VELOCITIES.put(key, getter);
}
@ -27,4 +35,35 @@ public class HexAPIImpl implements HexAPI {
}
return entity.getDeltaMovement();
}
//region brainsweeping
@Override
public <T extends Mob> void registerCustomBrainsweepingBehavior(EntityType<T> key, Consumer<T> hook) {
if (SPECIAL_BRAINSWEEPS.containsKey(key)) {
HexAPI.LOGGER.warn("A special brainsweep hook was already registered to {}, clobbering it!",
key.toString());
}
SPECIAL_BRAINSWEEPS.put(key, hook);
}
@Override
public <T extends Mob> Consumer<T> getBrainsweepBehavior(EntityType<T> mobType) {
var behavior = SPECIAL_BRAINSWEEPS.getOrDefault(mobType, this.defaultBrainsweepingBehavior());
return (Consumer<T>) behavior;
}
@Override
public Consumer<Mob> defaultBrainsweepingBehavior() {
return mob -> {
mob.removeFreeWill();
// TODO: do we add this?
// if (mob instanceof InventoryCarrier inv) {
// inv.getInventory().removeAllItems().forEach(mob::spawnAtLocation);
// }
};
}
//endregion
}

View file

@ -24,7 +24,7 @@ public class BrainsweepingEvents {
public static InteractionResult copyBrainsweepPostTransformation(LivingEntity original, LivingEntity outcome) {
if (original instanceof Mob mOriginal && outcome instanceof Mob mOutcome
&& IXplatAbstractions.INSTANCE.isBrainswept(mOriginal)) {
IXplatAbstractions.INSTANCE.brainsweep(mOutcome);
IXplatAbstractions.INSTANCE.setBrainsweepAddlData(mOutcome);
}
return InteractionResult.PASS;
}

View file

@ -2,12 +2,14 @@ package at.petrak.hexcasting.common.misc;
import at.petrak.hexcasting.api.HexAPI;
import at.petrak.hexcasting.mixin.accessor.AccessorAbstractArrow;
import at.petrak.hexcasting.mixin.accessor.AccessorVillager;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.ai.memory.MemoryModuleType;
import net.minecraft.world.entity.projectile.AbstractArrow;
import net.minecraft.world.phys.Vec3;
public class VelocityFudging {
public class RegisterMisc {
public static void register() {
HexAPI.instance().registerSpecialVelocityGetter(EntityType.PLAYER, player -> {
if (player instanceof ServerPlayer splayer) {
@ -18,10 +20,19 @@ public class VelocityFudging {
}
});
HexAPI.instance().registerSpecialVelocityGetter(EntityType.ARROW, VelocityFudging::arrowVelocitizer);
HexAPI.instance().registerSpecialVelocityGetter(EntityType.SPECTRAL_ARROW, VelocityFudging::arrowVelocitizer);
HexAPI.instance().registerSpecialVelocityGetter(EntityType.ARROW, RegisterMisc::arrowVelocitizer);
HexAPI.instance().registerSpecialVelocityGetter(EntityType.SPECTRAL_ARROW, RegisterMisc::arrowVelocitizer);
// this is an arrow apparently
HexAPI.instance().registerSpecialVelocityGetter(EntityType.TRIDENT, VelocityFudging::arrowVelocitizer);
HexAPI.instance().registerSpecialVelocityGetter(EntityType.TRIDENT, RegisterMisc::arrowVelocitizer);
HexAPI.instance().registerCustomBrainsweepingBehavior(EntityType.VILLAGER, villager -> {
((AccessorVillager) villager).hex$releaseAllPois();
HexAPI.instance().defaultBrainsweepingBehavior().accept(villager);
});
HexAPI.instance().registerCustomBrainsweepingBehavior(EntityType.ALLAY, allay -> {
allay.getBrain().eraseMemory(MemoryModuleType.LIKED_PLAYER);
HexAPI.instance().defaultBrainsweepingBehavior().accept(allay);
});
}
private static Vec3 arrowVelocitizer(AbstractArrow arrow) {

View file

@ -70,9 +70,12 @@ public interface IXplatAbstractions {
// Things that used to be caps
/**
* Irregardless of whether it can actually be brainswept (you need to do the checking yourself)
* Doesn't actually knock out its AI or anything anymore, just sets caps/ccs
*/
void brainsweep(Mob mob);
// heheheheh addled data
void setBrainsweepAddlData(Mob mob);
boolean isBrainswept(Mob mob);
void setColorizer(Player target, FrozenColorizer colorizer);
@ -86,8 +89,6 @@ public interface IXplatAbstractions {
void setPatterns(ServerPlayer target, List<ResolvedPattern> patterns);
boolean isBrainswept(Mob mob);
@Nullable FlightAbility getFlight(ServerPlayer player);
@Nullable AltioraAbility getAltiora(Player player);

View file

@ -23,7 +23,7 @@ import at.petrak.hexcasting.common.lib.hex.HexSpecialHandlers
import at.petrak.hexcasting.common.misc.AkashicTreeGrower
import at.petrak.hexcasting.common.misc.BrainsweepingEvents
import at.petrak.hexcasting.common.misc.PlayerPositionRecorder
import at.petrak.hexcasting.common.misc.VelocityFudging
import at.petrak.hexcasting.common.misc.RegisterMisc
import at.petrak.hexcasting.common.recipe.HexRecipeStuffRegistry
import at.petrak.hexcasting.fabric.event.VillagerConversionCallback
import at.petrak.hexcasting.fabric.interop.gravity.GravityApiInterop
@ -75,7 +75,7 @@ object FabricHexInitializer : ModInitializer {
FabricImpetusStorage.registerStorage()
HexInterop.init()
VelocityFudging.register()
RegisterMisc.register()
}
fun initListeners() {

View file

@ -24,7 +24,6 @@ import at.petrak.hexcasting.fabric.interop.trinkets.TrinketsApiInterop;
import at.petrak.hexcasting.fabric.recipe.FabricUnsealedIngredient;
import at.petrak.hexcasting.interop.HexInterop;
import at.petrak.hexcasting.interop.pehkui.PehkuiInterop;
import at.petrak.hexcasting.mixin.accessor.AccessorVillager;
import at.petrak.hexcasting.xplat.IXplatAbstractions;
import at.petrak.hexcasting.xplat.IXplatTags;
import at.petrak.hexcasting.xplat.Platform;
@ -60,7 +59,6 @@ import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.npc.Villager;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.*;
import net.minecraft.world.item.crafting.Ingredient;
@ -136,15 +134,10 @@ public class FabricXplatImpl implements IXplatAbstractions {
}
@Override
public void brainsweep(Mob mob) {
public void setBrainsweepAddlData(Mob mob) {
var cc = HexCardinalComponents.BRAINSWEPT.get(mob);
cc.setBrainswept(true);
// CC API does the syncing for us
mob.removeFreeWill();
if (mob instanceof Villager villager) {
((AccessorVillager) villager).hex$releaseAllPois();
}
}
@Override

View file

@ -20,7 +20,7 @@ import at.petrak.hexcasting.common.lib.hex.HexSpecialHandlers;
import at.petrak.hexcasting.common.misc.AkashicTreeGrower;
import at.petrak.hexcasting.common.misc.BrainsweepingEvents;
import at.petrak.hexcasting.common.misc.PlayerPositionRecorder;
import at.petrak.hexcasting.common.misc.VelocityFudging;
import at.petrak.hexcasting.common.misc.RegisterMisc;
import at.petrak.hexcasting.common.recipe.HexRecipeStuffRegistry;
import at.petrak.hexcasting.forge.cap.CapSyncers;
import at.petrak.hexcasting.forge.cap.ForgeCapabilityHandler;
@ -117,7 +117,7 @@ public class ForgeHexInitializer {
HexAdvancementTriggers.registerTriggers();
VelocityFudging.register();
RegisterMisc.register();
}
// https://github.com/VazkiiMods/Botania/blob/1.18.x/Forge/src/main/java/vazkii/botania/forge/ForgeCommonInitializer.java

View file

@ -46,7 +46,7 @@ public record MsgBrainsweepAck(int target) implements IMessage {
if (level != null) {
Entity entity = level.getEntity(msg.target());
if (entity instanceof Mob living) {
IXplatAbstractions.INSTANCE.brainsweep(living);
IXplatAbstractions.INSTANCE.setBrainsweepAddlData(living);
}
}
}

View file

@ -31,7 +31,6 @@ import at.petrak.hexcasting.forge.network.MsgBrainsweepAck;
import at.petrak.hexcasting.forge.recipe.ForgeUnsealedIngredient;
import at.petrak.hexcasting.interop.HexInterop;
import at.petrak.hexcasting.interop.pehkui.PehkuiInterop;
import at.petrak.hexcasting.mixin.accessor.AccessorVillager;
import at.petrak.hexcasting.xplat.IXplatAbstractions;
import at.petrak.hexcasting.xplat.IXplatTags;
import at.petrak.hexcasting.xplat.Platform;
@ -54,7 +53,6 @@ import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
import net.minecraft.world.entity.npc.Villager;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.Item;
@ -126,14 +124,9 @@ public class ForgeXplatImpl implements IXplatAbstractions {
}
@Override
public void brainsweep(Mob mob) {
public void setBrainsweepAddlData(Mob mob) {
mob.getPersistentData().putBoolean(TAG_BRAINSWEPT, true);
mob.removeFreeWill();
if (mob instanceof Villager villager) {
((AccessorVillager) villager).hex$releaseAllPois();
}
if (mob.level instanceof ServerLevel) {
ForgePacketHandler.getNetwork()
.send(PacketDistributor.TRACKING_ENTITY.with(() -> mob), MsgBrainsweepAck.of(mob));