From c324f2124be9449a3b8875d1479fb879eec40b0d Mon Sep 17 00:00:00 2001 From: Anuken Date: Tue, 15 Feb 2022 16:46:32 -0500 Subject: [PATCH] DEATH AND DESTRUCTION --- core/assets/scripts/global.js | 1 - .../BoundedSlotAssignmentStrategy.java | 44 --- .../DistanceAssignmentStrategy.java | 51 --- .../mindustry/ai/formations/Formation.java | 214 ----------- .../ai/formations/FormationMember.java | 16 - .../formations/FormationMotionModerator.java | 52 --- .../ai/formations/FormationPattern.java | 29 -- .../FreeSlotAssignmentStrategy.java | 34 -- .../ai/formations/SlotAssignment.java | 29 -- .../ai/formations/SlotAssignmentStrategy.java | 20 - .../SoftRoleSlotAssignmentStrategy.java | 164 -------- .../formations/patterns/CircleFormation.java | 22 -- .../formations/patterns/SquareFormation.java | 25 -- core/src/mindustry/ai/types/DefenderAI.java | 9 +- core/src/mindustry/ai/types/FlyingAI.java | 8 +- core/src/mindustry/ai/types/FormationAI.java | 105 ------ core/src/mindustry/ai/types/GroundAI.java | 11 +- core/src/mindustry/ai/types/HugAI.java | 51 +-- core/src/mindustry/ai/types/LogicAI.java | 11 +- core/src/mindustry/ai/types/SuicideAI.java | 27 +- core/src/mindustry/content/Blocks.java | 355 +++++++++--------- core/src/mindustry/content/Bullets.java | 8 +- core/src/mindustry/content/Planets.java | 1 - .../mindustry/content/SerpuloTechTree.java | 4 - core/src/mindustry/content/UnitTypes.java | 13 - core/src/mindustry/core/Logic.java | 6 - core/src/mindustry/core/NetServer.java | 4 - .../mindustry/entities/comp/BuildingComp.java | 38 +- .../entities/comp/CommanderComp.java | 129 ------- .../mindustry/entities/comp/PlayerComp.java | 4 - .../src/mindustry/entities/comp/UnitComp.java | 21 +- .../entities/units/AIController.java | 4 - .../mindustry/entities/units/UnitCommand.java | 18 - .../entities/units/UnitController.java | 4 - core/src/mindustry/game/EventType.java | 11 - core/src/mindustry/game/Rules.java | 2 - core/src/mindustry/game/Schematic.java | 3 +- core/src/mindustry/game/Teams.java | 3 - .../src/mindustry/graphics/BlockRenderer.java | 2 +- core/src/mindustry/input/Binding.java | 2 - core/src/mindustry/input/DesktopInput.java | 7 +- core/src/mindustry/input/InputHandler.java | 54 +-- core/src/mindustry/input/MobileInput.java | 24 +- core/src/mindustry/io/TypeIO.java | 24 +- core/src/mindustry/logic/GlobalConstants.java | 8 +- core/src/mindustry/logic/LAccess.java | 1 - core/src/mindustry/logic/LExecutor.java | 2 +- .../maps/planet/ErekirPlanetGenerator.java | 1 - core/src/mindustry/mod/ClassMap.java | 12 +- core/src/mindustry/mod/ContentParser.java | 16 +- core/src/mindustry/service/GameService.java | 7 - core/src/mindustry/type/UnitType.java | 4 +- .../mindustry/type/ammo/PowerAmmoType.java | 6 +- .../mindustry/type/unit/ErekirUnitType.java | 1 - .../ui/dialogs/CustomRulesDialog.java | 1 - .../mindustry/ui/fragments/HintsFragment.java | 1 - core/src/mindustry/world/Block.java | 162 ++++++-- .../world/blocks/campaign/Accelerator.java | 2 +- .../world/blocks/campaign/LaunchPad.java | 4 +- .../world/blocks/defense/BuildTurret.java | 1 - .../defense/DirectionalForceProjector.java | 8 +- .../world/blocks/defense/ForceProjector.java | 15 +- .../blocks/defense/OverdriveProjector.java | 2 +- .../blocks/defense/turrets/BaseTurret.java | 12 +- .../turrets/ContinuousLiquidTurret.java | 2 +- .../defense/turrets/ContinuousTurret.java | 9 +- .../blocks/defense/turrets/ItemTurret.java | 2 +- .../blocks/defense/turrets/LaserTurret.java | 8 +- .../blocks/defense/turrets/LiquidTurret.java | 2 +- .../blocks/defense/turrets/PayloadTurret.java | 2 +- .../blocks/defense/turrets/ReloadTurret.java | 7 +- .../defense/turrets/TractorBeamTurret.java | 3 +- .../world/blocks/defense/turrets/Turret.java | 2 +- .../distribution/DirectionalUnloader.java | 2 +- .../world/blocks/heat/HeatConductor.java | 2 +- .../world/blocks/heat/HeatProducer.java | 2 +- .../blocks/legacy/LegacyCommandCenter.java | 28 ++ .../world/blocks/liquid/LiquidJunction.java | 2 +- .../world/blocks/payloads/BlockProducer.java | 4 +- .../blocks/payloads/PayloadDeconstructor.java | 2 +- .../world/blocks/payloads/PayloadLoader.java | 14 +- .../blocks/payloads/PayloadUnloader.java | 2 +- .../mindustry/world/blocks/power/Battery.java | 6 +- .../world/blocks/power/BeamNode.java | 4 +- .../world/blocks/power/ImpactReactor.java | 8 +- .../blocks/power/ItemLiquidGenerator.java | 6 +- .../world/blocks/power/NuclearReactor.java | 18 +- .../world/blocks/power/PowerDiode.java | 4 +- .../world/blocks/power/PowerGenerator.java | 4 +- .../world/blocks/power/PowerGraph.java | 95 +++-- .../world/blocks/power/PowerNode.java | 26 +- .../blocks/production/AttributeCrafter.java | 2 +- .../world/blocks/production/BeamDrill.java | 2 +- .../world/blocks/production/Drill.java | 2 +- .../blocks/production/GenericCrafter.java | 2 +- .../world/blocks/production/HeatCrafter.java | 2 +- .../blocks/production/LiquidConverter.java | 22 +- .../world/blocks/production/Separator.java | 15 +- .../world/blocks/production/SolidPump.java | 2 +- .../world/blocks/production/WallCrafter.java | 2 +- .../world/blocks/sandbox/ItemSource.java | 2 +- .../world/blocks/sandbox/LiquidSource.java | 2 +- .../world/blocks/sandbox/LiquidVoid.java | 2 +- .../world/blocks/sandbox/PowerVoid.java | 2 +- .../world/blocks/storage/CoreBlock.java | 2 +- .../world/blocks/storage/Unloader.java | 2 +- .../world/blocks/units/CommandCenter.java | 143 ------- .../world/blocks/units/Reconstructor.java | 10 +- .../world/blocks/units/RepairPoint.java | 9 +- .../world/blocks/units/UnitAssembler.java | 10 +- .../world/blocks/units/UnitCargoLoader.java | 2 +- .../world/blocks/units/UnitFactory.java | 6 +- .../mindustry/world/consumers/Consume.java | 33 +- .../world/consumers/ConsumeItemDynamic.java | 6 +- .../world/consumers/ConsumeItemFilter.java | 13 +- .../world/consumers/ConsumeItems.java | 13 +- .../world/consumers/ConsumeLiquid.java | 7 +- .../world/consumers/ConsumeLiquidBase.java | 5 +- .../world/consumers/ConsumeLiquidFilter.java | 6 +- .../world/consumers/ConsumeLiquids.java | 12 +- .../consumers/ConsumePayloadDynamic.java | 5 - .../world/consumers/ConsumePayloadFilter.java | 5 - .../world/consumers/ConsumePayloads.java | 5 - .../world/consumers/ConsumePower.java | 7 +- .../ConsumePowerCondition.java} | 7 +- .../ConsumePowerDynamic.java} | 7 +- .../world/consumers/ConsumeType.java | 10 - .../mindustry/world/consumers/Consumers.java | 141 ------- core/src/mindustry/world/draw/DrawLiquid.java | 10 +- core/src/mindustry/world/draw/DrawMixer.java | 10 +- core/src/mindustry/world/meta/BlockBars.java | 22 -- core/src/mindustry/world/meta/Stat.java | 1 - .../test/java/power/DirectConsumerTests.java | 4 +- .../src/test/java/power/PowerTestFixture.java | 8 +- tests/src/test/java/power/PowerTests.java | 6 +- 135 files changed, 703 insertions(+), 2079 deletions(-) delete mode 100644 core/src/mindustry/ai/formations/BoundedSlotAssignmentStrategy.java delete mode 100644 core/src/mindustry/ai/formations/DistanceAssignmentStrategy.java delete mode 100644 core/src/mindustry/ai/formations/Formation.java delete mode 100644 core/src/mindustry/ai/formations/FormationMember.java delete mode 100644 core/src/mindustry/ai/formations/FormationMotionModerator.java delete mode 100644 core/src/mindustry/ai/formations/FormationPattern.java delete mode 100644 core/src/mindustry/ai/formations/FreeSlotAssignmentStrategy.java delete mode 100644 core/src/mindustry/ai/formations/SlotAssignment.java delete mode 100644 core/src/mindustry/ai/formations/SlotAssignmentStrategy.java delete mode 100644 core/src/mindustry/ai/formations/SoftRoleSlotAssignmentStrategy.java delete mode 100644 core/src/mindustry/ai/formations/patterns/CircleFormation.java delete mode 100644 core/src/mindustry/ai/formations/patterns/SquareFormation.java delete mode 100644 core/src/mindustry/ai/types/FormationAI.java delete mode 100644 core/src/mindustry/entities/comp/CommanderComp.java delete mode 100644 core/src/mindustry/entities/units/UnitCommand.java create mode 100644 core/src/mindustry/world/blocks/legacy/LegacyCommandCenter.java delete mode 100644 core/src/mindustry/world/blocks/units/CommandCenter.java rename core/src/mindustry/world/{blocks/power/ConditionalConsumePower.java => consumers/ConsumePowerCondition.java} (61%) rename core/src/mindustry/world/{blocks/power/DynamicConsumePower.java => consumers/ConsumePowerDynamic.java} (63%) delete mode 100644 core/src/mindustry/world/consumers/ConsumeType.java delete mode 100644 core/src/mindustry/world/consumers/Consumers.java delete mode 100644 core/src/mindustry/world/meta/BlockBars.java diff --git a/core/assets/scripts/global.js b/core/assets/scripts/global.js index f4ebebe16f95..d09954ca520f 100755 --- a/core/assets/scripts/global.js +++ b/core/assets/scripts/global.js @@ -175,7 +175,6 @@ const SectorCaptureEvent = Packages.mindustry.game.EventType.SectorCaptureEvent const PlayerChatEvent = Packages.mindustry.game.EventType.PlayerChatEvent const MenuOptionChooseEvent = Packages.mindustry.game.EventType.MenuOptionChooseEvent const ClientPreConnectEvent = Packages.mindustry.game.EventType.ClientPreConnectEvent -const CommandIssueEvent = Packages.mindustry.game.EventType.CommandIssueEvent const SchematicCreateEvent = Packages.mindustry.game.EventType.SchematicCreateEvent const SectorLaunchEvent = Packages.mindustry.game.EventType.SectorLaunchEvent const LaunchItemEvent = Packages.mindustry.game.EventType.LaunchItemEvent diff --git a/core/src/mindustry/ai/formations/BoundedSlotAssignmentStrategy.java b/core/src/mindustry/ai/formations/BoundedSlotAssignmentStrategy.java deleted file mode 100644 index 62461bde31fa..000000000000 --- a/core/src/mindustry/ai/formations/BoundedSlotAssignmentStrategy.java +++ /dev/null @@ -1,44 +0,0 @@ -package mindustry.ai.formations; - - -import arc.struct.*; - -/** - * {@code BoundedSlotAssignmentStrategy} is an abstract implementation of {@link SlotAssignmentStrategy} that supports roles. - * Generally speaking, there are hard and soft roles. Hard roles cannot be broken, soft roles can. - *

- * This abstract class provides an implementation of the {@link #calculateNumberOfSlots(Seq) calculateNumberOfSlots} method that - * is more general (and costly) than the simplified implementation in {@link FreeSlotAssignmentStrategy}. It scans the assignment - * list to find the number of filled slots, which is the highest slot number in the assignments. - * @author davebaol - */ -public abstract class BoundedSlotAssignmentStrategy implements SlotAssignmentStrategy{ - - @Override - public abstract void updateSlotAssignments(Seq assignments); - - @Override - public int calculateNumberOfSlots(Seq assignments){ - // Find the number of filled slots: it will be the - // highest slot number in the assignments - int filledSlots = -1; - for(int i = 0; i < assignments.size; i++){ - SlotAssignment assignment = assignments.get(i); - if(assignment.slotNumber >= filledSlots) filledSlots = assignment.slotNumber; - } - - // Add one to go from the index of the highest slot to the number of slots needed. - return filledSlots + 1; - } - - @Override - public void removeSlotAssignment(Seq assignments, int index){ - int sn = assignments.get(index).slotNumber; - for(int i = 0; i < assignments.size; i++){ - SlotAssignment sa = assignments.get(i); - if(sa.slotNumber >= sn) sa.slotNumber--; - } - assignments.remove(index); - } - -} diff --git a/core/src/mindustry/ai/formations/DistanceAssignmentStrategy.java b/core/src/mindustry/ai/formations/DistanceAssignmentStrategy.java deleted file mode 100644 index 9713e668624c..000000000000 --- a/core/src/mindustry/ai/formations/DistanceAssignmentStrategy.java +++ /dev/null @@ -1,51 +0,0 @@ -package mindustry.ai.formations; - -import arc.math.*; -import arc.math.geom.*; -import arc.struct.*; - -public class DistanceAssignmentStrategy implements SlotAssignmentStrategy{ - private final Vec3 vec = new Vec3(); - private final FormationPattern form; - - public DistanceAssignmentStrategy(FormationPattern form){ - this.form = form; - } - - @Override - public void updateSlotAssignments(Seq assignments){ - IntSeq slots = IntSeq.range(0, assignments.size); - - for(SlotAssignment slot : assignments){ - int mindex = 0; - float mcost = Float.MAX_VALUE; - - for(int i = 0; i < slots.size; i++){ - float cost = cost(slot.member, slots.get(i)); - if(cost < mcost){ - mcost = cost; - mindex = i; - } - } - - slot.slotNumber = slots.get(mindex); - slots.removeIndex(mindex); - - } - } - - @Override - public int calculateNumberOfSlots(Seq assignments){ - return assignments.size; - } - - @Override - public void removeSlotAssignment(Seq assignments, int index){ - assignments.remove(index); - } - - float cost(FormationMember member, int slot){ - form.calculateSlotLocation(vec, slot); - return Mathf.dst2(member.formationPos().x, member.formationPos().y, vec.x, vec.y); - } -} diff --git a/core/src/mindustry/ai/formations/Formation.java b/core/src/mindustry/ai/formations/Formation.java deleted file mode 100644 index cbbb02a54145..000000000000 --- a/core/src/mindustry/ai/formations/Formation.java +++ /dev/null @@ -1,214 +0,0 @@ -package mindustry.ai.formations; - -import arc.math.*; -import arc.math.geom.*; -import arc.struct.*; - -/** - * A {@code Formation} coordinates the movement of a group of characters so that they retain some group organization. Characters - * belonging to a formation must implement the {@link FormationMember} interface. At its simplest, a formation can consist of - * moving in a fixed geometric pattern such as a V or line abreast, but it is not limited to that. Formations can also make use of - * the environment. Squads of characters can move between cover points using formation steering with only minor modifications, for - * example. - *

- * Formation motion is used in team sports games, squad-based games, real-time strategy games, and sometimes in first-person - * shooters, driving games, and action adventures too. It is a simple and flexible technique that is much quicker to write and - * execute and can produce much more stable behavior than collaborative tactical decision making. - * @author davebaol - */ -public class Formation{ - /** A list of slots assignments. */ - public Seq slotAssignments; - /** The anchor point of this formation. */ - public Vec3 anchor; - /** The formation pattern */ - public FormationPattern pattern; - /** The strategy used to assign a member to his slot */ - public SlotAssignmentStrategy slotAssignmentStrategy; - /** The formation motion moderator */ - public FormationMotionModerator motionModerator; - - private final Vec2 positionOffset; - private final Mat orientationMatrix = new Mat(); - - /** The location representing the drift offset for the currently filled slots. */ - private final Vec3 driftOffset; - - /** - * Creates a {@code Formation} for the specified {@code pattern} using a {@link FreeSlotAssignmentStrategy} and no motion - * moderator. - * @param anchor the anchor point of this formation, Cannot be {@code null}. - * @param pattern the pattern of this formation - * @throws IllegalArgumentException if the anchor point is {@code null} - */ - public Formation(Vec3 anchor, FormationPattern pattern){ - this(anchor, pattern, new FreeSlotAssignmentStrategy(), null); - } - - /** - * Creates a {@code Formation} for the specified {@code pattern} and {@code slotAssignmentStrategy} using no motion moderator. - * @param anchor the anchor point of this formation, Cannot be {@code null}. - * @param pattern the pattern of this formation - * @param slotAssignmentStrategy the strategy used to assign a member to his slot - * @throws IllegalArgumentException if the anchor point is {@code null} - */ - public Formation(Vec3 anchor, FormationPattern pattern, SlotAssignmentStrategy slotAssignmentStrategy){ - this(anchor, pattern, slotAssignmentStrategy, null); - } - - /** - * Creates a {@code Formation} for the specified {@code pattern}, {@code slotAssignmentStrategy} and {@code moderator}. - * @param anchor the anchor point of this formation, Cannot be {@code null}. - * @param pattern the pattern of this formation - * @param slotAssignmentStrategy the strategy used to assign a member to his slot - * @param motionModerator the motion moderator. Can be {@code null} if moderation is not needed - * @throws IllegalArgumentException if the anchor point is {@code null} - */ - public Formation(Vec3 anchor, FormationPattern pattern, SlotAssignmentStrategy slotAssignmentStrategy, - FormationMotionModerator motionModerator){ - if(anchor == null) throw new IllegalArgumentException("The anchor point cannot be null"); - this.anchor = anchor; - this.pattern = pattern; - this.slotAssignmentStrategy = slotAssignmentStrategy; - this.motionModerator = motionModerator; - - this.slotAssignments = new Seq<>(); - this.driftOffset = new Vec3(); - this.positionOffset = new Vec2(anchor.x, anchor.y).cpy(); - } - - /** Updates the assignment of members to slots */ - public void updateSlotAssignments(){ - pattern.slots = slotAssignments.size; - - // Apply the strategy to update slot assignments - slotAssignmentStrategy.updateSlotAssignments(slotAssignments); - - // Set the newly calculated number of slots - pattern.slots = slotAssignmentStrategy.calculateNumberOfSlots(slotAssignments); - - // Update the drift offset if a motion moderator is set - if(motionModerator != null) motionModerator.calculateDriftOffset(driftOffset, slotAssignments, pattern); - } - - /** - * Changes the pattern of this formation and updates slot assignments if the number of member is supported by the given - * pattern. - * @param pattern the pattern to set - * @return {@code true} if the pattern has effectively changed; {@code false} otherwise. - */ - public boolean changePattern(FormationPattern pattern){ - // Find out how many slots we have occupied - int occupiedSlots = slotAssignments.size; - - // Check if the pattern supports one more slot - if(pattern.supportsSlots(occupiedSlots)){ - this.pattern = pattern; - - // Update the slot assignments and return success - updateSlotAssignments(); - - return true; - } - - return false; - } - - /** Much more efficient than adding a single member. - * @return number of members added. */ - public int addMembers(Iterable members){ - int added = 0; - for(FormationMember member : members){ - if(pattern.supportsSlots(slotAssignments.size + 1)){ - slotAssignments.add(new SlotAssignment(member, slotAssignments.size)); - added ++; - } - } - - updateSlotAssignments(); - return added; - } - - /** - * Adds a new member to the first available slot and updates slot assignments if the number of member is supported by the - * current pattern. - * @param member the member to add - * @return {@code false} if no more slots are available; {@code true} otherwise. - */ - public boolean addMember(FormationMember member){ - // Check if the pattern supports one more slot - if(pattern.supportsSlots(slotAssignments.size + 1)){ - // Add a new slot assignment - slotAssignments.add(new SlotAssignment(member, slotAssignments.size)); - - // Update the slot assignments and return success - updateSlotAssignments(); - return true; - } - - return false; - } - - /** - * Removes a member from its slot and updates slot assignments. - * @param member the member to remove - */ - public void removeMember(FormationMember member){ - // Find the member's slot - int slot = findMemberSlot(member); - - // Make sure we've found a valid result - if(slot >= 0){ - // Remove the slot - // slotAssignments.removeIndex(slot); - slotAssignmentStrategy.removeSlotAssignment(slotAssignments, slot); - - // Update the assignments - updateSlotAssignments(); - } - } - - private int findMemberSlot(FormationMember member){ - for(int i = 0; i < slotAssignments.size; i++){ - if(slotAssignments.get(i).member == member) return i; - } - return -1; - } - - /** Writes new slot locations to each member */ - public void updateSlots(){ - positionOffset.set(anchor); - float orientationOffset = anchor.z; - if(motionModerator != null){ - positionOffset.sub(driftOffset); - orientationOffset -= driftOffset.z; - } - - // Get the orientation of the anchor point as a matrix - orientationMatrix.idt().rotate(anchor.z); - - // Go through each member in turn - for(int i = 0; i < slotAssignments.size; i++){ - SlotAssignment slotAssignment = slotAssignments.get(i); - - // Retrieve the location reference of the formation member to calculate the new value - Vec3 relativeLoc = slotAssignment.member.formationPos(); - float z = relativeLoc.z; - - // Ask for the location of the slot relative to the anchor point - pattern.calculateSlotLocation(relativeLoc, slotAssignment.slotNumber); - - // Transform it by the anchor point's position and orientation - relativeLoc.mul(orientationMatrix); - - // Add the anchor and drift components - relativeLoc.add(positionOffset.x, positionOffset.y, 0); - relativeLoc.z = z + orientationOffset; - } - - // Possibly reset the anchor point if a moderator is set - if(motionModerator != null){ - motionModerator.updateAnchorPoint(anchor); - } - } -} diff --git a/core/src/mindustry/ai/formations/FormationMember.java b/core/src/mindustry/ai/formations/FormationMember.java deleted file mode 100644 index 2fdf259f6274..000000000000 --- a/core/src/mindustry/ai/formations/FormationMember.java +++ /dev/null @@ -1,16 +0,0 @@ -package mindustry.ai.formations; - -import arc.math.geom.*; - -/** - * Game characters coordinated by a {@link Formation} must implement this interface. Any {@code FormationMember} has a target - * location which is the place where it should be in order to stay in formation. This target location is calculated by the - * formation itself. - * @author davebaol - */ -public interface FormationMember{ - /** Returns the target location of this formation member. */ - Vec3 formationPos(); - - float formationSize(); -} diff --git a/core/src/mindustry/ai/formations/FormationMotionModerator.java b/core/src/mindustry/ai/formations/FormationMotionModerator.java deleted file mode 100644 index 65e55951c90f..000000000000 --- a/core/src/mindustry/ai/formations/FormationMotionModerator.java +++ /dev/null @@ -1,52 +0,0 @@ -package mindustry.ai.formations; - -import arc.math.geom.*; -import arc.struct.*; - -/** - * A {@code FormationMotionModerator} moderates the movement of the formation based on the current positions of the members in its - * slots: in effect to keep the anchor point on a leash. If the members in the slots are having trouble reaching their targets, - * then the formation as a whole should be held back to give them a chance to catch up. - * @author davebaol - */ -public abstract class FormationMotionModerator{ - private Vec3 tempLocation; - - /** - * Update the anchor point to moderate formation motion. This method is called at each frame. - * @param anchor the anchor point - */ - public abstract void updateAnchorPoint(Vec3 anchor); - - /** - * Calculates the drift offset when members are in the given set of slots for the specified pattern. - * @param centerOfMass the output location set to the calculated drift offset - * @param slotAssignments the set of slots - * @param pattern the pattern - * @return the given location for chaining. - */ - public Vec3 calculateDriftOffset(Vec3 centerOfMass, Seq slotAssignments, FormationPattern pattern){ - // Clear the center of mass - centerOfMass.x = centerOfMass.y = 0; - float centerOfMassOrientation = 0; - - // Make sure tempLocation is instantiated - if(tempLocation == null) tempLocation = new Vec3(); - - // Go through each assignment and add its contribution to the center - float numberOfAssignments = slotAssignments.size; - for(int i = 0; i < numberOfAssignments; i++){ - pattern.calculateSlotLocation(tempLocation, slotAssignments.get(i).slotNumber); - centerOfMass.add(tempLocation); - centerOfMassOrientation += tempLocation.z; - } - - // Divide through to get the drift offset. - centerOfMass.scl(1f / numberOfAssignments); - centerOfMassOrientation /= numberOfAssignments; - centerOfMass.z = centerOfMassOrientation; - - return centerOfMass; - } - -} diff --git a/core/src/mindustry/ai/formations/FormationPattern.java b/core/src/mindustry/ai/formations/FormationPattern.java deleted file mode 100644 index 5fe84bcda924..000000000000 --- a/core/src/mindustry/ai/formations/FormationPattern.java +++ /dev/null @@ -1,29 +0,0 @@ -package mindustry.ai.formations; - -import arc.math.geom.*; - -/** - * The {@code FormationPattern} interface represents the shape of a formation and generates the slot offsets, relative to its - * anchor point. Since formations can be scalable the pattern must be able to determine if a given number of slots is supported. - *

- * Each particular pattern (such as a V, wedge, circle) needs its own instance of a class that implements this - * {@code FormationPattern} interface. - * @author davebaol - */ -public abstract class FormationPattern{ - public int slots; - /** Spacing between members. */ - public float spacing = 20f; - - /** Returns the location of the given slot index. */ - public abstract Vec3 calculateSlotLocation(Vec3 out, int slot); - - /** - * Returns true if the pattern can support the given number of slots - * @param slotCount the number of slots - * @return {@code true} if this pattern can support the given number of slots; {@code false} othervwise. - */ - public boolean supportsSlots(int slotCount){ - return true; - } -} diff --git a/core/src/mindustry/ai/formations/FreeSlotAssignmentStrategy.java b/core/src/mindustry/ai/formations/FreeSlotAssignmentStrategy.java deleted file mode 100644 index 89e51054d286..000000000000 --- a/core/src/mindustry/ai/formations/FreeSlotAssignmentStrategy.java +++ /dev/null @@ -1,34 +0,0 @@ -package mindustry.ai.formations; - - -import arc.struct.*; - -/** - * {@code FreeSlotAssignmentStrategy} is the simplest implementation of {@link SlotAssignmentStrategy}. It simply go through - * each assignment in the list and assign sequential slot numbers. The number of slots is just the length of the list. - *

- * Because each member can occupy any slot this implementation does not support roles. - * @author davebaol - */ -public class FreeSlotAssignmentStrategy implements SlotAssignmentStrategy{ - - @Override - public void updateSlotAssignments(Seq assignments){ - // A very simple assignment algorithm: we simply go through - // each assignment in the list and assign sequential slot numbers - for(int i = 0; i < assignments.size; i++){ - assignments.get(i).slotNumber = i; - } - } - - @Override - public int calculateNumberOfSlots(Seq assignments){ - return assignments.size; - } - - @Override - public void removeSlotAssignment(Seq assignments, int index){ - assignments.remove(index); - } - -} diff --git a/core/src/mindustry/ai/formations/SlotAssignment.java b/core/src/mindustry/ai/formations/SlotAssignment.java deleted file mode 100644 index c30cc6e22682..000000000000 --- a/core/src/mindustry/ai/formations/SlotAssignment.java +++ /dev/null @@ -1,29 +0,0 @@ -package mindustry.ai.formations; - - -/** - * A {@code SlotAssignment} instance represents the assignment of a single {@link FormationMember} to its slot in the - * {@link Formation}. - * @author davebaol - */ -public class SlotAssignment{ - public FormationMember member; - public int slotNumber; - - /** - * Creates a {@code SlotAssignment} for the given {@code member}. - * @param member the member of this slot assignment - */ - public SlotAssignment(FormationMember member){ - this(member, 0); - } - - /** - * Creates a {@code SlotAssignment} for the given {@code member} and {@code slotNumber}. - * @param member the member of this slot assignment - */ - public SlotAssignment(FormationMember member, int slotNumber){ - this.member = member; - this.slotNumber = slotNumber; - } -} diff --git a/core/src/mindustry/ai/formations/SlotAssignmentStrategy.java b/core/src/mindustry/ai/formations/SlotAssignmentStrategy.java deleted file mode 100644 index 2ccea7aa15a4..000000000000 --- a/core/src/mindustry/ai/formations/SlotAssignmentStrategy.java +++ /dev/null @@ -1,20 +0,0 @@ -package mindustry.ai.formations; - -import arc.struct.*; - -/** - * This interface defines how each {@link FormationMember} is assigned to a slot in the {@link Formation}. - * @author davebaol - */ -public interface SlotAssignmentStrategy{ - - /** Updates the assignment of members to slots */ - void updateSlotAssignments(Seq assignments); - - /** Calculates the number of slots from the assignment data. */ - int calculateNumberOfSlots(Seq assignments); - - /** Removes the slot assignment at the specified index. */ - void removeSlotAssignment(Seq assignments, int index); - -} diff --git a/core/src/mindustry/ai/formations/SoftRoleSlotAssignmentStrategy.java b/core/src/mindustry/ai/formations/SoftRoleSlotAssignmentStrategy.java deleted file mode 100644 index 59c933c20506..000000000000 --- a/core/src/mindustry/ai/formations/SoftRoleSlotAssignmentStrategy.java +++ /dev/null @@ -1,164 +0,0 @@ -package mindustry.ai.formations; - - -import arc.struct.*; -import arc.util.*; - -/** - * {@code SoftRoleSlotAssignmentStrategy} is a concrete implementation of {@link BoundedSlotAssignmentStrategy} that supports soft - * roles, i.e. roles that can be broken. Rather than a member having a list of roles it can fulfill, it has a set of values - * representing how difficult it would find it to fulfill every role. The value is known as the slot cost. To make a slot - * impossible for a member to fill, its slot cost should be infinite (you can even set a threshold to ignore all slots whose cost - * is too high; this will reduce computation time when several costs are exceeding). To make a slot ideal for a member, its slot - * cost should be zero. We can have different levels of unsuitable assignment for one member. - *

- * Slot costs do not necessarily have to depend only on the member and the slot roles. They can be generalized to include any - * difficulty a member might have in taking up a slot. If a formation is spread out, for example, a member may choose a slot that - * is close by over a more distant slot. Distance can be directly used as a slot cost. - *

- * IMPORTANVec2 NOTES: - *

- * @author davebaol - */ -public class SoftRoleSlotAssignmentStrategy extends BoundedSlotAssignmentStrategy{ - protected SlotCostProvider slotCostProvider; - protected float costThreshold; - private BoolSeq filledSlots; - - /** - * Creates a {@code SoftRoleSlotAssignmentStrategy} with the given slot cost provider and no cost threshold. - * @param slotCostProvider the slot cost provider - */ - public SoftRoleSlotAssignmentStrategy(SlotCostProvider slotCostProvider){ - this(slotCostProvider, Float.POSITIVE_INFINITY); - } - - /** - * Creates a {@code SoftRoleSlotAssignmentStrategy} with the given slot cost provider and cost threshold. - * @param slotCostProvider the slot cost provider - * @param costThreshold is a slot-cost limit, beyond which a slot is considered to be too expensive to consider occupying. - */ - public SoftRoleSlotAssignmentStrategy(SlotCostProvider slotCostProvider, float costThreshold){ - this.slotCostProvider = slotCostProvider; - this.costThreshold = costThreshold; - - this.filledSlots = new BoolSeq(); - } - - @Override - public void updateSlotAssignments(Seq assignments){ - // Holds a list of member and slot data for each member. - Seq memberData = new Seq<>(); - - // Compile the member data - int numberOfAssignments = assignments.size; - for(int i = 0; i < numberOfAssignments; i++){ - SlotAssignment assignment = assignments.get(i); - - // Create a new member datum, and fill it - MemberAndSlots datum = new MemberAndSlots(assignment.member); - - // Add each valid slot to it - for(int j = 0; j < numberOfAssignments; j++){ - - // Get the cost of the slot - float cost = slotCostProvider.getCost(assignment.member, j); - - // Make sure the slot is valid - if(cost >= costThreshold) continue; - - SlotAssignment slot = assignments.get(j); - - // Store the slot information - CostAndSlot slotDatum = new CostAndSlot(cost, slot.slotNumber); - datum.costAndSlots.add(slotDatum); - - // Add it to the member's ease of assignment - datum.assignmentEase += 1f / (1f + cost); - } - - // Add member datum - memberData.add(datum); - } - - // Reset the array to keep track of which slots we have already filled. - if(numberOfAssignments > filledSlots.size) filledSlots.ensureCapacity(numberOfAssignments - filledSlots.size); - filledSlots.size = numberOfAssignments; - for(int i = 0; i < numberOfAssignments; i++) - filledSlots.set(i, false); - - // Arrange members in order of ease of assignment, with the least easy first. - memberData.sort(); - MEMBER_LOOP: - for(int i = 0; i < memberData.size; i++){ - MemberAndSlots memberDatum = memberData.get(i); - - // Choose the first slot in the list that is still empty (non-filled) - memberDatum.costAndSlots.sort(); - int m = memberDatum.costAndSlots.size; - for(int j = 0; j < m; j++){ - int slotNumber = memberDatum.costAndSlots.get(j).slotNumber; - - // Check if this slot is valid - if(!filledSlots.get(slotNumber)){ - // Fill this slot - SlotAssignment slot = assignments.get(slotNumber); - slot.member = memberDatum.member; - slot.slotNumber = slotNumber; - - // Reserve the slot - filledSlots.set(slotNumber, true); - - // Go to the next member - continue MEMBER_LOOP; - } - } - - // If we reach here, it's because a member has no valid assignment. - // - // TODO - // Some sensible action should be taken, such as reporting to the player. - throw new ArcRuntimeException("SoftRoleSlotAssignmentStrategy cannot find valid slot assignment for member " + memberDatum.member); - } - } - - static class CostAndSlot implements Comparable{ - float cost; - int slotNumber; - - public CostAndSlot(float cost, int slotNumber){ - this.cost = cost; - this.slotNumber = slotNumber; - } - - @Override - public int compareTo(CostAndSlot other){ - return Float.compare(cost, other.cost); - } - } - - static class MemberAndSlots implements Comparable{ - FormationMember member; - float assignmentEase; - Seq costAndSlots; - - public MemberAndSlots(FormationMember member){ - this.member = member; - this.assignmentEase = 0f; - this.costAndSlots = new Seq<>(); - } - - @Override - public int compareTo(MemberAndSlots other){ - return Float.compare(assignmentEase, other.assignmentEase); - } - } - - public interface SlotCostProvider{ - float getCost(FormationMember member, int slotNumber); - } -} diff --git a/core/src/mindustry/ai/formations/patterns/CircleFormation.java b/core/src/mindustry/ai/formations/patterns/CircleFormation.java deleted file mode 100644 index d905f40ea355..000000000000 --- a/core/src/mindustry/ai/formations/patterns/CircleFormation.java +++ /dev/null @@ -1,22 +0,0 @@ -package mindustry.ai.formations.patterns; - -import arc.math.*; -import arc.math.geom.*; -import mindustry.ai.formations.*; - -public class CircleFormation extends FormationPattern{ - - @Override - public Vec3 calculateSlotLocation(Vec3 outLocation, int slotNumber){ - if(slots > 1){ - float angle = (360f * slotNumber) / slots + (slots == 8 ? 22.5f : 0); - float radius = spacing / (float)Math.sin(180f / slots * Mathf.degRad); - outLocation.set(Angles.trnsx(angle, radius), Angles.trnsy(angle, radius), angle); - }else{ - outLocation.set(0, spacing * 1.1f, 360f * slotNumber); - } - - return outLocation; - } - -} diff --git a/core/src/mindustry/ai/formations/patterns/SquareFormation.java b/core/src/mindustry/ai/formations/patterns/SquareFormation.java deleted file mode 100644 index 9d7ddab549e8..000000000000 --- a/core/src/mindustry/ai/formations/patterns/SquareFormation.java +++ /dev/null @@ -1,25 +0,0 @@ -package mindustry.ai.formations.patterns; - -import arc.math.*; -import arc.math.geom.*; -import mindustry.ai.formations.*; - -public class SquareFormation extends FormationPattern{ - - @Override - public Vec3 calculateSlotLocation(Vec3 out, int slot){ - //side of each square of formation - int side = Mathf.ceil(Mathf.sqrt(slots + 1)); - int cx = slot % side, cy = slot / side; - - //don't hog the middle spot - if(cx == side /2 && cy == side/2 && (side%2)==1){ - slot = slots; - - cx = slot % side; - cy = slot / side; - } - - return out.set(cx - (side/2f - 0.5f), cy - (side/2f - 0.5f), 0).scl(spacing); - } -} diff --git a/core/src/mindustry/ai/types/DefenderAI.java b/core/src/mindustry/ai/types/DefenderAI.java index 528f2baec2af..c7db9e788052 100644 --- a/core/src/mindustry/ai/types/DefenderAI.java +++ b/core/src/mindustry/ai/types/DefenderAI.java @@ -28,12 +28,9 @@ public void updateTargeting(){ @Override public Teamc findTarget(float x, float y, float range, boolean air, boolean ground){ - //find unit to follow if not in rally mode - if(command() != UnitCommand.rally){ - //Sort by max health and closer target. - var result = Units.closest(unit.team, x, y, Math.max(range, 400f), u -> !u.dead() && u.type != unit.type, (u, tx, ty) -> -u.maxHealth + Mathf.dst2(u.x, u.y, tx, ty) / 6400f); - if(result != null) return result; - } + //Sort by max health and closer target. + var result = Units.closest(unit.team, x, y, Math.max(range, 400f), u -> !u.dead() && u.type != unit.type, (u, tx, ty) -> -u.maxHealth + Mathf.dst2(u.x, u.y, tx, ty) / 6400f); + if(result != null) return result; //find rally point var block = targetFlag(unit.x, unit.y, BlockFlag.rally, false); diff --git a/core/src/mindustry/ai/types/FlyingAI.java b/core/src/mindustry/ai/types/FlyingAI.java index 4c1b960592ca..a22a708c0d40 100644 --- a/core/src/mindustry/ai/types/FlyingAI.java +++ b/core/src/mindustry/ai/types/FlyingAI.java @@ -14,7 +14,7 @@ public class FlyingAI extends AIController{ public void updateMovement(){ unloadPayloads(); - if(target != null && unit.hasWeapons() && command() == UnitCommand.attack){ + if(target != null && unit.hasWeapons()){ if(!unit.type.circleTarget){ moveTo(target, unit.type.range * 0.8f); unit.lookAt(target); @@ -23,13 +23,9 @@ public void updateMovement(){ } } - if(target == null && command() == UnitCommand.attack && state.rules.waves && unit.team == state.rules.defaultTeam){ + if(target == null && state.rules.waves && unit.team == state.rules.defaultTeam){ moveTo(getClosestSpawner(), state.rules.dropZoneRadius + 130f); } - - if(command() == UnitCommand.rally){ - moveTo(targetFlag(unit.x, unit.y, BlockFlag.rally, false), 60f); - } } @Override diff --git a/core/src/mindustry/ai/types/FormationAI.java b/core/src/mindustry/ai/types/FormationAI.java deleted file mode 100644 index 6ef6dd8d3a6a..000000000000 --- a/core/src/mindustry/ai/types/FormationAI.java +++ /dev/null @@ -1,105 +0,0 @@ -package mindustry.ai.types; - -import arc.math.*; -import arc.math.geom.*; -import arc.util.*; -import mindustry.ai.formations.*; -import mindustry.entities.units.*; -import mindustry.gen.*; -import mindustry.world.blocks.storage.CoreBlock.*; - -public class FormationAI extends AIController implements FormationMember{ - public Unit leader; - - private Vec3 target = new Vec3(); - private @Nullable Formation formation; - - public FormationAI(Unit leader, Formation formation){ - this.leader = leader; - this.formation = formation; - } - - @Override - public void init(){ - target.set(unit.x, unit.y, 0); - } - - @Override - public void updateUnit(){ - - if(leader == null || leader.dead){ - unit.resetController(); - return; - } - - if(unit.type.canBoost){ - unit.elevation = Mathf.approachDelta(unit.elevation, - unit.onSolid() ? 1f : //definitely cannot land - unit.isFlying() && !unit.canLand() ? unit.elevation : //try to maintain altitude - leader.type.canBoost ? leader.elevation : //follow leader - 0f, - unit.type.riseSpeed); - } - - unit.controlWeapons(true, leader.isShooting); - - unit.aim(leader.aimX(), leader.aimY()); - - if(unit.type.rotateShooting){ - unit.lookAt(leader.aimX(), leader.aimY()); - }else if(unit.moving()){ - unit.lookAt(unit.vel.angle()); - } - - Vec2 realtarget = vec.set(target).add(leader.vel); - - float speed = unit.speed() * Time.delta; - unit.approach(Mathf.arrive(unit.x, unit.y, realtarget.x, realtarget.y, unit.vel, speed, 0f, speed, 1f).scl(1f / Time.delta)); - - if(unit.canMine() && leader.canMine()){ - if(leader.mineTile != null && unit.validMine(leader.mineTile)){ - unit.mineTile(leader.mineTile); - - CoreBuild core = unit.team.core(); - - if(core != null && leader.mineTile.drop() != null && unit.within(core, unit.type.range) && !unit.acceptsItem(leader.mineTile.drop())){ - if(core.acceptStack(unit.stack.item, unit.stack.amount, unit) > 0){ - Call.transferItemTo(unit, unit.stack.item, unit.stack.amount, unit.x, unit.y, core); - - unit.clearItem(); - } - } - }else{ - unit.mineTile(null); - } - } - - if(unit.canBuild() && leader.canBuild() && leader.activelyBuilding()){ - unit.clearBuilding(); - unit.addBuild(leader.buildPlan()); - } - } - - @Override - public void removed(Unit unit){ - if(formation != null){ - formation.removeMember(this); - unit.resetController(); - } - } - - @Override - public float formationSize(){ - return unit.hitSize * 1.3f; - } - - @Override - public boolean isBeingControlled(Unit player){ - return leader == player; - } - - @Override - public Vec3 formationPos(){ - return target; - } -} diff --git a/core/src/mindustry/ai/types/GroundAI.java b/core/src/mindustry/ai/types/GroundAI.java index 80c5da653acd..602ceaea7c3b 100644 --- a/core/src/mindustry/ai/types/GroundAI.java +++ b/core/src/mindustry/ai/types/GroundAI.java @@ -5,7 +5,6 @@ import mindustry.entities.units.*; import mindustry.gen.*; import mindustry.world.*; -import mindustry.world.meta.*; import static mindustry.Vars.*; @@ -25,7 +24,7 @@ public void updateMovement(){ } } - if((core == null || !unit.within(core, unit.type.range * 0.5f)) && command() == UnitCommand.attack){ + if((core == null || !unit.within(core, unit.type.range * 0.5f))){ boolean move = true; if(state.rules.waves && unit.team == state.rules.defaultTeam){ @@ -42,14 +41,6 @@ public void updateMovement(){ if(move) pathfind(Pathfinder.fieldCore); } - if(command() == UnitCommand.rally){ - Teamc target = targetFlag(unit.x, unit.y, BlockFlag.rally, false); - - if(target != null && !unit.within(target, 70f)){ - pathfind(Pathfinder.fieldRally); - } - } - if(unit.type.canBoost && unit.elevation > 0.001f && !unit.onSolid()){ unit.elevation = Mathf.approachDelta(unit.elevation, 0f, unit.type.riseSpeed); } diff --git a/core/src/mindustry/ai/types/HugAI.java b/core/src/mindustry/ai/types/HugAI.java index 70d2bce36ef8..633f083c4736 100644 --- a/core/src/mindustry/ai/types/HugAI.java +++ b/core/src/mindustry/ai/types/HugAI.java @@ -8,7 +8,6 @@ import mindustry.entities.units.*; import mindustry.gen.*; import mindustry.world.*; -import mindustry.world.meta.*; import static mindustry.Vars.*; @@ -28,41 +27,31 @@ public void updateMovement(){ } } - if(command() == UnitCommand.attack){ - boolean move = true; + boolean move = true; - if(state.rules.waves && unit.team == state.rules.defaultTeam){ - Tile spawner = getClosestSpawner(); - if(spawner != null && unit.within(spawner, state.rules.dropZoneRadius + 120f)) move = false; - } + if(state.rules.waves && unit.team == state.rules.defaultTeam){ + Tile spawner = getClosestSpawner(); + if(spawner != null && unit.within(spawner, state.rules.dropZoneRadius + 120f)) move = false; + } - //raycast for target - if(target != null && unit.within(target, unit.type.range) && !Vars.world.raycast(unit.tileX(), unit.tileY(), target.tileX(), target.tileY(), (x, y) -> { - for(Point2 p : Geometry.d4c){ - if(!unit.canPass(x + p.x, y + p.y)){ - return true; - } - } - return false; - })){ - if(unit.within(target, (unit.hitSize + (target instanceof Sized s ? s.hitSize() : 1f)) * 0.6f)){ - //circle target - unit.movePref(vec.set(target).sub(unit).rotate(90f).setLength(unit.speed())); - }else{ - //move toward target in a straight line - unit.movePref(vec.set(target).sub(unit).limit(unit.speed())); + //raycast for target + if(target != null && unit.within(target, unit.type.range) && !Vars.world.raycast(unit.tileX(), unit.tileY(), target.tileX(), target.tileY(), (x, y) -> { + for(Point2 p : Geometry.d4c){ + if(!unit.canPass(x + p.x, y + p.y)){ + return true; } - }else if(move){ - pathfind(Pathfinder.fieldCore); } - } - - if(command() == UnitCommand.rally){ - Teamc target = targetFlag(unit.x, unit.y, BlockFlag.rally, false); - - if(target != null && !unit.within(target, 70f)){ - pathfind(Pathfinder.fieldRally); + return false; + })){ + if(unit.within(target, (unit.hitSize + (target instanceof Sized s ? s.hitSize() : 1f)) * 0.6f)){ + //circle target + unit.movePref(vec.set(target).sub(unit).rotate(90f).setLength(unit.speed())); + }else{ + //move toward target in a straight line + unit.movePref(vec.set(target).sub(unit).limit(unit.speed())); } + }else if(move){ + pathfind(Pathfinder.fieldCore); } if(unit.type.canBoost && unit.elevation > 0.001f && !unit.onSolid()){ diff --git a/core/src/mindustry/ai/types/LogicAI.java b/core/src/mindustry/ai/types/LogicAI.java index bd5899f48ec9..c74a6edbf411 100644 --- a/core/src/mindustry/ai/types/LogicAI.java +++ b/core/src/mindustry/ai/types/LogicAI.java @@ -8,7 +8,6 @@ import mindustry.gen.*; import mindustry.logic.*; import mindustry.world.*; -import mindustry.world.meta.*; import static mindustry.Vars.*; @@ -72,7 +71,7 @@ public void updateMovement(){ case pathfind -> { Building core = unit.closestEnemyCore(); - if((core == null || !unit.within(core, unit.range() * 0.5f)) && command() == UnitCommand.attack){ + if((core == null || !unit.within(core, unit.range() * 0.5f))){ boolean move = true; if(state.rules.waves && unit.team == state.rules.defaultTeam){ @@ -82,14 +81,6 @@ public void updateMovement(){ if(move) pathfind(Pathfinder.fieldCore); } - - if(command() == UnitCommand.rally){ - Teamc target = targetFlag(unit.x, unit.y, BlockFlag.rally, false); - - if(target != null && !unit.within(target, 70f)){ - pathfind(Pathfinder.fieldRally); - } - } } case stop -> { unit.clearBuilding(); diff --git a/core/src/mindustry/ai/types/SuicideAI.java b/core/src/mindustry/ai/types/SuicideAI.java index dc452909327a..7b07f784b305 100644 --- a/core/src/mindustry/ai/types/SuicideAI.java +++ b/core/src/mindustry/ai/types/SuicideAI.java @@ -4,7 +4,6 @@ import mindustry.*; import mindustry.ai.*; import mindustry.entities.*; -import mindustry.entities.units.*; import mindustry.gen.*; import mindustry.world.*; import mindustry.world.blocks.distribution.*; @@ -77,26 +76,18 @@ public void updateUnit(){ } if(!moveToTarget){ - if(command() == UnitCommand.rally){ - Teamc target = targetFlag(unit.x, unit.y, BlockFlag.rally, false); + boolean move = true; - if(target != null && !unit.within(target, 70f)){ - pathfind(Pathfinder.fieldRally); - } - }else if(command() == UnitCommand.attack){ - boolean move = true; - - //stop moving toward the drop zone if applicable - if(core == null && state.rules.waves && unit.team == state.rules.defaultTeam){ - Tile spawner = getClosestSpawner(); - if(spawner != null && unit.within(spawner, state.rules.dropZoneRadius + 120f)){ - move = false; - } + //stop moving toward the drop zone if applicable + if(core == null && state.rules.waves && unit.team == state.rules.defaultTeam){ + Tile spawner = getClosestSpawner(); + if(spawner != null && unit.within(spawner, state.rules.dropZoneRadius + 120f)){ + move = false; } + } - if(move){ - pathfind(Pathfinder.fieldCore); - } + if(move){ + pathfind(Pathfinder.fieldCore); } } diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index c60d11f2437c..102b376969dd 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -130,7 +130,6 @@ public class Blocks{ breach, sublimate, titan, disperse, afflict, //units - commandCenter, groundFactory, airFactory, navalFactory, additiveReconstructor, multiplicativeReconstructor, exponentialReconstructor, tetrativeReconstructor, repairPoint, repairTurret, @@ -853,7 +852,7 @@ public static void load(){ size = 2; hasItems = true; - consumes.item(Items.coal, 2); + consumeItem(Items.coal, 2); }}; multiPress = new GenericCrafter("multi-press"){{ @@ -868,9 +867,9 @@ public static void load(){ hasLiquids = true; hasPower = true; - consumes.power(1.8f); - consumes.item(Items.coal, 3); - consumes.liquid(Liquids.water, 0.1f); + consumePower(1.8f); + consumeItem(Items.coal, 3); + consumeLiquid(Liquids.water, 0.1f); }}; siliconSmelter = new GenericCrafter("silicon-smelter"){{ @@ -885,8 +884,8 @@ public static void load(){ ambientSound = Sounds.smelter; ambientSoundVolume = 0.07f; - consumes.items(with(Items.coal, 1, Items.sand, 2)); - consumes.power(0.50f); + consumeItems(with(Items.coal, 1, Items.sand, 2)); + consumePower(0.50f); }}; siliconCrucible = new AttributeCrafter("silicon-crucible"){{ @@ -903,8 +902,8 @@ public static void load(){ ambientSound = Sounds.smelter; ambientSoundVolume = 0.07f; - consumes.items(with(Items.coal, 4, Items.sand, 6, Items.pyratite, 1)); - consumes.power(4f); + consumeItems(with(Items.coal, 4, Items.sand, 6, Items.pyratite, 1)); + consumePower(4f); }}; siliconArcFurnace = new GenericCrafter("silicon-arc-furnace"){{ @@ -920,8 +919,8 @@ public static void load(){ itemCapacity = 30; drawer = new DrawArcSmelter(); - consumes.items(with(Items.graphite, 1, Items.sand, 4)); - consumes.power(6f); + consumeItems(with(Items.graphite, 1, Items.sand, 4)); + consumePower(6f); }}; kiln = new GenericCrafter("kiln"){{ @@ -935,8 +934,8 @@ public static void load(){ ambientSound = Sounds.smelter; ambientSoundVolume = 0.07f; - consumes.items(with(Items.lead, 1, Items.sand, 1)); - consumes.power(0.60f); + consumeItems(with(Items.lead, 1, Items.sand, 1)); + consumePower(0.60f); }}; plastaniumCompressor = new GenericCrafter("plastanium-compressor"){{ @@ -952,9 +951,9 @@ public static void load(){ updateEffect = Fx.plasticburn; drawer = new DrawGlow(); - consumes.liquid(Liquids.oil, 0.25f); - consumes.power(3f); - consumes.item(Items.titanium, 2); + consumeLiquid(Liquids.oil, 0.25f); + consumePower(3f); + consumeItem(Items.titanium, 2); }}; phaseWeaver = new GenericCrafter("phase-weaver"){{ @@ -970,8 +969,8 @@ public static void load(){ ambientSound = Sounds.techloop; ambientSoundVolume = 0.02f; - consumes.items(with(Items.thorium, 4, Items.sand, 10)); - consumes.power(5f); + consumeItems(with(Items.thorium, 4, Items.sand, 10)); + consumePower(5f); itemCapacity = 20; }}; @@ -985,8 +984,8 @@ public static void load(){ itemCapacity = 20; drawer = new DrawSmelter(); - consumes.power(4f); - consumes.items(with(Items.copper, 3, Items.lead, 4, Items.titanium, 2, Items.silicon, 3)); + consumePower(4f); + consumeItems(with(Items.copper, 3, Items.lead, 4, Items.titanium, 2, Items.silicon, 3)); }}; cryofluidMixer = new LiquidConverter("cryofluid-mixer"){{ @@ -1003,9 +1002,9 @@ public static void load(){ envEnabled = Env.any; drawer = new DrawMixer(true); - consumes.power(1f); - consumes.item(Items.titanium); - consumes.liquid(Liquids.water, 0.2f); + consumePower(1f); + consumeItem(Items.titanium); + consumeLiquid(Liquids.water, 0.2f); }}; pyratiteMixer = new GenericCrafter("pyratite-mixer"){{ @@ -1017,8 +1016,8 @@ public static void load(){ size = 2; - consumes.power(0.20f); - consumes.items(with(Items.coal, 1, Items.lead, 2, Items.sand, 2)); + consumePower(0.20f); + consumeItems(with(Items.coal, 1, Items.lead, 2, Items.sand, 2)); }}; blastMixer = new GenericCrafter("blast-mixer"){{ @@ -1029,8 +1028,8 @@ public static void load(){ size = 2; envEnabled |= Env.space; - consumes.items(with(Items.pyratite, 1, Items.sporePod, 1)); - consumes.power(0.40f); + consumeItems(with(Items.pyratite, 1, Items.sporePod, 1)); + consumePower(0.40f); }}; melter = new GenericCrafter("melter"){{ @@ -1039,10 +1038,12 @@ public static void load(){ outputLiquid = new LiquidStack(Liquids.slag, 2f); craftTime = 10f; hasLiquids = hasPower = true; - drawer = new DrawLiquid(); + drawer = new DrawLiquid(){{ + liquidDrawn = Liquids.slag; + }}; - consumes.power(1f); - consumes.item(Items.scrap, 1); + consumePower(1f); + consumeItem(Items.scrap, 1); }}; separator = new Separator("separator"){{ @@ -1057,8 +1058,8 @@ public static void load(){ craftTime = 35f; size = 2; - consumes.power(1.1f); - consumes.liquid(Liquids.slag, 4f / 60f); + consumePower(1.1f); + consumeLiquid(Liquids.slag, 4f / 60f); }}; disassembler = new Separator("disassembler"){{ @@ -1074,9 +1075,9 @@ public static void load(){ size = 3; itemCapacity = 20; - consumes.power(4f); - consumes.item(Items.scrap); - consumes.liquid(Liquids.slag, 0.12f); + consumePower(4f); + consumeItem(Items.scrap); + consumeLiquid(Liquids.slag, 0.12f); }}; sporePress = new GenericCrafter("spore-press"){{ @@ -1091,8 +1092,8 @@ public static void load(){ craftEffect = Fx.none; drawer = new DrawAnimation(); - consumes.item(Items.sporePod, 1); - consumes.power(0.7f); + consumeItem(Items.sporePod, 1); + consumePower(0.7f); }}; pulverizer = new GenericCrafter("pulverizer"){{ @@ -1108,8 +1109,8 @@ public static void load(){ ambientSound = Sounds.grinding; ambientSoundVolume = 0.025f; - consumes.item(Items.scrap, 1); - consumes.power(0.50f); + consumeItem(Items.scrap, 1); + consumePower(0.50f); }}; coalCentrifuge = new GenericCrafter("coal-centrifuge"){{ @@ -1121,15 +1122,15 @@ public static void load(){ hasPower = hasItems = hasLiquids = true; rotateDraw = false; - consumes.liquid(Liquids.oil, 0.1f); - consumes.power(0.7f); + consumeLiquid(Liquids.oil, 0.1f); + consumePower(0.7f); }}; incinerator = new Incinerator("incinerator"){{ requirements(Category.crafting, with(Items.graphite, 5, Items.lead, 15)); health = 90; envEnabled |= Env.space; - consumes.power(0.50f); + consumePower(0.50f); }}; //TODO better name @@ -1143,8 +1144,8 @@ public static void load(){ liquidCapacity = 50f; - consumes.liquid(Liquids.water, 10f / 60f); - consumes.power(1f); + consumeLiquid(Liquids.water, 10f / 60f); + consumePower(1f); drawer = new DrawMulti( new DrawRegion("-bottom"), @@ -1191,7 +1192,7 @@ public static void load(){ researchCostMultiplier = 1.1f; liquidCapacity = 40f; - consumes.power(2f); + consumePower(2f); heatRequirement = 6f; @@ -1206,9 +1207,9 @@ public static void load(){ outputItem = new ItemStack(Items.oxide, 1); researchCostMultiplier = 1.1f; - consumes.liquid(Liquids.ozone, 2f / 60f); - consumes.item(Items.beryllium); - consumes.power(0.5f); + consumeLiquid(Liquids.ozone, 2f / 60f); + consumeItem(Items.beryllium); + consumePower(0.5f); rotateDraw = false; @@ -1231,7 +1232,7 @@ public static void load(){ drawer.iconOverride = new String[]{""}; size = 2; heatOutput = 3f; - consumes.power(50f / 60f); + consumePower(50f / 60f); }}; phaseHeater = new HeatProducer("phase-heater"){{ @@ -1242,8 +1243,8 @@ public static void load(){ size = 2; heatOutput = 10f; craftTime = 60f * 8f; - consumes.item(Items.phaseFabric); - consumes.power(0.5f / 60f); + consumeItem(Items.phaseFabric); + consumePower(0.5f / 60f); }}; heatRedirector = new HeatConductor("heat-redirector"){{ @@ -1258,7 +1259,7 @@ public static void load(){ slagIncinerator = new ItemIncinerator("slag-incinerator"){{ requirements(Category.crafting, with(Items.tungsten, 15)); size = 1; - consumes.liquid(Liquids.slag, 2f / 60f); + consumeLiquid(Liquids.slag, 2f / 60f); }}; carbideCrucible = new HeatCrafter("carbide-crucible"){{ @@ -1276,18 +1277,18 @@ public static void load(){ heatRequirement = 10f; - consumes.items(with(Items.tungsten, 2, Items.graphite, 3)); - consumes.power(2f); + consumeItems(with(Items.tungsten, 2, Items.graphite, 3)); + consumePower(2f); }}; slagCentrifuge = new GenericCrafter("slag-centrifuge"){{ requirements(Category.crafting, with(Items.carbide, 70, Items.graphite, 60, Items.silicon, 40, Items.oxide, 40)); - consumes.power(2f / 60f); + consumePower(2f / 60f); size = 3; - consumes.item(Items.sand, 1); - consumes.liquid(Liquids.slag, 40f / 60f); + consumeItem(Items.sand, 1); + consumeLiquid(Liquids.slag, 40f / 60f); liquidCapacity = 80f; var drawers = Seq.with(new DrawRegion("-bottom"), new DrawLiquidRegion(Liquids.slag){{ alpha = 0.7f; }}); @@ -1344,11 +1345,11 @@ public static void load(){ }}); drawer.iconOverride = new String[]{"-bottom", ""}; - consumes.item(Items.silicon, 3); + consumeItem(Items.silicon, 3); //TODO must consume from 2 pumps, 1, or 1.5? //TODO consume hydrogen/ozone? - consumes.liquid(Liquids.slag, 80f / 60f); - consumes.power(2f); //TODO necessary? + consumeLiquid(Liquids.slag, 80f / 60f); + consumePower(2f); //TODO necessary? }}; cyanogenSynthesizer = new HeatCrafter("cyanogen-synthesizer"){{ @@ -1377,9 +1378,9 @@ public static void load(){ outputLiquid = new LiquidStack(Liquids.cyanogen, 3f); craftTime = 60f * 1f; - consumes.liquids(LiquidStack.with(Liquids.hydrogen, 3f / 60f, Liquids.nitrogen, 2f / 60f)); - consumes.item(Items.graphite); - consumes.power(2f); + consumeLiquids(LiquidStack.with(Liquids.hydrogen, 3f / 60f, Liquids.nitrogen, 2f / 60f)); + consumeItem(Items.graphite); + consumePower(2f); }}; //TODO bad name, and there's no use for phase yet... @@ -1412,9 +1413,9 @@ public static void load(){ }}); drawer.iconOverride = new String[]{"-bottom", "-weave", ""}; - consumes.items(with(Items.thorium, 2, Items.sand, 6)); - consumes.liquid(Liquids.ozone, 2f / 60f); - consumes.power(8f); + consumeItems(with(Items.thorium, 2, Items.sand, 6)); + consumeLiquid(Liquids.ozone, 2f / 60f); + consumePower(8f); }}; heatReactor = new HeatProducer("heat-reactor"){{ @@ -1425,8 +1426,8 @@ public static void load(){ craftEffect = new RadialEffect(Fx.heatReactorSmoke, 4, 90f, 7f); itemCapacity = 20; - consumes.item(Items.thorium, 3); - consumes.liquid(Liquids.nitrogen, 1f / 60f); + consumeItem(Items.thorium, 3); + consumeLiquid(Liquids.nitrogen, 1f / 60f); outputItem = new ItemStack(Items.fissileMatter, 1); }}; @@ -1619,7 +1620,7 @@ public static void load(){ mender = new MendProjector("mender"){{ requirements(Category.effect, with(Items.lead, 30, Items.copper, 25)); - consumes.power(0.3f); + consumePower(0.3f); size = 1; reload = 200f; range = 40f; @@ -1627,37 +1628,37 @@ public static void load(){ phaseBoost = 4f; phaseRangeBoost = 20f; health = 80; - consumes.item(Items.silicon).boost(); + consumeItem(Items.silicon).boost(); }}; mendProjector = new MendProjector("mend-projector"){{ requirements(Category.effect, with(Items.lead, 100, Items.titanium, 25, Items.silicon, 40, Items.copper, 50)); - consumes.power(1.5f); + consumePower(1.5f); size = 2; reload = 250f; range = 85f; healPercent = 11f; phaseBoost = 15f; scaledHealth = 80; - consumes.item(Items.phaseFabric).boost(); + consumeItem(Items.phaseFabric).boost(); }}; overdriveProjector = new OverdriveProjector("overdrive-projector"){{ requirements(Category.effect, with(Items.lead, 100, Items.titanium, 75, Items.silicon, 75, Items.plastanium, 30)); - consumes.power(3.50f); + consumePower(3.50f); size = 2; - consumes.item(Items.phaseFabric).boost(); + consumeItem(Items.phaseFabric).boost(); }}; overdriveDome = new OverdriveProjector("overdrive-dome"){{ requirements(Category.effect, with(Items.lead, 200, Items.titanium, 130, Items.silicon, 130, Items.plastanium, 80, Items.surgeAlloy, 120)); - consumes.power(10f); + consumePower(10f); size = 3; range = 200f; speedBoost = 2.5f; useTime = 300f; hasBoost = false; - consumes.items(with(Items.phaseFabric, 1, Items.silicon, 1)); + consumeItems(with(Items.phaseFabric, 1, Items.silicon, 1)); }}; forceProjector = new ForceProjector("force-projector"){{ @@ -1670,8 +1671,8 @@ public static void load(){ cooldownLiquid = 1.2f; cooldownBrokenBase = 0.35f; - consumes.item(Items.phaseFabric).boost(); - consumes.power(4f); + boostConsumer = consumeItem(Items.phaseFabric).boost(); + consumePower(4f); }}; shockMine = new ShockMine("shock-mine"){{ @@ -1687,7 +1688,7 @@ public static void load(){ buildTower = new BuildTurret("build-tower"){{ requirements(Category.effect, with(Items.silicon, 80, Items.carbide, 30, Items.oxide, 40, Items.thorium, 30)); outlineColor = Pal.darkOutline; - consumes.power(3f); + consumePower(3f); range = 160f; size = 3; buildSpeed = 1.5f; @@ -1696,13 +1697,13 @@ public static void load(){ regenProjector = new RegenProjector("regen-projector"){{ requirements(Category.effect, with(Items.silicon, 80, Items.tungsten, 60, Items.oxide, 40, Items.beryllium, 80)); size = 3; - consumes.power(1f); + consumePower(1f); range = 28; baseColor = Pal.regen; - consumes.liquid(Liquids.hydrogen, 1f / 60f); + consumeLiquid(Liquids.hydrogen, 1f / 60f); - consumes.item(Items.phaseFabric).boost(); + consumeItem(Items.phaseFabric).boost(); healPercent = 4f / 60f; @@ -1733,7 +1734,7 @@ public static void load(){ cooldownNormal = 3f; cooldownBrokenBase = 0.35f; - consumes.power(4f); + consumePower(4f); }}; //TODO 5x5?? @@ -1742,7 +1743,7 @@ public static void load(){ size = 3; - consumes.power(5f); + consumePower(5f); }}; largeShieldProjector = new BaseShield("large-shield-projector"){{ @@ -1751,7 +1752,7 @@ public static void load(){ size = 4; radius = 400f; - consumes.power(5f); + consumePower(5f); }}; //endregion @@ -1811,7 +1812,7 @@ public static void load(){ hasPower = true; pulse = true; envEnabled |= Env.space; - consumes.power(0.30f); + consumePower(0.30f); }}; sorter = new Sorter("sorter"){{ @@ -1853,7 +1854,7 @@ public static void load(){ itemCapacity = 120; reloadTime = 200f; range = 440f; - consumes.power(1.75f); + consumePower(1.75f); }}; //erekir transport blocks @@ -1897,7 +1898,7 @@ public static void load(){ consumesPower = true; conductivePower = true; baseEfficiency = 1f; - consumes.power(1f / 60f); + consumePower(1f / 60f); }}; surgeRouter = new StackRouter("surge-router"){{ @@ -1909,7 +1910,7 @@ public static void load(){ consumesPower = true; conductivePower = true; baseEfficiency = 1f; - consumes.power(3f / 60f); + consumePower(3f / 60f); }}; unitCargoLoader = new UnitCargoLoader("unit-cargo-loader"){{ @@ -1917,7 +1918,7 @@ public static void load(){ size = 3; - consumes.power(4f / 60f); + consumePower(4f / 60f); itemCapacity = 200; }}; @@ -1941,7 +1942,7 @@ public static void load(){ rotaryPump = new Pump("rotary-pump"){{ requirements(Category.liquid, with(Items.copper, 70, Items.metaglass, 50, Items.silicon, 20, Items.titanium, 35)); pumpAmount = 0.2f; - consumes.power(0.3f); + consumePower(0.3f); liquidCapacity = 30f; hasPower = true; size = 2; @@ -1950,7 +1951,7 @@ public static void load(){ impulsePump = new Pump("impulse-pump"){{ requirements(Category.liquid, with(Items.copper, 80, Items.metaglass, 90, Items.silicon, 30, Items.titanium, 40, Items.thorium, 35)); pumpAmount = 0.22f; - consumes.power(1.3f); + consumePower(1.3f); liquidCapacity = 40f; hasPower = true; size = 3; @@ -2016,7 +2017,7 @@ public static void load(){ hasPower = true; canOverdrive = false; pulse = true; - consumes.power(0.30f); + consumePower(0.30f); }}; //reinforced stuff @@ -2025,7 +2026,7 @@ public static void load(){ reinforcedPump = new Pump("reinforced-pump"){{ requirements(Category.liquid, with(Items.beryllium, 40, Items.tungsten, 30, Items.silicon, 20)); //TODO CUSTOM DRAW ANIMATION - pistons - repurpose DrawBlock? - consumes.liquid(Liquids.hydrogen, 1.5f / 60f); + consumeLiquid(Liquids.hydrogen, 1.5f / 60f); pumpAmount = 80f / 60f / 4f; liquidCapacity = 40f; @@ -2117,21 +2118,21 @@ public static void load(){ battery = new Battery("battery"){{ requirements(Category.power, with(Items.copper, 5, Items.lead, 20)); - consumes.powerBuffered(4000f); + consumePowerBuffered(4000f); baseExplosiveness = 1f; }}; batteryLarge = new Battery("battery-large"){{ requirements(Category.power, with(Items.titanium, 20, Items.lead, 50, Items.silicon, 30)); size = 3; - consumes.powerBuffered(50000f); + consumePowerBuffered(50000f); baseExplosiveness = 5f; }}; beamNode = new BeamNode("beam-node"){{ requirements(Category.power, with(Items.graphite, 5, Items.beryllium, 3)); consumesPower = outputsPower = true; - consumes.powerBuffered(1000f); + consumePowerBuffered(1000f); range = 10; researchCostMultiplier = 0.8f; }}; @@ -2141,7 +2142,7 @@ public static void load(){ requirements(Category.power, with(Items.beryllium, 30, Items.oxide, 20, Items.silicon, 10)); size = 3; consumesPower = outputsPower = true; - consumes.powerBuffered(40000f); + consumePowerBuffered(40000f); range = 23; }}; @@ -2179,7 +2180,7 @@ public static void load(){ requirements(Category.power, with(Items.copper, 35, Items.graphite, 25, Items.lead, 40, Items.silicon, 30)); powerProduction = 5.5f; itemDuration = 90f; - consumes.liquid(Liquids.water, 0.1f); + consumeLiquid(Liquids.water, 0.1f); hasLiquids = true; size = 2; drawer.iconOverride = new String[]{"", "-turbine0", "-turbine1"}; @@ -2200,8 +2201,8 @@ public static void load(){ drawer = new DrawMulti(new DrawBlock(), new DrawWarmupRegion()); - consumes.item(Items.pyratite); - consumes.liquid(Liquids.cryofluid, 0.1f); + consumeItem(Items.pyratite); + consumeLiquid(Liquids.cryofluid, 0.1f); }}; rtgGenerator = new DecayGenerator("rtg-generator"){{ @@ -2230,9 +2231,9 @@ public static void load(){ health = 700; itemDuration = 360f; powerProduction = 15f; - consumes.item(Items.thorium); + consumeItem(Items.thorium); heating = 0.02f; - consumes.liquid(Liquids.cryofluid, heating / coolantPower).update(false); + consumeLiquid(Liquids.cryofluid, heating / coolantPower).update(false); }}; impactReactor = new ImpactReactor("impact-reactor"){{ @@ -2244,9 +2245,9 @@ public static void load(){ ambientSound = Sounds.pulse; ambientSoundVolume = 0.07f; - consumes.power(25f); - consumes.item(Items.blastCompound); - consumes.liquid(Liquids.cryofluid, 0.25f); + consumePower(25f); + consumeItem(Items.blastCompound); + consumeLiquid(Liquids.cryofluid, 0.25f); }}; //erekir @@ -2275,7 +2276,7 @@ public static void load(){ chemicalCombustionChamber = new ConsumeGenerator("chemical-combustion-chamber"){{ requirements(Category.power, with(Items.graphite, 40, Items.tungsten, 40, Items.oxide, 40f, Items.silicon, 30)); powerProduction = 9f; - consumes.liquids(LiquidStack.with(Liquids.ozone, 2f / 60f, Liquids.arkycite, 40f / 60f)); + consumeLiquids(LiquidStack.with(Liquids.ozone, 2f / 60f, Liquids.arkycite, 40f / 60f)); size = 3; drawer = new DrawMulti(new DrawRegion("-bottom"), new DrawPistons(){{ sinMag = 3f; @@ -2312,7 +2313,7 @@ public static void load(){ }}); //TODO ratios, extra requirements? - consumes.liquids(LiquidStack.with(Liquids.slag, 20f / 60f, Liquids.arkycite, 30f / 60f)); + consumeLiquids(LiquidStack.with(Liquids.slag, 20f / 60f, Liquids.arkycite, 30f / 60f)); size = 3; liquidCapacity = 30f * 5; @@ -2337,7 +2338,7 @@ public static void load(){ //mechanical drill doesn't work in space envEnabled ^= Env.space; - consumes.liquid(Liquids.water, 0.05f).boost(); + consumeLiquid(Liquids.water, 0.05f).boost(); }}; pneumaticDrill = new Drill("pneumatic-drill"){{ @@ -2346,7 +2347,7 @@ public static void load(){ drillTime = 400; size = 2; - consumes.liquid(Liquids.water, 0.06f).boost(); + consumeLiquid(Liquids.water, 0.06f).boost(); }}; laserDrill = new Drill("laser-drill"){{ @@ -2358,8 +2359,8 @@ public static void load(){ updateEffect = Fx.pulverizeMedium; drillEffect = Fx.mineBig; - consumes.power(1.10f); - consumes.liquid(Liquids.water, 0.08f).boost(); + consumePower(1.10f); + consumeLiquid(Liquids.water, 0.08f).boost(); }}; blastDrill = new Drill("blast-drill"){{ @@ -2379,8 +2380,8 @@ public static void load(){ //more than the laser drill liquidBoostIntensity = 1.8f; - consumes.power(3f); - consumes.liquid(Liquids.water, 0.1f).boost(); + consumePower(3f); + consumeLiquid(Liquids.water, 0.1f).boost(); }}; waterExtractor = new SolidPump("water-extractor"){{ @@ -2393,7 +2394,7 @@ public static void load(){ attribute = Attribute.water; envRequired |= Env.groundWater; - consumes.power(1.5f); + consumePower(1.5f); }}; cultivator = new AttributeCrafter("cultivator"){{ @@ -2413,8 +2414,8 @@ public static void load(){ drawer = new DrawCultivator(); maxBoost = 2f; - consumes.power(80f / 60f); - consumes.liquid(Liquids.water, 18f / 60f); + consumePower(80f / 60f); + consumeLiquid(Liquids.water, 18f / 60f); }}; oilExtractor = new Fracker("oil-extractor"){{ @@ -2429,9 +2430,9 @@ public static void load(){ baseEfficiency = 0f; itemUseTime = 60f; - consumes.item(Items.sand); - consumes.power(3f); - consumes.liquid(Liquids.water, 0.15f); + consumeItem(Items.sand); + consumePower(3f); + consumeLiquid(Liquids.water, 0.15f); }}; //TODO output heat? @@ -2452,14 +2453,14 @@ public static void load(){ continuousLiquidOutput = true; boostScale = 1f / 9f; outputLiquid = new LiquidStack(Liquids.water, 30f / 60f); - consumes.power(0.5f); + consumePower(0.5f); liquidCapacity = 60f; }}; cliffCrusher = new WallCrafter("cliff-crusher"){{ requirements(Category.production, with(Items.graphite, 25, Items.beryllium, 20)); - consumes.power(0.8f); + consumePower(0.8f); drillTime = 110f; size = 2; @@ -2469,21 +2470,21 @@ public static void load(){ plasmaBore = new BeamDrill("plasma-bore"){{ requirements(Category.production, with(Items.graphite, 20, Items.beryllium, 30)); - consumes.power(0.15f); + consumePower(0.15f); drillTime = 160f; tier = 3; size = 2; range = 4; researchCostMultiplier = 0.18f; - consumes.liquid(Liquids.hydrogen, 0.25f / 60f).boost(); + consumeLiquid(Liquids.hydrogen, 0.25f / 60f).boost(); }}; //TODO awful name largePlasmaBore = new BeamDrill("large-plasma-bore"){{ //TODO requirements requirements(Category.production, with(Items.silicon, 100, Items.oxide, 30, Items.beryllium, 100, Items.tungsten, 70)); - consumes.power(0.8f); + consumePower(0.8f); drillTime = 120f; tier = 4; size = 3; @@ -2491,8 +2492,8 @@ public static void load(){ laserWidth = 0.7f; itemCapacity = 20; - consumes.liquid(Liquids.hydrogen, 1f / 60f).boost(); - consumes.liquid(Liquids.nitrogen, 4f / 60f).boost(); + consumeLiquid(Liquids.hydrogen, 1f / 60f).boost(); + consumeLiquid(Liquids.nitrogen, 4f / 60f).boost(); }}; //TODO should be crusher or something @@ -2508,8 +2509,8 @@ public static void load(){ //can't mine thorium for balance reasons, needs better drill blockedItem = Items.thorium; - consumes.power(160f / 60f); - consumes.liquid(Liquids.water, 0.2f); + consumePower(160f / 60f); + consumeLiquid(Liquids.water, 0.2f); }}; //TODO bad name @@ -2534,8 +2535,8 @@ public static void load(){ glowColor.a = 0.6f; //TODO different requirements - consumes.power(6f); - consumes.liquids(LiquidStack.with(Liquids.water, 0.4f, Liquids.hydrogen, 4f / 60f)); + consumePower(6f); + consumeLiquids(LiquidStack.with(Liquids.water, 0.4f, Liquids.hydrogen, 4f / 60f)); }}; //endregion @@ -2789,7 +2790,7 @@ public static void load(){ targetAir = false; shootSound = Sounds.laser; - consumes.power(6f); + consumePower(6f); shootType = new LaserBulletType(140){{ colors = new Color[]{Pal.lancerLaser.cpy().a(0.4f), Pal.lancerLaser, Color.white}; @@ -2814,7 +2815,7 @@ public static void load(){ reloadTime = 35f; shootCone = 40f; rotateSpeed = 8f; - consumes.power(3.3f); + consumePower(3.3f); targetAir = false; range = 90f; shootEffect = Fx.lightningShoot; @@ -2837,7 +2838,7 @@ public static void load(){ scaledHealth = 160; rotateSpeed = 10; - consumes.powerCond(3f, (TractorBeamBuild e) -> e.target != null); + consumePowerCond(3f, (TractorBeamBuild e) -> e.target != null); }}; swarmer = new ItemTurret("swarmer"){{ @@ -2895,7 +2896,7 @@ public static void load(){ scaledHealth = 250; range = 180f; hasPower = true; - consumes.powerCond(8f, (PointDefenseBuild b) -> b.target != null); + consumePowerCond(8f, (PointDefenseBuild b) -> b.target != null); size = 2; shootLength = 5f; bulletDamage = 30f; @@ -3056,7 +3057,7 @@ Items.surgeAlloy, new PointBulletType(){{ scaledHealth = 150; coolantUsage = 1f; - consumes.powerCond(10f, TurretBuild::isActive); + consumePowerCond(10f, TurretBuild::isActive); }}; spectre = new ItemTurret("spectre"){{ @@ -3098,7 +3099,7 @@ Items.surgeAlloy, new PointBulletType(){{ reloadTime = 90f; firingMoveFract = 0.5f; shootDuration = 230f; - consumes.power(17f); + consumePower(17f); shootSound = Sounds.laserbig; loopSound = Sounds.beam; loopSoundVolume = 2f; @@ -3118,7 +3119,7 @@ Items.surgeAlloy, new PointBulletType(){{ }}; scaledHealth = 200; - consumes.add(new ConsumeCoolant(0.5f)).update(false); + consume(new ConsumeCoolant(0.5f)).update(false); }}; breach = new ItemTurret("breach"){{ @@ -3332,7 +3333,7 @@ Items.thorium, new ArtilleryBulletType(2.5f, 300, "shell"){{ outlineColor = Pal.darkOutline; acceptCoolant = false; - consumes.liquid(Liquids.hydrogen, 5f / 60f); + consumeLiquid(Liquids.hydrogen, 5f / 60f); scaledHealth = 300; range = 390f; @@ -3433,12 +3434,6 @@ Items.thorium, new ArtilleryBulletType(2.5f, 300, "shell"){{ //endregion //region units - commandCenter = new CommandCenter("command-center"){{ - requirements(Category.units, ItemStack.with(Items.copper, 200, Items.lead, 250, Items.silicon, 250, Items.graphite, 100)); - size = 2; - scaledHealth = 55; - }}; - groundFactory = new UnitFactory("ground-factory"){{ requirements(Category.units, with(Items.copper, 50, Items.lead, 120, Items.silicon, 80)); plans = Seq.with( @@ -3447,7 +3442,7 @@ Items.thorium, new ArtilleryBulletType(2.5f, 300, "shell"){{ new UnitPlan(UnitTypes.nova, 60f * 40, with(Items.silicon, 30, Items.lead, 20, Items.titanium, 20)) ); size = 3; - consumes.power(1.2f); + consumePower(1.2f); }}; airFactory = new UnitFactory("air-factory"){{ @@ -3457,7 +3452,7 @@ Items.thorium, new ArtilleryBulletType(2.5f, 300, "shell"){{ new UnitPlan(UnitTypes.mono, 60f * 35, with(Items.silicon, 30, Items.lead, 15)) ); size = 3; - consumes.power(1.2f); + consumePower(1.2f); }}; navalFactory = new UnitFactory("naval-factory"){{ @@ -3467,7 +3462,7 @@ Items.thorium, new ArtilleryBulletType(2.5f, 300, "shell"){{ new UnitPlan(UnitTypes.retusa, 60f * 50f, with(Items.silicon, 15, Items.metaglass, 25, Items.titanium, 20)) ); size = 3; - consumes.power(1.2f); + consumePower(1.2f); floating = true; }}; @@ -3475,8 +3470,8 @@ Items.thorium, new ArtilleryBulletType(2.5f, 300, "shell"){{ requirements(Category.units, with(Items.copper, 200, Items.lead, 120, Items.silicon, 90)); size = 3; - consumes.power(3f); - consumes.items(with(Items.silicon, 40, Items.graphite, 40)); + consumePower(3f); + consumeItems(with(Items.silicon, 40, Items.graphite, 40)); constructTime = 60f * 10f; @@ -3495,8 +3490,8 @@ Items.thorium, new ArtilleryBulletType(2.5f, 300, "shell"){{ requirements(Category.units, with(Items.lead, 650, Items.silicon, 450, Items.titanium, 350, Items.thorium, 650)); size = 5; - consumes.power(6f); - consumes.items(with(Items.silicon, 130, Items.titanium, 80, Items.metaglass, 40)); + consumePower(6f); + consumeItems(with(Items.silicon, 130, Items.titanium, 80, Items.metaglass, 40)); constructTime = 60f * 30f; @@ -3515,9 +3510,9 @@ Items.thorium, new ArtilleryBulletType(2.5f, 300, "shell"){{ requirements(Category.units, with(Items.lead, 2000, Items.silicon, 1000, Items.titanium, 2000, Items.thorium, 750, Items.plastanium, 450, Items.phaseFabric, 600)); size = 7; - consumes.power(13f); - consumes.items(with(Items.silicon, 850, Items.titanium, 750, Items.plastanium, 650)); - consumes.liquid(Liquids.cryofluid, 1f); + consumePower(13f); + consumeItems(with(Items.silicon, 850, Items.titanium, 750, Items.plastanium, 650)); + consumeLiquid(Liquids.cryofluid, 1f); constructTime = 60f * 60f * 1.5f; liquidCapacity = 60f; @@ -3537,9 +3532,9 @@ Items.thorium, new ArtilleryBulletType(2.5f, 300, "shell"){{ requirements(Category.units, with(Items.lead, 4000, Items.silicon, 3000, Items.thorium, 1000, Items.plastanium, 600, Items.phaseFabric, 600, Items.surgeAlloy, 800)); size = 9; - consumes.power(25f); - consumes.items(with(Items.silicon, 1000, Items.plastanium, 600, Items.surgeAlloy, 500, Items.phaseFabric, 350)); - consumes.liquid(Liquids.cryofluid, 3f); + consumePower(25f); + consumeItems(with(Items.silicon, 1000, Items.plastanium, 600, Items.surgeAlloy, 500, Items.phaseFabric, 350)); + consumeLiquid(Liquids.cryofluid, 3f); constructTime = 60f * 60f * 4; liquidCapacity = 180f; @@ -3593,11 +3588,11 @@ Items.thorium, new ArtilleryBulletType(2.5f, 300, "shell"){{ size = 5; //TODO remove ducts and crushers, replace with 2-3 high cost special blocks with silicon requirements plans.add(new AssemblerUnitPlan(UnitTypes.vanquish, 60f * 50f, BlockStack.list(Blocks.tungstenWallLarge, 10, Blocks.primeControlCore, 2))); - consumes.power(3f); + consumePower(3f); areaSize = 13; researchCostMultiplier = 0.4f; - consumes.liquid(Liquids.nitrogen, 24f / 60f); + consumeLiquid(Liquids.nitrogen, 24f / 60f); }}; //TODO requirements @@ -3605,11 +3600,11 @@ Items.thorium, new ArtilleryBulletType(2.5f, 300, "shell"){{ requirements(Category.units, with(Items.beryllium, 700, Items.oxide, 300, Items.tungsten, 500, Items.silicon, 800)); size = 5; plans.add(new AssemblerUnitPlan(UnitTypes.quell, 60f * 60f, BlockStack.list(Blocks.berylliumWallLarge, 20, Blocks.primeControlCore, 2))); - consumes.power(3f); + consumePower(3f); areaSize = 13; researchCostMultiplier = 0.4f; - consumes.liquid(Liquids.nitrogen, 24f / 60f); + consumeLiquid(Liquids.nitrogen, 24f / 60f); }}; //TODO requirements @@ -3618,17 +3613,17 @@ Items.thorium, new ArtilleryBulletType(2.5f, 300, "shell"){{ size = 5; //TODO different reqs plans.add(new AssemblerUnitPlan(UnitTypes.bulwark, 60f * 60f, BlockStack.list(Blocks.tungstenWallLarge, 12, Blocks.primeControlCore, 2))); - consumes.power(3f); + consumePower(3f); areaSize = 13; researchCostMultiplier = 0.4f; - consumes.liquid(Liquids.nitrogen, 24f / 60f); + consumeLiquid(Liquids.nitrogen, 24f / 60f); }}; //TODO requirements basicAssemblerModule = new UnitAssemblerModule("basic-assembler-module"){{ requirements(Category.units, with(Items.graphite, 10)); - consumes.power(0.5f); + consumePower(0.5f); size = 3; }}; @@ -3639,7 +3634,7 @@ Items.thorium, new ArtilleryBulletType(2.5f, 300, "shell"){{ requirements(Category.units, with(Items.graphite, 10)); size = 3; - consumes.power(3f); + consumePower(3f); droneType = UnitTypes.effectDrone; }}; @@ -3682,7 +3677,7 @@ Items.thorium, new ArtilleryBulletType(2.5f, 300, "shell"){{ //TODO 500 or 400? does it need to be better than the standard mass driver? range = 450f; maxPayloadSize = 2.5f; - consumes.power(2f); + consumePower(2f); }}; payloadPropulsionTower = new PayloadMassDriver("payload-propulsion-tower"){{ @@ -3692,13 +3687,13 @@ Items.thorium, new ArtilleryBulletType(2.5f, 300, "shell"){{ chargeTime = 100f; range = 1100f; maxPayloadSize = 3.5f; - consumes.power(6f); + consumePower(6f); }}; smallDeconstructor = new PayloadDeconstructor("small-deconstructor"){{ requirements(Category.units, with(Items.beryllium, 100, Items.silicon, 100, Items.oxide, 50, Items.graphite, 80)); itemCapacity = 100; - consumes.power(1f); + consumePower(1f); size = 3; deconstructSpeed = 1f; }}; @@ -3707,7 +3702,7 @@ Items.thorium, new ArtilleryBulletType(2.5f, 300, "shell"){{ deconstructor = new PayloadDeconstructor("deconstructor"){{ requirements(Category.units, with(Items.beryllium, 250, Items.oxide, 100, Items.silicon, 250, Items.carbide, 250)); itemCapacity = 250; - consumes.power(3f); + consumePower(3f); size = 5; deconstructSpeed = 2f; }}; @@ -3716,7 +3711,7 @@ Items.thorium, new ArtilleryBulletType(2.5f, 300, "shell"){{ requirements(Category.units, with(Items.silicon, 100, Items.beryllium, 150, Items.tungsten, 80)); hasPower = true; buildSpeed = 0.3f; - consumes.power(2f); + consumePower(2f); size = 3; //TODO expand this list filter = Seq.with(Blocks.primeControlCore, Blocks.tungstenWallLarge, Blocks.berylliumWallLarge, Blocks.reinforcedLiquidContainer, Blocks.beamNode); @@ -3726,7 +3721,7 @@ Items.thorium, new ArtilleryBulletType(2.5f, 300, "shell"){{ largeConstructor = new Constructor("large-constructor"){{ requirements(Category.units, with(Items.silicon, 150, Items.oxide, 150, Items.tungsten, 200, Items.phaseFabric, 40)); hasPower = true; - consumes.power(2f); + consumePower(2f); buildSpeed = 0.3f; maxBlockSize = 4; minBlockSize = 3; @@ -3736,14 +3731,14 @@ Items.thorium, new ArtilleryBulletType(2.5f, 300, "shell"){{ payloadLoader = new PayloadLoader("payload-loader"){{ requirements(Category.units, with(Items.graphite, 50, Items.silicon, 50, Items.tungsten, 80)); hasPower = true; - consumes.power(2f); + consumePower(2f); size = 3; }}; payloadUnloader = new PayloadUnloader("payload-unloader"){{ requirements(Category.units, with(Items.graphite, 50, Items.silicon, 50, Items.oxide, 30)); hasPower = true; - consumes.power(2f); + consumePower(2f); size = 3; }}; @@ -3798,7 +3793,7 @@ Items.thorium, new ArtilleryBulletType(2.5f, 300, "shell"){{ requirements(Category.effect, BuildVisibility.lightingOnly, with(Items.graphite, 12, Items.silicon, 8, Items.lead, 8)); brightness = 0.75f; radius = 140f; - consumes.power(0.05f); + consumePower(0.05f); }}; //endregion @@ -3814,6 +3809,10 @@ Items.thorium, new ArtilleryBulletType(2.5f, 300, "shell"){{ replacement = Blocks.groundFactory; }}; + new LegacyCommandCenter("command-center"){{ + size = 2; + }}; + //endregion //region campaign @@ -3823,7 +3822,7 @@ Items.thorium, new ArtilleryBulletType(2.5f, 300, "shell"){{ itemCapacity = 100; launchTime = 60f * 20; hasPower = true; - consumes.power(4f); + consumePower(4f); }}; interplanetaryAccelerator = new Accelerator("interplanetary-accelerator"){{ @@ -3831,7 +3830,7 @@ Items.thorium, new ArtilleryBulletType(2.5f, 300, "shell"){{ researchCostMultiplier = 0.1f; size = 7; hasPower = true; - consumes.power(10f); + consumePower(10f); buildCostMultiplier = 0.5f; scaledHealth = 80; }}; @@ -3868,7 +3867,7 @@ Items.thorium, new ArtilleryBulletType(2.5f, 300, "shell"){{ hyperProcessor = new LogicBlock("hyper-processor"){{ requirements(Category.logic, with(Items.lead, 450, Items.silicon, 150, Items.thorium, 75, Items.surgeAlloy, 50)); - consumes.liquid(Liquids.cryofluid, 0.08f); + consumeLiquid(Liquids.cryofluid, 0.08f); hasLiquids = true; instructionsPerTick = 25; diff --git a/core/src/mindustry/content/Bullets.java b/core/src/mindustry/content/Bullets.java index e21d7e3f10ea..bc1c3609fa68 100644 --- a/core/src/mindustry/content/Bullets.java +++ b/core/src/mindustry/content/Bullets.java @@ -186,7 +186,7 @@ public static void load(){ despawnEffect = Fx.none; }}; - fragPlasticFrag = new BasicBulletType(2.5f, 10, "bullet"){{ + fragPlasticFrag = new BasicBulletType(2.5f, 12, "bullet"){{ width = 10f; height = 12f; shrinkY = 1f; @@ -196,15 +196,15 @@ public static void load(){ despawnEffect = Fx.none; }}; - fragGlass = new FlakBulletType(4f, 3){{ + fragGlass = new FlakBulletType(4f, 9){{ ammoMultiplier = 3f; shootEffect = Fx.shootSmall; reloadMultiplier = 0.8f; width = 6f; height = 8f; hitEffect = Fx.flakExplosion; - splashDamage = 18f * 1.5f; - splashDamageRadius = 16f; + splashDamage = 28f * 1.5f; + splashDamageRadius = 22f; fragBullet = fragGlassFrag; fragBullets = 4; explodeRange = 20f; diff --git a/core/src/mindustry/content/Planets.java b/core/src/mindustry/content/Planets.java index 95df967cfbbd..92a0877e5abe 100644 --- a/core/src/mindustry/content/Planets.java +++ b/core/src/mindustry/content/Planets.java @@ -63,7 +63,6 @@ public static void load(){ clearSectorOnLose = true; hiddenItems.addAll(Items.serpuloItems).removeAll(Items.erekirItems); ruleSetter = r -> { - r.unitCommand = true; r.placeRangeCheck = true; }; diff --git a/core/src/mindustry/content/SerpuloTechTree.java b/core/src/mindustry/content/SerpuloTechTree.java index 8603d2bed22f..391fe20fc81f 100644 --- a/core/src/mindustry/content/SerpuloTechTree.java +++ b/core/src/mindustry/content/SerpuloTechTree.java @@ -333,9 +333,6 @@ public static void load(){ }); node(groundFactory, () -> { - node(commandCenter, () -> { - - }); node(dagger, () -> { node(mace, () -> { @@ -514,7 +511,6 @@ public static void load(){ node(saltFlats, Seq.with( new SectorComplete(windsweptIslands), - new Research(commandCenter), new Research(groundFactory), new Research(additiveReconstructor), new Research(airFactory), diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index 7bb17788c4bc..16cc6b2a530a 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -302,7 +302,6 @@ public static void load(){ health = 120f; buildSpeed = 0.8f; armor = 1f; - commandLimit = 8; abilities.add(new RepairFieldAbility(10f, 60f * 4, 60f)); ammoType = new PowerAmmoType(1000); @@ -339,7 +338,6 @@ public static void load(){ mineTier = 2; mineSpeed = 5f; - commandLimit = 9; abilities.add(new ShieldRegenFieldAbility(20f, 40f, 60f * 5, 60f)); ammoType = new PowerAmmoType(1300); @@ -393,7 +391,6 @@ public static void load(){ landShake = 2f; riseSpeed = 0.05f; - commandLimit = 10; mechFrontSway = 0.55f; ammoType = new PowerAmmoType(1500); @@ -453,7 +450,6 @@ public static void load(){ landShake = 4f; immunities = ObjectSet.with(StatusEffects.burning); - commandLimit = 8; singleTarget = true; weapons.add(new Weapon("vela-weapon"){{ @@ -521,8 +517,6 @@ public static void load(){ rotateSpeed = 1.5f; drownTimeMultiplier = 6f; - commandLimit = 8; - legCount = 4; legLength = 14f; legBaseOffset = 11f; @@ -975,7 +969,6 @@ public static void load(){ //as default AI, flares are not very useful in core rushes, they attack nothing in the way playerTargetFlags = new BlockFlag[]{null}; targetFlags = new BlockFlag[]{BlockFlag.generator, null}; - commandLimit = 4; circleTarget = true; hitSize = 7; itemCapacity = 15; @@ -1012,7 +1005,6 @@ public static void load(){ //do not rush core, attack closest playerTargetFlags = new BlockFlag[]{null}; targetFlags = new BlockFlag[]{BlockFlag.factory, null}; - commandLimit = 5; circleTarget = true; ammoType = new ItemAmmoType(Items.graphite); @@ -1458,7 +1450,6 @@ public static void load(){ payloadCapacity = (5.5f * 5.5f) * tilePayload; buildSpeed = 4f; drawShields = false; - commandLimit = 6; lowAltitude = true; buildBeamOffset = 43; ammoCapacity = 1; @@ -2325,7 +2316,6 @@ public static void load(){ health = 150f; engineOffset = 6f; hitSize = 8f; - commandLimit = 3; alwaysUnlocked = true; weapons.add(new Weapon("small-basic-weapon"){{ @@ -2364,7 +2354,6 @@ public static void load(){ hitSize = 9f; rotateShooting = false; lowAltitude = true; - commandLimit = 4; weapons.add(new Weapon("small-mount-weapon"){{ top = false; @@ -2405,7 +2394,6 @@ public static void load(){ health = 220f; engineOffset = 6f; hitSize = 11f; - commandLimit = 5; weapons.add(new Weapon("small-mount-weapon"){{ top = false; @@ -3321,7 +3309,6 @@ public static void load(){ health = 1; rotateSpeed = 360f; itemCapacity = 0; - commandLimit = 0; hidden = true; internal = true; }}; diff --git a/core/src/mindustry/core/Logic.java b/core/src/mindustry/core/Logic.java index ec9d81c37587..2b4868bdb586 100644 --- a/core/src/mindustry/core/Logic.java +++ b/core/src/mindustry/core/Logic.java @@ -4,7 +4,6 @@ import arc.math.*; import arc.util.*; import mindustry.annotations.Annotations.*; -import mindustry.content.*; import mindustry.core.GameState.*; import mindustry.ctype.*; import mindustry.game.EventType.*; @@ -124,11 +123,6 @@ public Logic(){ state.rules.waveTeam.rules().ai = true; } - //TODO unit commanding is not allowed on serpulo until I test it properly - if(state.getSector().planet != Planets.serpulo){ - state.rules.unitCommand = true; - } - state.rules.coreIncinerates = true; state.rules.waveTeam.rules().aiTier = state.getSector().threat * 0.8f; state.rules.waveTeam.rules().infiniteResources = true; diff --git a/core/src/mindustry/core/NetServer.java b/core/src/mindustry/core/NetServer.java index 358e0322b758..26417a924739 100644 --- a/core/src/mindustry/core/NetServer.java +++ b/core/src/mindustry/core/NetServer.java @@ -504,10 +504,6 @@ boolean checkPass(){ return; } - if(!player.dead() && player.unit().isCommanding()){ - player.unit().clearCommand(); - } - player.getInfo().lastSyncTime = Time.millis(); Call.worldDataBegin(player.con); netServer.sendWorldData(player); diff --git a/core/src/mindustry/entities/comp/BuildingComp.java b/core/src/mindustry/entities/comp/BuildingComp.java index bee00f5847d0..d769dd522764 100644 --- a/core/src/mindustry/entities/comp/BuildingComp.java +++ b/core/src/mindustry/entities/comp/BuildingComp.java @@ -442,7 +442,7 @@ public boolean consOptionalValid(){ } public void consume(){ - for(Consume cons : block.consumes.all){ + for(Consume cons : block.consumers){ cons.trigger(self()); } } @@ -465,7 +465,7 @@ public float edelta(){ public float efficiency(){ //disabled -> 0 efficiency if(!enabled) return 0; - return power != null && (block.consumes.has(ConsumeType.power) && !block.consumes.getPower().buffered) ? power.status : 1f; + return power != null && (block.consPower != null && !block.consPower.buffered) ? power.status : 1f; } /** @@ -702,11 +702,11 @@ public void handleItem(Building source, Item item){ } public boolean acceptItem(Building source, Item item){ - return block.consumes.consumesItem(item) && items.get(item) < getMaximumAccepted(item); + return block.consumesItem(item) && items.get(item) < getMaximumAccepted(item); } public boolean acceptLiquid(Building source, Liquid liquid){ - return block.hasLiquids && block.consumes.liquidfilters.get(liquid.id); + return block.hasLiquids && block.consumesLiquid(liquid); } public void handleLiquid(Building source, Liquid liquid, float amount){ @@ -791,7 +791,7 @@ public float moveLiquid(Building next, Liquid liquid){ liquids.remove(liquid, flow); return flow; //handle reactions between different liquid types â–¼ - }else if(!next.block.consumes.consumesLiquid(liquid) && next.liquids.currentAmount() / next.block.liquidCapacity > 0.1f && fract > 0.1f){ + }else if(!next.block.consumesLiquid(liquid) && next.liquids.currentAmount() / next.block.liquidCapacity > 0.1f && fract > 0.1f){ //TODO !IMPORTANT! uses current(), which is 1) wrong for multi-liquid blocks and 2) causes unwanted reactions, e.g. hydrogen + slag in pump //TODO these are incorrect effect positions float fx = (x + next.x) / 2f, fy = (y + next.y) / 2f; @@ -1043,7 +1043,7 @@ public boolean shouldAmbientSound(){ } public void drawStatus(){ - if(block.enableDrawStatus && block.consumes.any()){ + if(block.enableDrawStatus && block.consumers.length > 0){ float multiplier = block.size > 1 ? 1 : 0.64f; float brcx = x + (block.size * tilesize / 2f) - (tilesize * multiplier / 2f); float brcy = y - (block.size * tilesize / 2f) + (tilesize * multiplier / 2f); @@ -1249,8 +1249,8 @@ public void onDestroyed(){ explosiveness += liquids.sum((liquid, amount) -> liquid.explosiveness * amount / 2f); } - if(block.consumes.hasPower() && block.consumes.getPower().buffered){ - power += this.power.status * block.consumes.getPower().capacity; + if(block.consPower != null && block.consPower.buffered){ + power += this.power.status * block.consPower.capacity; } if(block.hasLiquids && state.rules.damageExplosions){ @@ -1397,14 +1397,14 @@ public void display(Table table){ public void displayConsumption(Table table){ table.left(); - for(Consume cons : block.consumes.all){ - if(cons.isOptional() && cons.isBoost()) continue; + for(Consume cons : block.consumers){ + if(cons.optional && cons.booster) continue; cons.build(self(), table); } } public void displayBars(Table table){ - for(Func bar : block.bars.list()){ + for(Func bar : block.listBars()){ table.add(bar.get(self())).growX(); table.row(); } @@ -1521,7 +1521,7 @@ public void afterPickedUp(){ //TODO can lead to ghost graphs? power.graph = new PowerGraph(); power.links.clear(); - if(block.consumes.hasPower() && !block.consumes.getPower().buffered){ + if(block.consPower != null && !block.consPower.buffered){ power.status = 0f; } } @@ -1590,18 +1590,18 @@ public void updateConsumption(){ consOptionalValid = true; boolean docons = shouldConsume() && productionValid(); - for(Consume cons : block.consumes.all){ - if(cons.isOptional()) continue; + for(Consume cons : block.consumers){ + if(cons.optional) continue; - if(docons && cons.isUpdate() && prevValid && cons.valid(self())){ + if(docons && cons.update && prevValid && cons.valid(self())){ cons.update(self()); } consValid &= cons.valid(self()); } - for(Consume cons : block.consumes.optionals){ - if(docons && cons.isUpdate() && prevValid && cons.valid(self())){ + for(Consume cons : block.optionalConsumers){ + if(docons && cons.update && prevValid && cons.valid(self())){ cons.update(self()); } @@ -1693,10 +1693,10 @@ public double sense(LAccess sensor){ case totalItems -> items == null ? 0 : items.total(); //TODO will give wildly fluctuating amounts due to switching of current() for multi-liquid blocks. totalLiquids is inherently bad design, but unfortunately it is useful for conduits/tanks case totalLiquids -> liquids == null ? 0 : liquids.currentAmount(); - case totalPower -> power == null || !block.consumes.hasPower() ? 0 : power.status * (block.consumes.getPower().buffered ? block.consumes.getPower().capacity : 1f); + case totalPower -> power == null || block.consPower == null ? 0 : power.status * (block.consPower.buffered ? block.consPower.capacity : 1f); case itemCapacity -> block.hasItems ? block.itemCapacity : 0; case liquidCapacity -> block.hasLiquids ? block.liquidCapacity : 0; - case powerCapacity -> block.consumes.hasPower() ? block.consumes.getPower().capacity : 0f; + case powerCapacity -> block.consPower != null ? block.consPower.capacity : 0f; case powerNetIn -> power == null ? 0 : power.graph.getLastScaledPowerIn() * 60; case powerNetOut -> power == null ? 0 : power.graph.getLastScaledPowerOut() * 60; case powerNetStored -> power == null ? 0 : power.graph.getLastPowerStored(); diff --git a/core/src/mindustry/entities/comp/CommanderComp.java b/core/src/mindustry/entities/comp/CommanderComp.java deleted file mode 100644 index 0f2ab77a8bf9..000000000000 --- a/core/src/mindustry/entities/comp/CommanderComp.java +++ /dev/null @@ -1,129 +0,0 @@ -package mindustry.entities.comp; - -import arc.func.*; -import arc.math.geom.*; -import arc.struct.*; -import arc.util.*; -import mindustry.*; -import mindustry.ai.formations.*; -import mindustry.ai.types.*; -import mindustry.annotations.Annotations.*; -import mindustry.entities.*; -import mindustry.entities.units.*; -import mindustry.game.*; -import mindustry.gen.*; -import mindustry.type.*; - -/** - * A unit that can command other units. - * @deprecated This mechanic is likely to be removed or completely reworked in the future. - * */ -@Deprecated -@Component -abstract class CommanderComp implements Entityc, Posc{ - private static final Seq members = new Seq<>(); - private static final Seq units = new Seq<>(); - - @Import float x, y, rotation, hitSize; - @Import Team team; - @Import UnitType type; - - transient @Nullable Formation formation; - transient Seq controlling = new Seq<>(10); - /** minimum speed of any unit in the formation. */ - transient float minFormationSpeed; - - public void update(){ - if(controlling.isEmpty() && !Vars.net.client()){ - formation = null; - } - - if(formation != null){ - formation.anchor.set(x, y, 0); - formation.updateSlots(); - controlling.removeAll(u -> u.dead || !(u.controller() instanceof FormationAI ai && ai.leader == self())); - } - } - - public void remove(){ - clearCommand(); - } - - public void killed(){ - clearCommand(); - } - - //make sure to reset command state when the controller is switched - public void controller(UnitController next){ - clearCommand(); - } - - void commandNearby(FormationPattern pattern){ - commandNearby(pattern, u -> true); - } - - void commandNearby(FormationPattern pattern, Boolf include){ - Formation formation = new Formation(new Vec3(x, y, rotation), pattern); - formation.slotAssignmentStrategy = new DistanceAssignmentStrategy(pattern); - - 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 && u.type.playerControllable){ - units.add(u); - } - }); - - if(units.isEmpty()) return; - - //sort by hitbox size, then by distance - units.sort(Structs.comps(Structs.comparingFloat(u -> -u.hitSize), Structs.comparingFloat(u -> u.dst2(this)))); - units.truncate(type.commandLimit); - - command(formation, units); - } - - void command(Formation formation, Seq units){ - clearCommand(); - units.shuffle(); - - float spacing = hitSize * 0.9f; - minFormationSpeed = type.speed; - - controlling.addAll(units); - for(Unit unit : units){ - FormationAI ai; - unit.controller(ai = new FormationAI(self(), formation)); - spacing = Math.max(spacing, ai.formationSize()); - minFormationSpeed = Math.min(minFormationSpeed, unit.type.speed); - } - this.formation = formation; - - //update formation spacing based on max size - formation.pattern.spacing = spacing; - - members.clear(); - for(Unitc u : units){ - members.add((FormationAI)u.controller()); - } - - //TODO doesn't handle units that don't fit a formation - formation.addMembers(members); - } - - boolean isCommanding(){ - return formation != null; - } - - void clearCommand(){ - //reset controlled units - for(Unit unit : controlling){ - if(unit.controller().isBeingControlled(self())){ - unit.controller(unit.type.createController(unit)); - } - } - - controlling.clear(); - formation = null; - } -} diff --git a/core/src/mindustry/entities/comp/PlayerComp.java b/core/src/mindustry/entities/comp/PlayerComp.java index 4761633486f9..b9db68809c80 100644 --- a/core/src/mindustry/entities/comp/PlayerComp.java +++ b/core/src/mindustry/entities/comp/PlayerComp.java @@ -124,12 +124,8 @@ public void afterSync(){ unit.aim(mouseX, mouseY); //this is only necessary when the thing being controlled isn't synced unit.controlWeapons(shooting, shooting); - //save previous formation to prevent reset - var formation = unit.formation; //extra precaution, necessary for non-synced things unit.controller(this); - //keep previous formation - unit.formation = formation; } @Override diff --git a/core/src/mindustry/entities/comp/UnitComp.java b/core/src/mindustry/entities/comp/UnitComp.java index 97dd5ddf0566..30b45c81e8e3 100644 --- a/core/src/mindustry/entities/comp/UnitComp.java +++ b/core/src/mindustry/entities/comp/UnitComp.java @@ -1,7 +1,6 @@ package mindustry.entities.comp; import arc.*; -import arc.func.*; import arc.graphics.*; import arc.graphics.g2d.*; import arc.math.*; @@ -32,10 +31,10 @@ import static mindustry.logic.GlobalConstants.*; @Component(base = true) -abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, Itemsc, Rotc, Unitc, Weaponsc, Drawc, Boundedc, Syncc, Shieldc, Commanderc, Displayable, Senseable, Ranged, Minerc, Builderc{ +abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, Itemsc, Rotc, Unitc, Weaponsc, Drawc, Boundedc, Syncc, Shieldc, Displayable, Senseable, Ranged, Minerc, Builderc{ @Import boolean hovering, dead, disarmed; - @Import float x, y, rotation, elevation, maxHealth, drag, armor, hitSize, health, ammo, minFormationSpeed, dragMultiplier; + @Import float x, y, rotation, elevation, maxHealth, drag, armor, hitSize, health, ammo, dragMultiplier; @Import Team team; @Import int id; @Import @Nullable Tile mineTile; @@ -120,14 +119,7 @@ public boolean hasWeapons(){ public float speed(){ float strafePenalty = isGrounded() || !isPlayer() ? 1f : Mathf.lerp(1f, type.strafePenalty, Angles.angleDist(vel().angle(), rotation) / 180f); float boost = Mathf.lerp(1f, type.canBoost ? type.boostMultiplier : 1f, elevation); - //limit speed to minimum formation speed to preserve formation - return (isCommanding() ? minFormationSpeed * 0.98f : type.speed) * strafePenalty * boost * floorSpeedMultiplier(); - } - - /** Iterates through this unit and everything it is controlling. */ - public void eachGroup(Cons cons){ - cons.get(self()); - controlling().each(cons); + return type.speed * strafePenalty * boost * floorSpeedMultiplier(); } /** @return where the unit wants to look at. */ @@ -185,9 +177,7 @@ public double sense(LAccess sensor){ case controlled -> !isValid() ? 0 : controller instanceof LogicAI ? ctrlProcessor : controller instanceof Player ? ctrlPlayer : - controller instanceof FormationAI ? ctrlFormation : 0; - case commanded -> controller instanceof FormationAI && isValid() ? 1 : 0; case payloadCount -> ((Object)this) instanceof Payloadc pay ? pay.payloads().size : 0; case size -> hitSize / tilesize; case color -> Color.toDoubleBits(team.color.r, team.color.g, team.color.b, 1f); @@ -201,7 +191,7 @@ public Object senseObject(LAccess sensor){ case type -> type; case name -> controller instanceof Player p ? p.name : null; case firstItem -> stack().amount == 0 ? null : item(); - case controller -> !isValid() ? null : controller instanceof LogicAI log ? log.controller : controller instanceof FormationAI form ? form.leader : this; + case controller -> !isValid() ? null : controller instanceof LogicAI log ? log.controller : this; case payloadType -> ((Object)this) instanceof Payloadc pay ? (pay.payloads().isEmpty() ? null : pay.payloads().peek() instanceof UnitPayload p1 ? p1.unit.type : @@ -559,12 +549,11 @@ public void destroy(){ remove(); } - /** @return name of direct or indirect player controller. */ + /** @return name of direct or indirect player controller. TODO comamnd support*/ @Override public @Nullable String getControllerName(){ if(isPlayer()) return getPlayer().name; if(controller instanceof LogicAI ai && ai.controller != null) return ai.controller.lastAccessed; - if(controller instanceof FormationAI ai && ai.leader != null && ai.leader.isPlayer()) return ai.leader.getPlayer().name; return null; } diff --git a/core/src/mindustry/entities/units/AIController.java b/core/src/mindustry/entities/units/AIController.java index 37811aad2199..806ae8c6573b 100644 --- a/core/src/mindustry/entities/units/AIController.java +++ b/core/src/mindustry/entities/units/AIController.java @@ -69,10 +69,6 @@ public boolean useFallback(){ return false; } - public UnitCommand command(){ - return unit.team.data().command; - } - public void updateVisuals(){ if(unit.isFlying()){ unit.wobble(); diff --git a/core/src/mindustry/entities/units/UnitCommand.java b/core/src/mindustry/entities/units/UnitCommand.java deleted file mode 100644 index 977150a92d1f..000000000000 --- a/core/src/mindustry/entities/units/UnitCommand.java +++ /dev/null @@ -1,18 +0,0 @@ -package mindustry.entities.units; - -import arc.*; - -public enum UnitCommand{ - attack, rally, idle; - - private final String localized; - public static final UnitCommand[] all = values(); - - UnitCommand(){ - localized = Core.bundle.get("command." + name()); - } - - public String localized(){ - return localized; - } -} diff --git a/core/src/mindustry/entities/units/UnitController.java b/core/src/mindustry/entities/units/UnitController.java index 63aec52ee308..7df6e0f02d6b 100644 --- a/core/src/mindustry/entities/units/UnitController.java +++ b/core/src/mindustry/entities/units/UnitController.java @@ -10,10 +10,6 @@ default boolean isValidController(){ return true; } - default void command(UnitCommand command){ - - } - default void updateUnit(){ } diff --git a/core/src/mindustry/game/EventType.java b/core/src/mindustry/game/EventType.java index 26d7dcb740d9..81e492e11ec1 100644 --- a/core/src/mindustry/game/EventType.java +++ b/core/src/mindustry/game/EventType.java @@ -3,7 +3,6 @@ import arc.util.*; import mindustry.core.GameState.*; import mindustry.ctype.*; -import mindustry.entities.units.*; import mindustry.gen.*; import mindustry.net.*; import mindustry.net.Packets.*; @@ -121,16 +120,6 @@ public SchematicCreateEvent(Schematic schematic){ } } - public static class CommandIssueEvent{ - public final Building tile; - public final UnitCommand command; - - public CommandIssueEvent(Building tile, UnitCommand command){ - this.tile = tile; - this.command = command; - } - } - public static class ClientPreConnectEvent{ public final Host host; diff --git a/core/src/mindustry/game/Rules.java b/core/src/mindustry/game/Rules.java index 6e5e73422d38..bdf082beb686 100644 --- a/core/src/mindustry/game/Rules.java +++ b/core/src/mindustry/game/Rules.java @@ -47,8 +47,6 @@ public class Rules{ public boolean damageExplosions = true; /** Whether fire is enabled. */ public boolean fire = true; - /** Erekir-specific: If true, unit RTS controls can be used. */ - public boolean unitCommand = false; /** Whether units use and require ammo. */ public boolean unitAmmo = false; /** EXPERIMENTAL! If true, blocks will update in units and share power. */ diff --git a/core/src/mindustry/game/Schematic.java b/core/src/mindustry/game/Schematic.java index 89556e58814d..75ac43ec66aa 100644 --- a/core/src/mindustry/game/Schematic.java +++ b/core/src/mindustry/game/Schematic.java @@ -9,7 +9,6 @@ import mindustry.world.*; import mindustry.world.blocks.power.*; import mindustry.world.blocks.storage.*; -import mindustry.world.consumers.*; import static mindustry.Vars.*; @@ -36,7 +35,7 @@ public float powerProduction(){ } public float powerConsumption(){ - return tiles.sumf(s -> s.block.consumes.has(ConsumeType.power) ? s.block.consumes.getPower().usage : 0f); + return tiles.sumf(s -> s.block.consPower != null ? s.block.consPower.usage : 0f); } public ItemSeq requirements(){ diff --git a/core/src/mindustry/game/Teams.java b/core/src/mindustry/game/Teams.java index af489f693526..fdd1f90506e7 100644 --- a/core/src/mindustry/game/Teams.java +++ b/core/src/mindustry/game/Teams.java @@ -8,7 +8,6 @@ import arc.util.*; import mindustry.*; import mindustry.ai.*; -import mindustry.entities.units.*; import mindustry.gen.*; import mindustry.type.*; import mindustry.world.blocks.payloads.*; @@ -231,8 +230,6 @@ public static class TeamData{ public Team[] coreEnemies = {}; /** Planned blocks for drones. This is usually only blocks that have been broken. */ public Queue blocks = new Queue<>(); - /** The current command for units to follow. */ - public UnitCommand command = UnitCommand.attack; /** Quadtree for all buildings of this team. Null if not active. */ public @Nullable QuadTree buildings; diff --git a/core/src/mindustry/graphics/BlockRenderer.java b/core/src/mindustry/graphics/BlockRenderer.java index 6291770cbec4..9a6880e01dbb 100644 --- a/core/src/mindustry/graphics/BlockRenderer.java +++ b/core/src/mindustry/graphics/BlockRenderer.java @@ -387,7 +387,7 @@ public void drawBlocks(){ Draw.z(Layer.block); } - if(build.team == player.team() && renderer.drawStatus && block.consumes.any()){ + if(build.team == player.team() && renderer.drawStatus && block.hasConsumers){ build.drawStatus(); } } diff --git a/core/src/mindustry/input/Binding.java b/core/src/mindustry/input/Binding.java index 9a9ff7606204..b9eab5048e89 100644 --- a/core/src/mindustry/input/Binding.java +++ b/core/src/mindustry/input/Binding.java @@ -22,8 +22,6 @@ public enum Binding implements KeyBind{ pickupCargo(KeyCode.leftBracket), dropCargo(KeyCode.rightBracket), - command(KeyCode.g), - clear_building(KeyCode.q), pause_building(KeyCode.e), rotate(new Axis(KeyCode.scroll)), diff --git a/core/src/mindustry/input/DesktopInput.java b/core/src/mindustry/input/DesktopInput.java index 1e0745ed2647..1ef4683555b2 100644 --- a/core/src/mindustry/input/DesktopInput.java +++ b/core/src/mindustry/input/DesktopInput.java @@ -278,7 +278,7 @@ public void update(){ shouldShoot = !scene.hasMouse() && !locked; - if(!locked && state.rules.unitCommand && block == null && !scene.hasField()){ + if(!locked && block == null && !scene.hasField()){ commandMode = input.keyDown(Binding.commandMode); }else{ commandMode = false; @@ -806,10 +806,5 @@ protected void updateMovement(Unit unit){ tryDropPayload(); } } - - //update commander unit - if(Core.input.keyTap(Binding.command) && unit.type.commandLimit > 0){ - Call.unitCommand(player); - } } } diff --git a/core/src/mindustry/input/InputHandler.java b/core/src/mindustry/input/InputHandler.java index b91c6998c899..80398be57754 100644 --- a/core/src/mindustry/input/InputHandler.java +++ b/core/src/mindustry/input/InputHandler.java @@ -13,7 +13,6 @@ import arc.scene.ui.layout.*; import arc.struct.*; import arc.util.*; -import mindustry.ai.formations.patterns.*; import mindustry.ai.types.*; import mindustry.annotations.Annotations.*; import mindustry.content.*; @@ -241,14 +240,8 @@ public static void requestItem(Player player, Building build, Item item, int amo throw new ValidateException(player, "Player cannot request items."); } - //remove item for every controlling unit - player.unit().eachGroup(unit -> { - Call.takeItems(build, item, Math.min(unit.maxAccepted(item), amount), unit); - - if(unit == player.unit()){ - Events.fire(new WithdrawEvent(build, player, item, amount)); - } - }); + Call.takeItems(build, item, Math.min(player.unit().maxAccepted(item), amount), player.unit()); + Events.fire(new WithdrawEvent(build, player, item, amount)); } @Remote(targets = Loc.both, forward = true, called = Loc.server) @@ -264,16 +257,13 @@ public static void transferInventory(Player player, Building build){ } //deposit for every controlling unit - player.unit().eachGroup(unit -> { - Item item = unit.item(); - int accepted = build.acceptStack(item, unit.stack.amount, unit); + var unit = player.unit(); + Item item = unit.item(); + int accepted = build.acceptStack(item, unit.stack.amount, unit); - Call.transferItemTo(unit, item, accepted, unit.x, unit.y, build); + Call.transferItemTo(unit, item, accepted, unit.x, unit.y, build); - if(unit == player.unit()){ - Events.fire(new DepositEvent(build, player, item, accepted)); - } - }); + Events.fire(new DepositEvent(build, player, item, accepted)); } @Remote(variants = Variant.one) @@ -369,11 +359,6 @@ public static void payloadDropped(Unit unit, float x, float y){ pay.set(x, y); pay.dropLastPayload(); pay.set(prevx, prevy); - pay.controlling().each(u -> { - if(u instanceof Payloadc){ - Call.payloadDropped(u, u.x, u.y); - } - }); } } @@ -385,10 +370,9 @@ public static void dropItem(Player player, float angle){ throw new ValidateException(player, "Player cannot drop an item."); } - player.unit().eachGroup(unit -> { - Fx.dropItem.at(unit.x, unit.y, angle, Color.white, unit.item()); - unit.clearItem(); - }); + var unit = player.unit(); + Fx.dropItem.at(unit.x, unit.y, angle, Color.white, unit.item()); + unit.clearItem(); } @Remote(targets = Loc.both, called = Loc.server, forward = true, unreliable = true) @@ -545,24 +529,6 @@ public static void unitClear(Player player){ player.deathTimer = Player.deathDelay + 1f; //for instant respawn } - @Remote(targets = Loc.both, called = Loc.server, forward = true) - public static void unitCommand(Player player){ - if(player == null || player.dead() || (player.unit() == null)) return; - - //make sure player is allowed to make the command - if(net.server() && !netServer.admins.allowAction(player, ActionType.command, action -> {})){ - throw new ValidateException(player, "Player cannot command a unit."); - } - - if(player.unit().isCommanding()){ - player.unit().clearCommand(); - }else if(player.unit().type.commandLimit > 0){ - - player.unit().commandNearby(new CircleFormation()); - Fx.commandSend.at(player, player.unit().type.commandRadius); - } - } - /** Adds an input lock; if this function returns true, input is locked. Used for mod 'cutscenes' or custom camera panning. */ public void addLock(Boolp lock){ inputLocks.add(lock); diff --git a/core/src/mindustry/input/MobileInput.java b/core/src/mindustry/input/MobileInput.java index d4cc19c091f1..0c8076398fcc 100644 --- a/core/src/mindustry/input/MobileInput.java +++ b/core/src/mindustry/input/MobileInput.java @@ -620,20 +620,16 @@ public boolean tap(float x, float y, int count, KeyCode button){ if(count == 2){ //reset payload target payloadTarget = null; - //apply command on double tap when own unit is tapped - if(!player.dead() && Mathf.within(worldx, worldy, player.unit().x, player.unit().y, player.unit().hitSize * 0.6f + 8f) && player.unit().type.commandLimit > 0){ - Call.unitCommand(player); - }else{ - //control a unit/block detected on first tap of double-tap - if(unitTapped != null){ - Call.unitControl(player, unitTapped); - recentRespawnTimer = 1f; - }else if(buildingTapped != null){ - Call.buildingControlSelect(player, buildingTapped); - recentRespawnTimer = 1f; - }else if(!tryBeginMine(cursor)){ - tileTapped(linked.build); - } + + //control a unit/block detected on first tap of double-tap + if(unitTapped != null){ + Call.unitControl(player, unitTapped); + recentRespawnTimer = 1f; + }else if(buildingTapped != null){ + Call.buildingControlSelect(player, buildingTapped); + recentRespawnTimer = 1f; + }else if(!tryBeginMine(cursor)){ + tileTapped(linked.build); } return false; } diff --git a/core/src/mindustry/io/TypeIO.java b/core/src/mindustry/io/TypeIO.java index 18acb76d1da2..8c57f2a34c65 100644 --- a/core/src/mindustry/io/TypeIO.java +++ b/core/src/mindustry/io/TypeIO.java @@ -92,9 +92,6 @@ public static void writeObject(Writes write, Object object){ write.b((byte)14); write.i(b.length); write.b(b); - }else if(object instanceof UnitCommand c){ - write.b((byte)15); - write.b(c.ordinal()); }else if(object instanceof boolean[] b){ write.b(16); write.i(b.length); @@ -165,7 +162,6 @@ public static Object readObjectBoxed(Reads read, boolean box){ read.b(bytes); yield bytes; } - case 15 -> UnitCommand.all[read.b()]; case 16 -> { int boollen = read.i(); boolean[] bools = new boolean[boollen]; @@ -385,9 +381,6 @@ public static void writeController(Writes write, UnitController control){ if(control instanceof Player p){ write.b(0); write.i(p.id); - }else if(control instanceof FormationAI form && form.leader != null){ - write.b(1); - write.i(form.leader.id); }else if(control instanceof LogicAI logic && logic.controller != null){ write.b(3); write.i(logic.controller.pos()); @@ -423,13 +416,6 @@ public static UnitController readController(Reads read, UnitController prev){ //make sure player exists if(player == null) return prev; return player; - }else if(type == 1){ //formation controller - int id = read.i(); - if(prev instanceof FormationAI f){ - f.leader = Groups.unit.getByID(id); - return f; - } - return new FormationAI(Groups.unit.getByID(id), null); }else if(type == 3){ int pos = read.i(); if(prev instanceof LogicAI pai){ @@ -475,7 +461,7 @@ public static UnitController readController(Reads read, UnitController prev){ //2: prev controller was a player, so replace this controller with *anything else* //...since AI doesn't update clientside it doesn't matter //TODO I hate this - return (!(prev instanceof AIController) || (prev instanceof FormationAI) || (prev instanceof LogicAI)) ? new GroundAI() : prev; + return (!(prev instanceof AIController) || (prev instanceof LogicAI)) ? new GroundAI() : prev; } } @@ -548,14 +534,6 @@ public static Team readTeam(Reads read){ return Team.get(read.b()); } - public static void writeUnitCommand(Writes write, UnitCommand reason){ - write.b((byte)reason.ordinal()); - } - - public static UnitCommand readUnitCommand(Reads read){ - return UnitCommand.all[read.b()]; - } - public static void writeAction(Writes write, AdminAction reason){ write.b((byte)reason.ordinal()); } diff --git a/core/src/mindustry/logic/GlobalConstants.java b/core/src/mindustry/logic/GlobalConstants.java index bb00e579d3d4..00fa84b6fe13 100644 --- a/core/src/mindustry/logic/GlobalConstants.java +++ b/core/src/mindustry/logic/GlobalConstants.java @@ -8,7 +8,6 @@ import mindustry.*; import mindustry.content.*; import mindustry.ctype.*; -import mindustry.entities.units.*; import mindustry.game.*; import mindustry.logic.LExecutor.*; import mindustry.type.*; @@ -20,7 +19,7 @@ /** Stores global constants for logic processors. */ public class GlobalConstants{ - public static final int ctrlProcessor = 1, ctrlPlayer = 2, ctrlFormation = 3; + public static final int ctrlProcessor = 1, ctrlPlayer = 2; public static final ContentType[] lookableContent = {ContentType.block, ContentType.unit, ContentType.item, ContentType.liquid}; /** Global random state. */ public static final Rand rand = new Rand(); @@ -50,7 +49,6 @@ public void init(){ put("@ctrlProcessor", ctrlProcessor); put("@ctrlPlayer", ctrlPlayer); - put("@ctrlFormation", ctrlFormation); //store base content @@ -83,10 +81,6 @@ public void init(){ put("@" + sensor.name(), sensor); } - for(UnitCommand cmd : UnitCommand.all){ - put("@command" + Strings.capitalize(cmd.name()), cmd); - } - logicIdToContent = new UnlockableContent[ContentType.all.length][]; contentIdToLogicId = new int[ContentType.all.length][]; diff --git a/core/src/mindustry/logic/LAccess.java b/core/src/mindustry/logic/LAccess.java index b2ee761cfa33..14d873089376 100644 --- a/core/src/mindustry/logic/LAccess.java +++ b/core/src/mindustry/logic/LAccess.java @@ -42,7 +42,6 @@ public enum LAccess{ flag, controlled, controller, - commanded, name, payloadCount, payloadType, diff --git a/core/src/mindustry/logic/LExecutor.java b/core/src/mindustry/logic/LExecutor.java index f39e93d6a134..1080fb183432 100644 --- a/core/src/mindustry/logic/LExecutor.java +++ b/core/src/mindustry/logic/LExecutor.java @@ -338,7 +338,7 @@ public UnitControlI(){ /** Checks is a unit is valid for logic AI control, and returns the controller. */ @Nullable public static LogicAI checkLogicAI(LExecutor exec, Object unitObj){ - if(unitObj instanceof Unit unit && unit.isValid() && exec.obj(varUnit) == unit && unit.team == exec.team && !unit.isPlayer() && !(unit.controller() instanceof FormationAI)){ + if(unitObj instanceof Unit unit && unit.isValid() && exec.obj(varUnit) == unit && unit.team == exec.team && !unit.isPlayer()){ if(unit.controller() instanceof LogicAI la){ la.controller = exec.building(varThis); return la; diff --git a/core/src/mindustry/maps/planet/ErekirPlanetGenerator.java b/core/src/mindustry/maps/planet/ErekirPlanetGenerator.java index 1e1e2fd03d57..fa207636f235 100644 --- a/core/src/mindustry/maps/planet/ErekirPlanetGenerator.java +++ b/core/src/mindustry/maps/planet/ErekirPlanetGenerator.java @@ -444,7 +444,6 @@ protected void generate(){ //it is very hot state.rules.attributes.set(Attribute.heat, 0.8f); state.rules.environment = sector.planet.defaultEnv; - state.rules.unitCommand = true; state.rules.placeRangeCheck = true; //TODO remove slag and arkycite around core. diff --git a/core/src/mindustry/mod/ClassMap.java b/core/src/mindustry/mod/ClassMap.java index 3b6c3ce655a6..9084b0dcfe26 100644 --- a/core/src/mindustry/mod/ClassMap.java +++ b/core/src/mindustry/mod/ClassMap.java @@ -1,6 +1,9 @@ package mindustry.mod; import arc.struct.*; +import mindustry.world.blocks.legacy.*; +import mindustry.world.consumers.*; + /** Generated class. Maps simple class names to concrete classes. For use in JSON mods. */ @SuppressWarnings("deprecation") public class ClassMap{ @@ -14,7 +17,6 @@ public class ClassMap{ classes.put("DefenderAI", mindustry.ai.types.DefenderAI.class); classes.put("FlyingAI", mindustry.ai.types.FlyingAI.class); classes.put("FlyingFollowAI", mindustry.ai.types.FlyingFollowAI.class); - classes.put("FormationAI", mindustry.ai.types.FormationAI.class); classes.put("GroundAI", mindustry.ai.types.GroundAI.class); classes.put("HugAI", mindustry.ai.types.HugAI.class); classes.put("LogicAI", mindustry.ai.types.LogicAI.class); @@ -296,11 +298,11 @@ public class ClassMap{ classes.put("BeamNodeBuild", mindustry.world.blocks.power.BeamNode.BeamNodeBuild.class); classes.put("BurnerGenerator", mindustry.world.blocks.power.BurnerGenerator.class); classes.put("BurnerGeneratorBuild", mindustry.world.blocks.power.BurnerGenerator.BurnerGeneratorBuild.class); - classes.put("ConditionalConsumePower", mindustry.world.blocks.power.ConditionalConsumePower.class); + classes.put("ConditionalConsumePower", ConsumePowerCondition.class); classes.put("ConsumeGenerator", mindustry.world.blocks.power.ConsumeGenerator.class); classes.put("ConsumeGeneratorBuild", mindustry.world.blocks.power.ConsumeGenerator.ConsumeGeneratorBuild.class); classes.put("DecayGenerator", mindustry.world.blocks.power.DecayGenerator.class); - classes.put("DynamicConsumePower", mindustry.world.blocks.power.DynamicConsumePower.class); + classes.put("DynamicConsumePower", ConsumePowerDynamic.class); classes.put("ImpactReactor", mindustry.world.blocks.power.ImpactReactor.class); classes.put("ImpactReactorBuild", mindustry.world.blocks.power.ImpactReactor.ImpactReactorBuild.class); classes.put("ItemLiquidGenerator", mindustry.world.blocks.power.ItemLiquidGenerator.class); @@ -372,8 +374,8 @@ public class ClassMap{ classes.put("Unloader", mindustry.world.blocks.storage.Unloader.class); classes.put("ContainerStat", mindustry.world.blocks.storage.Unloader.ContainerStat.class); classes.put("UnloaderBuild", mindustry.world.blocks.storage.Unloader.UnloaderBuild.class); - classes.put("CommandCenter", mindustry.world.blocks.units.CommandCenter.class); - classes.put("CommandBuild", mindustry.world.blocks.units.CommandCenter.CommandBuild.class); + classes.put("CommandCenter", LegacyCommandCenter.class); + classes.put("CommandBuild", LegacyCommandCenter.CommandBuild.class); classes.put("ControlCore", mindustry.world.blocks.units.ControlCore.class); classes.put("DroneCenter", mindustry.world.blocks.units.DroneCenter.class); classes.put("DroneCenterBuild", mindustry.world.blocks.units.DroneCenter.DroneCenterBuild.class); diff --git a/core/src/mindustry/mod/ContentParser.java b/core/src/mindustry/mod/ContentParser.java index b8219932ff5f..ba8dfc82121c 100644 --- a/core/src/mindustry/mod/ContentParser.java +++ b/core/src/mindustry/mod/ContentParser.java @@ -382,19 +382,19 @@ private T internalRead(Class type, Class elementType, JsonValue jsonData, if(value.has("consumes") && value.get("consumes").isObject()){ for(JsonValue child : value.get("consumes")){ switch(child.name){ - case "item" -> block.consumes.item(find(ContentType.item, child.asString())); - case "items" -> block.consumes.add((Consume)parser.readValue(ConsumeItems.class, child)); - case "liquid" -> block.consumes.add((Consume)parser.readValue(ConsumeLiquid.class, child)); - case "liquids" -> block.consumes.add((Consume)parser.readValue(ConsumeLiquids.class, child)); - case "coolant" -> block.consumes.add((Consume)parser.readValue(ConsumeCoolant.class, child)); + case "item" -> block.consumeItem(find(ContentType.item, child.asString())); + case "items" -> block.consume((Consume)parser.readValue(ConsumeItems.class, child)); + case "liquid" -> block.consume((Consume)parser.readValue(ConsumeLiquid.class, child)); + case "liquids" -> block.consume((Consume)parser.readValue(ConsumeLiquids.class, child)); + case "coolant" -> block.consume((Consume)parser.readValue(ConsumeCoolant.class, child)); case "power" -> { if(child.isNumber()){ - block.consumes.power(child.asFloat()); + block.consumePower(child.asFloat()); }else{ - block.consumes.add((Consume)parser.readValue(ConsumePower.class, child)); + block.consume((Consume)parser.readValue(ConsumePower.class, child)); } } - case "powerBuffered" -> block.consumes.powerBuffered(child.asFloat()); + case "powerBuffered" -> block.consumePowerBuffered(child.asFloat()); default -> throw new IllegalArgumentException("Unknown consumption type: '" + child.name + "' for block '" + block.name + "'."); } } diff --git a/core/src/mindustry/service/GameService.java b/core/src/mindustry/service/GameService.java index 76c647c25057..1429da3bcf35 100644 --- a/core/src/mindustry/service/GameService.java +++ b/core/src/mindustry/service/GameService.java @@ -6,7 +6,6 @@ import mindustry.*; import mindustry.content.*; import mindustry.ctype.*; -import mindustry.entities.units.*; import mindustry.game.EventType.*; import mindustry.game.SectorInfo.*; import mindustry.gen.*; @@ -113,12 +112,6 @@ private void registerEvents(){ } })); - Events.on(CommandIssueEvent.class, e -> { - if(campaign() && e.command == UnitCommand.attack){ - issueAttackCommand.complete(); - } - }); - Events.on(BlockBuildEndEvent.class, e -> { if(campaign() && e.unit != null && e.unit.isLocal() && !e.breaking){ SStat.blocksBuilt.add(); diff --git a/core/src/mindustry/type/UnitType.java b/core/src/mindustry/type/UnitType.java index c521c268755c..4a4e1dd402c0 100644 --- a/core/src/mindustry/type/UnitType.java +++ b/core/src/mindustry/type/UnitType.java @@ -91,7 +91,6 @@ public class UnitType extends UnlockableContent{ public boolean targetable = true; public boolean drawBuildBeam = true; public boolean rotateToBuilding = true; - public int commandLimit = 8; public float commandRadius = 150f; public float visualElevation = -1f; /** If true and this is a legged unit, this unit can walk over blocks. */ @@ -350,7 +349,6 @@ public void setStats(){ stats.add(Stat.size, StatValues.squared(hitSize / tilesize, StatUnit.blocksSquared)); stats.add(Stat.itemCapacity, itemCapacity); stats.add(Stat.range, (int)(maxRange / tilesize), StatUnit.blocks); - stats.add(Stat.commandLimit, commandLimit); if(abilities.any()){ var unique = new ObjectSet(); @@ -685,7 +683,7 @@ public ItemStack[] getTotalRequirements(){ //find reconstructor var rec = (Reconstructor)content.blocks().find(b -> b instanceof Reconstructor re && re.upgrades.contains(u -> u[1] == this)); - if(rec != null && rec.consumes.has(ConsumeType.item) && rec.consumes.get(ConsumeType.item) instanceof ConsumeItems ci){ + if(rec != null && Structs.find(rec.consumers, i -> i instanceof ConsumeItems) instanceof ConsumeItems ci){ if(prevReturn != null){ prevReturn[0] = rec.upgrades.find(u -> u[1] == this)[0]; } diff --git a/core/src/mindustry/type/ammo/PowerAmmoType.java b/core/src/mindustry/type/ammo/PowerAmmoType.java index 49d0b4dbb5bb..c1d2c4e0027a 100644 --- a/core/src/mindustry/type/ammo/PowerAmmoType.java +++ b/core/src/mindustry/type/ammo/PowerAmmoType.java @@ -38,17 +38,17 @@ public Color barColor(){ public void resupply(Unit unit){ float range = unit.hitSize + this.range; - Building build = Units.closestBuilding(unit.team, unit.x, unit.y, range, u -> u.block.consumes.hasPower() && u.block.consumes.getPower().buffered); + Building build = Units.closestBuilding(unit.team, unit.x, unit.y, range, u -> u.block.consPower != null && u.block.consPower.buffered); if(build != null){ - float amount = build.power.status * build.block.consumes.getPower().capacity; + float amount = build.power.status * build.block.consPower.capacity; float powerPerAmmo = totalPower / unit.type.ammoCapacity; float ammoRequired = unit.type.ammoCapacity - unit.ammo; float powerRequired = ammoRequired * powerPerAmmo; float powerTaken = Math.min(amount, powerRequired); if(powerTaken > 1){ - build.power.status -= powerTaken / build.block.consumes.getPower().capacity; + build.power.status -= powerTaken / build.block.consPower.capacity; unit.ammo += powerTaken / powerPerAmmo; Fx.itemTransfer.at(build.x, build.y, Math.max(powerTaken / 100f, 1f), Pal.power, unit); diff --git a/core/src/mindustry/type/unit/ErekirUnitType.java b/core/src/mindustry/type/unit/ErekirUnitType.java index 784e31b57975..306d9700557c 100644 --- a/core/src/mindustry/type/unit/ErekirUnitType.java +++ b/core/src/mindustry/type/unit/ErekirUnitType.java @@ -10,7 +10,6 @@ public class ErekirUnitType extends UnitType{ public ErekirUnitType(String name){ super(name); - commandLimit = 0; outlineColor = Pal.darkOutline; envDisabled = Env.space; unitBasedDefaultController = u -> !playerControllable || u.team.isAI() ? defaultController.get() : new CommandAI(); diff --git a/core/src/mindustry/ui/dialogs/CustomRulesDialog.java b/core/src/mindustry/ui/dialogs/CustomRulesDialog.java index 7d9b3810e7ae..8d52f0625274 100644 --- a/core/src/mindustry/ui/dialogs/CustomRulesDialog.java +++ b/core/src/mindustry/ui/dialogs/CustomRulesDialog.java @@ -171,7 +171,6 @@ void setup(){ main.row(); title("@rules.title.unit"); - check("@rules.unitcommand", b -> rules.unitCommand = b, () -> rules.unitCommand); check("@rules.unitammo", b -> rules.unitAmmo = b, () -> rules.unitAmmo); check("@rules.unitcapvariable", b -> rules.unitCapVariable = b, () -> rules.unitCapVariable); number("@rules.unitcap", true, f -> rules.unitCap = f, () -> rules.unitCap, -999, 999); diff --git a/core/src/mindustry/ui/fragments/HintsFragment.java b/core/src/mindustry/ui/fragments/HintsFragment.java index d4f33fafbf09..b310cbf066f3 100644 --- a/core/src/mindustry/ui/fragments/HintsFragment.java +++ b/core/src/mindustry/ui/fragments/HintsFragment.java @@ -165,7 +165,6 @@ public enum DefaultHint implements Hint{ boost(visibleDesktop, () -> !player.dead() && player.unit().type.canBoost, () -> Core.input.keyDown(Binding.boost)), blockInfo(() -> !(state.isCampaign() && state.rules.sector == SectorPresets.groundZero.sector && state.wave < 3), () -> ui.content.isShown()), derelict(() -> ui.hints.events.contains("derelictmouse"), () -> false), - command(() -> state.rules.defaultTeam.data().units.size > 3 && !net.active(), () -> player.unit().isCommanding()), payloadPickup(() -> !player.unit().dead && player.unit() instanceof Payloadc p && p.payloads().isEmpty(), () -> player.unit() instanceof Payloadc p && p.payloads().any()), payloadDrop(() -> !player.unit().dead && player.unit() instanceof Payloadc p && p.payloads().any(), () -> player.unit() instanceof Payloadc p && p.payloads().isEmpty()), waveFire(() -> Groups.fire.size() > 0 && Blocks.wave.unlockedNow(), () -> indexer.getFlagged(state.rules.defaultTeam, BlockFlag.extinguisher).size > 0), diff --git a/core/src/mindustry/world/Block.java b/core/src/mindustry/world/Block.java index c63518e18344..53aa9d5e3489 100644 --- a/core/src/mindustry/world/Block.java +++ b/core/src/mindustry/world/Block.java @@ -59,9 +59,6 @@ public class Block extends UnlockableContent implements Senseable{ public float liquidCapacity = 10f; public float liquidPressure = 1f; - public final BlockBars bars = new BlockBars(); - public final Consumers consumes = new Consumers(); - /** If true, this block outputs to its facing direction, when applicable. * Used for blending calculations. */ public boolean outputFacing = true; @@ -288,10 +285,25 @@ public class Block extends UnlockableContent implements Senseable{ public @Nullable Class subclass; /** Determines if this block gets a higher unloader priority. */ public boolean highUnloadPriority = false; - - public float selectScroll; //scroll position for certain blocks - public Prov buildType = null; //initialized later + /** Scroll position for certain blocks. */ + public float selectScroll; + /** Building that is created for this block. Initialized in init() via reflection. Set manually if modded. */ + public Prov buildType = null; + /** Configuration handlers by type. */ public ObjectMap, Cons2> configurations = new ObjectMap<>(); + /** Consumption filters. */ + public boolean[] itemFilter, liquidFilter; + /** Array of consumers used by this block. Only populated after init(). */ + public Consume[] consumers = {}, optionalConsumers = {}; + /** Set to true if this block has any consumers in its array. */ + public boolean hasConsumers; + /** The single power consumer, if applicable. */ + public @Nullable ConsumePower consPower; + + /** Map of bars by name. */ + protected OrderedMap> barMap = new OrderedMap<>(); + /** List for building up consumption before init(). */ + protected Seq consumeBuilder = new Seq<>(); protected TextureRegion[] generatedIcons; protected TextureRegion[] editorVariantRegions; @@ -304,7 +316,7 @@ public class Block extends UnlockableContent implements Senseable{ public TextureRegion[] teamRegions, variantRegions, variantShadowRegions; protected static final Seq tempTiles = new Seq<>(); - protected static final Seq tempTileEnts = new Seq<>(); + protected static final Seq tempBuilds = new Seq<>(); /** Dump timer ID.*/ protected final int timerDump = timers++; @@ -469,15 +481,29 @@ public void setStats(){ stats.add(Stat.maxConsecutive, 2, StatUnit.none); } - consumes.display(stats); + for(var c : consumers){ + c.display(stats); + } //Note: Power stats are added by the consumers. if(hasLiquids) stats.add(Stat.liquidCapacity, liquidCapacity, StatUnit.liquidUnits); if(hasItems && itemCapacity > 0) stats.add(Stat.itemCapacity, itemCapacity, StatUnit.items); } + public void addBar(String name, Func sup){ + barMap.put(name, (Func)sup); + } + + public void removeBar(String name){ + barMap.remove(name); + } + + public Iterable> listBars(){ + return barMap.values(); + } + public void addLiquidBar(Liquid liq){ - bars.add("liquid-" + liq.name, entity -> new Bar( + addBar("liquid-" + liq.name, entity -> new Bar( () -> liq.localizedName, liq::barColor, () -> entity.liquids.get(liq) / liquidCapacity) @@ -486,7 +512,7 @@ public void addLiquidBar(Liquid liq){ /** Adds a liquid bar that dynamically displays a liquid type. */ public void addLiquidBar(Func current){ - bars.add("liquid", entity -> new Bar( + addBar("liquid", entity -> new Bar( () -> current.get((T)entity) == null || entity.liquids.get(current.get((T)entity)) <= 0.001f ? Core.bundle.get("bar.liquid") : current.get((T)entity).localizedName, () -> current.get((T)entity) == null ? Color.clear : current.get((T)entity).barColor(), () -> current.get((T)entity) == null ? 0f : entity.liquids.get(current.get((T)entity)) / liquidCapacity) @@ -494,23 +520,22 @@ public void addLiquidBar(Func current){ } public void setBars(){ - bars.add("health", entity -> new Bar("stat.health", Pal.health, entity::healthf).blink(Color.white)); + addBar("health", entity -> new Bar("stat.health", Pal.health, entity::healthf).blink(Color.white)); - if(hasPower && consumes.hasPower()){ - ConsumePower cons = consumes.getPower(); - boolean buffered = cons.buffered; - float capacity = cons.capacity; + if(consPower != null){ + boolean buffered = consPower.buffered; + float capacity = consPower.capacity; - bars.add("power", entity -> new Bar( + addBar("power", entity -> new Bar( () -> buffered ? Core.bundle.format("bar.poweramount", Float.isNaN(entity.power.status * capacity) ? "" : UI.formatAmount((int)(entity.power.status * capacity))) : Core.bundle.get("bar.power"), () -> Pal.powerBar, - () -> Mathf.zero(cons.requestedPower(entity)) && entity.power.graph.getPowerProduced() + entity.power.graph.getBatteryStored() > 0f ? 1f : entity.power.status) + () -> Mathf.zero(consPower.requestedPower(entity)) && entity.power.graph.getPowerProduced() + entity.power.graph.getBatteryStored() > 0f ? 1f : entity.power.status) ); } if(hasItems && configurable){ - bars.add("items", entity -> new Bar( + addBar("items", entity -> new Bar( () -> Core.bundle.format("bar.items", entity.items.total()), () -> Pal.items, () -> (float)entity.items.total() / itemCapacity) @@ -533,9 +558,9 @@ public void setBars(){ boolean added = false; + //TODO handle in consumer //add bars for *specific* consumed liquids - if(consumes.has(ConsumeType.liquid)){ - var consl = consumes.get(ConsumeType.liquid); + for(var consl : consumers){ if(consl instanceof ConsumeLiquid liq){ added = true; addLiquidBar(liq.liquid); @@ -554,6 +579,14 @@ public void setBars(){ } } + public boolean consumesItem(Item item){ + return itemFilter[item.id]; + } + + public boolean consumesLiquid(Liquid liq){ + return liquidFilter[liq.id]; + } + public boolean canReplace(Block other){ if(other.alwaysReplace) return true; return other.replaceable && (other != this || rotate) && this.group != BlockGroup.none && other.group == this.group && @@ -818,6 +851,67 @@ public boolean isStatic(){ return cacheLayer == CacheLayer.walls; } + public T findConsumer(Boolf filter){ + return consumers.length == 0 ? (T)consumeBuilder.find(filter) : (T)Structs.find(consumers, filter); + } + + public ConsumeLiquid consumeLiquid(Liquid liquid, float amount){ + return consume(new ConsumeLiquid(liquid, amount)); + } + + public ConsumeLiquids consumeLiquids(LiquidStack... stacks){ + return consume(new ConsumeLiquids(stacks)); + } + + /** + * Creates a consumer which directly uses power without buffering it. + * @param powerPerTick The amount of power which is required each tick for 100% efficiency. + * @return the created consumer object. + */ + public ConsumePower consumePower(float powerPerTick){ + return consume(new ConsumePower(powerPerTick, 0.0f, false)); + } + + /** Creates a consumer which only consumes power when the condition is met. */ + public ConsumePower consumePowerCond(float usage, Boolf cons){ + return consume(new ConsumePowerCondition(usage, (Boolf)cons)); + } + + /** Creates a consumer that consumes a dynamic amount of power. */ + public ConsumePower consumePowerDynamic(Floatf usage){ + return consume(new ConsumePowerDynamic((Floatf)usage)); + } + + /** + * Creates a consumer which stores power. + * @param powerCapacity The maximum capacity in power units. + */ + public ConsumePower consumePowerBuffered(float powerCapacity){ + return consume(new ConsumePower(0f, powerCapacity, true)); + } + + public ConsumeItems consumeItem(Item item){ + return consumeItem(item, 1); + } + + public ConsumeItems consumeItem(Item item, int amount){ + return consume(new ConsumeItems(new ItemStack[]{new ItemStack(item, amount)})); + } + + public ConsumeItems consumeItems(ItemStack... items){ + return consume(new ConsumeItems(items)); + } + + public T consume(T consume){ + if(consume instanceof ConsumePower){ + //there can only be one power consumer + consumeBuilder.removeAll(b -> b instanceof ConsumePower); + consPower = (ConsumePower)consume; + } + consumeBuilder.add(consume); + return consume; + } + public void setupRequirements(Category cat, ItemStack[] stacks){ requirements(cat, stacks); } @@ -904,8 +998,8 @@ public void getDependencies(Cons cons){ } //also requires inputs - consumes.each(c -> { - if(c.isOptional()) return; + for(var c : consumeBuilder){ + if(c.optional) continue; if(c instanceof ConsumeItems i){ for(ItemStack stack : i.items){ @@ -918,7 +1012,7 @@ public void getDependencies(Cons cons){ cons.get(stack.liquid); } } - }); + } } @Override @@ -966,7 +1060,7 @@ public void init(){ clipSize = Math.max(clipSize, lightRadius * 2f); } - if(group == BlockGroup.transportation || consumes.has(ConsumeType.item) || category == Category.distribution){ + if(group == BlockGroup.transportation || category == Category.distribution){ acceptsItems = true; } @@ -981,15 +1075,21 @@ public void init(){ buildCost *= buildCostMultiplier; - if(consumes.has(ConsumeType.power)) hasPower = true; - if(consumes.has(ConsumeType.item)) hasItems = true; - if(consumes.has(ConsumeType.liquid)) hasLiquids = true; + consumers = consumeBuilder.toArray(Consume.class); + optionalConsumers = consumeBuilder.filter(consume -> consume.optional).toArray(Consume.class); + hasConsumers = consumers.length > 0; + itemFilter = new boolean[content.items().size]; + liquidFilter = new boolean[content.liquids().size]; + + for(Consume cons : consumers){ + cons.apply(this); + } setBars(); stats.useCategories = true; - consumes.init(); + //TODO check for double power consumption if(!logicConfigurable){ configurations.each((key, val) -> { @@ -999,9 +1099,9 @@ public void init(){ }); } - if(!outputsPower && consumes.hasPower() && consumes.getPower().buffered){ + if(!outputsPower && consPower != null && consPower.buffered){ Log.warn("Consumer using buffered power: @. Disabling buffered power.", name); - consumes.getPower().buffered = false; + consPower.buffered = false; } if(buildVisibility == BuildVisibility.sandboxOnly){ @@ -1156,7 +1256,7 @@ public double sense(LAccess sensor){ case size -> size * tilesize; case itemCapacity -> itemCapacity; case liquidCapacity -> liquidCapacity; - case powerCapacity -> consumes.hasPower() && consumes.getPower().buffered ? consumes.getPower().capacity : 0f; + case powerCapacity -> consPower != null && consPower.buffered ? consPower.capacity : 0f; default -> Double.NaN; }; } diff --git a/core/src/mindustry/world/blocks/campaign/Accelerator.java b/core/src/mindustry/world/blocks/campaign/Accelerator.java index d4049b2e3566..b839d7b1ec36 100644 --- a/core/src/mindustry/world/blocks/campaign/Accelerator.java +++ b/core/src/mindustry/world/blocks/campaign/Accelerator.java @@ -41,7 +41,7 @@ public void init(){ capacities[stack.item.id] = stack.amount; itemCapacity += stack.amount; } - consumes.items(launching.requirements); + consumeItems(launching.requirements); super.init(); } diff --git a/core/src/mindustry/world/blocks/campaign/LaunchPad.java b/core/src/mindustry/world/blocks/campaign/LaunchPad.java index 06c4fdb2d0e0..203ea3e25512 100644 --- a/core/src/mindustry/world/blocks/campaign/LaunchPad.java +++ b/core/src/mindustry/world/blocks/campaign/LaunchPad.java @@ -55,10 +55,10 @@ public void setStats(){ public void setBars(){ super.setBars(); - bars.add("items", entity -> new Bar(() -> Core.bundle.format("bar.items", entity.items.total()), () -> Pal.items, () -> (float)entity.items.total() / itemCapacity)); + addBar("items", entity -> new Bar(() -> Core.bundle.format("bar.items", entity.items.total()), () -> Pal.items, () -> (float)entity.items.total() / itemCapacity)); //TODO is "bar.launchcooldown" the right terminology? - bars.add("progress", (LaunchPadBuild build) -> new Bar(() -> Core.bundle.get("bar.launchcooldown"), () -> Pal.ammo, () -> Mathf.clamp(build.launchCounter / launchTime))); + addBar("progress", (LaunchPadBuild build) -> new Bar(() -> Core.bundle.get("bar.launchcooldown"), () -> Pal.ammo, () -> Mathf.clamp(build.launchCounter / launchTime))); } @Override diff --git a/core/src/mindustry/world/blocks/defense/BuildTurret.java b/core/src/mindustry/world/blocks/defense/BuildTurret.java index 6c8b74e476f3..7565ef2fb2ae 100644 --- a/core/src/mindustry/world/blocks/defense/BuildTurret.java +++ b/core/src/mindustry/world/blocks/defense/BuildTurret.java @@ -57,7 +57,6 @@ public void init(){ hitSize = 0f; health = 1; itemCapacity = 0; - commandLimit = 0; rotateSpeed = BuildTurret.this.rotateSpeed; buildBeamOffset = BuildTurret.this.buildBeamOffset; buildRange = BuildTurret.this.range; diff --git a/core/src/mindustry/world/blocks/defense/DirectionalForceProjector.java b/core/src/mindustry/world/blocks/defense/DirectionalForceProjector.java index 6ca4b35ab601..8fb12698e780 100644 --- a/core/src/mindustry/world/blocks/defense/DirectionalForceProjector.java +++ b/core/src/mindustry/world/blocks/defense/DirectionalForceProjector.java @@ -20,6 +20,7 @@ //TODO use completely different layer //TODO consume heat +//TODO broken class!!!!! public class DirectionalForceProjector extends Block{ protected static final Vec2 intersectOut = new Vec2(), p1 = new Vec2(), p2 = new Vec2(); protected static DirectionalForceProjectorBuild paramEntity; @@ -82,7 +83,7 @@ public void init(){ @Override public void setBars(){ super.setBars(); - bars.add("shield", (DirectionalForceProjectorBuild entity) -> new Bar("stat.shieldhealth", Pal.accent, () -> entity.broken ? 0f : 1f - entity.buildup / (shieldHealth)).blink(Color.white)); + addBar("shield", (DirectionalForceProjectorBuild entity) -> new Bar("stat.shieldhealth", Pal.accent, () -> entity.broken ? 0f : 1f - entity.buildup / (shieldHealth)).blink(Color.white)); } @Override @@ -138,9 +139,10 @@ public void updateTile(){ warmup = Mathf.lerpDelta(warmup, efficiency(), 0.1f); - if(buildup > 0 && consumes.has(ConsumeType.liquid)){ + //TODO aaaaaaaaaaaaAAAAAAAAAAAAAAaa + if(buildup > 0 && false){ float scale = !broken ? cooldownNormal : cooldownBrokenBase; - Consume cons = consumes.get(ConsumeType.liquid); + Consume cons = null; if(cons.valid(this)){ cons.update(this); scale *= (cooldownLiquid * (1f + (liquids.current().heatCapacity - 0.4f) * 0.9f)); diff --git a/core/src/mindustry/world/blocks/defense/ForceProjector.java b/core/src/mindustry/world/blocks/defense/ForceProjector.java index 98653a318c24..152a823b8883 100644 --- a/core/src/mindustry/world/blocks/defense/ForceProjector.java +++ b/core/src/mindustry/world/blocks/defense/ForceProjector.java @@ -37,6 +37,9 @@ public class ForceProjector extends Block{ public Effect shieldBreakEffect = Fx.shieldBreak; public @Load("@-top") TextureRegion topRegion; + //TODO json support + public @Nullable Consume boostConsumer; + protected static ForceBuild paramEntity; protected static Effect paramEffect; protected static final Cons shieldConsumer = bullet -> { @@ -61,7 +64,7 @@ public ForceProjector(String name){ ambientSoundVolume = 0.08f; if(consumeCoolant){ - consumes.add(new ConsumeCoolant(coolantConsumption)).boost().update(false); + consume(new ConsumeCoolant(coolantConsumption)).boost().update(false); } } @@ -74,7 +77,7 @@ public void init(){ @Override public void setBars(){ super.setBars(); - bars.add("shield", (ForceBuild entity) -> new Bar("stat.shieldhealth", Pal.accent, () -> entity.broken ? 0f : 1f - entity.buildup / (shieldHealth + phaseShieldBoost * entity.phaseHeat)).blink(Color.white)); + addBar("shield", (ForceBuild entity) -> new Bar("stat.shieldhealth", Pal.accent, () -> entity.broken ? 0f : 1f - entity.buildup / (shieldHealth + phaseShieldBoost * entity.phaseHeat)).blink(Color.white)); } @Override @@ -84,7 +87,7 @@ public boolean outputsItems(){ @Override public void setStats(){ - boolean consItems = consumes.has(ConsumeType.item); + boolean consItems = boostConsumer != null; if(consItems) stats.timePeriod = phaseUseTime; super.setStats(); @@ -139,7 +142,7 @@ public void pickedUp(){ @Override public void updateTile(){ - boolean phaseValid = consumes.has(ConsumeType.item) && consumes.get(ConsumeType.item).valid(this); + boolean phaseValid = boostConsumer != null && boostConsumer.valid(this); phaseHeat = Mathf.lerpDelta(phaseHeat, Mathf.num(phaseValid), 0.1f); @@ -158,13 +161,15 @@ public void updateTile(){ if(buildup > 0){ float scale = !broken ? cooldownNormal : cooldownBrokenBase; + //TODO I hate this system + /* if(consumes.has(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)); } - } + }*/ buildup -= delta() * scale; } diff --git a/core/src/mindustry/world/blocks/defense/OverdriveProjector.java b/core/src/mindustry/world/blocks/defense/OverdriveProjector.java index db22ff6ac6f4..435b65a40733 100644 --- a/core/src/mindustry/world/blocks/defense/OverdriveProjector.java +++ b/core/src/mindustry/world/blocks/defense/OverdriveProjector.java @@ -76,7 +76,7 @@ public void setStats(){ @Override public void setBars(){ super.setBars(); - bars.add("boost", (OverdriveBuild entity) -> new Bar(() -> Core.bundle.format("bar.boost", Mathf.round(Math.max((entity.realBoost() * 100 - 100), 0))), () -> Pal.accent, () -> entity.realBoost() / (hasBoost ? speedBoost + speedBoostPhase : speedBoost))); + addBar("boost", (OverdriveBuild entity) -> new Bar(() -> Core.bundle.format("bar.boost", Mathf.round(Math.max((entity.realBoost() * 100 - 100), 0))), () -> Pal.accent, () -> entity.realBoost() / (hasBoost ? speedBoost + speedBoostPhase : speedBoost))); } public class OverdriveBuild extends Building implements Ranged{ diff --git a/core/src/mindustry/world/blocks/defense/turrets/BaseTurret.java b/core/src/mindustry/world/blocks/defense/turrets/BaseTurret.java index 59ce1cb3e057..7867f17157c9 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/BaseTurret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/BaseTurret.java @@ -20,6 +20,7 @@ public class BaseTurret extends Block{ public float rotateSpeed = 5; public float coolantUsage = 0.2f; + @Deprecated public boolean acceptCoolant = true; /** Effect displayed when coolant is used. */ public Effect coolEffect = Fx.fuelburn; @@ -28,6 +29,8 @@ public class BaseTurret extends Block{ /** Liquid that is used by coolant; null to use default. */ public @Nullable Liquid coolantOverride; + protected @Nullable ConsumeLiquidBase coolantConsumer; + public BaseTurret(String name){ super(name); @@ -41,13 +44,18 @@ public BaseTurret(String name){ @Override public void init(){ - if(acceptCoolant && !consumes.has(ConsumeType.liquid)){ + //TODO fundamentally flawed + if(acceptCoolant && findConsumer(f -> f instanceof ConsumeLiquidBase) == null){ hasLiquids = true; - consumes.add(coolantOverride != null ? new ConsumeLiquid(coolantOverride, coolantUsage) : new ConsumeCoolant(coolantUsage)).update(false).boost(); + consume(coolantOverride != null ? new ConsumeLiquid(coolantOverride, coolantUsage) : new ConsumeCoolant(coolantUsage)).update(false).boost(); } placeOverlapRange = Math.max(placeOverlapRange, range + placeOverlapMargin); super.init(); + + if(acceptCoolant){ + coolantConsumer = findConsumer(c -> c instanceof ConsumeLiquidBase && c.booster); + } } @Override diff --git a/core/src/mindustry/world/blocks/defense/turrets/ContinuousLiquidTurret.java b/core/src/mindustry/world/blocks/defense/turrets/ContinuousLiquidTurret.java index 496b549f8961..75e87c73fbea 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/ContinuousLiquidTurret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/ContinuousLiquidTurret.java @@ -41,7 +41,7 @@ public void setStats(){ @Override public void init(){ //TODO display ammoMultiplier. - consumes.add(new ConsumeLiquidFilter(i -> ammoTypes.containsKey(i), liquidConsumed){ + consume(new ConsumeLiquidFilter(i -> ammoTypes.containsKey(i), liquidConsumed){ @Override public boolean valid(Building build){ return build.liquids.currentAmount() >= use(build); diff --git a/core/src/mindustry/world/blocks/defense/turrets/ContinuousTurret.java b/core/src/mindustry/world/blocks/defense/turrets/ContinuousTurret.java index 4dd4cadcc626..b0e91c4eb3b8 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/ContinuousTurret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/ContinuousTurret.java @@ -60,14 +60,9 @@ public BulletType peekAmmo(){ public void updateTile(){ super.updateTile(); - //unclean way of calculating ammo fraction to display + //TODO unclean way of calculating ammo fraction to display float ammoFract = efficiency(); - var liq = consumes.getOrNull(ConsumeType.liquid); - if(liq instanceof ConsumeLiquids cons){ - for(var stack : cons.liquids){ - ammoFract = Math.min(ammoFract, liquids.get(stack.liquid) / liquidCapacity); - } - }else if(liq instanceof ConsumeLiquid cons){ + if(findConsumer(f -> f instanceof ConsumeLiquidBase) instanceof ConsumeLiquid cons){ ammoFract = Math.min(ammoFract, liquids.get(cons.liquid) / liquidCapacity); } diff --git a/core/src/mindustry/world/blocks/defense/turrets/ItemTurret.java b/core/src/mindustry/world/blocks/defense/turrets/ItemTurret.java index 76d6a8e08e2b..4639782d179d 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/ItemTurret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/ItemTurret.java @@ -57,7 +57,7 @@ public void setStats(){ @Override public void init(){ - consumes.add(new ConsumeItemFilter(i -> ammoTypes.containsKey(i)){ + consume(new ConsumeItemFilter(i -> ammoTypes.containsKey(i)){ @Override public void build(Building build, Table table){ MultiReqImage image = new MultiReqImage(); diff --git a/core/src/mindustry/world/blocks/defense/turrets/LaserTurret.java b/core/src/mindustry/world/blocks/defense/turrets/LaserTurret.java index 1ddda5750031..6e62af59eade 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/LaserTurret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/LaserTurret.java @@ -11,6 +11,7 @@ import static mindustry.Vars.*; /** A turret that fires a continuous beam with a delay between shots. Liquid coolant is required. Yes, this class name is awful. */ +@Deprecated public class LaserTurret extends PowerTurret{ public float firingMoveFract = 0.25f; public float shootDuration = 100f; @@ -18,7 +19,7 @@ public class LaserTurret extends PowerTurret{ public LaserTurret(String name){ super(name); - consumes.add(new ConsumeCoolant(0.01f)).update(false); + consume(new ConsumeCoolant(0.01f)).update(false); coolantMultiplier = 1f; } @@ -27,7 +28,8 @@ public void setStats(){ super.setStats(); stats.remove(Stat.booster); - stats.add(Stat.input, StatValues.boosters(reloadTime, consumes.get(ConsumeType.liquid).amount, coolantMultiplier, false, l -> consumes.liquidfilters.get(l.id))); + //TODO bad + stats.add(Stat.input, StatValues.boosters(reloadTime, coolantConsumer.amount, coolantMultiplier, false, l -> consumesLiquid(l))); } public class LaserTurretBuild extends PowerTurretBuild{ @@ -67,7 +69,7 @@ public void updateTile(){ }else if(reload > 0){ wasShooting = true; Liquid liquid = liquids.current(); - float maxUsed = consumes.get(ConsumeType.liquid).amount; + float maxUsed = coolantConsumer.amount; float used = (cheating() ? maxUsed : Math.min(liquids.get(liquid), maxUsed)) * delta(); reload -= used * liquid.heatCapacity * coolantMultiplier; diff --git a/core/src/mindustry/world/blocks/defense/turrets/LiquidTurret.java b/core/src/mindustry/world/blocks/defense/turrets/LiquidTurret.java index 5f798c48480e..577bd074bd10 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/LiquidTurret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/LiquidTurret.java @@ -41,7 +41,7 @@ public void setStats(){ @Override public void init(){ - consumes.add(new ConsumeLiquidFilter(i -> ammoTypes.containsKey(i), 1f){ + consume(new ConsumeLiquidFilter(i -> ammoTypes.containsKey(i), 1f){ @Override public boolean valid(Building build){ return build.liquids.currentAmount() >= 0.001f; diff --git a/core/src/mindustry/world/blocks/defense/turrets/PayloadTurret.java b/core/src/mindustry/world/blocks/defense/turrets/PayloadTurret.java index 0ce4ea3ef4c9..6741a203627d 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/PayloadTurret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/PayloadTurret.java @@ -57,7 +57,7 @@ public void setStats(){ @Override public void init(){ - consumes.add(new ConsumePayloadFilter(i -> ammoTypes.containsKey(i)){ + consume(new ConsumePayloadFilter(i -> ammoTypes.containsKey(i)){ @Override public void build(Building build, Table table){ MultiReqImage image = new MultiReqImage(); diff --git a/core/src/mindustry/world/blocks/defense/turrets/ReloadTurret.java b/core/src/mindustry/world/blocks/defense/turrets/ReloadTurret.java index c16659490f4b..560bca7ce0bf 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/ReloadTurret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/ReloadTurret.java @@ -3,7 +3,6 @@ import arc.math.*; import arc.util.*; import mindustry.type.*; -import mindustry.world.consumers.*; import mindustry.world.meta.*; import static mindustry.Vars.*; @@ -19,8 +18,8 @@ public ReloadTurret(String name){ public void setStats(){ super.setStats(); - if(acceptCoolant){ - stats.add(Stat.booster, StatValues.boosters(reloadTime, consumes.get(ConsumeType.liquid).amount, coolantMultiplier, true, l -> l.coolant && consumes.liquidfilters.get(l.id))); + if(acceptCoolant && coolantConsumer != null){ + stats.add(Stat.booster, StatValues.boosters(reloadTime, coolantConsumer.amount, coolantMultiplier, true, l -> l.coolant && consumesLiquid(l))); } } @@ -36,7 +35,7 @@ public void created(){ protected void updateCooling(){ if(reload < reloadTime && acceptCoolant){ - float maxUsed = consumes.get(ConsumeType.liquid).amount; + float maxUsed = coolantConsumer.amount; Liquid liquid = liquids.current(); float used = Math.min(liquids.get(liquid), maxUsed * Time.delta) * baseReloadSpeed(); diff --git a/core/src/mindustry/world/blocks/defense/turrets/TractorBeamTurret.java b/core/src/mindustry/world/blocks/defense/turrets/TractorBeamTurret.java index 65d08d42a346..ff0c6749e3b7 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/TractorBeamTurret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/TractorBeamTurret.java @@ -12,7 +12,6 @@ import mindustry.gen.*; import mindustry.graphics.*; import mindustry.type.*; -import mindustry.world.consumers.*; import mindustry.world.meta.*; import static mindustry.Vars.*; @@ -88,7 +87,7 @@ public void updateTile(){ //consume coolant if(target != null && acceptCoolant){ - float maxUsed = consumes.get(ConsumeType.liquid).amount; + float maxUsed = coolantConsumer.amount; Liquid liquid = liquids.current(); diff --git a/core/src/mindustry/world/blocks/defense/turrets/Turret.java b/core/src/mindustry/world/blocks/defense/turrets/Turret.java index 8f41554dd0c0..791e20377379 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/Turret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/Turret.java @@ -138,7 +138,7 @@ public void setBars(){ super.setBars(); if(heatRequirement > 0){ - bars.add("heat", (TurretBuild entity) -> + addBar("heat", (TurretBuild entity) -> new Bar(() -> Core.bundle.format("bar.heatpercent", (int)entity.heatReq, (int)(Math.min(entity.heatReq / heatRequirement, maxHeatEfficiency) * 100)), () -> Pal.lightOrange, diff --git a/core/src/mindustry/world/blocks/distribution/DirectionalUnloader.java b/core/src/mindustry/world/blocks/distribution/DirectionalUnloader.java index 092edeb42189..5192530ccdb9 100644 --- a/core/src/mindustry/world/blocks/distribution/DirectionalUnloader.java +++ b/core/src/mindustry/world/blocks/distribution/DirectionalUnloader.java @@ -61,7 +61,7 @@ public void drawRequestConfig(BuildPlan plan, Eachable list){ @Override public void setBars(){ super.setBars(); - bars.remove("items"); + removeBar("items"); } @Override diff --git a/core/src/mindustry/world/blocks/heat/HeatConductor.java b/core/src/mindustry/world/blocks/heat/HeatConductor.java index 4979fefc17ba..0ec24898bdcb 100644 --- a/core/src/mindustry/world/blocks/heat/HeatConductor.java +++ b/core/src/mindustry/world/blocks/heat/HeatConductor.java @@ -27,7 +27,7 @@ public void setBars(){ super.setBars(); //TODO show number - bars.add("heat", (HeatConductorBuild entity) -> new Bar(() -> Core.bundle.format("bar.heatamount", (int)entity.heat), () -> Pal.lightOrange, () -> entity.heat / visualMaxHeat)); + addBar("heat", (HeatConductorBuild entity) -> new Bar(() -> Core.bundle.format("bar.heatamount", (int)entity.heat), () -> Pal.lightOrange, () -> entity.heat / visualMaxHeat)); } @Override diff --git a/core/src/mindustry/world/blocks/heat/HeatProducer.java b/core/src/mindustry/world/blocks/heat/HeatProducer.java index b54f4cd5eb14..0b95cd82abf5 100644 --- a/core/src/mindustry/world/blocks/heat/HeatProducer.java +++ b/core/src/mindustry/world/blocks/heat/HeatProducer.java @@ -33,7 +33,7 @@ public void setStats(){ public void setBars(){ super.setBars(); - bars.add("heat", (HeatProducerBuild entity) -> new Bar("bar.heat", Pal.lightOrange, () -> entity.heat / heatOutput)); + addBar("heat", (HeatProducerBuild entity) -> new Bar("bar.heat", Pal.lightOrange, () -> entity.heat / heatOutput)); } public class HeatProducerBuild extends GenericCrafterBuild implements HeatBlock{ diff --git a/core/src/mindustry/world/blocks/legacy/LegacyCommandCenter.java b/core/src/mindustry/world/blocks/legacy/LegacyCommandCenter.java new file mode 100644 index 000000000000..5ea8aee12af7 --- /dev/null +++ b/core/src/mindustry/world/blocks/legacy/LegacyCommandCenter.java @@ -0,0 +1,28 @@ +package mindustry.world.blocks.legacy; + +import arc.util.io.*; +import mindustry.gen.*; + +public class LegacyCommandCenter extends LegacyBlock{ + + public LegacyCommandCenter(String name){ + super(name); + + update = true; + } + + public class CommandBuild extends Building{ + + @Override + public void write(Writes write){ + super.write(write); + write.b(0); + } + + @Override + public void read(Reads read, byte version){ + super.read(read, version); + read.b(); + } + } +} diff --git a/core/src/mindustry/world/blocks/liquid/LiquidJunction.java b/core/src/mindustry/world/blocks/liquid/LiquidJunction.java index a781a4fa5259..5ac5e0064da5 100644 --- a/core/src/mindustry/world/blocks/liquid/LiquidJunction.java +++ b/core/src/mindustry/world/blocks/liquid/LiquidJunction.java @@ -21,7 +21,7 @@ public void setStats(){ @Override public void setBars(){ super.setBars(); - bars.remove("liquid"); + removeBar("liquid"); } @Override diff --git a/core/src/mindustry/world/blocks/payloads/BlockProducer.java b/core/src/mindustry/world/blocks/payloads/BlockProducer.java index 0796775b56e3..969aae4f958d 100644 --- a/core/src/mindustry/world/blocks/payloads/BlockProducer.java +++ b/core/src/mindustry/world/blocks/payloads/BlockProducer.java @@ -33,7 +33,7 @@ public BlockProducer(String name){ rotate = true; regionRotated1 = 1; - consumes.add(new ConsumeItemDynamic((BlockProducerBuild e) -> e.recipe() != null ? e.recipe().requirements : ItemStack.empty)); + consume(new ConsumeItemDynamic((BlockProducerBuild e) -> e.recipe() != null ? e.recipe().requirements : ItemStack.empty)); } @Override @@ -52,7 +52,7 @@ public void drawRequestRegion(BuildPlan plan, Eachable list){ public void setBars(){ super.setBars(); - bars.add("progress", (BlockProducerBuild entity) -> new Bar("bar.progress", Pal.ammo, () -> entity.recipe() == null ? 0f : (entity.progress / entity.recipe().buildCost))); + addBar("progress", (BlockProducerBuild entity) -> new Bar("bar.progress", Pal.ammo, () -> entity.recipe() == null ? 0f : (entity.progress / entity.recipe().buildCost))); } public abstract class BlockProducerBuild extends PayloadBlockBuild{ diff --git a/core/src/mindustry/world/blocks/payloads/PayloadDeconstructor.java b/core/src/mindustry/world/blocks/payloads/PayloadDeconstructor.java index 29c25120a687..cd2df6d253d0 100644 --- a/core/src/mindustry/world/blocks/payloads/PayloadDeconstructor.java +++ b/core/src/mindustry/world/blocks/payloads/PayloadDeconstructor.java @@ -43,7 +43,7 @@ public TextureRegion[] icons(){ public void setBars(){ super.setBars(); - bars.add("progress", (PayloadDeconstructorBuild e) -> new Bar("bar.progress", Pal.ammo, () -> e.progress)); + addBar("progress", (PayloadDeconstructorBuild e) -> new Bar("bar.progress", Pal.ammo, () -> e.progress)); } public class PayloadDeconstructorBuild extends PayloadBlockBuild{ diff --git a/core/src/mindustry/world/blocks/payloads/PayloadLoader.java b/core/src/mindustry/world/blocks/payloads/PayloadLoader.java index de1756f4b811..4de001e17478 100644 --- a/core/src/mindustry/world/blocks/payloads/PayloadLoader.java +++ b/core/src/mindustry/world/blocks/payloads/PayloadLoader.java @@ -54,7 +54,7 @@ public boolean outputsItems(){ public void setBars(){ super.setBars(); - bars.add("progress", (PayloadLoaderBuild build) -> new Bar(() -> + addBar("progress", (PayloadLoaderBuild build) -> new Bar(() -> Core.bundle.format(build.payload != null && build.payload.block().hasItems ? "bar.items" : "bar.loadprogress", build.payload == null || !build.payload.block().hasItems ? 0 : build.payload.build.items.total()), () -> Pal.items, build::fraction)); } @@ -70,8 +70,8 @@ public void drawRequestRegion(BuildPlan plan, Eachable list){ @Override public void init(){ if(loadPowerDynamic){ - basePowerUse = consumes.hasPower() ? consumes.getPower().usage : 0f; - consumes.powerDynamic((PayloadLoaderBuild loader) -> loader.hasBattery() && !loader.exporting ? maxPowerConsumption + basePowerUse : basePowerUse); + basePowerUse = consPower != null ? consPower.usage : 0f; + consumePowerDynamic((PayloadLoaderBuild loader) -> loader.hasBattery() && !loader.exporting ? maxPowerConsumption + basePowerUse : basePowerUse); } super.init(); @@ -90,7 +90,7 @@ public boolean acceptPayload(Building source, Payload payload){ //liquid container (build.build.block().hasLiquids && build.block().liquidCapacity >= 10f) || //battery - (build.build.block.consumes.hasPower() && build.build.block.consumes.getPower().buffered) + (build.build.block.consPower != null && build.build.block.consPower.buffered) ); } @@ -153,7 +153,7 @@ public void updateTile(){ payload.build.handleItem(payload.build, item); items.remove(item, 1); break; - }else if(payload.block().separateItemCapacity || payload.block().consumes.consumesItem(item)){ + }else if(payload.block().separateItemCapacity || payload.block().consumesItem(item)){ exporting = true; break; } @@ -183,7 +183,7 @@ public void updateTile(){ float availableInput = Math.max(powerInput - basePowerUse, 0f); //charge the battery - float cap = payload.block().consumes.getPower().capacity; + float cap = payload.block().consPower.capacity; payload.build.power.status += availableInput / cap * edelta(); //export if full @@ -212,7 +212,7 @@ public boolean shouldExport(){ } public boolean hasBattery(){ - return payload != null && payload.block().hasPower && payload.block().consumes.getPower().buffered; + return payload != null && payload.block().consPower != null && payload.block().consPower.buffered; } @Override diff --git a/core/src/mindustry/world/blocks/payloads/PayloadUnloader.java b/core/src/mindustry/world/blocks/payloads/PayloadUnloader.java index b6e1b4002e5e..95bd47a8098c 100644 --- a/core/src/mindustry/world/blocks/payloads/PayloadUnloader.java +++ b/core/src/mindustry/world/blocks/payloads/PayloadUnloader.java @@ -92,7 +92,7 @@ public void updateTile(){ } if(hasBattery()){ - float cap = payload.block().consumes.getPower().capacity; + float cap = payload.block().consPower.capacity; float total = payload.build.power.status * cap; float unloaded = Math.min(maxPowerUnload * edelta(), total); lastOutputPower = unloaded; diff --git a/core/src/mindustry/world/blocks/power/Battery.java b/core/src/mindustry/world/blocks/power/Battery.java index c4e46167f4ee..807e510505ab 100644 --- a/core/src/mindustry/world/blocks/power/Battery.java +++ b/core/src/mindustry/world/blocks/power/Battery.java @@ -39,9 +39,9 @@ public void draw(){ @Override public void overwrote(Seq previous){ for(Building other : previous){ - if(other.power != null && other.block.consumes.hasPower() && other.block.consumes.getPower().buffered){ - float amount = other.block.consumes.getPower().capacity * other.power.status; - power.status = Mathf.clamp(power.status + amount / block.consumes.getPower().capacity); + if(other.power != null && other.block.consPower != null && other.block.consPower.buffered){ + float amount = other.block.consPower.capacity * other.power.status; + power.status = Mathf.clamp(power.status + amount / consPower.capacity); } } } diff --git a/core/src/mindustry/world/blocks/power/BeamNode.java b/core/src/mindustry/world/blocks/power/BeamNode.java index 00c86e210afd..e4c5632adc72 100644 --- a/core/src/mindustry/world/blocks/power/BeamNode.java +++ b/core/src/mindustry/world/blocks/power/BeamNode.java @@ -40,8 +40,8 @@ public BeamNode(String name){ public void setBars(){ super.setBars(); - bars.add("power", PowerNode.makePowerBalance()); - bars.add("batteries", PowerNode.makeBatteryBalance()); + addBar("power", PowerNode.makePowerBalance()); + addBar("batteries", PowerNode.makeBatteryBalance()); } @Override diff --git a/core/src/mindustry/world/blocks/power/ImpactReactor.java b/core/src/mindustry/world/blocks/power/ImpactReactor.java index b31e5bed42ad..0b4dfa909bd4 100644 --- a/core/src/mindustry/world/blocks/power/ImpactReactor.java +++ b/core/src/mindustry/world/blocks/power/ImpactReactor.java @@ -50,9 +50,9 @@ public ImpactReactor(String name){ public void setBars(){ super.setBars(); - bars.add("poweroutput", (GeneratorBuild entity) -> new Bar(() -> + addBar("poweroutput", (GeneratorBuild entity) -> new Bar(() -> Core.bundle.format("bar.poweroutput", - Strings.fixed(Math.max(entity.getPowerProduction() - consumes.getPower().usage, 0) * 60 * entity.timeScale, 1)), + Strings.fixed(Math.max(entity.getPowerProduction() - consPower.usage, 0) * 60 * entity.timeScale, 1)), () -> Pal.powerBar, () -> entity.productionEfficiency)); } @@ -77,14 +77,14 @@ public class ImpactReactorBuild extends GeneratorBuild{ @Override public void updateTile(){ if(consValid() && power.status >= 0.99f){ - boolean prevOut = getPowerProduction() <= consumes.getPower().requestedPower(this); + boolean prevOut = getPowerProduction() <= consPower.requestedPower(this); warmup = Mathf.lerpDelta(warmup, 1f, warmupSpeed * timeScale); if(Mathf.equal(warmup, 1f, 0.001f)){ warmup = 1f; } - if(!prevOut && (getPowerProduction() > consumes.getPower().requestedPower(this))){ + if(!prevOut && (getPowerProduction() > consPower.requestedPower(this))){ Events.fire(Trigger.impactPower); } diff --git a/core/src/mindustry/world/blocks/power/ItemLiquidGenerator.java b/core/src/mindustry/world/blocks/power/ItemLiquidGenerator.java index 9e5de6bcc687..2e3bf4f02800 100644 --- a/core/src/mindustry/world/blocks/power/ItemLiquidGenerator.java +++ b/core/src/mindustry/world/blocks/power/ItemLiquidGenerator.java @@ -18,6 +18,8 @@ * Power generation block which can use items, liquids or both as input sources for power production. * Liquids will take priority over items. */ +//TODO remove +@Deprecated public class ItemLiquidGenerator extends PowerGenerator{ public float minItemEfficiency = 0.2f; /** The time in number of ticks during which a single item will produce power. */ @@ -49,11 +51,11 @@ public ItemLiquidGenerator(String name){ protected void setDefaults(){ if(hasItems){ - consumes.add(new ConsumeItemFilter(item -> getItemEfficiency(item) >= minItemEfficiency)).update(false).optional(true, false); + consume(new ConsumeItemFilter(item -> getItemEfficiency(item) >= minItemEfficiency)).update(false).optional(true, false); } if(hasLiquids){ - consumes.add(new ConsumeLiquidFilter(liquid -> getLiquidEfficiency(liquid) >= minLiquidEfficiency, maxLiquidGenerate)).update(false).optional(true, false); + consume(new ConsumeLiquidFilter(liquid -> getLiquidEfficiency(liquid) >= minLiquidEfficiency, maxLiquidGenerate)).update(false).optional(true, false); } defaults = true; diff --git a/core/src/mindustry/world/blocks/power/NuclearReactor.java b/core/src/mindustry/world/blocks/power/NuclearReactor.java index 54ec929eb601..38b440c5a114 100644 --- a/core/src/mindustry/world/blocks/power/NuclearReactor.java +++ b/core/src/mindustry/world/blocks/power/NuclearReactor.java @@ -17,7 +17,6 @@ import mindustry.logic.*; import mindustry.type.*; import mindustry.ui.*; -import mindustry.world.consumers.*; import mindustry.world.meta.*; import static mindustry.Vars.*; @@ -44,6 +43,8 @@ public class NuclearReactor extends PowerGenerator{ /** heat removed per unit of coolant */ public float coolantPower = 0.5f; + public Item fuelItem = Items.thorium; + public @Load("@-top") TextureRegion topRegion; public @Load("@-lights") TextureRegion lightsRegion; @@ -71,7 +72,7 @@ public void setStats(){ @Override public void setBars(){ super.setBars(); - bars.add("heat", (NuclearReactorBuild entity) -> new Bar("bar.heat", Pal.lightOrange, () -> entity.heat)); + addBar("heat", (NuclearReactorBuild entity) -> new Bar("bar.heat", Pal.lightOrange, () -> entity.heat)); } public class NuclearReactorBuild extends GeneratorBuild{ @@ -80,10 +81,7 @@ public class NuclearReactorBuild extends GeneratorBuild{ @Override public void updateTile(){ - ConsumeLiquid cliquid = consumes.get(ConsumeType.liquid); - Item item = consumes.getItem().items[0].item; - - int fuel = items.get(item); + int fuel = items.get(fuelItem); float fullness = (float)fuel / itemCapacity; productionEfficiency = fullness; @@ -97,12 +95,10 @@ public void updateTile(){ productionEfficiency = 0f; } - Liquid liquid = cliquid.liquid; - if(heat > 0){ - float maxUsed = Math.min(liquids.get(liquid), heat / coolantPower); + float maxUsed = Math.min(liquids.currentAmount(), heat / coolantPower); heat -= maxUsed * coolantPower; - liquids.remove(liquid, maxUsed); + liquids.remove(liquids.current(), maxUsed); } if(heat > smokeThreshold){ @@ -133,7 +129,7 @@ public void onDestroyed(){ Sounds.explosionbig.at(this); - int fuel = items.get(consumes.get(ConsumeType.item).items[0].item); + int fuel = items.get(fuelItem); if((fuel < 5 && heat < 0.5f) || !state.rules.reactorExplosions) return; diff --git a/core/src/mindustry/world/blocks/power/PowerDiode.java b/core/src/mindustry/world/blocks/power/PowerDiode.java index 558850c1ae4c..2fa2885ecaa9 100644 --- a/core/src/mindustry/world/blocks/power/PowerDiode.java +++ b/core/src/mindustry/world/blocks/power/PowerDiode.java @@ -30,8 +30,8 @@ public PowerDiode(String name){ public void setBars(){ super.setBars(); - bars.add("back", entity -> new Bar("bar.input", Pal.powerBar, () -> bar(entity.back()))); - bars.add("front", entity -> new Bar("bar.output", Pal.powerBar, () -> bar(entity.front()))); + addBar("back", entity -> new Bar("bar.input", Pal.powerBar, () -> bar(entity.back()))); + addBar("front", entity -> new Bar("bar.output", Pal.powerBar, () -> bar(entity.front()))); } @Override diff --git a/core/src/mindustry/world/blocks/power/PowerGenerator.java b/core/src/mindustry/world/blocks/power/PowerGenerator.java index 41127d37428b..463ffce8f561 100644 --- a/core/src/mindustry/world/blocks/power/PowerGenerator.java +++ b/core/src/mindustry/world/blocks/power/PowerGenerator.java @@ -47,8 +47,8 @@ public void setStats(){ public void setBars(){ super.setBars(); - if(hasPower && outputsPower && !consumes.hasPower()){ - bars.add("power", (GeneratorBuild entity) -> new Bar(() -> + if(hasPower && outputsPower && consPower != null){ + addBar("power", (GeneratorBuild entity) -> new Bar(() -> Core.bundle.format("bar.poweroutput", Strings.fixed(entity.getPowerProduction() * 60 * entity.timeScale(), 1)), () -> Pal.powerBar, diff --git a/core/src/mindustry/world/blocks/power/PowerGraph.java b/core/src/mindustry/world/blocks/power/PowerGraph.java index 4335808222b0..23bcd6256d1c 100644 --- a/core/src/mindustry/world/blocks/power/PowerGraph.java +++ b/core/src/mindustry/world/blocks/power/PowerGraph.java @@ -95,12 +95,9 @@ public float getPowerProduced(){ public float getPowerNeeded(){ float powerNeeded = 0f; for(Building consumer : consumers){ - Consumers consumes = consumer.block.consumes; - if(consumes.hasPower()){ - ConsumePower consumePower = consumes.getPower(); - if(otherConsumersAreValid(consumer, consumePower)){ - powerNeeded += consumePower.requestedPower(consumer) * consumer.delta(); - } + ConsumePower consumePower = consumer.block.consPower; + if(otherConsumersAreValid(consumer, consumePower)){ + powerNeeded += consumePower.requestedPower(consumer) * consumer.delta(); } } return powerNeeded; @@ -109,9 +106,8 @@ public float getPowerNeeded(){ public float getBatteryStored(){ float totalAccumulator = 0f; for(Building battery : batteries){ - Consumers consumes = battery.block.consumes; - if(battery.enabled && consumes.hasPower()){ - totalAccumulator += battery.power.status * consumes.getPower().capacity; + if(battery.enabled){ + totalAccumulator += battery.power.status * battery.block.consPower.capacity; } } return totalAccumulator; @@ -120,9 +116,8 @@ public float getBatteryStored(){ public float getBatteryCapacity(){ float totalCapacity = 0f; for(Building battery : batteries){ - if(battery.enabled && battery.block.consumes.hasPower()){ - ConsumePower power = battery.block.consumes.getPower(); - totalCapacity += (1f - battery.power.status) * power.capacity; + if(battery.enabled){ + totalCapacity += (1f - battery.power.status) * battery.block.consPower.capacity; } } return totalCapacity; @@ -131,8 +126,8 @@ public float getBatteryCapacity(){ public float getTotalBatteryCapacity(){ float totalCapacity = 0f; for(Building battery : batteries){ - if(battery.enabled && battery.block.consumes.hasPower()){ - totalCapacity += battery.block.consumes.getPower().capacity; + if(battery.enabled){ + totalCapacity += battery.block.consPower.capacity; } } return totalCapacity; @@ -145,8 +140,7 @@ public float useBatteries(float needed){ float used = Math.min(stored, needed); float consumedPowerPercentage = Math.min(1.0f, needed / stored); for(Building battery : batteries){ - Consumers consumes = battery.block.consumes; - if(battery.enabled && consumes.hasPower()){ + if(battery.enabled){ battery.power.status *= (1f-consumedPowerPercentage); } } @@ -160,12 +154,9 @@ public float chargeBatteries(float excess){ if(Mathf.equal(capacity, 0f)) return 0f; for(Building battery : batteries){ - Consumers consumes = battery.block.consumes; - if(battery.enabled && consumes.hasPower()){ - ConsumePower consumePower = consumes.getPower(); - if(consumePower.capacity > 0f){ - battery.power.status += (1f- battery.power.status) * chargedPercent; - } + //TODO why would it be 0 + if(battery.enabled && battery.block.consPower.capacity > 0f){ + battery.power.status += (1f - battery.power.status) * chargedPercent; } } return Math.min(excess, capacity); @@ -175,25 +166,23 @@ public void distributePower(float needed, float produced, boolean charged){ //distribute even if not needed. this is because some might be requiring power but not using it; it updates consumers float coverage = Mathf.zero(needed) && Mathf.zero(produced) && !charged && Mathf.zero(lastPowerStored) ? 0f : Mathf.zero(needed) ? 1f : Math.min(1, produced / needed); for(Building consumer : consumers){ - Consumers consumes = consumer.block.consumes; - if(consumes.hasPower()){ - ConsumePower consumePower = consumes.getPower(); - if(consumePower.buffered){ - if(!Mathf.zero(consumePower.capacity)){ - // Add an equal percentage of power to all buffers, based on the global power coverage in this graph - float maximumRate = consumePower.requestedPower(consumer) * coverage * consumer.delta(); - consumer.power.status = Mathf.clamp(consumer.power.status + maximumRate / consumePower.capacity); - } - }else{ - //valid consumers get power as usual - if(otherConsumersAreValid(consumer, consumePower)){ - consumer.power.status = coverage; - }else{ //invalid consumers get an estimate, if they were to activate - consumer.power.status = Math.min(1, produced / (needed + consumePower.usage * consumer.delta())); - //just in case - if(Float.isNaN(consumer.power.status)){ - consumer.power.status = 0f; - } + //TODO how would it even be null + ConsumePower cons = consumer.block.consPower; + if(cons.buffered){ + if(!Mathf.zero(cons.capacity)){ + // Add an equal percentage of power to all buffers, based on the global power coverage in this graph + float maximumRate = cons.requestedPower(consumer) * coverage * consumer.delta(); + consumer.power.status = Mathf.clamp(consumer.power.status + maximumRate / cons.capacity); + } + }else{ + //valid consumers get power as usual + if(otherConsumersAreValid(consumer, cons)){ + consumer.power.status = coverage; + }else{ //invalid consumers get an estimate, if they were to activate + consumer.power.status = Math.min(1, produced / (needed + cons.usage * consumer.delta())); + //just in case + if(Float.isNaN(consumer.power.status)){ + consumer.power.status = 0f; } } } @@ -268,15 +257,17 @@ public void add(Building build){ //there's something to update, add the entity entity.add(); - if(build.block.outputsPower && build.block.consumesPower && !build.block.consumes.getPower().buffered){ - producers.add(build); - consumers.add(build); - }else if(build.block.outputsPower && build.block.consumesPower){ - batteries.add(build); - }else if(build.block.outputsPower){ - producers.add(build); - }else if(build.block.consumesPower){ - consumers.add(build); + if(build.block.consPower != null){ + if(build.block.outputsPower && build.block.consumesPower && !build.block.consPower.buffered){ + producers.add(build); + consumers.add(build); + }else if(build.block.outputsPower && build.block.consumesPower){ + batteries.add(build); + }else if(build.block.outputsPower){ + producers.add(build); + }else if(build.block.consumesPower){ + consumers.add(build); + } } } } @@ -352,8 +343,8 @@ public void remove(Building tile){ } private boolean otherConsumersAreValid(Building build, Consume consumePower){ - for(Consume cons : build.block.consumes.all){ - if(cons != consumePower && !cons.isOptional() && !cons.valid(build)){ + for(Consume cons : build.block.consumers){ + if(cons != consumePower && !cons.optional && !cons.valid(build)){ return false; } } diff --git a/core/src/mindustry/world/blocks/power/PowerNode.java b/core/src/mindustry/world/blocks/power/PowerNode.java index 259b204c0de7..326ed3f95fb5 100644 --- a/core/src/mindustry/world/blocks/power/PowerNode.java +++ b/core/src/mindustry/world/blocks/power/PowerNode.java @@ -100,10 +100,10 @@ public PowerNode(String name){ @Override public void setBars(){ super.setBars(); - bars.add("power", makePowerBalance()); - bars.add("batteries", makeBatteryBalance()); + addBar("power", makePowerBalance()); + addBar("batteries", makeBatteryBalance()); - bars.add("connections", entity -> new Bar(() -> + addBar("connections", entity -> new Bar(() -> Core.bundle.format("bar.powerlines", entity.power.links.size, maxNodes), () -> Pal.items, () -> (float)entity.power.links.size / (float)maxNodes @@ -217,7 +217,7 @@ protected void getPotentialLinks(Tile tile, Team team, Cons others){ return t != null && t.build == other; }); - tempTileEnts.clear(); + tempBuilds.clear(); graphs.clear(); //add conducting graphs to prevent double link @@ -234,12 +234,12 @@ protected void getPotentialLinks(Tile tile, Team team, Cons others){ Geometry.circle(tile.x, tile.y, (int)(laserRange + 2), (x, y) -> { Building other = world.build(x, y); - if(valid.get(other) && !tempTileEnts.contains(other)){ - tempTileEnts.add(other); + if(valid.get(other) && !tempBuilds.contains(other)){ + tempBuilds.add(other); } }); - tempTileEnts.sort((a, b) -> { + tempBuilds.sort((a, b) -> { int type = -Boolean.compare(a.block instanceof PowerNode, b.block instanceof PowerNode); if(type != 0) return type; return Float.compare(a.dst2(tile), b.dst2(tile)); @@ -247,7 +247,7 @@ protected void getPotentialLinks(Tile tile, Team team, Cons others){ returnInt = 0; - tempTileEnts.each(valid, t -> { + tempBuilds.each(valid, t -> { if(returnInt ++ < maxNodes){ graphs.add(t.power.graph); others.get(t); @@ -269,7 +269,7 @@ public static void getNodeLinks(Tile tile, Block block, Team team, Cons { Building other = world.build(x, y); - if(valid.get(other) && !tempTileEnts.contains(other)){ - tempTileEnts.add(other); + if(valid.get(other) && !tempBuilds.contains(other)){ + tempBuilds.add(other); } }); - tempTileEnts.sort((a, b) -> { + tempBuilds.sort((a, b) -> { int type = -Boolean.compare(a.block instanceof PowerNode, b.block instanceof PowerNode); if(type != 0) return type; return Float.compare(a.dst2(tile), b.dst2(tile)); }); - tempTileEnts.each(valid, t -> { + tempBuilds.each(valid, t -> { graphs.add(t.power.graph); others.get(t); }); diff --git a/core/src/mindustry/world/blocks/production/AttributeCrafter.java b/core/src/mindustry/world/blocks/production/AttributeCrafter.java index c40ebd6d6b0c..0c5a037cdcea 100644 --- a/core/src/mindustry/world/blocks/production/AttributeCrafter.java +++ b/core/src/mindustry/world/blocks/production/AttributeCrafter.java @@ -37,7 +37,7 @@ public void setBars(){ if(!displayEfficiency) return; - bars.add("efficiency", (AttributeCrafterBuild entity) -> + addBar("efficiency", (AttributeCrafterBuild entity) -> new Bar(() -> Core.bundle.format("bar.efficiency", (int)(entity.efficiencyScale() * 100 * displayEfficiencyScale)), () -> Pal.lightOrange, diff --git a/core/src/mindustry/world/blocks/production/BeamDrill.java b/core/src/mindustry/world/blocks/production/BeamDrill.java index 27ad65e5cc0f..ee233ae05807 100644 --- a/core/src/mindustry/world/blocks/production/BeamDrill.java +++ b/core/src/mindustry/world/blocks/production/BeamDrill.java @@ -73,7 +73,7 @@ public void init(){ public void setBars(){ super.setBars(); - bars.add("drillspeed", (BeamDrillBuild e) -> + addBar("drillspeed", (BeamDrillBuild e) -> new Bar(() -> Core.bundle.format("bar.drillspeed", Strings.fixed(e.lastDrillSpeed * 60, 2)), () -> Pal.ammo, () -> e.warmup)); } diff --git a/core/src/mindustry/world/blocks/production/Drill.java b/core/src/mindustry/world/blocks/production/Drill.java index 71922ac06661..a1b324c5bb49 100644 --- a/core/src/mindustry/world/blocks/production/Drill.java +++ b/core/src/mindustry/world/blocks/production/Drill.java @@ -103,7 +103,7 @@ public void drawRequestConfigTop(BuildPlan plan, Eachable list){ public void setBars(){ super.setBars(); - bars.add("drillspeed", (DrillBuild e) -> + addBar("drillspeed", (DrillBuild e) -> new Bar(() -> Core.bundle.format("bar.drillspeed", Strings.fixed(e.lastDrillSpeed * 60 * e.timeScale, 2)), () -> Pal.ammo, () -> e.warmup)); } diff --git a/core/src/mindustry/world/blocks/production/GenericCrafter.java b/core/src/mindustry/world/blocks/production/GenericCrafter.java index b890e4aab5cc..b5b4cd0fe8bd 100644 --- a/core/src/mindustry/world/blocks/production/GenericCrafter.java +++ b/core/src/mindustry/world/blocks/production/GenericCrafter.java @@ -77,7 +77,7 @@ public void setBars(){ //set up liquid bars for liquid outputs if(outputLiquids != null && outputLiquids.length > 0){ //no need for dynamic liquid bar - bars.remove("liquid"); + removeBar("liquid"); //then display output buffer for(var stack : outputLiquids){ diff --git a/core/src/mindustry/world/blocks/production/HeatCrafter.java b/core/src/mindustry/world/blocks/production/HeatCrafter.java index a2eb5d11dc50..5eba3788045b 100644 --- a/core/src/mindustry/world/blocks/production/HeatCrafter.java +++ b/core/src/mindustry/world/blocks/production/HeatCrafter.java @@ -24,7 +24,7 @@ public HeatCrafter(String name){ public void setBars(){ super.setBars(); - bars.add("heat", (HeatCrafterBuild entity) -> + addBar("heat", (HeatCrafterBuild entity) -> new Bar(() -> Core.bundle.format("bar.heatpercent", (int)entity.heat, (int)(entity.efficiencyScale() * 100)), () -> Pal.lightOrange, diff --git a/core/src/mindustry/world/blocks/production/LiquidConverter.java b/core/src/mindustry/world/blocks/production/LiquidConverter.java index 5b50ab96511b..674f4b88dda3 100644 --- a/core/src/mindustry/world/blocks/production/LiquidConverter.java +++ b/core/src/mindustry/world/blocks/production/LiquidConverter.java @@ -1,10 +1,12 @@ package mindustry.world.blocks.production; import arc.math.*; +import arc.util.*; import mindustry.world.consumers.*; import mindustry.world.meta.*; public class LiquidConverter extends GenericCrafter{ + protected @Nullable ConsumeLiquid consumer; public LiquidConverter(String name){ super(name); @@ -18,13 +20,11 @@ public boolean outputsItems(){ @Override public void init(){ - if(!consumes.has(ConsumeType.liquid) || !(consumes.get(ConsumeType.liquid) instanceof ConsumeLiquid)){ - throw new RuntimeException("LiquidsConverters must have a ConsumeLiquid. Note that filters are not supported."); - } - - ConsumeLiquid cl = consumes.get(ConsumeType.liquid); - cl.update(false); super.init(); + + consumer = findConsumer(b -> b instanceof ConsumeLiquid); + if(consumer == null) throw new RuntimeException("LiquidConverters must have a ConsumeLiquid."); + consumer.update = false; } @Override @@ -44,20 +44,18 @@ public void drawLight(){ @Override public void updateTile(){ - ConsumeLiquid cl = consumes.get(ConsumeType.liquid); - if(consValid()){ if(Mathf.chanceDelta(updateEffectChance)){ updateEffect.at(x + Mathf.range(size * 4f), y + Mathf.range(size * 4)); } warmup = Mathf.lerpDelta(warmup, 1f, 0.02f); - float use = Math.min(cl.amount * edelta(), liquidCapacity - liquids.get(outputLiquid.liquid)); - float ratio = outputLiquid.amount / cl.amount; + float use = Math.min(consumer.amount * edelta(), liquidCapacity - liquids.get(outputLiquid.liquid)); + float ratio = outputLiquid.amount / consumer.amount; - liquids.remove(cl.liquid, Math.min(use, liquids.get(cl.liquid))); + liquids.remove(consumer.liquid, Math.min(use, liquids.get(consumer.liquid))); - progress += use / cl.amount; + progress += use / consumer.amount; liquids.add(outputLiquid.liquid, use * ratio); if(progress >= craftTime){ consume(); diff --git a/core/src/mindustry/world/blocks/production/Separator.java b/core/src/mindustry/world/blocks/production/Separator.java index 6ec3828fe245..6bd8ec1cb874 100644 --- a/core/src/mindustry/world/blocks/production/Separator.java +++ b/core/src/mindustry/world/blocks/production/Separator.java @@ -18,6 +18,8 @@ * Extracts a random list of items from an input item and an input liquid. */ public class Separator extends Block{ + protected @Nullable ConsumeItems consItems; + public ItemStack[] results; public float craftTime; @@ -43,6 +45,12 @@ public void setStats(){ stats.add(Stat.productionTime, craftTime / 60f, StatUnit.seconds); } + @Override + public void init(){ + super.init(); + consItems = findConsumer(c -> c instanceof ConsumeItems); + } + public class SeparatorBuild extends Building{ public float progress; public float totalProgress; @@ -63,9 +71,8 @@ public boolean shouldAmbientSound(){ public boolean shouldConsume(){ int total = items.total(); //very inefficient way of allowing separators to ignore input buffer storage - if(consumes.has(ConsumeType.item) && consumes.get(ConsumeType.item) instanceof ConsumeItems){ - ConsumeItems c = consumes.get(ConsumeType.item); - for(ItemStack stack : c.items){ + if(consItems != null){ + for(ItemStack stack : consItems.items){ total -= items.get(stack.item); } } @@ -132,7 +139,7 @@ public double sense(LAccess sensor){ @Override public boolean canDump(Building to, Item item){ - return !consumes.consumesItem(item); + return !consumesItem(item); } @Override diff --git a/core/src/mindustry/world/blocks/production/SolidPump.java b/core/src/mindustry/world/blocks/production/SolidPump.java index 94a2ecf2562f..fcebdbc0f657 100644 --- a/core/src/mindustry/world/blocks/production/SolidPump.java +++ b/core/src/mindustry/world/blocks/production/SolidPump.java @@ -47,7 +47,7 @@ public void drawPlace(int x, int y, int rotation, boolean valid){ @Override public void setBars(){ super.setBars(); - bars.add("efficiency", (SolidPumpBuild entity) -> new Bar(() -> Core.bundle.formatFloat("bar.pumpspeed", + addBar("efficiency", (SolidPumpBuild entity) -> new Bar(() -> Core.bundle.formatFloat("bar.pumpspeed", entity.lastPump * 60, 1), () -> Pal.ammo, () -> entity.warmup * entity.efficiency())); diff --git a/core/src/mindustry/world/blocks/production/WallCrafter.java b/core/src/mindustry/world/blocks/production/WallCrafter.java index b0a272439a8a..c4b96cc2b00c 100644 --- a/core/src/mindustry/world/blocks/production/WallCrafter.java +++ b/core/src/mindustry/world/blocks/production/WallCrafter.java @@ -54,7 +54,7 @@ public WallCrafter(String name){ public void setBars(){ super.setBars(); - bars.add("drillspeed", (WallCrafterBuild e) -> + addBar("drillspeed", (WallCrafterBuild e) -> new Bar(() -> Core.bundle.format("bar.drillspeed", Strings.fixed(e.lastEfficiency * 60 / drillTime, 2)), () -> Pal.ammo, () -> e.warmup)); } diff --git a/core/src/mindustry/world/blocks/sandbox/ItemSource.java b/core/src/mindustry/world/blocks/sandbox/ItemSource.java index ace6b1850bd0..70babad3d39f 100644 --- a/core/src/mindustry/world/blocks/sandbox/ItemSource.java +++ b/core/src/mindustry/world/blocks/sandbox/ItemSource.java @@ -35,7 +35,7 @@ public ItemSource(String name){ @Override public void setBars(){ super.setBars(); - bars.remove("items"); + removeBar("items"); } @Override diff --git a/core/src/mindustry/world/blocks/sandbox/LiquidSource.java b/core/src/mindustry/world/blocks/sandbox/LiquidSource.java index 31cc98cbbb61..de80130695b8 100644 --- a/core/src/mindustry/world/blocks/sandbox/LiquidSource.java +++ b/core/src/mindustry/world/blocks/sandbox/LiquidSource.java @@ -42,7 +42,7 @@ public LiquidSource(String name){ public void setBars(){ super.setBars(); - bars.remove("liquid"); + removeBar("liquid"); } @Override diff --git a/core/src/mindustry/world/blocks/sandbox/LiquidVoid.java b/core/src/mindustry/world/blocks/sandbox/LiquidVoid.java index b1fbe79b95a7..6f25ac1bfcd7 100644 --- a/core/src/mindustry/world/blocks/sandbox/LiquidVoid.java +++ b/core/src/mindustry/world/blocks/sandbox/LiquidVoid.java @@ -19,7 +19,7 @@ public LiquidVoid(String name){ @Override public void setBars(){ super.setBars(); - bars.remove("liquid"); + removeBar("liquid"); } public class LiquidVoidBuild extends Building{ diff --git a/core/src/mindustry/world/blocks/sandbox/PowerVoid.java b/core/src/mindustry/world/blocks/sandbox/PowerVoid.java index 15fb0ac57429..d0a8acf4d743 100644 --- a/core/src/mindustry/world/blocks/sandbox/PowerVoid.java +++ b/core/src/mindustry/world/blocks/sandbox/PowerVoid.java @@ -7,7 +7,7 @@ public class PowerVoid extends PowerBlock{ public PowerVoid(String name){ super(name); - consumes.power(Float.MAX_VALUE); + consumePower(Float.MAX_VALUE); envEnabled = Env.any; enableDrawStatus = false; } diff --git a/core/src/mindustry/world/blocks/storage/CoreBlock.java b/core/src/mindustry/world/blocks/storage/CoreBlock.java index 6daf7c0a39bc..87e76c4b41f8 100644 --- a/core/src/mindustry/world/blocks/storage/CoreBlock.java +++ b/core/src/mindustry/world/blocks/storage/CoreBlock.java @@ -92,7 +92,7 @@ public void setStats(){ public void setBars(){ super.setBars(); - bars.add("capacity", (CoreBuild e) -> new Bar( + addBar("capacity", (CoreBuild e) -> new Bar( () -> Core.bundle.format("bar.capacity", UI.formatAmount(e.storageCapacity)), () -> Pal.items, () -> e.items.total() / ((float)e.storageCapacity * content.items().count(i -> i.unlockedNow())) diff --git a/core/src/mindustry/world/blocks/storage/Unloader.java b/core/src/mindustry/world/blocks/storage/Unloader.java index 6a326e68db60..924a7eff0756 100644 --- a/core/src/mindustry/world/blocks/storage/Unloader.java +++ b/core/src/mindustry/world/blocks/storage/Unloader.java @@ -54,7 +54,7 @@ public void drawRequestConfig(BuildPlan plan, Eachable list){ @Override public void setBars(){ super.setBars(); - bars.remove("items"); + removeBar("items"); } public static class ContainerStat{ diff --git a/core/src/mindustry/world/blocks/units/CommandCenter.java b/core/src/mindustry/world/blocks/units/CommandCenter.java deleted file mode 100644 index a2e3ad6c2a69..000000000000 --- a/core/src/mindustry/world/blocks/units/CommandCenter.java +++ /dev/null @@ -1,143 +0,0 @@ -package mindustry.world.blocks.units; - -import arc.*; -import arc.graphics.*; -import arc.graphics.g2d.*; -import arc.scene.style.*; -import arc.scene.ui.*; -import arc.scene.ui.layout.*; -import arc.struct.*; -import arc.util.*; -import arc.util.io.*; -import mindustry.*; -import mindustry.content.*; -import mindustry.entities.*; -import mindustry.entities.units.*; -import mindustry.game.EventType.*; -import mindustry.gen.*; -import mindustry.ui.*; -import mindustry.world.*; -import mindustry.world.meta.*; - -public class CommandCenter extends Block{ - public final int timerEffect = timers ++; - - public TextureRegionDrawable[] commandRegions = new TextureRegionDrawable[UnitCommand.all.length]; - public Color topColor = null, bottomColor = Color.valueOf("5e5e5e"); - public Effect effect = Fx.commandSend; - public float effectSize = 150f; - public float forceRadius = 31f, forceStrength = 0.2f; - - public CommandCenter(String name){ - super(name); - - flags = EnumSet.of(BlockFlag.rally); - update = true; - solid = true; - configurable = true; - drawDisabled = false; - logicConfigurable = true; - envEnabled = Env.any; - - config(UnitCommand.class, (CommandBuild build, UnitCommand command) -> { - if(build.team.data().command != command){ - build.team.data().command = command; - //do not spam effect - if(build.timer(timerEffect, 60f)){ - effect.at(build, effectSize); - } - Events.fire(new CommandIssueEvent(build, command)); - } - }); - } - - @Override - public void load(){ - super.load(); - - if(Vars.ui != null){ - for(UnitCommand cmd : UnitCommand.all){ - commandRegions[cmd.ordinal()] = Vars.ui.getIcon("command" + Strings.capitalize(cmd.name()), "cancel"); - } - } - } - - @Override - public boolean configSenseable(){ - return true; - } - - public class CommandBuild extends Building{ - - @Override - public Object config(){ - return team.data().command; - } - - @Override - public void updateTile(){ - super.updateTile(); - - //push away allied units - team.data().tree().intersect(x - forceRadius/2f, y - forceRadius/2f, forceRadius, forceRadius, u -> { - if(!u.isPlayer()){ - float dst = dst(u); - float rs = forceRadius + u.hitSize/2f; - if(dst < rs){ - u.vel.add(Tmp.v1.set(u).sub(x, y).setLength(1f - dst / rs).scl(forceStrength)); - } - } - }); - } - - @Override - public void draw(){ - super.draw(); - - float size = 6f; - - Draw.color(bottomColor); - Draw.rect(commandRegions[team.data().command.ordinal()].getRegion(), x, y - 1, size, size); - Draw.color(topColor == null ? team.color : topColor); - Draw.rect(commandRegions[team.data().command.ordinal()].getRegion(), x, y, size, size); - Draw.color(); - } - - @Override - public void buildConfiguration(Table table){ - ButtonGroup group = new ButtonGroup<>(); - Table buttons = new Table(); - - for(UnitCommand cmd : UnitCommand.all){ - buttons.button(commandRegions[cmd.ordinal()], Styles.clearToggleTransi, () -> { - if(team.data().command != cmd) configure(cmd); - }).size(44).group(group).update(b -> b.setChecked(team.data().command == cmd)); - } - table.add(buttons); - table.row(); - table.label(() -> team.data().command.localized()).style(Styles.outlineLabel).center().growX().get().setAlignment(Align.center); - } - - @Override - public boolean onConfigureTileTapped(Building other){ - if(this == other){ - deselect(); - return false; - } - - return true; - } - - @Override - public void write(Writes write){ - super.write(write); - write.b(team.data().command.ordinal()); - } - - @Override - public void read(Reads read, byte version){ - super.read(read, version); - team.data().command = UnitCommand.all[read.b()]; - } - } -} diff --git a/core/src/mindustry/world/blocks/units/Reconstructor.java b/core/src/mindustry/world/blocks/units/Reconstructor.java index ce6bbfddc2bf..0dc3818f7ad6 100644 --- a/core/src/mindustry/world/blocks/units/Reconstructor.java +++ b/core/src/mindustry/world/blocks/units/Reconstructor.java @@ -50,8 +50,8 @@ public TextureRegion[] icons(){ public void setBars(){ super.setBars(); - bars.add("progress", (ReconstructorBuild entity) -> new Bar("bar.progress", Pal.ammo, entity::fraction)); - bars.add("units", (ReconstructorBuild e) -> + addBar("progress", (ReconstructorBuild entity) -> new Bar("bar.progress", Pal.ammo, entity::fraction)); + addBar("units", (ReconstructorBuild e) -> new Bar( () -> e.unit() == null ? "[lightgray]" + Iconc.cancel : Core.bundle.format("bar.unitcap", @@ -91,8 +91,10 @@ public void setStats(){ @Override public void init(){ capacities = new int[Vars.content.items().size]; - if(consumes.has(ConsumeType.item) && consumes.get(ConsumeType.item) instanceof ConsumeItems){ - for(ItemStack stack : consumes.get(ConsumeType.item).items){ + + ConsumeItems cons = findConsumer(c -> c instanceof ConsumeItems); + if(cons != null){ + for(ItemStack stack : cons.items){ capacities[stack.item.id] = Math.max(capacities[stack.item.id], stack.amount * 2); itemCapacity = Math.max(itemCapacity, stack.amount * 2); } diff --git a/core/src/mindustry/world/blocks/units/RepairPoint.java b/core/src/mindustry/world/blocks/units/RepairPoint.java index dbb68ad4a8d4..6a25eaef119b 100644 --- a/core/src/mindustry/world/blocks/units/RepairPoint.java +++ b/core/src/mindustry/world/blocks/units/RepairPoint.java @@ -70,7 +70,7 @@ public void setStats(){ stats.add(Stat.repairSpeed, repairSpeed * 60f, StatUnit.perSecond); if(acceptCoolant){ - stats.add(Stat.booster, StatValues.strengthBoosters(coolantMultiplier, l -> consumes.liquidfilters.get(l.id))); + stats.add(Stat.booster, StatValues.strengthBoosters(coolantMultiplier, this::consumesLiquid)); } } @@ -78,10 +78,10 @@ public void setStats(){ public void init(){ if(acceptCoolant){ hasLiquids = true; - consumes.add(new ConsumeCoolant(coolantUse)).optional(true, true); + consume(new ConsumeCoolant(coolantUse)).optional(true, true); } - consumes.powerCond(powerUse, (RepairPointBuild entity) -> entity.target != null); + consumePowerCond(powerUse, (RepairPointBuild entity) -> entity.target != null); clipSize = Math.max(clipSize, (repairRadius + tilesize) * 2); super.init(); } @@ -172,8 +172,7 @@ public void drawSelect(){ public void updateTile(){ float multiplier = 1f; if(acceptCoolant){ - var liq = consumes.get(ConsumeType.liquid); - multiplier = liq.valid(this) ? 1f + liquids.current().heatCapacity * coolantMultiplier : 1f; + multiplier = consOptionalValid() ? 1f + liquids.current().heatCapacity * coolantMultiplier : 1f; } if(target != null && (target.dead() || target.dst(this) - target.hitSize/2f > repairRadius || target.health() >= target.maxHealth())){ diff --git a/core/src/mindustry/world/blocks/units/UnitAssembler.java b/core/src/mindustry/world/blocks/units/UnitAssembler.java index 335db7f1652a..97bed7e268e4 100644 --- a/core/src/mindustry/world/blocks/units/UnitAssembler.java +++ b/core/src/mindustry/world/blocks/units/UnitAssembler.java @@ -39,6 +39,8 @@ public class UnitAssembler extends PayloadBlock{ public Seq plans = new Seq<>(4); + protected @Nullable ConsumePayloadDynamic consPayload; + public UnitAssembler(String name){ super(name); update = solid = true; @@ -85,9 +87,9 @@ public boolean canPlaceOn(Tile tile, Team team, int rotation){ public void setBars(){ super.setBars(); - bars.add("progress", (UnitAssemblerBuild e) -> new Bar("bar.progress", Pal.ammo, () -> e.progress)); + addBar("progress", (UnitAssemblerBuild e) -> new Bar("bar.progress", Pal.ammo, () -> e.progress)); - bars.add("units", (UnitAssemblerBuild e) -> + addBar("units", (UnitAssemblerBuild e) -> new Bar(() -> Core.bundle.format("bar.unitcap", Fonts.getUnicodeStr(e.unit().name), @@ -114,7 +116,7 @@ public TextureRegion[] icons(){ @Override public void init(){ clipSize = Math.max(clipSize, (areaSize + size) * tilesize * 2); - consumes.add(new ConsumePayloadDynamic((UnitAssemblerBuild build) -> build.plan().requirements)); + consume(consPayload = new ConsumePayloadDynamic((UnitAssemblerBuild build) -> build.plan().requirements)); super.init(); } @@ -254,7 +256,7 @@ public AssemblerUnitPlan plan(){ @Override public boolean shouldConsume(){ //liquid is only consumed when building is being done - return enabled && !wasOccupied && Units.canCreate(team, plan().unit) && consumes.get(ConsumeType.payload).valid(this); + return enabled && !wasOccupied && Units.canCreate(team, plan().unit) && consPayload.valid(this); } @Override diff --git a/core/src/mindustry/world/blocks/units/UnitCargoLoader.java b/core/src/mindustry/world/blocks/units/UnitCargoLoader.java index e72fac48da8c..147c61886566 100644 --- a/core/src/mindustry/world/blocks/units/UnitCargoLoader.java +++ b/core/src/mindustry/world/blocks/units/UnitCargoLoader.java @@ -38,7 +38,7 @@ public UnitCargoLoader(String name){ public void setBars(){ super.setBars(); - bars.add("units", (UnitTransportSourceBuild e) -> + addBar("units", (UnitTransportSourceBuild e) -> new Bar( () -> Core.bundle.format("bar.unitcap", diff --git a/core/src/mindustry/world/blocks/units/UnitFactory.java b/core/src/mindustry/world/blocks/units/UnitFactory.java index 48de87f87609..0244c23285c6 100644 --- a/core/src/mindustry/world/blocks/units/UnitFactory.java +++ b/core/src/mindustry/world/blocks/units/UnitFactory.java @@ -53,7 +53,7 @@ public UnitFactory(String name){ tile.progress = 0; }); - consumes.add(new ConsumeItemDynamic((UnitFactoryBuild e) -> e.currentPlan != -1 ? plans.get(e.currentPlan).requirements : ItemStack.empty)); + consume(new ConsumeItemDynamic((UnitFactoryBuild e) -> e.currentPlan != -1 ? plans.get(e.currentPlan).requirements : ItemStack.empty)); } @Override @@ -72,9 +72,9 @@ public void init(){ @Override public void setBars(){ super.setBars(); - bars.add("progress", (UnitFactoryBuild e) -> new Bar("bar.progress", Pal.ammo, e::fraction)); + addBar("progress", (UnitFactoryBuild e) -> new Bar("bar.progress", Pal.ammo, e::fraction)); - bars.add("units", (UnitFactoryBuild e) -> + addBar("units", (UnitFactoryBuild e) -> new Bar( () -> e.unit() == null ? "[lightgray]" + Iconc.cancel : Core.bundle.format("bar.unitcap", diff --git a/core/src/mindustry/world/consumers/Consume.java b/core/src/mindustry/world/consumers/Consume.java index 335c16e79aa0..89c6b13db154 100644 --- a/core/src/mindustry/world/consumers/Consume.java +++ b/core/src/mindustry/world/consumers/Consume.java @@ -1,8 +1,8 @@ package mindustry.world.consumers; import arc.scene.ui.layout.*; -import arc.struct.*; import mindustry.gen.*; +import mindustry.world.*; import mindustry.world.meta.*; /** An abstract class that defines a type of resource that a block can consume. */ @@ -11,21 +11,15 @@ public abstract class Consume{ public boolean optional; /** If true, this consumer will be displayed as a boost input. */ public boolean booster; - public boolean update = true; - - /** - * Apply a filter to items accepted. - * This should set all item IDs that are present in the filter to true. - */ - public void applyItemFilter(Bits filter){ - } + //TODO bad. + @Deprecated + public boolean update = true; /** - * Apply a filter to liquids accepted. - * This should set all liquid IDs that are present in the filter to true. + * Apply extra filters to a block. */ - public void applyLiquidFilter(Bits filter){ + public void apply(Block block){ } @@ -39,25 +33,12 @@ public Consume boost(){ return optional(true, true); } + @Deprecated public Consume update(boolean update){ this.update = update; return this; } - public boolean isOptional(){ - return optional; - } - - public boolean isBoost(){ - return booster; - } - - public boolean isUpdate(){ - return update; - } - - public abstract ConsumeType type(); - public void build(Building build, Table table){} /** Called when a consumption is triggered manually. */ diff --git a/core/src/mindustry/world/consumers/ConsumeItemDynamic.java b/core/src/mindustry/world/consumers/ConsumeItemDynamic.java index 3c4ff076585b..307f57156069 100644 --- a/core/src/mindustry/world/consumers/ConsumeItemDynamic.java +++ b/core/src/mindustry/world/consumers/ConsumeItemDynamic.java @@ -5,6 +5,7 @@ import mindustry.gen.*; import mindustry.type.*; import mindustry.ui.*; +import mindustry.world.*; public class ConsumeItemDynamic extends Consume{ public final Func items; @@ -15,8 +16,9 @@ public ConsumeItemDynamic(Func items){ } @Override - public ConsumeType type(){ - return ConsumeType.item; + public void apply(Block block){ + block.hasItems = true; + block.acceptsItems = true; } @Override diff --git a/core/src/mindustry/world/consumers/ConsumeItemFilter.java b/core/src/mindustry/world/consumers/ConsumeItemFilter.java index d3db73311755..9fdfde68d8d1 100644 --- a/core/src/mindustry/world/consumers/ConsumeItemFilter.java +++ b/core/src/mindustry/world/consumers/ConsumeItemFilter.java @@ -2,10 +2,10 @@ import arc.func.*; import arc.scene.ui.layout.*; -import arc.struct.*; import mindustry.gen.*; import mindustry.type.*; import mindustry.ui.*; +import mindustry.world.*; import mindustry.world.meta.*; import static mindustry.Vars.*; @@ -18,13 +18,10 @@ public ConsumeItemFilter(Boolf item){ } @Override - public void applyItemFilter(Bits arr){ - content.items().each(filter, item -> arr.set(item.id)); - } - - @Override - public ConsumeType type(){ - return ConsumeType.item; + public void apply(Block block){ + block.hasItems = true; + block.acceptsItems = true; + content.items().each(filter, item -> block.itemFilter[item.id] = true); } @Override diff --git a/core/src/mindustry/world/consumers/ConsumeItems.java b/core/src/mindustry/world/consumers/ConsumeItems.java index fb1e6a7b45d3..2172891f8877 100644 --- a/core/src/mindustry/world/consumers/ConsumeItems.java +++ b/core/src/mindustry/world/consumers/ConsumeItems.java @@ -1,10 +1,10 @@ package mindustry.world.consumers; import arc.scene.ui.layout.*; -import arc.struct.*; import mindustry.gen.*; import mindustry.type.*; import mindustry.ui.*; +import mindustry.world.*; import mindustry.world.meta.*; public class ConsumeItems extends Consume{ @@ -20,17 +20,14 @@ protected ConsumeItems(){ } @Override - public void applyItemFilter(Bits filter){ + public void apply(Block block){ + block.hasItems = true; + block.acceptsItems = true; for(var stack : items){ - filter.set(stack.item.id); + block.itemFilter[stack.item.id] = true; } } - @Override - public ConsumeType type(){ - return ConsumeType.item; - } - @Override public void build(Building build, Table table){ table.table(c -> { diff --git a/core/src/mindustry/world/consumers/ConsumeLiquid.java b/core/src/mindustry/world/consumers/ConsumeLiquid.java index 7dc1e557ec74..4fa765e5b5dc 100644 --- a/core/src/mindustry/world/consumers/ConsumeLiquid.java +++ b/core/src/mindustry/world/consumers/ConsumeLiquid.java @@ -1,10 +1,10 @@ package mindustry.world.consumers; import arc.scene.ui.layout.*; -import arc.struct.*; import mindustry.gen.*; import mindustry.type.*; import mindustry.ui.*; +import mindustry.world.*; import mindustry.world.meta.*; import static mindustry.Vars.*; @@ -23,8 +23,9 @@ protected ConsumeLiquid(){ } @Override - public void applyLiquidFilter(Bits filter){ - filter.set(liquid.id); + public void apply(Block block){ + super.apply(block); + block.liquidFilter[liquid.id] = true; } @Override diff --git a/core/src/mindustry/world/consumers/ConsumeLiquidBase.java b/core/src/mindustry/world/consumers/ConsumeLiquidBase.java index fb13ba7dc876..2bffebcde812 100644 --- a/core/src/mindustry/world/consumers/ConsumeLiquidBase.java +++ b/core/src/mindustry/world/consumers/ConsumeLiquidBase.java @@ -1,6 +1,7 @@ package mindustry.world.consumers; import mindustry.gen.*; +import mindustry.world.*; public abstract class ConsumeLiquidBase extends Consume{ /** amount used per frame */ @@ -13,8 +14,8 @@ public ConsumeLiquidBase(float amount){ public ConsumeLiquidBase(){} @Override - public ConsumeType type(){ - return ConsumeType.liquid; + public void apply(Block block){ + block.hasLiquids = true; } protected float use(Building entity){ diff --git a/core/src/mindustry/world/consumers/ConsumeLiquidFilter.java b/core/src/mindustry/world/consumers/ConsumeLiquidFilter.java index 9d3c69a71dcd..a7833d1b3869 100644 --- a/core/src/mindustry/world/consumers/ConsumeLiquidFilter.java +++ b/core/src/mindustry/world/consumers/ConsumeLiquidFilter.java @@ -6,6 +6,7 @@ import mindustry.gen.*; import mindustry.type.*; import mindustry.ui.*; +import mindustry.world.*; import mindustry.world.meta.*; import static mindustry.Vars.*; @@ -23,8 +24,9 @@ public ConsumeLiquidFilter(){ } @Override - public void applyLiquidFilter(Bits arr){ - content.liquids().each(filter, item -> arr.set(item.id)); + public void apply(Block block){ + block.hasLiquids = true; + content.liquids().each(filter, item -> block.liquidFilter[item.id] = true); } @Override diff --git a/core/src/mindustry/world/consumers/ConsumeLiquids.java b/core/src/mindustry/world/consumers/ConsumeLiquids.java index d3b24d399793..77f6d52f3a89 100644 --- a/core/src/mindustry/world/consumers/ConsumeLiquids.java +++ b/core/src/mindustry/world/consumers/ConsumeLiquids.java @@ -1,11 +1,11 @@ package mindustry.world.consumers; import arc.scene.ui.layout.*; -import arc.struct.*; import mindustry.*; import mindustry.gen.*; import mindustry.type.*; import mindustry.ui.*; +import mindustry.world.*; import mindustry.world.meta.*; //TODO test! @@ -22,17 +22,13 @@ protected ConsumeLiquids(){ } @Override - public void applyLiquidFilter(Bits filter){ + public void apply(Block block){ + block.hasLiquids = true; for(var stack : liquids){ - filter.set(stack.liquid.id); + block.itemFilter[stack.liquid.id] = true; } } - @Override - public ConsumeType type(){ - return ConsumeType.liquid; - } - @Override public void build(Building build, Table table){ table.table(c -> { diff --git a/core/src/mindustry/world/consumers/ConsumePayloadDynamic.java b/core/src/mindustry/world/consumers/ConsumePayloadDynamic.java index 81dea181f2c3..5bd5f67df4b9 100644 --- a/core/src/mindustry/world/consumers/ConsumePayloadDynamic.java +++ b/core/src/mindustry/world/consumers/ConsumePayloadDynamic.java @@ -60,9 +60,4 @@ private void rebuild(Building build, Table table){ } }).left(); } - - @Override - public ConsumeType type(){ - return ConsumeType.payload; - } } diff --git a/core/src/mindustry/world/consumers/ConsumePayloadFilter.java b/core/src/mindustry/world/consumers/ConsumePayloadFilter.java index d40099b3457b..8e7f0ae957d5 100644 --- a/core/src/mindustry/world/consumers/ConsumePayloadFilter.java +++ b/core/src/mindustry/world/consumers/ConsumePayloadFilter.java @@ -61,9 +61,4 @@ public void build(Building build, Table table){ table.add(image).size(8 * 4); } - - @Override - public ConsumeType type(){ - return ConsumeType.payload; - } } diff --git a/core/src/mindustry/world/consumers/ConsumePayloads.java b/core/src/mindustry/world/consumers/ConsumePayloads.java index 8296536f4e8d..9d351ba869e5 100644 --- a/core/src/mindustry/world/consumers/ConsumePayloads.java +++ b/core/src/mindustry/world/consumers/ConsumePayloads.java @@ -49,9 +49,4 @@ public void build(Building build, Table table){ } }).left(); } - - @Override - public ConsumeType type(){ - return ConsumeType.payload; - } } diff --git a/core/src/mindustry/world/consumers/ConsumePower.java b/core/src/mindustry/world/consumers/ConsumePower.java index bc79f7aa9fbe..ab00c386d24b 100644 --- a/core/src/mindustry/world/consumers/ConsumePower.java +++ b/core/src/mindustry/world/consumers/ConsumePower.java @@ -1,8 +1,8 @@ package mindustry.world.consumers; import arc.math.*; -import arc.scene.ui.layout.*; import mindustry.gen.*; +import mindustry.world.*; import mindustry.world.meta.*; /** Consumer class for blocks which consume power while being connected to a power graph. */ @@ -25,8 +25,9 @@ protected ConsumePower(){ } @Override - public ConsumeType type(){ - return ConsumeType.power; + public void apply(Block block){ + block.hasPower = true; + block.consPower = this; } @Override diff --git a/core/src/mindustry/world/blocks/power/ConditionalConsumePower.java b/core/src/mindustry/world/consumers/ConsumePowerCondition.java similarity index 61% rename from core/src/mindustry/world/blocks/power/ConditionalConsumePower.java rename to core/src/mindustry/world/consumers/ConsumePowerCondition.java index 61e1b4b059d5..5eee32bedf34 100644 --- a/core/src/mindustry/world/blocks/power/ConditionalConsumePower.java +++ b/core/src/mindustry/world/consumers/ConsumePowerCondition.java @@ -1,14 +1,13 @@ -package mindustry.world.blocks.power; +package mindustry.world.consumers; import arc.func.*; import mindustry.gen.*; -import mindustry.world.consumers.*; /** A power consumer that only activates sometimes. */ -public class ConditionalConsumePower extends ConsumePower{ +public class ConsumePowerCondition extends ConsumePower{ private final Boolf consume; - public ConditionalConsumePower(float usage, Boolf consume){ + public ConsumePowerCondition(float usage, Boolf consume){ super(usage, 0, false); this.consume = consume; } diff --git a/core/src/mindustry/world/blocks/power/DynamicConsumePower.java b/core/src/mindustry/world/consumers/ConsumePowerDynamic.java similarity index 63% rename from core/src/mindustry/world/blocks/power/DynamicConsumePower.java rename to core/src/mindustry/world/consumers/ConsumePowerDynamic.java index c020f80d1950..ff3d4af32ec0 100644 --- a/core/src/mindustry/world/blocks/power/DynamicConsumePower.java +++ b/core/src/mindustry/world/consumers/ConsumePowerDynamic.java @@ -1,14 +1,13 @@ -package mindustry.world.blocks.power; +package mindustry.world.consumers; import arc.func.*; import mindustry.gen.*; -import mindustry.world.consumers.*; /** A power consumer that uses a dynamic amount of power. */ -public class DynamicConsumePower extends ConsumePower{ +public class ConsumePowerDynamic extends ConsumePower{ private final Floatf usage; - public DynamicConsumePower(Floatf usage){ + public ConsumePowerDynamic(Floatf usage){ super(0, 0, false); this.usage = usage; } diff --git a/core/src/mindustry/world/consumers/ConsumeType.java b/core/src/mindustry/world/consumers/ConsumeType.java deleted file mode 100644 index fecd9f74de33..000000000000 --- a/core/src/mindustry/world/consumers/ConsumeType.java +++ /dev/null @@ -1,10 +0,0 @@ -package mindustry.world.consumers; - -public enum ConsumeType{ - item, - power, - liquid, - payload; - - public static final ConsumeType[] all = values(); -} diff --git a/core/src/mindustry/world/consumers/Consumers.java b/core/src/mindustry/world/consumers/Consumers.java deleted file mode 100644 index 490e05b767e2..000000000000 --- a/core/src/mindustry/world/consumers/Consumers.java +++ /dev/null @@ -1,141 +0,0 @@ -package mindustry.world.consumers; - -import arc.func.*; -import arc.struct.*; -import arc.util.*; -import mindustry.*; -import mindustry.gen.*; -import mindustry.type.*; -import mindustry.world.blocks.power.*; -import mindustry.world.meta.*; - -public class Consumers{ - private Consume[] map = new Consume[ConsumeType.all.length]; - - public Consume[] all = {}, optionals = {}; - - public final Bits itemFilters = new Bits(Vars.content.items().size); - public final Bits liquidfilters = new Bits(Vars.content.liquids().size); - - public boolean consumesItem(Item item){ - return itemFilters.get(item.id); - } - - public boolean consumesLiquid(Liquid liq){ - return liquidfilters.get(liq.id); - } - - public boolean any(){ - return all.length > 0; - } - - public void each(Cons c){ - for(var cons : map){ - if(cons != null){ - c.get(cons); - } - } - } - - public void init(){ - all = Structs.filter(Consume.class, map, m -> m != null); - optionals = Structs.filter(Consume.class, map, m -> m != null && m.isOptional()); - - for(Consume cons : all){ - cons.applyItemFilter(itemFilters); - cons.applyLiquidFilter(liquidfilters); - } - } - - public ConsumePower getPower(){ - return get(ConsumeType.power); - } - - public ConsumeItems getItem(){ - return get(ConsumeType.item); - } - - public boolean hasPower(){ - return has(ConsumeType.power); - } - - public ConsumeLiquid liquid(Liquid liquid, float amount){ - return add(new ConsumeLiquid(liquid, amount)); - } - - public ConsumeLiquids liquids(LiquidStack... stacks){ - return add(new ConsumeLiquids(stacks)); - } - - /** - * Creates a consumer which directly uses power without buffering it. - * @param powerPerTick The amount of power which is required each tick for 100% efficiency. - * @return the created consumer object. - */ - public ConsumePower power(float powerPerTick){ - return add(new ConsumePower(powerPerTick, 0.0f, false)); - } - - /** Creates a consumer which only consumes power when the condition is met. */ - public ConsumePower powerCond(float usage, Boolf cons){ - return add(new ConditionalConsumePower(usage, (Boolf)cons)); - } - - /** Creates a consumer that consumes a dynamic amount of power. */ - public ConsumePower powerDynamic(Floatf usage){ - return add(new DynamicConsumePower((Floatf)usage)); - } - - /** - * Creates a consumer which stores power. - * @param powerCapacity The maximum capacity in power units. - */ - public ConsumePower powerBuffered(float powerCapacity){ - return add(new ConsumePower(0f, powerCapacity, true)); - } - - public ConsumeItems item(Item item){ - return item(item, 1); - } - - public ConsumeItems item(Item item, int amount){ - return add(new ConsumeItems(new ItemStack[]{new ItemStack(item, amount)})); - } - - public ConsumeItems items(ItemStack... items){ - return add(new ConsumeItems(items)); - } - - public T add(T consume){ - map[consume.type().ordinal()] = consume; - return consume; - } - - public void remove(ConsumeType type){ - map[type.ordinal()] = null; - } - - public boolean has(ConsumeType type){ - return map[type.ordinal()] != null; - } - - @SuppressWarnings("unchecked") - public T get(ConsumeType type){ - if(map[type.ordinal()] == null){ - throw new IllegalArgumentException("Block does not contain consumer of type '" + type + "'!"); - } - return (T)map[type.ordinal()]; - } - - public @Nullable T getOrNull(ConsumeType type){ - return (T)map[type.ordinal()]; - } - - public void display(Stats stats){ - for(Consume c : map){ - if(c != null){ - c.display(stats); - } - } - } -} diff --git a/core/src/mindustry/world/draw/DrawLiquid.java b/core/src/mindustry/world/draw/DrawLiquid.java index 625a4f572e99..162055796291 100644 --- a/core/src/mindustry/world/draw/DrawLiquid.java +++ b/core/src/mindustry/world/draw/DrawLiquid.java @@ -2,14 +2,15 @@ import arc.*; import arc.graphics.g2d.*; +import arc.util.*; import mindustry.gen.*; import mindustry.graphics.*; import mindustry.type.*; import mindustry.world.*; import mindustry.world.blocks.production.*; -import mindustry.world.consumers.*; public class DrawLiquid extends DrawBlock{ + public @Nullable Liquid liquidDrawn; public TextureRegion inLiquid, liquid, top; public boolean useOutputSprite = false; @@ -25,11 +26,10 @@ public void drawBase(Building build){ Draw.rect(build.block.region, build.x, build.y); GenericCrafter type = (GenericCrafter)build.block; - if((inLiquid.found() || useOutputSprite) && type.consumes.has(ConsumeType.liquid)){ - Liquid input = type.consumes.get(ConsumeType.liquid).liquid; + if((inLiquid.found() || useOutputSprite) && liquidDrawn != null){ Drawf.liquid(useOutputSprite ? liquid : inLiquid, build.x, build.y, - build.liquids.get(input) / type.liquidCapacity, - input.color + build.liquids.get(liquidDrawn) / type.liquidCapacity, + liquidDrawn.color ); } diff --git a/core/src/mindustry/world/draw/DrawMixer.java b/core/src/mindustry/world/draw/DrawMixer.java index db5cff45ab08..a848dc1cea26 100644 --- a/core/src/mindustry/world/draw/DrawMixer.java +++ b/core/src/mindustry/world/draw/DrawMixer.java @@ -2,14 +2,15 @@ import arc.*; import arc.graphics.g2d.*; +import arc.util.*; import mindustry.gen.*; import mindustry.graphics.*; import mindustry.type.*; import mindustry.world.*; import mindustry.world.blocks.production.*; -import mindustry.world.consumers.*; public class DrawMixer extends DrawBlock{ + public @Nullable Liquid liquidDrawn; public TextureRegion inLiquid, liquid, top, bottom; public boolean useOutputSprite; @@ -26,11 +27,10 @@ public void drawBase(Building build){ float rotation = build.block.rotate ? build.rotdeg() : 0; Draw.rect(bottom, build.x, build.y, rotation); - if((inLiquid.found() || useOutputSprite) && build.block.consumes.has(ConsumeType.liquid)){ - Liquid input = build.block.consumes.get(ConsumeType.liquid).liquid; + if((inLiquid.found() || useOutputSprite) && liquidDrawn != null){ Drawf.liquid(useOutputSprite ? liquid : inLiquid, build.x, build.y, - build.liquids.get(input) / build.block.liquidCapacity, - input.color + build.liquids.get(liquidDrawn) / build.block.liquidCapacity, + liquidDrawn.color ); } diff --git a/core/src/mindustry/world/meta/BlockBars.java b/core/src/mindustry/world/meta/BlockBars.java deleted file mode 100644 index a7b78a427a22..000000000000 --- a/core/src/mindustry/world/meta/BlockBars.java +++ /dev/null @@ -1,22 +0,0 @@ -package mindustry.world.meta; - -import arc.func.*; -import arc.struct.*; -import mindustry.gen.*; -import mindustry.ui.*; - -public class BlockBars{ - private OrderedMap> bars = new OrderedMap<>(); - - public void add(String name, Func sup){ - bars.put(name, (Func)sup); - } - - public void remove(String name){ - bars.remove(name); - } - - public Iterable> list(){ - return bars.values(); - } -} diff --git a/core/src/mindustry/world/meta/Stat.java b/core/src/mindustry/world/meta/Stat.java index 5d341d5def4b..86826219ee18 100644 --- a/core/src/mindustry/world/meta/Stat.java +++ b/core/src/mindustry/world/meta/Stat.java @@ -26,7 +26,6 @@ public enum Stat{ mineSpeed, mineTier, payloadCapacity, - commandLimit, baseDeflectChance, lightningChance, lightningDamage, diff --git a/tests/src/test/java/power/DirectConsumerTests.java b/tests/src/test/java/power/DirectConsumerTests.java index 48110ee4e9f9..6919dd20b11d 100644 --- a/tests/src/test/java/power/DirectConsumerTests.java +++ b/tests/src/test/java/power/DirectConsumerTests.java @@ -33,8 +33,8 @@ void testUnitFactory(int siliconAmount, int leadAmount, float producedPower, flo Tile ct = createFakeTile(0, 0, new GenericCrafter("fakefactory"){{ hasPower = true; hasItems = true; - consumes.power(requestedPower); - consumes.items(new ItemStack(Items.silicon, 30), new ItemStack(Items.lead, 30)); + consumePower(requestedPower); + consumeItems(new ItemStack(Items.silicon, 30), new ItemStack(Items.lead, 30)); }}); ct.block().init(); ct.build.items.add(Items.silicon, siliconAmount); diff --git a/tests/src/test/java/power/PowerTestFixture.java b/tests/src/test/java/power/PowerTestFixture.java index e25c2e50cf24..ac0b9d72c5d9 100644 --- a/tests/src/test/java/power/PowerTestFixture.java +++ b/tests/src/test/java/power/PowerTestFixture.java @@ -58,14 +58,14 @@ protected static PowerGenerator createFakeProducerBlock(float producedPower){ protected static Battery createFakeBattery(float capacity){ return new Battery("fakebattery" + System.nanoTime()){{ buildType = () -> new BatteryBuild(); - consumes.powerBuffered(capacity); + consumePowerBuffered(capacity); }}; } protected static Block createFakeDirectConsumer(float powerPerTick){ return new PowerBlock("fakedirectconsumer" + System.nanoTime()){{ buildType = Building::create; - consumes.power(powerPerTick); + consumePower(powerPerTick); }}; } @@ -81,8 +81,8 @@ protected static Tile createFakeTile(int x, int y, Block block){ Tile tile = new Tile(x, y); //workaround since init() is not called for custom blocks - if(block.consumes.all == null || block.consumes.all.length == 0){ - block.consumes.init(); + if(block.consumers.length == 0){ + block.init(); } // Using the Tile(int, int, byte, byte) constructor would require us to register any fake block or tile we create diff --git a/tests/src/test/java/power/PowerTests.java b/tests/src/test/java/power/PowerTests.java index 18a47a9492df..131c88582be6 100644 --- a/tests/src/test/java/power/PowerTests.java +++ b/tests/src/test/java/power/PowerTests.java @@ -7,7 +7,6 @@ import mindustry.world.*; import mindustry.world.blocks.power.PowerGenerator.*; import mindustry.world.blocks.power.*; -import mindustry.world.consumers.*; import org.junit.jupiter.api.*; import static org.junit.jupiter.api.Assertions.*; @@ -133,9 +132,8 @@ void directConsumptionStopsWithNoPower(){ powerGraph.update(); assertEquals(0.0f, consumerTile.build.power.status, Mathf.FLOAT_ROUNDING_ERROR); - if(consumerTile.block().consumes.hasPower()){ - ConsumePower consumePower = consumerTile.block().consumes.getPower(); - assertFalse(consumePower.valid(consumerTile.build)); + if(consumerTile.block().consPower != null){ + assertFalse(consumerTile.block().consPower.valid(consumerTile.build)); } } }