New insectoid almost done + DestroyBlockObjective
BIN
core/assets-raw/sprites/units/anthicus-blade-heat.png
Normal file
|
After Width: | Height: | Size: 734 B |
BIN
core/assets-raw/sprites/units/anthicus-blade.png
Normal file
|
After Width: | Height: | Size: 194 B |
BIN
core/assets-raw/sprites/units/anthicus-leg-base.png
Normal file
|
After Width: | Height: | Size: 519 B |
BIN
core/assets-raw/sprites/units/anthicus-leg.png
Normal file
|
After Width: | Height: | Size: 557 B |
BIN
core/assets-raw/sprites/units/anthicus-weapon-blade-heat.png
Normal file
|
After Width: | Height: | Size: 624 B |
BIN
core/assets-raw/sprites/units/anthicus-weapon-blade.png
Normal file
|
After Width: | Height: | Size: 505 B |
BIN
core/assets-raw/sprites/units/anthicus-weapon-heat.png
Normal file
|
After Width: | Height: | Size: 741 B |
BIN
core/assets-raw/sprites/units/anthicus-weapon.png
Normal file
|
After Width: | Height: | Size: 369 B |
BIN
core/assets-raw/sprites/units/weapons/anthicus-missile-cell.png
Normal file
|
After Width: | Height: | Size: 183 B |
BIN
core/assets-raw/sprites/units/weapons/anthicus-missile.png
Normal file
|
After Width: | Height: | Size: 443 B |
|
|
@ -574,6 +574,7 @@ uncover = Uncover
|
|||
configure = Configure Loadout
|
||||
|
||||
objective.research = [accent]Research:\n[]{0}[lightgray]{1}
|
||||
objective.destroyblock = [accent]Destroy Structure:\n[]{0}[lightgray]{1}
|
||||
objective.item = [accent]Obtain: [][lightgray]{0}[]/{1}\n{2}[lightgray]{3}
|
||||
objective.coreitem = [accent]Move into Core:\n[][lightgray]{0}[]/{1}\n{2}[lightgray]{3}
|
||||
objective.build = [accent]Build: [][lightgray]{0}[]x\n{1}[lightgray]{2}
|
||||
|
|
|
|||
|
|
@ -548,3 +548,4 @@
|
|||
63144=canvas|block-canvas-ui
|
||||
63143=armored-duct|block-armored-duct-ui
|
||||
63142=anthicus|unit-anthicus-ui
|
||||
63141=anthicus-missile|unit-anthicus-missile-ui
|
||||
|
|
|
|||
|
|
@ -31,6 +31,6 @@ public class MissileAI extends AIController{
|
|||
@Override
|
||||
public boolean retarget(){
|
||||
//more frequent retarget due to high speed. TODO won't this lag?
|
||||
return timer.get(timerTarget, 10f);
|
||||
return timer.get(timerTarget, 4f);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import arc.graphics.g2d.*;
|
|||
import arc.math.*;
|
||||
import arc.math.geom.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import mindustry.ai.types.*;
|
||||
import mindustry.annotations.Annotations.*;
|
||||
import mindustry.entities.*;
|
||||
|
|
@ -2933,6 +2934,7 @@ public class UnitTypes{
|
|||
|
||||
legCount = 6;
|
||||
legLength = 18f;
|
||||
legGroupSize = 3;
|
||||
lockLegBase = true;
|
||||
legContinuousMove = true;
|
||||
legExtension = -3f;
|
||||
|
|
@ -2940,13 +2942,134 @@ public class UnitTypes{
|
|||
maxStretch = 1.1f;
|
||||
maxCompress = 0.2f;
|
||||
legLengthScl = 0.95f;
|
||||
legTrns = 0.7f;
|
||||
legTrns = 0.9f;
|
||||
|
||||
legMoveSpace = 1f;
|
||||
hovering = true;
|
||||
|
||||
visualElevation = 0.2f;
|
||||
groundLayer = Layer.legUnit - 1f;
|
||||
|
||||
for(int j = 0; j < 3; j++){
|
||||
int i = j;
|
||||
parts.add(new RegionPart("-blade"){{
|
||||
layerOffset = -0.01f;
|
||||
heatLayerOffset = 0.005f;
|
||||
x = 2f;
|
||||
moveX = 6f + i * 1.9f;
|
||||
moveY = 8f + -4f * i;
|
||||
moveRot = 40f - i * 25f;
|
||||
mirror = true;
|
||||
progress = PartProgress.warmup.delay(i * 0.2f);
|
||||
heatProgress = p -> Mathf.absin(Time.time + i * 14f, 7f, 1f);
|
||||
|
||||
heatColor = Pal.techBlue;
|
||||
}});
|
||||
}
|
||||
|
||||
weapons.add(new Weapon("anthicus-weapon"){{
|
||||
x = 29f / 4f;
|
||||
y = -11f / 4f;
|
||||
shootY = 1.5f;
|
||||
reload = 130f;
|
||||
layerOffset = 0.01f;
|
||||
heatColor = Color.red;
|
||||
cooldownTime = 60f;
|
||||
smoothReloadSpeed = 0.15f;
|
||||
shootWarmupSpeed = 0.05f;
|
||||
minWarmup = 0.9f;
|
||||
shootStatus = StatusEffects.slow;
|
||||
shootStatusDuration = reload + 1f;
|
||||
|
||||
rotateSpeed = 5f;
|
||||
inaccuracy = 20f;
|
||||
|
||||
rotate = true;
|
||||
|
||||
shoot = new ShootPattern(){{
|
||||
shots = 2;
|
||||
shotDelay = 6f;
|
||||
}};
|
||||
|
||||
parts.add(new RegionPart("-blade"){{
|
||||
mirror = true;
|
||||
moveRot = -25f;
|
||||
under = true;
|
||||
moves.add(new PartMove(PartProgress.reload, 1f, 0f, 0f));
|
||||
|
||||
heatColor = Color.red;
|
||||
cooldownTime = 60f;
|
||||
}});
|
||||
|
||||
parts.add(new RegionPart("-blade"){{
|
||||
mirror = true;
|
||||
moveRot = -50f;
|
||||
moveY = -2f;
|
||||
moves.add(new PartMove(PartProgress.reload.shorten(0.5f), 1f, 0f, -15f));
|
||||
under = true;
|
||||
|
||||
heatColor = Color.red;
|
||||
cooldownTime = 60f;
|
||||
}});
|
||||
|
||||
bullet = new BulletType(){{
|
||||
shootEffect = new MultiEffect(Fx.shootBigColor, new Effect(9, e -> {
|
||||
color(Color.white, e.color, e.fin());
|
||||
stroke(0.7f + e.fout());
|
||||
Lines.square(e.x, e.y, e.fin() * 5f, e.rotation + 45f);
|
||||
|
||||
Drawf.light(e.x, e.y, 23f, e.color, e.fout() * 0.7f);
|
||||
}), new WaveEffect(){{
|
||||
colorFrom = colorTo = Pal.techBlue;
|
||||
sizeTo = 15f;
|
||||
lifetime = 12f;
|
||||
strokeFrom = 3f;
|
||||
}});
|
||||
|
||||
smokeEffect = Fx.shootBigSmoke2;
|
||||
shake = 2f;
|
||||
speed = 0f;
|
||||
keepVelocity = false;
|
||||
inaccuracy = 2f;
|
||||
|
||||
spawnUnit = new MissileUnitType("anthicus-missile"){{
|
||||
trailColor = engineColor = Pal.techBlue;
|
||||
engineSize = 1.75f;
|
||||
engineLayer = Layer.effect;
|
||||
speed = 3.7f;
|
||||
maxRange = 6f;
|
||||
lifetime = 60f * 1.63f;
|
||||
outlineColor = Pal.darkOutline;
|
||||
health = 40;
|
||||
lowAltitude = true;
|
||||
|
||||
parts.add(new FlarePart(){{
|
||||
progress = PartProgress.life.slope().curve(Interp.pow2In);
|
||||
radius = 0f;
|
||||
radiusTo = 35f;
|
||||
stroke = 3f;
|
||||
rotation = 45f;
|
||||
y = -5f;
|
||||
followRotation = true;
|
||||
}});
|
||||
|
||||
weapons.add(new Weapon(){{
|
||||
shootCone = 360f;
|
||||
mirror = false;
|
||||
reload = 1f;
|
||||
shootOnDeath = true;
|
||||
bullet = new ExplosionBulletType(100f, 22f){{
|
||||
shootEffect = new MultiEffect(Fx.massiveExplosion, new WaveEffect(){{
|
||||
colorFrom = colorTo = Pal.techBlue;
|
||||
sizeTo = 40f;
|
||||
lifetime = 12f;
|
||||
strokeFrom = 4f;
|
||||
}});
|
||||
}};
|
||||
}});
|
||||
}};
|
||||
}};
|
||||
}});
|
||||
}};
|
||||
|
||||
bulwark = new ErekirUnitType("bulwark"){{
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import static mindustry.Vars.*;
|
|||
abstract class LegsComp implements Posc, Rotc, Hitboxc, Flyingc, Unitc{
|
||||
private static final Vec2 straightVec = new Vec2();
|
||||
|
||||
@Import float x, y, rotation;
|
||||
@Import float x, y, rotation, speedMultiplier;
|
||||
@Import UnitType type;
|
||||
@Import Team team;
|
||||
|
||||
|
|
@ -128,7 +128,7 @@ abstract class LegsComp implements Posc, Rotc, Hitboxc, Flyingc, Unitc{
|
|||
int div = Math.max(legs.length / type.legGroupSize, 2);
|
||||
moveSpace = legLength / 1.6f / (div / 2f) * type.legMoveSpace;
|
||||
//TODO should move legs even when still, based on speed. also, to prevent "slipping", make sure legs move when they are too far from their destination
|
||||
totalLength += type.legContinuousMove ? type.speed : Mathf.dst(deltaX(), deltaY());
|
||||
totalLength += type.legContinuousMove ? type.speed * speedMultiplier : Mathf.dst(deltaX(), deltaY());
|
||||
|
||||
float trns = moveSpace * 0.85f * type.legTrns;
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ public abstract class DrawPart{
|
|||
public boolean turretShading;
|
||||
/** If true, the layer is overridden to be under the weapon/turret itself. */
|
||||
public boolean under = false;
|
||||
/** For units, this is the index of the weapon this part gets its progress for. */
|
||||
public int weaponIndex = 0;
|
||||
|
||||
public abstract void draw(PartParams params);
|
||||
public abstract void load(String name);
|
||||
|
|
@ -81,6 +83,11 @@ public abstract class DrawPart{
|
|||
return p -> 1f - get(p);
|
||||
}
|
||||
|
||||
default PartProgress slope(){
|
||||
return p -> Mathf.slope(get(p));
|
||||
}
|
||||
|
||||
|
||||
default PartProgress clamp(){
|
||||
return p -> Mathf.clamp(get(p));
|
||||
}
|
||||
|
|
|
|||
53
core/src/mindustry/entities/part/FlarePart.java
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
package mindustry.entities.part;
|
||||
|
||||
import arc.graphics.*;
|
||||
import arc.graphics.g2d.*;
|
||||
import arc.math.*;
|
||||
import arc.util.*;
|
||||
import mindustry.graphics.*;
|
||||
|
||||
public class FlarePart extends DrawPart{
|
||||
public int sides = 4;
|
||||
public float radius = 100f, radiusTo = -1f, stroke = 6f, innerScl = 0.5f, innerRadScl = 0.33f;
|
||||
public float x, y, rotation, rotMove;
|
||||
public boolean followRotation;
|
||||
public Color color1 = Pal.techBlue, color2 = Color.white;
|
||||
public PartProgress progress = PartProgress.warmup;
|
||||
public float layer = Layer.effect;
|
||||
|
||||
@Override
|
||||
public void draw(PartParams params){
|
||||
float z = Draw.z();
|
||||
if(layer > 0) Draw.z(layer);
|
||||
|
||||
float prog = progress.getClamp(params);
|
||||
int i = params.sideOverride == -1 ? 0 : params.sideOverride;
|
||||
|
||||
float sign = (i == 0 ? 1 : -1) * params.sideMultiplier;
|
||||
Tmp.v1.set(x * sign, y).rotate(params.rotation - 90);
|
||||
|
||||
float
|
||||
rx = params.x + Tmp.v1.x,
|
||||
ry = params.y + Tmp.v1.y,
|
||||
rot = (followRotation ? params.rotation : 0f) + rotMove * prog + rotation,
|
||||
rad = radiusTo < 0 ? radius : Mathf.lerp(radius, radiusTo, prog);
|
||||
|
||||
Draw.color(color1);
|
||||
for(int j = 0; j < sides; j++){
|
||||
Drawf.tri(rx, ry, stroke, rad, j * 360f / sides + rot);
|
||||
}
|
||||
|
||||
Draw.color(color2);
|
||||
for(int j = 0; j < sides; j++){
|
||||
Drawf.tri(rx, ry, stroke * innerScl, rad * innerRadScl, j * 360f / sides + rot);
|
||||
}
|
||||
|
||||
Draw.color();
|
||||
Draw.z(z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(String name){
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -29,7 +29,7 @@ public class RegionPart extends DrawPart{
|
|||
/** Progress function for heat alpha. */
|
||||
public PartProgress heatProgress = PartProgress.heat;
|
||||
public Blending blending = Blending.normal;
|
||||
public float layer = -1, layerOffset = 0f;
|
||||
public float layer = -1, layerOffset = 0f, heatLayerOffset = 1f;
|
||||
public float outlineLayerOffset = -0.001f;
|
||||
public float x, y, rotation;
|
||||
public float moveX, moveY, moveRot;
|
||||
|
|
@ -62,7 +62,7 @@ public class RegionPart extends DrawPart{
|
|||
|
||||
float prevZ = Draw.z();
|
||||
float prog = progress.getClamp(params);
|
||||
float mx = moveX * prog, my = moveY * prog, mr = moveRot * prog;
|
||||
float mx = moveX * prog, my = moveY * prog, mr = moveRot * prog + rotation;
|
||||
|
||||
if(moves.size > 0){
|
||||
for(int i = 0; i < moves.size; i++){
|
||||
|
|
@ -111,7 +111,7 @@ public class RegionPart extends DrawPart{
|
|||
}
|
||||
|
||||
if(heat.found()){
|
||||
Drawf.additive(heat, heatColor.write(Tmp.c1).a(heatProgress.getClamp(params) * heatColor.a), rx, ry, rot, turretShading ? Layer.turretHeat : z + 1f);
|
||||
Drawf.additive(heat, heatColor.write(Tmp.c1).a(heatProgress.getClamp(params) * heatColor.a), rx, ry, rot, turretShading ? Layer.turretHeat : Draw.z() + heatLayerOffset);
|
||||
}
|
||||
|
||||
Draw.xscl = 1f;
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ public class ShapePart extends DrawPart{
|
|||
}
|
||||
|
||||
if(!circle){
|
||||
Fill.poly(rx, ry, sides, rad, moveRot * prog * sign + params.rotation - 90);
|
||||
Fill.poly(rx, ry, sides, rad, moveRot * prog * sign + params.rotation - 90 * sign + rotation * sign);
|
||||
}else{
|
||||
Fill.circle(rx, ry, rad);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ public class MapObjectives{
|
|||
public static Prov<MapObjective>[] allObjectiveTypes = new Prov[]{
|
||||
ResearchObjective::new, BuildCountObjective::new, UnitCountObjective::new, ItemObjective::new,
|
||||
CommandModeObjective::new, CoreItemObjective::new, DestroyCoreObjective::new, DestroyUnitsObjective::new,
|
||||
TimerObjective::new, FlagObjective::new
|
||||
TimerObjective::new, FlagObjective::new, DestroyBlockObjective::new
|
||||
};
|
||||
|
||||
public static Prov<ObjectiveMarker>[] allMarkerTypes = new Prov[]{
|
||||
|
|
@ -208,6 +208,34 @@ public class MapObjectives{
|
|||
}
|
||||
}
|
||||
|
||||
public static class DestroyBlockObjective extends MapObjective{
|
||||
public int x, y;
|
||||
public Team team = Team.malis;
|
||||
public Block block = Blocks.router;
|
||||
|
||||
public DestroyBlockObjective(Block block, int x, int y, Team team){
|
||||
this.block = block;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.team = team;
|
||||
}
|
||||
|
||||
public DestroyBlockObjective(){
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean complete(){
|
||||
var build = world.build(x, y);
|
||||
return build == null || build.team != team || build.block != block;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String text(){
|
||||
return Core.bundle.format("objective.destroyblock", block.emoji(), block.localizedName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Command any unit to do anything. Always compete in headless mode. */
|
||||
public static class CommandModeObjective extends MapObjective{
|
||||
|
||||
|
|
|
|||
|
|
@ -881,18 +881,20 @@ public class UnitType extends UnlockableContent{
|
|||
|
||||
//TODO how/where do I draw under?
|
||||
if(parts.size > 0){
|
||||
//TODO does it need an outline?
|
||||
WeaponMount first = unit.mounts.length > 0 ? unit.mounts[0] : null;
|
||||
if(unit.mounts.length > 0){
|
||||
DrawPart.params.set(first.warmup, first.reload / weapons.first().reload, first.smoothReload, first.heat, unit.x, unit.y, unit.rotation);
|
||||
}else{
|
||||
DrawPart.params.set(0f, 0f, 0f, 0f, unit.x, unit.y, unit.rotation);
|
||||
}
|
||||
if(unit instanceof Scaled s){
|
||||
DrawPart.params.life = s.fin();
|
||||
}
|
||||
for(int i = 0; i < parts.size; i++){
|
||||
var part = parts.items[i];
|
||||
|
||||
WeaponMount first = unit.mounts.length > part.weaponIndex ? unit.mounts[part.weaponIndex] : null;
|
||||
if(first != null){
|
||||
DrawPart.params.set(first.warmup, first.reload / weapons.first().reload, first.smoothReload, first.heat, unit.x, unit.y, unit.rotation);
|
||||
}else{
|
||||
DrawPart.params.set(0f, 0f, 0f, 0f, unit.x, unit.y, unit.rotation);
|
||||
}
|
||||
|
||||
if(unit instanceof Scaled s){
|
||||
DrawPart.params.life = s.fin();
|
||||
}
|
||||
|
||||
part.draw(DrawPart.params);
|
||||
}
|
||||
}
|
||||
|
|
|
|||