Select command from reconstructor / Units save command when controlled
This commit is contained in:
@@ -34,6 +34,14 @@ public class Annotations{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Indicates that a field should not be synced to clients (but may still be non-transient) */
|
||||||
|
@Target({ElementType.FIELD})
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
public @interface NoSync{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Indicates that a component field is imported from other components. This means it doesn't actually exist. */
|
/** Indicates that a component field is imported from other components. This means it doesn't actually exist. */
|
||||||
@Target({ElementType.FIELD})
|
@Target({ElementType.FIELD})
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ public class EntityIO{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeSync(MethodSpec.Builder method, boolean write, Seq<Svar> syncFields, Seq<Svar> allFields) throws Exception{
|
void writeSync(MethodSpec.Builder method, boolean write, Seq<Svar> allFields) throws Exception{
|
||||||
this.method = method;
|
this.method = method;
|
||||||
this.write = write;
|
this.write = write;
|
||||||
|
|
||||||
@@ -138,6 +138,7 @@ public class EntityIO{
|
|||||||
//add code for reading revision
|
//add code for reading revision
|
||||||
for(RevisionField field : rev.fields){
|
for(RevisionField field : rev.fields){
|
||||||
Svar var = allFields.find(s -> s.name().equals(field.name));
|
Svar var = allFields.find(s -> s.name().equals(field.name));
|
||||||
|
if(var == null || var.has(NoSync.class)) continue;
|
||||||
boolean sf = var.has(SyncField.class), sl = var.has(SyncLocal.class);
|
boolean sf = var.has(SyncField.class), sl = var.has(SyncLocal.class);
|
||||||
|
|
||||||
if(sl) cont("if(!islocal)");
|
if(sl) cont("if(!islocal)");
|
||||||
|
|||||||
@@ -490,7 +490,7 @@ public class EntityProcess extends BaseProcessor{
|
|||||||
|
|
||||||
//SPECIAL CASE: sync I/O code
|
//SPECIAL CASE: sync I/O code
|
||||||
if((first.name().equals("readSync") || first.name().equals("writeSync"))){
|
if((first.name().equals("readSync") || first.name().equals("writeSync"))){
|
||||||
io.writeSync(mbuilder, first.name().equals("writeSync"), syncedFields, allFields);
|
io.writeSync(mbuilder, first.name().equals("writeSync"), allFields);
|
||||||
}
|
}
|
||||||
|
|
||||||
//SPECIAL CASE: sync I/O code for writing to/from a manual buffer
|
//SPECIAL CASE: sync I/O code for writing to/from a manual buffer
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
{version:1,fields:[{name:admin,type:boolean},{name:boosting,type:boolean},{name:color,type:arc.graphics.Color},{name:lastCommand,type:mindustry.ai.UnitCommand},{name:mouseX,type:float},{name:mouseY,type:float},{name:name,type:java.lang.String},{name:shooting,type:boolean},{name:team,type:mindustry.game.Team},{name:typing,type:boolean},{name:unit,type:Unit},{name:x,type:float},{name:y,type:float}]}
|
||||||
@@ -2,6 +2,7 @@ package mindustry.ai;
|
|||||||
|
|
||||||
import arc.*;
|
import arc.*;
|
||||||
import arc.func.*;
|
import arc.func.*;
|
||||||
|
import arc.scene.style.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import mindustry.ai.types.*;
|
import mindustry.ai.types.*;
|
||||||
import mindustry.entities.units.*;
|
import mindustry.entities.units.*;
|
||||||
@@ -60,6 +61,10 @@ public class UnitCommand{
|
|||||||
return Core.bundle.get("command." + name);
|
return Core.bundle.get("command." + name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TextureRegionDrawable getIcon(){
|
||||||
|
return Icon.icons.get(icon, Icon.cancel);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString(){
|
public String toString(){
|
||||||
return "UnitCommand:" + name;
|
return "UnitCommand:" + name;
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import arc.scene.ui.layout.*;
|
|||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import arc.util.pooling.*;
|
import arc.util.pooling.*;
|
||||||
import mindustry.*;
|
import mindustry.*;
|
||||||
|
import mindustry.ai.*;
|
||||||
|
import mindustry.ai.types.*;
|
||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.entities.units.*;
|
import mindustry.entities.units.*;
|
||||||
@@ -36,6 +38,8 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
|
|||||||
@ReadOnly Team team = Team.sharded;
|
@ReadOnly Team team = Team.sharded;
|
||||||
@SyncLocal boolean typing, shooting, boosting;
|
@SyncLocal boolean typing, shooting, boosting;
|
||||||
@SyncLocal float mouseX, mouseY;
|
@SyncLocal float mouseX, mouseY;
|
||||||
|
/** command the unit had before it was controlled. */
|
||||||
|
@Nullable @NoSync UnitCommand lastCommand;
|
||||||
boolean admin;
|
boolean admin;
|
||||||
String name = "frog";
|
String name = "frog";
|
||||||
Color color = new Color();
|
Color color = new Color();
|
||||||
@@ -203,9 +207,18 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
|
|||||||
if(unit == null) throw new IllegalArgumentException("Unit cannot be null. Use clearUnit() instead.");
|
if(unit == null) throw new IllegalArgumentException("Unit cannot be null. Use clearUnit() instead.");
|
||||||
if(this.unit == unit) return;
|
if(this.unit == unit) return;
|
||||||
|
|
||||||
|
//save last command this unit had
|
||||||
|
if(unit.controller() instanceof CommandAI ai){
|
||||||
|
lastCommand = ai.command;
|
||||||
|
}
|
||||||
|
|
||||||
if(this.unit != Nulls.unit){
|
if(this.unit != Nulls.unit){
|
||||||
//un-control the old unit
|
//un-control the old unit
|
||||||
this.unit.resetController();
|
this.unit.resetController();
|
||||||
|
//restore last command issued before it was controlled
|
||||||
|
if(lastCommand != null && this.unit.controller() instanceof CommandAI ai){
|
||||||
|
ai.command(lastCommand);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this.unit = unit;
|
this.unit = unit;
|
||||||
if(unit != Nulls.unit){
|
if(unit != Nulls.unit){
|
||||||
|
|||||||
@@ -301,12 +301,13 @@ public class TypeIO{
|
|||||||
return Nulls.unit;
|
return Nulls.unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void writeCommand(Writes write, UnitCommand command){
|
public static void writeCommand(Writes write, @Nullable UnitCommand command){
|
||||||
write.b(command.id);
|
write.b(command == null ? 255 : command.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UnitCommand readCommand(Reads read){
|
public static @Nullable UnitCommand readCommand(Reads read){
|
||||||
return UnitCommand.all.get(read.ub());
|
int val = read.ub();
|
||||||
|
return val == 255 ? null : UnitCommand.all.get(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void writeEntity(Writes write, Entityc entity){
|
public static void writeEntity(Writes write, Entityc entity){
|
||||||
|
|||||||
@@ -1,13 +1,18 @@
|
|||||||
package mindustry.world.blocks.units;
|
package mindustry.world.blocks.units;
|
||||||
|
|
||||||
import arc.*;
|
import arc.*;
|
||||||
|
import arc.Graphics.*;
|
||||||
|
import arc.Graphics.Cursor.*;
|
||||||
import arc.graphics.g2d.*;
|
import arc.graphics.g2d.*;
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
|
import arc.scene.ui.*;
|
||||||
|
import arc.scene.ui.layout.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import arc.util.io.*;
|
import arc.util.io.*;
|
||||||
import mindustry.*;
|
import mindustry.*;
|
||||||
|
import mindustry.ai.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
import mindustry.entities.units.*;
|
import mindustry.entities.units.*;
|
||||||
@@ -35,6 +40,7 @@ public class Reconstructor extends UnitBlock{
|
|||||||
regionRotated2 = 2;
|
regionRotated2 = 2;
|
||||||
commandable = true;
|
commandable = true;
|
||||||
ambientSound = Sounds.respawning;
|
ambientSound = Sounds.respawning;
|
||||||
|
configurable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -132,6 +138,7 @@ public class Reconstructor extends UnitBlock{
|
|||||||
|
|
||||||
public class ReconstructorBuild extends UnitBuild{
|
public class ReconstructorBuild extends UnitBuild{
|
||||||
public @Nullable Vec2 commandPos;
|
public @Nullable Vec2 commandPos;
|
||||||
|
public @Nullable UnitCommand command;
|
||||||
|
|
||||||
public float fraction(){
|
public float fraction(){
|
||||||
return progress / constructTime;
|
return progress / constructTime;
|
||||||
@@ -157,6 +164,51 @@ public class Reconstructor extends UnitBlock{
|
|||||||
return hasUpgrade(unit.type) && !upgrade(unit.type).isBanned();
|
return hasUpgrade(unit.type) && !upgrade(unit.type).isBanned();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean canSetCommand(){
|
||||||
|
var output = unit();
|
||||||
|
return output != null && output.commands.length > 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Cursor getCursor(){
|
||||||
|
return canSetCommand() ? super.getCursor() : SystemCursor.arrow;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldShowConfigure(Player player){
|
||||||
|
return canSetCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void buildConfiguration(Table table){
|
||||||
|
var unit = unit();
|
||||||
|
|
||||||
|
if(unit == null){
|
||||||
|
deselect();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var group = new ButtonGroup<ImageButton>();
|
||||||
|
group.setMinCheckCount(0);
|
||||||
|
int i = 0, columns = 4;
|
||||||
|
|
||||||
|
table.background(Styles.black6);
|
||||||
|
|
||||||
|
var list = unit().commands;
|
||||||
|
for(var item : list){
|
||||||
|
ImageButton button = table.button(item.getIcon(), Styles.clearNoneTogglei, 40f, () -> {
|
||||||
|
command = (command == item ? null : item);
|
||||||
|
deselect();
|
||||||
|
}).tooltip(item.localized()).group(group).get();
|
||||||
|
|
||||||
|
button.update(() -> button.setChecked(command == item));
|
||||||
|
|
||||||
|
if(++i % columns == 0){
|
||||||
|
table.row();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean acceptPayload(Building source, Payload payload){
|
public boolean acceptPayload(Building source, Payload payload){
|
||||||
if(!(this.payload == null
|
if(!(this.payload == null
|
||||||
@@ -252,9 +304,17 @@ public class Reconstructor extends UnitBlock{
|
|||||||
//upgrade the unit
|
//upgrade the unit
|
||||||
if(progress >= constructTime){
|
if(progress >= constructTime){
|
||||||
payload.unit = upgrade(payload.unit.type).create(payload.unit.team());
|
payload.unit = upgrade(payload.unit.type).create(payload.unit.team());
|
||||||
if(commandPos != null && payload.unit.isCommandable()){
|
|
||||||
payload.unit.command().commandPosition(commandPos);
|
if(payload.unit.isCommandable()){
|
||||||
|
if(commandPos != null){
|
||||||
|
payload.unit.command().commandPosition(commandPos);
|
||||||
|
}
|
||||||
|
if(command != null){
|
||||||
|
//this already checks if it is a valid command for the unit type
|
||||||
|
payload.unit.command().command(command);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
progress %= 1f;
|
progress %= 1f;
|
||||||
Effect.shake(2f, 3f, this);
|
Effect.shake(2f, 3f, this);
|
||||||
Fx.producesmoke.at(this);
|
Fx.producesmoke.at(this);
|
||||||
@@ -303,7 +363,7 @@ public class Reconstructor extends UnitBlock{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte version(){
|
public byte version(){
|
||||||
return 2;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -312,6 +372,7 @@ public class Reconstructor extends UnitBlock{
|
|||||||
|
|
||||||
write.f(progress);
|
write.f(progress);
|
||||||
TypeIO.writeVecNullable(write, commandPos);
|
TypeIO.writeVecNullable(write, commandPos);
|
||||||
|
TypeIO.writeCommand(write, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -325,6 +386,10 @@ public class Reconstructor extends UnitBlock{
|
|||||||
if(revision >= 2){
|
if(revision >= 2){
|
||||||
commandPos = TypeIO.readVecNullable(read);
|
commandPos = TypeIO.readVecNullable(read);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(revision >= 3){
|
||||||
|
command = TypeIO.readCommand(read);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user