Internal refactoring & cleanup
This commit is contained in:
@@ -0,0 +1 @@
|
|||||||
|
{version:1,fields:[{name:ammo,type:float,size:4},{name:armor,type:float,size:4},{name:controller,type:mindustry.entities.units.UnitController,size:-1},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:isShooting,type:boolean,size:1},{name:mounts,type:"mindustry.entities.units.WeaponMount[]",size:-1},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:spawnedByCore,type:boolean,size:1},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{version:1,fields:[{name:ammo,type:float,size:4},{name:armor,type:float,size:4},{name:baseRotation,type:float,size:4},{name:controller,type:mindustry.entities.units.UnitController,size:-1},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:isShooting,type:boolean,size:1},{name:mineTile,type:mindustry.world.Tile,size:-1},{name:mounts,type:"mindustry.entities.units.WeaponMount[]",size:-1},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>,size:-1},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:spawnedByCore,type:boolean,size:1},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{version:1,fields:[{name:ammo,type:float,size:4},{name:armor,type:float,size:4},{name:controller,type:mindustry.entities.units.UnitController,size:-1},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:isShooting,type:boolean,size:1},{name:mounts,type:"mindustry.entities.units.WeaponMount[]",size:-1},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>,size:-1},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:spawnedByCore,type:boolean,size:1},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{version:1,fields:[{name:ammo,type:float,size:4},{name:armor,type:float,size:4},{name:controller,type:mindustry.entities.units.UnitController,size:-1},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:isShooting,type:boolean,size:1},{name:mineTile,type:mindustry.world.Tile,size:-1},{name:mounts,type:"mindustry.entities.units.WeaponMount[]",size:-1},{name:payloads,type:arc.struct.Seq<mindustry.world.blocks.payloads.Payload>,size:-1},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>,size:-1},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:spawnedByCore,type:boolean,size:1},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{version:1,fields:[{name:ammo,type:float,size:4},{name:armor,type:float,size:4},{name:controller,type:mindustry.entities.units.UnitController,size:-1},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:isShooting,type:boolean,size:1},{name:mineTile,type:mindustry.world.Tile,size:-1},{name:mounts,type:"mindustry.entities.units.WeaponMount[]",size:-1},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>,size:-1},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:spawnedByCore,type:boolean,size:1},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{version:1,fields:[{name:ammo,type:float,size:4},{name:armor,type:float,size:4},{name:controller,type:mindustry.entities.units.UnitController,size:-1},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:isShooting,type:boolean,size:1},{name:mounts,type:"mindustry.entities.units.WeaponMount[]",size:-1},{name:payloads,type:arc.struct.Seq<mindustry.world.blocks.payloads.Payload>,size:-1},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>,size:-1},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:spawnedByCore,type:boolean,size:1},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{version:1,fields:[{name:ammo,type:float,size:4},{name:armor,type:float,size:4},{name:controller,type:mindustry.entities.units.UnitController,size:-1},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:isShooting,type:boolean,size:1},{name:mounts,type:"mindustry.entities.units.WeaponMount[]",size:-1},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:spawnedByCore,type:boolean,size:1},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{version:1,fields:[{name:ammo,type:float,size:4},{name:armor,type:float,size:4},{name:baseRotation,type:float,size:4},{name:controller,type:mindustry.entities.units.UnitController,size:-1},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:isShooting,type:boolean,size:1},{name:mounts,type:"mindustry.entities.units.WeaponMount[]",size:-1},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:spawnedByCore,type:boolean,size:1},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{version:1,fields:[{name:ammo,type:float,size:4},{name:armor,type:float,size:4},{name:controller,type:mindustry.entities.units.UnitController,size:-1},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:isShooting,type:boolean,size:1},{name:mounts,type:"mindustry.entities.units.WeaponMount[]",size:-1},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:spawnedByCore,type:boolean,size:1},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||||
1
annotations/src/main/resources/revisions/LegsUnit/1.json
Normal file
1
annotations/src/main/resources/revisions/LegsUnit/1.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{version:1,fields:[{name:ammo,type:float,size:4},{name:armor,type:float,size:4},{name:controller,type:mindustry.entities.units.UnitController,size:-1},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:isShooting,type:boolean,size:1},{name:mounts,type:"mindustry.entities.units.WeaponMount[]",size:-1},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:spawnedByCore,type:boolean,size:1},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||||
1
annotations/src/main/resources/revisions/MechUnit/1.json
Normal file
1
annotations/src/main/resources/revisions/MechUnit/1.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{version:1,fields:[{name:ammo,type:float,size:4},{name:armor,type:float,size:4},{name:baseRotation,type:float,size:4},{name:controller,type:mindustry.entities.units.UnitController,size:-1},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:isShooting,type:boolean,size:1},{name:mounts,type:"mindustry.entities.units.WeaponMount[]",size:-1},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:spawnedByCore,type:boolean,size:1},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{version:1,fields:[{name:ammo,type:float,size:4},{name:armor,type:float,size:4},{name:controller,type:mindustry.entities.units.UnitController,size:-1},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:isShooting,type:boolean,size:1},{name:mineTile,type:mindustry.world.Tile,size:-1},{name:mounts,type:"mindustry.entities.units.WeaponMount[]",size:-1},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:spawnedByCore,type:boolean,size:1},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{version:1,fields:[{name:ammo,type:float,size:4},{name:armor,type:float,size:4},{name:controller,type:mindustry.entities.units.UnitController,size:-1},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:isShooting,type:boolean,size:1},{name:mounts,type:"mindustry.entities.units.WeaponMount[]",size:-1},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:spawnedByCore,type:boolean,size:1},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||||
@@ -932,6 +932,8 @@ unit.beta.name = Beta
|
|||||||
unit.gamma.name = Gamma
|
unit.gamma.name = Gamma
|
||||||
unit.scepter.name = Scepter
|
unit.scepter.name = Scepter
|
||||||
unit.reign.name = Reign
|
unit.reign.name = Reign
|
||||||
|
unit.vela.name = Vela
|
||||||
|
unit.corvus.name = Corvus
|
||||||
|
|
||||||
block.resupply-point.name = Resupply Point
|
block.resupply-point.name = Resupply Point
|
||||||
block.parallax.name = Parallax
|
block.parallax.name = Parallax
|
||||||
|
|||||||
@@ -74,15 +74,12 @@ public class GroundAI extends AIController{
|
|||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void moveTo(int pathType){
|
protected void moveTo(int pathTarget){
|
||||||
int costType =
|
int costType = unit.pathType();
|
||||||
unit instanceof Legsc ? Pathfinder.costLegs :
|
|
||||||
unit instanceof WaterMovec ? Pathfinder.costWater :
|
|
||||||
Pathfinder.costGround;
|
|
||||||
|
|
||||||
Tile tile = unit.tileOn();
|
Tile tile = unit.tileOn();
|
||||||
if(tile == null) return;
|
if(tile == null) return;
|
||||||
Tile targetTile = pathfinder.getTargetTile(tile, pathfinder.getField(unit.team, costType, pathType));
|
Tile targetTile = pathfinder.getTargetTile(tile, pathfinder.getField(unit.team, costType, pathTarget));
|
||||||
|
|
||||||
if(tile == targetTile || (costType == Pathfinder.costWater && !targetTile.floor().isLiquid)) return;
|
if(tile == targetTile || (costType == Pathfinder.costWater && !targetTile.floor().isLiquid)) return;
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ public class TeamIndexProcess implements AsyncProcess{
|
|||||||
private QuadTree<Unit>[] trees = new QuadTree[Team.all.length];
|
private QuadTree<Unit>[] trees = new QuadTree[Team.all.length];
|
||||||
private int[] counts = new int[Team.all.length];
|
private int[] counts = new int[Team.all.length];
|
||||||
private int[][] typeCounts = new int[Team.all.length][0];
|
private int[][] typeCounts = new int[Team.all.length][0];
|
||||||
private int[][] activeCounts = new int[Team.all.length][0];
|
|
||||||
|
|
||||||
public QuadTree<Unit> tree(Team team){
|
public QuadTree<Unit> tree(Team team){
|
||||||
if(trees[team.id] == null) trees[team.id] = new QuadTree<>(Vars.world.getQuadBounds(new Rect()));
|
if(trees[team.id] == null) trees[team.id] = new QuadTree<>(Vars.world.getQuadBounds(new Rect()));
|
||||||
@@ -30,10 +29,6 @@ public class TeamIndexProcess implements AsyncProcess{
|
|||||||
return typeCounts[team.id].length <= type.id ? 0 : typeCounts[team.id][type.id];
|
return typeCounts[team.id].length <= type.id ? 0 : typeCounts[team.id][type.id];
|
||||||
}
|
}
|
||||||
|
|
||||||
public int countActive(Team team, UnitType type){
|
|
||||||
return activeCounts[team.id].length <= type.id ? 0 : activeCounts[team.id][type.id];
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateCount(Team team, UnitType type, int amount){
|
public void updateCount(Team team, UnitType type, int amount){
|
||||||
counts[team.id] += amount;
|
counts[team.id] += amount;
|
||||||
if(typeCounts[team.id].length <= type.id){
|
if(typeCounts[team.id].length <= type.id){
|
||||||
@@ -42,16 +37,8 @@ public class TeamIndexProcess implements AsyncProcess{
|
|||||||
typeCounts[team.id][type.id] += amount;
|
typeCounts[team.id][type.id] += amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateActiveCount(Team team, UnitType type, int amount){
|
|
||||||
if(activeCounts[team.id].length <= type.id){
|
|
||||||
activeCounts[team.id] = new int[Vars.content.units().size];
|
|
||||||
}
|
|
||||||
activeCounts[team.id][type.id] += amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void count(Unit unit){
|
private void count(Unit unit){
|
||||||
updateCount(unit.team, unit.type(), 1);
|
updateCount(unit.team, unit.type(), 1);
|
||||||
if(!unit.deactivated) updateActiveCount(unit.team, unit.type(), 1);
|
|
||||||
|
|
||||||
if(unit instanceof Payloadc){
|
if(unit instanceof Payloadc){
|
||||||
((Payloadc)unit).payloads().each(p -> {
|
((Payloadc)unit).payloads().each(p -> {
|
||||||
@@ -77,7 +64,6 @@ public class TeamIndexProcess implements AsyncProcess{
|
|||||||
}
|
}
|
||||||
|
|
||||||
Arrays.fill(typeCounts[team.id], 0);
|
Arrays.fill(typeCounts[team.id], 0);
|
||||||
Arrays.fill(activeCounts[team.id], 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Arrays.fill(counts, 0);
|
Arrays.fill(counts, 0);
|
||||||
|
|||||||
@@ -1306,7 +1306,6 @@ public class UnitTypes implements ContentList{
|
|||||||
health = 280;
|
health = 280;
|
||||||
accel = 0.4f;
|
accel = 0.4f;
|
||||||
rotateSpeed = 3.3f;
|
rotateSpeed = 3.3f;
|
||||||
immunities = ObjectSet.with(StatusEffects.wet);
|
|
||||||
trailLength = 20;
|
trailLength = 20;
|
||||||
rotateShooting = false;
|
rotateShooting = false;
|
||||||
|
|
||||||
@@ -1358,7 +1357,6 @@ public class UnitTypes implements ContentList{
|
|||||||
armor = 4f;
|
armor = 4f;
|
||||||
accel = 0.3f;
|
accel = 0.3f;
|
||||||
rotateSpeed = 2.6f;
|
rotateSpeed = 2.6f;
|
||||||
immunities = ObjectSet.with(StatusEffects.wet);
|
|
||||||
rotateShooting = false;
|
rotateShooting = false;
|
||||||
|
|
||||||
trailLength = 20;
|
trailLength = 20;
|
||||||
@@ -1400,7 +1398,6 @@ public class UnitTypes implements ContentList{
|
|||||||
drag = 0.17f;
|
drag = 0.17f;
|
||||||
hitsize = 16f;
|
hitsize = 16f;
|
||||||
armor = 7f;
|
armor = 7f;
|
||||||
immunities = ObjectSet.with(StatusEffects.wet);
|
|
||||||
rotateShooting = false;
|
rotateShooting = false;
|
||||||
|
|
||||||
trailLength = 22;
|
trailLength = 22;
|
||||||
@@ -1495,7 +1492,6 @@ public class UnitTypes implements ContentList{
|
|||||||
hitsize = 39f;
|
hitsize = 39f;
|
||||||
accel = 0.2f;
|
accel = 0.2f;
|
||||||
rotateSpeed = 1.3f;
|
rotateSpeed = 1.3f;
|
||||||
immunities = ObjectSet.with(StatusEffects.wet);
|
|
||||||
rotateShooting = false;
|
rotateShooting = false;
|
||||||
|
|
||||||
trailLength = 50;
|
trailLength = 50;
|
||||||
@@ -1580,10 +1576,9 @@ public class UnitTypes implements ContentList{
|
|||||||
armor = 16f;
|
armor = 16f;
|
||||||
accel = 0.19f;
|
accel = 0.19f;
|
||||||
rotateSpeed = 0.9f;
|
rotateSpeed = 0.9f;
|
||||||
immunities = ObjectSet.with(StatusEffects.wet);
|
|
||||||
rotateShooting = false;
|
rotateShooting = false;
|
||||||
|
|
||||||
float spawnTime = 60f * 25f;
|
float spawnTime = 60f * 15f;
|
||||||
|
|
||||||
abilities.add(new UnitSpawnAbility(flare, spawnTime, 19.25f, -31.75f), new UnitSpawnAbility(flare, spawnTime, -19.25f, -31.75f));
|
abilities.add(new UnitSpawnAbility(flare, spawnTime, 19.25f, -31.75f), new UnitSpawnAbility(flare, spawnTime, -19.25f, -31.75f));
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ public class Units{
|
|||||||
if(unit != null){
|
if(unit != null){
|
||||||
unit.dead = true;
|
unit.dead = true;
|
||||||
Fx.unitCapKill.at(unit);
|
Fx.unitCapKill.at(unit);
|
||||||
Core.app.post(() -> Call.unitDeath(unit.id));
|
Core.app.post(() -> Call.unitDestroy(unit.id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,6 +42,21 @@ public class Units{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//destroys immediately
|
||||||
|
@Remote(called = Loc.server)
|
||||||
|
public static void unitDestroy(int uid){
|
||||||
|
Unit unit = Groups.unit.getByID(uid);
|
||||||
|
|
||||||
|
//if there's no unit don't add it later and get it stuck as a ghost
|
||||||
|
if(netClient != null){
|
||||||
|
netClient.addRemovedEntity(uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(unit != null){
|
||||||
|
unit.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Remote(called = Loc.server)
|
@Remote(called = Loc.server)
|
||||||
public static void unitDespawn(Unit unit){
|
public static void unitDespawn(Unit unit){
|
||||||
Fx.unitDespawn.at(unit.x, unit.y, 0, unit);
|
Fx.unitDespawn.at(unit.x, unit.y, 0, unit);
|
||||||
|
|||||||
@@ -4,6 +4,12 @@ import mindustry.content.*;
|
|||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
|
|
||||||
|
//TODO this class is bad for multiple reasons, remove/replace it.
|
||||||
|
//- effects unreliable
|
||||||
|
//- not really hitscan but works like it
|
||||||
|
//- buggy trails
|
||||||
|
//- looks bad
|
||||||
|
//- generally unreliable
|
||||||
public class RailBulletType extends BulletType{
|
public class RailBulletType extends BulletType{
|
||||||
public Effect pierceEffect = Fx.hitBulletSmall, updateEffect = Fx.none;
|
public Effect pierceEffect = Fx.hitBulletSmall, updateEffect = Fx.none;
|
||||||
/** Multiplier of damage decreased per health pierced. */
|
/** Multiplier of damage decreased per health pierced. */
|
||||||
|
|||||||
@@ -1,23 +1,18 @@
|
|||||||
package mindustry.entities.comp;
|
package mindustry.entities.comp;
|
||||||
|
|
||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
|
import mindustry.entities.*;
|
||||||
|
import mindustry.entities.EntityCollisions.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
abstract class ElevationMoveComp implements Velc, Posc, Flyingc, Hitboxc{
|
abstract class ElevationMoveComp implements Velc, Posc, Flyingc, Hitboxc{
|
||||||
@Import float x, y;
|
@Import float x, y;
|
||||||
|
|
||||||
@Replace
|
@Replace
|
||||||
@Override
|
@Override
|
||||||
public void move(float cx, float cy){
|
public SolidPred solidity(){
|
||||||
if(isFlying()){
|
return isFlying() ? null : EntityCollisions::solid;
|
||||||
x += cx;
|
|
||||||
y += cy;
|
|
||||||
}else{
|
|
||||||
collisions.move(this, cx, cy);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,16 +4,16 @@ import arc.math.*;
|
|||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.*;
|
import mindustry.*;
|
||||||
|
import mindustry.ai.*;
|
||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
|
import mindustry.entities.EntityCollisions.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
import mindustry.world.blocks.environment.*;
|
import mindustry.world.blocks.environment.*;
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
abstract class LegsComp implements Posc, Rotc, Hitboxc, Flyingc, Unitc{
|
abstract class LegsComp implements Posc, Rotc, Hitboxc, Flyingc, Unitc{
|
||||||
@Import float x, y;
|
@Import float x, y;
|
||||||
@@ -26,8 +26,14 @@ abstract class LegsComp implements Posc, Rotc, Hitboxc, Flyingc, Unitc{
|
|||||||
|
|
||||||
@Replace
|
@Replace
|
||||||
@Override
|
@Override
|
||||||
public void move(float cx, float cy){
|
public SolidPred solidity(){
|
||||||
collisions.moveCheck(this, cx, cy, !type.allowLegStep ? EntityCollisions::solid : EntityCollisions::legsSolid);
|
return !type.allowLegStep ? EntityCollisions::solid : EntityCollisions::legsSolid;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Replace
|
||||||
|
public int pathType(){
|
||||||
|
return Pathfinder.costLegs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package mindustry.entities.comp;
|
package mindustry.entities.comp;
|
||||||
|
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
|
import arc.math.geom.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
@@ -9,11 +10,23 @@ import mindustry.gen.*;
|
|||||||
abstract class MechComp implements Posc, Flyingc, Hitboxc, Unitc, Mechc, ElevationMovec{
|
abstract class MechComp implements Posc, Flyingc, Hitboxc, Unitc, Mechc, ElevationMovec{
|
||||||
@SyncField(false) @SyncLocal float baseRotation;
|
@SyncField(false) @SyncLocal float baseRotation;
|
||||||
transient float walkTime, walkExtension;
|
transient float walkTime, walkExtension;
|
||||||
|
transient private boolean walked;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(){
|
public void update(){
|
||||||
float len = deltaLen();
|
//trigger animation only when walking manually
|
||||||
baseRotation = Angles.moveToward(baseRotation, deltaAngle(), type().baseRotateSpeed * Mathf.clamp(len / type().speed / Time.delta) * Time.delta);
|
if(walked){
|
||||||
walkTime += len;
|
float len = deltaLen();
|
||||||
|
baseRotation = Angles.moveToward(baseRotation, deltaAngle(), type().baseRotateSpeed * Mathf.clamp(len / type().speed / Time.delta) * Time.delta);
|
||||||
|
walkTime += len;
|
||||||
|
walked = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void moveAt(Vec2 vector, float acceleration){
|
||||||
|
if(!vector.isZero()){
|
||||||
|
walked = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,11 +98,7 @@ abstract class PayloadComp implements Posc, Rotc, Hitboxc, Unitc{
|
|||||||
Unit u = payload.unit;
|
Unit u = payload.unit;
|
||||||
|
|
||||||
//can't drop ground units
|
//can't drop ground units
|
||||||
//TODO bad code, solidity should not be handled this way
|
if(!u.canPassOn()){
|
||||||
if(
|
|
||||||
((tileOn() == null || tileOn().solid()) && u.elevation < 0.1f && !u.type().allowLegStep) ||
|
|
||||||
(!floorOn().isLiquid && u instanceof WaterMovec) ||
|
|
||||||
(u.type().allowLegStep && EntityCollisions.legsSolid(u.tileX(), u.tileY()))){
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import arc.scene.ui.layout.*;
|
|||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.ArcAnnotate.*;
|
import arc.util.ArcAnnotate.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
|
import mindustry.ai.*;
|
||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.ctype.*;
|
import mindustry.ctype.*;
|
||||||
@@ -37,7 +38,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
|||||||
|
|
||||||
private UnitController controller;
|
private UnitController controller;
|
||||||
private UnitType type;
|
private UnitType type;
|
||||||
boolean spawnedByCore, deactivated; //TODO remove deactivation boolean
|
boolean spawnedByCore;
|
||||||
|
|
||||||
transient Seq<Ability> abilities = new Seq<>(0);
|
transient Seq<Ability> abilities = new Seq<>(0);
|
||||||
|
|
||||||
@@ -103,7 +104,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
|||||||
@Override
|
@Override
|
||||||
@Replace
|
@Replace
|
||||||
public boolean canDrown(){
|
public boolean canDrown(){
|
||||||
return isGrounded() && !hovering && type.canDrown && !(this instanceof WaterMovec);
|
return isGrounded() && !hovering && type.canDrown;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -149,6 +150,11 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return pathfinder path type for calculating costs */
|
||||||
|
public int pathType(){
|
||||||
|
return Pathfinder.costGround;
|
||||||
|
}
|
||||||
|
|
||||||
public void lookAt(float angle){
|
public void lookAt(float angle){
|
||||||
rotation = Angles.moveToward(rotation, angle, type.rotateSpeed * Time.delta * speedMultiplier());
|
rotation = Angles.moveToward(rotation, angle, type.rotateSpeed * Time.delta * speedMultiplier());
|
||||||
}
|
}
|
||||||
@@ -206,12 +212,9 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
|||||||
public void add(){
|
public void add(){
|
||||||
|
|
||||||
//check if over unit cap
|
//check if over unit cap
|
||||||
if(count() > cap() && !spawnedByCore){
|
if(count() > cap() && !spawnedByCore && !dead){
|
||||||
deactivated = true;
|
Call.unitCapDeath(self());
|
||||||
|
teamIndex.updateCount(team, type, -1);
|
||||||
if(!dead){
|
|
||||||
Call.unitCapDeath(self());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,22 +235,13 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(){
|
public void update(){
|
||||||
//activate the unit when possible
|
|
||||||
if(!net.client() && deactivated && teamIndex.countActive(team, type) < Units.getCap(team)){
|
|
||||||
teamIndex.updateActiveCount(team, type, 1);
|
|
||||||
deactivated = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!deactivated){
|
type.update(self());
|
||||||
type.update(self());
|
|
||||||
|
|
||||||
if(abilities.size > 0){
|
if(abilities.size > 0){
|
||||||
for(Ability a : abilities){
|
for(Ability a : abilities){
|
||||||
a.update(self());
|
a.update(self());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}else if(!dead){
|
|
||||||
Call.unitCapDeath(self());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
drag = type.drag * (isGrounded() ? (floorOn().dragMultiplier) : 1f);
|
drag = type.drag * (isGrounded() ? (floorOn().dragMultiplier) : 1f);
|
||||||
@@ -305,18 +299,20 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
|||||||
if(floor.damageTaken > 0f){
|
if(floor.damageTaken > 0f){
|
||||||
damageContinuous(floor.damageTaken);
|
damageContinuous(floor.damageTaken);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(tile.solid()){
|
//kill entities on tiles that are solid to them
|
||||||
if(type.canBoost){
|
if(tile != null && !canPassOn()){
|
||||||
elevation = 1f;
|
//boost if possible
|
||||||
}else if(!net.client()){
|
if(type.canBoost){
|
||||||
kill();
|
elevation = 1f;
|
||||||
}
|
}else if(!net.client()){
|
||||||
|
kill();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//AI only updates on the server
|
//AI only updates on the server
|
||||||
if(!net.client() && !dead && !deactivated){
|
if(!net.client() && !dead){
|
||||||
controller.updateUnit();
|
controller.updateUnit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -325,11 +321,6 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
|||||||
resetController();
|
resetController();
|
||||||
}
|
}
|
||||||
|
|
||||||
//do not control anything when deactivated
|
|
||||||
if(deactivated){
|
|
||||||
controlWeapons(false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
//remove units spawned by the core
|
//remove units spawned by the core
|
||||||
if(spawnedByCore && !isPlayer()){
|
if(spawnedByCore && !isPlayer()){
|
||||||
Call.unitDespawn(self());
|
Call.unitDespawn(self());
|
||||||
|
|||||||
@@ -3,9 +3,13 @@ package mindustry.entities.comp;
|
|||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
|
import arc.util.ArcAnnotate.*;
|
||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
|
import mindustry.entities.EntityCollisions.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
|
|
||||||
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
abstract class VelComp implements Posc{
|
abstract class VelComp implements Posc{
|
||||||
@Import float x, y;
|
@Import float x, y;
|
||||||
@@ -22,12 +26,35 @@ abstract class VelComp implements Posc{
|
|||||||
vel.scl(Mathf.clamp(1f - drag * Time.delta));
|
vel.scl(Mathf.clamp(1f - drag * Time.delta));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return function to use for check solid state. if null, no checking is done. */
|
||||||
|
@Nullable
|
||||||
|
SolidPred solidity(){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return whether this entity can move through a location*/
|
||||||
|
boolean canPass(int tileX, int tileY){
|
||||||
|
SolidPred s = solidity();
|
||||||
|
return s == null || !s.solid(tileX, tileY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return whether this entity can exist on its current location*/
|
||||||
|
boolean canPassOn(){
|
||||||
|
return canPass(tileX(), tileY());
|
||||||
|
}
|
||||||
|
|
||||||
boolean moving(){
|
boolean moving(){
|
||||||
return !vel.isZero(0.01f);
|
return !vel.isZero(0.01f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void move(float cx, float cy){
|
void move(float cx, float cy){
|
||||||
x += cx;
|
SolidPred check = solidity();
|
||||||
y += cy;
|
|
||||||
|
if(check != null){
|
||||||
|
collisions.move(self(), cx, cy, check);
|
||||||
|
}else{
|
||||||
|
x += cx;
|
||||||
|
y += cy;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,17 +4,17 @@ import arc.graphics.*;
|
|||||||
import arc.graphics.g2d.*;
|
import arc.graphics.g2d.*;
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
|
import mindustry.ai.*;
|
||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
|
import mindustry.entities.EntityCollisions.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
import mindustry.world.blocks.environment.*;
|
import mindustry.world.blocks.environment.*;
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
|
||||||
|
|
||||||
//just a proof of concept
|
//just a proof of concept
|
||||||
@Component
|
@Component
|
||||||
abstract class WaterMoveComp implements Posc, Velc, Hitboxc, Flyingc, Unitc{
|
abstract class WaterMoveComp implements Posc, Velc, Hitboxc, Flyingc, Unitc{
|
||||||
@@ -38,16 +38,8 @@ abstract class WaterMoveComp implements Posc, Velc, Hitboxc, Flyingc, Unitc{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Replace
|
@Replace
|
||||||
public void lookAt(float angle){
|
public int pathType(){
|
||||||
if(onLiquid()){
|
return Pathfinder.costWater;
|
||||||
rotation = Angles.moveToward(rotation, angle, type.rotateSpeed * Time.delta);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Replace
|
|
||||||
public boolean canShoot(){
|
|
||||||
return onLiquid();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -74,13 +66,8 @@ abstract class WaterMoveComp implements Posc, Velc, Hitboxc, Flyingc, Unitc{
|
|||||||
|
|
||||||
@Replace
|
@Replace
|
||||||
@Override
|
@Override
|
||||||
public void move(float cx, float cy){
|
public SolidPred solidity(){
|
||||||
if(isGrounded()){
|
return isFlying() ? null : EntityCollisions::waterSolid;
|
||||||
collisions.moveCheck(this, cx, cy, EntityCollisions::waterSolid);
|
|
||||||
}else{
|
|
||||||
x += cx;
|
|
||||||
y += cy;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Replace
|
@Replace
|
||||||
|
|||||||
@@ -596,7 +596,7 @@ public class DesktopInput extends InputHandler{
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void updateMovement(Unit unit){
|
protected void updateMovement(Unit unit){
|
||||||
boolean omni = !(unit instanceof WaterMovec);
|
boolean omni = unit.type().omniMovement;
|
||||||
boolean ground = unit.isGrounded();
|
boolean ground = unit.isGrounded();
|
||||||
|
|
||||||
float strafePenalty = ground ? 1f : Mathf.lerp(1f, unit.type().strafePenalty, Angles.angleDist(unit.vel().angle(), unit.rotation()) / 180f);
|
float strafePenalty = ground ? 1f : Mathf.lerp(1f, unit.type().strafePenalty, Angles.angleDist(unit.vel().angle(), unit.rotation()) / 180f);
|
||||||
|
|||||||
@@ -292,7 +292,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
}else if(unit == null){ //just clear the unit (is this used?)
|
}else if(unit == null){ //just clear the unit (is this used?)
|
||||||
player.clearUnit();
|
player.clearUnit();
|
||||||
//make sure it's AI controlled, so players can't overwrite each other
|
//make sure it's AI controlled, so players can't overwrite each other
|
||||||
}else if(unit.isAI() && unit.team == player.team() && !unit.deactivated() && !unit.dead){
|
}else if(unit.isAI() && unit.team == player.team() && !unit.dead){
|
||||||
if(!net.client()){
|
if(!net.client()){
|
||||||
player.unit(unit);
|
player.unit(unit);
|
||||||
}
|
}
|
||||||
@@ -365,7 +365,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(controlledType != null && player.dead()){
|
if(controlledType != null && player.dead()){
|
||||||
Unit unit = Units.closest(player.team(), player.x, player.y, u -> !u.isPlayer() && u.type() == controlledType && !u.deactivated() && !u.dead);
|
Unit unit = Units.closest(player.team(), player.x, player.y, u -> !u.isPlayer() && u.type() == controlledType && !u.dead);
|
||||||
|
|
||||||
if(unit != null){
|
if(unit != null){
|
||||||
Call.unitControl(player, unit);
|
Call.unitControl(player, unit);
|
||||||
@@ -375,7 +375,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
|
|
||||||
public void checkUnit(){
|
public void checkUnit(){
|
||||||
if(controlledType != null){
|
if(controlledType != null){
|
||||||
Unit unit = Units.closest(player.team(), player.x, player.y, u -> !u.isPlayer() && u.type() == controlledType && !u.deactivated() && !u.dead);
|
Unit unit = Units.closest(player.team(), player.x, player.y, u -> !u.isPlayer() && u.type() == controlledType && !u.dead);
|
||||||
if(unit == null && controlledType == UnitTypes.block){
|
if(unit == null && controlledType == UnitTypes.block){
|
||||||
unit = world.buildWorld(player.x, player.y) instanceof ControlBlock ? ((ControlBlock)world.buildWorld(player.x, player.y)).unit() : null;
|
unit = world.buildWorld(player.x, player.y) instanceof ControlBlock ? ((ControlBlock)world.buildWorld(player.x, player.y)).unit() : null;
|
||||||
}
|
}
|
||||||
@@ -931,7 +931,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable Unit selectedUnit(){
|
public @Nullable Unit selectedUnit(){
|
||||||
Unit unit = Units.closest(player.team(), Core.input.mouseWorld().x, Core.input.mouseWorld().y, 40f, u -> u.isAI() && !u.deactivated());
|
Unit unit = Units.closest(player.team(), Core.input.mouseWorld().x, Core.input.mouseWorld().y, 40f, u -> u.isAI());
|
||||||
if(unit != null){
|
if(unit != null){
|
||||||
unit.hitbox(Tmp.r1);
|
unit.hitbox(Tmp.r1);
|
||||||
Tmp.r1.grow(6f);
|
Tmp.r1.grow(6f);
|
||||||
|
|||||||
@@ -804,7 +804,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
if(type == null) return;
|
if(type == null) return;
|
||||||
|
|
||||||
boolean flying = type.flying;
|
boolean flying = type.flying;
|
||||||
boolean omni = !(unit instanceof WaterMovec);
|
boolean omni = unit.type().omniMovement;
|
||||||
boolean legs = unit.isGrounded();
|
boolean legs = unit.isGrounded();
|
||||||
boolean allowHealing = type.canHeal;
|
boolean allowHealing = type.canHeal;
|
||||||
boolean validHealTarget = allowHealing && target instanceof Building && ((Building)target).isValid() && target.team() == unit.team &&
|
boolean validHealTarget = allowHealing && target instanceof Building && ((Building)target).isValid() && target.team() == unit.team &&
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ public class UnitType extends UnlockableContent{
|
|||||||
public float visualElevation = -1f;
|
public float visualElevation = -1f;
|
||||||
public boolean allowLegStep = false;
|
public boolean allowLegStep = false;
|
||||||
public boolean hovering = false;
|
public boolean hovering = false;
|
||||||
|
public boolean omniMovement = true;
|
||||||
public Effect fallEffect = Fx.fallSmoke;
|
public Effect fallEffect = Fx.fallSmoke;
|
||||||
public Effect fallThrusterEffect = Fx.fallSmoke;
|
public Effect fallThrusterEffect = Fx.fallSmoke;
|
||||||
public Seq<Ability> abilities = new Seq<>();
|
public Seq<Ability> abilities = new Seq<>();
|
||||||
@@ -195,13 +196,6 @@ public class UnitType extends UnlockableContent{
|
|||||||
}).growX();
|
}).growX();
|
||||||
|
|
||||||
table.row();
|
table.row();
|
||||||
if(unit.deactivated){
|
|
||||||
table.table(d -> {
|
|
||||||
d.left();
|
|
||||||
d.label(() -> Core.bundle.format("bar.limitreached", unit.count(), unit.cap(), Fonts.getUnicodeStr(name)));
|
|
||||||
}).left().visible(() -> unit.deactivated);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -231,6 +225,15 @@ public class UnitType extends UnlockableContent{
|
|||||||
public void init(){
|
public void init(){
|
||||||
if(constructor == null) throw new IllegalArgumentException("no constructor set up for unit '" + name + "'");
|
if(constructor == null) throw new IllegalArgumentException("no constructor set up for unit '" + name + "'");
|
||||||
|
|
||||||
|
Unit example = constructor.get();
|
||||||
|
|
||||||
|
//water preset
|
||||||
|
if(example instanceof WaterMovec){
|
||||||
|
canDrown = false;
|
||||||
|
omniMovement = false;
|
||||||
|
immunities.add(StatusEffects.wet);
|
||||||
|
}
|
||||||
|
|
||||||
singleTarget = weapons.size <= 1;
|
singleTarget = weapons.size <= 1;
|
||||||
|
|
||||||
if(itemCapacity < 0){
|
if(itemCapacity < 0){
|
||||||
@@ -397,10 +400,6 @@ public class UnitType extends UnlockableContent{
|
|||||||
unit.trns(-legOffset.x, -legOffset.y);
|
unit.trns(-legOffset.x, -legOffset.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(unit.deactivated){
|
|
||||||
drawDeactive(unit);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(unit.abilities.size > 0){
|
if(unit.abilities.size > 0){
|
||||||
for(Ability a : unit.abilities){
|
for(Ability a : unit.abilities){
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
@@ -411,16 +410,6 @@ public class UnitType extends UnlockableContent{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void drawDeactive(Unit unit){
|
|
||||||
Draw.color(Color.scarlet);
|
|
||||||
Draw.alpha(0.8f);
|
|
||||||
|
|
||||||
float size = 8f;
|
|
||||||
Draw.rect(Icon.warning.getRegion(), unit.x, unit.y, size, size);
|
|
||||||
|
|
||||||
Draw.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T extends Unit & Payloadc> void drawPayload(T unit){
|
public <T extends Unit & Payloadc> void drawPayload(T unit){
|
||||||
if(unit.hasPayload()){
|
if(unit.hasPayload()){
|
||||||
Payload pay = unit.payloads().first();
|
Payload pay = unit.payloads().first();
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import mindustry.world.blocks.production.*;
|
|||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
public class PayloadConveyor extends Block{
|
public class PayloadConveyor extends Block{
|
||||||
public float moveTime = 50f;
|
public float moveTime = 40f, moveForce = 201f;
|
||||||
public @Load("@-top") TextureRegion topRegion;
|
public @Load("@-top") TextureRegion topRegion;
|
||||||
public @Load("@-edge") TextureRegion edgeRegion;
|
public @Load("@-edge") TextureRegion edgeRegion;
|
||||||
public Interp interp = Interp.pow5;
|
public Interp interp = Interp.pow5;
|
||||||
@@ -53,6 +53,7 @@ public class PayloadConveyor extends Block{
|
|||||||
public class PayloadConveyorBuild extends Building{
|
public class PayloadConveyorBuild extends Building{
|
||||||
public @Nullable Payload item;
|
public @Nullable Payload item;
|
||||||
public float progress, itemRotation, animation;
|
public float progress, itemRotation, animation;
|
||||||
|
public float curInterp, lastInterp;
|
||||||
public @Nullable Building next;
|
public @Nullable Building next;
|
||||||
public boolean blocked;
|
public boolean blocked;
|
||||||
public int step = -1, stepAccepted = -1;
|
public int step = -1, stepAccepted = -1;
|
||||||
@@ -99,6 +100,10 @@ public class PayloadConveyor extends Block{
|
|||||||
public void updateTile(){
|
public void updateTile(){
|
||||||
if(!enabled) return;
|
if(!enabled) return;
|
||||||
|
|
||||||
|
lastInterp = curInterp;
|
||||||
|
curInterp = fract();
|
||||||
|
//rollover skip
|
||||||
|
if(lastInterp > curInterp) lastInterp = 0f;
|
||||||
progress = time() % moveTime;
|
progress = time() % moveTime;
|
||||||
|
|
||||||
updatePayload();
|
updatePayload();
|
||||||
@@ -201,6 +206,14 @@ public class PayloadConveyor extends Block{
|
|||||||
return Time.time();
|
return Time.time();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unitOn(Unit unit){
|
||||||
|
//calculate derivative of units moved last frame
|
||||||
|
float delta = (curInterp - lastInterp) * size * tilesize;
|
||||||
|
Tmp.v1.trns(rotdeg(), delta * moveForce).scl(1f / Math.max(unit.mass(), 201f));
|
||||||
|
unit.move(Tmp.v1.x, Tmp.v1.y);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean acceptPayload(Building source, Payload payload){
|
public boolean acceptPayload(Building source, Payload payload){
|
||||||
if(source == this){
|
if(source == this){
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import arc.util.*;
|
|||||||
import arc.util.io.*;
|
import arc.util.io.*;
|
||||||
import mindustry.*;
|
import mindustry.*;
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
|
import mindustry.entities.EntityCollisions.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
import mindustry.ui.*;
|
import mindustry.ui.*;
|
||||||
@@ -47,15 +48,16 @@ public class UnitPayload implements Payload{
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//naval units need water.
|
//check if unit can be dumped here
|
||||||
if(unit instanceof WaterMovec){
|
SolidPred solid = unit.solidity();
|
||||||
|
if(solid != null){
|
||||||
int tx = unit.tileX(), ty = unit.tileY();
|
int tx = unit.tileX(), ty = unit.tileY();
|
||||||
boolean nearEmpty = !EntityCollisions.waterSolid(tx, ty);
|
boolean nearEmpty = !solid.solid(tx, ty);
|
||||||
for(Point2 p : Geometry.d4){
|
for(Point2 p : Geometry.d4){
|
||||||
nearEmpty |= !EntityCollisions.waterSolid(tx + p.x, ty + p.y);
|
nearEmpty |= !solid.solid(tx + p.x, ty + p.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
//cannot dump on dry land
|
//cannot dump on solid blocks
|
||||||
if(!nearEmpty) return false;
|
if(!nearEmpty) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user