mirror of
https://github.com/Anuken/Mindustry.git
synced 2024-09-11 08:15:35 +03:00
Support for unit missiles
This commit is contained in:
parent
f5e9df1265
commit
0b7d8f371e
@ -26,6 +26,7 @@ mindustry.type.Weather.WeatherStateComp=14
|
||||
mindustry.world.blocks.campaign.LaunchPad.LaunchPayloadComp=15
|
||||
mindustry.world.blocks.campaign.PayloadLaunchPad.LargeLaunchPayloadComp=34
|
||||
mindustry.world.blocks.defense.ForceProjector.ForceDrawComp=22
|
||||
missile=39
|
||||
mono=16
|
||||
nova=17
|
||||
oct=26
|
||||
@ -36,5 +37,7 @@ quasar=32
|
||||
risso=20
|
||||
scuttler=35
|
||||
spiroct=21
|
||||
timed=38
|
||||
timedDef=37
|
||||
toxopid=33
|
||||
vela=25
|
1
annotations/src/main/resources/revisions/missile/0.json
Normal file
1
annotations/src/main/resources/revisions/missile/0.json
Normal file
@ -0,0 +1 @@
|
||||
{fields:[{name:ammo,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:lifetime,type:float},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>},{name:rotation,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>},{name:team,type:mindustry.game.Team},{name:time,type:float},{name:type,type:mindustry.type.UnitType},{name:updateBuilding,type:boolean},{name:vel,type:arc.math.geom.Vec2},{name:x,type:float},{name:y,type:float}]}
|
Binary file not shown.
Before Width: | Height: | Size: 947 B After Width: | Height: | Size: 1.1 KiB |
34
core/src/mindustry/ai/types/MissileAI.java
Normal file
34
core/src/mindustry/ai/types/MissileAI.java
Normal file
@ -0,0 +1,34 @@
|
||||
package mindustry.ai.types;
|
||||
|
||||
import mindustry.entities.units.*;
|
||||
|
||||
public class MissileAI extends AIController{
|
||||
|
||||
//TODO UNPREDICTABLE TARGETING
|
||||
@Override
|
||||
public void updateMovement(){
|
||||
unloadPayloads();
|
||||
|
||||
if(target != null){
|
||||
unit.lookAt(target);
|
||||
|
||||
var build = unit.buildOn();
|
||||
|
||||
//kill instantly on building contact
|
||||
//TODO kill on target unit contact too
|
||||
if(build != null && build == target){
|
||||
unit.kill();
|
||||
}
|
||||
}
|
||||
|
||||
//move forward forever
|
||||
unit.moveAt(vec.trns(unit.rotation, unit.speed()));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean retarget(){
|
||||
//more frequent retarget. TODO lag?
|
||||
return timer.get(timerTarget, 10f);
|
||||
}
|
||||
}
|
@ -72,6 +72,9 @@ public class UnitTypes{
|
||||
|
||||
//endregion
|
||||
|
||||
//missile definition, needed for codegen
|
||||
public static @EntityDef({Unitc.class, TimedKillc.class}) UnitType missile;
|
||||
|
||||
//region neoplasm
|
||||
|
||||
public static @EntityDef({Unitc.class, Crawlc.class}) UnitType scuttler;
|
||||
@ -598,7 +601,11 @@ public class UnitTypes{
|
||||
shootSound = Sounds.explosion;
|
||||
x = shootY = 0f;
|
||||
mirror = false;
|
||||
bullet = new BombBulletType(0f, 0f, "clear"){{
|
||||
bullet = new BulletType(){{
|
||||
collidesTiles = false;
|
||||
collides = false;
|
||||
hitSound = Sounds.explosion;
|
||||
|
||||
hitEffect = Fx.pulverize;
|
||||
lifetime = 10f;
|
||||
speed = 1f;
|
||||
@ -1461,7 +1468,6 @@ public class UnitTypes{
|
||||
health = 280;
|
||||
accel = 0.4f;
|
||||
rotateSpeed = 3.3f;
|
||||
trailLength = 20;
|
||||
rotateShooting = false;
|
||||
|
||||
armor = 2f;
|
||||
@ -2413,6 +2419,9 @@ public class UnitTypes{
|
||||
}});
|
||||
}};
|
||||
|
||||
//endregion
|
||||
//region erekir - core
|
||||
|
||||
//TODO bad name
|
||||
evoke = new UnitType("evoke"){{
|
||||
defaultController = BuilderAI::new;
|
||||
@ -2438,8 +2447,8 @@ public class UnitTypes{
|
||||
engineSize = 0;
|
||||
|
||||
setEnginesMirror(
|
||||
new UnitEngine(21 / 4f, 19 / 4f, 2.2f, 45f),
|
||||
new UnitEngine(23 / 4f, -22 / 4f, 2.2f, 315f)
|
||||
new UnitEngine(21 / 4f, 19 / 4f, 2.2f, 45f),
|
||||
new UnitEngine(23 / 4f, -22 / 4f, 2.2f, 315f)
|
||||
);
|
||||
|
||||
weapons.add(new Weapon(){{
|
||||
@ -2470,6 +2479,30 @@ public class UnitTypes{
|
||||
smokeEffect = Fx.shootBigSmoke;
|
||||
buildingDamageMultiplier = 0.4f;
|
||||
}};
|
||||
|
||||
//TODO REMOVE
|
||||
/*
|
||||
unitSpawned = new MissileUnitType("duo"){{
|
||||
trailScl = 1.1f;
|
||||
speed = 3f;
|
||||
weapons.add(new Weapon(){{
|
||||
shootOnDeath = true;
|
||||
bullet = new BulletType(){{
|
||||
collidesTiles = false;
|
||||
collides = false;
|
||||
hitSound = Sounds.explosion;
|
||||
|
||||
lifetime = 10f;
|
||||
speed = 1f;
|
||||
splashDamageRadius = 55f;
|
||||
instantDisappear = true;
|
||||
splashDamage = 90f;
|
||||
killShooter = true;
|
||||
hittable = false;
|
||||
collidesAir = true;
|
||||
}};
|
||||
}});
|
||||
}};*/
|
||||
}});
|
||||
}};
|
||||
|
||||
@ -2597,8 +2630,6 @@ public class UnitTypes{
|
||||
}});
|
||||
i ++;
|
||||
}
|
||||
|
||||
|
||||
}};
|
||||
|
||||
//endregion
|
||||
|
@ -69,7 +69,7 @@ abstract class CommanderComp implements Entityc, Posc{
|
||||
units.clear();
|
||||
|
||||
Units.nearby(team, x, y, type.commandRadius, u -> {
|
||||
if(u.isAI() && include.get(u) && u != self() && u.type.flying == type.flying && u.hitSize <= hitSize * 1.1f){
|
||||
if(u.isAI() && include.get(u) && u != self() && u.type.flying == type.flying && u.hitSize <= hitSize * 1.1f && u.type.playerControllable){
|
||||
units.add(u);
|
||||
}
|
||||
});
|
||||
|
@ -5,6 +5,7 @@ import arc.util.*;
|
||||
import mindustry.annotations.Annotations.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.core.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.world.*;
|
||||
import mindustry.world.blocks.environment.*;
|
||||
|
||||
@ -50,9 +51,9 @@ abstract class PosComp implements Position{
|
||||
return tile == null ? Blocks.air : tile.block();
|
||||
}
|
||||
|
||||
boolean onSolid(){
|
||||
Tile tile = tileOn();
|
||||
return tile == null || tile.solid();
|
||||
@Nullable
|
||||
Building buildOn(){
|
||||
return world.buildWorld(x, y);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@ -60,6 +61,11 @@ abstract class PosComp implements Position{
|
||||
return world.tileWorld(x, y);
|
||||
}
|
||||
|
||||
boolean onSolid(){
|
||||
Tile tile = tileOn();
|
||||
return tile == null || tile.solid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getX(){
|
||||
return x;
|
||||
|
28
core/src/mindustry/entities/comp/TimedKillComp.java
Normal file
28
core/src/mindustry/entities/comp/TimedKillComp.java
Normal file
@ -0,0 +1,28 @@
|
||||
package mindustry.entities.comp;
|
||||
|
||||
import arc.math.*;
|
||||
import arc.util.*;
|
||||
import mindustry.annotations.Annotations.*;
|
||||
import mindustry.gen.*;
|
||||
|
||||
//basically just TimedComp but kills instead of removing.
|
||||
@Component
|
||||
abstract class TimedKillComp implements Entityc, Healthc, Scaled{
|
||||
float time, lifetime;
|
||||
|
||||
//called last so pooling and removal happens then.
|
||||
@MethodPriority(100)
|
||||
@Override
|
||||
public void update(){
|
||||
time = Math.min(time + Time.delta, lifetime);
|
||||
|
||||
if(time >= lifetime){
|
||||
kill();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public float fin(){
|
||||
return time / lifetime;
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
package mindustry.entities.comp;
|
||||
|
||||
import arc.math.*;
|
||||
import mindustry.annotations.Annotations.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.graphics.*;
|
||||
import mindustry.type.*;
|
||||
|
||||
@Component
|
||||
abstract class TrailComp implements Unitc{
|
||||
@Import UnitType type;
|
||||
@Import float x, y, rotation;
|
||||
|
||||
transient Trail trail = new Trail(6);
|
||||
|
||||
@Override
|
||||
public void update(){
|
||||
trail.length = type.trailLength;
|
||||
|
||||
float scale = elevation();
|
||||
float offset = type.engineOffset/2f + type.engineOffset/2f*scale;
|
||||
|
||||
float cx = x + Angles.trnsx(rotation + 180, offset), cy = y + Angles.trnsy(rotation + 180, offset);
|
||||
trail.update(cx, cy);
|
||||
}
|
||||
}
|
@ -20,6 +20,7 @@ import mindustry.entities.units.*;
|
||||
import mindustry.game.EventType.*;
|
||||
import mindustry.game.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.graphics.*;
|
||||
import mindustry.logic.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.ui.*;
|
||||
@ -46,6 +47,8 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
||||
boolean spawnedByCore;
|
||||
double flag;
|
||||
|
||||
transient @Nullable Trail trail;
|
||||
|
||||
transient float shadowAlpha = -1f;
|
||||
transient Seq<Ability> abilities = new Seq<>(0);
|
||||
transient float healTime;
|
||||
@ -339,6 +342,11 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
||||
public void remove(){
|
||||
team.data().updateCount(type, -1);
|
||||
controller.removed(self());
|
||||
|
||||
//make sure trail doesn't just go poof
|
||||
if(trail != null && trail.size() > 0){
|
||||
Fx.trailFade.at(x, y, trail.width(), team.color, trail.copy());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -390,6 +398,16 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
||||
}
|
||||
}
|
||||
|
||||
if(trail != null){
|
||||
trail.length = type.trailLength;
|
||||
|
||||
float scale = elevation();
|
||||
float offset = type.engineOffset/2f + type.engineOffset/2f*scale;
|
||||
|
||||
float cx = x + Angles.trnsx(rotation + 180, offset), cy = y + Angles.trnsy(rotation + 180, offset);
|
||||
trail.update(cx, cy);
|
||||
}
|
||||
|
||||
drag = type.drag * (isGrounded() ? (floorOn().dragMultiplier) : 1f) * dragMultiplier * state.rules.dragMultiplier;
|
||||
|
||||
//apply knockback based on spawns
|
||||
|
@ -10,7 +10,7 @@ public class Trail{
|
||||
public int length;
|
||||
|
||||
private final FloatSeq points;
|
||||
private float lastX = -1, lastY = -1, lastAngle = -1, counter = 0f;
|
||||
private float lastX = -1, lastY = -1, lastAngle = -1, counter = 0f, lastW = 0f;
|
||||
|
||||
public Trail(int length){
|
||||
this.length = length;
|
||||
@ -26,6 +26,10 @@ public class Trail{
|
||||
return out;
|
||||
}
|
||||
|
||||
public float width(){
|
||||
return lastW;
|
||||
}
|
||||
|
||||
public void clear(){
|
||||
points.clear();
|
||||
}
|
||||
@ -49,23 +53,43 @@ public class Trail{
|
||||
public void draw(Color color, float width){
|
||||
Draw.color(color);
|
||||
float[] items = points.items;
|
||||
float lx = lastX, ly = lastY, lastAngle = this.lastAngle;
|
||||
float lastAngle = this.lastAngle;
|
||||
float size = width / (points.size / 3);
|
||||
|
||||
for(int i = 0; i < points.size - 3; i+= 3){
|
||||
float x1 = items[i], y1 = items[i + 1], w1 = items[i + 2],
|
||||
x2 = items[i + 3], y2 = items[i + 4], w2 = items[i + 5];
|
||||
float size = width / (points.size/3);
|
||||
float z1 = lastAngle;
|
||||
float z2 = -Angles.angleRad(x2, y2, lx, ly);
|
||||
for(int i = 0; i < points.size; i += 3){
|
||||
float x1 = items[i], y1 = items[i + 1], w1 = items[i + 2];
|
||||
float x2, y2, w2;
|
||||
|
||||
//last position is always lastX/Y/W
|
||||
if(i < points.size - 3){
|
||||
x2 = items[i + 3];
|
||||
y2 = items[i + 4];
|
||||
w2 = items[i + 5];
|
||||
}else{
|
||||
x2 = lastX;
|
||||
y2 = lastY;
|
||||
w2 = lastW;
|
||||
}
|
||||
|
||||
float z2 = -Angles.angleRad(x1, y1, x2, y2);
|
||||
//end of the trail (i = 0) has the same angle as the next.
|
||||
float z1 = i == 0 ? z2 : lastAngle;
|
||||
if(w1 <= 0.001f || w2 <= 0.001f) continue;
|
||||
|
||||
float cx = Mathf.sin(z1) * i/3f * size * w1, cy = Mathf.cos(z1) * i/3f * size * w1,
|
||||
nx = Mathf.sin(z2) * (i/3f + 1) * size * w2, ny = Mathf.cos(z2) * (i/3f + 1) * size * w2;
|
||||
Fill.quad(x1 - cx, y1 - cy, x1 + cx, y1 + cy, x2 + nx, y2 + ny, x2 - nx, y2 - ny);
|
||||
float
|
||||
cx = Mathf.sin(z1) * i/3f * size * w1,
|
||||
cy = Mathf.cos(z1) * i/3f * size * w1,
|
||||
nx = Mathf.sin(z2) * (i/3f + 1) * size * w2,
|
||||
ny = Mathf.cos(z2) * (i/3f + 1) * size * w2;
|
||||
|
||||
Fill.quad(
|
||||
x1 - cx, y1 - cy,
|
||||
x1 + cx, y1 + cy,
|
||||
x2 + nx, y2 + ny,
|
||||
x2 - nx, y2 - ny
|
||||
);
|
||||
|
||||
lastAngle = z2;
|
||||
lx = x2;
|
||||
ly = y2;
|
||||
}
|
||||
|
||||
Draw.reset();
|
||||
@ -89,19 +113,21 @@ public class Trail{
|
||||
|
||||
/** Adds a new point to the trail at intervals. */
|
||||
public void update(float x, float y, float width){
|
||||
if((counter += Time.delta) >= 0.99f){
|
||||
//TODO fix longer trails at low FPS
|
||||
if((counter += Time.delta) >= 1f){
|
||||
if(points.size > length*3){
|
||||
points.removeRange(0, 2);
|
||||
}
|
||||
|
||||
lastAngle = -Angles.angleRad(x, y, lastX, lastY);
|
||||
|
||||
points.add(x, y, width);
|
||||
|
||||
lastX = x;
|
||||
lastY = y;
|
||||
|
||||
counter = 0f;
|
||||
counter %= 1f;
|
||||
}
|
||||
|
||||
//update last position regardless, so it joins
|
||||
lastAngle = -Angles.angleRad(x, y, lastX, lastY);
|
||||
lastX = x;
|
||||
lastY = y;
|
||||
lastW = width;
|
||||
}
|
||||
}
|
||||
|
30
core/src/mindustry/type/MissileUnitType.java
Normal file
30
core/src/mindustry/type/MissileUnitType.java
Normal file
@ -0,0 +1,30 @@
|
||||
package mindustry.type;
|
||||
|
||||
import mindustry.ai.types.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.world.meta.*;
|
||||
|
||||
/** Field template for unit types. No new functionality. */
|
||||
public class MissileUnitType extends UnitType{
|
||||
|
||||
public MissileUnitType(String name){
|
||||
super(name);
|
||||
|
||||
playerControllable = false;
|
||||
createWreck = false;
|
||||
logicControllable = false;
|
||||
isCounted = false;
|
||||
useUnitCap = false;
|
||||
allowedInPayloads = false;
|
||||
defaultController = MissileAI::new;
|
||||
flying = true;
|
||||
constructor = TimedKillUnit::create;
|
||||
envEnabled = Env.any;
|
||||
envDisabled = Env.none;
|
||||
trailLength = 7;
|
||||
hidden = true;
|
||||
rotateSpeed = 2f;
|
||||
range = 30f;
|
||||
//TODO weapons, etc
|
||||
}
|
||||
}
|
@ -43,7 +43,7 @@ public class UnitType extends UnlockableContent{
|
||||
|
||||
/** If true, the unit is always at elevation 1. */
|
||||
public boolean flying;
|
||||
/** If `flying` and this is true, the unit can appear on the title screen */
|
||||
/** If `flying` and this is true, the unit can appear on the title screen. TODO remove with new menu*/
|
||||
public boolean onTitleScreen = true;
|
||||
/** Creates a new instance of this unit class. */
|
||||
public Prov<? extends Unit> constructor;
|
||||
@ -60,6 +60,7 @@ public class UnitType extends UnlockableContent{
|
||||
public float speed = 1.1f, boostMultiplier = 1f, rotateSpeed = 5f, baseRotateSpeed = 5f;
|
||||
public float drag = 0.3f, accel = 0.5f, landShake = 0f, rippleScale = 1f, riseSpeed = 0.08f, fallSpeed = 0.018f;
|
||||
public float health = 200f, range = -1, miningRange = 70f, armor = 0f, maxRange = -1f, buildRange = Vars.buildingRange;
|
||||
public float lifetime = 60f * 5f; //for missiles only
|
||||
public float crashDamageMultiplier = 1f;
|
||||
public boolean targetAir = true, targetGround = true;
|
||||
public boolean faceTarget = true, rotateShooting = true, isCounted = true, lowAltitude = false, circleTarget = false;
|
||||
@ -135,7 +136,7 @@ public class UnitType extends UnlockableContent{
|
||||
public float lightRadius = -1f, lightOpacity = 0.6f;
|
||||
public Color lightColor = Pal.powerLight;
|
||||
public boolean drawCell = true, drawItems = true, drawShields = true, drawBody = true;
|
||||
public int trailLength = 3;
|
||||
public int trailLength = 0;
|
||||
public float trailX = 4f, trailY = -3f, trailScl = 1f;
|
||||
/** Whether the unit can heal blocks. Initialized in init() */
|
||||
public boolean canHeal = false;
|
||||
@ -182,6 +183,9 @@ public class UnitType extends UnlockableContent{
|
||||
unit.ammo = ammoCapacity; //fill up on ammo upon creation
|
||||
unit.elevation = flying ? 1f : 0;
|
||||
unit.heal();
|
||||
if(unit instanceof TimedKillc u){
|
||||
u.lifetime(lifetime);
|
||||
}
|
||||
return unit;
|
||||
}
|
||||
|
||||
@ -811,9 +815,8 @@ public class UnitType extends UnlockableContent{
|
||||
float scale = unit.elevation;
|
||||
float offset = engineOffset/2f + engineOffset/2f*scale;
|
||||
|
||||
if(unit instanceof Trailc){
|
||||
Trail trail = ((Trailc)unit).trail();
|
||||
trail.draw(unit.team.color, (engineSize + Mathf.absin(Time.time, 2f, engineSize / 4f) * scale) * trailScl);
|
||||
if(trailLength > 0 && !naval){
|
||||
drawTrail(unit);
|
||||
}
|
||||
|
||||
Draw.color(engineColor == null ? unit.team.color : engineColor);
|
||||
@ -831,6 +834,14 @@ public class UnitType extends UnlockableContent{
|
||||
Draw.color();
|
||||
}
|
||||
|
||||
public void drawTrail(Unit unit){
|
||||
if(unit.trail == null){
|
||||
unit.trail = new Trail(trailLength);
|
||||
}
|
||||
Trail trail = unit.trail;
|
||||
trail.draw(unit.team.color, (engineSize + Mathf.absin(Time.time, 2f, engineSize / 4f) * unit.elevation) * trailScl);
|
||||
}
|
||||
|
||||
public void drawEngines(Unit unit){
|
||||
if(!unit.isFlying()) return;
|
||||
|
||||
|
@ -29,6 +29,8 @@ public class Weapon implements Cloneable{
|
||||
public String name;
|
||||
/** bullet shot */
|
||||
public BulletType bullet = Bullets.standardCopper;
|
||||
/** unit, to spawn at bullet, e.g. missile. TODO prevent bullet creation */
|
||||
public @Nullable UnitType unitSpawned;
|
||||
/** shell ejection effect */
|
||||
public Effect ejectEffect = Fx.none;
|
||||
/** whether to consume ammo when ammo is enabled in rules */
|
||||
@ -403,13 +405,24 @@ public class Weapon implements Cloneable{
|
||||
unit.apply(shootStatus, shootStatusDuration);
|
||||
}
|
||||
|
||||
protected Bullet bullet(Unit unit, float shootX, float shootY, float angle, float lifescl){
|
||||
protected @Nullable Bullet bullet(Unit unit, float shootX, float shootY, float angle, float lifescl){
|
||||
float xr = Mathf.range(xRand);
|
||||
float
|
||||
x = shootX + Angles.trnsx(angle, 0, xr),
|
||||
y = shootY + Angles.trnsy(angle, 0, xr);
|
||||
|
||||
return bullet.create(unit, unit.team,
|
||||
shootX + Angles.trnsx(angle, 0, xr),
|
||||
shootY + Angles.trnsy(angle, 0, xr),
|
||||
angle, (1f - velocityRnd) + Mathf.random(velocityRnd), lifescl);
|
||||
if(unitSpawned == null){
|
||||
return bullet.create(unit, unit.team, x, y, angle, (1f - velocityRnd) + Mathf.random(velocityRnd), lifescl);
|
||||
}else{
|
||||
Unit spawned = unitSpawned.create(unit.team);
|
||||
spawned.set(x, y);
|
||||
spawned.rotation = angle;
|
||||
//immediately spawn at top speed, since it was launched
|
||||
spawned.vel.trns(angle, unitSpawned.speed);
|
||||
spawned.add();
|
||||
//TODO assign AI target here?
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Weapon copy(){
|
||||
|
@ -1,4 +1,18 @@
|
||||
package mindustry.world.blocks.defense;
|
||||
|
||||
public class DirectionalForceProjector{
|
||||
public class DirectionalForceProjector extends ForceProjector{
|
||||
|
||||
public DirectionalForceProjector(String name){
|
||||
super(name);
|
||||
|
||||
consumeCoolant = false;
|
||||
}
|
||||
|
||||
public class DirectionalForceProjectorBuild extends ForceBuild{
|
||||
|
||||
@Override
|
||||
public void deflectBullets(){
|
||||
//TODO
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,13 +32,15 @@ public class ForceProjector extends Block{
|
||||
public float cooldownNormal = 1.75f;
|
||||
public float cooldownLiquid = 1.5f;
|
||||
public float cooldownBrokenBase = 0.35f;
|
||||
public float coolantConsumption = 0.1f;
|
||||
public boolean consumeCoolant = true;
|
||||
public Effect absorbEffect = Fx.absorb;
|
||||
public Effect shieldBreakEffect = Fx.shieldBreak;
|
||||
public @Load("@-top") TextureRegion topRegion;
|
||||
|
||||
static ForceBuild paramEntity;
|
||||
static Effect paramEffect;
|
||||
static final Cons<Bullet> shieldConsumer = trait -> {
|
||||
protected static ForceBuild paramEntity;
|
||||
protected static Effect paramEffect;
|
||||
protected static final Cons<Bullet> shieldConsumer = trait -> {
|
||||
if(trait.team != paramEntity.team && trait.type.absorbable && Intersector.isInsideHexagon(paramEntity.x, paramEntity.y, paramEntity.realRadius() * 2f, trait.x(), trait.y())){
|
||||
trait.absorb();
|
||||
paramEffect.at(trait);
|
||||
@ -55,10 +57,13 @@ public class ForceProjector extends Block{
|
||||
hasPower = true;
|
||||
hasLiquids = true;
|
||||
hasItems = true;
|
||||
envEnabled |= Env.space;
|
||||
ambientSound = Sounds.shield;
|
||||
ambientSoundVolume = 0.08f;
|
||||
consumes.add(new ConsumeCoolant(0.1f)).boost().update(false);
|
||||
envEnabled |= Env.space;
|
||||
|
||||
if(consumeCoolant){
|
||||
consumes.add(new ConsumeCoolant(coolantConsumption)).boost().update(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -80,12 +85,17 @@ public class ForceProjector extends Block{
|
||||
|
||||
@Override
|
||||
public void setStats(){
|
||||
stats.timePeriod = phaseUseTime;
|
||||
boolean consItems = consumes.has(ConsumeType.item);
|
||||
|
||||
if(consItems) stats.timePeriod = phaseUseTime;
|
||||
super.setStats();
|
||||
stats.add(Stat.shieldHealth, shieldHealth, StatUnit.none);
|
||||
stats.add(Stat.cooldownTime, (int) (shieldHealth / cooldownBrokenBase / 60f), StatUnit.seconds);
|
||||
stats.add(Stat.boostEffect, phaseRadiusBoost / tilesize, StatUnit.blocks);
|
||||
stats.add(Stat.boostEffect, phaseShieldBoost, StatUnit.shieldHealth);
|
||||
|
||||
if(consItems){
|
||||
stats.add(Stat.boostEffect, phaseRadiusBoost / tilesize, StatUnit.blocks);
|
||||
stats.add(Stat.boostEffect, phaseShieldBoost, StatUnit.shieldHealth);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -146,9 +156,9 @@ public class ForceProjector extends Block{
|
||||
|
||||
warmup = Mathf.lerpDelta(warmup, efficiency(), 0.1f);
|
||||
|
||||
if(buildup > 0){
|
||||
if(buildup > 0 && consumes.has(ConsumeType.liquid)){
|
||||
float scale = !broken ? cooldownNormal : cooldownBrokenBase;
|
||||
ConsumeLiquidFilter cons = consumes.get(ConsumeType.liquid);
|
||||
Consume cons = consumes.get(ConsumeType.liquid);
|
||||
if(cons.valid(this)){
|
||||
cons.update(this);
|
||||
scale *= (cooldownLiquid * (1f + (liquids.current().heatCapacity - 0.4f) * 0.9f));
|
||||
|
Loading…
Reference in New Issue
Block a user