mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-08 01:17:47 +01:00
feat: add experimental player pose update logic
This commit is contained in:
parent
8715f4305d
commit
d8ef618d08
@ -101,7 +101,7 @@ public class Entity implements Viewable, Tickable, Schedulable, Snapshotable, Ev
|
|||||||
protected Pos lastSyncedPosition;
|
protected Pos lastSyncedPosition;
|
||||||
protected boolean onGround;
|
protected boolean onGround;
|
||||||
|
|
||||||
private BoundingBox boundingBox;
|
protected BoundingBox boundingBox;
|
||||||
private PhysicsResult lastPhysicsResult = null;
|
private PhysicsResult lastPhysicsResult = null;
|
||||||
|
|
||||||
protected Entity vehicle;
|
protected Entity vehicle;
|
||||||
|
@ -21,6 +21,9 @@ import net.minestom.server.adventure.AdventurePacketConvertor;
|
|||||||
import net.minestom.server.adventure.Localizable;
|
import net.minestom.server.adventure.Localizable;
|
||||||
import net.minestom.server.adventure.audience.Audiences;
|
import net.minestom.server.adventure.audience.Audiences;
|
||||||
import net.minestom.server.attribute.Attribute;
|
import net.minestom.server.attribute.Attribute;
|
||||||
|
import net.minestom.server.collision.BoundingBox;
|
||||||
|
import net.minestom.server.collision.CollisionUtils;
|
||||||
|
import net.minestom.server.collision.PhysicsResult;
|
||||||
import net.minestom.server.command.CommandSender;
|
import net.minestom.server.command.CommandSender;
|
||||||
import net.minestom.server.coordinate.Point;
|
import net.minestom.server.coordinate.Point;
|
||||||
import net.minestom.server.coordinate.Pos;
|
import net.minestom.server.coordinate.Pos;
|
||||||
@ -28,6 +31,7 @@ import net.minestom.server.coordinate.Vec;
|
|||||||
import net.minestom.server.effects.Effects;
|
import net.minestom.server.effects.Effects;
|
||||||
import net.minestom.server.entity.damage.DamageType;
|
import net.minestom.server.entity.damage.DamageType;
|
||||||
import net.minestom.server.entity.fakeplayer.FakePlayer;
|
import net.minestom.server.entity.fakeplayer.FakePlayer;
|
||||||
|
import net.minestom.server.entity.metadata.LivingEntityMeta;
|
||||||
import net.minestom.server.entity.metadata.PlayerMeta;
|
import net.minestom.server.entity.metadata.PlayerMeta;
|
||||||
import net.minestom.server.entity.vehicle.PlayerVehicleInformation;
|
import net.minestom.server.entity.vehicle.PlayerVehicleInformation;
|
||||||
import net.minestom.server.event.EventDispatcher;
|
import net.minestom.server.event.EventDispatcher;
|
||||||
@ -39,6 +43,7 @@ import net.minestom.server.event.player.*;
|
|||||||
import net.minestom.server.instance.Chunk;
|
import net.minestom.server.instance.Chunk;
|
||||||
import net.minestom.server.instance.EntityTracker;
|
import net.minestom.server.instance.EntityTracker;
|
||||||
import net.minestom.server.instance.Instance;
|
import net.minestom.server.instance.Instance;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
import net.minestom.server.inventory.Inventory;
|
import net.minestom.server.inventory.Inventory;
|
||||||
import net.minestom.server.inventory.PlayerInventory;
|
import net.minestom.server.inventory.PlayerInventory;
|
||||||
import net.minestom.server.item.ItemStack;
|
import net.minestom.server.item.ItemStack;
|
||||||
@ -115,6 +120,8 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
|
|||||||
private static final int PACKET_PER_TICK = Integer.getInteger("minestom.packet-per-tick", 20);
|
private static final int PACKET_PER_TICK = Integer.getInteger("minestom.packet-per-tick", 20);
|
||||||
private static final int PACKET_QUEUE_SIZE = Integer.getInteger("minestom.packet-queue-size", 1000);
|
private static final int PACKET_QUEUE_SIZE = Integer.getInteger("minestom.packet-queue-size", 1000);
|
||||||
|
|
||||||
|
public static final boolean EXPERIMENT_PERFORM_POSE_UPDATES = Boolean.getBoolean("minestom.experiment.pose-updates");
|
||||||
|
|
||||||
private long lastKeepAlive;
|
private long lastKeepAlive;
|
||||||
private boolean answerKeepAlive;
|
private boolean answerKeepAlive;
|
||||||
|
|
||||||
@ -421,6 +428,8 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (EXPERIMENT_PERFORM_POSE_UPDATES) updatePose();
|
||||||
|
|
||||||
// Tick event
|
// Tick event
|
||||||
EventDispatcher.call(new PlayerTickEvent(this));
|
EventDispatcher.call(new PlayerTickEvent(this));
|
||||||
}
|
}
|
||||||
@ -745,6 +754,63 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
|
|||||||
EventDispatcher.call(new PlayerSpawnEvent(this, instance, firstSpawn));
|
EventDispatcher.call(new PlayerSpawnEvent(this, instance, firstSpawn));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void updatePose() {
|
||||||
|
Pose oldPose = getPose();
|
||||||
|
Pose newPose;
|
||||||
|
|
||||||
|
// Figure out their expected state
|
||||||
|
var meta = Objects.requireNonNull(getLivingEntityMeta());
|
||||||
|
if (meta.isFlyingWithElytra()) {
|
||||||
|
newPose = Pose.FALL_FLYING;
|
||||||
|
} else if (false) { // When should they be sleeping? We don't have any in-bed state...
|
||||||
|
newPose = Pose.SLEEPING;
|
||||||
|
} else if (meta.isSwimming()) {
|
||||||
|
newPose = Pose.SWIMMING;
|
||||||
|
} else if (meta.isInRiptideSpinAttack()) {
|
||||||
|
newPose = Pose.SPIN_ATTACK;
|
||||||
|
} else if (isSneaking() && !isFlying()) {
|
||||||
|
newPose = Pose.SNEAKING;
|
||||||
|
} else {
|
||||||
|
newPose = Pose.STANDING;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to put them in their expected state, or the closest if they don't fit.
|
||||||
|
if (canFitWithBoundingBox(newPose)) {
|
||||||
|
// Use expected state
|
||||||
|
} else if (canFitWithBoundingBox(Pose.SNEAKING)) {
|
||||||
|
newPose = Pose.SNEAKING;
|
||||||
|
} else if (canFitWithBoundingBox(Pose.SWIMMING)) {
|
||||||
|
newPose = Pose.SWIMMING;
|
||||||
|
} else {
|
||||||
|
// If they can't fit anywhere, just use standing
|
||||||
|
newPose = Pose.STANDING;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newPose != oldPose) setPose(newPose);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the player can fit at the current position with the given {@link net.minestom.server.entity.Entity.Pose}, false otherwise.
|
||||||
|
* @param pose The pose to check
|
||||||
|
*/
|
||||||
|
private boolean canFitWithBoundingBox(@NotNull Pose pose) {
|
||||||
|
BoundingBox bb = pose == Pose.STANDING ? boundingBox : BoundingBox.fromPose(pose);
|
||||||
|
if (bb == null) return false;
|
||||||
|
|
||||||
|
var position = getPosition();
|
||||||
|
var iter = bb.getBlocks(getPosition());
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
var pos = iter.next();
|
||||||
|
var hit = instance.getBlock(pos, Block.Getter.Condition.TYPE)
|
||||||
|
.registry().collisionShape()
|
||||||
|
.intersectBox(position.sub(pos), bb);
|
||||||
|
if (hit) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a plugin message to the player.
|
* Sends a plugin message to the player.
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user