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){
|
||||
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(){
|
||||
if(timer.get(0, playerSyncTime)){
|
||||
Unit unit = player.dead() ? Nulls.unit : player.unit();
|
||||
int uid = player.dead() ? -1 : unit.id;
|
||||
boolean dead = player.dead();
|
||||
Unit unit = dead ? null : player.unit();
|
||||
int uid = dead || unit == null ? -1 : unit.id;
|
||||
|
||||
Call.clientSnapshot(
|
||||
lastSent++,
|
||||
uid,
|
||||
player.dead(),
|
||||
player.dead() ? player.x : unit.x, player.dead() ? player.y : unit.y,
|
||||
player.unit().aimX(), player.unit().aimY(),
|
||||
unit.rotation,
|
||||
dead,
|
||||
dead ? player.x : unit.x, dead ? player.y : unit.y,
|
||||
dead ? 0f : unit.aimX(), dead ? 0f : unit.aimY(),
|
||||
unit == null ? 0f : unit.rotation,
|
||||
unit instanceof Mechc m ? m.baseRotation() : 0,
|
||||
unit.vel.x, unit.vel.y,
|
||||
player.unit().mineTile,
|
||||
unit == null ? 0f : unit.vel.x, unit == null ? 0f : unit.vel.y,
|
||||
dead ? null : unit.mineTile,
|
||||
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.width, Core.camera.height
|
||||
);
|
||||
|
@ -98,7 +98,7 @@ public class NetServer implements ApplicationListener{
|
||||
private boolean closing = false, pvpAutoPaused = true;
|
||||
private Interval timer = new Interval(10);
|
||||
private IntSet buildHealthChanged = new IntSet();
|
||||
|
||||
|
||||
/** Current kick session. */
|
||||
public @Nullable VoteSession currentlyKicking = null;
|
||||
/** Duration of a kick in seconds. */
|
||||
@ -548,10 +548,10 @@ public class NetServer implements ApplicationListener{
|
||||
@Remote(targets = Loc.client, variants = Variant.one)
|
||||
public static void requestDebugStatus(Player player){
|
||||
int flags =
|
||||
(player.con.hasDisconnected ? 1 : 0) |
|
||||
(player.con.hasConnected ? 2 : 0) |
|
||||
(player.isAdded() ? 4 : 0) |
|
||||
(player.con.hasBegunConnecting ? 8 : 0);
|
||||
(player.con.hasDisconnected ? 1 : 0) |
|
||||
(player.con.hasConnected ? 2 : 0) |
|
||||
(player.isAdded() ? 4 : 0) |
|
||||
(player.con.hasBegunConnecting ? 8 : 0);
|
||||
|
||||
Call.debugStatusClient(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)
|
||||
public static void clientSnapshot(
|
||||
Player player,
|
||||
int snapshotID,
|
||||
int unitID,
|
||||
boolean dead,
|
||||
float x, float y,
|
||||
float pointerX, float pointerY,
|
||||
float rotation, float baseRotation,
|
||||
float xVelocity, float yVelocity,
|
||||
Tile mining,
|
||||
boolean boosting, boolean shooting, boolean chatting, boolean building,
|
||||
@Nullable Queue<BuildPlan> plans,
|
||||
float viewX, float viewY, float viewWidth, float viewHeight
|
||||
Player player,
|
||||
int snapshotID,
|
||||
int unitID,
|
||||
boolean dead,
|
||||
float x, float y,
|
||||
float pointerX, float pointerY,
|
||||
float rotation, float baseRotation,
|
||||
float xVelocity, float yVelocity,
|
||||
Tile mining,
|
||||
boolean boosting, boolean shooting, boolean chatting, boolean building,
|
||||
@Nullable Queue<BuildPlan> plans,
|
||||
float viewX, float viewY, float viewWidth, float viewHeight
|
||||
){
|
||||
NetConnection con = player.con;
|
||||
if(con == null || snapshotID < con.lastReceivedClientSnapshot) return;
|
||||
@ -660,12 +660,11 @@ public class NetServer implements ApplicationListener{
|
||||
player.shooting = shooting;
|
||||
player.boosting = boosting;
|
||||
|
||||
player.unit().controlWeapons(shooting, shooting);
|
||||
player.unit().aim(pointerX, pointerY);
|
||||
@Nullable var unit = player.unit();
|
||||
|
||||
if(player.isBuilder()){
|
||||
player.unit().clearBuilding();
|
||||
player.unit().updateBuilding(building);
|
||||
unit.clearBuilding();
|
||||
unit.updateBuilding(building);
|
||||
|
||||
if(plans != null){
|
||||
for(BuildPlan req : plans){
|
||||
@ -694,12 +693,12 @@ public class NetServer implements ApplicationListener{
|
||||
}
|
||||
}
|
||||
|
||||
player.unit().mineTile = mining;
|
||||
|
||||
con.rejectedRequests.clear();
|
||||
|
||||
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);
|
||||
float maxSpeed = unit.speed();
|
||||
@ -1125,7 +1124,7 @@ public class NetServer implements ApplicationListener{
|
||||
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.",
|
||||
player.name, target.name, votes, votesRequired()));
|
||||
player.name, target.name, votes, votesRequired()));
|
||||
|
||||
checkPass();
|
||||
}
|
||||
|
@ -35,10 +35,6 @@ abstract class EntityComp{
|
||||
return ((Object)this) instanceof Unitc u && u.isPlayer() && !isLocal();
|
||||
}
|
||||
|
||||
boolean isNull(){
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Replaced with `this` after code generation. */
|
||||
<T extends Entityc> T self(){
|
||||
return (T)this;
|
||||
|
@ -33,7 +33,7 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
|
||||
|
||||
@Import float x, y;
|
||||
|
||||
@ReadOnly Unit unit = Nulls.unit;
|
||||
@ReadOnly @Nullable Unit unit;
|
||||
transient @Nullable NetConnection con;
|
||||
@ReadOnly Team team = Team.sharded;
|
||||
@SyncLocal boolean typing, shooting, boosting;
|
||||
@ -49,12 +49,12 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
|
||||
transient float textFadeTime;
|
||||
transient Ratekeeper itemDepositRate = new Ratekeeper();
|
||||
|
||||
transient private Unit lastReadUnit = Nulls.unit;
|
||||
transient private @Nullable Unit lastReadUnit;
|
||||
transient private int wrongReadUnits;
|
||||
transient @Nullable Unit justSwitchFrom, justSwitchTo;
|
||||
|
||||
public boolean isBuilder(){
|
||||
return unit.canBuild();
|
||||
return unit != null && unit.canBuild();
|
||||
}
|
||||
|
||||
public @Nullable CoreBuild closestCore(){
|
||||
@ -89,7 +89,7 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
|
||||
x = y = 0f;
|
||||
if(!dead()){
|
||||
unit.resetController();
|
||||
unit = Nulls.unit;
|
||||
unit = null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -105,7 +105,7 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
|
||||
|
||||
@Replace
|
||||
public float clipSize(){
|
||||
return unit.isNull() ? 20 : unit.type.hitSize * 2f;
|
||||
return unit == null ? 20 : unit.type.hitSize * 2f;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -131,17 +131,18 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
|
||||
unit = lastReadUnit;
|
||||
unit(set);
|
||||
lastReadUnit = unit;
|
||||
|
||||
unit.aim(mouseX, mouseY);
|
||||
//this is only necessary when the thing being controlled isn't synced
|
||||
unit.controlWeapons(shooting, shooting);
|
||||
//extra precaution, necessary for non-synced things
|
||||
unit.controller(this);
|
||||
if(unit != null){
|
||||
unit.aim(mouseX, mouseY);
|
||||
//this is only necessary when the thing being controlled isn't synced
|
||||
unit.controlWeapons(shooting, shooting);
|
||||
//extra precaution, necessary for non-synced things
|
||||
unit.controller(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(){
|
||||
if(!unit.isValid()){
|
||||
if(unit != null && !unit.isValid()){
|
||||
clearUnit();
|
||||
}
|
||||
|
||||
@ -181,42 +182,43 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
|
||||
@Override
|
||||
public void remove(){
|
||||
//clear unit upon removal
|
||||
if(!unit.isNull()){
|
||||
if(unit != null){
|
||||
clearUnit();
|
||||
}
|
||||
|
||||
lastReadUnit = Nulls.unit;
|
||||
lastReadUnit = null;
|
||||
justSwitchTo = justSwitchFrom = null;
|
||||
}
|
||||
|
||||
public void team(Team team){
|
||||
this.team = team;
|
||||
unit.team(team);
|
||||
if(unit != null){
|
||||
unit.team(team);
|
||||
}
|
||||
}
|
||||
|
||||
public void clearUnit(){
|
||||
unit(Nulls.unit);
|
||||
unit(null);
|
||||
}
|
||||
|
||||
public Unit unit(){
|
||||
public @Nullable Unit unit(){
|
||||
return unit;
|
||||
}
|
||||
|
||||
public void unit(Unit unit){
|
||||
public void unit(@Nullable Unit unit){
|
||||
//refuse to switch when the unit was just transitioned from
|
||||
if(isLocal() && unit == justSwitchFrom && justSwitchFrom != null && justSwitchTo != null){
|
||||
return;
|
||||
}
|
||||
|
||||
if(unit == null) throw new IllegalArgumentException("Unit cannot be null. Use clearUnit() instead.");
|
||||
if(this.unit == unit) return;
|
||||
|
||||
//save last command this unit had
|
||||
if(unit.controller() instanceof CommandAI ai){
|
||||
if(unit != null && unit.controller() instanceof CommandAI ai){
|
||||
lastCommand = ai.command;
|
||||
}
|
||||
|
||||
if(this.unit != Nulls.unit){
|
||||
if(this.unit != null){
|
||||
//un-control the old unit
|
||||
this.unit.resetController();
|
||||
//restore last command issued before it was controlled
|
||||
@ -225,7 +227,7 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
|
||||
}
|
||||
}
|
||||
this.unit = unit;
|
||||
if(unit != Nulls.unit){
|
||||
if(unit != null){
|
||||
unit.team(team);
|
||||
unit.controller(this);
|
||||
|
||||
@ -244,7 +246,7 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
|
||||
}
|
||||
|
||||
boolean dead(){
|
||||
return unit.isNull() || !unit.isValid();
|
||||
return unit == null || !unit.isValid();
|
||||
}
|
||||
|
||||
String ip(){
|
||||
|
@ -116,7 +116,9 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
private WidgetGroup group = new WidgetGroup();
|
||||
|
||||
private final Eachable<BuildPlan> allPlans = cons -> {
|
||||
player.unit().plans().each(cons);
|
||||
if(!player.dead()){
|
||||
player.unit().plans().each(cons);
|
||||
}
|
||||
selectPlans.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){
|
||||
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 -> {
|
||||
event.unitIDs = unitIds;
|
||||
})){
|
||||
@ -260,7 +259,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
}
|
||||
|
||||
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;
|
||||
if(queueCommand){
|
||||
@ -282,7 +281,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
if(ai.commandQueue.size <= 0){
|
||||
ai.group = null;
|
||||
}
|
||||
|
||||
|
||||
//remove when other player command
|
||||
if(!headless && player != Vars.player){
|
||||
control.input.selectedUnits.remove(unit);
|
||||
@ -489,8 +488,6 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
|
||||
@Remote(targets = Loc.server, called = Loc.server)
|
||||
public static void pickedUnitPayload(Unit unit, Unit target){
|
||||
if(target == Nulls.unit) return;
|
||||
|
||||
if(target != null && unit instanceof Payloadc pay){
|
||||
pay.pickup(target);
|
||||
}else if(target != null){
|
||||
@ -599,7 +596,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
if(build == null) return;
|
||||
|
||||
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.");
|
||||
}
|
||||
|
||||
@ -618,7 +615,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
if(build == null) return;
|
||||
|
||||
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){
|
||||
var packet = new TileConfigCallPacket(); //undo the config on the client
|
||||
@ -697,7 +694,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
|
||||
player.unit(unit);
|
||||
|
||||
if(before != null && !before.isNull()){
|
||||
if(before != null){
|
||||
if(before.spawnedByCore){
|
||||
unit.dockedType = before.type;
|
||||
}else if(before.dockedType != null && before.dockedType.coreUnitDock){
|
||||
@ -812,7 +809,9 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
}
|
||||
|
||||
playerPlanTree.clear();
|
||||
player.unit().plans.each(playerPlanTree::insert);
|
||||
if(!player.dead()){
|
||||
player.unit().plans.each(playerPlanTree::insert);
|
||||
}
|
||||
|
||||
player.typing = ui.chatfrag.shown();
|
||||
|
||||
@ -824,7 +823,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
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());
|
||||
}
|
||||
|
||||
@ -1673,9 +1672,9 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
|
||||
boolean canMine(Tile tile){
|
||||
return !Core.scene.hasMouse()
|
||||
&& player.unit().validMine(tile)
|
||||
&& player.unit().acceptsItem(player.unit().getMineResult(tile))
|
||||
&& !((!Core.settings.getBool("doubletapmine") && tile.floor().playerUnmineable) && tile.overlay().itemDrop == null);
|
||||
&& player.unit().validMine(tile)
|
||||
&& player.unit().acceptsItem(player.unit().getMineResult(tile))
|
||||
&& !((!Core.settings.getBool("doubletapmine") && tile.floor().playerUnmineable) && tile.overlay().itemDrop == null);
|
||||
}
|
||||
|
||||
/** Returns the tile at the specified MOUSE coordinates. */
|
||||
@ -1841,7 +1840,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
|
||||
public boolean canShoot(){
|
||||
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(){
|
||||
@ -1867,7 +1866,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
ItemStack stack = player.unit().stack;
|
||||
|
||||
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){
|
||||
Call.transferInventory(player, build);
|
||||
|
@ -90,7 +90,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
void checkTargets(float x, float y){
|
||||
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;
|
||||
target = unit;
|
||||
}else{
|
||||
@ -126,18 +126,21 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
}
|
||||
}
|
||||
|
||||
for(var plan : player.unit().plans()){
|
||||
Tile other = world.tile(plan.x, plan.y);
|
||||
if(!player.dead()){
|
||||
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.setCenter(other.worldx() + plan.block.offset, other.worldy() + plan.block.offset);
|
||||
r1.setSize(plan.block.size * tilesize);
|
||||
r1.setCenter(other.worldx() + plan.block.offset, other.worldy() + plan.block.offset);
|
||||
|
||||
if(r2.overlaps(r1)){
|
||||
return true;
|
||||
if(r2.overlaps(r1)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -263,7 +266,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
}
|
||||
|
||||
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(){
|
||||
@ -277,7 +280,9 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
t.visible(this::showCancel);
|
||||
t.bottom().left();
|
||||
t.button("@cancel", Icon.cancel, () -> {
|
||||
player.unit().clearBuilding();
|
||||
if(!player.dead()){
|
||||
player.unit().clearBuilding();
|
||||
}
|
||||
selectPlans.clear();
|
||||
mode = none;
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -1037,7 +1042,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
unit.movePref(movement);
|
||||
|
||||
//update shooting if not building + not mining
|
||||
if(!player.unit().activelyBuilding() && player.unit().mineTile == null){
|
||||
if(!unit.activelyBuilding() && unit.mineTile == null){
|
||||
|
||||
//autofire targeting
|
||||
if(manualShooting){
|
||||
@ -1046,7 +1051,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
}else if(target == null){
|
||||
player.shooting = false;
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -279,7 +279,7 @@ public class TypeIO{
|
||||
}
|
||||
|
||||
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
|
||||
if(unit instanceof BlockUnitc){
|
||||
@ -295,15 +295,14 @@ public class TypeIO{
|
||||
byte type = read.b();
|
||||
int id = read.i();
|
||||
//nothing
|
||||
if(type == 0) return Nulls.unit;
|
||||
if(type == 0) return null;
|
||||
if(type == 2){ //standard unit
|
||||
Unit unit = Groups.unit.getByID(id);
|
||||
return unit == null ? Nulls.unit : unit;
|
||||
return Groups.unit.getByID(id);
|
||||
}else if(type == 1){ //block
|
||||
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){
|
||||
|
@ -1242,7 +1242,7 @@ public class LExecutor{
|
||||
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 build -> {
|
||||
Block block = extra.obj() instanceof Block b ? b : null;
|
||||
|
@ -152,7 +152,7 @@ public class BlockInventoryFragment{
|
||||
|
||||
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();
|
||||
l.enabled = canPick;
|
||||
|
@ -167,7 +167,7 @@ public class HintsFragment{
|
||||
zoom(visibleDesktop, () -> Core.input.axis(KeyCode.scroll) != 0),
|
||||
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),
|
||||
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)),
|
||||
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(),
|
||||
@ -179,8 +179,8 @@ public class HintsFragment{
|
||||
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") && !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()),
|
||||
payloadDrop(() -> !player.unit().dead && player.unit() instanceof Payloadc p && p.payloads().any(), () -> player.unit() instanceof Payloadc p && p.payloads().isEmpty()),
|
||||
payloadPickup(() -> isSerpulo() && !player.dead() && player.unit() instanceof Payloadc p && p.payloads().isEmpty(), () -> player.unit() instanceof Payloadc p && p.payloads().any()),
|
||||
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),
|
||||
generator(() -> control.input.block == Blocks.combustionGenerator, () -> ui.hints.placedBlocks.contains(Blocks.combustionGenerator)),
|
||||
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.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);
|
||||
@ -913,7 +913,7 @@ public class HudFragment{
|
||||
|
||||
table.table().update(t -> {
|
||||
t.left();
|
||||
Bits applied = player.unit().statusBits();
|
||||
Bits applied = player.unit() == null ? null : player.unit().statusBits();
|
||||
if(!statuses.equals(applied)){
|
||||
t.clear();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user