mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-23 21:38:00 +01:00
Fixed flight velocity/control state going out of sync with the server and add some behavioural tweaks
Note to Fauli: SPACE TO FLAP/ASCENT, SHIFT TO DESCEND Also changed the behaviour for changeling flight (again). Fixes #205 Fixes #179 Fixes #165 Fixes #176
This commit is contained in:
parent
427fc7d210
commit
b4a595550a
3 changed files with 77 additions and 27 deletions
|
@ -19,6 +19,8 @@ import com.minelittlepony.unicopia.item.AmuletItem;
|
||||||
import com.minelittlepony.unicopia.item.ChargeableItem;
|
import com.minelittlepony.unicopia.item.ChargeableItem;
|
||||||
import com.minelittlepony.unicopia.item.UItems;
|
import com.minelittlepony.unicopia.item.UItems;
|
||||||
import com.minelittlepony.unicopia.item.enchantment.UEnchantments;
|
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.particle.*;
|
||||||
import com.minelittlepony.unicopia.projectile.ProjectileUtil;
|
import com.minelittlepony.unicopia.projectile.ProjectileUtil;
|
||||||
import com.minelittlepony.unicopia.server.world.BlockDestructionManager;
|
import com.minelittlepony.unicopia.server.world.BlockDestructionManager;
|
||||||
|
@ -43,6 +45,7 @@ import net.minecraft.predicate.entity.EntityPredicates;
|
||||||
import net.minecraft.registry.RegistryKeys;
|
import net.minecraft.registry.RegistryKeys;
|
||||||
import net.minecraft.sound.SoundCategory;
|
import net.minecraft.sound.SoundCategory;
|
||||||
import net.minecraft.sound.SoundEvent;
|
import net.minecraft.sound.SoundEvent;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
import net.minecraft.util.math.*;
|
import net.minecraft.util.math.*;
|
||||||
import net.minecraft.world.dimension.DimensionType;
|
import net.minecraft.world.dimension.DimensionType;
|
||||||
import net.minecraft.world.event.GameEvent;
|
import net.minecraft.world.event.GameEvent;
|
||||||
|
@ -130,7 +133,7 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isGliding() {
|
public boolean isGliding() {
|
||||||
return ticksToGlide <= 0 && isFlying() && !entity.isSneaking();
|
return ticksToGlide <= 0 && isFlying() && !pony.getJumpingHeuristic().getState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -228,6 +231,10 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
||||||
public void tick() {
|
public void tick() {
|
||||||
super.tick();
|
super.tick();
|
||||||
|
|
||||||
|
if (pony.isClient() && this.isFlying()) {
|
||||||
|
Channel.FLIGHT_CONTROLS_INPUT.sendToServer(new MsgPlayerFlightControlsInput(pony));
|
||||||
|
}
|
||||||
|
|
||||||
prevThrustScale = thrustScale;
|
prevThrustScale = thrustScale;
|
||||||
|
|
||||||
if (wallHitCooldown > 0) {
|
if (wallHitCooldown > 0) {
|
||||||
|
@ -404,16 +411,14 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
||||||
|
|
||||||
entity.fallDistance = 0;
|
entity.fallDistance = 0;
|
||||||
|
|
||||||
if (type.isAvian()) {
|
applyThrust(velocity);
|
||||||
applyThrust(velocity);
|
|
||||||
|
|
||||||
|
if (type.isAvian()) {
|
||||||
if (pony.getObservedSpecies() != Race.BAT && entity.getWorld().random.nextInt(9000) == 0) {
|
if (pony.getObservedSpecies() != Race.BAT && entity.getWorld().random.nextInt(9000) == 0) {
|
||||||
entity.dropItem(UItems.PEGASUS_FEATHER);
|
entity.dropItem(UItems.PEGASUS_FEATHER);
|
||||||
playSound(USounds.ENTITY_PLAYER_PEGASUS_MOLT, 0.3F, 1);
|
playSound(USounds.ENTITY_PLAYER_PEGASUS_MOLT, 0.3F, 1);
|
||||||
UCriteria.SHED_FEATHER.trigger(entity);
|
UCriteria.SHED_FEATHER.trigger(entity);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
applyThrust(velocity);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
moveFlying(velocity);
|
moveFlying(velocity);
|
||||||
|
@ -429,8 +434,6 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
||||||
InteractionManager.instance().playLoopingSound(entity, InteractionManager.SOUND_GLIDING, entity.getId());
|
InteractionManager.instance().playLoopingSound(entity, InteractionManager.SOUND_GLIDING, entity.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} else if (type == FlightType.INSECTOID && !SpellPredicate.IS_DISGUISE.isOn(pony)) {
|
} else if (type == FlightType.INSECTOID && !SpellPredicate.IS_DISGUISE.isOn(pony)) {
|
||||||
if (entity.getWorld().isClient && !soundPlaying) {
|
if (entity.getWorld().isClient && !soundPlaying) {
|
||||||
soundPlaying = true;
|
soundPlaying = true;
|
||||||
|
@ -477,7 +480,8 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
||||||
}
|
}
|
||||||
|
|
||||||
private void playSound(SoundEvent sound, float volume, float pitch) {
|
private void playSound(SoundEvent sound, float volume, float pitch) {
|
||||||
entity.getWorld().playSoundFromEntity(null, entity, sound, SoundCategory.PLAYERS, volume, pitch);
|
entity.sendMessage(Text.literal((entity.getWorld().isClient ? "[Client]" : "[Server]") + "Playing " + sound));
|
||||||
|
entity.getWorld().playSoundFromEntity(entity, entity, sound, SoundCategory.PLAYERS, volume, pitch);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tickNaturalFlight(MutableVector velocity) {
|
private void tickNaturalFlight(MutableVector velocity) {
|
||||||
|
@ -556,12 +560,14 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
||||||
isFlyingEither = true;
|
isFlyingEither = true;
|
||||||
isFlyingSurvival = true;
|
isFlyingSurvival = true;
|
||||||
thrustScale = 0;
|
thrustScale = 0;
|
||||||
|
descentRate = 0;
|
||||||
entity.calculateDimensions();
|
entity.calculateDimensions();
|
||||||
|
|
||||||
if (entity.isOnGround() || !force) {
|
if (entity.isOnGround() || !force) {
|
||||||
Supplier<Vec3d> vec = VecHelper.sphere(pony.asWorld().getRandom(), 0.5D);
|
Supplier<Vec3d> pos = VecHelper.sphere(pony.asWorld().getRandom(), 0.5D);
|
||||||
pony.spawnParticles(ParticleTypes.CAMPFIRE_COSY_SMOKE, vec, vec, 5);
|
Supplier<Vec3d> vel = VecHelper.sphere(pony.asWorld().getRandom(), 0.15D);
|
||||||
pony.spawnParticles(ParticleTypes.CLOUD, vec, vec, 5);
|
pony.spawnParticles(ParticleTypes.CAMPFIRE_COSY_SMOKE, pos, vel, 5);
|
||||||
|
pony.spawnParticles(ParticleTypes.CLOUD, pos, vel, 5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -627,11 +633,12 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
||||||
if (descentRate < 0) {
|
if (descentRate < 0) {
|
||||||
descentRate *= 0.8F;
|
descentRate *= 0.8F;
|
||||||
}
|
}
|
||||||
|
|
||||||
velocity.y -= descentRate * getGravityModifier();
|
velocity.y -= descentRate * getGravityModifier();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyThrust(MutableVector velocity) {
|
private void applyThrust(MutableVector velocity) {
|
||||||
boolean manualFlap = pony.sneakingChanged() && entity.isSneaking();
|
boolean manualFlap = pony.getJumpingHeuristic().hasChanged(Heuristic.ONCE) && pony.getJumpingHeuristic().getState();
|
||||||
if (manualFlap) {
|
if (manualFlap) {
|
||||||
flapping = true;
|
flapping = true;
|
||||||
ticksToGlide = MAX_TICKS_TO_GLIDE;
|
ticksToGlide = MAX_TICKS_TO_GLIDE;
|
||||||
|
@ -641,24 +648,30 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
||||||
|
|
||||||
boolean hovering = entity.getVelocity().horizontalLength() < 0.1;
|
boolean hovering = entity.getVelocity().horizontalLength() < 0.1;
|
||||||
|
|
||||||
if (thrustScale <= 0.000001F & flapping) {
|
if (!entity.getWorld().isClient) {
|
||||||
flapping = false;
|
entity.sendMessage(Text.literal("Jumping:" + pony.getJumpingHeuristic().getState()));
|
||||||
if (!SpellPredicate.IS_DISGUISE.isOn(pony)) {
|
}
|
||||||
if (lastFlightType != FlightType.INSECTOID) {
|
|
||||||
|
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)) {
|
||||||
playSound(lastFlightType.getWingFlapSound(), 0.25F, entity.getSoundPitch() * lastFlightType.getWingFlapSoundPitch());
|
playSound(lastFlightType.getWingFlapSound(), 0.25F, entity.getSoundPitch() * lastFlightType.getWingFlapSoundPitch());
|
||||||
|
entity.getWorld().emitGameEvent(entity, GameEvent.ELYTRA_GLIDE, entity.getPos());
|
||||||
|
}
|
||||||
|
thrustScale = 1;
|
||||||
|
if (manualFlap) {
|
||||||
|
descentRate -= 0.5;
|
||||||
|
} else {
|
||||||
|
descentRate = Math.max(0, descentRate / 2);
|
||||||
}
|
}
|
||||||
entity.getWorld().emitGameEvent(entity, GameEvent.ELYTRA_GLIDE, entity.getPos());
|
|
||||||
}
|
|
||||||
thrustScale = 1;
|
|
||||||
if (manualFlap) {
|
|
||||||
descentRate -= 0.5;
|
|
||||||
} else {
|
|
||||||
descentRate = Math.max(0, descentRate / 2);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float heavyness = EnchantmentHelper.getEquipmentLevel(UEnchantments.HEAVY, entity);
|
float heavyness = EnchantmentHelper.getEquipmentLevel(UEnchantments.HEAVY, entity);
|
||||||
float thrustStrength = 0.135F * thrustScale;
|
float thrustStrength = 0.235F * thrustScale;
|
||||||
|
|
||||||
if (heavyness > 0) {
|
if (heavyness > 0) {
|
||||||
thrustStrength /= 1 + heavyness;
|
thrustStrength /= 1 + heavyness;
|
||||||
|
@ -666,9 +679,13 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
||||||
|
|
||||||
Vec3d direction = entity.getRotationVec(1).normalize().multiply(thrustStrength);
|
Vec3d direction = entity.getRotationVec(1).normalize().multiply(thrustStrength);
|
||||||
|
|
||||||
if (!hovering) {
|
if (hovering) {
|
||||||
velocity.x += direction.x;
|
if (entity.isSneaking()) {
|
||||||
velocity.z += direction.z;
|
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
|
velocity.y += ((direction.y * 2.45 + Math.abs(direction.y) * 10)) * getGravitySignum();// - heavyness / 5F
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ public interface Channel {
|
||||||
C2SPacketType<MsgRequestSpeciesChange> CLIENT_REQUEST_SPECIES_CHANGE = SimpleNetworking.clientToServer(Unicopia.id("request_capabilities"), MsgRequestSpeciesChange::new);
|
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<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<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<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);
|
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);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue