Skip to content

Commit

Permalink
close #4356
Browse files Browse the repository at this point in the history
  • Loading branch information
yrsegal committed Sep 30, 2023
1 parent 0f2df17 commit 3ea6a0a
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 36 deletions.
42 changes: 35 additions & 7 deletions src/main/java/vazkii/quark/base/handler/MiscUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.MobSpawnType;
import net.minecraft.world.entity.ai.goal.Goal;
import net.minecraft.world.entity.ai.goal.GoalSelector;
import net.minecraft.world.entity.ai.goal.WrappedGoal;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.enchantment.Enchantment;
Expand All @@ -56,7 +59,6 @@
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.minecraftforge.fml.util.ObfuscationReflectionHelper;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
import net.minecraftforge.items.ItemStackHandler;
Expand All @@ -70,12 +72,7 @@
import vazkii.quark.mixin.accessor.AccessorLootTable;

import javax.annotation.Nonnull;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Random;
import java.util.*;
import java.util.stream.Collectors;

@EventBusSubscriber(modid = Quark.MOD_ID)
Expand Down Expand Up @@ -105,6 +102,37 @@ public static BooleanProperty directionProperty(Direction direction) {
};
}

/**
* Reconstructs the goal selector's list to add in a new goal.
*
* This is because vanilla doesn't play it safe around CMEs with skeletons.
* See: https://github.com/VazkiiMods/Quark/issues/4356
*
* If a Skeleton is killed with Thorns damage and drops its weapon, it will reassess its goals.
* Because the thorns damage is being dealt during goal execution of the MeleeAttackGoal or RangedBowAttackGoal,
* this will cause a CME if the attack goal is not the VERY LAST goal in the set.
*
* Thankfully, the set GoalSelector uses is Linked, so we can just reconstruct the set and avoid the problem.
*/
public static void addGoalJustAfterLatestWithPriority(GoalSelector selector, int priority, Goal goal) {
Set<WrappedGoal> allGoals = new LinkedHashSet<>(selector.getAvailableGoals());
WrappedGoal latestWithPriority = null;
for (WrappedGoal wrappedGoal : allGoals) {
if (wrappedGoal.getPriority() == priority)
latestWithPriority = wrappedGoal;
}

selector.removeAllGoals();
if (latestWithPriority == null)
selector.addGoal(priority, goal);

for (WrappedGoal wrappedGoal : allGoals) {
selector.addGoal(wrappedGoal.getPriority(), wrappedGoal.getGoal());
if (wrappedGoal == latestWithPriority)
selector.addGoal(priority, goal);
}
}

