91 lines
2.4 KiB
Java
91 lines
2.4 KiB
Java
package mindustry.entities.def;
|
|
|
|
import arc.math.*;
|
|
import arc.math.geom.*;
|
|
import arc.util.*;
|
|
import mindustry.annotations.Annotations.*;
|
|
import mindustry.content.*;
|
|
import mindustry.gen.*;
|
|
import mindustry.world.blocks.*;
|
|
|
|
import static mindustry.Vars.net;
|
|
|
|
@Component
|
|
abstract class FlyingComp implements Posc, Velc, Healthc, Hitboxc{
|
|
@Import float x, y, drag;
|
|
@Import Vec2 vel;
|
|
|
|
float elevation;
|
|
float drownTime;
|
|
transient float splashTimer;
|
|
|
|
boolean isGrounded(){
|
|
return elevation < 0.001f;
|
|
}
|
|
|
|
boolean isFlying(){
|
|
return elevation >= 0.001f;
|
|
}
|
|
|
|
boolean canDrown(){
|
|
return isGrounded();
|
|
}
|
|
|
|
void wobble(){
|
|
x += Mathf.sin(Time.time() + id() * 99, 25f, 0.05f) * Time.delta() * elevation;
|
|
y += Mathf.cos(Time.time() + id() * 99, 25f, 0.05f) * Time.delta() * elevation;
|
|
}
|
|
|
|
void moveAt(Vec2 vector){
|
|
moveAt(vector, 1f);
|
|
}
|
|
|
|
void moveAt(Vec2 vector, float acceleration){
|
|
Vec2 t = Tmp.v3.set(vector).scl(floorSpeedMultiplier()); //target vector
|
|
Tmp.v1.set(t).sub(vel).limit(acceleration * vector.len()); //delta vector
|
|
vel.add(Tmp.v1);
|
|
|
|
//float mag = Tmp.v3.len() * acceleration;
|
|
//vel.lerp(t, Tmp.v3.len() * acceleration);
|
|
//vel.x = Mathf.approach(vel.x, t.x, mag);
|
|
//vel.y = Mathf.approach(vel.y, t.y, mag);
|
|
}
|
|
|
|
float floorSpeedMultiplier(){
|
|
Floor on = isFlying() ? Blocks.air.asFloor() : floorOn();
|
|
return on.speedMultiplier;
|
|
}
|
|
|
|
@Override
|
|
public void update(){
|
|
Floor floor = floorOn();
|
|
|
|
if(isFlying() && !net.client()){
|
|
wobble();
|
|
}
|
|
|
|
if(isGrounded() && floor.isLiquid){
|
|
if((splashTimer += Mathf.dst(deltaX(), deltaY())) >= 7f){
|
|
floor.walkEffect.at(x, y, 0, floor.mapColor);
|
|
splashTimer = 0f;
|
|
}
|
|
}
|
|
|
|
if(canDrown() && floor.isLiquid && floor.drownTime > 0){
|
|
drownTime += Time.delta() * 1f / floor.drownTime;
|
|
drownTime = Mathf.clamp(drownTime);
|
|
if(Mathf.chance(Time.delta() * 0.05f)){
|
|
floor.drownUpdateEffect.at(x, y, 0f, floor.mapColor);
|
|
}
|
|
|
|
//TODO is the netClient check necessary?
|
|
if(drownTime >= 0.999f && !net.client()){
|
|
kill();
|
|
//TODO drown event!
|
|
}
|
|
}else{
|
|
drownTime = Mathf.lerpDelta(drownTime, 0f, 0.03f);
|
|
}
|
|
}
|
|
}
|