A significant waste of time and effort

This commit is contained in:
Anuken
2021-11-23 22:41:25 -05:00
parent 4d49b0b2ee
commit ba14151a01
21 changed files with 413 additions and 72 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 356 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 794 B

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -457,3 +457,4 @@
63249=slag-heater|block-slag-heater-ui 63249=slag-heater|block-slag-heater-ui
63248=slag-incinerator|block-slag-incinerator-ui 63248=slag-incinerator|block-slag-incinerator-ui
63247=phase-synthesizer|block-phase-synthesizer-ui 63247=phase-synthesizer|block-phase-synthesizer-ui
63246=sublimate|block-sublimate-ui

Binary file not shown.

View File

@@ -99,7 +99,7 @@ public class Blocks implements ContentList{
//storage //storage
coreShard, coreFoundation, coreNucleus, vault, container, unloader, coreShard, coreFoundation, coreNucleus, vault, container, unloader,
//storage - erekir //storage - erekir
coreBastion, coreCitadel, coreAcropolis, coreBastion, coreCitadel, coreAcropolis, reinforcedContainer, reinforcedVault,
//turrets //turrets
duo, scatter, scorch, hail, arc, wave, lancer, swarmer, salvo, fuse, ripple, cyclone, foreshadow, spectre, meltdown, segment, parallax, tsunami, duo, scatter, scorch, hail, arc, wave, lancer, swarmer, salvo, fuse, ripple, cyclone, foreshadow, spectre, meltdown, segment, parallax, tsunami,
@@ -1143,14 +1143,13 @@ public class Blocks implements ContentList{
size = 3; size = 3;
liquidCapacity = 40f;
outputLiquid = new LiquidStack(Liquids.cyanogen, 3f); outputLiquid = new LiquidStack(Liquids.cyanogen, 3f);
craftTime = 60f * 1f; craftTime = 60f * 1f;
consumes.liquid(Liquids.hydrogen, 3f / 60f); consumes.liquid(Liquids.hydrogen, 3f / 60f);
consumes.item(Items.graphite); consumes.item(Items.graphite);
consumes.power(2f); consumes.power(2f);
liquidCapacity = 40f;
}}; }};
//TODO bad name //TODO bad name
@@ -1181,7 +1180,7 @@ public class Blocks implements ContentList{
}}, new DrawBlock(), new DrawHeatInput(), new DrawHeatRegion("-vents"){{ }}, new DrawBlock(), new DrawHeatInput(), new DrawHeatRegion("-vents"){{
heatColor = new Color(1f, 0.4f, 0.3f, 1f); heatColor = new Color(1f, 0.4f, 0.3f, 1f);
}}); }});
iconOverride = new String[]{"-bottom", ""}; iconOverride = new String[]{"-bottom", "-weave", ""};
consumes.items(with(Items.thorium, 2, Items.sand, 6)); consumes.items(with(Items.thorium, 2, Items.sand, 6));
consumes.liquid(Liquids.ozone, 2f / 60f); consumes.liquid(Liquids.ozone, 2f / 60f);
@@ -2126,13 +2125,6 @@ public class Blocks implements ContentList{
researchCostMultiplier = 0.11f; researchCostMultiplier = 0.11f;
}}; }};
vault = new StorageBlock("vault"){{
requirements(Category.effect, with(Items.titanium, 250, Items.thorium, 125));
size = 3;
itemCapacity = 1000;
health = size * size * 55;
}};
container = new StorageBlock("container"){{ container = new StorageBlock("container"){{
requirements(Category.effect, with(Items.titanium, 100)); requirements(Category.effect, with(Items.titanium, 100));
size = 2; size = 2;
@@ -2140,12 +2132,27 @@ public class Blocks implements ContentList{
health = size * size * 55; health = size * size * 55;
}}; }};
vault = new StorageBlock("vault"){{
requirements(Category.effect, with(Items.titanium, 250, Items.thorium, 125));
size = 3;
itemCapacity = 1000;
health = size * size * 55;
}};
//TODO move tabs?
unloader = new Unloader("unloader"){{ unloader = new Unloader("unloader"){{
requirements(Category.effect, with(Items.titanium, 25, Items.silicon, 30)); requirements(Category.effect, with(Items.titanium, 25, Items.silicon, 30));
speed = 60f / 11f; speed = 60f / 11f;
group = BlockGroup.transportation; group = BlockGroup.transportation;
}}; }};
reinforcedContainer = new StorageBlock("reinforced-container"){{
requirements(Category.effect, with(Items.titanium, 250, Items.thorium, 125));
size = 3;
itemCapacity = 1000;
health = size * size * 120;
}};
//endregion //endregion
//region turrets //region turrets
@@ -2681,10 +2688,31 @@ public class Blocks implements ContentList{
}}; }};
//TODO bad name //TODO bad name
if(false)
sublimate = new ContinuousTurret("sublimate"){{ sublimate = new ContinuousTurret("sublimate"){{
//TODO requirements //TODO requirements
requirements(Category.turret, with(Items.tungsten, 35, Items.silicon, 35), true); requirements(Category.turret, with(Items.tungsten, 35, Items.silicon, 35), true);
draw = new DrawTurret("reinforced-"){{
parts.addAll(new RegionPart("-back"){{
outline = true;
rotMove = 30f;
offsetX = 29 / 4f;
offsetY = -10f / 4f;
originX = -8f / 4f;
originY = 8f / 4f;
}});
}};
outlineColor = Pal.darkOutline;
consumes.liquids(LiquidStack.with(Liquids.cyanogen, 3f / 60f, Liquids.ozone, 2f / 60f));
range = 170f;
shootType = new ContinuousFlameBulletType(){{
length = range;
}};
shootLength = 9f;
size = 3;
}}; }};
//endregion //endregion

