Drownable legged units

This commit is contained in:
Anuken
2021-08-22 11:06:25 -04:00
parent 1d46fb5425
commit 4af101bf7d
8 changed files with 77 additions and 29 deletions

View File

@@ -129,7 +129,7 @@ public class Units{
nearby(x, y, width, height, unit -> {
if(boolResult) return;
if((unit.isGrounded() && !unit.type.hovering) == ground){
if((unit.isGrounded() && !unit.hovering) == ground){
unit.hitboxTile(hitrect);
if(hitrect.overlaps(x, y, width, height)){

View File

@@ -25,6 +25,7 @@ abstract class CrawlComp implements Posc, Rotc, Hitboxc, Unitc{
@Import Team team;
@Import Vec2 vel;
transient Floor lastDeepFloor;
//TODO segments
transient float lastCrawlSlowdown = 1f;
transient float segmentRot, crawlTime;
@@ -55,13 +56,20 @@ abstract class CrawlComp implements Posc, Rotc, Hitboxc, Unitc{
segmentRot = rotation;
}
@Override
@Replace
public Floor drownFloor(){
return lastDeepFloor;
}
@Override
public void update(){
if(moving()){
segmentRot = Angles.moveToward(segmentRot, rotation, type.segmentRotSpeed);
int radius = (int)Math.max(0, hitSize / tilesize);
int count = 0, solids = 0;
int count = 0, solids = 0, deeps = 0;
lastDeepFloor = null;
//calculate tiles under this unit, and apply slowdown + particle effects
for(int cx = -radius; cx <= radius; cx++){
@@ -75,6 +83,11 @@ abstract class CrawlComp implements Posc, Rotc, Hitboxc, Unitc{
solids ++;
}
if(t.floor().isDeep()){
deeps ++;
lastDeepFloor = t.floor();
}
if(t.build != null && t.build.team != team){
t.build.damage(team, type.crawlDamage * Time.delta);
}
@@ -89,6 +102,11 @@ abstract class CrawlComp implements Posc, Rotc, Hitboxc, Unitc{
}
}
//when most blocks under this unit cannot be drowned in, do not drown
if((float)deeps / count < 0.75f){
lastDeepFloor = null;
}
lastCrawlSlowdown = Mathf.lerp(1f, type.crawlSlowdown, Mathf.clamp((float)solids / count / type.crawlSlowdownFrac));
}
segmentRot = Angles.clampRange(segmentRot, rotation, type.segmentMaxRot);

View File

@@ -17,7 +17,7 @@ import static mindustry.Vars.*;
abstract class FlyingComp implements Posc, Velc, Healthc, Hitboxc{
private static final Vec2 tmp1 = new Vec2(), tmp2 = new Vec2();
@Import float x, y, speedMultiplier;
@Import float x, y, speedMultiplier, hitSize;
@Import Vec2 vel;
@Import UnitType type;
@@ -47,7 +47,7 @@ abstract class FlyingComp implements Posc, Velc, Healthc, Hitboxc{
//TODO
@Nullable
Floor drownFloor(){
return null;
return canDrown() ? floorOn() : null;
}
void landed(){
@@ -95,13 +95,17 @@ abstract class FlyingComp implements Posc, Velc, Healthc, Hitboxc{
}
}
//TODO separate method?
//TODO drown eligibility, store drown color.
if(canDrown() && floor.isLiquid && floor.drownTime > 0){
updateDrowning();
}
public void updateDrowning(){
Floor floor = drownFloor();
if(floor != null && floor.isLiquid && floor.drownTime > 0){
lastDrownFloor = floor;
drownTime += Time.delta / floor.drownTime / type.drownTimeMultiplier;
if(Mathf.chanceDelta(0.05f)){
floor.drownUpdateEffect.at(x, y, 1f, floor.mapColor);
floor.drownUpdateEffect.at(x, y, hitSize, floor.mapColor);
}
if(drownTime >= 0.999f && !net.client()){

View File

@@ -9,6 +9,7 @@ import mindustry.annotations.Annotations.*;
import mindustry.content.*;
import mindustry.entities.*;
import mindustry.entities.EntityCollisions.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.type.*;
@@ -18,22 +19,30 @@ import mindustry.world.blocks.environment.*;
abstract class LegsComp implements Posc, Rotc, Hitboxc, Flyingc, Unitc{
@Import float x, y;
@Import UnitType type;
@Import Team team;
transient Leg[] legs = {};
transient float totalLength;
transient float moveSpace;
transient float baseRotation;
transient Floor lastDeepFloor;
@Replace
@Override
public SolidPred solidity(){
return !type.allowLegStep ? EntityCollisions::solid : EntityCollisions::legsSolid;
return type.allowLegStep ? EntityCollisions::legsSolid : EntityCollisions::solid;
}
@Override
@Replace
public int pathType(){
return Pathfinder.costLegs;
return type.allowLegStep ? Pathfinder.costGround : Pathfinder.costLegs;
}
@Override
@Replace
public Floor drownFloor(){
return lastDeepFloor;
}
@Override
@@ -85,6 +94,9 @@ abstract class LegsComp implements Posc, Rotc, Hitboxc, Flyingc, Unitc{
Vec2 moveOffset = Tmp.v4.trns(rot, trns);
boolean moving = moving();
lastDeepFloor = null;
int deeps = 0;
for(int i = 0; i < legs.length; i++){
float dstRot = legAngle(rot, i);
Vec2 baseOffset = Tmp.v5.trns(dstRot, type.legBaseOffset).add(x, y);
@@ -105,11 +117,16 @@ abstract class LegsComp implements Posc, Rotc, Hitboxc, Flyingc, Unitc{
l.moving = move;
l.stage = moving ? stageF % 1f : Mathf.lerpDelta(l.stage, 0f, 0.1f);
Floor floor = Vars.world.floorWorld(l.base.x, l.base.y);
if(floor.isDeep()){
deeps ++;
lastDeepFloor = floor;
}
if(l.group != group){
//create effect when transitioning to a group it can't move in
if(!move && i % div == l.group){
Floor floor = Vars.world.floorWorld(l.base.x, l.base.y);
if(floor.isLiquid){
floor.walkEffect.at(l.base.x, l.base.y, type.rippleScale, floor.mapColor);
floor.walkSound.at(x, y, 1f, floor.walkSoundVolume);
@@ -123,7 +140,7 @@ abstract class LegsComp implements Posc, Rotc, Hitboxc, Flyingc, Unitc{
}
if(type.legSplashDamage > 0){
Damage.damage(team(), l.base.x, l.base.y, type.legSplashRange, type.legSplashDamage, false, true);
Damage.damage(team, l.base.x, l.base.y, type.legSplashRange, type.legSplashDamage, false, true);
}
}
@@ -148,6 +165,11 @@ abstract class LegsComp implements Posc, Rotc, Hitboxc, Flyingc, Unitc{
l.joint.lerpDelta(jointDest, moveSpeed / 4f);
}
//when at least 1 leg is touching land, it can't drown
if(deeps != legs.length){
lastDeepFloor = null;
}
}
/** @return outwards facing angle of leg at the specified index. */