From 141cf518a220c354c5d78604e3d126e14457f725 Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 3 Feb 2020 14:07:06 -0500 Subject: [PATCH] Refactoring --- .../mindustry/annotations/Annotations.java | 9 +- .../annotations/impl/EntityProcess.java | 39 +- .../mindustry/annotations/util/Selement.java | 9 + .../mindustry/annotations/util/Stype.java | 5 - core/src/mindustry/Vars.java | 2 +- core/src/mindustry/core/NetClient.java | 5 +- core/src/mindustry/core/Renderer.java | 15 +- core/src/mindustry/entities/Damage.java | 9 +- core/src/mindustry/entities/SaveTrait.java | 8 + .../entities/{traits => }/Saveable.java | 2 +- core/src/mindustry/entities/Units.java | 31 +- .../mindustry/entities/def/EntityComps.java | 607 +++++++++++++++--- core/src/mindustry/entities/effect/Decal.java | 1 - core/src/mindustry/entities/effect/Fire.java | 1 - .../entities/effect/GroundEffectEntity.java | 1 - .../entities/effect/ItemTransfer.java | 29 +- .../mindustry/entities/effect/Lightning.java | 6 +- .../src/mindustry/entities/effect/Puddle.java | 2 - .../entities/traits/BuilderTrait.java | 285 -------- .../mindustry/entities/traits/MinerTrait.java | 119 ---- .../mindustry/entities/traits/SaveTrait.java | 8 - .../entities/traits/SpawnerTrait.java | 18 - .../mindustry/entities/type/BaseEntity.java | 65 -- .../src/mindustry/entities/type/BaseUnit.java | 5 +- core/src/mindustry/entities/type/Bullet.java | 11 +- .../mindustry/entities/type/EffectEntity.java | 79 --- core/src/mindustry/entities/type/Player.java | 2 +- .../mindustry/entities/type/TileEntity.java | 41 +- .../mindustry/entities/type/TimedEntity.java | 33 - core/src/mindustry/entities/type/Unit.java | 504 --------------- .../entities/type/base/MinerDrone.java | 1 - .../mindustry/entities/units/Statuses.java | 7 +- .../entities/units/UnitController.java | 5 + core/src/mindustry/game/EventType.java | 20 +- .../mindustry/graphics/MinimapRenderer.java | 4 +- core/src/mindustry/input/MobileInput.java | 3 +- core/src/mindustry/io/SaveVersion.java | 1 - core/src/mindustry/io/TypeIO.java | 10 +- core/src/mindustry/io/versions/Save1.java | 2 +- core/src/mindustry/io/versions/Save2.java | 2 +- core/src/mindustry/type/StatusEffect.java | 18 +- core/src/mindustry/type/UnitDef.java | 19 +- .../ui/fragments/PlayerListFragment.java | 3 +- core/src/mindustry/world/Block.java | 4 +- core/src/mindustry/world/BlockStorage.java | 31 +- .../mindustry/world/blocks/BuildBlock.java | 9 +- core/src/mindustry/world/blocks/Floor.java | 4 +- .../world/blocks/defense/ForceProjector.java | 2 - .../world/blocks/defense/ShockMine.java | 3 +- .../blocks/defense/turrets/ItemTurret.java | 4 +- .../world/blocks/distribution/Conveyor.java | 6 +- .../world/blocks/distribution/Junction.java | 3 +- .../world/blocks/storage/CoreBlock.java | 3 +- .../mindustry/world/blocks/units/MechPad.java | 4 +- .../world/blocks/units/RepairPoint.java | 3 +- .../world/blocks/units/UnitFactory.java | 2 +- 56 files changed, 706 insertions(+), 1418 deletions(-) create mode 100644 core/src/mindustry/entities/SaveTrait.java rename core/src/mindustry/entities/{traits => }/Saveable.java (83%) delete mode 100644 core/src/mindustry/entities/traits/BuilderTrait.java delete mode 100644 core/src/mindustry/entities/traits/MinerTrait.java delete mode 100644 core/src/mindustry/entities/traits/SaveTrait.java delete mode 100644 core/src/mindustry/entities/traits/SpawnerTrait.java delete mode 100755 core/src/mindustry/entities/type/BaseEntity.java delete mode 100644 core/src/mindustry/entities/type/EffectEntity.java delete mode 100644 core/src/mindustry/entities/type/TimedEntity.java delete mode 100644 core/src/mindustry/entities/type/Unit.java create mode 100644 core/src/mindustry/entities/units/UnitController.java diff --git a/annotations/src/main/java/mindustry/annotations/Annotations.java b/annotations/src/main/java/mindustry/annotations/Annotations.java index b5533616ec..abbcabc8bc 100644 --- a/annotations/src/main/java/mindustry/annotations/Annotations.java +++ b/annotations/src/main/java/mindustry/annotations/Annotations.java @@ -10,7 +10,14 @@ public class Annotations{ @Retention(RetentionPolicy.SOURCE) public @interface Component{ /** Dependencies. */ - Class[] value() default {}; + //Class[] value() default {}; + } + + /** Indicates priority of a method in an entity. Methods with higher priority are done last. */ + @Target(ElementType.METHOD) + @Retention(RetentionPolicy.SOURCE) + public @interface MethodPriority{ + float value(); } /** Indicates that a component def is present on all entities. */ diff --git a/annotations/src/main/java/mindustry/annotations/impl/EntityProcess.java b/annotations/src/main/java/mindustry/annotations/impl/EntityProcess.java index cb4499e506..42b52d7eab 100644 --- a/annotations/src/main/java/mindustry/annotations/impl/EntityProcess.java +++ b/annotations/src/main/java/mindustry/annotations/impl/EntityProcess.java @@ -21,6 +21,7 @@ import javax.lang.model.type.*; public class EntityProcess extends BaseProcessor{ Array definitions = new Array<>(); Array baseComponents; + ObjectMap componentNames = new ObjectMap<>(); ObjectMap> componentDependencies = new ObjectMap<>(); ObjectMap> defComponents = new ObjectMap<>(); ObjectSet imports = new ObjectSet<>(); @@ -36,17 +37,12 @@ public class EntityProcess extends BaseProcessor{ if(round == 1){ baseComponents = types(BaseComponent.class); Array allDefs = types(EntityDef.class); + Array allComponents = types(Component.class); - ObjectSet allComponents = new ObjectSet<>(); - - //find all components used... - for(Stype type : allDefs){ - allComponents.addAll(allComponents(type)); + for(Stype type : allComponents){ + componentNames.put(type.name(), type); } - //add all components w/ dependencies - allComponents.addAll(types(Component.class).map(s -> Array.withArrays(getDependencies(s), s)).flatten()); - //add component imports for(Stype comp : allComponents){ imports.addAll(getImports(comp.e)); @@ -57,7 +53,7 @@ public class EntityProcess extends BaseProcessor{ TypeSpec.Builder inter = TypeSpec.interfaceBuilder(interfaceName(component)).addModifiers(Modifier.PUBLIC).addAnnotation(EntityInterface.class); //implement extra interfaces these components may have, e.g. position - for(Stype extraInterface : component.interfaces()){ + for(Stype extraInterface : component.interfaces().select(i -> !isCompInterface(i))){ inter.addSuperinterface(extraInterface.mirror()); } @@ -130,6 +126,8 @@ public class EntityProcess extends BaseProcessor{ //add all methods from components for(ObjectMap.Entry> entry : methods){ + entry.value.sort(m -> m.has(MethodPriority.class) ? m.annotation(MethodPriority.class).value() : 0); + //representative method Smethod first = entry.value.first(); //build method using same params/returns @@ -261,18 +259,8 @@ public class EntityProcess extends BaseProcessor{ Array getDependencies(Stype component){ if(!componentDependencies.containsKey(component)){ ObjectSet out = new ObjectSet<>(); - out.addAll(component.superclasses()); - //TODO extreme confusion - //out.addAll(component.interfaces().select(this::isComponent)); - - //get dependency classes - if(component.annotation(Component.class) != null){ - try{ - component.annotation(Component.class).value(); - }catch(MirroredTypesException e){ - out.addAll(Array.with(e.getTypeMirrors()).map(Stype::of)); - } - } + //add base component interfaces + out.addAll(component.interfaces().select(this::isCompInterface).map(this::interfaceToComp)); //out now contains the base dependencies; finish constructing the tree ObjectSet result = new ObjectSet<>(); @@ -291,6 +279,15 @@ public class EntityProcess extends BaseProcessor{ return componentDependencies.get(component); } + boolean isCompInterface(Stype type){ + return interfaceToComp(type) != null; + } + + Stype interfaceToComp(Stype type){ + String name = type.name().substring(0, type.name().length() - 1) + "Comp"; + return componentNames.get(name); + } + boolean isComponent(Stype type){ return type.annotation(Component.class) != null; } diff --git a/annotations/src/main/java/mindustry/annotations/util/Selement.java b/annotations/src/main/java/mindustry/annotations/util/Selement.java index d7e458a20e..1e7278188a 100644 --- a/annotations/src/main/java/mindustry/annotations/util/Selement.java +++ b/annotations/src/main/java/mindustry/annotations/util/Selement.java @@ -5,6 +5,7 @@ import mindustry.annotations.*; import javax.lang.model.element.*; import javax.lang.model.type.*; +import java.lang.annotation.*; public class Selement{ public final T e; @@ -13,6 +14,14 @@ public class Selement{ this.e = e; } + public A annotation(Class annotation){ + return e.getAnnotation(annotation); + } + + public boolean has(Class annotation){ + return e.getAnnotation(annotation) != null; + } + public Element up(){ return e.getEnclosingElement(); } diff --git a/annotations/src/main/java/mindustry/annotations/util/Stype.java b/annotations/src/main/java/mindustry/annotations/util/Stype.java index 99b9b9f781..abb6792f14 100644 --- a/annotations/src/main/java/mindustry/annotations/util/Stype.java +++ b/annotations/src/main/java/mindustry/annotations/util/Stype.java @@ -5,7 +5,6 @@ import mindustry.annotations.*; import javax.lang.model.element.*; import javax.lang.model.type.*; -import java.lang.annotation.*; public class Stype extends Selement{ @@ -35,10 +34,6 @@ public class Stype extends Selement{ return new Stype((TypeElement)BaseProcessor.typeu.asElement(BaseProcessor.typeu.directSupertypes(mirror()).get(0))); } - public A annotation(Class annotation){ - return e.getAnnotation(annotation); - } - public Array fields(){ return Array.with(e.getEnclosedElements()).select(e -> e instanceof VariableElement).map(e -> new Svar((VariableElement)e)); } diff --git a/core/src/mindustry/Vars.java b/core/src/mindustry/Vars.java index ab88d572bf..c137395f84 100644 --- a/core/src/mindustry/Vars.java +++ b/core/src/mindustry/Vars.java @@ -189,7 +189,7 @@ public class Vars implements Loadable{ public static EntityGroup fireGroup; public static EntityGroup unitGroup; - public static Player player; + public static Unitc player; @Override public void loadAsync(){ diff --git a/core/src/mindustry/core/NetClient.java b/core/src/mindustry/core/NetClient.java index 4ced1cb803..ee52e41588 100644 --- a/core/src/mindustry/core/NetClient.java +++ b/core/src/mindustry/core/NetClient.java @@ -13,7 +13,6 @@ import mindustry.annotations.Annotations.*; import mindustry.core.GameState.*; import mindustry.ctype.*; import mindustry.entities.*; -import mindustry.entities.traits.*; import mindustry.entities.type.*; import mindustry.entities.units.*; import mindustry.game.EventType.*; @@ -365,8 +364,8 @@ public class NetClient implements ApplicationListener{ if(created && entity.getInterpolator() != null && entity.getInterpolator().target != null){ //set initial starting position entity.setNet(entity.getInterpolator().target.x, entity.getInterpolator().target.y); - if(entity instanceof Unit && entity.getInterpolator().targets.length > 0){ - ((Unit)entity).rotation = entity.getInterpolator().targets[0]; + if(entity instanceof Unitc && entity.getInterpolator().targets.length > 0){ + ((Unitc)entity).rotation = entity.getInterpolator().targets[0]; } } diff --git a/core/src/mindustry/core/Renderer.java b/core/src/mindustry/core/Renderer.java index fc1c5a7105..d9e03e58e8 100644 --- a/core/src/mindustry/core/Renderer.java +++ b/core/src/mindustry/core/Renderer.java @@ -12,7 +12,6 @@ import arc.scene.ui.layout.*; import arc.util.*; import mindustry.content.*; import mindustry.core.GameState.*; -import mindustry.entities.traits.*; import mindustry.entities.type.*; import mindustry.game.EventType.*; import mindustry.graphics.*; @@ -306,7 +305,7 @@ public class Renderer implements ApplicationListener{ Draw.color(0, 0, 0, 0.4f); float rad = 1.6f; - Cons draw = u -> { + Cons draw = u -> { float size = Math.max(u.getIconRegion().getWidth(), u.getIconRegion().getHeight()) * Draw.scl; Draw.rect("circle-shadow", u.x, u.y, size * rad, size * rad); }; @@ -331,14 +330,14 @@ public class Renderer implements ApplicationListener{ } private void drawAllTeams(boolean flying){ - unitGroup.draw(u -> u.isFlying() == flying && !u.isDead(), Unit::drawUnder); - playerGroup.draw(p -> p.isFlying() == flying && !p.isDead(), Unit::drawUnder); + unitGroup.draw(u -> u.isFlying() == flying && !u.isDead(), Unitc::drawUnder); + playerGroup.draw(p -> p.isFlying() == flying && !p.isDead(), Unitc::drawUnder); - unitGroup.draw(u -> u.isFlying() == flying && !u.isDead(), Unit::drawAll); - playerGroup.draw(p -> p.isFlying() == flying, Unit::drawAll); + unitGroup.draw(u -> u.isFlying() == flying && !u.isDead(), Unitc::drawAll); + playerGroup.draw(p -> p.isFlying() == flying, Unitc::drawAll); - unitGroup.draw(u -> u.isFlying() == flying && !u.isDead(), Unit::drawOver); - playerGroup.draw(p -> p.isFlying() == flying, Unit::drawOver); + unitGroup.draw(u -> u.isFlying() == flying && !u.isDead(), Unitc::drawOver); + playerGroup.draw(p -> p.isFlying() == flying, Unitc::drawOver); } public void scaleCamera(float amount){ diff --git a/core/src/mindustry/entities/Damage.java b/core/src/mindustry/entities/Damage.java index 3161c6667f..0a8612d31a 100644 --- a/core/src/mindustry/entities/Damage.java +++ b/core/src/mindustry/entities/Damage.java @@ -9,7 +9,6 @@ import arc.math.*; import arc.math.geom.*; import arc.util.*; import mindustry.content.*; -import mindustry.entities.Effects.*; import mindustry.entities.effect.*; import mindustry.entities.type.*; import mindustry.game.EventType.*; @@ -125,7 +124,7 @@ public class Damage{ rect.width += expand * 2; rect.height += expand * 2; - Cons cons = e -> { + Cons cons = e -> { e.hitbox(hitrect); Rect other = hitrect; other.y -= expand; @@ -146,8 +145,8 @@ public class Damage{ } /** Damages all entities and blocks in a radius that are enemies of the team. */ - public static void damageUnits(Team team, float x, float y, float size, float damage, Boolf predicate, Cons acceptor){ - Cons cons = entity -> { + public static void damageUnits(Team team, float x, float y, float size, float damage, Boolf predicate, Cons acceptor){ + Cons cons = entity -> { if(!predicate.get(entity)) return; entity.hitbox(hitrect); @@ -178,7 +177,7 @@ public class Damage{ /** Damages all entities and blocks in a radius that are enemies of the team. */ public static void damage(Team team, float x, float y, float radius, float damage, boolean complete){ - Cons cons = entity -> { + Cons cons = entity -> { if(entity.getTeam() == team || entity.dst(x, y) > radius){ return; } diff --git a/core/src/mindustry/entities/SaveTrait.java b/core/src/mindustry/entities/SaveTrait.java new file mode 100644 index 0000000000..6cb2437ef6 --- /dev/null +++ b/core/src/mindustry/entities/SaveTrait.java @@ -0,0 +1,8 @@ +package mindustry.entities; + +/** + * Marks an entity as serializable. + */ +public interface SaveTrait extends Saveable{ + byte version(); +} diff --git a/core/src/mindustry/entities/traits/Saveable.java b/core/src/mindustry/entities/Saveable.java similarity index 83% rename from core/src/mindustry/entities/traits/Saveable.java rename to core/src/mindustry/entities/Saveable.java index 801e4ab426..0eb4bb143d 100644 --- a/core/src/mindustry/entities/traits/Saveable.java +++ b/core/src/mindustry/entities/Saveable.java @@ -1,4 +1,4 @@ -package mindustry.entities.traits; +package mindustry.entities; import java.io.*; diff --git a/core/src/mindustry/entities/Units.java b/core/src/mindustry/entities/Units.java index 67fe01dc9e..dd1d899d80 100644 --- a/core/src/mindustry/entities/Units.java +++ b/core/src/mindustry/entities/Units.java @@ -3,7 +3,6 @@ package mindustry.entities; import arc.func.*; import arc.math.*; import arc.math.geom.*; -import mindustry.entities.traits.*; import mindustry.entities.type.*; import mindustry.game.*; import mindustry.world.*; @@ -13,7 +12,7 @@ import static mindustry.Vars.*; /** Utility class for unit and team interactions.*/ public class Units{ private static Rect hitrect = new Rect(); - private static Unit result; + private static Unitc result; private static float cdist; private static boolean boolResult; @@ -41,7 +40,7 @@ public class Units{ } /** See {@link #invalidateTarget(TargetTrait, Team, float, float, float)} */ - public static boolean invalidateTarget(TargetTrait target, Unit targeter){ + public static boolean invalidateTarget(TargetTrait target, Unitc targeter){ return invalidateTarget(target, targeter.getTeam(), targeter.x, targeter.y, targeter.getWeapon().bullet.range()); } @@ -88,19 +87,19 @@ public class Units{ /** Returns the closest target enemy. First, units are checked, then tile entities. */ public static TargetTrait closestTarget(Team team, float x, float y, float range){ - return closestTarget(team, x, y, range, Unit::isValid); + return closestTarget(team, x, y, range, Unitc::isValid); } /** Returns the closest target enemy. First, units are checked, then tile entities. */ - public static TargetTrait closestTarget(Team team, float x, float y, float range, Boolf unitPred){ + public static TargetTrait closestTarget(Team team, float x, float y, float range, Boolf unitPred){ return closestTarget(team, x, y, range, unitPred, t -> true); } /** Returns the closest target enemy. First, units are checked, then tile entities. */ - public static TargetTrait closestTarget(Team team, float x, float y, float range, Boolf unitPred, Boolf tilePred){ + public static TargetTrait closestTarget(Team team, float x, float y, float range, Boolf unitPred, Boolf tilePred){ if(team == Team.derelict) return null; - Unit unit = closestEnemy(team, x, y, range, unitPred); + Unitc unit = closestEnemy(team, x, y, range, unitPred); if(unit != null){ return unit; }else{ @@ -109,7 +108,7 @@ public class Units{ } /** Returns the closest enemy of this team. Filter by predicate. */ - public static Unit closestEnemy(Team team, float x, float y, float range, Boolf predicate){ + public static Unitc closestEnemy(Team team, float x, float y, float range, Boolf predicate){ if(team == Team.derelict) return null; result = null; @@ -129,7 +128,7 @@ public class Units{ } /** Returns the closest ally of this team. Filter by predicate. */ - public static Unit closest(Team team, float x, float y, float range, Boolf predicate){ + public static Unitc closest(Team team, float x, float y, float range, Boolf predicate){ result = null; cdist = 0f; @@ -147,7 +146,7 @@ public class Units{ } /** Iterates over all units in a rectangle. */ - public static void nearby(Team team, float x, float y, float width, float height, Cons cons){ + public static void nearby(Team team, float x, float y, float width, float height, Cons cons){ unitGroup.intersect(x, y, width, height, u -> { if(u.getTeam() == team){ cons.get(u); @@ -161,7 +160,7 @@ public class Units{ } /** Iterates over all units in a circle around this position. */ - public static void nearby(Team team, float x, float y, float radius, Cons cons){ + public static void nearby(Team team, float x, float y, float radius, Cons cons){ unitGroup.intersect(x - radius, y - radius, radius*2f, radius*2f, unit -> { if(unit.getTeam() == team && unit.withinDst(x, y, radius)){ cons.get(unit); @@ -176,18 +175,18 @@ public class Units{ } /** Iterates over all units in a rectangle. */ - public static void nearby(float x, float y, float width, float height, Cons cons){ + public static void nearby(float x, float y, float width, float height, Cons cons){ unitGroup.intersect(x, y, width, height, cons); playerGroup.intersect(x, y, width, height, cons); } /** Iterates over all units in a rectangle. */ - public static void nearby(Rect rect, Cons cons){ + public static void nearby(Rect rect, Cons cons){ nearby(rect.x, rect.y, rect.width, rect.height, cons); } /** Iterates over all units that are enemies of this team. */ - public static void nearbyEnemies(Team team, float x, float y, float width, float height, Cons cons){ + public static void nearbyEnemies(Team team, float x, float y, float width, float height, Cons cons){ unitGroup.intersect(x, y, width, height, u -> { if(team.isEnemy(u.getTeam())){ cons.get(u); @@ -202,12 +201,12 @@ public class Units{ } /** Iterates over all units that are enemies of this team. */ - public static void nearbyEnemies(Team team, Rect rect, Cons cons){ + public static void nearbyEnemies(Team team, Rect rect, Cons cons){ nearbyEnemies(team, rect.x, rect.y, rect.width, rect.height, cons); } /** Iterates over all units. */ - public static void all(Cons cons){ + public static void all(Cons cons){ unitGroup.all().each(cons); playerGroup.all().each(cons); } diff --git a/core/src/mindustry/entities/def/EntityComps.java b/core/src/mindustry/entities/def/EntityComps.java index c75d80404e..9cd64d8299 100644 --- a/core/src/mindustry/entities/def/EntityComps.java +++ b/core/src/mindustry/entities/def/EntityComps.java @@ -1,13 +1,16 @@ package mindustry.entities.def; +import arc.*; import arc.graphics.*; import arc.graphics.g2d.*; import arc.math.*; import arc.math.geom.*; +import arc.scene.ui.layout.*; import arc.struct.Bits; +import arc.struct.Queue; import arc.struct.*; -import arc.util.ArcAnnotate.*; import arc.util.*; +import arc.util.ArcAnnotate.*; import arc.util.pooling.*; import mindustry.*; import mindustry.annotations.Annotations.*; @@ -15,64 +18,154 @@ import mindustry.content.*; import mindustry.ctype.*; import mindustry.entities.*; import mindustry.entities.bullet.*; -import mindustry.entities.def.EntityComps.MinerComp.*; import mindustry.entities.effect.*; -import mindustry.entities.traits.*; import mindustry.entities.type.*; import mindustry.entities.units.*; +import mindustry.game.EventType.*; import mindustry.game.*; import mindustry.gen.*; +import mindustry.graphics.*; import mindustry.net.*; import mindustry.type.*; +import mindustry.ui.*; import mindustry.world.*; +import mindustry.world.blocks.*; import mindustry.world.blocks.BuildBlock.*; import java.io.*; +import java.util.*; -import static arc.math.Mathf.dst; import static mindustry.Vars.*; +import static mindustry.entities.traits.BuilderTrait.BuildDataStatic.tmptr; @SuppressWarnings("unused") public class EntityComps{ - @Component({HealthComp.class, VelComp.class, StatusComp.class, TeamComp.class, ItemsComp.class}) - class UnitComp{ + @Component + abstract class UnitComp implements Healthc, Velc, Statusc, Teamc, Itemsc, Hitboxc, Rotc{ UnitDef type; + UnitController controller; + + float getBounds(){ + return getHitSize() * 2f; + } + + public void update(){ + //apply knockback based on spawns + //TODO move elsewhere + if(getTeam() != state.rules.waveTeam){ + float relativeSize = state.rules.dropZoneRadius + getBounds()/2f + 1f; + for(Tile spawn : spawner.getGroundSpawns()){ + if(withinDst(spawn.worldx(), spawn.worldy(), relativeSize)){ + getVel().add(Tmp.v1.set(this).sub(spawn.worldx(), spawn.worldy()).setLength(0.1f + 1f - dst(spawn) / relativeSize).scl(0.45f * Time.delta())); + } + } + } + + Tile tile = tileOn(); + Floor floor = floorOn(); + + if(tile != null){ + //unit block update + tile.block().unitOn(tile, (mindustry.gen.Unitc)this); + + //apply damage + if(floor.damageTaken > 0f){ + damageContinuous(floor.damageTaken); + } + } + } + + public void drawLight(){ + //TODO move + if(type.lightRadius > 0){ + renderer.lights.add(getX(), getY(), type.lightRadius, type.lightColor, 0.6f); + } + } + + public void draw(){ + //draw power cell - TODO move + Draw.color(Color.black, getTeam().color, healthf() + Mathf.absin(Time.time(), Math.max(healthf() * 5f, 1f), 1f - healthf())); + Draw.rect(type.cellRegion, getX(), getY(), getRotation() - 90); + Draw.color(); + } + + public void killed(){ + float explosiveness = 2f + item().explosiveness * getStack().amount; + float flammability = item().flammability * getStack().amount; + Damage.dynamicExplosion(getX(), getY(), flammability, explosiveness, 0f, getBounds() / 2f, Pal.darkFlame); + + //TODO cleanup + ScorchDecal.create(getX(), getY()); + Fx.explosion.at(this); + Effects.shake(2f, 2f, this); + + Sounds.bang.at(this); + Events.fire(new UnitDestroyEvent((mindustry.gen.Unitc)this)); + + //TODO implement suicide bomb trigger + //if(explosiveness > 7f && this == player){ + // Events.fire(Trigger.suicideBomb); + //} + } } + @Component class OwnerComp{ Entityc owner; } - @Component({TimedComp.class, DamageComp.class, HitboxComp.class}) - class BulletComp{ + @Component + abstract class ChildComp implements Posc{ + transient float x, y; + + private @Nullable Posc parent; + private float offsetX, offsetY; + + public void add(){ + if(parent != null){ + offsetX = x - parent.getX(); + offsetY = y - parent.getY(); + } + } + + public void update(){ + if(parent != null){ + x = parent.getX() + offsetX; + y = parent.getY() + offsetY; + } + } + } + + @Component + abstract class BulletComp implements Timedc, Damagec, Hitboxc, Teamc{ BulletType bullet; - float getDamage(){ + public float getDamage(){ return bullet.damage; } - void init(){ + public void init(){ //TODO bullet.init(null); } - void remove(){ + public void remove(){ //TODO bullet.despawned(null); } } @Component - class DamageComp{ - native float getDamage(); + abstract class DamageComp{ + abstract float getDamage(); } @Component - abstract class TimedComp extends EntityComp implements Scaled{ + abstract class TimedComp implements Entityc, Scaled{ float time, lifetime; - void update(){ + public void update(){ time = Math.min(time + Time.delta(), lifetime); if(time >= lifetime){ @@ -87,16 +180,22 @@ public class EntityComps{ } @Component - class HealthComp{ + abstract class HealthComp implements Entityc{ + static final float hitDuration = 9f; + float health, maxHealth, hitTime; boolean dead; + boolean isValid(){ + return !dead && isAdded(); + } + float healthf(){ return health / maxHealth; } - void update(){ - hitTime -= Time.delta() / 9f; + public void update(){ + hitTime -= Time.delta() / hitDuration; } void killed(){ @@ -125,6 +224,20 @@ public class EntityComps{ } } + void damage(float amount, boolean withEffect){ + float pre = hitTime; + + damage(amount); + + if(!withEffect){ + hitTime = pre; + } + } + + void damageContinuous(float amount){ + damage(amount * Time.delta(), hitTime <= -20 + hitDuration); + } + void clampHealth(){ health = Mathf.clamp(health, 0, maxHealth); } @@ -136,23 +249,67 @@ public class EntityComps{ } @Component - class FlyingComp{ - boolean flying; + abstract class FlyingComp implements Posc, Velc, Healthc{ + transient float x, y; + transient Vec2 vel; + + float elevation; + float drownTime; + + boolean isGrounded(){ + return elevation < 0.001f; + } + + public void update(){ + Floor floor = floorOn(); + + if(isGrounded() && floor.isLiquid && vel.len2() > 0.4f*0.4f && Mathf.chance((vel.len2() * floor.speedMultiplier) * 0.03f * Time.delta())){ + floor.walkEffect.at(x, y, 0, floor.color); + } + + if(isGrounded() && floor.isLiquid && floor.drownTime > 0){ + drownTime += Time.delta() * 1f / floor.drownTime; + drownTime = Mathf.clamp(drownTime); + if(Mathf.chance(Time.delta() * 0.05f)){ + floor.drownUpdateEffect.at(getX(), getY(), 0f, floor.color); + } + + //TODO is the netClient check necessary? + if(drownTime >= 0.999f && !net.client()){ + kill(); + //TODO drown event! + } + }else{ + drownTime = Mathf.lerpDelta(drownTime, 0f, 0.03f); + } + } } @Component - class LegsComp{ + abstract class LegsComp implements Posc, Flyingc{ float baseRotation; - float drownTime; } @Component class RotComp{ float rotation; + + void interpolate(){ + Syncc sync = (Syncc)this; + + if(sync.getInterpolator().values.length > 0){ + rotation = sync.getInterpolator().values[0]; + } + } + } + + @Component + abstract class TileComp implements Posc, Teamc{ + Tile tile; } @Component - abstract class TeamComp{ + abstract class TeamComp implements Posc{ transient float x, y; Team team = Team.sharded; @@ -162,8 +319,8 @@ public class EntityComps{ } } - @Component({RotComp.class, PosComp.class}) - abstract static class WeaponsComp implements Teamc{ + @Component + abstract static class WeaponsComp implements Teamc, Posc, Rotc{ transient float x, y, rotation; /** 1 */ @@ -184,7 +341,7 @@ public class EntityComps{ } /** Aim at something. This will make all mounts point at it. */ - void aim(Unit unit, float x, float y){ + void aim(Unitc unit, float x, float y){ Tmp.v1.set(x, y).sub(this.x, this.y); if(Tmp.v1.len() < minAimDst) Tmp.v1.setLength(minAimDst); @@ -198,12 +355,12 @@ public class EntityComps{ } /** Update shooting and rotation for this unit. */ - void update(Unit unit){ + public void update(){ for(WeaponMount mount : mounts){ Weapon weapon = mount.weapon; mount.reload -= Time.delta(); - float rotation = unit.rotation - 90; + float rotation = this.rotation - 90; //rotate if applicable if(weapon.rotate){ @@ -294,39 +451,115 @@ public class EntityComps{ private void bullet(Weapon weapon, float x, float y, float angle){ Tmp.v1.trns(angle, 3f); - Bullet.create(weapon.bullet, this, getTeam(), x + Tmp.v1.x, y + Tmp.v1.y, angle, (1f - weapon.velocityRnd) + Mathf.random(weapon.velocityRnd)); + //TODO create the bullet + //Bullet.create(weapon.bullet, this, getTeam(), x + Tmp.v1.x, y + Tmp.v1.y, angle, (1f - weapon.velocityRnd) + Mathf.random(weapon.velocityRnd)); } } @Component - class DrawComp{ - //TODO ponder. + abstract static class DrawShadowComp implements Drawc, Rotc, Flyingc{ + static final float shadowTX = -12, shadowTY = -13, shadowColor = Color.toFloatBits(0, 0, 0, 0.22f); - native float drawSize(); + transient float x, y, rotation; + + abstract TextureRegion getShadowRegion(); + + void drawShadow(){ + if(!isGrounded()){ + Draw.color(shadowColor); + Draw.rect(getShadowRegion(), x + shadowTX * getElevation(), y + shadowTY * getElevation(), rotation - 90); + Draw.color(); + } + } + } + + @Component + abstract class DrawItemsComp implements Drawc, Itemsc, Posc, Rotc{ + transient float x, y, rotation; + + float itemTime; + + //drawn after base + @MethodPriority(3) + public void draw(){ + boolean number = isLocal(); + itemTime = Mathf.lerpDelta(itemTime, Mathf.num(hasItem()), 0.05f); + + //draw back items + if(itemTime > 0.01f){ + float backTrns = 5f; + float size = (itemSize + Mathf.absin(Time.time(), 5f, 1f)) * itemTime; + + Draw.mixcol(Pal.accent, Mathf.absin(Time.time(), 5f, 0.5f)); + Draw.rect(item().icon(Cicon.medium), + x + Angles.trnsx(rotation + 180f, backTrns), + y + Angles.trnsy(rotation + 180f, backTrns), + size, size, rotation); + + Draw.mixcol(); + + Lines.stroke(1f, Pal.accent); + Lines.circle( + x + Angles.trnsx(rotation + 180f, backTrns), + y + Angles.trnsy(rotation + 180f, backTrns), + (3f + Mathf.absin(Time.time(), 5f, 1f)) * itemTime); + + if(isLocal()){ + Fonts.outline.draw(getStack().amount + "", + x + Angles.trnsx(rotation + 180f, backTrns), + y + Angles.trnsy(rotation + 180f, backTrns) - 3, + Pal.accent, 0.25f * itemTime / Scl.scl(1f), false, Align.center + ); + } + + Draw.reset(); + } + } + } + + @Component + abstract class DrawLightComp implements Drawc{ + void drawLight(){} + } + + @Component + abstract class DrawOverComp implements Drawc{ + void drawOver(){} + } + + @Component + abstract class DrawUnderComp implements Drawc{ + void drawUnder(){} + } + + @Component + abstract class DrawComp{ + + abstract float clipSize(); void draw(){ } } - @Component(PosComp.class) - abstract class SyncComp extends PosComp{ + @Component + abstract class SyncComp implements Posc{ + transient float x, y; + Interpolator interpolator = new Interpolator(); void setNet(float x, float y){ set(x, y); //TODO change interpolator API - if(interpolator != null){ - interpolator.target.set(x, y); - interpolator.last.set(x, y); - interpolator.pos.set(0, 0); - interpolator.updateSpacing = 16; - interpolator.lastUpdated = 0; - } + interpolator.target.set(x, y); + interpolator.last.set(x, y); + interpolator.pos.set(0, 0); + interpolator.updateSpacing = 16; + interpolator.lastUpdated = 0; } - void update(){ + public void update(){ if(Vars.net.client() && !isLocal()){ interpolate(); } @@ -340,7 +573,35 @@ public class EntityComps{ } @Component - abstract class PosComp extends EntityComp implements Position{ + abstract class BoundedComp implements Velc, Posc, Healthc, Flyingc{ + static final float warpDst = 180f; + + transient float x, y; + transient Vec2 vel; + + @Override + public void update(){ + //repel unit out of bounds + if(x < 0) vel.x += (-x/warpDst); + if(y < 0) vel.y += (-y/warpDst); + if(x > world.unitWidth()) vel.x -= (x - world.unitWidth())/warpDst; + if(y > world.unitHeight()) vel.y -= (y - world.unitHeight())/warpDst; + + //clamp position if not flying + if(isGrounded()){ + x = Mathf.clamp(x, 0, world.width() * tilesize - tilesize); + y = Mathf.clamp(y, 0, world.height() * tilesize - tilesize); + } + + //kill when out of bounds + if(x < -finalWorldBounds || y < -finalWorldBounds || x >= world.width() * tilesize + finalWorldBounds || y >= world.height() * tilesize + finalWorldBounds){ + kill(); + } + } + } + + @Component + abstract class PosComp implements Position{ float x, y; void set(float x, float y){ @@ -359,19 +620,31 @@ public class EntityComps{ int tileY(){ return Vars.world.toTile(getY()); } + + /** Returns air if this unit is on a non-air top block. */ + public Floor floorOn(){ + Tile tile = tileOn(); + return tile == null || tile.block() != Blocks.air ? (Floor)Blocks.air : tile.floor(); + } + + public @Nullable Tile tileOn(){ + return world.tileWorld(x, y); + } } - @Component({ItemsComp.class, TeamComp.class, RotComp.class}) + @Component static abstract class MinerComp implements Itemsc, Posc, Teamc, Rotc{ static float miningRange = 70f; + transient float x, y, rotation; + @Nullable Tile mineTile; - native boolean canMine(Item item); + abstract boolean canMine(Item item); - native float getMiningSpeed(); + abstract float getMiningSpeed(); - native boolean offloadImmediately(); + abstract boolean offloadImmediately(); boolean isMining(){ return mineTile != null; @@ -381,7 +654,7 @@ public class EntityComps{ TileEntity core = getClosestCore(); if(core != null && mineTile != null && mineTile.drop() != null && !acceptsItem(mineTile.drop()) && dst(core) < mineTransferRange){ - int accepted = core.tile.block().acceptStack(item(), getStack().amount, core.tile, unit); + int accepted = core.tile.block().acceptStack(item(), getStack().amount, core.tile, this); if(accepted > 0){ Call.transferItemTo(item(), accepted, mineTile.worldx() + Mathf.range(tilesize / 2f), @@ -399,7 +672,7 @@ public class EntityComps{ if(Mathf.chance(Time.delta() * (0.06 - item.hardness * 0.01) * getMiningSpeed())){ - if(dst(core) < mineTransferRange && core.tile.block().acceptStack(item, 1, core.tile, unit) == 1 && offloadImmediately()){ + if(dst(core) < mineTransferRange && core.tile.block().acceptStack(item, 1, core.tile, this) == 1 && offloadImmediately()){ Call.transferItemTo(item, 1, mineTile.worldx() + Mathf.range(tilesize / 2f), mineTile.worldy() + Mathf.range(tilesize / 2f), core.tile); @@ -408,7 +681,7 @@ public class EntityComps{ ItemTransfer.transferItemToUnit(item, mineTile.worldx() + Mathf.range(tilesize / 2f), mineTile.worldy() + Mathf.range(tilesize / 2f), - unit); + this); } } @@ -417,19 +690,136 @@ public class EntityComps{ } } } + + void drawOver(){ + if(!isMining()) return; + float focusLen = 4f + Mathf.absin(Time.time(), 1.1f, 0.5f); + float swingScl = 12f, swingMag = tilesize / 8f; + float flashScl = 0.3f; + + float px = x + Angles.trnsx(rotation, focusLen); + float py = y + Angles.trnsy(rotation, focusLen); + + float ex = mineTile.worldx() + Mathf.sin(Time.time() + 48, swingScl, swingMag); + float ey = mineTile.worldy() + Mathf.sin(Time.time() + 48, swingScl + 2f, swingMag); + + Draw.color(Color.lightGray, Color.white, 1f - flashScl + Mathf.absin(Time.time(), 0.5f, flashScl)); + + Drawf.laser(Core.atlas.find("minelaser"), Core.atlas.find("minelaser-end"), px, py, ex, ey, 0.75f); + + //TODO hack? + if(isLocal()){ + Lines.stroke(1f, Pal.accent); + Lines.poly(mineTile.worldx(), mineTile.worldy(), 4, tilesize / 2f * Mathf.sqrt2, Time.time()); + } + + Draw.color(); + } } @Component - class BuilderComp{ + abstract static class BuilderComp implements mindustry.gen.Unitc{ + static final float placeDistance = 220f; + static final Vec2[] tmptr = new Vec2[]{new Vec2(), new Vec2(), new Vec2(), new Vec2()}; + + transient float x, y, rotation; + Queue requests = new Queue<>(); float buildSpeed = 1f; //boolean building; + void updateBuilding(){ + float finalPlaceDst = state.rules.infiniteResources ? Float.MAX_VALUE : placeDistance; + + Iterator it = requests.iterator(); + while(it.hasNext()){ + BuildRequest req = it.next(); + Tile tile = world.tile(req.x, req.y); + if(tile == null || (req.breaking && tile.block() == Blocks.air) || (!req.breaking && (tile.rotation() == req.rotation || !req.block.rotate) && tile.block() == req.block)){ + it.remove(); + } + } + + TileEntity core = getClosestCore(); + + //nothing to build. + if(buildRequest() == null) return; + + //find the next build request + if(requests.size > 1){ + int total = 0; + BuildRequest req; + while((dst((req = buildRequest()).tile()) > finalPlaceDst || shouldSkip(req, core)) && total < requests.size){ + requests.removeFirst(); + requests.addLast(req); + total++; + } + } + + BuildRequest current = buildRequest(); + + if(dst(current.tile()) > finalPlaceDst) return; + + Tile tile = world.tile(current.x, current.y); + + if(!(tile.block() instanceof BuildBlock)){ + if(!current.initialized && !current.breaking && Build.validPlace(getTeam(), current.x, current.y, current.block, current.rotation)){ + Build.beginPlace(getTeam(), current.x, current.y, current.block, current.rotation); + }else if(!current.initialized && current.breaking && Build.validBreak(getTeam(), current.x, current.y)){ + Build.beginBreak(getTeam(), current.x, current.y); + }else{ + requests.removeFirst(); + return; + } + } + + if(tile.entity instanceof BuildEntity && !current.initialized){ + Core.app.post(() -> Events.fire(new BuildSelectEvent(tile, getTeam(), (Builderc)this, current.breaking))); + current.initialized = true; + } + + //if there is no core to build with or no build entity, stop building! + if((core == null && !state.rules.infiniteResources) || !(tile.entity instanceof BuildEntity)){ + return; + } + + //otherwise, update it. + BuildEntity entity = tile.ent(); + + if(entity == null){ + return; + } + + if(dst(tile) <= finalPlaceDst){ + rotation = Mathf.slerpDelta(rotation, angleTo(entity), 0.4f); + } + + if(current.breaking){ + entity.deconstruct(this, core, 1f / entity.buildCost * Time.delta() * buildSpeed * state.rules.buildSpeedMultiplier); + }else{ + if(entity.construct(this, core, 1f / entity.buildCost * Time.delta() * buildSpeed * state.rules.buildSpeedMultiplier, current.hasConfig)){ + if(current.hasConfig){ + Call.onTileConfig(null, tile, current.config); + } + } + } + + current.stuck = Mathf.equal(current.progress, entity.progress); + current.progress = entity.progress; + } + + /** @return whether this request should be skipped, in favor of the next one. */ + boolean shouldSkip(BuildRequest request, @Nullable TileEntity core){ + //requests that you have at least *started* are considered + if(state.rules.infiniteResources || request.breaking || !request.initialized || core == null) return false; + return request.stuck && !core.items.has(request.block.requirements); + } + void removeBuild(int x, int y, boolean breaking){ //remove matching request - int idx = player.buildQueue().indexOf(req -> req.breaking == breaking && req.x == x && req.y == y); + int idx = requests.indexOf(req -> req.breaking == breaking && req.x == x && req.y == y); if(idx != -1){ - player.buildQueue().removeIndex(idx); + requests.removeIndex(idx); } } @@ -475,10 +865,47 @@ public class EntityComps{ @Nullable BuildRequest buildRequest(){ return requests.size == 0 ? null : requests.first(); } + + void drawOver(){ + if(!isBuilding()) return; + BuildRequest request = buildRequest(); + Tile tile = world.tile(request.x, request.y); + + if(dst(tile) > placeDistance && !state.isEditor()){ + return; + } + + Lines.stroke(1f, Pal.accent); + float focusLen = 3.8f + Mathf.absin(Time.time(), 1.1f, 0.6f); + float px = x + Angles.trnsx(rotation, focusLen); + float py = y + Angles.trnsy(rotation, focusLen); + + float sz = Vars.tilesize * tile.block().size / 2f; + float ang = angleTo(tile); + + tmptr[0].set(tile.drawx() - sz, tile.drawy() - sz); + tmptr[1].set(tile.drawx() + sz, tile.drawy() - sz); + tmptr[2].set(tile.drawx() - sz, tile.drawy() + sz); + tmptr[3].set(tile.drawx() + sz, tile.drawy() + sz); + + Arrays.sort(tmptr, Structs.comparingFloat(vec -> Angles.angleDist(angleTo(vec), ang))); + + float x1 = tmptr[0].x, y1 = tmptr[0].y, + x3 = tmptr[1].x, y3 = tmptr[1].y; + + Draw.alpha(1f); + + Lines.line(px, py, x1, y1); + Lines.line(px, py, x3, y3); + + Fill.circle(px, py, 1.6f + Mathf.absin(Time.time(), 0.8f, 1.5f)); + + Draw.color(); + } } - @Component(DamageComp.class) - class ShielderComp{ + @Component + abstract class ShielderComp implements Damagec{ void absorb(){ @@ -486,12 +913,16 @@ public class EntityComps{ } @Component - class ItemsComp{ + abstract class ItemsComp{ ItemStack stack = new ItemStack(); - native int getItemCapacity(); + abstract int getItemCapacity(); - public Item item(){ + void update(){ + stack.amount = Mathf.clamp(stack.amount, 0, getItemCapacity()); + } + + Item item(){ return stack.item; } @@ -508,47 +939,50 @@ public class EntityComps{ } } - @Component(VelComp.class) - class MassComp{ + @Component + abstract class MassComp implements Velc{ float mass; } - @Component({PosComp.class, DrawComp.class, TimedComp.class}) - class EffectComp extends EntityComp{ + @Component + abstract class EffectComp implements Posc, Drawc, Timedc{ Effect effect; Color color = new Color(Color.white); Object data; float rotation = 0f; - void draw(){ + public void draw(){ } - void update(){ + public void update(){ //TODO fix effects, make everything poolable } } @Component - abstract class VelComp extends PosComp{ + abstract class VelComp implements Posc{ + transient float x, y; + final Vec2 vel = new Vec2(); float drag = 0f; - void update(){ + public void update(){ + //TODO handle solidity x += vel.x; y += vel.y; vel.scl(1f - drag * Time.delta()); } } - @Component(PosComp.class) - class HitboxComp{ + @Component + abstract class HitboxComp implements Posc{ transient float x, y; float hitSize; float lastX, lastY; - void update(){ + public void update(){ } @@ -575,8 +1009,8 @@ public class EntityComps{ } } - @Component(PosComp.class) - class StatusComp{ + @Component + abstract class StatusComp implements Posc{ private Array statuses = new Array<>(); private Bits applied = new Bits(content.getBy(ContentType.status).size); @@ -584,6 +1018,11 @@ public class EntityComps{ private float damageMultiplier; private float armorMultiplier; + /** @return damage taken based on status armor multipliers */ + float getDamage(float amount){ + return amount * Mathf.clamp(1f - armorMultiplier / 100f); + } + void apply(StatusEffect effect, float duration){ if(effect == StatusEffects.none || effect == null || isImmune(effect)) return; //don't apply empty or immune effects @@ -597,7 +1036,7 @@ public class EntityComps{ }else if(entry.effect.reactsWith(effect)){ //find opposite StatusEntry.tmp.effect = entry.effect; //TODO unit cannot be null here - entry.effect.getTransition(null, effect, entry.time, duration, StatusEntry.tmp); + entry.effect.getTransition((mindustry.gen.Unitc)this, effect, entry.time, duration, StatusEntry.tmp); entry.time = StatusEntry.tmp.time; if(StatusEntry.tmp.effect != entry.effect){ @@ -634,7 +1073,18 @@ public class EntityComps{ return Tmp.c1.set(r / statuses.size, g / statuses.size, b / statuses.size, 1f); } - void update(){ + public void update(){ + Floor floor = floorOn(); + Tile tile = tileOn(); + boolean flying = false; + //TODO conditionally apply status effects on floor, if not flying + if(!flying && tile != null){ + //apply effect + if(floor.status != null){ + apply(floor.status, floor.statusDuration); + } + } + applied.clear(); speedMultiplier = damageMultiplier = armorMultiplier = 1f; @@ -651,8 +1101,8 @@ public class EntityComps{ speedMultiplier *= entry.effect.speedMultiplier; armorMultiplier *= entry.effect.armorMultiplier; damageMultiplier *= entry.effect.damageMultiplier; - //TODO unit can't be null - entry.effect.update(null, entry.time); + //TODO ugly casting + entry.effect.update((mindustry.gen.Unitc)this, entry.time); } return false; @@ -694,6 +1144,10 @@ public class EntityComps{ class EntityComp{ int id; + boolean isAdded(){ + return true; + } + void init(){} void update(){} @@ -707,8 +1161,7 @@ public class EntityComps{ } boolean isLocal(){ - //TODO fix - return this == (Object)Vars.player; + return this == Vars.player; } T as(Class type){ diff --git a/core/src/mindustry/entities/effect/Decal.java b/core/src/mindustry/entities/effect/Decal.java index 776eb6212b..29ef37052e 100644 --- a/core/src/mindustry/entities/effect/Decal.java +++ b/core/src/mindustry/entities/effect/Decal.java @@ -3,7 +3,6 @@ package mindustry.entities.effect; import arc.graphics.g2d.Draw; import arc.math.Mathf; import mindustry.entities.EntityGroup; -import mindustry.entities.type.TimedEntity; import mindustry.graphics.Pal; import static mindustry.Vars.groundEffectGroup; diff --git a/core/src/mindustry/entities/effect/Fire.java b/core/src/mindustry/entities/effect/Fire.java index 3a37e51cee..2d5ac2e0d1 100644 --- a/core/src/mindustry/entities/effect/Fire.java +++ b/core/src/mindustry/entities/effect/Fire.java @@ -8,7 +8,6 @@ import arc.math.geom.*; import arc.util.*; import mindustry.content.*; import mindustry.entities.*; -import mindustry.entities.traits.*; import mindustry.entities.type.*; import mindustry.game.EventType.*; import mindustry.game.*; diff --git a/core/src/mindustry/entities/effect/GroundEffectEntity.java b/core/src/mindustry/entities/effect/GroundEffectEntity.java index 644757512c..22568f70a2 100644 --- a/core/src/mindustry/entities/effect/GroundEffectEntity.java +++ b/core/src/mindustry/entities/effect/GroundEffectEntity.java @@ -6,7 +6,6 @@ import mindustry.Vars; import mindustry.entities.Effects; import mindustry.entities.Effects.Effect; import mindustry.entities.Effects.EffectRenderer; -import mindustry.entities.type.EffectEntity; import mindustry.world.Tile; /** diff --git a/core/src/mindustry/entities/effect/ItemTransfer.java b/core/src/mindustry/entities/effect/ItemTransfer.java index cacb8e267e..85beec2b3e 100644 --- a/core/src/mindustry/entities/effect/ItemTransfer.java +++ b/core/src/mindustry/entities/effect/ItemTransfer.java @@ -1,22 +1,19 @@ package mindustry.entities.effect; -import mindustry.annotations.Annotations.Loc; -import mindustry.annotations.Annotations.Remote; import arc.graphics.g2d.*; -import arc.math.Interpolation; -import arc.math.Mathf; -import arc.math.geom.Position; -import arc.math.geom.Vec2; -import arc.util.Time; -import arc.util.pooling.Pools; +import arc.math.*; +import arc.math.geom.*; +import arc.util.*; +import arc.util.pooling.*; +import mindustry.annotations.Annotations.*; import mindustry.entities.*; -import mindustry.entities.type.TimedEntity; -import mindustry.entities.type.Unit; -import mindustry.graphics.Pal; -import mindustry.type.Item; -import mindustry.world.Tile; +import mindustry.entities.type.*; +import mindustry.gen.*; +import mindustry.graphics.*; +import mindustry.type.*; +import mindustry.world.*; -import static mindustry.Vars.*; +import static mindustry.Vars.effectGroup; public class ItemTransfer extends TimedEntity implements DrawTrait{ private Vec2 from = new Vec2(); @@ -31,14 +28,14 @@ public class ItemTransfer extends TimedEntity implements DrawTrait{ } @Remote(called = Loc.server, unreliable = true) - public static void transferItemEffect(Item item, float x, float y, Unit to){ + public static void transferItemEffect(Item item, float x, float y, Itemsc to){ if(to == null) return; create(item, x, y, to, () -> { }); } @Remote(called = Loc.server, unreliable = true) - public static void transferItemToUnit(Item item, float x, float y, Unit to){ + public static void transferItemToUnit(Item item, float x, float y, Itemsc to){ if(to == null) return; create(item, x, y, to, () -> to.addItem(item)); } diff --git a/core/src/mindustry/entities/effect/Lightning.java b/core/src/mindustry/entities/effect/Lightning.java index 9a1e51d0a3..78447a9f1a 100644 --- a/core/src/mindustry/entities/effect/Lightning.java +++ b/core/src/mindustry/entities/effect/Lightning.java @@ -13,8 +13,6 @@ import mindustry.content.Bullets; import mindustry.entities.EntityGroup; import mindustry.entities.Units; import mindustry.entities.type.Bullet; -import mindustry.entities.type.TimedEntity; -import mindustry.entities.type.Unit; import mindustry.game.Team; import mindustry.gen.Call; import mindustry.graphics.Pal; @@ -27,7 +25,7 @@ public class Lightning extends TimedEntity implements DrawTrait, TimeTrait{ private static final Rand random = new Rand(); private static final Rect rect = new Rect(); - private static final Array entities = new Array<>(); + private static final Array entities = new Array<>(); private static final IntSet hit = new IntSet(); private static final int maxChain = 8; private static final float hitRange = 30f; @@ -98,7 +96,7 @@ public class Lightning extends TimedEntity implements DrawTrait, TimeTrait{ }); } - Unit furthest = Geometry.findFurthest(x, y, entities); + Unitc furthest = Geometry.findFurthest(x, y, entities); if(furthest != null){ hit.add(furthest.getID()); diff --git a/core/src/mindustry/entities/effect/Puddle.java b/core/src/mindustry/entities/effect/Puddle.java index 5740d0451a..ac1b68f0b3 100644 --- a/core/src/mindustry/entities/effect/Puddle.java +++ b/core/src/mindustry/entities/effect/Puddle.java @@ -11,8 +11,6 @@ import arc.util.pooling.Pool.*; import arc.util.pooling.*; import mindustry.content.*; import mindustry.entities.*; -import mindustry.entities.traits.*; -import mindustry.entities.type.*; import mindustry.game.*; import mindustry.gen.*; import mindustry.type.*; diff --git a/core/src/mindustry/entities/traits/BuilderTrait.java b/core/src/mindustry/entities/traits/BuilderTrait.java deleted file mode 100644 index 188c39f776..0000000000 --- a/core/src/mindustry/entities/traits/BuilderTrait.java +++ /dev/null @@ -1,285 +0,0 @@ -package mindustry.entities.traits; - -import arc.*; -import arc.struct.Queue; -import arc.graphics.g2d.*; -import arc.math.*; -import arc.math.geom.*; -import arc.util.ArcAnnotate.*; -import arc.util.*; -import mindustry.*; -import mindustry.content.*; -import mindustry.entities.type.*; -import mindustry.entities.units.*; -import mindustry.game.EventType.*; -import mindustry.gen.*; -import mindustry.graphics.*; -import mindustry.world.*; -import mindustry.world.blocks.*; -import mindustry.world.blocks.BuildBlock.*; - -import java.io.*; -import java.util.*; - -import static mindustry.Vars.*; -import static mindustry.entities.traits.BuilderTrait.BuildDataStatic.*; - -/** Interface for units that build things.*/ -public interface BuilderTrait extends Entity, TeamTrait{ - //these are not instance variables! - float placeDistance = 220f; - float mineDistance = 70f; - - /** Updates building mechanism for this unit.*/ - default void updateBuilding(){ - float finalPlaceDst = state.rules.infiniteResources ? Float.MAX_VALUE : placeDistance; - Unit unit = (Unit)this; - - Iterator it = buildQueue().iterator(); - while(it.hasNext()){ - BuildRequest req = it.next(); - Tile tile = world.tile(req.x, req.y); - if(tile == null || (req.breaking && tile.block() == Blocks.air) || (!req.breaking && (tile.rotation() == req.rotation || !req.block.rotate) && tile.block() == req.block)){ - it.remove(); - } - } - - TileEntity core = unit.getClosestCore(); - - //nothing to build. - if(buildRequest() == null) return; - - //find the next build request - if(buildQueue().size > 1){ - int total = 0; - BuildRequest req; - while((dst((req = buildRequest()).tile()) > finalPlaceDst || shouldSkip(req, core)) && total < buildQueue().size){ - buildQueue().removeFirst(); - buildQueue().addLast(req); - total++; - } - } - - BuildRequest current = buildRequest(); - - if(dst(current.tile()) > finalPlaceDst) return; - - Tile tile = world.tile(current.x, current.y); - - if(!(tile.block() instanceof BuildBlock)){ - if(!current.initialized && canCreateBlocks() && !current.breaking && Build.validPlace(getTeam(), current.x, current.y, current.block, current.rotation)){ - Build.beginPlace(getTeam(), current.x, current.y, current.block, current.rotation); - }else if(!current.initialized && canCreateBlocks() && current.breaking && Build.validBreak(getTeam(), current.x, current.y)){ - Build.beginBreak(getTeam(), current.x, current.y); - }else{ - buildQueue().removeFirst(); - return; - } - } - - if(tile.entity instanceof BuildEntity && !current.initialized){ - Core.app.post(() -> Events.fire(new BuildSelectEvent(tile, unit.getTeam(), this, current.breaking))); - current.initialized = true; - } - - //if there is no core to build with or no build entity, stop building! - if((core == null && !state.rules.infiniteResources) || !(tile.entity instanceof BuildEntity)){ - return; - } - - //otherwise, update it. - BuildEntity entity = tile.ent(); - - if(entity == null){ - return; - } - - if(unit.dst(tile) <= finalPlaceDst){ - unit.rotation = Mathf.slerpDelta(unit.rotation, unit.angleTo(entity), 0.4f); - } - - if(current.breaking){ - entity.deconstruct(unit, core, 1f / entity.buildCost * Time.delta() * getBuildPower(tile) * state.rules.buildSpeedMultiplier); - }else{ - if(entity.construct(unit, core, 1f / entity.buildCost * Time.delta() * getBuildPower(tile) * state.rules.buildSpeedMultiplier, current.hasConfig)){ - if(current.hasConfig){ - Call.onTileConfig(null, tile, current.config); - } - } - } - - current.stuck = Mathf.equal(current.progress, entity.progress); - current.progress = entity.progress; - } - - /** @return whether this request should be skipped, in favor of the next one. */ - default boolean shouldSkip(BuildRequest request, @Nullable TileEntity core){ - //requests that you have at least *started* are considered - if(state.rules.infiniteResources || request.breaking || !request.initialized || core == null) return false; - return request.stuck && !core.items.has(request.block.requirements); - } - - default void removeRequest(int x, int y, boolean breaking){ - //remove matching request - int idx = player.buildQueue().indexOf(req -> req.breaking == breaking && req.x == x && req.y == y); - if(idx != -1){ - player.buildQueue().removeIndex(idx); - } - } - - /** Returns the queue for storing build requests. */ - Queue buildQueue(); - - /** Build power, can be any float. 1 = builds recipes in normal time, 0 = doesn't build at all. */ - float getBuildPower(Tile tile); - - /** Whether this type of builder can begin creating new blocks. */ - default boolean canCreateBlocks(){ - return true; - } - - default void writeBuilding(DataOutput output) throws IOException{ - BuildRequest request = buildRequest(); - - if(request != null && (request.block != null || request.breaking)){ - output.writeByte(request.breaking ? 1 : 0); - output.writeInt(Pos.get(request.x, request.y)); - output.writeFloat(request.progress); - if(!request.breaking){ - output.writeShort(request.block.id); - output.writeByte(request.rotation); - } - }else{ - output.writeByte(-1); - } - } - - default void readBuilding(DataInput input) throws IOException{ - readBuilding(input, true); - } - - default void readBuilding(DataInput input, boolean applyChanges) throws IOException{ - if(applyChanges) buildQueue().clear(); - - byte type = input.readByte(); - if(type != -1){ - int position = input.readInt(); - float progress = input.readFloat(); - BuildRequest request; - - if(type == 1){ //remove - request = new BuildRequest(Pos.x(position), Pos.y(position)); - }else{ //place - short block = input.readShort(); - byte rotation = input.readByte(); - request = new BuildRequest(Pos.x(position), Pos.y(position), rotation, content.block(block)); - } - - request.progress = progress; - - if(applyChanges){ - buildQueue().addLast(request); - }else if(isBuilding()){ - BuildRequest last = buildRequest(); - last.progress = progress; - if(last.tile() != null && last.tile().entity instanceof BuildEntity){ - ((BuildEntity)last.tile().entity).progress = progress; - } - } - } - } - - /** Return whether this builder's place queue contains items. */ - default boolean isBuilding(){ - return buildQueue().size != 0; - } - - /** Clears the placement queue. */ - default void clearBuilding(){ - buildQueue().clear(); - } - - /** Add another build requests to the tail of the queue, if it doesn't exist there yet. */ - default void addBuildRequest(BuildRequest place){ - addBuildRequest(place, true); - } - - /** Add another build requests to the queue, if it doesn't exist there yet. */ - default void addBuildRequest(BuildRequest place, boolean tail){ - BuildRequest replace = null; - for(BuildRequest request : buildQueue()){ - if(request.x == place.x && request.y == place.y){ - replace = request; - break; - } - } - if(replace != null){ - buildQueue().remove(replace); - } - Tile tile = world.tile(place.x, place.y); - if(tile != null && tile.entity instanceof BuildEntity){ - place.progress = tile.ent().progress; - } - if(tail){ - buildQueue().addLast(place); - }else{ - buildQueue().addFirst(place); - } - } - - /** - * Return the build requests currently active, or the one at the top of the queue. - * May return null. - */ - default @Nullable - BuildRequest buildRequest(){ - return buildQueue().size == 0 ? null : buildQueue().first(); - } - - //due to iOS weirdness, this is apparently required - class BuildDataStatic{ - static Vec2[] tmptr = new Vec2[]{new Vec2(), new Vec2(), new Vec2(), new Vec2()}; - } - - /** Draw placement effects for an entity. */ - default void drawBuilding(){ - if(!isBuilding()) return; - - Unit unit = (Unit)this; - BuildRequest request = buildRequest(); - Tile tile = world.tile(request.x, request.y); - - if(dst(tile) > placeDistance && !state.isEditor()){ - return; - } - - Lines.stroke(1f, Pal.accent); - float focusLen = 3.8f + Mathf.absin(Time.time(), 1.1f, 0.6f); - float px = unit.x + Angles.trnsx(unit.rotation, focusLen); - float py = unit.y + Angles.trnsy(unit.rotation, focusLen); - - float sz = Vars.tilesize * tile.block().size / 2f; - float ang = unit.angleTo(tile); - - tmptr[0].set(tile.drawx() - sz, tile.drawy() - sz); - tmptr[1].set(tile.drawx() + sz, tile.drawy() - sz); - tmptr[2].set(tile.drawx() - sz, tile.drawy() + sz); - tmptr[3].set(tile.drawx() + sz, tile.drawy() + sz); - - Arrays.sort(tmptr, (a, b) -> -Float.compare(Angles.angleDist(Angles.angle(unit.x, unit.y, a.x, a.y), ang), - Angles.angleDist(Angles.angle(unit.x, unit.y, b.x, b.y), ang))); - - float x1 = tmptr[0].x, y1 = tmptr[0].y, - x3 = tmptr[1].x, y3 = tmptr[1].y; - - Draw.alpha(1f); - - Lines.line(px, py, x1, y1); - Lines.line(px, py, x3, y3); - - Fill.circle(px, py, 1.6f + Mathf.absin(Time.time(), 0.8f, 1.5f)); - - Draw.color(); - } - -} diff --git a/core/src/mindustry/entities/traits/MinerTrait.java b/core/src/mindustry/entities/traits/MinerTrait.java deleted file mode 100644 index 5b3d51c21d..0000000000 --- a/core/src/mindustry/entities/traits/MinerTrait.java +++ /dev/null @@ -1,119 +0,0 @@ -package mindustry.entities.traits; - -import arc.Core; -import arc.graphics.Color; -import arc.graphics.g2d.*; -import arc.math.*; -import arc.util.Time; -import mindustry.content.*; -import mindustry.entities.Effects; -import mindustry.entities.effect.*; -import mindustry.entities.type.*; -import mindustry.gen.Call; -import mindustry.graphics.*; -import mindustry.type.Item; -import mindustry.world.Tile; - -import static mindustry.Vars.*; - -public interface MinerTrait extends Entity{ - - /** Returns the range at which this miner can mine blocks.*/ - default float getMiningRange(){ - return 70f; - } - - default boolean isMining(){ - return getMineTile() != null; - } - - /** Returns the tile this builder is currently mining. */ - Tile getMineTile(); - - /** Sets the tile this builder is currently mining. */ - void setMineTile(Tile tile); - - /** Returns the mining speed of this miner. 1 = standard, 0.5 = half speed, 2 = double speed, etc. */ - float getMinePower(); - - /** Returns whether or not this builder can mine a specific item type. */ - boolean canMine(Item item); - - /** @return whether to offload mined items immediately at the core. if false, items are collected and dropped in a burst. */ - default boolean offloadImmediately(){ - return false; - } - - default void updateMining(){ - Unit unit = (Unit)this; - Tile tile = getMineTile(); - TileEntity core = unit.getClosestCore(); - - if(core != null && tile != null && tile.drop() != null && !unit.acceptsItem(tile.drop()) && unit.dst(core) < mineTransferRange){ - int accepted = core.tile.block().acceptStack(unit.item().item, unit.item().amount, core.tile, unit); - if(accepted > 0){ - Call.transferItemTo(unit.item().item, accepted, - tile.worldx() + Mathf.range(tilesize / 2f), - tile.worldy() + Mathf.range(tilesize / 2f), core.tile); - unit.clearItem(); - } - } - - if(tile == null || core == null || tile.block() != Blocks.air || dst(tile.worldx(), tile.worldy()) > getMiningRange() - || tile.drop() == null || !unit.acceptsItem(tile.drop()) || !canMine(tile.drop())){ - setMineTile(null); - }else{ - Item item = tile.drop(); - unit.rotation = Mathf.slerpDelta(unit.rotation, unit.angleTo(tile.worldx(), tile.worldy()), 0.4f); - - if(Mathf.chance(Time.delta() * (0.06 - item.hardness * 0.01) * getMinePower())){ - - if(unit.dst(core) < mineTransferRange && core.tile.block().acceptStack(item, 1, core.tile, unit) == 1 && offloadImmediately()){ - Call.transferItemTo(item, 1, - tile.worldx() + Mathf.range(tilesize / 2f), - tile.worldy() + Mathf.range(tilesize / 2f), core.tile); - }else if(unit.acceptsItem(item)){ - //this is clientside, since items are synced anyway - ItemTransfer.transferItemToUnit(item, - tile.worldx() + Mathf.range(tilesize / 2f), - tile.worldy() + Mathf.range(tilesize / 2f), - unit); - } - } - - if(Mathf.chance(0.06 * Time.delta())){ - Effects.effect(Fx.pulverizeSmall, - tile.worldx() + Mathf.range(tilesize / 2f), - tile.worldy() + Mathf.range(tilesize / 2f), 0f, item.color); - } - } - } - - default void drawMining(){ - Unit unit = (Unit)this; - Tile tile = getMineTile(); - - if(tile == null) return; - - float focusLen = 4f + Mathf.absin(Time.time(), 1.1f, 0.5f); - float swingScl = 12f, swingMag = tilesize / 8f; - float flashScl = 0.3f; - - float px = unit.x + Angles.trnsx(unit.rotation, focusLen); - float py = unit.y + Angles.trnsy(unit.rotation, focusLen); - - float ex = tile.worldx() + Mathf.sin(Time.time() + 48, swingScl, swingMag); - float ey = tile.worldy() + Mathf.sin(Time.time() + 48, swingScl + 2f, swingMag); - - Draw.color(Color.lightGray, Color.white, 1f - flashScl + Mathf.absin(Time.time(), 0.5f, flashScl)); - - Drawf.laser(Core.atlas.find("minelaser"), Core.atlas.find("minelaser-end"), px, py, ex, ey, 0.75f); - - if(unit instanceof Player && ((Player)unit).isLocal){ - Lines.stroke(1f, Pal.accent); - Lines.poly(tile.worldx(), tile.worldy(), 4, tilesize / 2f * Mathf.sqrt2, Time.time()); - } - - Draw.color(); - } -} diff --git a/core/src/mindustry/entities/traits/SaveTrait.java b/core/src/mindustry/entities/traits/SaveTrait.java deleted file mode 100644 index ee051dcd15..0000000000 --- a/core/src/mindustry/entities/traits/SaveTrait.java +++ /dev/null @@ -1,8 +0,0 @@ -package mindustry.entities.traits; - -/** - * Marks an entity as serializable. - */ -public interface SaveTrait extends Entity, TypeTrait, Saveable{ - byte version(); -} diff --git a/core/src/mindustry/entities/traits/SpawnerTrait.java b/core/src/mindustry/entities/traits/SpawnerTrait.java deleted file mode 100644 index 3eeee072e5..0000000000 --- a/core/src/mindustry/entities/traits/SpawnerTrait.java +++ /dev/null @@ -1,18 +0,0 @@ -package mindustry.entities.traits; - -import arc.math.geom.Position; -import mindustry.entities.type.*; -import mindustry.world.Tile; - -public interface SpawnerTrait extends TargetTrait, Position{ - Tile getTile(); - - void updateSpawning(Player unit); - - boolean hasUnit(Unit unit); - - @Override - default boolean isValid(){ - return getTile().entity instanceof SpawnerTrait; - } -} diff --git a/core/src/mindustry/entities/type/BaseEntity.java b/core/src/mindustry/entities/type/BaseEntity.java deleted file mode 100755 index 722804bd04..0000000000 --- a/core/src/mindustry/entities/type/BaseEntity.java +++ /dev/null @@ -1,65 +0,0 @@ -package mindustry.entities.type; - -import mindustry.entities.EntityGroup; - -public abstract class BaseEntity implements Entity{ - private static int lastid; - /** Do not modify. Used for network operations and mapping. */ - public int id; - public float x, y; - protected transient EntityGroup group; - - public BaseEntity(){ - id = lastid++; - } - - @Override - public int getID(){ - return id; - } - - @Override - public void resetID(int id){ - this.id = id; - } - - @Override - public EntityGroup getGroup(){ - return group; - } - - @Override - public void setGroup(EntityGroup group){ - this.group = group; - } - - @Override - public float getX(){ - return x; - } - - @Override - public void setX(float x){ - this.x = x; - } - - @Override - public float getY(){ - return y; - } - - @Override - public void setY(float y){ - this.y = y; - } - - @Override - public String toString(){ - return getClass() + " " + id; - } - - /** Increments this entity's ID. Used for pooled entities.*/ - public void incrementID(){ - id = lastid++; - } -} diff --git a/core/src/mindustry/entities/type/BaseUnit.java b/core/src/mindustry/entities/type/BaseUnit.java index e96dc64f4c..cc36369e95 100644 --- a/core/src/mindustry/entities/type/BaseUnit.java +++ b/core/src/mindustry/entities/type/BaseUnit.java @@ -11,7 +11,6 @@ import mindustry.*; import mindustry.content.*; import mindustry.ctype.ContentType; import mindustry.entities.*; -import mindustry.entities.traits.*; import mindustry.entities.units.*; import mindustry.game.EventType.*; import mindustry.game.*; @@ -31,7 +30,7 @@ import java.io.*; import static mindustry.Vars.*; /** Base class for AI units. */ -public abstract class BaseUnit extends Unit implements ShooterTrait{ +public abstract class BaseUnit extends Unitc implements ShooterTrait{ protected static int timerIndex = 0; protected static final int timerTarget = timerIndex++; @@ -151,7 +150,7 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{ } public void updateTargeting(){ - if(target == null || (target instanceof Unit && (target.isDead() || target.getTeam() == team)) + if(target == null || (target instanceof Unitc && (target.isDead() || target.getTeam() == team)) || (target instanceof TileEntity && ((TileEntity)target).tile.entity == null)){ target = null; } diff --git a/core/src/mindustry/entities/type/Bullet.java b/core/src/mindustry/entities/type/Bullet.java index 6d9a6eb12e..a4f6a2bfdf 100644 --- a/core/src/mindustry/entities/type/Bullet.java +++ b/core/src/mindustry/entities/type/Bullet.java @@ -9,7 +9,6 @@ import arc.util.pooling.*; import mindustry.entities.*; import mindustry.entities.bullet.*; import mindustry.entities.effect.*; -import mindustry.entities.traits.*; import mindustry.game.*; import mindustry.graphics.*; import mindustry.world.*; @@ -122,8 +121,8 @@ public class Bullet extends SolidEntity implements DamageTrait, Scaled, Poolable } public float damageMultiplier(){ - if(owner instanceof Unit){ - return ((Unit)owner).getDamageMultipler(); + if(owner instanceof Unitc){ + return ((Unitc)owner).getDamageMultipler(); } return 1f; } @@ -166,7 +165,7 @@ public class Bullet extends SolidEntity implements DamageTrait, Scaled, Poolable @Override public boolean collides(SolidTrait other){ - return type.collides && (other != owner && !(other instanceof DamageTrait)) && !supressCollision && !(other instanceof Unit && ((Unit)other).isFlying() && !type.collidesAir); + return type.collides && (other != owner && !(other instanceof DamageTrait)) && !supressCollision && !(other instanceof Unitc && ((Unitc)other).isFlying() && !type.collidesAir); } @Override @@ -174,8 +173,8 @@ public class Bullet extends SolidEntity implements DamageTrait, Scaled, Poolable if(!type.pierce) remove(); type.hit(this, x, y); - if(other instanceof Unit){ - Unit unit = (Unit)other; + if(other instanceof Unitc){ + Unitc unit = (Unitc)other; unit.velocity().add(Tmp.v3.set(other.getX(), other.getY()).sub(x, y).setLength(type.knockback / unit.mass())); unit.applyEffect(type.status, type.statusDuration); } diff --git a/core/src/mindustry/entities/type/EffectEntity.java b/core/src/mindustry/entities/type/EffectEntity.java deleted file mode 100644 index 7c3a196935..0000000000 --- a/core/src/mindustry/entities/type/EffectEntity.java +++ /dev/null @@ -1,79 +0,0 @@ -package mindustry.entities.type; - -import arc.graphics.*; -import arc.util.pooling.Pool.*; -import arc.util.pooling.*; -import mindustry.entities.*; -import mindustry.entities.Effects.*; -import mindustry.entities.traits.*; - -import static mindustry.Vars.effectGroup; - -public class EffectEntity extends TimedEntity implements Poolable, DrawTrait{ - public Effect effect; - public Color color = new Color(Color.white); - public Object data; - public float rotation = 0f; - - public Entity parent; - public float poffsetx, poffsety; - - /** For pooling use only! */ - public EffectEntity(){ - } - - public void setParent(Entity parent){ - this.parent = parent; - this.poffsetx = x - parent.getX(); - this.poffsety = y - parent.getY(); - } - - @Override - public EntityGroup targetGroup(){ - //this should never actually be called - return effectGroup; - } - - @Override - public float lifetime(){ - return effect.lifetime; - } - - @Override - public float drawSize(){ - return effect.size; - } - - @Override - public void update(){ - if(effect == null){ - remove(); - return; - } - - super.update(); - if(parent != null){ - x = parent.getX() + poffsetx; - y = parent.getY() + poffsety; - } - } - - @Override - public void reset(){ - effect = null; - color.set(Color.white); - rotation = time = poffsetx = poffsety = 0f; - parent = null; - data = null; - } - - @Override - public void draw(){ - Effects.renderEffect(id, effect, color, time, rotation, x, y, data); - } - - @Override - public void removed(){ - Pools.free(this); - } -} diff --git a/core/src/mindustry/entities/type/Player.java b/core/src/mindustry/entities/type/Player.java index c6fb99f31c..be335b3d9c 100644 --- a/core/src/mindustry/entities/type/Player.java +++ b/core/src/mindustry/entities/type/Player.java @@ -34,7 +34,7 @@ import java.io.*; import static mindustry.Vars.*; -public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{ +public class Player extends Unitc implements BuilderMinerTrait, ShooterTrait{ public static final int timerSync = 2; public static final int timerAbility = 3; private static final float liftoffBoost = 0.2f; diff --git a/core/src/mindustry/entities/type/TileEntity.java b/core/src/mindustry/entities/type/TileEntity.java index 63c1e2087e..32975e52de 100644 --- a/core/src/mindustry/entities/type/TileEntity.java +++ b/core/src/mindustry/entities/type/TileEntity.java @@ -21,7 +21,7 @@ import java.io.*; import static mindustry.Vars.*; -public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{ +public class TileEntity{ public static final float timeToSleep = 60f * 1; //1 second to fall asleep private static final ObjectSet tmpTiles = new ObjectSet<>(); /** This value is only used for debugging. */ @@ -112,10 +112,6 @@ public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{ } } - public boolean isSleeping(){ - return sleeping; - } - public boolean isDead(){ return dead || tile.entity != this; } @@ -256,26 +252,6 @@ public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{ } } - @Override - public void health(float health){ - this.health = health; - } - - @Override - public float health(){ - return health; - } - - @Override - public float maxHealth(){ - return block.health; - } - - @Override - public void setDead(boolean dead){ - this.dead = dead; - } - @Override public void onDeath(){ if(!dead){ @@ -289,16 +265,6 @@ public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{ } } - @Override - public Team getTeam(){ - return tile.getTeam(); - } - - @Override - public Vec2 velocity(){ - return Vec2.ZERO; - } - @Override public void update(){ timeScaleDuration -= Time.delta(); @@ -339,11 +305,6 @@ public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{ return !isDead() && tile.entity == this; } - @Override - public EntityGroup targetGroup(){ - return tileGroup; - } - @Override public String toString(){ return "TileEntity{" + diff --git a/core/src/mindustry/entities/type/TimedEntity.java b/core/src/mindustry/entities/type/TimedEntity.java deleted file mode 100644 index 17b688002d..0000000000 --- a/core/src/mindustry/entities/type/TimedEntity.java +++ /dev/null @@ -1,33 +0,0 @@ -package mindustry.entities.type; - -import arc.util.pooling.Pool.*; -import mindustry.entities.traits.*; - -public abstract class TimedEntity extends BaseEntity implements TimeTrait, Poolable{ - public float time; - - @Override - public void time(float time){ - this.time = time; - } - - @Override - public float time(){ - return time; - } - - @Override - public void update(){ - updateTime(); - } - - @Override - public void reset(){ - time = 0f; - } - - @Override - public float fin(){ - return time() / lifetime(); - } -} diff --git a/core/src/mindustry/entities/type/Unit.java b/core/src/mindustry/entities/type/Unit.java deleted file mode 100644 index 00648007bd..0000000000 --- a/core/src/mindustry/entities/type/Unit.java +++ /dev/null @@ -1,504 +0,0 @@ -package mindustry.entities.type; - -import arc.*; -import arc.graphics.*; -import arc.graphics.g2d.*; -import arc.math.*; -import arc.math.geom.*; -import arc.scene.ui.layout.*; -import arc.struct.*; -import arc.util.*; -import arc.util.ArcAnnotate.*; -import mindustry.content.*; -import mindustry.entities.*; -import mindustry.entities.effect.*; -import mindustry.entities.traits.*; -import mindustry.entities.units.*; -import mindustry.game.EventType.*; -import mindustry.game.*; -import mindustry.gen.*; -import mindustry.graphics.*; -import mindustry.net.*; -import mindustry.type.*; -import mindustry.ui.*; -import mindustry.world.*; -import mindustry.world.blocks.*; - -import java.io.*; - -import static mindustry.Vars.*; - -public abstract class Unit extends DestructibleEntity implements SaveTrait, TargetTrait, SyncTrait, DrawTrait, TeamTrait, ShooterTrait{ - /** Total duration of hit flash effect */ - public static final float hitDuration = 9f; - /** Percision divisor of velocity, used when writing. For example a value of '2' would mean the percision is 1/2 = 0.5-size chunks. */ - public static final float velocityPercision = 8f; - /** Maximum absolute value of a velocity vector component. */ - public static final float maxAbsVelocity = 127f / velocityPercision; - public static final int noSpawner = Pos.get(-1, 1); - - private static final Vec2 moveVector = new Vec2(); - - public float rotation; - - protected final Interpolator interpolator = new Interpolator(); - /** status effects */ - protected final Statuses status = new Statuses(); - /** current item held */ - protected final ItemStack item = new ItemStack(content.item(0), 0); - /** holds weapon aiming positions and angles */ - protected final Weapons weapons = new Weapons(); - - /** team; can be changed at any time */ - protected Team team = Team.sharded; - /** timers for drowning and getting hit */ - protected float drownTime, hitTime; - /** this unit's type; do not change internally without calling setType(...) */ - protected UnitDef type; - - public void setType(UnitDef type){ - this.type = type; - clampHealth(); - weapons.init(this); - } - - public UnitDef type(){ - return type; - } - - @Override - public boolean collidesGrid(int x, int y){ - return !isFlying(); - } - - @Override - public Team getTeam(){ - return team; - } - - @Override - public Weapons getWeapons(){ - return weapons; - } - - @Override - public void interpolate(){ - interpolator.update(); - - x = interpolator.pos.x; - y = interpolator.pos.y; - - if(interpolator.values.length > 0){ - rotation = interpolator.values[0]; - } - } - - @Override - public Interpolator getInterpolator(){ - return interpolator; - } - - @Override - public void damage(float amount){ - if(!net.client()){ - super.damage(calculateDamage(amount)); - } - hitTime = hitDuration; - } - - @Override - public boolean collides(SolidTrait other){ - if(isDead()) return false; - - if(other instanceof DamageTrait){ - return other instanceof TeamTrait && (((TeamTrait)other).getTeam()).isEnemy(team); - }else{ - return other instanceof Unit && ((Unit)other).isFlying() == isFlying(); - } - } - - @Override - public void onDeath(){ - float explosiveness = 2f + item.item.explosiveness * item.amount; - float flammability = item.item.flammability * item.amount; - Damage.dynamicExplosion(x, y, flammability, explosiveness, 0f, getSize() / 2f, Pal.darkFlame); - - ScorchDecal.create(x, y); - Fx.explosion.at(this); - Effects.shake(2f, 2f, this); - - Sounds.bang.at(this); - item.amount = 0; - drownTime = 0f; - status.clear(); - Events.fire(new UnitDestroyEvent(this)); - - if(explosiveness > 7f && this == player){ - Events.fire(Trigger.suicideBomb); - } - } - - @Override - public Vec2 velocity(){ - return velocity; - } - - @Override - public void move(float x, float y){ - if(!isFlying()){ - super.move(x, y); - }else{ - moveBy(x, y); - } - } - - @Override - public boolean isValid(){ - return !isDead() && isAdded(); - } - - @Override - public void hitbox(Rect rect){ - rect.setSize(type.hitsize).setCenter(x, y); - } - - @Override - public void hitboxTile(Rect rect){ - rect.setSize(type.hitsizeTile).setCenter(x, y); - } - - - @Override - public float drag(){ - return type.drag; - } - - @Override - public void writeSave(DataOutput stream) throws IOException{ - writeSave(stream, false); - } - - @Override - public void readSave(DataInput stream, byte version) throws IOException{ - byte team = stream.readByte(); - boolean dead = stream.readBoolean(); - float x = stream.readFloat(); - float y = stream.readFloat(); - byte xv = stream.readByte(); - byte yv = stream.readByte(); - float rotation = stream.readShort() / 2f; - int health = stream.readShort(); - byte itemID = stream.readByte(); - short itemAmount = stream.readShort(); - - this.status.readSave(stream, version); - this.item.amount = itemAmount; - this.item.item = content.item(itemID); - this.dead = dead; - this.team = Team.get(team); - this.health = health; - this.x = x; - this.y = y; - this.velocity.set(xv / velocityPercision, yv / velocityPercision); - this.rotation = rotation; - } - - public void writeSave(DataOutput stream, boolean net) throws IOException{ - if(item.item == null) item.item = Items.copper; - - stream.writeByte(team.id); - stream.writeBoolean(isDead()); - stream.writeFloat(net ? interpolator.target.x : x); - stream.writeFloat(net ? interpolator.target.y : y); - stream.writeByte((byte)(Mathf.clamp(velocity.x, -maxAbsVelocity, maxAbsVelocity) * velocityPercision)); - stream.writeByte((byte)(Mathf.clamp(velocity.y, -maxAbsVelocity, maxAbsVelocity) * velocityPercision)); - stream.writeShort((short)(rotation * 2)); - stream.writeShort((short)health); - stream.writeByte(item.item.id); - stream.writeShort((short)item.amount); - status.writeSave(stream); - } - - protected void clampPosition(){ - x = Mathf.clamp(x, 0, world.width() * tilesize - tilesize); - y = Mathf.clamp(y, 0, world.height() * tilesize - tilesize); - } - - public boolean isImmune(StatusEffect effect){ - return type.immunities.contains(effect); - } - - public boolean isOutOfBounds(){ - return x < -worldBounds || y < -worldBounds || x > world.width() * tilesize + worldBounds || y > world.height() * tilesize + worldBounds; - } - - public float calculateDamage(float amount){ - return amount * Mathf.clamp(1f - status.getArmorMultiplier() / 100f); - } - - public float getDamageMultipler(){ - return status.getDamageMultiplier(); - } - - public boolean hasEffect(StatusEffect effect){ - return status.hasEffect(effect); - } - - public void avoidOthers(){ - float radScl = 1.5f; - float fsize = getSize() / radScl; - moveVector.setZero(); - float cx = x - fsize/2f, cy = y - fsize/2f; - avoid(unitGroup.intersect(cx, cy, fsize, fsize)); - if(!(this instanceof Player)){ - avoid(playerGroup.intersect(cx, cy, fsize, fsize)); - } - velocity.add(moveVector.x / mass() * Time.delta(), moveVector.y / mass() * Time.delta()); - } - - private void avoid(Array arr){ - float radScl = 1.5f; - - for(Unit en : arr){ - if(en.isFlying() != isFlying() || (en instanceof Player && en.getTeam() != getTeam()) || (this instanceof Player && en.isFlying())) continue; - float dst = dst(en); - float scl = Mathf.clamp(1f - dst / (getSize()/(radScl*2f) + en.getSize()/(radScl*2f))); - moveVector.add(Tmp.v1.set((x - en.x) * scl, (y - en.y) * scl).limit(0.4f)); - } - } - - public @Nullable TileEntity getClosestCore(){ - return state.teams.closestCore(x, y, team); - } - - public Floor getFloorOn(){ - Tile tile = world.tileWorld(x, y); - return tile == null ? (Floor)Blocks.air : tile.floor(); - } - - public @Nullable Tile tileOn(){ - return world.tileWorld(x, y); - } - - public void onRespawn(Tile tile){ - } - - /** Updates velocity and status effects. */ - public void updateVelocityStatus(){ - Floor floor = getFloorOn(); - - Tile tile = world.tileWorld(x, y); - - status.update(this); - item.amount = Mathf.clamp(this.item.amount, 0, getItemCapacity()); - - //velocity.limit(maxVelocity()).scl(1f + (status.getSpeedMultiplier() - 1f) * Time.delta()); - - if(x < -finalWorldBounds || y < -finalWorldBounds || x >= world.width() * tilesize + finalWorldBounds || y >= world.height() * tilesize + finalWorldBounds){ - kill(); - } - - //apply knockback based on spawns - if(getTeam() != state.rules.waveTeam){ - float relativeSize = state.rules.dropZoneRadius + getSize()/2f + 1f; - for(Tile spawn : spawner.getGroundSpawns()){ - if(withinDst(spawn.worldx(), spawn.worldy(), relativeSize)){ - velocity.add(Tmp.v1.set(this).sub(spawn.worldx(), spawn.worldy()).setLength(0.1f + 1f - dst(spawn) / relativeSize).scl(0.45f * Time.delta())); - } - } - } - - //repel player out of bounds - final float warpDst = 180f; - - if(x < 0) velocity.x += (-x/warpDst); - if(y < 0) velocity.y += (-y/warpDst); - if(x > world.unitWidth()) velocity.x -= (x - world.unitWidth())/warpDst; - if(y > world.unitHeight()) velocity.y -= (y - world.unitHeight())/warpDst; - - if(isFlying()){ - drownTime = 0f; - move(velocity.x * Time.delta(), velocity.y * Time.delta()); - }else{ - boolean onLiquid = floor.isLiquid; - - if(tile != null){ - tile.block().unitOn(tile, this); - if(tile.block() != Blocks.air){ - onLiquid = false; - } - } - - if(onLiquid && velocity.len() > 0.4f && Mathf.chance((velocity.len() * floor.speedMultiplier) * 0.06f * Time.delta())){ - floor.walkEffect.at(floor.color, x, y); - } - - if(onLiquid){ - status.handleApply(this, floor.status, floor.statusDuration); - - if(floor.damageTaken > 0f){ - damagePeriodic(floor.damageTaken); - } - } - - if(onLiquid && floor.drownTime > 0){ - drownTime += Time.delta() * 1f / floor.drownTime; - if(Mathf.chance(Time.delta() * 0.05f)){ - floor.drownUpdateEffect.at(floor.color, x, y); - } - }else{ - drownTime = Mathf.lerpDelta(drownTime, 0f, 0.03f); - } - - drownTime = Mathf.clamp(drownTime); - - if(drownTime >= 0.999f && !net.client()){ - damage(health + 1); - if(this == player){ - Events.fire(Trigger.drown); - } - } - - float px = x, py = y; - move(velocity.x * floor.speedMultiplier * Time.delta(), velocity.y * floor.speedMultiplier * Time.delta()); - if(Math.abs(px - x) <= 0.0001f) velocity.x = 0f; - if(Math.abs(py - y) <= 0.0001f) velocity.y = 0f; - } - - //velocity.scl(Mathf.clamp(1f - drag() * (isFlying() ? 1f : floor.dragMultiplier) * Time.delta())); - } - - public boolean acceptsItem(Item item){ - return this.item.amount <= 0 || (this.item.item == item && this.item.amount <= getItemCapacity()); - } - - public void addItem(Item item){ - addItem(item, 1); - } - - public void addItem(Item item, int amount){ - this.item.amount = this.item.item == item ? this.item.amount + amount : amount; - this.item.item = item; - this.item.amount = Mathf.clamp(this.item.amount, 0, getItemCapacity()); - } - - public void clearItem(){ - item.amount = 0; - } - - public ItemStack item(){ - return item; - } - - public int maxAccepted(Item item){ - return this.item.item != item && this.item.amount > 0 ? 0 : getItemCapacity() - this.item.amount; - } - - public void applyEffect(StatusEffect effect, float duration){ - if(dead || net.client()) return; //effects are synced and thus not applied through clients - status.handleApply(this, effect, duration); - } - - public void damagePeriodic(float amount){ - damage(amount * Time.delta(), hitTime <= -20 + hitDuration); - } - - public void damage(float amount, boolean withEffect){ - float pre = hitTime; - - damage(amount); - - if(!withEffect){ - hitTime = pre; - } - } - - public void drawUnder(){ - } - - public void drawOver(){ - } - - public void drawStats(){ - Draw.color(Color.black, team.color, healthf() + Mathf.absin(Time.time(), Math.max(healthf() * 5f, 1f), 1f - healthf())); - Draw.rect(getPowerCellRegion(), x, y, rotation - 90); - Draw.color(); - - drawBackItems(item.amount > 0 ? 1f : 0f, false); - - drawLight(); - } - - public void drawLight(){ - if(type.lightRadius > 0){ - renderer.lights.add(x, y, type.lightRadius, type.lightColor, 0.6f); - } - } - - public void drawBackItems(float itemtime, boolean number){ - //draw back items - if(itemtime > 0.01f && item.item != null){ - float backTrns = 5f; - float size = (itemSize + Mathf.absin(Time.time(), 5f, 1f)) * itemtime; - - Draw.mixcol(Pal.accent, Mathf.absin(Time.time(), 5f, 0.5f)); - Draw.rect(item.item.icon(Cicon.medium), - x + Angles.trnsx(rotation + 180f, backTrns), - y + Angles.trnsy(rotation + 180f, backTrns), - size, size, rotation); - - Draw.mixcol(); - - Lines.stroke(1f, Pal.accent); - Lines.circle( - x + Angles.trnsx(rotation + 180f, backTrns), - y + Angles.trnsy(rotation + 180f, backTrns), - (3f + Mathf.absin(Time.time(), 5f, 1f)) * itemtime); - - if(number){ - Fonts.outline.draw(item.amount + "", - x + Angles.trnsx(rotation + 180f, backTrns), - y + Angles.trnsy(rotation + 180f, backTrns) - 3, - Pal.accent, 0.25f * itemtime / Scl.scl(1f), false, Align.center - ); - } - } - - Draw.reset(); - } - - public TextureRegion getPowerCellRegion(){ - return Core.atlas.find("power-cell"); - } - - public void drawAll(){ - if(!isDead()){ - draw(); - drawStats(); - } - } - - public void drawShadow(float offsetX, float offsetY){ - Draw.rect(getIconRegion(), x + offsetX, y + offsetY, rotation - 90); - } - - public float getSize(){ - hitbox(Tmp.r1); - return Math.max(Tmp.r1.width, Tmp.r1.height) * 2f; - } - - public abstract TextureRegion getIconRegion(); - - public final int getItemCapacity(){ - return type.itemCapacity; - } - - @Override - public float mass(){ - return type.mass; - } - - public boolean isFlying(){ - return type.flying; - } -} diff --git a/core/src/mindustry/entities/type/base/MinerDrone.java b/core/src/mindustry/entities/type/base/MinerDrone.java index 5c10983577..cfa9ea16c8 100644 --- a/core/src/mindustry/entities/type/base/MinerDrone.java +++ b/core/src/mindustry/entities/type/base/MinerDrone.java @@ -3,7 +3,6 @@ package mindustry.entities.type.base; import arc.math.Mathf; import arc.util.Structs; import mindustry.content.Blocks; -import mindustry.entities.traits.MinerTrait; import mindustry.entities.type.TileEntity; import mindustry.entities.units.UnitState; import mindustry.gen.Call; diff --git a/core/src/mindustry/entities/units/Statuses.java b/core/src/mindustry/entities/units/Statuses.java index 7fd37abe5b..2af3575184 100644 --- a/core/src/mindustry/entities/units/Statuses.java +++ b/core/src/mindustry/entities/units/Statuses.java @@ -7,8 +7,7 @@ import arc.util.*; import arc.util.pooling.*; import mindustry.content.*; import mindustry.ctype.ContentType; -import mindustry.entities.traits.*; -import mindustry.entities.type.*; +import mindustry.entities.*; import mindustry.type.*; import java.io.*; @@ -27,7 +26,7 @@ public class Statuses implements Saveable{ private float damageMultiplier; private float armorMultiplier; - public void handleApply(Unit unit, StatusEffect effect, float duration){ + public void handleApply(Unitc unit, StatusEffect effect, float duration){ if(effect == StatusEffects.none || effect == null || unit.isImmune(effect)) return; //don't apply empty or immune effects if(statuses.size > 0){ @@ -76,7 +75,7 @@ public class Statuses implements Saveable{ statuses.clear(); } - public void update(Unit unit){ + public void update(Unitc unit){ applied.clear(); speedMultiplier = damageMultiplier = armorMultiplier = 1f; diff --git a/core/src/mindustry/entities/units/UnitController.java b/core/src/mindustry/entities/units/UnitController.java new file mode 100644 index 0000000000..c41aca463f --- /dev/null +++ b/core/src/mindustry/entities/units/UnitController.java @@ -0,0 +1,5 @@ +package mindustry.entities.units; + +//TODO rename +public class UnitController{ +} diff --git a/core/src/mindustry/game/EventType.java b/core/src/mindustry/game/EventType.java index 9eed10da2e..e2518d7e0c 100644 --- a/core/src/mindustry/game/EventType.java +++ b/core/src/mindustry/game/EventType.java @@ -1,13 +1,13 @@ package mindustry.game; import arc.util.ArcAnnotate.*; -import mindustry.core.GameState.State; -import mindustry.ctype.UnlockableContent; -import mindustry.entities.traits.BuilderTrait; +import mindustry.core.GameState.*; +import mindustry.ctype.*; import mindustry.entities.type.*; import mindustry.entities.units.*; +import mindustry.gen.*; import mindustry.type.*; -import mindustry.world.Tile; +import mindustry.world.*; public class EventType{ @@ -280,10 +280,10 @@ public class EventType{ public static class BuildSelectEvent{ public final Tile tile; public final Team team; - public final BuilderTrait builder; + public final Builderc builder; public final boolean breaking; - public BuildSelectEvent(Tile tile, Team team, BuilderTrait builder, boolean breaking){ + public BuildSelectEvent(Tile tile, Team team, Builderc builder, boolean breaking){ this.tile = tile; this.team = team; this.builder = builder; @@ -302,17 +302,17 @@ public class EventType{ } public static class UnitDestroyEvent{ - public final Unit unit; + public final Unitc unit; - public UnitDestroyEvent(Unit unit){ + public UnitDestroyEvent(Unitc unit){ this.unit = unit; } } public static class UnitCreateEvent{ - public final BaseUnit unit; + public final Unitc unit; - public UnitCreateEvent(BaseUnit unit){ + public UnitCreateEvent(Unitc unit){ this.unit = unit; } } diff --git a/core/src/mindustry/graphics/MinimapRenderer.java b/core/src/mindustry/graphics/MinimapRenderer.java index c34bb246ec..2773042d78 100644 --- a/core/src/mindustry/graphics/MinimapRenderer.java +++ b/core/src/mindustry/graphics/MinimapRenderer.java @@ -22,7 +22,7 @@ import static mindustry.Vars.*; public class MinimapRenderer implements Disposable{ private static final float baseSize = 16f; - private final Array units = new Array<>(); + private final Array units = new Array<>(); private Pixmap pixmap; private Texture texture; private TextureRegion region; @@ -87,7 +87,7 @@ public class MinimapRenderer implements Disposable{ rect.set((dx - sz) * tilesize, (dy - sz) * tilesize, sz * 2 * tilesize, sz * 2 * tilesize); - for(Unit unit : units){ + for(Unitc unit : units){ if(unit.isDead()) continue; float rx = !withLabels ? (unit.x - rect.x) / rect.width * w : unit.x / (world.width() * tilesize) * w; float ry = !withLabels ? (unit.y - rect.y) / rect.width * h : unit.y / (world.height() * tilesize) * h; diff --git a/core/src/mindustry/input/MobileInput.java b/core/src/mindustry/input/MobileInput.java index 6d761d5f70..a332454f3e 100644 --- a/core/src/mindustry/input/MobileInput.java +++ b/core/src/mindustry/input/MobileInput.java @@ -16,7 +16,6 @@ import mindustry.*; import mindustry.content.*; import mindustry.core.GameState.*; import mindustry.entities.*; -import mindustry.entities.traits.*; import mindustry.entities.type.*; import mindustry.entities.units.*; import mindustry.game.EventType.*; @@ -69,7 +68,7 @@ public class MobileInput extends InputHandler implements GestureListener{ /** Check and assign targets for a specific position. */ void checkTargets(float x, float y){ - Unit unit = Units.closestEnemy(player.getTeam(), x, y, 20f, u -> !u.isDead()); + Unitc unit = Units.closestEnemy(player.getTeam(), x, y, 20f, u -> !u.isDead()); if(unit != null){ player.setMineTile(null); diff --git a/core/src/mindustry/io/SaveVersion.java b/core/src/mindustry/io/SaveVersion.java index 06c75bc878..3b5c88fcba 100644 --- a/core/src/mindustry/io/SaveVersion.java +++ b/core/src/mindustry/io/SaveVersion.java @@ -8,7 +8,6 @@ import mindustry.core.*; import mindustry.ctype.*; import mindustry.ctype.ContentType; import mindustry.entities.*; -import mindustry.entities.traits.*; import mindustry.game.*; import mindustry.game.Teams.*; import mindustry.maps.*; diff --git a/core/src/mindustry/io/TypeIO.java b/core/src/mindustry/io/TypeIO.java index 841aa238b8..dd27139ffb 100644 --- a/core/src/mindustry/io/TypeIO.java +++ b/core/src/mindustry/io/TypeIO.java @@ -42,8 +42,8 @@ public class TypeIO{ return id == -1 ? null : playerGroup.getByID(id); } - @WriteClass(Unit.class) - public static void writeUnit(ByteBuffer buffer, Unit unit){ + @WriteClass(Unitc.class) + public static void writeUnit(ByteBuffer buffer, Unitc unit){ if(unit.getGroup() == null){ buffer.put((byte)-1); return; @@ -52,12 +52,12 @@ public class TypeIO{ buffer.putInt(unit.getID()); } - @ReadClass(Unit.class) - public static Unit readUnit(ByteBuffer buffer){ + @ReadClass(Unitc.class) + public static Unitc readUnit(ByteBuffer buffer){ byte gid = buffer.get(); if(gid == -1) return null; int id = buffer.getInt(); - return (Unit)entities.get(gid).getByID(id); + return (Unitc)entities.get(gid).getByID(id); } @WriteClass(ShooterTrait.class) diff --git a/core/src/mindustry/io/versions/Save1.java b/core/src/mindustry/io/versions/Save1.java index 446fe8e80b..a10911396f 100644 --- a/core/src/mindustry/io/versions/Save1.java +++ b/core/src/mindustry/io/versions/Save1.java @@ -1,7 +1,7 @@ package mindustry.io.versions; import arc.func.*; -import mindustry.entities.traits.*; +import mindustry.entities.*; import java.io.*; diff --git a/core/src/mindustry/io/versions/Save2.java b/core/src/mindustry/io/versions/Save2.java index 497289ed71..e50d6ae481 100644 --- a/core/src/mindustry/io/versions/Save2.java +++ b/core/src/mindustry/io/versions/Save2.java @@ -1,7 +1,7 @@ package mindustry.io.versions; import mindustry.ctype.ContentType; -import mindustry.entities.traits.*; +import mindustry.entities.*; import mindustry.io.*; import mindustry.type.TypeID; diff --git a/core/src/mindustry/type/StatusEffect.java b/core/src/mindustry/type/StatusEffect.java index 2b0c5c4189..99eb17afdf 100644 --- a/core/src/mindustry/type/StatusEffect.java +++ b/core/src/mindustry/type/StatusEffect.java @@ -1,16 +1,14 @@ package mindustry.type; -import arc.struct.*; import arc.graphics.*; import arc.math.*; +import arc.struct.*; import arc.util.*; import mindustry.content.*; import mindustry.ctype.*; -import mindustry.ctype.ContentType; import mindustry.entities.*; -import mindustry.entities.Effects.*; -import mindustry.entities.type.*; import mindustry.entities.units.*; +import mindustry.gen.*; public class StatusEffect extends MappableContent{ /** Damage dealt by the unit with the effect. */ @@ -44,15 +42,15 @@ public class StatusEffect extends MappableContent{ } /** Runs every tick on the affected unit while time is greater than 0. */ - public void update(Unit unit, float time){ + public void update(Unitc unit, float time){ if(damage > 0){ - unit.damagePeriodic(damage); + unit.damageContinuous(damage); }else if(damage < 0){ //heal unit - unit.healBy(damage * Time.delta()); + unit.heal(damage * Time.delta()); } if(effect != Fx.none && Mathf.chance(Time.delta() * 0.15f)){ - effect.at(unit.x + Mathf.range(unit.getSize() / 2f), unit.y + Mathf.range(unit.getSize() / 2f)); + effect.at(unit.getX() + Mathf.range(unit.getBounds() / 2f), unit.getY() + Mathf.range(unit.getBounds() / 2f)); } } @@ -83,7 +81,7 @@ public class StatusEffect extends MappableContent{ * @param time The current status effect time * @param newTime The time that the new status effect will last */ - public StatusEntry getTransition(Unit unit, StatusEffect to, float time, float newTime, StatusEntry result){ + public StatusEntry getTransition(Unitc unit, StatusEffect to, float time, float newTime, StatusEntry result){ if(transitions.containsKey(to)){ transitions.get(to).handle(unit, time, newTime, result); return result; @@ -98,6 +96,6 @@ public class StatusEffect extends MappableContent{ } public interface TransitionHandler{ - void handle(Unit unit, float time, float newTime, StatusEntry result); + void handle(Unitc unit, float time, float newTime, StatusEntry result); } } diff --git a/core/src/mindustry/type/UnitDef.java b/core/src/mindustry/type/UnitDef.java index f4f64c188c..31543fe1aa 100644 --- a/core/src/mindustry/type/UnitDef.java +++ b/core/src/mindustry/type/UnitDef.java @@ -49,7 +49,7 @@ public class UnitDef extends UnlockableContent{ public Sound deathSound = Sounds.bang; public Array weapons = new Array<>(); - public TextureRegion baseRegion, legRegion, region; + public TextureRegion baseRegion, legRegion, region, cellRegion; public UnitDef(String name){ super(name); @@ -87,6 +87,7 @@ public class UnitDef extends UnlockableContent{ region = Core.atlas.find(name); legRegion = Core.atlas.find(name + "-leg"); baseRegion = Core.atlas.find(name + "-base"); + cellRegion = Core.atlas.find(name + "-cell", Core.atlas.find("power-cell")); } @Override @@ -96,13 +97,13 @@ public class UnitDef extends UnlockableContent{ //TODO remove methods below! - public void update(Unit player){ + public void update(Unitc player){ } - public void draw(Unit player){ + public void draw(Unitc player){ } - public void drawStats(Unit player){ + public void drawStats(Unitc player){ if(drawCell){ float health = player.healthf(); Draw.color(Color.black, player.getTeam().color, health + Mathf.absin(Time.time(), health * 5f, 1f - health)); @@ -118,25 +119,25 @@ public class UnitDef extends UnlockableContent{ } } - public float getExtraArmor(Unit player){ + public float getExtraArmor(Unitc player){ return 0f; } //TODO remove - public float spreadX(Unit player){ + public float spreadX(Unitc player){ return 0f; } //TODO remove - public float getRotationAlpha(Unit player){ + public float getRotationAlpha(Unitc player){ return 1f; } - public boolean canShoot(Unit player){ + public boolean canShoot(Unitc player){ return true; } - public void onLand(Unit player){ + public void onLand(Unitc player){ } } diff --git a/core/src/mindustry/ui/fragments/PlayerListFragment.java b/core/src/mindustry/ui/fragments/PlayerListFragment.java index 7a29b7ffb0..1b71d710c7 100644 --- a/core/src/mindustry/ui/fragments/PlayerListFragment.java +++ b/core/src/mindustry/ui/fragments/PlayerListFragment.java @@ -8,7 +8,6 @@ import arc.scene.ui.*; import arc.scene.ui.layout.*; import arc.util.*; import mindustry.core.GameState.*; -import mindustry.entities.type.*; import mindustry.gen.*; import mindustry.graphics.*; import mindustry.net.*; @@ -66,7 +65,7 @@ public class PlayerListFragment extends Fragment{ float h = 74f; - playerGroup.all().sort(Structs.comparing(Unit::getTeam)); + playerGroup.all().sort(Structs.comparing(Unitc::getTeam)); playerGroup.all().each(user -> { NetConnection connection = user.con; diff --git a/core/src/mindustry/world/Block.java b/core/src/mindustry/world/Block.java index 4fc50c376c..efaf8675c8 100644 --- a/core/src/mindustry/world/Block.java +++ b/core/src/mindustry/world/Block.java @@ -358,11 +358,11 @@ public class Block extends BlockStorage{ } /** Called every frame a unit is on this tile. */ - public void unitOn(Tile tile, Unit unit){ + public void unitOn(Tile tile, Unitc unit){ } /** Called when a unit that spawned at this tile is removed. */ - public void unitRemoved(Tile tile, Unit unit){ + public void unitRemoved(Tile tile, Unitc unit){ } /** Returns whether ot not this block can be place on the specified tile. */ diff --git a/core/src/mindustry/world/BlockStorage.java b/core/src/mindustry/world/BlockStorage.java index 4f8f34c34c..9dbfba53f8 100644 --- a/core/src/mindustry/world/BlockStorage.java +++ b/core/src/mindustry/world/BlockStorage.java @@ -1,21 +1,18 @@ package mindustry.world; -import arc.struct.Array; -import arc.math.Mathf; -import arc.math.geom.Vec2; +import arc.math.*; +import arc.math.geom.*; +import arc.struct.*; import arc.util.*; -import mindustry.Vars; -import mindustry.content.Fx; -import mindustry.entities.Effects; -import mindustry.entities.effect.Puddle; -import mindustry.entities.type.TileEntity; -import mindustry.entities.type.Unit; -import mindustry.ctype.UnlockableContent; -import mindustry.type.Item; -import mindustry.type.Liquid; -import mindustry.world.consumers.Consumers; -import mindustry.world.meta.BlockBars; -import mindustry.world.meta.BlockStats; +import mindustry.*; +import mindustry.content.*; +import mindustry.ctype.*; +import mindustry.entities.effect.*; +import mindustry.entities.type.*; +import mindustry.gen.*; +import mindustry.type.*; +import mindustry.world.consumers.*; +import mindustry.world.meta.*; public abstract class BlockStorage extends UnlockableContent{ public boolean hasItems; @@ -51,7 +48,7 @@ public abstract class BlockStorage extends UnlockableContent{ } /** Returns the amount of items this block can accept. */ - public int acceptStack(Item item, int amount, Tile tile, Unit source){ + public int acceptStack(Item item, int amount, Tile tile, Teamc source){ if(acceptItem(item, tile, tile) && hasItems && (source == null || source.getTeam() == tile.getTeam())){ return Math.min(getMaximumAccepted(tile, item) - tile.entity.items.get(item), amount); }else{ @@ -73,7 +70,7 @@ public abstract class BlockStorage extends UnlockableContent{ } /** Handle a stack input. */ - public void handleStack(Item item, int amount, Tile tile, Unit source){ + public void handleStack(Item item, int amount, Tile tile, Teamc source){ tile.entity.noSleep(); tile.entity.items.add(item, amount); } diff --git a/core/src/mindustry/world/blocks/BuildBlock.java b/core/src/mindustry/world/blocks/BuildBlock.java index 36ee6dc448..b936b918a6 100644 --- a/core/src/mindustry/world/blocks/BuildBlock.java +++ b/core/src/mindustry/world/blocks/BuildBlock.java @@ -217,7 +217,7 @@ public class BuildBlock extends Block{ private float[] accumulator; private float[] totalAccumulator; - public boolean construct(Unit builder, @Nullable TileEntity core, float amount, boolean configured){ + public boolean construct(Unitc builder, @Nullable TileEntity core, float amount, boolean configured){ if(cblock == null){ kill(); return false; @@ -238,10 +238,7 @@ public class BuildBlock extends Block{ maxProgress = core == null ? maxProgress : checkRequired(core.items, maxProgress, true); progress = Mathf.clamp(progress + maxProgress); - - if(builder instanceof Player){ - builderID = builder.getID(); - } + builderID = builder.getId(); if(progress >= 1f || state.rules.infiniteResources){ constructed(tile, cblock, builderID, tile.rotation(), builder.getTeam(), configured); @@ -250,7 +247,7 @@ public class BuildBlock extends Block{ return false; } - public void deconstruct(Unit builder, @Nullable TileEntity core, float amount){ + public void deconstruct(Unitc builder, @Nullable TileEntity core, float amount){ float deconstructMultiplier = 0.5f; if(cblock != null){ diff --git a/core/src/mindustry/world/blocks/Floor.java b/core/src/mindustry/world/blocks/Floor.java index c9d7759bc9..ca0fa782cd 100644 --- a/core/src/mindustry/world/blocks/Floor.java +++ b/core/src/mindustry/world/blocks/Floor.java @@ -1,14 +1,14 @@ package mindustry.world.blocks; import arc.*; -import arc.struct.*; import arc.graphics.*; import arc.graphics.g2d.*; import arc.graphics.g2d.TextureAtlas.*; import arc.math.*; import arc.math.geom.*; +import arc.struct.*; import mindustry.content.*; -import mindustry.entities.Effects.*; +import mindustry.entities.*; import mindustry.graphics.*; import mindustry.graphics.MultiPacker.*; import mindustry.type.*; diff --git a/core/src/mindustry/world/blocks/defense/ForceProjector.java b/core/src/mindustry/world/blocks/defense/ForceProjector.java index d68ebfed9a..ab7e7d3d36 100644 --- a/core/src/mindustry/world/blocks/defense/ForceProjector.java +++ b/core/src/mindustry/world/blocks/defense/ForceProjector.java @@ -9,9 +9,7 @@ import arc.math.geom.*; import arc.util.*; import mindustry.content.*; import mindustry.entities.*; -import mindustry.entities.traits.*; import mindustry.entities.type.*; -import mindustry.entities.type.BaseEntity; import mindustry.graphics.*; import mindustry.world.*; import mindustry.world.consumers.*; diff --git a/core/src/mindustry/world/blocks/defense/ShockMine.java b/core/src/mindustry/world/blocks/defense/ShockMine.java index 61864556b8..4c6c526ea7 100644 --- a/core/src/mindustry/world/blocks/defense/ShockMine.java +++ b/core/src/mindustry/world/blocks/defense/ShockMine.java @@ -4,7 +4,6 @@ import arc.graphics.g2d.Draw; import arc.graphics.g2d.Fill; import arc.math.Mathf; import mindustry.entities.effect.Lightning; -import mindustry.entities.type.Unit; import mindustry.graphics.Layer; import mindustry.graphics.Pal; import mindustry.world.Block; @@ -49,7 +48,7 @@ public class ShockMine extends Block{ } @Override - public void unitOn(Tile tile, Unit unit){ + public void unitOn(Tile tile, Unitc unit){ if(unit.getTeam() != tile.getTeam() && tile.entity.timer.get(timerDamage, cooldown)){ for(int i = 0; i < tendrils; i++){ Lightning.create(tile.getTeam(), Pal.lancerLaser, damage, tile.drawx(), tile.drawy(), Mathf.random(360f), length); diff --git a/core/src/mindustry/world/blocks/defense/turrets/ItemTurret.java b/core/src/mindustry/world/blocks/defense/turrets/ItemTurret.java index b40b8d58b6..e8616599ad 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/ItemTurret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/ItemTurret.java @@ -86,7 +86,7 @@ public class ItemTurret extends CooledTurret{ } @Override - public int acceptStack(Item item, int amount, Tile tile, Unit source){ + public int acceptStack(Item item, int amount, Tile tile, Unitc source){ TurretEntity entity = tile.ent(); BulletType type = ammo.get(item); @@ -97,7 +97,7 @@ public class ItemTurret extends CooledTurret{ } @Override - public void handleStack(Item item, int amount, Tile tile, Unit source){ + public void handleStack(Item item, int amount, Tile tile, Unitc source){ for(int i = 0; i < amount; i++){ handleItem(item, tile, null); } diff --git a/core/src/mindustry/world/blocks/distribution/Conveyor.java b/core/src/mindustry/world/blocks/distribution/Conveyor.java index 45b65c39e8..575771c0af 100644 --- a/core/src/mindustry/world/blocks/distribution/Conveyor.java +++ b/core/src/mindustry/world/blocks/distribution/Conveyor.java @@ -138,7 +138,7 @@ public class Conveyor extends Block implements Autotiler{ } @Override - public void unitOn(Tile tile, Unit unit){ + public void unitOn(Tile tile, Unitc unit){ ConveyorEntity entity = tile.ent(); if(entity.clogHeat > 0.5f){ @@ -256,13 +256,13 @@ public class Conveyor extends Block implements Autotiler{ } @Override - public int acceptStack(Item item, int amount, Tile tile, Unit source){ + public int acceptStack(Item item, int amount, Tile tile, Unitc source){ ConveyorEntity entity = tile.ent(); return Math.min((int)(entity.minitem / itemSpace), amount); } @Override - public void handleStack(Item item, int amount, Tile tile, Unit source){ + public void handleStack(Item item, int amount, Tile tile, Unitc source){ ConveyorEntity e = tile.ent(); for(int i = amount - 1; i >= 0; i--){ diff --git a/core/src/mindustry/world/blocks/distribution/Junction.java b/core/src/mindustry/world/blocks/distribution/Junction.java index 99c22057e1..d558d7ff3e 100644 --- a/core/src/mindustry/world/blocks/distribution/Junction.java +++ b/core/src/mindustry/world/blocks/distribution/Junction.java @@ -2,7 +2,6 @@ package mindustry.world.blocks.distribution; import arc.util.Time; import mindustry.entities.type.TileEntity; -import mindustry.entities.type.Unit; import mindustry.gen.BufferItem; import mindustry.type.Item; import mindustry.world.Block; @@ -31,7 +30,7 @@ public class Junction extends Block{ } @Override - public int acceptStack(Item item, int amount, Tile tile, Unit source){ + public int acceptStack(Item item, int amount, Tile tile, Unitc source){ return 0; } diff --git a/core/src/mindustry/world/blocks/storage/CoreBlock.java b/core/src/mindustry/world/blocks/storage/CoreBlock.java index 9cf4e792d1..1a681aa77f 100644 --- a/core/src/mindustry/world/blocks/storage/CoreBlock.java +++ b/core/src/mindustry/world/blocks/storage/CoreBlock.java @@ -8,7 +8,6 @@ import arc.graphics.g2d.*; import arc.math.*; import arc.math.geom.*; import mindustry.content.*; -import mindustry.entities.*; import mindustry.entities.traits.*; import mindustry.entities.type.*; import mindustry.game.EventType.*; @@ -239,7 +238,7 @@ public class CoreBlock extends StorageBlock{ protected int storageCapacity; @Override - public boolean hasUnit(Unit unit){ + public boolean hasUnit(Unitc unit){ return unit == spawnPlayer; } diff --git a/core/src/mindustry/world/blocks/units/MechPad.java b/core/src/mindustry/world/blocks/units/MechPad.java index 375e4d74c3..b20977f7ac 100644 --- a/core/src/mindustry/world/blocks/units/MechPad.java +++ b/core/src/mindustry/world/blocks/units/MechPad.java @@ -9,13 +9,11 @@ import arc.math.geom.*; import arc.util.*; import arc.util.ArcAnnotate.*; import mindustry.content.*; -import mindustry.entities.*; import mindustry.entities.traits.*; import mindustry.entities.type.*; import mindustry.game.EventType.*; import mindustry.gen.*; import mindustry.graphics.*; -import mindustry.type.*; import mindustry.world.*; import mindustry.world.blocks.*; import mindustry.world.meta.*; @@ -143,7 +141,7 @@ public class MechPad extends Block{ float heat; @Override - public boolean hasUnit(Unit unit){ + public boolean hasUnit(Unitc unit){ return unit == player; } diff --git a/core/src/mindustry/world/blocks/units/RepairPoint.java b/core/src/mindustry/world/blocks/units/RepairPoint.java index a17fffe1b1..e6cf13403b 100644 --- a/core/src/mindustry/world/blocks/units/RepairPoint.java +++ b/core/src/mindustry/world/blocks/units/RepairPoint.java @@ -10,7 +10,6 @@ import arc.math.geom.Rect; import arc.util.Time; import mindustry.entities.Units; import mindustry.entities.type.TileEntity; -import mindustry.entities.type.Unit; import mindustry.graphics.*; import mindustry.world.Block; import mindustry.world.Tile; @@ -141,7 +140,7 @@ public class RepairPoint extends Block{ } public class RepairPointEntity extends TileEntity{ - public Unit target; + public Unitc target; public float strength, rotation = 90; } } diff --git a/core/src/mindustry/world/blocks/units/UnitFactory.java b/core/src/mindustry/world/blocks/units/UnitFactory.java index 791194cbc2..7e93202dfe 100644 --- a/core/src/mindustry/world/blocks/units/UnitFactory.java +++ b/core/src/mindustry/world/blocks/units/UnitFactory.java @@ -109,7 +109,7 @@ public class UnitFactory extends Block{ } @Override - public void unitRemoved(Tile tile, Unit unit){ + public void unitRemoved(Tile tile, Unitc unit){ UnitFactoryEntity entity = tile.ent(); entity.spawned--; entity.spawned = Math.max(entity.spawned, 0);