Complete phase 9 ambience polish
This commit is contained in:
@@ -36,6 +36,7 @@ import net.minecraft.world.entity.animal.Squid;
|
||||
import net.minecraft.world.entity.animal.Bee;
|
||||
import net.minecraft.world.entity.monster.Monster;
|
||||
import net.minecraft.world.entity.MobSpawnType;
|
||||
import net.minecraft.world.entity.item.ItemEntity;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.Biomes;
|
||||
@@ -616,6 +617,10 @@ public class LivingWorldMod {
|
||||
Math.max(movement.y, 0.12),
|
||||
movement.z + (random.nextDouble() - 0.5) * 0.35);
|
||||
}
|
||||
if (bootstrap.isStormIncoming(coord) && random.nextInt(8) == 0) {
|
||||
playAmbientSound(player, Holder.direct(SoundEvents.WEATHER_RAIN),
|
||||
0.08f, 0.75f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -651,6 +656,7 @@ public class LivingWorldMod {
|
||||
double tidalPushZ = Math.sin(windAngle) * tidalCurrentMag * TIDAL_CURRENT_STRENGTH;
|
||||
boolean hasTidalCurrent = Math.abs(tidalCurrentMag) > 0.1;
|
||||
|
||||
Set<UUID> processedItems = new HashSet<>();
|
||||
for (ServerPlayer player : minecraftServer.getPlayerList().getPlayers()) {
|
||||
if (!(player.level() instanceof ServerLevel level)) continue;
|
||||
BlockPos pos = player.blockPosition();
|
||||
@@ -694,6 +700,31 @@ public class LivingWorldMod {
|
||||
var mm = mob.getDeltaMovement();
|
||||
mob.setDeltaMovement(mm.x + mobFlow.x * mobForce, mm.y, mm.z + mobFlow.z * mobForce);
|
||||
}
|
||||
|
||||
var nearbyItems = entityLevel.getEntitiesOfClass(
|
||||
ItemEntity.class, player.getBoundingBox().inflate(48));
|
||||
for (ItemEntity item : nearbyItems) {
|
||||
if (!processedItems.add(item.getUUID())) continue;
|
||||
var itemFluid = entityLevel.getFluidState(item.blockPosition());
|
||||
if (!itemFluid.is(FluidTags.WATER)) continue;
|
||||
var movement = item.getDeltaMovement();
|
||||
if (!itemFluid.isSource()) {
|
||||
var itemFlow = itemFluid.getFlow(entityLevel, item.blockPosition());
|
||||
double force = CURRENT_STRENGTH * (itemFluid.getAmount() / 8.0) * 0.8;
|
||||
item.setDeltaMovement(movement.x + itemFlow.x * force,
|
||||
movement.y, movement.z + itemFlow.z * force);
|
||||
} else if (hasTidalCurrent) {
|
||||
RegionCoordinate itemCoord = RegionCoordinate.fromBlock(
|
||||
entityLevel.dimension().location().toString(),
|
||||
item.blockPosition().getX(), item.blockPosition().getZ(),
|
||||
LivingWorldConstants.DEFAULT_REGION_SIZE_CHUNKS);
|
||||
Double elevation = bootstrap.getRegionElevation(itemCoord);
|
||||
if (elevation != null && elevation <= seaLevel + 6) {
|
||||
item.setDeltaMovement(movement.x + tidalPushX,
|
||||
movement.y, movement.z + tidalPushZ);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -710,14 +741,16 @@ public class LivingWorldMod {
|
||||
RegionCoordinate coord = new RegionCoordinate(dimId, regionX, regionZ);
|
||||
|
||||
// Volcanic ambience — highest priority when eruption is active
|
||||
String volcanoPhase = bootstrap.getVolcanoPhaseAt(coord);
|
||||
String volcanoPhase = bootstrap.getNearbyVolcanoPhase(coord, 3);
|
||||
if (volcanoPhase != null) {
|
||||
if ("ERUPTING".equals(volcanoPhase) && random.nextInt(4) == 0) {
|
||||
playAmbientSound(player, Holder.direct(SoundEvents.FIRE_AMBIENT), 0.55f, 0.8f + random.nextFloat() * 0.4f);
|
||||
if ("ERUPTING".equals(volcanoPhase) && random.nextInt(3) == 0) {
|
||||
playAmbientSound(player, SoundEvents.AMBIENT_BASALT_DELTAS_MOOD,
|
||||
0.45f, 0.55f + random.nextFloat() * 0.25f);
|
||||
return true;
|
||||
}
|
||||
if ("BUILDING".equals(volcanoPhase) && random.nextInt(20) == 0) {
|
||||
playAmbientSound(player, SoundEvents.AMBIENT_BASALT_DELTAS_MOOD, 0.25f, 0.7f + random.nextFloat() * 0.2f);
|
||||
if ("BUILDING".equals(volcanoPhase) && random.nextInt(10) == 0) {
|
||||
playAmbientSound(player, SoundEvents.AMBIENT_BASALT_DELTAS_MOOD,
|
||||
0.22f, 0.75f + random.nextFloat() * 0.15f);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1489,6 +1489,33 @@ public final class LivingWorldBootstrap {
|
||||
return phase != null ? phase.name() : null;
|
||||
}
|
||||
|
||||
/** Returns the strongest volcanic phase within the requested region radius. */
|
||||
public String getNearbyVolcanoPhase(RegionCoordinate coord, int radius) {
|
||||
if (coord == null) return null;
|
||||
VolcanoPhase strongest = null;
|
||||
for (RegionCoordinate volcanic : volcanicRegions) {
|
||||
if (!volcanic.dimensionId().equals(coord.dimensionId())) continue;
|
||||
if (Math.abs(volcanic.x() - coord.x()) > radius
|
||||
|| Math.abs(volcanic.z() - coord.z()) > radius) continue;
|
||||
VolcanoPhase phase = volcanoPhase.get(volcanic);
|
||||
if (phase == VolcanoPhase.ERUPTING) return phase.name();
|
||||
if (phase == VolcanoPhase.BUILDING) strongest = phase;
|
||||
}
|
||||
return strongest != null ? strongest.name() : null;
|
||||
}
|
||||
|
||||
public boolean isStormIncoming(RegionCoordinate coord) {
|
||||
if (coord == null || isClimateEventActive(coord, ClimateEventType.LIGHTNING_STORM)
|
||||
|| isClimateEventActive(coord, ClimateEventType.BLIZZARD)
|
||||
|| isClimateEventActive(coord, ClimateEventType.SANDSTORM)) {
|
||||
return false;
|
||||
}
|
||||
return getRegionalWeather(coord)
|
||||
.map(atmosphere -> atmosphere.getThunderLevel() >= 0.25
|
||||
&& atmosphere.getThunderLevel() < 0.55)
|
||||
.orElse(false);
|
||||
}
|
||||
|
||||
/** Marks a region as oceanic so it can host submarine volcanoes. */
|
||||
public void markOceanicRegion(RegionCoordinate coord) {
|
||||
if (coord != null) oceanicRegions.add(coord);
|
||||
|
||||
Reference in New Issue
Block a user