From 6fb2b3e920300fcc817e3dc84dc31a4813134322 Mon Sep 17 00:00:00 2001 From: Anuken Date: Tue, 2 Nov 2021 00:13:25 -0400 Subject: [PATCH] WIP build tower --- core/src/mindustry/content/Blocks.java | 9 ++ .../mindustry/entities/comp/BuilderComp.java | 18 ++- core/src/mindustry/type/UnitType.java | 3 +- .../world/blocks/defense/BuildTurret.java | 113 ++++++++++++++++++ 4 files changed, 137 insertions(+), 6 deletions(-) create mode 100644 core/src/mindustry/world/blocks/defense/BuildTurret.java diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index eeefe9291d..9ff4968c88 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -65,6 +65,7 @@ public class Blocks implements ContentList{ //defense copperWall, copperWallLarge, titaniumWall, titaniumWallLarge, plastaniumWall, plastaniumWallLarge, thoriumWall, thoriumWallLarge, door, doorLarge, phaseWall, phaseWallLarge, surgeWall, surgeWallLarge, mender, mendProjector, overdriveProjector, overdriveDome, forceProjector, shockMine, + buildTower, scrapWall, scrapWallLarge, scrapWallHuge, scrapWallGigantic, thruster, //ok, these names are getting ridiculous, but at least I don't have humongous walls yet //transport @@ -1157,6 +1158,14 @@ public class Blocks implements ContentList{ tendrils = 4; }}; + buildTower = new BuildTurret("build-tower"){{ + requirements(Category.effect, with(Items.lead, 40, Items.beryllium, 50)); + consumes.power(0.2f); + range = 200f; + size = 3; + health = 80; + }}; + //endregion //region distribution diff --git a/core/src/mindustry/entities/comp/BuilderComp.java b/core/src/mindustry/entities/comp/BuilderComp.java index c151562835..d1736c658c 100644 --- a/core/src/mindustry/entities/comp/BuilderComp.java +++ b/core/src/mindustry/entities/comp/BuilderComp.java @@ -46,6 +46,10 @@ abstract class BuilderComp implements Posc, Statusc, Teamc, Rotc{ @Override public void update(){ + updateBuildLogic(); + } + + public void updateBuildLogic(){ if(!headless){ //visual activity update if(lastActive != null && buildAlpha <= 0.01f){ @@ -57,7 +61,7 @@ abstract class BuilderComp implements Posc, Statusc, Teamc, Rotc{ if(!updateBuilding || !canBuild()) return; - float finalPlaceDst = state.rules.infiniteResources ? Float.MAX_VALUE : buildingRange; + float finalPlaceDst = state.rules.infiniteResources ? Float.MAX_VALUE : type.buildRange; boolean infinite = state.rules.infiniteResources || team().rules().infiniteResources; Iterator it = plans.iterator(); @@ -143,7 +147,7 @@ abstract class BuilderComp implements Posc, Statusc, Teamc, Rotc{ /** Draw all current build plans. Does not draw the beam effect, only the positions. */ void drawBuildPlans(){ - Boolf skip = plan -> plan.progress > 0.01f || (buildPlan() == plan && plan.initialized && (within(plan.x * tilesize, plan.y * tilesize, buildingRange) || state.isEditor())); + Boolf skip = plan -> plan.progress > 0.01f || (buildPlan() == plan && plan.initialized && (within(plan.x * tilesize, plan.y * tilesize, type.buildRange) || state.isEditor())); for(int i = 0; i < 2; i++){ for(BuildPlan plan : plans){ @@ -182,7 +186,7 @@ abstract class BuilderComp implements Posc, Statusc, Teamc, Rotc{ /** @return whether this request should be skipped, in favor of the next one. */ boolean shouldSkip(BuildPlan request, @Nullable Building core){ //requests that you have at least *started* are considered - if(state.rules.infiniteResources || team.rules().infiniteResources || request.breaking || core == null || request.isRotation(team) || (isBuilding() && !within(plans.last(), buildingRange))) return false; + if(state.rules.infiniteResources || team.rules().infiniteResources || request.breaking || core == null || request.isRotation(team) || (isBuilding() && !within(plans.last(), type.buildRange))) return false; return (request.stuck && !core.items.has(request.block.requirements)) || (Structs.contains(request.block.requirements, i -> !core.items.has(i.item, Math.min(i.amount, 15)) && Mathf.round(i.amount * state.rules.buildCostMultiplier) > 0) && !request.initialized); } @@ -238,7 +242,7 @@ abstract class BuilderComp implements Posc, Statusc, Teamc, Rotc{ boolean activelyBuilding(){ //not actively building when not near the build plan if(isBuilding()){ - if(!state.isEditor() && !within(buildPlan(), state.rules.infiniteResources ? Float.MAX_VALUE : buildingRange)){ + if(!state.isEditor() && !within(buildPlan(), state.rules.infiniteResources ? Float.MAX_VALUE : type.buildRange)){ return false; } } @@ -252,6 +256,10 @@ abstract class BuilderComp implements Posc, Statusc, Teamc, Rotc{ } public void draw(){ + drawBuilding(); + } + + public void drawBuilding(){ boolean active = activelyBuilding(); if(!active && lastActive == null) return; @@ -261,7 +269,7 @@ abstract class BuilderComp implements Posc, Statusc, Teamc, Rotc{ Tile tile = world.tile(plan.x, plan.y); var core = team.core(); - if(tile == null || !within(plan, state.rules.infiniteResources ? Float.MAX_VALUE : buildingRange)){ + if(tile == null || !within(plan, state.rules.infiniteResources ? Float.MAX_VALUE : type.buildRange)){ return; } diff --git a/core/src/mindustry/type/UnitType.java b/core/src/mindustry/type/UnitType.java index 4c5b61709e..2969a80997 100644 --- a/core/src/mindustry/type/UnitType.java +++ b/core/src/mindustry/type/UnitType.java @@ -12,6 +12,7 @@ import arc.scene.ui.*; import arc.scene.ui.layout.*; import arc.struct.*; import arc.util.*; +import mindustry.*; import mindustry.ai.types.*; import mindustry.annotations.Annotations.*; import mindustry.content.*; @@ -58,7 +59,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; + public float health = 200f, range = -1, miningRange = 70f, armor = 0f, maxRange = -1f, buildRange = Vars.buildingRange; public float crashDamageMultiplier = 1f; public boolean targetAir = true, targetGround = true; public boolean faceTarget = true, rotateShooting = true, isCounted = true, lowAltitude = false, circleTarget = false; diff --git a/core/src/mindustry/world/blocks/defense/BuildTurret.java b/core/src/mindustry/world/blocks/defense/BuildTurret.java new file mode 100644 index 0000000000..0d73223578 --- /dev/null +++ b/core/src/mindustry/world/blocks/defense/BuildTurret.java @@ -0,0 +1,113 @@ +package mindustry.world.blocks.defense; + +import arc.graphics.g2d.*; +import arc.util.*; +import mindustry.annotations.Annotations.*; +import mindustry.gen.*; +import mindustry.graphics.*; +import mindustry.type.*; +import mindustry.world.blocks.*; +import mindustry.world.blocks.defense.turrets.*; +import mindustry.world.meta.*; + +public class BuildTurret extends BaseTurret{ + public @Load(value = "@-base", fallback = "block-@size") TextureRegion baseRegion; + public float buildSpeed = 1f; + //created in init() + public @Nullable UnitType unitType; + public float elevation = -1f; + + public BuildTurret(String name){ + super(name); + group = BlockGroup.turrets; + } + + @Override + public void init(){ + super.init(); + + if(elevation < 0) elevation = size / 2f; + + //this is super hacky, but since blocks are initialized before units it does not run into init/concurrent modification issues + unitType = new UnitType("turret-unit-" + name){{ + speed = 0f; + hitSize = 0f; + health = 1; + rotateSpeed = 360f; + itemCapacity = 0; + commandLimit = 0; + constructor = BlockUnitUnit::create; + buildRange = BuildTurret.this.range; + buildSpeed = BuildTurret.this.buildSpeed; + }}; + } + + public class BuildTurretBuild extends BaseTurretBuild implements ControlBlock{ + public BlockUnitc unit = (BlockUnitc)unitType.create(team); + + @Override + public boolean canControl(){ + return true; + } + + @Override + public Unit unit(){ + //make sure stats are correct + unit.tile(this); + unit.team(team); + return (Unit)unit; + } + + @Override + public void updateTile(){ + unit.tile(this); + unit.team(team); + + //only cares about where the unit itself is looking + rotation = unit.rotation(); + + if(unit.activelyBuilding()){ + unit.lookAt(angleTo(unit.buildPlan())); + } + + if(!isControlled()){ + unit.updateBuilding(true); + } + + //please do not commit suicide + unit.plans().remove(b -> b.build() == this); + + unit.updateBuildLogic(); + } + + @Override + public void draw(){ + super.draw(); + + Draw.rect(baseRegion, x, y); + Draw.color(); + + Draw.z(Layer.turret); + + Drawf.shadow(region, x - elevation, y - elevation, rotation - 90); + Draw.rect(region, x, y, rotation - 90); + + unit.drawBuilding(); + } + + /* + @Override + public void write(Writes write){ + super.write(write); + write.f(rotation); + //TODO build queue + } + + @Override + public void read(Reads read, byte revision){ + super.read(read, revision); + rotation = read.f(); + unit.rotation(rotation); + }*/ + } +}