mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-30 16:28:00 +01:00
Merge branch '1.20-bugfix' into 1.20.2-bugfix
This commit is contained in:
commit
10227325d5
10 changed files with 167 additions and 83 deletions
|
@ -42,6 +42,10 @@ public enum FlightType {
|
|||
return this == INSECTOID ? 0.66F : 1;
|
||||
}
|
||||
|
||||
public FlightType or(FlightType other) {
|
||||
return ordinal() > other.ordinal() ? this : other;
|
||||
}
|
||||
|
||||
/**
|
||||
* Predicate for abilities to control whether a player can fly.
|
||||
*
|
||||
|
|
|
@ -103,8 +103,7 @@ public record Race (Supplier<Composite> compositeSupplier, boolean canCast, Flig
|
|||
}
|
||||
|
||||
public Identifier getId() {
|
||||
Identifier id = REGISTRY.getId(this);
|
||||
return id;
|
||||
return REGISTRY.getId(this);
|
||||
}
|
||||
|
||||
public Text getDisplayName() {
|
||||
|
@ -126,10 +125,6 @@ public record Race (Supplier<Composite> compositeSupplier, boolean canCast, Flig
|
|||
}
|
||||
|
||||
public boolean isPermitted(@Nullable PlayerEntity sender) {
|
||||
if (isOp() && (sender == null || !sender.getAbilities().creativeMode)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Set<String> whitelist = Unicopia.getConfig().speciesWhiteList.get();
|
||||
|
||||
return isUnset()
|
||||
|
@ -220,6 +215,13 @@ public record Race (Supplier<Composite> compositeSupplier, boolean canCast, Flig
|
|||
public boolean canCast() {
|
||||
return any(Race::canCast);
|
||||
}
|
||||
|
||||
public FlightType flightType() {
|
||||
if (pseudo() == null) {
|
||||
return physical().flightType();
|
||||
}
|
||||
return physical().flightType().or(pseudo().flightType());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -54,14 +54,20 @@ public class SproutBlock extends CropBlock implements TintedBlock {
|
|||
@Override
|
||||
public void randomTick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
|
||||
super.randomTick(state, world, pos, random);
|
||||
onGrow(world, world.getBlockState(pos), pos);
|
||||
state = world.getBlockState(pos);
|
||||
if (state.isOf(this)) {
|
||||
onGrow(world, state, pos);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyGrowth(World world, BlockPos pos, BlockState state) {
|
||||
super.applyGrowth(world, pos, state);
|
||||
state = world.getBlockState(pos);
|
||||
if (state.isOf(this)) {
|
||||
onGrow(world, world.getBlockState(pos), pos);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ItemConvertible getSeedsItem() {
|
||||
|
@ -81,7 +87,7 @@ public class SproutBlock extends CropBlock implements TintedBlock {
|
|||
|
||||
protected void mature(World world, BlockState state, BlockPos pos) {
|
||||
state = matureState.get();
|
||||
world.setBlockState(pos, matureState.get());
|
||||
world.setBlockState(pos, state);
|
||||
BlockSoundGroup group = state.getSoundGroup();
|
||||
world.playSound(null, pos, group.getPlaceSound(), SoundCategory.BLOCKS, group.getVolume(), group.getPitch());
|
||||
}
|
||||
|
|
|
@ -20,10 +20,10 @@ import net.minecraft.world.BlockView;
|
|||
import net.minecraft.world.World;
|
||||
|
||||
public class WeatherVaneBlock extends BlockWithEntity {
|
||||
/*private static final VoxelShape SHAPE = VoxelShapes.union(
|
||||
private static final VoxelShape SHAPE = VoxelShapes.union(
|
||||
Block.createCuboidShape(7.5F, 0, 7.5F, 8.5F, 14, 8.5F),
|
||||
Block.createCuboidShape(7, 0, 7, 9, 1, 9)
|
||||
);*/
|
||||
);
|
||||
|
||||
protected WeatherVaneBlock(Settings settings) {
|
||||
super(settings);
|
||||
|
@ -32,10 +32,7 @@ public class WeatherVaneBlock extends BlockWithEntity {
|
|||
@Deprecated
|
||||
@Override
|
||||
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||
return VoxelShapes.union(
|
||||
Block.createCuboidShape(7.5F, 0, 7.5F, 8.5F, 14, 8.5F),
|
||||
Block.createCuboidShape(7, 0, 7, 9, 1, 9)
|
||||
);
|
||||
return SHAPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -112,7 +112,11 @@ public class RaceChangeStatusEffect extends StatusEffect {
|
|||
magic.getExertion().set(0);
|
||||
|
||||
if (!pony.asEntity().isCreative()) {
|
||||
entity.damage(Living.living(entity).damageOf(UDamageTypes.TRIBE_SWAP), Float.MAX_VALUE);
|
||||
if (!entity.damage(Living.living(entity).damageOf(UDamageTypes.TRIBE_SWAP), Float.MAX_VALUE)) {
|
||||
entity.setHealth(0);
|
||||
pony.setRespawnRace(Race.UNSET);
|
||||
pony.setSpecies(race);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
eq.setSpecies(race);
|
||||
|
|
|
@ -19,6 +19,8 @@ import com.minelittlepony.unicopia.item.AmuletItem;
|
|||
import com.minelittlepony.unicopia.item.ChargeableItem;
|
||||
import com.minelittlepony.unicopia.item.UItems;
|
||||
import com.minelittlepony.unicopia.item.enchantment.UEnchantments;
|
||||
import com.minelittlepony.unicopia.network.Channel;
|
||||
import com.minelittlepony.unicopia.network.MsgPlayerFlightControlsInput;
|
||||
import com.minelittlepony.unicopia.particle.*;
|
||||
import com.minelittlepony.unicopia.projectile.ProjectileUtil;
|
||||
import com.minelittlepony.unicopia.server.world.BlockDestructionManager;
|
||||
|
@ -130,7 +132,7 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
|
||||
@Override
|
||||
public boolean isGliding() {
|
||||
return ticksToGlide <= 0 && isFlying() && !entity.isSneaking();
|
||||
return ticksToGlide <= 0 && isFlying() && !pony.getJumpingHeuristic().getState();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -153,7 +155,7 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
float spreadAmount = -0.5F;
|
||||
|
||||
if (isFlying()) {
|
||||
if (getFlightType() == FlightType.INSECTOID) {
|
||||
if (lastFlightType == FlightType.INSECTOID) {
|
||||
spreadAmount += Math.sin(pony.asEntity().age * 4F) * 8;
|
||||
} else {
|
||||
if (isGliding()) {
|
||||
|
@ -181,6 +183,10 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
}
|
||||
|
||||
public FlightType getFlightType() {
|
||||
return lastFlightType;
|
||||
}
|
||||
|
||||
private FlightType recalculateFlightType() {
|
||||
DimensionType dimension = entity.getWorld().getDimension();
|
||||
|
||||
if ((RegistryUtils.isIn(entity.getWorld(), dimension, RegistryKeys.DIMENSION_TYPE, UTags.HAS_NO_ATMOSPHERE)
|
||||
|
@ -197,7 +203,7 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
.filter(effect -> !effect.isDead() && effect instanceof FlightType.Provider)
|
||||
.map(effect -> ((FlightType.Provider)effect).getFlightType())
|
||||
.filter(FlightType::isPresent)
|
||||
.orElse(pony.getObservedSpecies().flightType());
|
||||
.orElse(pony.getCompositeRace().flightType());
|
||||
}
|
||||
|
||||
public void cancelFlight(boolean force) {
|
||||
|
@ -224,6 +230,10 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
public void tick() {
|
||||
super.tick();
|
||||
|
||||
if (pony.isClient() && this.isFlying()) {
|
||||
Channel.FLIGHT_CONTROLS_INPUT.sendToServer(new MsgPlayerFlightControlsInput(pony));
|
||||
}
|
||||
|
||||
prevThrustScale = thrustScale;
|
||||
|
||||
if (wallHitCooldown > 0) {
|
||||
|
@ -246,20 +256,21 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
entity.setPose(EntityPose.STANDING);
|
||||
}
|
||||
|
||||
FlightType type = getFlightType();
|
||||
FlightType type = recalculateFlightType();
|
||||
|
||||
boolean typeChanged = type != lastFlightType && (lastFlightType.isArtifical() || type.isArtifical());
|
||||
boolean typeChanged = type != lastFlightType;
|
||||
|
||||
if (typeChanged) {
|
||||
if (typeChanged && (lastFlightType.isArtifical() || type.isArtifical())) {
|
||||
pony.spawnParticles(ParticleTypes.CLOUD, 10);
|
||||
|
||||
playSound(entity.getWorld().getDimension().ultrawarm() ? USounds.ITEM_ICARUS_WINGS_CORRUPT : USounds.ITEM_ICARUS_WINGS_PURIFY, 0.1125F, 1.5F);
|
||||
}
|
||||
|
||||
entity.getAbilities().allowFlying = type.canFlyCreative(entity);
|
||||
lastFlightType = type;
|
||||
|
||||
entity.getAbilities().allowFlying = lastFlightType.canFlyCreative(entity);
|
||||
|
||||
boolean creative = entity.isCreative() || entity.isSpectator();
|
||||
|
||||
boolean startedFlyingCreative = !creative && isFlyingEither != entity.getAbilities().flying;
|
||||
|
||||
if (!creative) {
|
||||
|
@ -271,8 +282,8 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
isCancelled = false;
|
||||
}
|
||||
|
||||
entity.getAbilities().flying |= (type.canFly() || entity.getAbilities().allowFlying) && isFlyingEither;
|
||||
if (!type.canFly() && (type != lastFlightType)) {
|
||||
entity.getAbilities().flying |= (lastFlightType.canFly() || entity.getAbilities().allowFlying) && isFlyingEither;
|
||||
if (!lastFlightType.canFly() && typeChanged) {
|
||||
entity.getAbilities().flying = false;
|
||||
}
|
||||
|
||||
|
@ -288,8 +299,6 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
|
||||
cancelFlight(false);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (isGravityNegative()) {
|
||||
|
@ -302,7 +311,6 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
}
|
||||
}
|
||||
|
||||
lastFlightType = type;
|
||||
isFlyingSurvival = entity.getAbilities().flying && !creative;
|
||||
isFlyingEither = isFlyingSurvival || (creative && entity.getAbilities().flying);
|
||||
|
||||
|
@ -310,10 +318,10 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
entity.calculateDimensions();
|
||||
}
|
||||
|
||||
if (type.canFly()) {
|
||||
if (lastFlightType.canFly()) {
|
||||
if (isFlying()) {
|
||||
ticksInAir++;
|
||||
tickFlight(type, velocity);
|
||||
tickFlight(lastFlightType, velocity);
|
||||
|
||||
int strafing = (int)Math.signum(entity.sidewaysSpeed);
|
||||
if (strafing != prevStrafe) {
|
||||
|
@ -321,8 +329,8 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
strafe = 1;
|
||||
ticksToGlide = MAX_TICKS_TO_GLIDE;
|
||||
if (!SpellPredicate.IS_DISGUISE.isOn(pony)) {
|
||||
if (type != FlightType.INSECTOID) {
|
||||
playSound(type.getWingFlapSound(), 0.25F, entity.getSoundPitch() * type.getWingFlapSoundPitch());
|
||||
if (lastFlightType != FlightType.INSECTOID) {
|
||||
playSound(lastFlightType.getWingFlapSound(), 0.25F, entity.getSoundPitch() * lastFlightType.getWingFlapSoundPitch());
|
||||
}
|
||||
entity.getWorld().emitGameEvent(entity, GameEvent.ELYTRA_GLIDE, entity.getPos());
|
||||
}
|
||||
|
@ -356,7 +364,7 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
descentRate = 0;
|
||||
ticksDiving = 0;
|
||||
|
||||
if (Abilities.RAINBOOM.canUse(pony.getSpecies()) && entity.isOnGround()) {
|
||||
if (Abilities.RAINBOOM.canUse(pony.getCompositeRace()) && entity.isOnGround()) {
|
||||
pony.getMagicalReserves().getCharge().set(0);
|
||||
}
|
||||
|
||||
|
@ -402,16 +410,14 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
|
||||
entity.fallDistance = 0;
|
||||
|
||||
if (type.isAvian()) {
|
||||
applyThrust(velocity);
|
||||
|
||||
if (type.isAvian()) {
|
||||
if (pony.getObservedSpecies() != Race.BAT && entity.getWorld().random.nextInt(9000) == 0) {
|
||||
entity.dropItem(UItems.PEGASUS_FEATHER);
|
||||
playSound(USounds.ENTITY_PLAYER_PEGASUS_MOLT, 0.3F, 1);
|
||||
UCriteria.SHED_FEATHER.trigger(entity);
|
||||
}
|
||||
} else {
|
||||
applyThrust(velocity);
|
||||
}
|
||||
|
||||
moveFlying(velocity);
|
||||
|
@ -427,8 +433,6 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
InteractionManager.instance().playLoopingSound(entity, InteractionManager.SOUND_GLIDING, entity.getId());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} else if (type == FlightType.INSECTOID && !SpellPredicate.IS_DISGUISE.isOn(pony)) {
|
||||
if (entity.getWorld().isClient && !soundPlaying) {
|
||||
soundPlaying = true;
|
||||
|
@ -467,7 +471,7 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
stack.damage(minDamage + entity.getWorld().random.nextInt(50), entity, e -> e.sendEquipmentBreakStatus(EquipmentSlot.CHEST));
|
||||
}
|
||||
|
||||
if (!getFlightType().canFly()) {
|
||||
if (!lastFlightType.canFly()) {
|
||||
playSound(USounds.ITEM_ICARUS_WINGS_EXHAUSTED, 1, 2);
|
||||
cancelFlight(false);
|
||||
}
|
||||
|
@ -475,7 +479,7 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
}
|
||||
|
||||
private void playSound(SoundEvent sound, float volume, float pitch) {
|
||||
entity.getWorld().playSoundFromEntity(null, entity, sound, SoundCategory.PLAYERS, volume, pitch);
|
||||
entity.getWorld().playSoundFromEntity(entity, entity, sound, SoundCategory.PLAYERS, volume, pitch);
|
||||
}
|
||||
|
||||
private void tickNaturalFlight(MutableVector velocity) {
|
||||
|
@ -554,12 +558,14 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
isFlyingEither = true;
|
||||
isFlyingSurvival = true;
|
||||
thrustScale = 0;
|
||||
descentRate = 0;
|
||||
entity.calculateDimensions();
|
||||
|
||||
if (entity.isOnGround() || !force) {
|
||||
Supplier<Vec3d> vec = VecHelper.sphere(pony.asWorld().getRandom(), 0.5D);
|
||||
pony.spawnParticles(ParticleTypes.CAMPFIRE_COSY_SMOKE, vec, vec, 5);
|
||||
pony.spawnParticles(ParticleTypes.CLOUD, vec, vec, 5);
|
||||
Supplier<Vec3d> pos = VecHelper.sphere(pony.asWorld().getRandom(), 0.5D);
|
||||
Supplier<Vec3d> vel = VecHelper.sphere(pony.asWorld().getRandom(), 0.15D);
|
||||
pony.spawnParticles(ParticleTypes.CAMPFIRE_COSY_SMOKE, pos, vel, 5);
|
||||
pony.spawnParticles(ParticleTypes.CLOUD, pos, vel, 5);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -625,11 +631,12 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
if (descentRate < 0) {
|
||||
descentRate *= 0.8F;
|
||||
}
|
||||
|
||||
velocity.y -= descentRate * getGravityModifier();
|
||||
}
|
||||
|
||||
private void applyThrust(MutableVector velocity) {
|
||||
boolean manualFlap = pony.sneakingChanged() && entity.isSneaking();
|
||||
boolean manualFlap = pony.getJumpingHeuristic().hasChanged(Heuristic.ONCE) && pony.getJumpingHeuristic().getState();
|
||||
if (manualFlap) {
|
||||
flapping = true;
|
||||
ticksToGlide = MAX_TICKS_TO_GLIDE;
|
||||
|
@ -639,12 +646,13 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
|
||||
boolean hovering = entity.getVelocity().horizontalLength() < 0.1;
|
||||
|
||||
if (lastFlightType == FlightType.INSECTOID) {
|
||||
descentRate = pony.getJumpingHeuristic().getState() ? -0.5F : 0;
|
||||
} else {
|
||||
if (thrustScale <= 0.000001F & flapping) {
|
||||
flapping = false;
|
||||
if (!SpellPredicate.IS_DISGUISE.isOn(pony)) {
|
||||
if (getFlightType() != FlightType.INSECTOID) {
|
||||
playSound(getFlightType().getWingFlapSound(), 0.25F, entity.getSoundPitch() * getFlightType().getWingFlapSoundPitch());
|
||||
}
|
||||
playSound(lastFlightType.getWingFlapSound(), 0.25F, entity.getSoundPitch() * lastFlightType.getWingFlapSoundPitch());
|
||||
entity.getWorld().emitGameEvent(entity, GameEvent.ELYTRA_GLIDE, entity.getPos());
|
||||
}
|
||||
thrustScale = 1;
|
||||
|
@ -654,9 +662,10 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
descentRate = Math.max(0, descentRate / 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float heavyness = EnchantmentHelper.getEquipmentLevel(UEnchantments.HEAVY, entity);
|
||||
float thrustStrength = 0.135F * thrustScale;
|
||||
float thrustStrength = 0.235F * thrustScale;
|
||||
|
||||
if (heavyness > 0) {
|
||||
thrustStrength /= 1 + heavyness;
|
||||
|
@ -664,9 +673,13 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
|
||||
Vec3d direction = entity.getRotationVec(1).normalize().multiply(thrustStrength);
|
||||
|
||||
if (!hovering) {
|
||||
velocity.x += direction.x;
|
||||
velocity.z += direction.z;
|
||||
if (hovering) {
|
||||
if (entity.isSneaking()) {
|
||||
velocity.y -= 0.2F;
|
||||
}
|
||||
} else {
|
||||
velocity.x += direction.x * 1.3F;
|
||||
velocity.z += direction.z * 1.3F;
|
||||
velocity.y += ((direction.y * 2.45 + Math.abs(direction.y) * 10)) * getGravitySignum();// - heavyness / 5F
|
||||
}
|
||||
|
||||
|
@ -709,10 +722,11 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
* Called when a player's species changes to update whether they can fly or not
|
||||
*/
|
||||
public void updateFlightState() {
|
||||
FlightType type = getFlightType();
|
||||
FlightType type = recalculateFlightType();
|
||||
entity.getAbilities().allowFlying = type.canFlyCreative(entity);
|
||||
entity.getAbilities().flying &= type.canFly() || entity.getAbilities().allowFlying;
|
||||
isFlyingSurvival = entity.getAbilities().flying;
|
||||
lastFlightType = type;
|
||||
}
|
||||
|
||||
public void dashForward(float speed) {
|
||||
|
|
|
@ -94,8 +94,7 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
|
||||
private final Interpolator interpolator = new LinearInterpolator();
|
||||
|
||||
@Nullable
|
||||
private Race.Composite compositeRace;
|
||||
private Race.Composite compositeRace = Race.UNSET.composite();
|
||||
private Race respawnRace = Race.UNSET;
|
||||
|
||||
private boolean dirty;
|
||||
|
@ -220,19 +219,6 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
*/
|
||||
@Override
|
||||
public Race.Composite getCompositeRace() {
|
||||
if (compositeRace == null || entity.age % 2 == 0) {
|
||||
compositeRace = getSpellSlot()
|
||||
.get(SpellPredicate.IS_MIMIC, true)
|
||||
.map(AbstractDisguiseSpell::getDisguise)
|
||||
.map(EntityAppearance::getAppearance)
|
||||
.flatMap(Pony::of)
|
||||
.map(Pony::getSpecies)
|
||||
.orElseGet(this::getSpecies).composite(
|
||||
AmuletSelectors.UNICORN_AMULET.test(entity) ? Race.UNICORN
|
||||
: AmuletSelectors.ALICORN_AMULET.test(entity) ? Race.ALICORN
|
||||
: null
|
||||
);
|
||||
}
|
||||
return compositeRace;
|
||||
}
|
||||
|
||||
|
@ -352,6 +338,20 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
|
||||
@Override
|
||||
public boolean beforeUpdate() {
|
||||
if (compositeRace.includes(Race.UNSET) || entity.age % 2 == 0) {
|
||||
compositeRace = getSpellSlot()
|
||||
.get(SpellPredicate.IS_MIMIC, true)
|
||||
.map(AbstractDisguiseSpell::getDisguise)
|
||||
.map(EntityAppearance::getAppearance)
|
||||
.flatMap(Pony::of)
|
||||
.map(Pony::getSpecies)
|
||||
.orElseGet(this::getSpecies).composite(
|
||||
AmuletSelectors.UNICORN_AMULET.test(entity) ? Race.UNICORN
|
||||
: AmuletSelectors.ALICORN_AMULET.test(entity) ? Race.ALICORN
|
||||
: null
|
||||
);
|
||||
}
|
||||
|
||||
if (isClient()) {
|
||||
if (entity.hasVehicle() && entity.isSneaking()) {
|
||||
|
||||
|
@ -420,9 +420,14 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
entity.setVelocity(entity.getVelocity().multiply(1, 0, 1));
|
||||
entity.setSneaking(false);
|
||||
}
|
||||
} else if (attachDirection != null && isFaceClimbable(entity.getWorld(), entity.getBlockPos(), attachDirection)) {
|
||||
} else if (attachDirection != null) {
|
||||
if (isFaceClimbable(entity.getWorld(), entity.getBlockPos(), attachDirection)) {
|
||||
entity.setBodyYaw(attachDirection.asRotation());
|
||||
entity.prevBodyYaw = attachDirection.asRotation();
|
||||
} else {
|
||||
entity.setVelocity(vel);
|
||||
entity.isClimbing();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -480,8 +485,10 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
@Override
|
||||
public Optional<BlockPos> chooseClimbingPos() {
|
||||
if (getObservedSpecies() == Race.CHANGELING && getSpellSlot().get(SpellPredicate.IS_DISGUISE, false).isEmpty()) {
|
||||
if (isFaceClimbable(entity.getWorld(), entity.getBlockPos(), entity.getHorizontalFacing()) || canHangAt(entity.getBlockPos())) {
|
||||
return Optional.of(entity.getBlockPos());
|
||||
}
|
||||
}
|
||||
return super.chooseClimbingPos();
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ public interface Channel {
|
|||
C2SPacketType<MsgRequestSpeciesChange> CLIENT_REQUEST_SPECIES_CHANGE = SimpleNetworking.clientToServer(Unicopia.id("request_capabilities"), MsgRequestSpeciesChange::new);
|
||||
C2SPacketType<MsgMarkTraitRead> MARK_TRAIT_READ = SimpleNetworking.clientToServer(Unicopia.id("mark_trait_read"), MsgMarkTraitRead::new);
|
||||
C2SPacketType<MsgRemoveSpell> REMOVE_SPELL = SimpleNetworking.clientToServer(Unicopia.id("remove_spell"), MsgRemoveSpell::new);
|
||||
C2SPacketType<MsgPlayerFlightControlsInput> FLIGHT_CONTROLS_INPUT = SimpleNetworking.clientToServer(Unicopia.id("flight_controls"), MsgPlayerFlightControlsInput::new);
|
||||
|
||||
S2CPacketType<MsgPlayerCapabilities> SERVER_PLAYER_CAPABILITIES = SimpleNetworking.serverToClient(Unicopia.id("player_capabilities"), MsgPlayerCapabilities::new);
|
||||
S2CPacketType<MsgSpawnProjectile> SERVER_SPAWN_PROJECTILE = SimpleNetworking.serverToClient(Unicopia.id("projectile_entity"), MsgSpawnProjectile::new);
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
package com.minelittlepony.unicopia.network;
|
||||
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.sollace.fabwork.api.packets.HandledPacket;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
|
||||
public record MsgPlayerFlightControlsInput (
|
||||
boolean ascending,
|
||||
boolean descending
|
||||
) implements HandledPacket<ServerPlayerEntity> {
|
||||
|
||||
public MsgPlayerFlightControlsInput(Pony pony) {
|
||||
this(pony.getJumpingHeuristic().getState(), pony.asEntity().isSneaking());
|
||||
}
|
||||
|
||||
public MsgPlayerFlightControlsInput(PacketByteBuf buffer) {
|
||||
this(buffer.readBoolean(), buffer.readBoolean());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toBuffer(PacketByteBuf buffer) {
|
||||
buffer.writeBoolean(ascending);
|
||||
buffer.writeBoolean(descending);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(ServerPlayerEntity sender) {
|
||||
sender.setSneaking(descending);
|
||||
sender.setJumping(ascending);
|
||||
}
|
||||
}
|
|
@ -708,48 +708,65 @@
|
|||
"death.attack.unicopia.generic.and_also": "%1$s and %2$s",
|
||||
"death.attack.unicopia.generic.whilst_flying": "%1$s whilst flying",
|
||||
"death.attack.unicopia.tribe_swap": "%1$s was reborn into a different tribe",
|
||||
"death.attack.unicopia.tribe_swap.self": "%1$s was doomed themselved to be reborn into a different tribe",
|
||||
"death.attack.unicopia.tribe_swap.player": "%1$s was doomed to be reborn into a different tribe by %2$s",
|
||||
"death.attack.unicopia.sun": "%1$s stared into the sun",
|
||||
"death.attack.unicopia.sun.self": "%1$s stared into the sun",
|
||||
"death.attack.unicopia.sun.player": "%1$s stared into the sun whilst fighting %2$s",
|
||||
"death.attack.unicopia.sunlight": "%1$s was burned by the sun",
|
||||
"death.attack.unicopia.sunlight.self": "%1$s was burned by the sun",
|
||||
"death.attack.unicopia.sunlight.player": "%1$s was burned by the sun whilst fighting %2$s",
|
||||
"death.attack.unicopia.petrified": "%1$s turned to stone",
|
||||
"death.attack.unicopia.petrified.self": "%1$s turned to stone",
|
||||
"death.attack.unicopia.petrified.player": "%1$s turned to stone whilst fighting %2$s",
|
||||
"death.attack.unicopia.magical_exhaustion": "%1$s exhausted themselves",
|
||||
"death.attack.unicopia.magical_exhaustion.self": "%1$s exhausted themselves",
|
||||
"death.attack.unicopia.magical_exhaustion.player": "%1$s exhausted themselves whilst fighting %2$s",
|
||||
"death.attack.unicopia.alicorn_amulet": "%1$s was driven insane",
|
||||
"death.attack.unicopia.alicorn_amulet.self": "%1$s drove themselves insane",
|
||||
"death.attack.unicopia.alicorn_amulet.player": "%1$s went insane whilst fighting %2$s",
|
||||
"death.attack.unicopia.darkness": "%1$s went missing",
|
||||
"death.attack.unicopia.darkness.self": "%1$s went missing",
|
||||
"death.attack.unicopia.darkness.player": "%1$s went missing whilst fighting %2$s",
|
||||
"death.attack.unicopia.love_draining": "%1$s was drained of all love",
|
||||
"death.attack.unicopia.love_draining.self": "%1$s expelled all of their own love",
|
||||
"death.attack.unicopia.love_draining.player": "%2$s drained %1$s of all their love",
|
||||
"death.attack.unicopia.life_draining": "%1$s was sucked dry",
|
||||
"death.attack.unicopia.life_draining.self": "%1$s was killed by their own spell",
|
||||
"death.attack.unicopia.life_draining.player": "%1$s was killed by a spell cast by %2$s",
|
||||
"death.attack.unicopia.bat_screech": "%1$s was spooked",
|
||||
"death.attack.unicopia.bat_screech.self": "%1$s spooked themselves",
|
||||
"death.attack.unicopia.bat_screech.player": "%2$s spooked %1$s",
|
||||
"death.attack.unicopia.bat_screech.item": "%1$s was spooked by %2$s using %3$s",
|
||||
"death.attack.unicopia.bat_screech.self": "%1$s spooked themselves",
|
||||
"death.attack.unicopia.gravity_well_recoil": "%1$s turned into spaghetti",
|
||||
"death.attack.unicopia.gravity_well_recoil.player": "%1$s turned into spaghetti by a spell cast by %2$s",
|
||||
"death.attack.unicopia.gravity_well_recoil.item": "%1$s turned into spaghetti by a spell cast by %2$s using %3$s",
|
||||
"death.attack.unicopia.gravity_well_recoil.self": "%1$s cast a spell that turned them into spaghetti",
|
||||
"death.attack.unicopia.smash": "%1$s was crushed under hoof",
|
||||
"death.attack.unicopia.smash.self": "%1$s got themselves crushed under a hoof",
|
||||
"death.attack.unicopia.smash.player": "%1$s was crushed by %2$s",
|
||||
"death.attack.unicopia.zap": "%1$s bit into a Zap Apple",
|
||||
"death.attack.unicopia.zap.self": "%1$s bit into a Zap Apple",
|
||||
"death.attack.unicopia.zap.player": "%1$s bit into a Zap Apple whilst fighting %2$s",
|
||||
"death.attack.unicopia.paradox": "%1$s imploded",
|
||||
"death.attack.unicopia.paradox.self": "%1$s imploded themselves",
|
||||
"death.attack.unicopia.paradox.player": "%1$s imploded with some help from %2$s",
|
||||
"death.attack.unicopia.food_poisoning": "%1$s died of food poisoning",
|
||||
"death.attack.unicopia.food_poisoning.self": "%1$s died of food poisoning",
|
||||
"death.attack.unicopia.food_poisoning.player": "%2$s poisoned %1$s to death",
|
||||
"death.attack.unicopia.black_hole": "%1$s was sucked into a black hole",
|
||||
"death.attack.unicopia.black_hole.self": "%1$s was sucked into a black hole",
|
||||
"death.attack.unicopia.black_hole.player": "%1$s got sucked into %2$s's black hole",
|
||||
"death.attack.unicopia.kick": "%1$s was kicked really hard",
|
||||
"death.attack.unicopia.kick.self": "%1$s kicked themselves really hard",
|
||||
"death.attack.unicopia.kick.player": "%2$s kicked %1$s really hard",
|
||||
"death.attack.unicopia.steamroller": "%1$s was flattened",
|
||||
"death.attack.unicopia.steamroller.self": "%1$s was flattened",
|
||||
"death.attack.unicopia.steamroller.player": "%2$s steamrolled %1$s",
|
||||
"death.attack.unicopia.stalagmite.pegasus": "%1$s tried to perch on a stalagmite",
|
||||
"death.attack.unicopia.stalagmite.pegasus.player": "%1$s flew into a stalagmite whilst fighting %2$s",
|
||||
"death.attack.unicopia.rock": "%1$s was pummeled",
|
||||
"death.attack.unicopia.rock.self": "%1$s was pummeled",
|
||||
"death.attack.unicopia.rock.item": "%1$s was pummelled by %2$s using %3$s",
|
||||
"death.attack.unicopia.rock.player": "%1$s was pummelled by %2$s",
|
||||
|
||||
|
|
Loading…
Reference in a new issue