View File

@@ -0,0 +1,63 @@
package mindustry.entities.bullet;
import mindustry.content.*;
import mindustry.entities.*;
import mindustry.gen.*;
/** Basic continuous bullet type that does not draw itself. Essentially abstract. */
public class ContinuousBulletType extends BulletType{
public float length = 220f;
public float shake = 0f;
public float damageInterval = 5f;
public boolean largeHit = false;
{
speed = 0f;
despawnEffect = Fx.none;
lifetime = 16f;
impact = true;
keepVelocity = false;
collides = false;
pierce = true;
hittable = false;
absorbable = false;
}
@Override
public float continuousDamage(){
return damage / damageInterval * 60f;
}
@Override
public float estimateDPS(){
//assume firing duration is about 100 by default, may not be accurate there's no way of knowing in this method
//assume it pierces 3 blocks/units
return damage * 100f / damageInterval * 3f;
}
@Override
public float range(){
return Math.max(length, maxRange);
}
@Override
public void init(){
super.init();
drawSize = Math.max(drawSize, length*2f);
}
@Override
public void update(Bullet b){
//damage every 5 ticks
if(b.timer(1, damageInterval)){
Damage.collideLine(b, b.team, hitEffect, b.x, b.y, b.rotation(), length, largeHit);
}
if(shake > 0){
Effect.shake(shake, shake, b);
}
}
}

View File

