fix some additional issues.
This commit is contained in:
@@ -132,15 +132,14 @@ public final class AdaptiveSpecialAbilities {
|
|||||||
if (event.phase != TickEvent.Phase.END || event.getServer() == null) {
|
if (event.phase != TickEvent.Phase.END || event.getServer() == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
long now = event.getServer().overworld().getGameTime();
|
|
||||||
Iterator<TemporaryBlock> blockIterator = TEMPORARY_BLOCKS.iterator();
|
Iterator<TemporaryBlock> blockIterator = TEMPORARY_BLOCKS.iterator();
|
||||||
while (blockIterator.hasNext()) {
|
while (blockIterator.hasNext()) {
|
||||||
TemporaryBlock block = blockIterator.next();
|
TemporaryBlock block = blockIterator.next();
|
||||||
if (now < block.expireTick) {
|
ServerLevel level = block.server == event.getServer() ? event.getServer().getLevel(block.dimension) : null;
|
||||||
|
if (level == null || level.getGameTime() < block.expireTick) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ServerLevel level = block.server == event.getServer() ? event.getServer().getLevel(block.dimension) : null;
|
if (level.getBlockState(block.pos).is(Blocks.COBWEB)) {
|
||||||
if (level != null && level.getBlockState(block.pos).is(Blocks.COBWEB)) {
|
|
||||||
level.removeBlock(block.pos, false);
|
level.removeBlock(block.pos, false);
|
||||||
}
|
}
|
||||||
blockIterator.remove();
|
blockIterator.remove();
|
||||||
@@ -149,12 +148,12 @@ public final class AdaptiveSpecialAbilities {
|
|||||||
Iterator<DelayedReappear> reappearIterator = DELAYED_REAPPEARS.iterator();
|
Iterator<DelayedReappear> reappearIterator = DELAYED_REAPPEARS.iterator();
|
||||||
while (reappearIterator.hasNext()) {
|
while (reappearIterator.hasNext()) {
|
||||||
DelayedReappear pending = reappearIterator.next();
|
DelayedReappear pending = reappearIterator.next();
|
||||||
if (now < pending.tick) {
|
ServerLevel level = pending.server == event.getServer() ? event.getServer().getLevel(pending.dimension) : null;
|
||||||
|
if (level == null || level.getGameTime() < pending.tick) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ServerLevel level = pending.server == event.getServer() ? event.getServer().getLevel(pending.dimension) : null;
|
Entity mobEntity = level.getEntity(pending.mobId);
|
||||||
Entity mobEntity = level == null ? null : level.getEntity(pending.mobId);
|
Entity targetEntity = level.getEntity(pending.targetId);
|
||||||
Entity targetEntity = level == null ? null : level.getEntity(pending.targetId);
|
|
||||||
if (mobEntity instanceof Silverfish mob && targetEntity instanceof LivingEntity target
|
if (mobEntity instanceof Silverfish mob && targetEntity instanceof LivingEntity target
|
||||||
&& mob.isAlive() && AdaptiveAIGoalUtils.isValidAdaptiveTarget(target) && mob.canAttack(target)) {
|
&& mob.isAlive() && AdaptiveAIGoalUtils.isValidAdaptiveTarget(target) && mob.canAttack(target)) {
|
||||||
Vec3 side = AdaptivePositioningUtils.sidePosition(mob, target, 1.6D,
|
Vec3 side = AdaptivePositioningUtils.sidePosition(mob, target, 1.6D,
|
||||||
|
|||||||
@@ -56,8 +56,9 @@ public final class AdaptiveMobsCommands {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static int setTier(CommandSourceStack source, int tier) {
|
private static int setTier(CommandSourceStack source, int tier) {
|
||||||
AdaptiveSavedData.get(source.getLevel()).setManualGlobalTier(Math.min(tier, AMConfig.maxTier));
|
int appliedTier = Math.min(tier, AMConfig.maxTier);
|
||||||
source.sendSuccess(() -> Component.literal("Adaptive Mobs: manual global tier set to " + tier), true);
|
AdaptiveSavedData.get(source.getLevel()).setManualGlobalTier(appliedTier);
|
||||||
|
source.sendSuccess(() -> Component.literal("Adaptive Mobs: manual global tier set to " + appliedTier), true);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -268,12 +268,10 @@ public final class AMConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static int tierValueInt(List<? extends Integer> list, int tier1based) {
|
public static int tierValueInt(List<? extends Integer> list, int tier1based) {
|
||||||
if (list == null || list.isEmpty()) {
|
if (list == null || tier1based <= 0 || tier1based > list.size()) {
|
||||||
return Integer.MAX_VALUE;
|
return Integer.MAX_VALUE;
|
||||||
}
|
}
|
||||||
int idx = Math.min(tier1based, list.size()) - 1;
|
return list.get(tier1based - 1);
|
||||||
idx = Math.max(0, idx);
|
|
||||||
return list.get(idx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int aiScanCooldown(net.minecraft.util.RandomSource random) {
|
public static int aiScanCooldown(net.minecraft.util.RandomSource random) {
|
||||||
|
|||||||
@@ -86,7 +86,8 @@ public final class AdaptiveDifficultyManager {
|
|||||||
|
|
||||||
private static int tierFromDay(long day) {
|
private static int tierFromDay(long day) {
|
||||||
int tier = 0;
|
int tier = 0;
|
||||||
for (int t = 1; t <= 5; t++) {
|
int configuredTiers = Math.min(5, AMConfig.DAY_THRESHOLDS.get().size());
|
||||||
|
for (int t = 1; t <= configuredTiers; t++) {
|
||||||
if (day >= AMConfig.tierValueInt(AMConfig.DAY_THRESHOLDS.get(), t)) {
|
if (day >= AMConfig.tierValueInt(AMConfig.DAY_THRESHOLDS.get(), t)) {
|
||||||
tier = t;
|
tier = t;
|
||||||
}
|
}
|
||||||
@@ -96,7 +97,8 @@ public final class AdaptiveDifficultyManager {
|
|||||||
|
|
||||||
private static int tierFromKills(long kills) {
|
private static int tierFromKills(long kills) {
|
||||||
int tier = 0;
|
int tier = 0;
|
||||||
for (int t = 1; t <= 5; t++) {
|
int configuredTiers = Math.min(5, AMConfig.KILL_THRESHOLDS.get().size());
|
||||||
|
for (int t = 1; t <= configuredTiers; t++) {
|
||||||
if (kills >= AMConfig.tierValueInt(AMConfig.KILL_THRESHOLDS.get(), t)) {
|
if (kills >= AMConfig.tierValueInt(AMConfig.KILL_THRESHOLDS.get(), t)) {
|
||||||
tier = t;
|
tier = t;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,13 +31,14 @@ import net.minecraftforge.event.level.LevelEvent;
|
|||||||
import net.minecraftforge.event.level.BlockEvent.EntityPlaceEvent;
|
import net.minecraftforge.event.level.BlockEvent.EntityPlaceEvent;
|
||||||
import net.minecraftforge.event.TickEvent;
|
import net.minecraftforge.event.TickEvent;
|
||||||
import net.minecraftforge.event.server.ServerStoppingEvent;
|
import net.minecraftforge.event.server.ServerStoppingEvent;
|
||||||
|
import net.minecraftforge.eventbus.api.EventPriority;
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
|
|
||||||
public class AdaptiveMobsEvents {
|
public class AdaptiveMobsEvents {
|
||||||
|
|
||||||
private static final String FRIENDLY_FIRE_SOURCE_KEY = "am_friendly_fire_source";
|
|
||||||
private static final String FRIENDLY_FIRE_COUNT_KEY = "am_friendly_fire_count";
|
private static final String FRIENDLY_FIRE_COUNT_KEY = "am_friendly_fire_count";
|
||||||
private static final String FRIENDLY_FIRE_EXPIRES_KEY = "am_friendly_fire_expires";
|
private static final String FRIENDLY_FIRE_EXPIRES_KEY = "am_friendly_fire_expires";
|
||||||
|
private static final String PENDING_SPAWN_PROCESSING_KEY = "am_pending_spawn_processing";
|
||||||
private static final int FRIENDLY_FIRE_WINDOW_TICKS = 100;
|
private static final int FRIENDLY_FIRE_WINDOW_TICKS = 100;
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
@@ -69,13 +70,10 @@ public class AdaptiveMobsEvents {
|
|||||||
}
|
}
|
||||||
|
|
||||||
long now = level.getGameTime();
|
long now = level.getGameTime();
|
||||||
String source = attacker.getUUID().toString();
|
boolean sameVolley = victim.getPersistentData().getLong(FRIENDLY_FIRE_EXPIRES_KEY) >= now;
|
||||||
boolean sameVolley = source.equals(victim.getPersistentData().getString(FRIENDLY_FIRE_SOURCE_KEY))
|
|
||||||
&& victim.getPersistentData().getLong(FRIENDLY_FIRE_EXPIRES_KEY) >= now;
|
|
||||||
int hits = sameVolley ? victim.getPersistentData().getInt(FRIENDLY_FIRE_COUNT_KEY) + 1 : 1;
|
int hits = sameVolley ? victim.getPersistentData().getInt(FRIENDLY_FIRE_COUNT_KEY) + 1 : 1;
|
||||||
int toleratedHits = Math.min(4, tier - 1);
|
int toleratedHits = Math.min(4, tier - 1);
|
||||||
if (hits <= toleratedHits) {
|
if (hits <= toleratedHits) {
|
||||||
victim.getPersistentData().putString(FRIENDLY_FIRE_SOURCE_KEY, source);
|
|
||||||
victim.getPersistentData().putInt(FRIENDLY_FIRE_COUNT_KEY, hits);
|
victim.getPersistentData().putInt(FRIENDLY_FIRE_COUNT_KEY, hits);
|
||||||
victim.getPersistentData().putLong(FRIENDLY_FIRE_EXPIRES_KEY, now + FRIENDLY_FIRE_WINDOW_TICKS);
|
victim.getPersistentData().putLong(FRIENDLY_FIRE_EXPIRES_KEY, now + FRIENDLY_FIRE_WINDOW_TICKS);
|
||||||
event.setCanceled(true);
|
event.setCanceled(true);
|
||||||
@@ -85,7 +83,7 @@ public class AdaptiveMobsEvents {
|
|||||||
clearFriendlyFireTolerance(victim);
|
clearFriendlyFireTolerance(victim);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent(priority = EventPriority.LOWEST, receiveCanceled = false)
|
||||||
public void onLivingHurt(LivingHurtEvent event) {
|
public void onLivingHurt(LivingHurtEvent event) {
|
||||||
AdaptiveSpecialAbilities.onLivingHurt(event);
|
AdaptiveSpecialAbilities.onLivingHurt(event);
|
||||||
if (!AMConfig.enabled || !AMConfig.ENABLE_THREAT_MEMORY_AI.get()) {
|
if (!AMConfig.enabled || !AMConfig.ENABLE_THREAT_MEMORY_AI.get()) {
|
||||||
@@ -128,7 +126,7 @@ public class AdaptiveMobsEvents {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent(priority = EventPriority.LOWEST, receiveCanceled = false)
|
||||||
public void onFinalizeSpawn(MobSpawnEvent.FinalizeSpawn event) {
|
public void onFinalizeSpawn(MobSpawnEvent.FinalizeSpawn event) {
|
||||||
if (!AMConfig.enabled || !(event.getLevel() instanceof ServerLevel level)) {
|
if (!AMConfig.enabled || !(event.getLevel() instanceof ServerLevel level)) {
|
||||||
return;
|
return;
|
||||||
@@ -138,10 +136,8 @@ public class AdaptiveMobsEvents {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mob.getPersistentData().putBoolean(PENDING_SPAWN_PROCESSING_KEY, true);
|
||||||
int tier = AdaptiveDifficultyManager.getMobTier(level, mob.getType());
|
int tier = AdaptiveDifficultyManager.getMobTier(level, mob.getType());
|
||||||
MobStatScaler.applyScaling(mob, tier);
|
|
||||||
GearScaler.applyGear(mob, tier);
|
|
||||||
AdaptiveGoalInjector.inject(mob, level, tier);
|
|
||||||
SpawnPressureHelper.maybeSpawnExtra(level, mob, tier, event.getSpawnType());
|
SpawnPressureHelper.maybeSpawnExtra(level, mob, tier, event.getSpawnType());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,6 +149,14 @@ public class AdaptiveMobsEvents {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Entity entity = event.getEntity();
|
Entity entity = event.getEntity();
|
||||||
|
if (AMConfig.enabled && entity instanceof Mob mob && mob instanceof Enemy
|
||||||
|
&& AMConfig.isMobEnabled(mob.getType())
|
||||||
|
&& mob.getPersistentData().getBoolean(PENDING_SPAWN_PROCESSING_KEY)) {
|
||||||
|
mob.getPersistentData().remove(PENDING_SPAWN_PROCESSING_KEY);
|
||||||
|
int tier = AdaptiveDifficultyManager.getMobTier(level, mob.getType());
|
||||||
|
MobStatScaler.applyScaling(mob, tier);
|
||||||
|
GearScaler.applyGear(mob, tier);
|
||||||
|
}
|
||||||
// Install dormant, config-gated goals on every supported hostile so a later config reload
|
// Install dormant, config-gated goals on every supported hostile so a later config reload
|
||||||
// can enable them without requiring the entity to unload and join again.
|
// can enable them without requiring the entity to unload and join again.
|
||||||
if (entity instanceof Mob mob && mob instanceof Enemy) {
|
if (entity instanceof Mob mob && mob instanceof Enemy) {
|
||||||
@@ -192,7 +196,6 @@ public class AdaptiveMobsEvents {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void clearFriendlyFireTolerance(Mob mob) {
|
private static void clearFriendlyFireTolerance(Mob mob) {
|
||||||
mob.getPersistentData().remove(FRIENDLY_FIRE_SOURCE_KEY);
|
|
||||||
mob.getPersistentData().remove(FRIENDLY_FIRE_COUNT_KEY);
|
mob.getPersistentData().remove(FRIENDLY_FIRE_COUNT_KEY);
|
||||||
mob.getPersistentData().remove(FRIENDLY_FIRE_EXPIRES_KEY);
|
mob.getPersistentData().remove(FRIENDLY_FIRE_EXPIRES_KEY);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ import net.minecraft.world.item.enchantment.Enchantments;
|
|||||||
*/
|
*/
|
||||||
public final class GearScaler {
|
public final class GearScaler {
|
||||||
|
|
||||||
|
private static final String GEAR_APPLIED_KEY = "am_gear_applied";
|
||||||
|
|
||||||
// Material ranks (low -> high) used both to pick new gear and to compare against existing gear.
|
// Material ranks (low -> high) used both to pick new gear and to compare against existing gear.
|
||||||
private static final Item[] HELMETS = {Items.LEATHER_HELMET, Items.GOLDEN_HELMET, Items.CHAINMAIL_HELMET, Items.IRON_HELMET, Items.DIAMOND_HELMET};
|
private static final Item[] HELMETS = {Items.LEATHER_HELMET, Items.GOLDEN_HELMET, Items.CHAINMAIL_HELMET, Items.IRON_HELMET, Items.DIAMOND_HELMET};
|
||||||
private static final Item[] CHESTS = {Items.LEATHER_CHESTPLATE, Items.GOLDEN_CHESTPLATE, Items.CHAINMAIL_CHESTPLATE, Items.IRON_CHESTPLATE, Items.DIAMOND_CHESTPLATE};
|
private static final Item[] CHESTS = {Items.LEATHER_CHESTPLATE, Items.GOLDEN_CHESTPLATE, Items.CHAINMAIL_CHESTPLATE, Items.IRON_CHESTPLATE, Items.DIAMOND_CHESTPLATE};
|
||||||
@@ -32,6 +34,10 @@ public final class GearScaler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void applyGear(Mob mob, int tier) {
|
public static void applyGear(Mob mob, int tier) {
|
||||||
|
if (mob.getPersistentData().getBoolean(GEAR_APPLIED_KEY)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mob.getPersistentData().putBoolean(GEAR_APPLIED_KEY, true);
|
||||||
if (!AMConfig.GEAR_SCALING_ENABLED.get() || tier <= 0) {
|
if (!AMConfig.GEAR_SCALING_ENABLED.get() || tier <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ package net.fretux.adaptivemobs.spawn;
|
|||||||
|
|
||||||
import net.fretux.adaptivemobs.AdaptiveMobs;
|
import net.fretux.adaptivemobs.AdaptiveMobs;
|
||||||
import net.fretux.adaptivemobs.config.AMConfig;
|
import net.fretux.adaptivemobs.config.AMConfig;
|
||||||
import net.fretux.adaptivemobs.gear.GearScaler;
|
|
||||||
import net.fretux.adaptivemobs.scaling.MobStatScaler;
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.util.RandomSource;
|
import net.minecraft.util.RandomSource;
|
||||||
@@ -13,6 +11,7 @@ import net.minecraft.world.entity.Mob;
|
|||||||
import net.minecraft.world.entity.MobSpawnType;
|
import net.minecraft.world.entity.MobSpawnType;
|
||||||
import net.minecraft.world.entity.monster.Monster;
|
import net.minecraft.world.entity.monster.Monster;
|
||||||
import net.minecraft.world.phys.AABB;
|
import net.minecraft.world.phys.AABB;
|
||||||
|
import net.minecraftforge.event.ForgeEventFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds modest spawn pressure: on a natural hostile spawn there is a tier-scaled chance to spawn
|
* Adds modest spawn pressure: on a natural hostile spawn there is a tier-scaled chance to spawn
|
||||||
@@ -75,12 +74,10 @@ public final class SpawnPressureHelper {
|
|||||||
random.nextFloat() * 360.0F, 0.0F);
|
random.nextFloat() * 360.0F, 0.0F);
|
||||||
// Honour collision, light/biome spawn rules and obstruction checks.
|
// Honour collision, light/biome spawn rules and obstruction checks.
|
||||||
if (level.noCollision(extra)
|
if (level.noCollision(extra)
|
||||||
&& extra.checkSpawnRules(level, MobSpawnType.NATURAL)
|
&& extra.checkSpawnRules(level, spawnType)
|
||||||
&& extra.checkSpawnObstruction(level)) {
|
&& extra.checkSpawnObstruction(level)) {
|
||||||
extra.finalizeSpawn(level, level.getCurrentDifficultyAt(extra.blockPosition()),
|
ForgeEventFactory.onFinalizeSpawn(extra, level,
|
||||||
MobSpawnType.NATURAL, null, null);
|
level.getCurrentDifficultyAt(extra.blockPosition()), spawnType, null, null);
|
||||||
MobStatScaler.applyScaling(extra, tier);
|
|
||||||
GearScaler.applyGear(extra, tier);
|
|
||||||
level.addFreshEntity(extra);
|
level.addFreshEntity(extra);
|
||||||
if (AMConfig.debug) {
|
if (AMConfig.debug) {
|
||||||
AdaptiveMobs.LOGGER.info("[AdaptiveMobs] Extra spawn ({}) at tier {} near {}",
|
AdaptiveMobs.LOGGER.info("[AdaptiveMobs] Extra spawn ({}) at tier {} near {}",
|
||||||
|
|||||||
Reference in New Issue
Block a user