mirror of
https://github.com/Anuken/Mindustry.git
synced 2024-09-11 08:15:35 +03:00
Removing Nulls.unit
This commit is contained in:
parent
e3ba8b714b
commit
295573142f
@ -851,89 +851,6 @@ public class EntityProcess extends BaseProcessor{
|
|||||||
for(TypeSpec.Builder b : baseClasses){
|
for(TypeSpec.Builder b : baseClasses){
|
||||||
write(b, imports.toSeq());
|
write(b, imports.toSeq());
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO nulls were an awful idea
|
|
||||||
//store nulls
|
|
||||||
TypeSpec.Builder nullsBuilder = TypeSpec.classBuilder("Nulls").addModifiers(Modifier.PUBLIC).addModifiers(Modifier.FINAL);
|
|
||||||
//TODO should be dynamic
|
|
||||||
ObjectSet<String> nullList = ObjectSet.with("unit");
|
|
||||||
|
|
||||||
//create mock types of all components
|
|
||||||
for(Stype interf : allInterfaces){
|
|
||||||
//indirect interfaces to implement methods for
|
|
||||||
Seq<Stype> dependencies = interf.allInterfaces().add(interf);
|
|
||||||
Seq<Smethod> methods = dependencies.flatMap(Stype::methods);
|
|
||||||
methods.sortComparing(Object::toString);
|
|
||||||
|
|
||||||
//optionally add superclass
|
|
||||||
Stype superclass = dependencies.map(this::interfaceToComp).find(s -> s != null && s.annotation(Component.class).base());
|
|
||||||
//use the base type when the interface being emulated has a base
|
|
||||||
TypeName type = superclass != null && interfaceToComp(interf).annotation(Component.class).base() ? tname(baseName(superclass)) : interf.tname();
|
|
||||||
|
|
||||||
//used method signatures
|
|
||||||
ObjectSet<String> signatures = new ObjectSet<>();
|
|
||||||
|
|
||||||
//create null builder
|
|
||||||
String baseName = interf.name().substring(0, interf.name().length() - 1);
|
|
||||||
|
|
||||||
//prevent Nulls bloat
|
|
||||||
if(!nullList.contains(Strings.camelize(baseName))){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
String className = "Null" + baseName;
|
|
||||||
TypeSpec.Builder nullBuilder = TypeSpec.classBuilder(className)
|
|
||||||
.addModifiers(Modifier.FINAL);
|
|
||||||
|
|
||||||
skipDeprecated(nullBuilder);
|
|
||||||
|
|
||||||
nullBuilder.addSuperinterface(interf.tname());
|
|
||||||
if(superclass != null) nullBuilder.superclass(tname(baseName(superclass)));
|
|
||||||
|
|
||||||
for(Smethod method : methods){
|
|
||||||
String signature = method.toString();
|
|
||||||
if(!signatures.add(signature)) continue;
|
|
||||||
|
|
||||||
Stype compType = interfaceToComp(method.type());
|
|
||||||
MethodSpec.Builder builder = MethodSpec.overriding(method.e).addModifiers(Modifier.PUBLIC, Modifier.FINAL);
|
|
||||||
int index = 0;
|
|
||||||
for(ParameterSpec spec : builder.parameters){
|
|
||||||
Reflect.set(spec, "name", "arg" + index++);
|
|
||||||
}
|
|
||||||
builder.addAnnotation(OverrideCallSuper.class); //just in case
|
|
||||||
|
|
||||||
if(!method.isVoid()){
|
|
||||||
String methodName = method.name();
|
|
||||||
switch(methodName){
|
|
||||||
case "isNull":
|
|
||||||
builder.addStatement("return true");
|
|
||||||
break;
|
|
||||||
case "id":
|
|
||||||
builder.addStatement("return -1");
|
|
||||||
break;
|
|
||||||
case "toString":
|
|
||||||
builder.addStatement("return $S", className);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Svar variable = compType == null || method.params().size > 0 ? null : compType.fields().find(v -> v.name().equals(methodName));
|
|
||||||
String desc = variable == null ? null : variable.descString();
|
|
||||||
if(variable == null || !varInitializers.containsKey(desc)){
|
|
||||||
builder.addStatement("return " + getDefault(method.ret().toString()));
|
|
||||||
}else{
|
|
||||||
String init = varInitializers.get(desc);
|
|
||||||
builder.addStatement("return " + (init.equals("{}") ? "new " + variable.mirror().toString() : "") + init);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nullBuilder.addMethod(builder.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
nullsBuilder.addField(FieldSpec.builder(type, Strings.camelize(baseName)).initializer("new " + className + "()").addModifiers(Modifier.FINAL, Modifier.STATIC, Modifier.PUBLIC).build());
|
|
||||||
|
|
||||||
write(nullBuilder, imports.toSeq());
|
|
||||||
}
|
|
||||||
|
|
||||||
write(nullsBuilder);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -622,21 +622,22 @@ public class NetClient implements ApplicationListener{
|
|||||||
|
|
||||||
void sync(){
|
void sync(){
|
||||||
if(timer.get(0, playerSyncTime)){
|
if(timer.get(0, playerSyncTime)){
|
||||||
Unit unit = player.dead() ? Nulls.unit : player.unit();
|
boolean dead = player.dead();
|
||||||
int uid = player.dead() ? -1 : unit.id;
|
Unit unit = dead ? null : player.unit();
|
||||||
|
int uid = dead || unit == null ? -1 : unit.id;
|
||||||
|
|
||||||
Call.clientSnapshot(
|
Call.clientSnapshot(
|
||||||
lastSent++,
|
lastSent++,
|
||||||
uid,
|
uid,
|
||||||
player.dead(),
|
dead,
|
||||||
player.dead() ? player.x : unit.x, player.dead() ? player.y : unit.y,
|
dead ? player.x : unit.x, dead ? player.y : unit.y,
|
||||||
player.unit().aimX(), player.unit().aimY(),
|
dead ? 0f : unit.aimX(), dead ? 0f : unit.aimY(),
|
||||||
unit.rotation,
|
unit == null ? 0f : unit.rotation,
|
||||||
unit instanceof Mechc m ? m.baseRotation() : 0,
|
unit instanceof Mechc m ? m.baseRotation() : 0,
|
||||||
unit.vel.x, unit.vel.y,
|
unit == null ? 0f : unit.vel.x, unit == null ? 0f : unit.vel.y,
|
||||||
player.unit().mineTile,
|
dead ? null : unit.mineTile,
|
||||||
player.boosting, player.shooting, ui.chatfrag.shown(), control.input.isBuilding,
|
player.boosting, player.shooting, ui.chatfrag.shown(), control.input.isBuilding,
|
||||||
player.isBuilder() ? player.unit().plans : null,
|
player.isBuilder() && unit != null ? unit.plans : null,
|
||||||
Core.camera.position.x, Core.camera.position.y,
|
Core.camera.position.x, Core.camera.position.y,
|
||||||
Core.camera.width, Core.camera.height
|
Core.camera.width, Core.camera.height
|
||||||
);
|
);
|
||||||
|
@ -98,7 +98,7 @@ public class NetServer implements ApplicationListener{
|
|||||||
private boolean closing = false, pvpAutoPaused = true;
|
private boolean closing = false, pvpAutoPaused = true;
|
||||||
private Interval timer = new Interval(10);
|
private Interval timer = new Interval(10);
|
||||||
private IntSet buildHealthChanged = new IntSet();
|
private IntSet buildHealthChanged = new IntSet();
|
||||||
|
|
||||||
/** Current kick session. */
|
/** Current kick session. */
|
||||||
public @Nullable VoteSession currentlyKicking = null;
|
public @Nullable VoteSession currentlyKicking = null;
|
||||||
/** Duration of a kick in seconds. */
|
/** Duration of a kick in seconds. */
|
||||||
@ -548,10 +548,10 @@ public class NetServer implements ApplicationListener{
|
|||||||
@Remote(targets = Loc.client, variants = Variant.one)
|
@Remote(targets = Loc.client, variants = Variant.one)
|
||||||
public static void requestDebugStatus(Player player){
|
public static void requestDebugStatus(Player player){
|
||||||
int flags =
|
int flags =
|
||||||
(player.con.hasDisconnected ? 1 : 0) |
|
(player.con.hasDisconnected ? 1 : 0) |
|
||||||
(player.con.hasConnected ? 2 : 0) |
|
(player.con.hasConnected ? 2 : 0) |
|
||||||
(player.isAdded() ? 4 : 0) |
|
(player.isAdded() ? 4 : 0) |
|
||||||
(player.con.hasBegunConnecting ? 8 : 0);
|
(player.con.hasBegunConnecting ? 8 : 0);
|
||||||
|
|
||||||
Call.debugStatusClient(player.con, flags, player.con.lastReceivedClientSnapshot, player.con.snapshotsSent);
|
Call.debugStatusClient(player.con, flags, player.con.lastReceivedClientSnapshot, player.con.snapshotsSent);
|
||||||
Call.debugStatusClientUnreliable(player.con, flags, player.con.lastReceivedClientSnapshot, player.con.snapshotsSent);
|
Call.debugStatusClientUnreliable(player.con, flags, player.con.lastReceivedClientSnapshot, player.con.snapshotsSent);
|
||||||
@ -610,18 +610,18 @@ public class NetServer implements ApplicationListener{
|
|||||||
|
|
||||||
@Remote(targets = Loc.client, unreliable = true)
|
@Remote(targets = Loc.client, unreliable = true)
|
||||||
public static void clientSnapshot(
|
public static void clientSnapshot(
|
||||||
Player player,
|
Player player,
|
||||||
int snapshotID,
|
int snapshotID,
|
||||||
int unitID,
|
int unitID,
|
||||||
boolean dead,
|
boolean dead,
|
||||||
float x, float y,
|
float x, float y,
|
||||||
float pointerX, float pointerY,
|
float pointerX, float pointerY,
|
||||||
float rotation, float baseRotation,
|
float rotation, float baseRotation,
|
||||||
float xVelocity, float yVelocity,
|
float xVelocity, float yVelocity,
|
||||||
Tile mining,
|
Tile mining,
|
||||||
boolean boosting, boolean shooting, boolean chatting, boolean building,
|
boolean boosting, boolean shooting, boolean chatting, boolean building,
|
||||||
@Nullable Queue<BuildPlan> plans,
|
@Nullable Queue<BuildPlan> plans,
|
||||||
float viewX, float viewY, float viewWidth, float viewHeight
|
float viewX, float viewY, float viewWidth, float viewHeight
|
||||||
){
|
){
|
||||||
NetConnection con = player.con;
|
NetConnection con = player.con;
|
||||||
if(con == null || snapshotID < con.lastReceivedClientSnapshot) return;
|
if(con == null || snapshotID < con.lastReceivedClientSnapshot) return;
|
||||||
@ -660,12 +660,11 @@ public class NetServer implements ApplicationListener{
|
|||||||
player.shooting = shooting;
|
player.shooting = shooting;
|
||||||
player.boosting = boosting;
|
player.boosting = boosting;
|
||||||
|
|
||||||
player.unit().controlWeapons(shooting, shooting);
|
@Nullable var unit = player.unit();
|
||||||
player.unit().aim(pointerX, pointerY);
|
|
||||||
|
|
||||||
if(player.isBuilder()){
|
if(player.isBuilder()){
|
||||||
player.unit().clearBuilding();
|
unit.clearBuilding();
|
||||||
player.unit().updateBuilding(building);
|
unit.updateBuilding(building);
|
||||||
|
|
||||||
if(plans != null){
|
if(plans != null){
|
||||||
for(BuildPlan req : plans){
|
for(BuildPlan req : plans){
|
||||||
@ -694,12 +693,12 @@ public class NetServer implements ApplicationListener{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
player.unit().mineTile = mining;
|
|
||||||
|
|
||||||
con.rejectedRequests.clear();
|
con.rejectedRequests.clear();
|
||||||
|
|
||||||
if(!player.dead()){
|
if(!player.dead()){
|
||||||
Unit unit = player.unit();
|
unit.controlWeapons(shooting, shooting);
|
||||||
|
unit.aim(pointerX, pointerY);
|
||||||
|
unit.mineTile = mining;
|
||||||
|
|
||||||
long elapsed = Math.min(Time.timeSinceMillis(con.lastReceivedClientTime), 1500);
|
long elapsed = Math.min(Time.timeSinceMillis(con.lastReceivedClientTime), 1500);
|
||||||
float maxSpeed = unit.speed();
|
float maxSpeed = unit.speed();
|
||||||
@ -1125,7 +1124,7 @@ public class NetServer implements ApplicationListener{
|
|||||||
voted.put(admins.getInfo(player.uuid()).lastIP, d);
|
voted.put(admins.getInfo(player.uuid()).lastIP, d);
|
||||||
|
|
||||||
Call.sendMessage(Strings.format("[lightgray]@[lightgray] has voted on kicking[orange] @[lightgray].[accent] (@/@)\n[lightgray]Type[orange] /vote <y/n>[] to agree.",
|
Call.sendMessage(Strings.format("[lightgray]@[lightgray] has voted on kicking[orange] @[lightgray].[accent] (@/@)\n[lightgray]Type[orange] /vote <y/n>[] to agree.",
|
||||||
player.name, target.name, votes, votesRequired()));
|
player.name, target.name, votes, votesRequired()));
|
||||||
|
|
||||||
checkPass();
|
checkPass();
|
||||||
}
|
}
|
||||||
|
@ -35,10 +35,6 @@ abstract class EntityComp{
|
|||||||
return ((Object)this) instanceof Unitc u && u.isPlayer() && !isLocal();
|
return ((Object)this) instanceof Unitc u && u.isPlayer() && !isLocal();
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isNull(){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Replaced with `this` after code generation. */
|
/** Replaced with `this` after code generation. */
|
||||||
<T extends Entityc> T self(){
|
<T extends Entityc> T self(){
|
||||||
return (T)this;
|
return (T)this;
|
||||||
|
@ -33,7 +33,7 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
|
|||||||
|
|
||||||
@Import float x, y;
|
@Import float x, y;
|
||||||
|
|
||||||
@ReadOnly Unit unit = Nulls.unit;
|
@ReadOnly @Nullable Unit unit;
|
||||||
transient @Nullable NetConnection con;
|
transient @Nullable NetConnection con;
|
||||||
@ReadOnly Team team = Team.sharded;
|
@ReadOnly Team team = Team.sharded;
|
||||||
@SyncLocal boolean typing, shooting, boosting;
|
@SyncLocal boolean typing, shooting, boosting;
|
||||||
@ -49,12 +49,12 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
|
|||||||
transient float textFadeTime;
|
transient float textFadeTime;
|
||||||
transient Ratekeeper itemDepositRate = new Ratekeeper();
|
transient Ratekeeper itemDepositRate = new Ratekeeper();
|
||||||
|
|
||||||
transient private Unit lastReadUnit = Nulls.unit;
|
transient private @Nullable Unit lastReadUnit;
|
||||||
transient private int wrongReadUnits;
|
transient private int wrongReadUnits;
|
||||||
transient @Nullable Unit justSwitchFrom, justSwitchTo;
|
transient @Nullable Unit justSwitchFrom, justSwitchTo;
|
||||||
|
|
||||||
public boolean isBuilder(){
|
public boolean isBuilder(){
|
||||||
return unit.canBuild();
|
return unit != null && unit.canBuild();
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable CoreBuild closestCore(){
|
public @Nullable CoreBuild closestCore(){
|
||||||
@ -89,7 +89,7 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
|
|||||||
x = y = 0f;
|
x = y = 0f;
|
||||||
if(!dead()){
|
if(!dead()){
|
||||||
unit.resetController();
|
unit.resetController();
|
||||||
unit = Nulls.unit;
|
unit = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,7 +105,7 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
|
|||||||
|
|
||||||
@Replace
|
@Replace
|
||||||
public float clipSize(){
|
public float clipSize(){
|
||||||
return unit.isNull() ? 20 : unit.type.hitSize * 2f;
|
return unit == null ? 20 : unit.type.hitSize * 2f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -131,17 +131,18 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
|
|||||||
unit = lastReadUnit;
|
unit = lastReadUnit;
|
||||||
unit(set);
|
unit(set);
|
||||||
lastReadUnit = unit;
|
lastReadUnit = unit;
|
||||||
|
if(unit != null){
|
||||||
unit.aim(mouseX, mouseY);
|
unit.aim(mouseX, mouseY);
|
||||||
//this is only necessary when the thing being controlled isn't synced
|
//this is only necessary when the thing being controlled isn't synced
|
||||||
unit.controlWeapons(shooting, shooting);
|
unit.controlWeapons(shooting, shooting);
|
||||||
//extra precaution, necessary for non-synced things
|
//extra precaution, necessary for non-synced things
|
||||||
unit.controller(this);
|
unit.controller(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(){
|
public void update(){
|
||||||
if(!unit.isValid()){
|
if(unit != null && !unit.isValid()){
|
||||||
clearUnit();
|
clearUnit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,42 +182,43 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
|
|||||||
@Override
|
@Override
|
||||||
public void remove(){
|
public void remove(){
|
||||||
//clear unit upon removal
|
//clear unit upon removal
|
||||||
if(!unit.isNull()){
|
if(unit != null){
|
||||||
clearUnit();
|
clearUnit();
|
||||||
}
|
}
|
||||||
|
|
||||||
lastReadUnit = Nulls.unit;
|
lastReadUnit = null;
|
||||||
justSwitchTo = justSwitchFrom = null;
|
justSwitchTo = justSwitchFrom = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void team(Team team){
|
public void team(Team team){
|
||||||
this.team = team;
|
this.team = team;
|
||||||
unit.team(team);
|
if(unit != null){
|
||||||
|
unit.team(team);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearUnit(){
|
public void clearUnit(){
|
||||||
unit(Nulls.unit);
|
unit(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Unit unit(){
|
public @Nullable Unit unit(){
|
||||||
return unit;
|
return unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unit(Unit unit){
|
public void unit(@Nullable Unit unit){
|
||||||
//refuse to switch when the unit was just transitioned from
|
//refuse to switch when the unit was just transitioned from
|
||||||
if(isLocal() && unit == justSwitchFrom && justSwitchFrom != null && justSwitchTo != null){
|
if(isLocal() && unit == justSwitchFrom && justSwitchFrom != null && justSwitchTo != null){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
//save last command this unit had
|
||||||
if(unit.controller() instanceof CommandAI ai){
|
if(unit != null && unit.controller() instanceof CommandAI ai){
|
||||||
lastCommand = ai.command;
|
lastCommand = ai.command;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.unit != Nulls.unit){
|
if(this.unit != null){
|
||||||
//un-control the old unit
|
//un-control the old unit
|
||||||
this.unit.resetController();
|
this.unit.resetController();
|
||||||
//restore last command issued before it was controlled
|
//restore last command issued before it was controlled
|
||||||
@ -225,7 +227,7 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.unit = unit;
|
this.unit = unit;
|
||||||
if(unit != Nulls.unit){
|
if(unit != null){
|
||||||
unit.team(team);
|
unit.team(team);
|
||||||
unit.controller(this);
|
unit.controller(this);
|
||||||
|
|
||||||
@ -244,7 +246,7 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean dead(){
|
boolean dead(){
|
||||||
return unit.isNull() || !unit.isValid();
|
return unit == null || !unit.isValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
String ip(){
|
String ip(){
|
||||||
|
@ -116,7 +116,9 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
private WidgetGroup group = new WidgetGroup();
|
private WidgetGroup group = new WidgetGroup();
|
||||||
|
|
||||||
private final Eachable<BuildPlan> allPlans = cons -> {
|
private final Eachable<BuildPlan> allPlans = cons -> {
|
||||||
player.unit().plans().each(cons);
|
if(!player.dead()){
|
||||||
|
player.unit().plans().each(cons);
|
||||||
|
}
|
||||||
selectPlans.each(cons);
|
selectPlans.each(cons);
|
||||||
linePlans.each(cons);
|
linePlans.each(cons);
|
||||||
};
|
};
|
||||||
@ -236,9 +238,6 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
public static void commandUnits(Player player, int[] unitIds, @Nullable Building buildTarget, @Nullable Unit unitTarget, @Nullable Vec2 posTarget, boolean queueCommand, boolean finalBatch){
|
public static void commandUnits(Player player, int[] unitIds, @Nullable Building buildTarget, @Nullable Unit unitTarget, @Nullable Vec2 posTarget, boolean queueCommand, boolean finalBatch){
|
||||||
if(player == null || unitIds == null) return;
|
if(player == null || unitIds == null) return;
|
||||||
|
|
||||||
//why did I ever think this was a good idea
|
|
||||||
if(unitTarget != null && unitTarget.isNull()) unitTarget = null;
|
|
||||||
|
|
||||||
if(net.server() && !netServer.admins.allowAction(player, ActionType.commandUnits, event -> {
|
if(net.server() && !netServer.admins.allowAction(player, ActionType.commandUnits, event -> {
|
||||||
event.unitIDs = unitIds;
|
event.unitIDs = unitIds;
|
||||||
})){
|
})){
|
||||||
@ -260,7 +259,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(teamTarget != null && teamTarget.team() != player.team() &&
|
if(teamTarget != null && teamTarget.team() != player.team() &&
|
||||||
!(teamTarget instanceof Unit u && !unit.canTarget(u)) && !(teamTarget instanceof Building && !unit.type.targetGround)){
|
!(teamTarget instanceof Unit u && !unit.canTarget(u)) && !(teamTarget instanceof Building && !unit.type.targetGround)){
|
||||||
|
|
||||||
anyCommandedTarget = true;
|
anyCommandedTarget = true;
|
||||||
if(queueCommand){
|
if(queueCommand){
|
||||||
@ -282,7 +281,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
if(ai.commandQueue.size <= 0){
|
if(ai.commandQueue.size <= 0){
|
||||||
ai.group = null;
|
ai.group = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
//remove when other player command
|
//remove when other player command
|
||||||
if(!headless && player != Vars.player){
|
if(!headless && player != Vars.player){
|
||||||
control.input.selectedUnits.remove(unit);
|
control.input.selectedUnits.remove(unit);
|
||||||
@ -489,8 +488,6 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
|
|
||||||
@Remote(targets = Loc.server, called = Loc.server)
|
@Remote(targets = Loc.server, called = Loc.server)
|
||||||
public static void pickedUnitPayload(Unit unit, Unit target){
|
public static void pickedUnitPayload(Unit unit, Unit target){
|
||||||
if(target == Nulls.unit) return;
|
|
||||||
|
|
||||||
if(target != null && unit instanceof Payloadc pay){
|
if(target != null && unit instanceof Payloadc pay){
|
||||||
pay.pickup(target);
|
pay.pickup(target);
|
||||||
}else if(target != null){
|
}else if(target != null){
|
||||||
@ -599,7 +596,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
if(build == null) return;
|
if(build == null) return;
|
||||||
|
|
||||||
if(net.server() && (!Units.canInteract(player, build) ||
|
if(net.server() && (!Units.canInteract(player, build) ||
|
||||||
!netServer.admins.allowAction(player, ActionType.rotate, build.tile(), action -> action.rotation = Mathf.mod(build.rotation + Mathf.sign(direction), 4)))){
|
!netServer.admins.allowAction(player, ActionType.rotate, build.tile(), action -> action.rotation = Mathf.mod(build.rotation + Mathf.sign(direction), 4)))){
|
||||||
throw new ValidateException(player, "Player cannot rotate a block.");
|
throw new ValidateException(player, "Player cannot rotate a block.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -618,7 +615,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
if(build == null) return;
|
if(build == null) return;
|
||||||
|
|
||||||
if(net.server() && (!Units.canInteract(player, build) ||
|
if(net.server() && (!Units.canInteract(player, build) ||
|
||||||
!netServer.admins.allowAction(player, ActionType.configure, build.tile, action -> action.config = value))){
|
!netServer.admins.allowAction(player, ActionType.configure, build.tile, action -> action.config = value))){
|
||||||
|
|
||||||
if(player.con != null){
|
if(player.con != null){
|
||||||
var packet = new TileConfigCallPacket(); //undo the config on the client
|
var packet = new TileConfigCallPacket(); //undo the config on the client
|
||||||
@ -697,7 +694,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
|
|
||||||
player.unit(unit);
|
player.unit(unit);
|
||||||
|
|
||||||
if(before != null && !before.isNull()){
|
if(before != null){
|
||||||
if(before.spawnedByCore){
|
if(before.spawnedByCore){
|
||||||
unit.dockedType = before.type;
|
unit.dockedType = before.type;
|
||||||
}else if(before.dockedType != null && before.dockedType.coreUnitDock){
|
}else if(before.dockedType != null && before.dockedType.coreUnitDock){
|
||||||
@ -812,7 +809,9 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
}
|
}
|
||||||
|
|
||||||
playerPlanTree.clear();
|
playerPlanTree.clear();
|
||||||
player.unit().plans.each(playerPlanTree::insert);
|
if(!player.dead()){
|
||||||
|
player.unit().plans.each(playerPlanTree::insert);
|
||||||
|
}
|
||||||
|
|
||||||
player.typing = ui.chatfrag.shown();
|
player.typing = ui.chatfrag.shown();
|
||||||
|
|
||||||
@ -824,7 +823,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
player.unit().updateBuilding(isBuilding);
|
player.unit().updateBuilding(isBuilding);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(player.shooting && !wasShooting && player.unit().hasWeapons() && state.rules.unitAmmo && !player.team().rules().infiniteAmmo && player.unit().ammo <= 0){
|
if(!player.dead() && player.shooting && !wasShooting && player.unit().hasWeapons() && state.rules.unitAmmo && !player.team().rules().infiniteAmmo && player.unit().ammo <= 0){
|
||||||
player.unit().type.weapons.first().noAmmoSound.at(player.unit());
|
player.unit().type.weapons.first().noAmmoSound.at(player.unit());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1673,9 +1672,9 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
|
|
||||||
boolean canMine(Tile tile){
|
boolean canMine(Tile tile){
|
||||||
return !Core.scene.hasMouse()
|
return !Core.scene.hasMouse()
|
||||||
&& player.unit().validMine(tile)
|
&& player.unit().validMine(tile)
|
||||||
&& player.unit().acceptsItem(player.unit().getMineResult(tile))
|
&& player.unit().acceptsItem(player.unit().getMineResult(tile))
|
||||||
&& !((!Core.settings.getBool("doubletapmine") && tile.floor().playerUnmineable) && tile.overlay().itemDrop == null);
|
&& !((!Core.settings.getBool("doubletapmine") && tile.floor().playerUnmineable) && tile.overlay().itemDrop == null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the tile at the specified MOUSE coordinates. */
|
/** Returns the tile at the specified MOUSE coordinates. */
|
||||||
@ -1841,7 +1840,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
|
|
||||||
public boolean canShoot(){
|
public boolean canShoot(){
|
||||||
return block == null && !onConfigurable() && !isDroppingItem() && !player.unit().activelyBuilding() &&
|
return block == null && !onConfigurable() && !isDroppingItem() && !player.unit().activelyBuilding() &&
|
||||||
!(player.unit() instanceof Mechc && player.unit().isFlying()) && !player.unit().mining() && !commandMode;
|
!(player.unit() instanceof Mechc && player.unit().isFlying()) && !player.unit().mining() && !commandMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean onConfigurable(){
|
public boolean onConfigurable(){
|
||||||
@ -1867,7 +1866,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
ItemStack stack = player.unit().stack;
|
ItemStack stack = player.unit().stack;
|
||||||
|
|
||||||
if(build != null && build.acceptStack(stack.item, stack.amount, player.unit()) > 0 && build.interactable(player.team()) &&
|
if(build != null && build.acceptStack(stack.item, stack.amount, player.unit()) > 0 && build.interactable(player.team()) &&
|
||||||
build.block.hasItems && player.unit().stack().amount > 0 && build.interactable(player.team())){
|
build.block.hasItems && player.unit().stack().amount > 0 && build.interactable(player.team())){
|
||||||
|
|
||||||
if(!(state.rules.onlyDepositCore && !(build instanceof CoreBuild)) && itemDepositCooldown <= 0f){
|
if(!(state.rules.onlyDepositCore && !(build instanceof CoreBuild)) && itemDepositCooldown <= 0f){
|
||||||
Call.transferInventory(player, build);
|
Call.transferInventory(player, build);
|
||||||
|
@ -90,7 +90,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
void checkTargets(float x, float y){
|
void checkTargets(float x, float y){
|
||||||
Unit unit = Units.closestEnemy(player.team(), x, y, 20f, u -> !u.dead);
|
Unit unit = Units.closestEnemy(player.team(), x, y, 20f, u -> !u.dead);
|
||||||
|
|
||||||
if(unit != null && player.unit().type.canAttack){
|
if(unit != null && !player.dead() && player.unit().type.canAttack){
|
||||||
player.unit().mineTile = null;
|
player.unit().mineTile = null;
|
||||||
target = unit;
|
target = unit;
|
||||||
}else{
|
}else{
|
||||||
@ -126,18 +126,21 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(var plan : player.unit().plans()){
|
if(!player.dead()){
|
||||||
Tile other = world.tile(plan.x, plan.y);
|
for(var plan : player.unit().plans()){
|
||||||
|
Tile other = world.tile(plan.x, plan.y);
|
||||||
|
|
||||||
if(other == null || plan.breaking) continue;
|
if(other == null || plan.breaking) continue;
|
||||||
|
|
||||||
r1.setSize(plan.block.size * tilesize);
|
r1.setSize(plan.block.size * tilesize);
|
||||||
r1.setCenter(other.worldx() + plan.block.offset, other.worldy() + plan.block.offset);
|
r1.setCenter(other.worldx() + plan.block.offset, other.worldy() + plan.block.offset);
|
||||||
|
|
||||||
if(r2.overlaps(r1)){
|
if(r2.overlaps(r1)){
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,7 +266,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean showCancel(){
|
boolean showCancel(){
|
||||||
return (player.unit().isBuilding() || block != null || mode == breaking || !selectPlans.isEmpty()) && !hasSchem();
|
return !player.dead() && (player.unit().isBuilding() || block != null || mode == breaking || !selectPlans.isEmpty()) && !hasSchem();
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean hasSchem(){
|
boolean hasSchem(){
|
||||||
@ -277,7 +280,9 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
t.visible(this::showCancel);
|
t.visible(this::showCancel);
|
||||||
t.bottom().left();
|
t.bottom().left();
|
||||||
t.button("@cancel", Icon.cancel, () -> {
|
t.button("@cancel", Icon.cancel, () -> {
|
||||||
player.unit().clearBuilding();
|
if(!player.dead()){
|
||||||
|
player.unit().clearBuilding();
|
||||||
|
}
|
||||||
selectPlans.clear();
|
selectPlans.clear();
|
||||||
mode = none;
|
mode = none;
|
||||||
block = null;
|
block = null;
|
||||||
@ -864,7 +869,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(player.shooting && (player.unit().activelyBuilding() || player.unit().mining())){
|
if(player.shooting && !player.dead() && (player.unit().activelyBuilding() || player.unit().mining())){
|
||||||
player.shooting = false;
|
player.shooting = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1037,7 +1042,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
unit.movePref(movement);
|
unit.movePref(movement);
|
||||||
|
|
||||||
//update shooting if not building + not mining
|
//update shooting if not building + not mining
|
||||||
if(!player.unit().activelyBuilding() && player.unit().mineTile == null){
|
if(!unit.activelyBuilding() && unit.mineTile == null){
|
||||||
|
|
||||||
//autofire targeting
|
//autofire targeting
|
||||||
if(manualShooting){
|
if(manualShooting){
|
||||||
@ -1046,7 +1051,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
}else if(target == null){
|
}else if(target == null){
|
||||||
player.shooting = false;
|
player.shooting = false;
|
||||||
if(Core.settings.getBool("autotarget") && !(player.unit() instanceof BlockUnitUnit u && u.tile() instanceof ControlBlock c && !c.shouldAutoTarget())){
|
if(Core.settings.getBool("autotarget") && !(player.unit() instanceof BlockUnitUnit u && u.tile() instanceof ControlBlock c && !c.shouldAutoTarget())){
|
||||||
if(player.unit().type.canAttack){
|
if(unit.type.canAttack){
|
||||||
target = Units.closestTarget(unit.team, unit.x, unit.y, range, u -> u.checkTarget(type.targetAir, type.targetGround), u -> type.targetGround);
|
target = Units.closestTarget(unit.team, unit.x, unit.y, range, u -> u.checkTarget(type.targetAir, type.targetGround), u -> type.targetGround);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,7 +279,7 @@ public class TypeIO{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void writeUnit(Writes write, Unit unit){
|
public static void writeUnit(Writes write, Unit unit){
|
||||||
write.b(unit == null || unit.isNull() ? 0 : unit instanceof BlockUnitc ? 1 : 2);
|
write.b(unit == null ? 0 : unit instanceof BlockUnitc ? 1 : 2);
|
||||||
|
|
||||||
//block units are special
|
//block units are special
|
||||||
if(unit instanceof BlockUnitc){
|
if(unit instanceof BlockUnitc){
|
||||||
@ -295,15 +295,14 @@ public class TypeIO{
|
|||||||
byte type = read.b();
|
byte type = read.b();
|
||||||
int id = read.i();
|
int id = read.i();
|
||||||
//nothing
|
//nothing
|
||||||
if(type == 0) return Nulls.unit;
|
if(type == 0) return null;
|
||||||
if(type == 2){ //standard unit
|
if(type == 2){ //standard unit
|
||||||
Unit unit = Groups.unit.getByID(id);
|
return Groups.unit.getByID(id);
|
||||||
return unit == null ? Nulls.unit : unit;
|
|
||||||
}else if(type == 1){ //block
|
}else if(type == 1){ //block
|
||||||
Building tile = world.build(id);
|
Building tile = world.build(id);
|
||||||
return tile instanceof ControlBlock cont ? cont.unit() : Nulls.unit;
|
return tile instanceof ControlBlock cont ? cont.unit() : null;
|
||||||
}
|
}
|
||||||
return Nulls.unit;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void writeCommand(Writes write, @Nullable UnitCommand command){
|
public static void writeCommand(Writes write, @Nullable UnitCommand command){
|
||||||
|
@ -1242,7 +1242,7 @@ public class LExecutor{
|
|||||||
result.setobj(units == null || i < 0 || i >= units.size ? null : units.get(i));
|
result.setobj(units == null || i < 0 || i >= units.size ? null : units.get(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case player -> result.setobj(i < 0 || i >= data.players.size || data.players.get(i).unit().isNull() ? null : data.players.get(i).unit());
|
case player -> result.setobj(i < 0 || i >= data.players.size ? null : data.players.get(i).unit());
|
||||||
case core -> result.setobj(i < 0 || i >= data.cores.size ? null : data.cores.get(i));
|
case core -> result.setobj(i < 0 || i >= data.cores.size ? null : data.cores.get(i));
|
||||||
case build -> {
|
case build -> {
|
||||||
Block block = extra.obj() instanceof Block b ? b : null;
|
Block block = extra.obj() instanceof Block b ? b : null;
|
||||||
|
@ -152,7 +152,7 @@ public class BlockInventoryFragment{
|
|||||||
|
|
||||||
container.add(i);
|
container.add(i);
|
||||||
|
|
||||||
Boolp canPick = () -> player.unit().acceptsItem(item) && !state.isPaused() && player.within(build, itemTransferRange);
|
Boolp canPick = () -> !player.dead() && player.unit().acceptsItem(item) && !state.isPaused() && player.within(build, itemTransferRange);
|
||||||
|
|
||||||
HandCursorListener l = new HandCursorListener();
|
HandCursorListener l = new HandCursorListener();
|
||||||
l.enabled = canPick;
|
l.enabled = canPick;
|
||||||
|
@ -167,7 +167,7 @@ public class HintsFragment{
|
|||||||
zoom(visibleDesktop, () -> Core.input.axis(KeyCode.scroll) != 0),
|
zoom(visibleDesktop, () -> Core.input.axis(KeyCode.scroll) != 0),
|
||||||
breaking(() -> isTutorial.get() && state.rules.defaultTeam.data().getCount(Blocks.conveyor) > 5, () -> ui.hints.events.contains("break")),
|
breaking(() -> isTutorial.get() && state.rules.defaultTeam.data().getCount(Blocks.conveyor) > 5, () -> ui.hints.events.contains("break")),
|
||||||
desktopShoot(visibleDesktop, () -> isSerpulo() && Vars.state.enemies > 0, () -> player.shooting),
|
desktopShoot(visibleDesktop, () -> isSerpulo() && Vars.state.enemies > 0, () -> player.shooting),
|
||||||
depositItems(() -> player.unit().hasItem(), () -> !player.unit().hasItem()),
|
depositItems(() -> !player.dead() && player.unit().hasItem(), () -> !player.dead() && !player.unit().hasItem()),
|
||||||
desktopPause(visibleDesktop, () -> isTutorial.get() && !Vars.net.active() && state.wave >= 2, () -> Core.input.keyTap(Binding.pause)),
|
desktopPause(visibleDesktop, () -> isTutorial.get() && !Vars.net.active() && state.wave >= 2, () -> Core.input.keyTap(Binding.pause)),
|
||||||
unitControl(() -> isSerpulo() && state.rules.defaultTeam.data().units.size > 2 && !net.active() && !player.dead(), () -> !player.dead() && !player.unit().spawnedByCore),
|
unitControl(() -> isSerpulo() && state.rules.defaultTeam.data().units.size > 2 && !net.active() && !player.dead(), () -> !player.dead() && !player.unit().spawnedByCore),
|
||||||
unitSelectControl(() -> isSerpulo() && state.rules.defaultTeam.data().units.size > 3 && !net.active() && !player.dead(),
|
unitSelectControl(() -> isSerpulo() && state.rules.defaultTeam.data().units.size > 3 && !net.active() && !player.dead(),
|
||||||
@ -179,8 +179,8 @@ public class HintsFragment{
|
|||||||
boost(visibleDesktop, () -> !player.dead() && player.unit().type.canBoost, () -> Core.input.keyDown(Binding.boost)),
|
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()),
|
blockInfo(() -> !(state.isCampaign() && state.rules.sector == SectorPresets.groundZero.sector && state.wave < 3), () -> ui.content.isShown()),
|
||||||
derelict(() -> ui.hints.events.contains("derelictmouse") && !isTutorial.get(), () -> ui.hints.events.contains("derelictbreak")),
|
derelict(() -> ui.hints.events.contains("derelictmouse") && !isTutorial.get(), () -> ui.hints.events.contains("derelictbreak")),
|
||||||
payloadPickup(() -> isSerpulo() && !player.unit().dead && player.unit() instanceof Payloadc p && p.payloads().isEmpty(), () -> player.unit() instanceof Payloadc p && p.payloads().any()),
|
payloadPickup(() -> isSerpulo() && !player.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()),
|
payloadDrop(() -> !player.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),
|
waveFire(() -> Groups.fire.size() > 0 && Blocks.wave.unlockedNow(), () -> indexer.getFlagged(state.rules.defaultTeam, BlockFlag.extinguisher).size > 0),
|
||||||
generator(() -> control.input.block == Blocks.combustionGenerator, () -> ui.hints.placedBlocks.contains(Blocks.combustionGenerator)),
|
generator(() -> control.input.block == Blocks.combustionGenerator, () -> ui.hints.placedBlocks.contains(Blocks.combustionGenerator)),
|
||||||
rebuildSelect(() -> state.rules.defaultTeam.data().plans.size >= 10, () -> control.input.isRebuildSelecting()),
|
rebuildSelect(() -> state.rules.defaultTeam.data().plans.size >= 10, () -> control.input.isRebuildSelecting()),
|
||||||
|
@ -767,7 +767,7 @@ public class HudFragment{
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
t.add(new SideBar(() -> player.unit().healthf(), () -> true, true)).width(bw).growY().padRight(pad);
|
t.add(new SideBar(() -> player.dead() ? 0f : player.unit().healthf(), () -> true, true)).width(bw).growY().padRight(pad);
|
||||||
t.image(() -> player.icon()).scaling(Scaling.bounded).grow().maxWidth(54f);
|
t.image(() -> player.icon()).scaling(Scaling.bounded).grow().maxWidth(54f);
|
||||||
t.add(new SideBar(() -> player.dead() ? 0f : player.displayAmmo() ? player.unit().ammof() : player.unit().healthf(), () -> !player.displayAmmo(), false)).width(bw).growY().padLeft(pad).update(b -> {
|
t.add(new SideBar(() -> player.dead() ? 0f : player.displayAmmo() ? player.unit().ammof() : player.unit().healthf(), () -> !player.displayAmmo(), false)).width(bw).growY().padLeft(pad).update(b -> {
|
||||||
b.color.set(player.displayAmmo() ? player.dead() || player.unit() instanceof BlockUnitc ? Pal.ammo : player.unit().type.ammoType.color() : Pal.health);
|
b.color.set(player.displayAmmo() ? player.dead() || player.unit() instanceof BlockUnitc ? Pal.ammo : player.unit().type.ammoType.color() : Pal.health);
|
||||||
@ -913,7 +913,7 @@ public class HudFragment{
|
|||||||
|
|
||||||
table.table().update(t -> {
|
table.table().update(t -> {
|
||||||
t.left();
|
t.left();
|
||||||
Bits applied = player.unit().statusBits();
|
Bits applied = player.unit() == null ? null : player.unit().statusBits();
|
||||||
if(!statuses.equals(applied)){
|
if(!statuses.equals(applied)){
|
||||||
t.clear();
|
t.clear();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user