@@ -0,0 +1,74 @@
package mindustry.entities.bullet;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.util.*;
import mindustry.content.*;
import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.graphics.*;
//TODO implement
public class ContinuousFlameBulletType extends ContinuousBulletType{
public float fadeTime = 16f;
public float lightStroke = 40f;
public float width = 3.7f, oscScl = 1.2f, oscMag = 0.02f;
public int divisions = 25;
/** Lengths, widths, ellipse panning, and offsets, all as fractions of the base width and length. Stored as an 'interleaved' array of values: LWPO1 LWPO2 LWPO3... */
public float[] lengthWidthPanOffsets = {
1.12f, 1.3f, 0.32f, 0f,
1f, 1f, 0.3f, 0f,
0.8f, 0.9f, 0.2f, 0.01f,
0.5f, 0.8f, 0.15f, 0.02f,
0.25f, 0.7f, 0.1f, 0.03f
};
public Color[] colors = {Color.valueOf("eb7abe").a(0.55f), Color.valueOf("e189f5").a(0.7f), Color.valueOf("907ef7").a(0.8f), Color.valueOf("91a4ff"), Color.white};
public ContinuousFlameBulletType(float damage){
this.damage = damage;
}
public ContinuousFlameBulletType(){
}
{
length = 120f;
hitEffect = Fx.hitBeam;
hitSize = 4;
drawSize = 420f;
lifetime = 16f;
hitColor = colors[3];
lightColor = colors[3];
}
@Override
public void draw(Bullet b){
float realLength = Damage.findLaserLength(b, length);
float fout = Mathf.clamp(b.time > b.lifetime - fadeTime ? 1f - (b.time - (lifetime - fadeTime)) / fadeTime : 1f);
float baseLen = realLength * fout;
float sin = Mathf.sin(Time.time, oscScl, oscMag);
for(int i = 0; i < colors.length; i++){
Draw.color(colors[i].write(Tmp.c1).mul(0.9f).mul(1f + Mathf.absin(Time.time, 1f, 0.1f)));
Drawf.flame(b.x, b.y, divisions, b.rotation(),
baseLen * lengthWidthPanOffsets[i * 4] * (1f - sin),
width * lengthWidthPanOffsets[i * 4 + 1] * fout * (1f + sin),
lengthWidthPanOffsets[i * 4 + 2],
baseLen * lengthWidthPanOffsets[i * 4 + 3]
);
}
Drawf.light(b.team, b.x, b.y, b.x + Tmp.v1.x, b.y + Tmp.v1.y, lightStroke, lightColor, 0.7f);
Draw.reset();
}
@Override
public void drawLight(Bullet b){
//no light drawn here
}
}

View File

