Add config for mob execution and knocked effects
This commit is contained in:
@@ -3,16 +3,20 @@ package net.fretux.knockedback;
|
||||
import net.fretux.knockedback.config.Config;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.effect.MobEffect;
|
||||
import net.minecraft.world.effect.MobEffectInstance;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.Pose;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.event.TickEvent;
|
||||
import net.minecraftforge.event.entity.living.LivingHurtEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.network.PacketDistributor;
|
||||
import net.minecraftforge.event.entity.player.PlayerEvent;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -42,6 +46,7 @@ public class KnockedManager {
|
||||
if (!isKnocked(entity)) {
|
||||
knockedEntities.put(entity.getUUID(), getKnockedDuration());
|
||||
entity.setHealth(1.0F);
|
||||
applyKnockedEffects((Player) entity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,6 +112,7 @@ public class KnockedManager {
|
||||
|| CarryManager.isBeingCarried(playerId)) {
|
||||
ServerPlayer p = NetworkHandlerHelper.getPlayerByUuid(server, playerId);
|
||||
if (p != null) {
|
||||
applyKnockedEffects(p);
|
||||
NetworkHandler.CHANNEL.send(
|
||||
PacketDistributor.PLAYER.with(() -> p),
|
||||
new KnockedTimePacket(timeLeft)
|
||||
@@ -118,6 +124,7 @@ public class KnockedManager {
|
||||
|| PlayerExecutionHandler.isBeingPlayerExecuted(playerId)) {
|
||||
ServerPlayer p = NetworkHandlerHelper.getPlayerByUuid(server, playerId);
|
||||
if (p != null) {
|
||||
applyKnockedEffects(p);
|
||||
NetworkHandler.CHANNEL.send(
|
||||
PacketDistributor.PLAYER.with(() -> p),
|
||||
new KnockedTimePacket(timeLeft)
|
||||
@@ -139,6 +146,7 @@ public class KnockedManager {
|
||||
entry.setValue(timeLeft);
|
||||
ServerPlayer p = NetworkHandlerHelper.getPlayerByUuid(server, playerId);
|
||||
if (p != null) {
|
||||
applyKnockedEffects(p);
|
||||
NetworkHandler.CHANNEL.send(
|
||||
PacketDistributor.PLAYER.with(() -> p),
|
||||
new KnockedTimePacket(timeLeft)
|
||||
@@ -186,6 +194,7 @@ public class KnockedManager {
|
||||
return;
|
||||
}
|
||||
knockedEntities.put(player.getUUID(), getKnockedDuration());
|
||||
applyKnockedEffects(player);
|
||||
event.setCanceled(true);
|
||||
}
|
||||
|
||||
@@ -209,4 +218,57 @@ public class KnockedManager {
|
||||
new GrippedStatePacket(playerId, false)
|
||||
);
|
||||
}
|
||||
|
||||
private static void applyKnockedEffects(Player player) {
|
||||
List<? extends String> configured = Config.COMMON.knockedPotionEffects.get();
|
||||
if (configured.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (String entry : configured) {
|
||||
MobEffectInstance instance = parseEffect(entry);
|
||||
if (instance == null) {
|
||||
continue;
|
||||
}
|
||||
MobEffect effect = instance.getEffect();
|
||||
MobEffectInstance existing = player.getEffect(effect);
|
||||
if (existing == null || existing.getDuration() < 20 || existing.getAmplifier() < instance.getAmplifier()) {
|
||||
player.addEffect(instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static MobEffectInstance parseEffect(String entry) {
|
||||
if (entry == null || entry.isBlank()) {
|
||||
return null;
|
||||
}
|
||||
String[] parts = entry.split(",");
|
||||
if (parts.length < 3) {
|
||||
return null;
|
||||
}
|
||||
ResourceLocation effectId = ResourceLocation.tryParse(parts[0].trim());
|
||||
if (effectId == null) {
|
||||
return null;
|
||||
}
|
||||
MobEffect effect = ForgeRegistries.MOB_EFFECTS.getValue(effectId);
|
||||
if (effect == null) {
|
||||
return null;
|
||||
}
|
||||
Integer duration = parseInt(parts[1].trim());
|
||||
Integer amplifier = parseInt(parts[2].trim());
|
||||
if (duration == null || amplifier == null) {
|
||||
return null;
|
||||
}
|
||||
boolean ambient = parts.length > 3 ? Boolean.parseBoolean(parts[3].trim()) : false;
|
||||
boolean visible = parts.length > 4 ? Boolean.parseBoolean(parts[4].trim()) : true;
|
||||
boolean showIcon = parts.length > 5 ? Boolean.parseBoolean(parts[5].trim()) : true;
|
||||
return new MobEffectInstance(effect, duration, amplifier, ambient, visible, showIcon);
|
||||
}
|
||||
|
||||
private static Integer parseInt(String value) {
|
||||
try {
|
||||
return Integer.parseInt(value);
|
||||
} catch (NumberFormatException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,11 +7,13 @@ import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.event.TickEvent;
|
||||
import net.minecraftforge.event.entity.living.LivingHurtEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.network.PacketDistributor;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
@@ -156,7 +158,7 @@ public class MobKillHandler {
|
||||
p.getX() + r, p.getY() + r, p.getZ() + r
|
||||
);
|
||||
return world.getEntitiesOfClass(Mob.class, box).stream()
|
||||
.filter(m -> isHostile(m) || isAggressiveNeutral(m, p))
|
||||
.filter(m -> (isHostile(m) || isAggressiveNeutral(m, p)) && isMobAllowedToExecute(m))
|
||||
.findAny().orElse(null);
|
||||
}
|
||||
|
||||
@@ -169,10 +171,19 @@ public class MobKillHandler {
|
||||
p.getX() + r, p.getY() + r, p.getZ() + r
|
||||
);
|
||||
return world.getEntitiesOfClass(Mob.class, box).stream()
|
||||
.filter(m -> m.getUUID().equals(mobId))
|
||||
.filter(m -> m.getUUID().equals(mobId) && isMobAllowedToExecute(m))
|
||||
.findAny().orElse(null);
|
||||
}
|
||||
|
||||
private boolean isMobAllowedToExecute(Mob mob) {
|
||||
List<? extends String> allowlist = Config.COMMON.mobExecutionAllowlist.get();
|
||||
if (allowlist.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
ResourceLocation id = ForgeRegistries.ENTITY_TYPES.getKey(mob.getType());
|
||||
return id != null && allowlist.contains(id.toString());
|
||||
}
|
||||
|
||||
|
||||
private boolean isHostile(Mob m) {
|
||||
return m instanceof net.minecraft.world.entity.monster.Monster;
|
||||
|
||||
@@ -2,6 +2,8 @@ package net.fretux.knockedback.config;
|
||||
|
||||
import net.minecraftforge.common.ForgeConfigSpec;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Config {
|
||||
public static final ForgeConfigSpec COMMON_SPEC;
|
||||
public static final Common COMMON;
|
||||
@@ -16,6 +18,8 @@ public class Config {
|
||||
public final ForgeConfigSpec.IntValue knockedDuration;
|
||||
public final ForgeConfigSpec.IntValue executionTime;
|
||||
public final ForgeConfigSpec.BooleanValue totemPreventsKnockdown;
|
||||
public final ForgeConfigSpec.ConfigValue<List<? extends String>> mobExecutionAllowlist;
|
||||
public final ForgeConfigSpec.ConfigValue<List<? extends String>> knockedPotionEffects;
|
||||
|
||||
public Common(ForgeConfigSpec.Builder builder) {
|
||||
builder.push("general");
|
||||
@@ -28,6 +32,18 @@ public class Config {
|
||||
.comment("How long (in ticks) it takes to execute a knocked player. Default: 60 (3 seconds).")
|
||||
.defineInRange("executionTime", 60, 20, 200);
|
||||
|
||||
mobExecutionAllowlist = builder
|
||||
.comment("List of entity ids allowed to execute knocked players.",
|
||||
"If empty, any hostile/aggro mob can execute.",
|
||||
"Example: [\"minecraft:zombie\", \"modid:custom_mob\"]")
|
||||
.defineListAllowEmpty("mobExecutionAllowlist", List.of(), o -> o instanceof String);
|
||||
|
||||
knockedPotionEffects = builder
|
||||
.comment("Potion effects to apply while a player is knocked.",
|
||||
"Format: effect_id,duration,amplifier[,ambient][,visible][,showIcon]",
|
||||
"Example: [\"minecraft:slowness,200,1\", \"minecraft:weakness,200,0,true,false,false\"]")
|
||||
.defineListAllowEmpty("knockedPotionEffects", List.of(), o -> o instanceof String);
|
||||
|
||||
builder.pop().push("damage_behavior");
|
||||
|
||||
totemPreventsKnockdown = builder
|
||||
|
||||
Reference in New Issue
Block a user