package com.hypixel.hytale.server.core.modules.physics.component;
import com.hypixel.hytale.codec.KeyedCodec;
import com.hypixel.hytale.codec.builder.BuilderCodec;
import com.hypixel.hytale.component.Component;
import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.protocol.ChangeVelocityType;
import com.hypixel.hytale.server.core.modules.entity.EntityModule;
import com.hypixel.hytale.server.core.modules.splitvelocity.VelocityConfig;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class Velocity implements Component<EntityStore> {
@Nonnull
public static final BuilderCodec<Velocity> CODEC;
@Nonnull
protected final List<Instruction> instructions;
@Nonnull
protected final Vector3d velocity;
@Nonnull
protected final Vector3d clientVelocity;
@Nonnull
public static ComponentType<EntityStore, Velocity> getComponentType() {
return EntityModule.get().getVelocityComponentType();
}
public Velocity() {
this.instructions = new ObjectArrayList<Instruction>();
this.velocity = new Vector3d();
this.clientVelocity = new Vector3d();
}
public Velocity(@Nonnull Velocity other) {
this(other.velocity.clone());
}
public Velocity(@Nonnull Vector3d initialVelocity) {
this.instructions = new ObjectArrayList<Instruction>();
this.velocity = new Vector3d();
this.clientVelocity = new Vector3d();
this.velocity.assign(initialVelocity);
}
public void setZero() {
this.set(0.0, 0.0, 0.0);
}
public void addForce(@Nonnull Vector3d force) {
this.velocity.add(force);
}
public void addForce(double x, double y, double z) {
this.velocity.add(x, y, z);
}
public void set(@Nonnull Vector3d newVelocity) {
this.set(newVelocity.getX(), newVelocity.getY(), newVelocity.getZ());
}
public void set(double x, double y, double z) {
this.velocity.assign(x, y, z);
}
public void setClient(@Nonnull Vector3d newVelocity) {
this.setClient(newVelocity.getX(), newVelocity.getY(), newVelocity.getZ());
}
public void setClient(double x, double y, double z) {
this.clientVelocity.assign(x, y, z);
}
public void setX(double x) {
this.velocity.setX(x);
}
public void setY(double y) {
this.velocity.setY(y);
}
public void setZ(double z) {
this.velocity.setZ(z);
}
public double getX() {
return this.velocity.getX();
}
public double getY() {
return this.velocity.getY();
}
public double getZ() {
return this.velocity.getZ();
}
public double getSpeed() {
return this.velocity.length();
}
public void addInstruction(@Nonnull Vector3d velocity, @Nullable VelocityConfig config, @Nonnull ChangeVelocityType type) {
this.instructions.add(new Instruction(velocity, config, type));
}
@Nonnull
public List<Instruction> getInstructions() {
return this.instructions;
}
@Nonnull
public Vector3d getVelocity() {
return this.velocity;
}
@Nonnull
public Vector3d getClientVelocity() {
return this.clientVelocity;
}
@Nonnull
public Vector3d assignVelocityTo(@Nonnull Vector3d vector) {
return vector.assign(this.velocity);
}
@Nonnull
public Component<EntityStore> clone() {
return new Velocity(this);
}
static {
CODEC = ((BuilderCodec.Builder)BuilderCodec.builder(Velocity.class, Velocity::new).append(new KeyedCodec("Velocity", Vector3d.CODEC), (entity, o) -> entity.velocity.assign(o), (entity) -> entity.velocity).add()).build();
}
public static final class Instruction {
@Nonnull
private final Vector3d velocity;
@Nullable
private final VelocityConfig config;
@Nonnull
private final ChangeVelocityType type;
public Instruction(@Nonnull Vector3d velocity, @Nullable VelocityConfig config, @Nonnull ChangeVelocityType type) {
this.velocity = velocity;
this.config = config;
this.type = type;
}
@Nonnull
public Vector3d getVelocity() {
return this.velocity;
}
@Nullable
public VelocityConfig getConfig() {
return this.config;
}
@Nonnull
public ChangeVelocityType getType() {
return this.type;
}
}
}