@@ -9,9 +9,7 @@ import mindustry.entities.*;
import mindustry.gen.*; import mindustry.gen.*;
import mindustry.graphics.*; import mindustry.graphics.*;
public class ContinuousLaserBulletType extends BulletType{ public class ContinuousLaserBulletType extends ContinuousBulletType{
public float length = 220f;
public float shake = 1f;
public float fadeTime = 16f; public float fadeTime = 16f;
public float lightStroke = 40f; public float lightStroke = 40f;
public float spaceMag = 35f; public float spaceMag = 35f;
@@ -20,14 +18,18 @@ public class ContinuousLaserBulletType extends BulletType{
public float[] strokes = {2f, 1.5f, 1f, 0.3f}; public float[] strokes = {2f, 1.5f, 1f, 0.3f};
public float[] lenscales = {1f, 1.12f, 1.15f, 1.17f}; public float[] lenscales = {1f, 1.12f, 1.15f, 1.17f};
public float width = 9f, oscScl = 0.8f, oscMag = 1.5f; public float width = 9f, oscScl = 0.8f, oscMag = 1.5f;
public boolean largeHit = true;
public ContinuousLaserBulletType(float damage){ public ContinuousLaserBulletType(float damage){
this.damage = damage; this.damage = damage;
this.speed = 0f; }
public ContinuousLaserBulletType(){
}
{
shake = 1f;
largeHit = true;
hitEffect = Fx.hitBeam; hitEffect = Fx.hitBeam;
despawnEffect = Fx.none;
hitSize = 4; hitSize = 4;
drawSize = 420f; drawSize = 420f;
lifetime = 16f; lifetime = 16f;
@@ -36,53 +38,6 @@ public class ContinuousLaserBulletType extends BulletType{
incendSpread = 5; incendSpread = 5;
incendChance = 0.4f; incendChance = 0.4f;
lightColor = Color.orange; lightColor = Color.orange;
impact = true;
keepVelocity = false;
collides = false;
pierce = true;
hittable = false;
absorbable = false;
}
protected ContinuousLaserBulletType(){
this(0);
}
@Override
public float continuousDamage(){
return damage / 5f * 60f;
}
@Override
public float estimateDPS(){
//assume firing duration is about 100 by default, may not be accurate there's no way of knowing in this method
//assume it pierces 3 blocks/units
return damage * 100f / 5f * 3f;
}
@Override
public float range(){
return Math.max(length, maxRange);
}
@Override
public void init(){
super.init();
drawSize = Math.max(drawSize, length*2f);
}
@Override
public void update(Bullet b){
//damage every 5 ticks
if(b.timer(1, 5f)){
Damage.collideLine(b, b.team, hitEffect, b.x, b.y, b.rotation(), length, largeHit);
}
if(shake > 0){
Effect.shake(shake, shake, b);
}
} }
@Override @Override

View File

@@ -5,6 +5,7 @@ import arc.graphics.*;
import arc.graphics.g2d.*; import arc.graphics.g2d.*;
import arc.math.*; import arc.math.*;
import arc.math.geom.*; import arc.math.geom.*;
import arc.struct.*;
import arc.util.*; import arc.util.*;
import mindustry.*; import mindustry.*;
import mindustry.ctype.*; import mindustry.ctype.*;
@@ -15,6 +16,51 @@ import mindustry.world.*;
import static mindustry.Vars.*; import static mindustry.Vars.*;
public class Drawf{ public class Drawf{
private static FloatSeq points = new FloatSeq();
public static void flame(float x, float y, int divisions, float rotation, float length, float width, float pan){
flame(x, y, divisions, rotation, length, width, pan, 0f);
}
public static void flame(float x, float y, int divisions, float rotation, float length, float width, float pan, float offset){
float len1 = length * pan, len2 = length * (1f - pan);
points.clear();
//left side; half arc beginning at 90 degrees and ending at 270
for(int i = 0; i < divisions; i++){
float rot = 90f + 180f * i / (float)divisions;
Tmp.v1.trnsExact(rot, width);
point(
(Tmp.v1.x + width) / width * len1, //convert to 0..1, then multiply by desired length
Tmp.v1.y, //Y axis remains unchanged
x, y,
rotation
);
}
//right side; half arc beginning at -90 (270) and ending at 90
for(int i = 0; i < divisions; i++){
float rot = -90f + 180f * i / (float)divisions;
Tmp.v1.trnsExact(rot, width);
point(
len1 + (Tmp.v1.x) / width * len2, //convert to 0..1, then multiply by desired length and offset relative to previous segment
Tmp.v1.y, //Y axis remains unchanged
x, y,
rotation
);
}
Fill.poly(points);
}
private static void point(float x, float y, float baseX, float baseY, float rotation){
//TODO test exact and non-exact
Tmp.v1.set(x, y).rotateRadExact(rotation * Mathf.degRad);
points.add(Tmp.v1.x + baseX, Tmp.v1.y + baseY);
}
public static void dashLine(Color color, float x, float y, float x2, float y2){ public static void dashLine(Color color, float x, float y, float x2, float y2){
int segments = (int)(Math.max(Math.abs(x - x2), Math.abs(y - y2)) / tilesize * 2); int segments = (int)(Math.max(Math.abs(x - x2), Math.abs(y - y2)) / tilesize * 2);

View File

@@ -240,7 +240,7 @@ public class Weapon implements Cloneable{
mountY = unit.y + Angles.trnsy(unit.rotation - 90, x, y), mountY = unit.y + Angles.trnsy(unit.rotation - 90, x, y),
bulletX = mountX + Angles.trnsx(weaponRotation, this.shootX, this.shootY), bulletX = mountX + Angles.trnsx(weaponRotation, this.shootX, this.shootY),
bulletY = mountY + Angles.trnsy(weaponRotation, this.shootX, this.shootY), bulletY = mountY + Angles.trnsy(weaponRotation, this.shootX, this.shootY),
shootAngle = rotate ? weaponRotation + 90 : Angles.angle(bulletX, bulletY, mount.aimX, mount.aimY) + (unit.rotation - unit.angleTo(mount.aimX, mount.aimY)); shootAngle = rotate ? unit.rotation + mount.rotation : Angles.angle(bulletX, bulletY, mount.aimX, mount.aimY) + (unit.rotation - unit.angleTo(mount.aimX, mount.aimY));
//find a new target //find a new target
if(!controllable && autoTarget){ if(!controllable && autoTarget){
@@ -333,8 +333,16 @@ public class Weapon implements Cloneable{
return Units.invalidateTarget(target, unit.team, x, y, range + Math.abs(shootY)); return Units.invalidateTarget(target, unit.team, x, y, range + Math.abs(shootY));
} }
protected Vec2 getShootPos(Unit unit, WeaponMount mount, Vec2 out){
float weaponRot = unit.rotation - 90 + (rotate ? mount.rotation : 0);
return out.set(unit.x, unit.y)
.add(Angles.trnsx(unit.rotation - 90, x, y), Angles.trnsy(unit.rotation - 90, x, y))
.add(Angles.trnsx(weaponRot, this.shootX, this.shootY), Angles.trnsx(weaponRot, this.shootX, this.shootY));
}
protected void shoot(Unit unit, WeaponMount mount, float shootX, float shootY, float aimX, float aimY, float mountX, float mountY, float rotation, int side){ protected void shoot(Unit unit, WeaponMount mount, float shootX, float shootY, float aimX, float aimY, float mountX, float mountY, float rotation, int side){
float baseX = unit.x, baseY = unit.y; Vec2 offset = getShootPos(unit, mount, Tmp.v1);
float baseX = offset.x, baseY = offset.y, baseRot = unit.rotation + mount.rotation;
boolean delay = firstShotDelay + shotDelay > 0f; boolean delay = firstShotDelay + shotDelay > 0f;
(delay ? chargeSound : continuous ? Sounds.none : shootSound).at(shootX, shootY, Mathf.random(soundPitchMin, soundPitchMax)); (delay ? chargeSound : continuous ? Sounds.none : shootSound).at(shootX, shootY, Mathf.random(soundPitchMin, soundPitchMax));
@@ -347,7 +355,11 @@ public class Weapon implements Cloneable{
Angles.shotgun(shots, spacing, rotation, f -> { Angles.shotgun(shots, spacing, rotation, f -> {
Time.run(sequenceNum * shotDelay + firstShotDelay, () -> { Time.run(sequenceNum * shotDelay + firstShotDelay, () -> {
if(!unit.isAdded()) return; if(!unit.isAdded()) return;
mount.bullet = bullet(unit, shootX + unit.x - baseX, shootY + unit.y - baseY, f + Mathf.range(inaccuracy), lifeScl);
getShootPos(unit, mount, offset).sub(baseX, baseY);
float rotOffset = unit.rotation + mount.rotation - baseRot;
mount.bullet = bullet(unit, shootX + offset.x, shootY + offset.y, f + Mathf.range(inaccuracy) + rotOffset, lifeScl);
if(!continuous){ if(!continuous){
shootSound.at(shootX, shootY, Mathf.random(soundPitchMin, soundPitchMax)); shootSound.at(shootX, shootY, Mathf.random(soundPitchMin, soundPitchMax));
} }
@@ -371,7 +383,10 @@ public class Weapon implements Cloneable{
if(!continuous){ if(!continuous){
shootSound.at(shootX, shootY, Mathf.random(soundPitchMin, soundPitchMax)); shootSound.at(shootX, shootY, Mathf.random(soundPitchMin, soundPitchMax));
} }
ammo.chargeShootEffect.at(shootX + unit.x - baseX, shootY + unit.y - baseY, rotation, parentize ? unit : null);
getShootPos(unit, mount, offset).sub(baseX, baseY);
ammo.chargeShootEffect.at(shootX + offset.x, shootY + offset.y, rotation, parentize ? unit : null);
}); });
}else{ }else{
unit.vel.add(Tmp.v1.trns(rotation + 180f, ammo.recoil)); unit.vel.add(Tmp.v1.trns(rotation + 180f, ammo.recoil));

View File

@@ -710,6 +710,10 @@ public class Block extends UnlockableContent{
return teamRegion.found() && minfo.mod == null ? new TextureRegion[]{r, teamRegions[Team.sharded.id]} : new TextureRegion[]{r}; return teamRegion.found() && minfo.mod == null ? new TextureRegion[]{r, teamRegions[Team.sharded.id]} : new TextureRegion[]{r};
} }
public void getRegionsToOutline(Seq<TextureRegion> out){
}
public TextureRegion[] getGeneratedIcons(){ public TextureRegion[] getGeneratedIcons(){
return generatedIcons == null ? (generatedIcons = icons()) : generatedIcons; return generatedIcons == null ? (generatedIcons = icons()) : generatedIcons;
} }

View File

@@ -42,7 +42,7 @@ public class ContinuousTurret extends Turret{
@Override @Override
public boolean hasAmmo(){ public boolean hasAmmo(){
return consValid(); return cons.canConsume();
} }
@Override @Override

View File

@@ -48,6 +48,7 @@ public class Turret extends ReloadTurret{
public float ammoEjectBack = 1f; public float ammoEjectBack = 1f;
public float inaccuracy = 0f; public float inaccuracy = 0f;
public float velocityInaccuracy = 0f; public float velocityInaccuracy = 0f;
public float shootWarmupSpeed = 3f / 60f;
public int shots = 1; public int shots = 1;
public float spread = 4f; public float spread = 4f;
public float recoilAmount = 1f; public float recoilAmount = 1f;
@@ -149,6 +150,11 @@ public class Turret extends ReloadTurret{
return draw.icons(this); return draw.icons(this);
} }
@Override
public void getRegionsToOutline(Seq<TextureRegion> out){
draw.getRegionsToOutline(out);
}
public static abstract class AmmoEntry{ public static abstract class AmmoEntry{
public int amount; public int amount;
@@ -165,6 +171,7 @@ public class Turret extends ReloadTurret{
public Seq<AmmoEntry> ammo = new Seq<>(); public Seq<AmmoEntry> ammo = new Seq<>();
public int totalAmmo; public int totalAmmo;
public float recoil, heat, logicControlTime = -1; public float recoil, heat, logicControlTime = -1;
public float shootWarmup;
public int shotCounter; public int shotCounter;
public boolean logicShooting = false; public boolean logicShooting = false;
public @Nullable Posc target; public @Nullable Posc target;
@@ -172,6 +179,11 @@ public class Turret extends ReloadTurret{
public BlockUnitc unit = (BlockUnitc)UnitTypes.block.create(team); public BlockUnitc unit = (BlockUnitc)UnitTypes.block.create(team);
public boolean wasShooting, charging; public boolean wasShooting, charging;
@Override
public float warmup(){
return shootWarmup;
}
@Override @Override
public float drawrot(){ public float drawrot(){
return rotation - 90; return rotation - 90;
@@ -273,6 +285,9 @@ public class Turret extends ReloadTurret{
public void updateTile(){ public void updateTile(){
if(!validateTarget()) target = null; if(!validateTarget()) target = null;
//TODO can be lerp instead, that's smoother
shootWarmup = Mathf.approachDelta(shootWarmup, isActive() ? 1f : 0f, shootWarmupSpeed);
wasShooting = false; wasShooting = false;
recoil = Mathf.lerpDelta(recoil, 0f, restitution); recoil = Mathf.lerpDelta(recoil, 0f, restitution);

View File

@@ -138,6 +138,11 @@ public class GenericCrafter extends Block{
return outputItems != null; return outputItems != null;
} }
@Override
public void getRegionsToOutline(Seq<TextureRegion> out){
drawer.getRegionsToOutline(out);
}
public class GenericCrafterBuild extends Building{ public class GenericCrafterBuild extends Building{
public float progress; public float progress;
public float totalProgress; public float totalProgress;

View File

@@ -2,6 +2,7 @@ package mindustry.world.draw;
import arc.graphics.g2d.*; import arc.graphics.g2d.*;
import arc.math.*; import arc.math.*;
import arc.struct.*;
import arc.util.*; import arc.util.*;
import mindustry.entities.units.*; import mindustry.entities.units.*;
import mindustry.gen.*; import mindustry.gen.*;
@@ -22,6 +23,10 @@ public class DrawBlock{
@Deprecated @Deprecated
public void drawLight(GenericCrafterBuild build){} public void drawLight(GenericCrafterBuild build){}
public void getRegionsToOutline(Seq<TextureRegion> out){
}
/** Draws the block itself. */ /** Draws the block itself. */
public void drawBase(Building build){ public void drawBase(Building build){
Draw.rect(build.block.region, build.x, build.y, build.drawrot()); Draw.rect(build.block.region, build.x, build.y, build.drawrot());

View File

@@ -24,6 +24,13 @@ public class DrawMulti extends DrawBlock{
this.drawers = drawers.toArray(DrawBlock.class); this.drawers = drawers.toArray(DrawBlock.class);
} }
@Override
public void getRegionsToOutline(Seq<TextureRegion> out){
for(var draw : drawers){
draw.getRegionsToOutline(out);
}
}
@Override @Override
public void drawBase(Building build){ public void drawBase(Building build){
for(var draw : drawers){ for(var draw : drawers){

View File

@@ -4,6 +4,8 @@ import arc.*;
import arc.graphics.*; import arc.graphics.*;
import arc.graphics.g2d.*; import arc.graphics.g2d.*;
import arc.math.*; import arc.math.*;
import arc.struct.*;
import arc.util.*;
import mindustry.gen.*; import mindustry.gen.*;
import mindustry.graphics.*; import mindustry.graphics.*;
import mindustry.world.*; import mindustry.world.*;
@@ -14,8 +16,9 @@ import mindustry.world.blocks.defense.turrets.Turret.*;
public class DrawTurret extends DrawBlock{ public class DrawTurret extends DrawBlock{
protected static final Rand rand = new Rand(); protected static final Rand rand = new Rand();
public Seq<TurretPart> parts = new Seq<>();
public String basePrefix = ""; public String basePrefix = "";
public TextureRegion base, liquid, top, heat; public TextureRegion base, liquid, top, heat, preview;
public DrawTurret(String basePrefix){ public DrawTurret(String basePrefix){
this.basePrefix = basePrefix; this.basePrefix = basePrefix;
@@ -24,6 +27,13 @@ public class DrawTurret extends DrawBlock{
public DrawTurret(){ public DrawTurret(){
} }
@Override
public void getRegionsToOutline(Seq<TextureRegion> out){
for(var part : parts){
part.getOutlines(out);
}
}
@Override @Override
public void drawBase(Building build){ public void drawBase(Building build){
Turret turret = (Turret)build.block; Turret turret = (Turret)build.block;
@@ -38,6 +48,12 @@ public class DrawTurret extends DrawBlock{
drawTurret(turret, tb); drawTurret(turret, tb);
drawHeat(turret, tb); drawHeat(turret, tb);
if(parts.size > 0){
for(var part : parts){
part.draw(tb);
}
}
} }
public void drawTurret(Turret block, TurretBuild build){ public void drawTurret(Turret block, TurretBuild build){
@@ -67,11 +83,16 @@ public class DrawTurret extends DrawBlock{
public void load(Block block){ public void load(Block block){
if(!(block instanceof Turret)) throw new ClassCastException("This drawer can only be used on turrets."); if(!(block instanceof Turret)) throw new ClassCastException("This drawer can only be used on turrets.");
preview = Core.atlas.find(block.name + "-preview", block.region);
liquid = Core.atlas.find(block.name + "-liquid"); liquid = Core.atlas.find(block.name + "-liquid");
top = Core.atlas.find(block.name + "-top"); top = Core.atlas.find(block.name + "-top");
heat = Core.atlas.find(block.name + "-heat"); heat = Core.atlas.find(block.name + "-heat");
base = Core.atlas.find(block.name + "-base"); base = Core.atlas.find(block.name + "-base");
for(var part : parts){
part.load(block);
}
//TODO test this for mods, e.g. exotic //TODO test this for mods, e.g. exotic
if(!base.found() && block.minfo.mod != null) base = Core.atlas.find(block.minfo.mod.name + "-block-" + block.size); if(!base.found() && block.minfo.mod != null) base = Core.atlas.find(block.minfo.mod.name + "-block-" + block.size);
if(!base.found()) base = Core.atlas.find(basePrefix + "block-" + block.size); if(!base.found()) base = Core.atlas.find(basePrefix + "block-" + block.size);
@@ -80,6 +101,98 @@ public class DrawTurret extends DrawBlock{
/** @return the generated icons to be used for this block. */ /** @return the generated icons to be used for this block. */
@Override @Override
public TextureRegion[] icons(Block block){ public TextureRegion[] icons(Block block){
return top.found() ? new TextureRegion[]{base, block.region, top} : new TextureRegion[]{base, block.region}; TextureRegion showTop = preview.found() ? preview : block.region;
return top.found() ? new TextureRegion[]{base, showTop, top} : new TextureRegion[]{base, showTop};
}
public static class RegionPart extends TurretPart{
public String suffix = "";
public boolean mirror = true;
public TextureRegion[] regions;
public TextureRegion[] outlines;
public boolean outline = false;
public float layer = -1;
public float outlineLayerOffset = -0.01f;
public float rotation, rotMove;
public float originX, originY;
public float offsetX, offsetY, offsetMoveX, offsetMoveY;
public RegionPart(String region){
this.suffix = region;
}
public RegionPart(){
}
@Override
public void draw(TurretBuild build){
float z = Draw.z();
if(layer > 0){
Draw.z(layer);
}
float prevZ = layer > 0 ? layer : z;
float progress = build.warmup();
for(int i = 0; i < regions.length; i++){
var region = regions[i];
float sign = i == 1 ? -1 : 1;
Tmp.v1.set((offsetX + offsetMoveX * progress) * sign, offsetY + offsetMoveY*progress).rotate(build.rotation - 90);
float
x = build.x + Tmp.v1.x,
y = build.y + Tmp.v1.y,
rot = (i == 0 ? rotation : 180f - rotation) + rotMove * progress * sign + build.rotation,
ox = originX + region.width * Draw.scl/2f, oy = originY + region.height * Draw.scl/2f;
if(outline){
Draw.z(prevZ + outlineLayerOffset);
Draw.rect(outlines[i],
x, y, region.width * Draw.scl, region.height * Draw.scl,
ox, oy, rot);
Draw.z(prevZ);
}
Draw.rect(region,
x, y, region.width * Draw.scl, region.height * Draw.scl,
ox, oy, rot);
}
Draw.z(z);
}
@Override
public void load(Block block){
if(mirror){
regions = new TextureRegion[]{
Core.atlas.find(block.name + suffix + "1"),
Core.atlas.find(block.name + suffix + "2")
};
outlines = new TextureRegion[]{
Core.atlas.find(block.name + suffix + "1-outline"),
Core.atlas.find(block.name + suffix + "2-outline")
};
}else{
regions = new TextureRegion[]{Core.atlas.find(block.name + suffix)};
outlines = new TextureRegion[]{Core.atlas.find(block.name + suffix + "-outline")};
}
}
@Override
public void getOutlines(Seq<TextureRegion> out){
if(outline){
out.addAll(regions);
}
}
}
public static abstract class TurretPart{
public abstract void draw(TurretBuild build);
public abstract void load(Block block);
public void getOutlines(Seq<TextureRegion> out){}
} }
} }

View File

@@ -220,6 +220,9 @@ public class Generators{
block.load(); block.load();
block.loadIcon(); block.loadIcon();
Seq<TextureRegion> toOutline = new Seq<>();
block.getRegionsToOutline(toOutline);
TextureRegion[] regions = block.getGeneratedIcons(); TextureRegion[] regions = block.getGeneratedIcons();
if(block.variants > 0 || block instanceof Floor){ if(block.variants > 0 || block instanceof Floor){
@@ -257,6 +260,13 @@ public class Generators{
} }
} }
if(toOutline != null){
for(TextureRegion region : toOutline){
Pixmap pix = get(region).outline(block.outlineColor, block.outlineRadius);
save(pix, ((GenRegion)region).name + "-outline");
}
}
if(regions.length == 0){ if(regions.length == 0){
continue; continue;
} }