mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-02-22 04:28:27 +07:00
aaaaaaaAAAAAAAAAAAAAAAAAA
This commit is contained in:
parent
41b669d6e1
commit
8023ea1d34
@ -1 +1 @@
|
||||
{fields:[{name:ammo,type:float},{name:building,type:Building},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{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:type,type:mindustry.type.UnitType},{name:updateBuilding,type:boolean},{name:vel,type:arc.math.geom.Vec2},{name:x,type:float},{name:y,type:float}]}
|
||||
{fields:[{name:ammo,type:float},{name:building,type:Building},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:payloads,type:arc.struct.Seq<mindustry.world.blocks.payloads.Payload>},{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: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: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 3.9 KiB |
Binary file not shown.
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
@ -1,22 +1,26 @@
|
||||
package mindustry.ai.types;
|
||||
|
||||
import arc.math.*;
|
||||
import arc.math.geom.*;
|
||||
import mindustry.entities.units.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.world.blocks.units.UnitAssembler.*;
|
||||
|
||||
public class AssemblerAI extends AIController{
|
||||
public Vec2 targetPos = new Vec2();
|
||||
public float targetAngle;
|
||||
|
||||
@Override
|
||||
public void updateMovement(){
|
||||
//TODO
|
||||
if(!targetPos.isZero()){
|
||||
moveTo(targetPos, 8f, 11f);
|
||||
moveTo(targetPos, 1f, 3f);
|
||||
}
|
||||
|
||||
if(unit instanceof BuildingTetherc tether && tether.building() instanceof UnitAssemblerBuild assembler){
|
||||
unit.lookAt(assembler.getUnitSpawn());
|
||||
if(unit.within(targetPos, 5f)){
|
||||
unit.lookAt(targetAngle);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean inPosition(){
|
||||
return unit.within(targetPos, 10f) && Angles.within(unit.rotation, targetAngle, 15f);
|
||||
}
|
||||
}
|
||||
|
@ -3319,7 +3319,7 @@ public class Blocks{
|
||||
//TODO completely unfinished
|
||||
tankAssembler = new UnitAssembler("tank-assembler"){{
|
||||
requirements(Category.units, with(Items.graphite, 10));
|
||||
size = 3;
|
||||
size = 5;
|
||||
droneType = UnitTypes.manifold;
|
||||
plans.add(new AssemblerUnitPlan(UnitTypes.vanquish, 60f * 5f, BlockStack.list(Blocks.thoriumWallLarge, 4, Blocks.duct, 2)));
|
||||
consumes.power(1f);
|
||||
|
@ -13,6 +13,7 @@ import mindustry.gen.*;
|
||||
import mindustry.graphics.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.world.*;
|
||||
import mindustry.world.blocks.units.UnitAssembler.*;
|
||||
|
||||
import static arc.graphics.g2d.Draw.rect;
|
||||
import static arc.graphics.g2d.Draw.*;
|
||||
@ -226,6 +227,17 @@ public class Fx{
|
||||
});
|
||||
}),
|
||||
|
||||
payloadDeposit = new Effect(30f, e -> {
|
||||
if(!(e.data instanceof YeetData data)) return;
|
||||
Tmp.v1.set(e.x, e.y).lerp(data.target, e.finpow());
|
||||
float x = Tmp.v1.x, y = Tmp.v1.y;
|
||||
|
||||
scl(e.fout(Interp.pow3Out) * 1.05f);
|
||||
Drawf.squareShadow(x, y, data.block.size * tilesize * 1.85f, 1f);
|
||||
mixcol(Pal.accent, e.fin());
|
||||
rect(data.block.fullIcon, x, y);
|
||||
}).layer(Layer.flyingUnitLow - 5f),
|
||||
|
||||
select = new Effect(23, e -> {
|
||||
color(Pal.accent);
|
||||
stroke(e.fout() * 3f);
|
||||
|
@ -68,8 +68,8 @@ public class UnitTypes{
|
||||
//special block unit type
|
||||
public static @EntityDef({Unitc.class, BlockUnitc.class}) UnitType block;
|
||||
|
||||
//special tethered
|
||||
public static @EntityDef({Unitc.class, BuildingTetherc.class}) UnitType manifold, assemblyDrone;
|
||||
//special tethered (has payload capability, because it's necessary sometimes)
|
||||
public static @EntityDef({Unitc.class, BuildingTetherc.class, Payloadc.class}) UnitType manifold, assemblyDrone, payloadDrone;
|
||||
|
||||
//tank
|
||||
//TODO tank comp
|
||||
@ -2431,7 +2431,7 @@ public class UnitTypes{
|
||||
hitSize = 28f;
|
||||
treadPullOffset = 4;
|
||||
speed = 0.6f;
|
||||
health = 10000;
|
||||
health = 9000;
|
||||
armor = 20f;
|
||||
treadRect = new Rect(22f, 16f, 28f, 130f);
|
||||
|
||||
@ -2448,7 +2448,7 @@ public class UnitTypes{
|
||||
y = 0;
|
||||
shadow = 28f;
|
||||
|
||||
bullet = new BasicBulletType(7f, 50){{
|
||||
bullet = new BasicBulletType(7f, 90){{
|
||||
sprite = "missile-large";
|
||||
width = 9f;
|
||||
height = 15f;
|
||||
@ -2744,6 +2744,10 @@ public class UnitTypes{
|
||||
envDisabled = Env.none;
|
||||
}};
|
||||
|
||||
//payloadDrone = new UnitType("payload-drone"){{
|
||||
|
||||
//}};
|
||||
|
||||
//endregion
|
||||
//region neoplasm
|
||||
|
||||
|
@ -224,6 +224,12 @@ public class Drawf{
|
||||
shadow(x, y, rad, 1f);
|
||||
}
|
||||
|
||||
public static void squareShadow(float x, float y, float rad, float alpha){
|
||||
Draw.color(0, 0, 0, 0.4f * alpha);
|
||||
Draw.rect("square-shadow", x, y, rad * Draw.xscl, rad * Draw.yscl);
|
||||
Draw.color();
|
||||
}
|
||||
|
||||
public static void shadow(float x, float y, float rad, float alpha){
|
||||
Draw.color(0, 0, 0, 0.4f * alpha);
|
||||
Draw.rect("circle-shadow", x, y, rad * Draw.xscl, rad * Draw.yscl);
|
||||
|
@ -252,12 +252,12 @@ public class ErekirPlanetGenerator extends PlanetGenerator{
|
||||
state.rules.defaultTeam.items().add(Seq.with(ItemStack.with(Items.beryllium, 300, Items.graphite, 300)));
|
||||
|
||||
//TODO proper waves
|
||||
state.rules.waves = false;
|
||||
state.rules.waves = true;
|
||||
state.rules.showSpawns = true;
|
||||
state.rules.waveTimer = true;
|
||||
state.rules.waveSpacing = 60f * 60f * 10f;
|
||||
state.rules.waveSpacing = 60f * 60f * 15f;
|
||||
state.rules.spawns = Seq.with(new SpawnGroup(){{
|
||||
type = UnitTypes.fortress;
|
||||
type = UnitTypes.vanquish;
|
||||
spacing = 1;
|
||||
shieldScaling = 60;
|
||||
unitScaling = 2f;
|
||||
|
@ -85,13 +85,15 @@ public class BuildPayload implements Payload{
|
||||
|
||||
@Override
|
||||
public void drawShadow(float alpha){
|
||||
Drawf.shadow(build.x, build.y, build.block.size * tilesize * 2f, alpha);
|
||||
Drawf.squareShadow(build.x, build.y, build.block.size * tilesize * 1.85f, alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(){
|
||||
drawShadow(1f);
|
||||
float prevZ = Draw.z();
|
||||
Draw.z(prevZ - 0.0001f);
|
||||
drawShadow(1f);
|
||||
Draw.z(prevZ);
|
||||
Draw.zTransform(z -> z >= Layer.flyingUnitLow ? z : 0.0011f + Mathf.clamp(z, prevZ - 0.001f, prevZ + 0.9f));
|
||||
build.tile = emptyTile;
|
||||
build.payloadDraw();
|
||||
|
@ -92,12 +92,12 @@ public class UnitAssembler extends PayloadBlock{
|
||||
|
||||
@Override
|
||||
public void init(){
|
||||
clipSize = Math.max(clipSize, (areaSize + size) * tilesize * 2);
|
||||
consumes.add(new ConsumePayloadDynamic((UnitAssemblerBuild build) -> build.plan().requirements));
|
||||
|
||||
super.init();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setStats(){
|
||||
super.setStats();
|
||||
@ -137,6 +137,16 @@ public class UnitAssembler extends PayloadBlock{
|
||||
AssemblerUnitPlan(){}
|
||||
}
|
||||
|
||||
public static class YeetData{
|
||||
public Vec2 target;
|
||||
public Block block;
|
||||
|
||||
public YeetData(Vec2 target, Block block){
|
||||
this.target = target;
|
||||
this.block = block;
|
||||
}
|
||||
}
|
||||
|
||||
public class UnitAssemblerBuild extends PayloadBlockBuild<BuildPayload>{
|
||||
protected IntSeq readUnits = new IntSeq();
|
||||
|
||||
@ -146,7 +156,6 @@ public class UnitAssembler extends PayloadBlock{
|
||||
public float progress, warmup;
|
||||
public float invalidWarmup = 0f;
|
||||
public int currentTier = 0;
|
||||
|
||||
public boolean wasOccupied = false;
|
||||
|
||||
public Vec2 getUnitSpawn(){
|
||||
@ -173,7 +182,6 @@ public class UnitAssembler extends PayloadBlock{
|
||||
public void updateModules(UnitAssemblerModuleBuild build){
|
||||
modules.addUnique(build);
|
||||
checkTier();
|
||||
//TODO tier check
|
||||
}
|
||||
|
||||
public void removeModule(UnitAssemblerModuleBuild build){
|
||||
@ -211,7 +219,7 @@ public class UnitAssembler extends PayloadBlock{
|
||||
Drawf.selected(module, Pal.accent);
|
||||
}
|
||||
|
||||
//TODO draw area
|
||||
//TODO draw area when no power
|
||||
}
|
||||
|
||||
//is this necessary? wastes a lot of space
|
||||
@ -265,10 +273,10 @@ public class UnitAssembler extends PayloadBlock{
|
||||
readUnits.clear();
|
||||
}
|
||||
|
||||
units.removeAll(u -> !u.isAdded() || u.dead);
|
||||
units.removeAll(u -> !u.isAdded() || u.dead || !(u.controller() instanceof AssemblerAI));
|
||||
|
||||
//TODO build up units, don't spawn immediately in batches
|
||||
if(efficiency() > 0 && units.size < dronesCreated){
|
||||
//TODO build animation? distribute spawning?
|
||||
var unit = droneType.create(team);
|
||||
if(unit instanceof BuildingTetherc bt){
|
||||
bt.building(this);
|
||||
@ -281,20 +289,26 @@ public class UnitAssembler extends PayloadBlock{
|
||||
units.add(unit);
|
||||
}
|
||||
|
||||
//TODO units should move stuff into position
|
||||
//TODO units should pick up and move payloads into position
|
||||
|
||||
Vec2 spawn = getUnitSpawn();
|
||||
|
||||
if(moveInPayload() && !wasOccupied){
|
||||
yeetPayload(payload);
|
||||
payload = null;
|
||||
}
|
||||
|
||||
//arrange units around perimeter
|
||||
for(int i = 0; i < units.size; i++){
|
||||
var unit = units.get(i);
|
||||
if(unit.controller() instanceof AssemblerAI ai){
|
||||
ai.targetPos.trns(i * 90f + 45f, areaSize / 2f * Mathf.sqrt2 * tilesize).add(spawn);
|
||||
}
|
||||
var ai = (AssemblerAI)unit.controller();
|
||||
|
||||
ai.targetPos.trns(i * 90f + 45f, areaSize / 2f * Mathf.sqrt2 * tilesize).add(spawn);
|
||||
ai.targetAngle = i * 90f + 45f + 180f;
|
||||
}
|
||||
|
||||
wasOccupied = checkSolid(spawn);
|
||||
float eff = (units.size / (float)dronesCreated);
|
||||
float eff = (units.count(u -> ((AssemblerAI)u.controller()).inPosition()) / (float)dronesCreated);
|
||||
|
||||
invalidWarmup = Mathf.lerpDelta(invalidWarmup, wasOccupied ? 1f : 0f, 0.1f);
|
||||
|
||||
@ -312,7 +326,8 @@ public class UnitAssembler extends PayloadBlock{
|
||||
var unit = plan.unit.create(team);
|
||||
unit.set(spawn.x + Mathf.range(0.001f), spawn.y + Mathf.range(0.001f));
|
||||
unit.rotation = 90f;
|
||||
unit.add();
|
||||
//TODO annoying so nothing is created yet
|
||||
//unit.add();
|
||||
progress = 0f;
|
||||
|
||||
Fx.spawn.at(unit);
|
||||
@ -329,7 +344,6 @@ public class UnitAssembler extends PayloadBlock{
|
||||
@Override
|
||||
public void draw(){
|
||||
Draw.rect(region, x, y);
|
||||
//Draw.rect(outRegion, x, y, rotdeg());
|
||||
|
||||
//draw input conveyors
|
||||
for(int i = 0; i < 4; i++){
|
||||
@ -340,12 +354,13 @@ public class UnitAssembler extends PayloadBlock{
|
||||
|
||||
Draw.z(Layer.blockOver);
|
||||
|
||||
//payRotation = rotdeg();
|
||||
//drawPayload();
|
||||
payRotation = rotdeg();
|
||||
drawPayload();
|
||||
|
||||
Draw.z(Layer.blockOver + 0.1f);
|
||||
|
||||
Draw.rect(topRegion, x, y);
|
||||
//TODO top?
|
||||
//Draw.rect(topRegion, x, y);
|
||||
|
||||
Vec2 spawn = getUnitSpawn();
|
||||
|
||||
@ -355,7 +370,6 @@ public class UnitAssembler extends PayloadBlock{
|
||||
|
||||
Draw.rect(plan.unit.fullIcon, spawn.x, spawn.y);
|
||||
|
||||
//TODO which layer?
|
||||
Draw.z(Layer.buildBeam);
|
||||
|
||||
//draw unit outline
|
||||
@ -364,16 +378,16 @@ public class UnitAssembler extends PayloadBlock{
|
||||
Draw.rect(plan.unit.fullIcon, spawn.x, spawn.y);
|
||||
|
||||
Draw.alpha(warmup * Draw.getColor().a);
|
||||
int c = 0;
|
||||
|
||||
//draw build beams
|
||||
for(var unit : units){
|
||||
if(!Angles.within(unit.rotation, c * 90f + 45f + 180f, 15f)) continue;
|
||||
if(!((AssemblerAI)unit.controller()).inPosition()) continue;
|
||||
|
||||
float
|
||||
px = unit.x + Angles.trnsx(unit.rotation, unit.type.buildBeamOffset),
|
||||
py = unit.y + Angles.trnsy(unit.rotation, unit.type.buildBeamOffset);
|
||||
|
||||
Drawf.buildBeam(px, py, spawn.x, spawn.y, plan.unit.hitSize/2f);
|
||||
c ++;
|
||||
}
|
||||
|
||||
Draw.reset();
|
||||
@ -389,37 +403,30 @@ public class UnitAssembler extends PayloadBlock{
|
||||
Draw.reset();
|
||||
|
||||
float outSize = plan.unit.hitSize + 9f;
|
||||
float hs = size * tilesize/2f, ha = outSize/2f;
|
||||
|
||||
Lines.stroke(2f, Tmp.c3.set(Pal.accent).lerp(Pal.remove, invalidWarmup).a(efficiency()));
|
||||
|
||||
//draw small square for area
|
||||
//TODO dash rect for output, fades in/out
|
||||
Lines.stroke(2f, Tmp.c3.set(Pal.accent).lerp(Pal.remove, invalidWarmup).a(efficiency()));
|
||||
Drawf.dashSquareBasic(spawn.x, spawn.y, outSize);
|
||||
|
||||
/*
|
||||
for(int i : Mathf.signs){
|
||||
Tmp.v1.trns(rotation * 90, hs, hs * i).add(x, y);
|
||||
|
||||
Tmp.v2.trns(rotation * 90, -ha, ha * i).add(spawn);
|
||||
Draw.color();
|
||||
|
||||
Drawf.dashLine(color, Tmp.v1.x, Tmp.v1.y, Tmp.v2.x, Tmp.v2.y);
|
||||
}*/
|
||||
|
||||
Draw.reset();
|
||||
|
||||
Draw.z(Layer.overlayUI - 1);
|
||||
|
||||
//TODO dashes bad
|
||||
|
||||
|
||||
Draw.reset();
|
||||
}
|
||||
|
||||
public boolean checkSolid(Vec2 v){
|
||||
var output = unit();
|
||||
return !output.flying && (collisions.overlapsTile(Tmp.r1.setCentered(v.x, v.y, output.hitSize), EntityCollisions::solid) || Units.anyEntities(v.x, v.y, output.hitSize));
|
||||
return !output.flying && (collisions.overlapsTile(Tmp.r1.setCentered(v.x, v.y, output.hitSize), EntityCollisions::solid) || Units.anyEntities(v.x, v.y, output.hitSize * 1.4f));
|
||||
}
|
||||
|
||||
/** @return true if this block is ready to produce units, e.g. requirements met */
|
||||
public boolean ready(){
|
||||
return consValid() && !wasOccupied;
|
||||
}
|
||||
|
||||
public void yeetPayload(BuildPayload payload){
|
||||
var spawn = getUnitSpawn();
|
||||
blocks.add(payload.block(), 1);
|
||||
float rot = payload.angleTo(spawn);
|
||||
Fx.shootPayloadDriver.at(payload.x(), payload.y(), rot);
|
||||
Fx.payloadDeposit.at(payload.x(), payload.y(), rot, new YeetData(spawn.cpy(), payload.block()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -427,19 +434,10 @@ public class UnitAssembler extends PayloadBlock{
|
||||
return blocks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handlePayload(Building source, Payload payload){
|
||||
//super.handlePayload(source, payload);
|
||||
|
||||
blocks.add(((BuildPayload)payload).block());
|
||||
|
||||
//payloads.add((BuildPayload)payload);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acceptPayload(Building source, Payload payload){
|
||||
var plan = plan();
|
||||
return payload instanceof BuildPayload bp && plan.requirements.contains(b -> b.block == bp.block() && blocks.get(bp.block()) < b.amount);
|
||||
return this.payload == null && payload instanceof BuildPayload bp && plan.requirements.contains(b -> b.block == bp.block() && blocks.get(bp.block()) < b.amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -453,11 +451,6 @@ public class UnitAssembler extends PayloadBlock{
|
||||
}
|
||||
|
||||
blocks.write(write);
|
||||
|
||||
//TODO save:
|
||||
//- unit IDs
|
||||
//- progress
|
||||
//- payloads in position (should they have positions?)
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -81,7 +81,7 @@ public class UnitAssemblerModule extends PayloadBlock{
|
||||
|
||||
@Override
|
||||
public boolean acceptPayload(Building source, Payload payload){
|
||||
return link != null && payload == null && link.acceptPayload(source, payload);
|
||||
return link != null && this.payload == null && link.acceptPayload(source, payload);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -108,10 +108,9 @@ public class UnitAssemblerModule extends PayloadBlock{
|
||||
findLink();
|
||||
}
|
||||
|
||||
if(moveInPayload()){
|
||||
if(link != null && link.moduleFits(block, x, y, rotation) && link.acceptPayload(this, payload)){
|
||||
link.handlePayload(this, payload);
|
||||
}
|
||||
if(moveInPayload() && link != null && link.moduleFits(block, x, y, rotation) && link.acceptPayload(this, payload)){
|
||||
link.yeetPayload(payload);
|
||||
payload = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,8 +53,11 @@ public class ConsumePayloadFilter extends Consume{
|
||||
var inv = build.getBlockPayloads();
|
||||
|
||||
MultiReqImage image = new MultiReqImage();
|
||||
content.blocks().each(i -> filter.get(i) && i.unlockedNow(), block -> image.add(new ReqImage(new ItemImage(block.uiIcon, 1),
|
||||
() -> inv.contains(block, 1))));
|
||||
|
||||
content.blocks().each(i -> filter.get(i) && i.unlockedNow(),
|
||||
block -> image.add(new ReqImage(new ItemImage(block.uiIcon, 1),
|
||||
() -> inv.contains(block, 1)))
|
||||
);
|
||||
|
||||
table.add(image).size(8 * 4);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user