@OnlyIn(Dist.CLIENT)
public static void drawChatBubble(PoseStack matrix, int x, int y, Font font, String text, float alpha, boolean extendRight) {
matrix.pushPose();
Expand Down
13 changes: 12 additions & 1 deletion src/main/java/vazkii/quark/base/module/ModuleLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ public final class ModuleLoader {
private enum Step {
CONSTRUCT, CONSTRUCT_CLIENT, REGISTER, POST_REGISTER, CONFIG_CHANGED, CONFIG_CHANGED_CLIENT, SETUP, SETUP_CLIENT,
REGISTER_RELOADABLE, MODEL_BAKE, MODEL_LAYERS, TEXTURE_STITCH, POST_TEXTURE_STITCH, LOAD_COMPLETE, GENERATE_HINTS,
FIRST_CLIENT_TICK, REGISTER_KEYBINDS, REGISTER_ADDITIONAL_MODELS, REGISTER_TOOLTIP_COMPONENT_FACTORIES
FIRST_CLIENT_TICK, REGISTER_KEYBINDS, REGISTER_ADDITIONAL_MODELS, REGISTER_TOOLTIP_COMPONENT_FACTORIES,
REGISTER_ITEM_COLORS, REGISTER_BLOCK_COLORS
}

public static final ModuleLoader INSTANCE = new ModuleLoader();
Expand Down Expand Up @@ -152,6 +153,16 @@ public void registerClientTooltipComponentFactories(RegisterClientTooltipCompone
dispatch(Step.REGISTER_TOOLTIP_COMPONENT_FACTORIES, m -> m.registerClientTooltipComponentFactories(event));
}

@OnlyIn(Dist.CLIENT)
public void registerItemColors(RegisterColorHandlersEvent.Item event) {
dispatch(Step.REGISTER_ITEM_COLORS, m -> m.registerItemColors(event));
}

@OnlyIn(Dist.CLIENT)
public void registerBlockColors(RegisterColorHandlersEvent.Block event) {
dispatch(Step.REGISTER_BLOCK_COLORS, m -> m.registerBlockColors(event));
}

public void loadComplete(ParallelDispatchEvent event) {
this.event = event;
dispatch(Step.LOAD_COMPLETE, QuarkModule::loadComplete);
Expand Down
34 changes: 17 additions & 17 deletions src/main/java/vazkii/quark/base/module/QuarkModule.java
Original file line number Diff line number Diff line change
@@ -1,35 +1,25 @@
package vazkii.quark.base.module;

import java.util.List;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Supplier;

import com.google.common.collect.Lists;

import net.minecraft.core.Registry;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.packs.resources.PreparableReloadListener;
import net.minecraft.world.item.Item;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.event.EntityRenderersEvent;
import net.minecraftforge.client.event.ModelEvent;
import net.minecraftforge.client.event.RegisterClientTooltipComponentFactoriesEvent;
import net.minecraftforge.client.event.RegisterKeyMappingsEvent;
import net.minecraftforge.client.event.TextureStitchEvent;
import net.minecraftforge.client.event.*;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.ModList;
import net.minecraftforge.fml.loading.FMLEnvironment;
import vazkii.arl.util.RegistryHelper;
import vazkii.quark.api.event.ModuleLoadedEvent;
import vazkii.quark.api.event.ModuleStateChangedEvent;
import vazkii.quark.base.Quark;
import vazkii.quark.base.module.config.ConfigFlagManager;
import vazkii.quark.base.module.hint.HintObject;

import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer;

public class QuarkModule {

public ModuleCategory category = null;
Expand Down Expand Up @@ -127,6 +117,16 @@ public void registerAdditionalModels(ModelEvent.RegisterAdditional event) {
// NO-OP
}

@OnlyIn(Dist.CLIENT)
public void registerItemColors(RegisterColorHandlersEvent.Item event) {
// NO-OP
}

@OnlyIn(Dist.CLIENT)
public void registerBlockColors(RegisterColorHandlersEvent.Block event) {
// NO-OP
}

@OnlyIn(Dist.CLIENT)
public void registerClientTooltipComponentFactories(RegisterClientTooltipComponentFactoriesEvent event) {
// NO-OP
Expand All @@ -139,15 +139,15 @@ public void loadComplete() {
public final void addStackInfo(BiConsumer<Item, Component> consumer) {
if(!enabled)
return;

for(HintObject hint : hints)
hint.apply(consumer);
addAdditionalHints(consumer);
}

public void addAdditionalHints(BiConsumer<Item, Component> consumer) {

}
}

@OnlyIn(Dist.CLIENT)
public void firstClientTick() {
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/vazkii/quark/base/proxy/ClientProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ public void registerListeners(IEventBus bus) {
bus.addListener(this::registerKeybinds);
bus.addListener(this::registerAdditionalModels);
bus.addListener(this::registerClientTooltipComponentFactories);
bus.addListener(this::registerItemColors);
bus.addListener(this::registerBlockColors);
}

public void clientSetup(FMLClientSetupEvent event) {
Expand Down Expand Up @@ -115,6 +117,16 @@ public void registerClientTooltipComponentFactories(RegisterClientTooltipCompone
ModuleLoader.INSTANCE.registerClientTooltipComponentFactories(event);
}

@OnlyIn(Dist.CLIENT)
public void registerItemColors(RegisterColorHandlersEvent.Item event) {
ModuleLoader.INSTANCE.registerItemColors(event);
}

@OnlyIn(Dist.CLIENT)
public void registerBlockColors(RegisterColorHandlersEvent.Block event) {
ModuleLoader.INSTANCE.registerBlockColors(event);
}

@Override
public void handleQuarkConfigChange() {
super.handleQuarkConfigChange();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.event.RegisterColorHandlersEvent;
import net.minecraftforge.eventbus.api.EventPriority;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.registries.ForgeRegistries;
import vazkii.arl.util.ItemNBTHelper;
import vazkii.quark.base.Quark;
Expand All @@ -39,7 +37,7 @@
import java.util.function.BooleanSupplier;
import java.util.function.IntUnaryOperator;

@LoadModule(category = ModuleCategory.CLIENT, subscribeOn = Dist.CLIENT)
@LoadModule(category = ModuleCategory.CLIENT)
public class BucketsShowInhabitantsModule extends QuarkModule {

@Config
Expand Down Expand Up @@ -70,8 +68,8 @@ public void clientSetup() {
});
}

@Override
@OnlyIn(Dist.CLIENT)
@SubscribeEvent(priority = EventPriority.LOWEST)
public void registerItemColors(RegisterColorHandlersEvent.Item evt) {
Holder.Reference<Item> tropicalBucket = ForgeRegistries.ITEMS.getDelegateOrThrow(Items.TROPICAL_FISH_BUCKET);
ItemColor parent = ((AccessorItemColors) evt.getItemColors()).quark$getItemColors().get(tropicalBucket);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import net.minecraftforge.eventbus.api.SubscribeEvent;
import vazkii.arl.util.RegistryHelper;
import vazkii.quark.base.Quark;
import vazkii.quark.base.handler.MiscUtil;
import vazkii.quark.base.module.LoadModule;
import vazkii.quark.base.module.ModuleCategory;
import vazkii.quark.base.module.QuarkModule;
Expand All @@ -36,7 +37,7 @@ public class SkullPikesModule extends QuarkModule {

public static EntityType<SkullPike> skullPikeType;

@Hint(key = "skull_pikes")
@Hint(key = "skull_pikes")
public static TagKey<Block> pikeTrophiesTag;

@Config public static double pikeRange = 5;
Expand Down Expand Up @@ -92,7 +93,7 @@ public void onMonsterAppear(EntityJoinLevelEvent event) {
boolean alreadySetUp = monster.goalSelector.getAvailableGoals().stream().anyMatch((goal) -> goal.getGoal() instanceof RunAwayFromPikesGoal);

if (!alreadySetUp)
monster.goalSelector.addGoal(3, new RunAwayFromPikesGoal(monster, (float) pikeRange, 1.0D, 1.2D));
MiscUtil.addGoalJustAfterLatestWithPriority(monster.goalSelector, 3, new RunAwayFromPikesGoal(monster, (float) pikeRange, 1.0D, 1.2D));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import net.minecraftforge.event.entity.living.AnimalTameEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import vazkii.quark.base.handler.MiscUtil;
import vazkii.quark.base.handler.QuarkSounds;
import vazkii.quark.base.module.LoadModule;
import vazkii.quark.base.module.ModuleCategory;
Expand Down Expand Up @@ -50,8 +51,8 @@ public void onWolfAppear(EntityJoinLevelEvent event) {
boolean alreadySetUp = wolf.goalSelector.getAvailableGoals().stream().anyMatch((goal) -> goal.getGoal() instanceof WantLoveGoal);

if (!alreadySetUp) {
wolf.goalSelector.addGoal(4, new NuzzleGoal(wolf, 0.5F, 16, 2, SoundEvents.WOLF_WHINE));
wolf.goalSelector.addGoal(5, new WantLoveGoal(wolf, 0.2F));
MiscUtil.addGoalJustAfterLatestWithPriority(wolf.goalSelector, 4, new NuzzleGoal(wolf, 0.5F, 16, 2, SoundEvents.WOLF_WHINE));
MiscUtil.addGoalJustAfterLatestWithPriority(wolf.goalSelector, 5, new WantLoveGoal(wolf, 0.2F));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import net.minecraftforge.event.entity.living.LivingEvent;
import net.minecraftforge.eventbus.api.EventPriority;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import vazkii.quark.base.handler.MiscUtil;
import vazkii.quark.base.module.LoadModule;
import vazkii.quark.base.module.ModuleCategory;
import vazkii.quark.base.module.ModuleLoader;
Expand Down Expand Up @@ -80,7 +81,7 @@ public void onPigAppear(EntityJoinLevelEvent event) {
.orElse(-1);

if (priority >= 0)
pig.goalSelector.addGoal(4, new TemptGoal(pig, 1.2D, Ingredient.of(Items.GOLDEN_CARROT), false));
MiscUtil.addGoalJustAfterLatestWithPriority(pig.goalSelector, 4, new TemptGoal(pig, 1.2D, Ingredient.of(Items.GOLDEN_CARROT), false));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraftforge.event.entity.EntityJoinLevelEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import vazkii.quark.base.handler.MiscUtil;
import vazkii.quark.base.module.LoadModule;
import vazkii.quark.base.module.ModuleCategory;
import vazkii.quark.base.module.QuarkModule;
Expand All @@ -18,7 +19,7 @@
*/
@LoadModule(category = ModuleCategory.TWEAKS, hasSubscriptions = true)
public class VillagersFollowEmeraldsModule extends QuarkModule {

@Hint Item emerald_block = Items.EMERALD_BLOCK;

@SubscribeEvent
Expand All @@ -28,7 +29,7 @@ public void onVillagerAppear(EntityJoinLevelEvent event) {

if (!alreadySetUp)
try {
villager.goalSelector.addGoal(2, new TemptGoal(villager, 0.6, Ingredient.of(Items.EMERALD_BLOCK), false));
MiscUtil.addGoalJustAfterLatestWithPriority(villager.goalSelector, 2, new TemptGoal(villager, 0.6, Ingredient.of(Items.EMERALD_BLOCK), false));
} catch(IllegalArgumentException e) {
// This appears to be a weird bug that happens when a villager is riding something and its chunk unloads
}
Expand Down

0 comments on commit 3ea6a0a

Please sign in to comment.