Long-range 4x4 turret (wip) / Java 14 language upgrade
This commit is contained in:
@@ -175,6 +175,18 @@ public class Units{
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the closest target enemy. First, units are checked, then tile entities. */
|
||||
public static Teamc bestTarget(Team team, float x, float y, float range, Boolf<Unit> unitPred, Boolf<Building> tilePred, Sortf sort){
|
||||
if(team == Team.derelict) return null;
|
||||
|
||||
Unit unit = bestEnemy(team, x, y, range, unitPred, sort);
|
||||
if(unit != null){
|
||||
return unit;
|
||||
}else{
|
||||
return findEnemyTile(team, x, y, range, tilePred);
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the closest enemy of this team. Filter by predicate. */
|
||||
public static Unit closestEnemy(Team team, float x, float y, float range, Boolf<Unit> predicate){
|
||||
if(team == Team.derelict) return null;
|
||||
@@ -195,6 +207,26 @@ public class Units{
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Returns the closest enemy of this team using a custom comparison function. Filter by predicate. */
|
||||
public static Unit bestEnemy(Team team, float x, float y, float range, Boolf<Unit> predicate, Sortf sort){
|
||||
if(team == Team.derelict) return null;
|
||||
|
||||
result = null;
|
||||
cdist = 0f;
|
||||
|
||||
nearbyEnemies(team, x - range, y - range, range*2f, range*2f, e -> {
|
||||
if(e.dead() || !predicate.get(e)) return;
|
||||
|
||||
float dst2 = sort.cost(e, x, y);
|
||||
if(dst2 < range*range && (result == null || dst2 < cdist)){
|
||||
result = e;
|
||||
cdist = dst2;
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Returns the closest ally of this team. Filter by predicate. No range. */
|
||||
public static Unit closest(Team team, float x, float y, Boolf<Unit> predicate){
|
||||
result = null;
|
||||
@@ -297,4 +329,7 @@ public class Units{
|
||||
nearbyEnemies(team, rect.x, rect.y, rect.width, rect.height, cons);
|
||||
}
|
||||
|
||||
public interface Sortf{
|
||||
float cost(Unit unit, float x, float y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,6 +71,9 @@ public abstract class BulletType extends Content{
|
||||
public boolean hittable = true;
|
||||
/** Whether this bullet can be reflected. */
|
||||
public boolean reflectable = true;
|
||||
/** Whether to move the bullet back depending on delta to fix some delta-time realted issues.
|
||||
* Do not change unless you know what you're doing. */
|
||||
public boolean backMove = true;
|
||||
/** Bullet range override. */
|
||||
public float range = -1f;
|
||||
|
||||
@@ -212,7 +215,7 @@ public abstract class BulletType extends Content{
|
||||
}
|
||||
|
||||
if(instantDisappear){
|
||||
b.time(lifetime);
|
||||
b.time = lifetime;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,7 +277,11 @@ public abstract class BulletType extends Content{
|
||||
bullet.owner = owner;
|
||||
bullet.team = team;
|
||||
bullet.vel.trns(angle, speed * velocityScl);
|
||||
bullet.set(x - bullet.vel.x * Time.delta, y - bullet.vel.y * Time.delta);
|
||||
if(backMove){
|
||||
bullet.set(x - bullet.vel.x * Time.delta, y - bullet.vel.y * Time.delta);
|
||||
}else{
|
||||
bullet.set(x, y);
|
||||
}
|
||||
bullet.lifetime = lifetime * lifetimeScl;
|
||||
bullet.data = data;
|
||||
bullet.drag = drag;
|
||||
|
||||
70
core/src/mindustry/entities/bullet/PointBulletType.java
Normal file
70
core/src/mindustry/entities/bullet/PointBulletType.java
Normal file
@@ -0,0 +1,70 @@
|
||||
package mindustry.entities.bullet;
|
||||
|
||||
import arc.math.geom.*;
|
||||
import arc.util.*;
|
||||
import mindustry.*;
|
||||
import mindustry.entities.*;
|
||||
import mindustry.gen.*;
|
||||
|
||||
public class PointBulletType extends BulletType{
|
||||
private static float cdist = 0f;
|
||||
private static Unit result;
|
||||
|
||||
public float trailSpacing = 10f;
|
||||
|
||||
public PointBulletType(){
|
||||
scaleVelocity = true;
|
||||
lifetime = 100f;
|
||||
collides = false;
|
||||
keepVelocity = false;
|
||||
backMove = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Bullet b){
|
||||
super.init(b);
|
||||
|
||||
float px = b.x + b.lifetime * b.vel.x,
|
||||
py = b.y + b.lifetime * b.vel.y,
|
||||
rot = b.rotation();
|
||||
|
||||
Geometry.iterateLine(0f, b.x, b.y, px, py, trailSpacing, (x, y) -> {
|
||||
trailEffect.at(x, y, rot);
|
||||
});
|
||||
|
||||
b.time = b.lifetime;
|
||||
b.set(px, py);
|
||||
|
||||
//calculate hit entity
|
||||
|
||||
cdist = 0f;
|
||||
result = null;
|
||||
float range = 1f;
|
||||
|
||||
Units.nearbyEnemies(b.team, px - range, py - range, range*2f, range*2f, e -> {
|
||||
if(e.dead()) return;
|
||||
|
||||
e.hitbox(Tmp.r1);
|
||||
if(!Tmp.r1.contains(px, py)) return;
|
||||
|
||||
float dst = e.dst(px, py) - e.hitSize;
|
||||
if((result == null || dst < cdist)){
|
||||
result = e;
|
||||
cdist = dst;
|
||||
}
|
||||
});
|
||||
|
||||
if(result != null){
|
||||
b.collision(result, px, py);
|
||||
}else{
|
||||
Building build = Vars.world.buildWorld(px, py);
|
||||
if(build != null && build.team != b.team){
|
||||
build.collision(b);
|
||||
}
|
||||
}
|
||||
|
||||
b.remove();
|
||||
|
||||
b.vel.setZero();
|
||||
}
|
||||
}
|
||||
@@ -1213,31 +1213,35 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
|
||||
@Override
|
||||
public double sense(LAccess sensor){
|
||||
if(sensor == LAccess.x) return x;
|
||||
if(sensor == LAccess.y) return y;
|
||||
if(sensor == LAccess.team) return team.id;
|
||||
if(sensor == LAccess.health) return health;
|
||||
if(sensor == LAccess.maxHealth) return maxHealth();
|
||||
if(sensor == LAccess.efficiency) return efficiency();
|
||||
if(sensor == LAccess.rotation) return rotation;
|
||||
if(sensor == LAccess.totalItems && items != null) return items.total();
|
||||
if(sensor == LAccess.totalLiquids && liquids != null) return liquids.total();
|
||||
if(sensor == LAccess.totalPower && power != null && block.consumes.hasPower()) return power.status * (block.consumes.getPower().buffered ? block.consumes.getPower().capacity : 1f);
|
||||
if(sensor == LAccess.itemCapacity) return block.itemCapacity;
|
||||
if(sensor == LAccess.liquidCapacity) return block.liquidCapacity;
|
||||
if(sensor == LAccess.powerCapacity) return block.consumes.hasPower() ? block.consumes.getPower().capacity : 0f;
|
||||
if(sensor == LAccess.powerNetIn && power != null) return power.graph.getLastScaledPowerIn() * 60;
|
||||
if(sensor == LAccess.powerNetOut && power != null) return power.graph.getLastScaledPowerOut() * 60;
|
||||
if(sensor == LAccess.powerNetStored && power != null) return power.graph.getLastPowerStored();
|
||||
if(sensor == LAccess.powerNetCapacity && power != null) return power.graph.getLastCapacity();
|
||||
return 0;
|
||||
return switch(sensor){
|
||||
case x -> x;
|
||||
case y -> y;
|
||||
case team -> team.id;
|
||||
case health -> health;
|
||||
case maxHealth -> maxHealth();
|
||||
case efficiency -> efficiency();
|
||||
case rotation -> rotation;
|
||||
case totalItems -> items == null ? 0 : items.total();
|
||||
case totalLiquids -> liquids == null ? 0 : liquids.total();
|
||||
case totalPower -> power == null || !block.consumes.hasPower() ? 0 : power.status * (block.consumes.getPower().buffered ? block.consumes.getPower().capacity : 1f);
|
||||
case itemCapacity -> block.itemCapacity;
|
||||
case liquidCapacity -> block.liquidCapacity;
|
||||
case powerCapacity -> block.consumes.hasPower() ? block.consumes.getPower().capacity : 0f;
|
||||
case powerNetIn -> power == null ? 0 : power.graph.getLastScaledPowerIn() * 60;
|
||||
case powerNetOut -> power == null ? 0 : power.graph.getLastScaledPowerOut() * 60;
|
||||
case powerNetStored -> power == null ? 0 : power.graph.getLastPowerStored();
|
||||
case powerNetCapacity -> power == null ? 0 : power.graph.getLastCapacity();
|
||||
default -> 0;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object senseObject(LAccess sensor){
|
||||
if(sensor == LAccess.type) return block;
|
||||
return switch(sensor){
|
||||
case type -> block;
|
||||
default -> noSensed;
|
||||
};
|
||||
|
||||
return noSensed;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -75,24 +75,28 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
||||
|
||||
@Override
|
||||
public double sense(LAccess sensor){
|
||||
if(sensor == LAccess.totalItems) return stack().amount;
|
||||
if(sensor == LAccess.rotation) return rotation;
|
||||
if(sensor == LAccess.health) return health;
|
||||
if(sensor == LAccess.maxHealth) return maxHealth;
|
||||
if(sensor == LAccess.x) return x;
|
||||
if(sensor == LAccess.y) return y;
|
||||
if(sensor == LAccess.team) return team.id;
|
||||
if(sensor == LAccess.shooting) return isShooting() ? 1 : 0;
|
||||
if(sensor == LAccess.shootX) return aimX();
|
||||
if(sensor == LAccess.shootY) return aimY();
|
||||
return 0;
|
||||
return switch(sensor){
|
||||
case totalItems -> stack().amount;
|
||||
case rotation -> rotation;
|
||||
case health -> health;
|
||||
case maxHealth -> maxHealth;
|
||||
case x -> x;
|
||||
case y -> y;
|
||||
case team -> team.id;
|
||||
case shooting -> isShooting() ? 1 : 0;
|
||||
case shootX -> aimX();
|
||||
case shootY -> aimY();
|
||||
default -> 0;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object senseObject(LAccess sensor){
|
||||
if(sensor == LAccess.type) return type;
|
||||
return switch(sensor){
|
||||
case type -> type;
|
||||
default -> noSensed;
|
||||
};
|
||||
|
||||
return noSensed;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user