mirror of
https://github.com/Anuken/Mindustry.git
synced 2026-04-19 03:51:07 -07:00
Tweaks to improve in-game editing
This commit is contained in:
parent
11ede2756e
commit
7a2234cd25
8 changed files with 153 additions and 118 deletions
|
|
@ -18,7 +18,7 @@ public class Annotations{
|
|||
}
|
||||
|
||||
/** Indicates that a method return or field can be null.*/
|
||||
@Target({ElementType.METHOD, ElementType.FIELD})
|
||||
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface Nullable{
|
||||
|
||||
|
|
|
|||
|
|
@ -40,10 +40,98 @@ public interface BuilderTrait extends Entity, TeamTrait{
|
|||
float placeDistance = 220f;
|
||||
float mineDistance = 70f;
|
||||
|
||||
//due to iOS wierdness
|
||||
class BuildDataStatic{
|
||||
static Array<BuildRequest> removal = new Array<>();
|
||||
static Vector2[] tmptr = new Vector2[]{new Vector2(), new Vector2(), new Vector2(), new Vector2()};
|
||||
/**
|
||||
* Update building mechanism for this unit.
|
||||
* This includes mining.
|
||||
*/
|
||||
default void updateBuilding(){
|
||||
float finalPlaceDst = state.rules.infiniteResources ? Float.MAX_VALUE : placeDistance;
|
||||
Unit unit = (Unit)this;
|
||||
//remove already completed build requests
|
||||
removal.clear();
|
||||
for(BuildRequest req : getPlaceQueue()){
|
||||
removal.add(req);
|
||||
}
|
||||
|
||||
getPlaceQueue().clear();
|
||||
|
||||
for(BuildRequest request : removal){
|
||||
if(!((request.breaking && world.tile(request.x, request.y).block() == Blocks.air) ||
|
||||
(!request.breaking && (world.tile(request.x, request.y).rotation() == request.rotation || !request.block.rotate)
|
||||
&& world.tile(request.x, request.y).block() == request.block))){
|
||||
getPlaceQueue().addLast(request);
|
||||
}
|
||||
}
|
||||
|
||||
BuildRequest current = getCurrentRequest();
|
||||
|
||||
//update mining here
|
||||
if(current == null){
|
||||
if(getMineTile() != null){
|
||||
updateMining();
|
||||
}
|
||||
return;
|
||||
}else{
|
||||
setMineTile(null);
|
||||
}
|
||||
|
||||
Tile tile = world.tile(current.x, current.y);
|
||||
|
||||
if(dst(tile) > finalPlaceDst){
|
||||
if(getPlaceQueue().size > 1){
|
||||
getPlaceQueue().removeFirst();
|
||||
getPlaceQueue().addLast(current);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if(!(tile.block() instanceof BuildBlock)){
|
||||
if(canCreateBlocks() && !current.breaking && Build.validPlace(getTeam(), current.x, current.y, current.block, current.rotation)){
|
||||
Call.beginPlace(getTeam(), current.x, current.y, current.block, current.rotation);
|
||||
}else if(canCreateBlocks() && current.breaking && Build.validBreak(getTeam(), current.x, current.y)){
|
||||
Call.beginBreak(getTeam(), current.x, current.y);
|
||||
}else{
|
||||
getPlaceQueue().removeFirst();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
TileEntity core = unit.getClosestCore();
|
||||
|
||||
//if there is no core to build with or no build entity, stop building!
|
||||
if((core == null && !state.rules.infiniteResources) || !(tile.entity instanceof BuildEntity)){
|
||||
return;
|
||||
}
|
||||
|
||||
//otherwise, update it.
|
||||
BuildEntity entity = tile.entity();
|
||||
|
||||
if(entity == null){
|
||||
return;
|
||||
}
|
||||
|
||||
if(unit.dst(tile) <= finalPlaceDst){
|
||||
unit.rotation = Mathf.slerpDelta(unit.rotation, unit.angleTo(entity), 0.4f);
|
||||
}
|
||||
|
||||
//progress is synced, thus not updated clientside
|
||||
if(!Net.client()){
|
||||
//deconstructing is 2x as fast
|
||||
if(current.breaking){
|
||||
entity.deconstruct(unit, core, 2f / entity.buildCost * Time.delta() * getBuildPower(tile) * state.rules.buildSpeedMultiplier);
|
||||
}else{
|
||||
entity.construct(unit, core, 1f / entity.buildCost * Time.delta() * getBuildPower(tile) * state.rules.buildSpeedMultiplier);
|
||||
}
|
||||
|
||||
current.progress = entity.progress();
|
||||
}else{
|
||||
entity.progress = current.progress;
|
||||
}
|
||||
|
||||
if(!current.initialized){
|
||||
Core.app.post(() -> Events.fire(new BuildSelectEvent(tile, unit.getTeam(), this, current.breaking)));
|
||||
current.initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the queue for storing build requests. */
|
||||
|
|
@ -148,97 +236,10 @@ public interface BuilderTrait extends Entity, TeamTrait{
|
|||
return getPlaceQueue().size == 0 ? null : getPlaceQueue().first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update building mechanism for this unit.
|
||||
* This includes mining.
|
||||
*/
|
||||
default void updateBuilding(){
|
||||
Unit unit = (Unit)this;
|
||||
//remove already completed build requests
|
||||
removal.clear();
|
||||
for(BuildRequest req : getPlaceQueue()){
|
||||
removal.add(req);
|
||||
}
|
||||
|
||||
getPlaceQueue().clear();
|
||||
|
||||
for(BuildRequest request : removal){
|
||||
if(!((request.breaking && world.tile(request.x, request.y).block() == Blocks.air) ||
|
||||
(!request.breaking && (world.tile(request.x, request.y).rotation() == request.rotation || !request.block.rotate)
|
||||
&& world.tile(request.x, request.y).block() == request.block))){
|
||||
getPlaceQueue().addLast(request);
|
||||
}
|
||||
}
|
||||
|
||||
BuildRequest current = getCurrentRequest();
|
||||
|
||||
//update mining here
|
||||
if(current == null){
|
||||
if(getMineTile() != null){
|
||||
updateMining();
|
||||
}
|
||||
return;
|
||||
}else{
|
||||
setMineTile(null);
|
||||
}
|
||||
|
||||
Tile tile = world.tile(current.x, current.y);
|
||||
|
||||
if(dst(tile) > placeDistance){
|
||||
if(getPlaceQueue().size > 1){
|
||||
getPlaceQueue().removeFirst();
|
||||
getPlaceQueue().addLast(current);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if(!(tile.block() instanceof BuildBlock)){
|
||||
if(canCreateBlocks() && !current.breaking && Build.validPlace(getTeam(), current.x, current.y, current.block, current.rotation)){
|
||||
Call.beginPlace(getTeam(), current.x, current.y, current.block, current.rotation);
|
||||
}else if(canCreateBlocks() && current.breaking && Build.validBreak(getTeam(), current.x, current.y)){
|
||||
Call.beginBreak(getTeam(), current.x, current.y);
|
||||
}else{
|
||||
getPlaceQueue().removeFirst();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
TileEntity core = unit.getClosestCore();
|
||||
|
||||
//if there is no core to build with or no build entity, stop building!
|
||||
if(core == null || !(tile.entity instanceof BuildEntity)){
|
||||
return;
|
||||
}
|
||||
|
||||
//otherwise, update it.
|
||||
BuildEntity entity = tile.entity();
|
||||
|
||||
if(entity == null){
|
||||
return;
|
||||
}
|
||||
|
||||
if(unit.dst(tile) <= placeDistance){
|
||||
unit.rotation = Mathf.slerpDelta(unit.rotation, unit.angleTo(entity), 0.4f);
|
||||
}
|
||||
|
||||
//progress is synced, thus not updated clientside
|
||||
if(!Net.client()){
|
||||
//deconstructing is 2x as fast
|
||||
if(current.breaking){
|
||||
entity.deconstruct(unit, core, 2f / entity.buildCost * Time.delta() * getBuildPower(tile) * state.rules.buildSpeedMultiplier);
|
||||
}else{
|
||||
entity.construct(unit, core, 1f / entity.buildCost * Time.delta() * getBuildPower(tile) * state.rules.buildSpeedMultiplier);
|
||||
}
|
||||
|
||||
current.progress = entity.progress();
|
||||
}else{
|
||||
entity.progress = current.progress;
|
||||
}
|
||||
|
||||
if(!current.initialized){
|
||||
Core.app.post(() -> Events.fire(new BuildSelectEvent(tile, unit.getTeam(), this, current.breaking)));
|
||||
current.initialized = true;
|
||||
}
|
||||
//due to iOS wierdness, this is apparently required
|
||||
class BuildDataStatic{
|
||||
static Array<BuildRequest> removal = new Array<>();
|
||||
static Vector2[] tmptr = new Vector2[]{new Vector2(), new Vector2(), new Vector2(), new Vector2()};
|
||||
}
|
||||
|
||||
/** Do not call directly. */
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package io.anuke.mindustry.entities.type;
|
||||
|
||||
import io.anuke.annotations.Annotations.Nullable;
|
||||
import io.anuke.arc.Core;
|
||||
import io.anuke.arc.Events;
|
||||
import io.anuke.arc.graphics.Color;
|
||||
|
|
@ -8,7 +9,8 @@ import io.anuke.arc.graphics.g2d.TextureRegion;
|
|||
import io.anuke.arc.math.Mathf;
|
||||
import io.anuke.arc.math.geom.Geometry;
|
||||
import io.anuke.arc.math.geom.Vector2;
|
||||
import io.anuke.arc.util.*;
|
||||
import io.anuke.arc.util.Time;
|
||||
import io.anuke.arc.util.Tmp;
|
||||
import io.anuke.mindustry.content.Blocks;
|
||||
import io.anuke.mindustry.content.Fx;
|
||||
import io.anuke.mindustry.entities.*;
|
||||
|
|
@ -221,7 +223,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
|||
velocity.add(moveVector.x / mass() * Time.delta(), moveVector.y / mass() * Time.delta());
|
||||
}
|
||||
|
||||
public TileEntity getClosestCore(){
|
||||
public @Nullable TileEntity getClosestCore(){
|
||||
TeamData data = state.teams.get(team);
|
||||
|
||||
Tile tile = Geometry.findClosest(x, y, data.cores);
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ public enum Gamemode{
|
|||
infiniteResources = true;
|
||||
editor = true;
|
||||
waves = true;
|
||||
enemyCoreBuildRadius = 0f;
|
||||
waveTimer = false;
|
||||
respawnTime = 0f;
|
||||
}}),;
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import io.anuke.arc.scene.utils.Elements;
|
|||
import io.anuke.arc.util.*;
|
||||
import io.anuke.mindustry.core.GameState.State;
|
||||
import io.anuke.mindustry.game.EventType.StateChangeEvent;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.game.UnlockableContent;
|
||||
import io.anuke.mindustry.gen.Call;
|
||||
import io.anuke.mindustry.graphics.Pal;
|
||||
|
|
@ -26,8 +27,6 @@ import io.anuke.mindustry.net.Packets.AdminAction;
|
|||
import io.anuke.mindustry.ui.*;
|
||||
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
|
||||
|
||||
import java.lang.StringBuilder;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class HudFragment extends Fragment{
|
||||
|
|
@ -131,8 +130,13 @@ public class HudFragment extends Fragment{
|
|||
}
|
||||
});
|
||||
|
||||
cont.table(stuff -> {
|
||||
stuff.left();
|
||||
Table wavesMain, editorMain;
|
||||
|
||||
cont.stack(wavesMain = new Table(), editorMain = new Table());
|
||||
|
||||
{
|
||||
wavesMain.visible(() -> shown && !state.isEditor());
|
||||
wavesMain.left();
|
||||
Stack stack = new Stack();
|
||||
TextButton waves = new TextButton("", "wave");
|
||||
Table btable = new Table().margin(0);
|
||||
|
|
@ -142,12 +146,36 @@ public class HudFragment extends Fragment{
|
|||
|
||||
addWaveTable(waves);
|
||||
addPlayButton(btable);
|
||||
stuff.add(stack).width(dsize * 4 + 3f);
|
||||
stuff.row();
|
||||
stuff.table("button", t -> t.margin(10f).add(new Bar("boss.health", Pal.health, () -> state.boss() == null ? 0f : state.boss().healthf()).blink(Color.WHITE))
|
||||
wavesMain.add(stack).width(dsize * 4 + 3f);
|
||||
wavesMain.row();
|
||||
wavesMain.table("button", t -> t.margin(10f).add(new Bar("boss.health", Pal.health, () -> state.boss() == null ? 0f : state.boss().healthf()).blink(Color.WHITE))
|
||||
.grow()).fillX().visible(() -> state.rules.waves && state.boss() != null).height(60f).get();
|
||||
stuff.row();
|
||||
}).visible(() -> shown);
|
||||
wavesMain.row();
|
||||
}
|
||||
|
||||
{
|
||||
editorMain.table("button-edge-4", t -> {
|
||||
//t.margin(0f);
|
||||
t.add("$editor.teams").growX().left();
|
||||
t.row();
|
||||
t.table(teams -> {
|
||||
teams.left();
|
||||
int i = 0;
|
||||
for(Team team : Team.all){
|
||||
ImageButton button = teams.addImageButton("white", "clear-toggle-partial", 40f, () -> player.setTeam(team))
|
||||
.size(50f).margin(6f).get();
|
||||
button.getImageCell().grow();
|
||||
button.getStyle().imageUpColor = team.color;
|
||||
button.update(() -> button.setChecked(player.getTeam() == team));
|
||||
|
||||
if(++i % 3 == 0){
|
||||
teams.row();
|
||||
}
|
||||
}
|
||||
}).left();
|
||||
}).width(dsize * 4 + 3f);
|
||||
editorMain.visible(() -> shown && state.isEditor());
|
||||
}
|
||||
|
||||
//fps display
|
||||
cont.table(info -> {
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ public class PlacementFragment extends Fragment{
|
|||
|
||||
button.update(() -> { //color unplacable things gray
|
||||
TileEntity core = player.getClosestCore();
|
||||
Color color = core != null && (core.items.has(block.buildRequirements, state.rules.buildCostMultiplier) || state.rules.infiniteResources) ? Color.WHITE : Color.GRAY;
|
||||
Color color = state.rules.infiniteResources || (core != null && (core.items.has(block.buildRequirements, state.rules.buildCostMultiplier) || state.rules.infiniteResources)) ? Color.WHITE : Color.GRAY;
|
||||
button.forEach(elem -> elem.setColor(color));
|
||||
button.setChecked(input.block == block);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ public class Build{
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
Tile tile = world.tile(x, y);
|
||||
|
||||
if(tile == null) return false;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package io.anuke.mindustry.world.blocks;
|
||||
|
||||
import io.anuke.annotations.Annotations.Loc;
|
||||
import io.anuke.annotations.Annotations.Remote;
|
||||
import io.anuke.annotations.Annotations.*;
|
||||
import io.anuke.arc.Core;
|
||||
import io.anuke.arc.Events;
|
||||
import io.anuke.arc.Graphics.Cursor;
|
||||
|
|
@ -185,13 +184,13 @@ public class BuildBlock extends Block{
|
|||
private float[] accumulator;
|
||||
private float[] totalAccumulator;
|
||||
|
||||
public void construct(Unit builder, TileEntity core, float amount){
|
||||
public void construct(Unit builder, @Nullable TileEntity core, float amount){
|
||||
if(cblock == null){
|
||||
kill();
|
||||
return;
|
||||
}
|
||||
|
||||
float maxProgress = checkRequired(core.items, amount, false);
|
||||
float maxProgress = core == null ? amount : checkRequired(core.items, amount, false);
|
||||
|
||||
for(int i = 0; i < cblock.buildRequirements.length; i++){
|
||||
int reqamount = Math.round(state.rules.buildCostMultiplier * cblock.buildRequirements[i].amount);
|
||||
|
|
@ -199,7 +198,7 @@ public class BuildBlock extends Block{
|
|||
totalAccumulator[i] = Math.min(totalAccumulator[i] + reqamount * maxProgress, reqamount);
|
||||
}
|
||||
|
||||
maxProgress = checkRequired(core.items, maxProgress, true);
|
||||
maxProgress = core == null ? maxProgress : checkRequired(core.items, maxProgress, true);
|
||||
|
||||
progress = Mathf.clamp(progress + maxProgress);
|
||||
|
||||
|
|
@ -212,7 +211,7 @@ public class BuildBlock extends Block{
|
|||
}
|
||||
}
|
||||
|
||||
public void deconstruct(Unit builder, TileEntity core, float amount){
|
||||
public void deconstruct(Unit builder, @Nullable TileEntity core, float amount){
|
||||
float deconstructMultiplier = 0.5f;
|
||||
|
||||
if(cblock != null){
|
||||
|
|
@ -229,10 +228,13 @@ public class BuildBlock extends Block{
|
|||
int accumulated = (int)(accumulator[i]); //get amount
|
||||
|
||||
if(amount > 0 && accumulated > 0){ //if it's positive, add it to the core
|
||||
int accepting = core.tile.block().acceptStack(requirements[i].item, accumulated, core.tile, builder);
|
||||
core.tile.block().handleStack(requirements[i].item, accepting, core.tile, builder);
|
||||
|
||||
accumulator[i] -= accepting;
|
||||
if(core != null){
|
||||
int accepting = core.tile.block().acceptStack(requirements[i].item, accumulated, core.tile, builder);
|
||||
core.tile.block().handleStack(requirements[i].item, accepting, core.tile, builder);
|
||||
accumulator[i] -= accepting;
|
||||
}else{
|
||||
accumulator[i] -= accumulated;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue