mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 15:17:59 +01:00
Spawn batponies in appropriate locations to avoid burning their eyes
This commit is contained in:
parent
d720a37cd9
commit
ab97a7b6ef
5 changed files with 114 additions and 14 deletions
|
@ -4,6 +4,7 @@ import org.jetbrains.annotations.Nullable;
|
|||
|
||||
import com.minelittlepony.unicopia.EquinePredicates;
|
||||
import com.minelittlepony.unicopia.UTags;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.trinkets.TrinketsDelegate;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
|
@ -14,7 +15,9 @@ import net.minecraft.entity.effect.StatusEffect;
|
|||
import net.minecraft.entity.effect.StatusEffectInstance;
|
||||
import net.minecraft.entity.effect.StatusEffectCategory;
|
||||
import net.minecraft.entity.effect.StatusEffects;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.LightType;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class SunBlindnessStatusEffect extends StatusEffect {
|
||||
public static final int MAX_DURATION = 250;
|
||||
|
@ -27,7 +30,7 @@ public class SunBlindnessStatusEffect extends StatusEffect {
|
|||
public void applyUpdateEffect(LivingEntity entity, int amplifier) {
|
||||
StatusEffectInstance state = entity.getStatusEffect(this);
|
||||
|
||||
if (state == null) {
|
||||
if (state == null || isSunImmune(entity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -50,9 +53,15 @@ public class SunBlindnessStatusEffect extends StatusEffect {
|
|||
return duration > 0;
|
||||
}
|
||||
|
||||
public static boolean isSunImmune(LivingEntity entity) {
|
||||
return entity.hasStatusEffect(StatusEffects.BLINDNESS)
|
||||
|| entity.hasPortalCooldown()
|
||||
|| Pony.of(entity).map(pony -> pony.isSunImmune()).orElse(false);
|
||||
}
|
||||
|
||||
public static boolean hasSunExposure(LivingEntity entity) {
|
||||
|
||||
if (entity.hasPortalCooldown()) {
|
||||
if (isSunImmune(entity)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -64,21 +73,21 @@ public class SunBlindnessStatusEffect extends StatusEffect {
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
if (entity.getEquippedStack(EquipmentSlot.HEAD).isIn(UTags.SHADES)) {
|
||||
if (entity.getEquippedStack(EquipmentSlot.HEAD).isIn(UTags.SHADES)
|
||||
|| TrinketsDelegate.getInstance().getEquipped(entity, TrinketsDelegate.FACE).anyMatch(i -> i.isIn(UTags.SHADES))
|
||||
|| entity.isSubmergedInWater()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (TrinketsDelegate.getInstance().getEquipped(entity, TrinketsDelegate.FACE).anyMatch(i -> i.isIn(UTags.SHADES))) {
|
||||
return false;
|
||||
return isPositionExposedToSun(entity.world, entity.getBlockPos());
|
||||
|
||||
}
|
||||
|
||||
public static boolean isPositionExposedToSun(World world, BlockPos pos) {
|
||||
if (world.isClient) {
|
||||
world.calculateAmbientDarkness();
|
||||
}
|
||||
|
||||
if (entity.world.isClient) {
|
||||
entity.world.calculateAmbientDarkness();
|
||||
}
|
||||
|
||||
int light = entity.world.getLightLevel(LightType.SKY, entity.getBlockPos());
|
||||
|
||||
return !(entity.isSubmergedInWater() || light < 12 || entity.world.isRaining() || entity.world.isThundering() || !entity.world.isDay());
|
||||
return world.getDimension().hasSkyLight() && world.getLightLevel(LightType.SKY, pos) >= 12 && !world.isRaining() && !world.isThundering() && world.isDay();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@ import net.minecraft.sound.SoundEvents;
|
|||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.math.*;
|
||||
import net.minecraft.world.GameMode;
|
||||
|
||||
public class Pony extends Living<PlayerEntity> implements Transmittable, Copieable<Pony>, UpdateCallback {
|
||||
|
||||
|
@ -107,6 +108,7 @@ public class Pony extends Living<PlayerEntity> implements Transmittable, Copieab
|
|||
|
||||
private int ticksInSun;
|
||||
private boolean hasShades;
|
||||
private int ticksSunImmunity = 20;
|
||||
|
||||
private Animation animation = Animation.NONE;
|
||||
private int animationMaxDuration;
|
||||
|
@ -221,6 +223,10 @@ public class Pony extends Living<PlayerEntity> implements Transmittable, Copieab
|
|||
this.invisible = invisible;
|
||||
}
|
||||
|
||||
public boolean isSunImmune() {
|
||||
return ticksSunImmunity > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Affinity getAffinity() {
|
||||
return getSpecies().getAffinity();
|
||||
|
@ -270,6 +276,15 @@ public class Pony extends Living<PlayerEntity> implements Transmittable, Copieab
|
|||
return interpolator;
|
||||
}
|
||||
|
||||
public void onSpawn() {
|
||||
if (entity.world instanceof ServerWorld sw
|
||||
&& getSpecies() == Race.BAT
|
||||
&& sw.getServer().getSaveProperties().getGameMode() != GameMode.ADVENTURE
|
||||
&& SunBlindnessStatusEffect.isPositionExposedToSun(sw, getOrigin())) {
|
||||
SpawnLocator.selectSpawnPosition(sw, entity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean beforeUpdate() {
|
||||
|
||||
|
@ -355,6 +370,10 @@ public class Pony extends Living<PlayerEntity> implements Transmittable, Copieab
|
|||
|
||||
@Override
|
||||
public void tick() {
|
||||
if (ticksSunImmunity > 0) {
|
||||
ticksSunImmunity--;
|
||||
}
|
||||
|
||||
if (animationDuration >= 0 && --animationDuration <= 0) {
|
||||
setAnimation(Animation.NONE);
|
||||
}
|
||||
|
@ -618,6 +637,7 @@ public class Pony extends Living<PlayerEntity> implements Transmittable, Copieab
|
|||
mana.getXp().set(oldPlayer.getMagicalReserves().getXp().get());
|
||||
advancementProgress.putAll(oldPlayer.getAdvancementProgress());
|
||||
setDirty();
|
||||
onSpawn();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
package com.minelittlepony.unicopia.entity.player;
|
||||
|
||||
import com.minelittlepony.unicopia.entity.effect.SunBlindnessStatusEffect;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.server.network.SpawnLocating;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.math.*;
|
||||
import net.minecraft.util.math.random.Random;
|
||||
|
||||
public class SpawnLocator extends SpawnLocating {
|
||||
|
||||
public static void selectSpawnPosition(ServerWorld world, PlayerEntity entity) {
|
||||
BlockPos spawnPos = world.getSpawnPos();
|
||||
int spawnRadius = Math.min(
|
||||
MathHelper.floor(world.getWorldBorder().getDistanceInsideBorder(spawnPos.getX(), spawnPos.getZ())),
|
||||
Math.max(0, world.getServer().getSpawnRadius(world))
|
||||
);
|
||||
|
||||
long l = spawnRadius * 2 + 1;
|
||||
long m = l * l;
|
||||
int spawnArea = m > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int)m;
|
||||
int offsetMultiplier = spawnArea <= 16 ? spawnArea - 1 : 17;
|
||||
int rng = Random.create().nextInt(spawnArea);
|
||||
|
||||
BlockPos.Mutable mutable = new BlockPos.Mutable();
|
||||
|
||||
for (int attempt = 0; attempt < spawnArea; attempt++) {
|
||||
int tile = (rng + offsetMultiplier * attempt) % spawnArea;
|
||||
int x = tile % (spawnRadius * 2 + 1);
|
||||
int z = tile / (spawnRadius * 2 + 1);
|
||||
|
||||
BlockPos candidatePos = findOverworldSpawn(world,
|
||||
spawnPos.getX() + x - spawnRadius,
|
||||
spawnPos.getZ() + z - spawnRadius
|
||||
);
|
||||
|
||||
if (candidatePos == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
mutable.set(candidatePos);
|
||||
mutable.move(0, -1, 0);
|
||||
|
||||
while (!world.isAir(mutable) && mutable.getY() >= spawnPos.getY() - spawnRadius * 2 && !world.isOutOfHeightLimit(mutable)) {
|
||||
mutable.move(0, -1, 0);
|
||||
}
|
||||
while (world.isAir(mutable) && mutable.getY() >= spawnPos.getY() - spawnRadius * 2 && !world.isOutOfHeightLimit(mutable)) {
|
||||
mutable.move(0, -1, 0);
|
||||
}
|
||||
if (!world.isAir(mutable)) {
|
||||
mutable.move(0, 1, 0);
|
||||
}
|
||||
|
||||
if (!world.getFluidState(mutable).isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
entity.refreshPositionAndAngles(mutable, 0, 0);
|
||||
|
||||
if (!world.isSpaceEmpty(entity) || SunBlindnessStatusEffect.isPositionExposedToSun(world, mutable)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,7 +9,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||
import com.minelittlepony.unicopia.entity.PonyContainer;
|
||||
import com.minelittlepony.unicopia.entity.duck.ServerPlayerEntityDuck;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.screen.ScreenHandlerListener;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
|
|
|
@ -47,6 +47,10 @@ public class MsgRequestSpeciesChange implements Packet<ServerPlayerEntity> {
|
|||
|
||||
if (force || player.getActualSpecies().isDefault() || (player.getActualSpecies() == worldDefaultRace && !player.isSpeciesPersisted())) {
|
||||
player.setSpecies(newRace.isPermitted(sender) ? newRace : worldDefaultRace);
|
||||
|
||||
if (force) {
|
||||
player.onSpawn();
|
||||
}
|
||||
}
|
||||
|
||||
Channel.SERVER_PLAYER_CAPABILITIES.send(sender, new MsgPlayerCapabilities(true, player));
|
||||
|
|
Loading…
Reference in a new issue