Refactoring
This commit is contained in:
@@ -10,7 +10,14 @@ public class Annotations{
|
|||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
public @interface Component{
|
public @interface Component{
|
||||||
/** Dependencies. */
|
/** 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. */
|
/** Indicates that a component def is present on all entities. */
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import javax.lang.model.type.*;
|
|||||||
public class EntityProcess extends BaseProcessor{
|
public class EntityProcess extends BaseProcessor{
|
||||||
Array<Definition> definitions = new Array<>();
|
Array<Definition> definitions = new Array<>();
|
||||||
Array<Stype> baseComponents;
|
Array<Stype> baseComponents;
|
||||||
|
ObjectMap<String, Stype> componentNames = new ObjectMap<>();
|
||||||
ObjectMap<Stype, Array<Stype>> componentDependencies = new ObjectMap<>();
|
ObjectMap<Stype, Array<Stype>> componentDependencies = new ObjectMap<>();
|
||||||
ObjectMap<Stype, Array<Stype>> defComponents = new ObjectMap<>();
|
ObjectMap<Stype, Array<Stype>> defComponents = new ObjectMap<>();
|
||||||
ObjectSet<String> imports = new ObjectSet<>();
|
ObjectSet<String> imports = new ObjectSet<>();
|
||||||
@@ -36,17 +37,12 @@ public class EntityProcess extends BaseProcessor{
|
|||||||
if(round == 1){
|
if(round == 1){
|
||||||
baseComponents = types(BaseComponent.class);
|
baseComponents = types(BaseComponent.class);
|
||||||
Array<Stype> allDefs = types(EntityDef.class);
|
Array<Stype> allDefs = types(EntityDef.class);
|
||||||
|
Array<Stype> allComponents = types(Component.class);
|
||||||
|
|
||||||
ObjectSet<Stype> allComponents = new ObjectSet<>();
|
for(Stype type : allComponents){
|
||||||
|
componentNames.put(type.name(), type);
|
||||||
//find all components used...
|
|
||||||
for(Stype type : allDefs){
|
|
||||||
allComponents.addAll(allComponents(type));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//add all components w/ dependencies
|
|
||||||
allComponents.addAll(types(Component.class).map(s -> Array.withArrays(getDependencies(s), s)).flatten());
|
|
||||||
|
|
||||||
//add component imports
|
//add component imports
|
||||||
for(Stype comp : allComponents){
|
for(Stype comp : allComponents){
|
||||||
imports.addAll(getImports(comp.e));
|
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);
|
TypeSpec.Builder inter = TypeSpec.interfaceBuilder(interfaceName(component)).addModifiers(Modifier.PUBLIC).addAnnotation(EntityInterface.class);
|
||||||
|
|
||||||
//implement extra interfaces these components may have, e.g. position
|
//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());
|
inter.addSuperinterface(extraInterface.mirror());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,6 +126,8 @@ public class EntityProcess extends BaseProcessor{
|
|||||||
|
|
||||||
//add all methods from components
|
//add all methods from components
|
||||||
for(ObjectMap.Entry<String, Array<Smethod>> entry : methods){
|
for(ObjectMap.Entry<String, Array<Smethod>> entry : methods){
|
||||||
|
entry.value.sort(m -> m.has(MethodPriority.class) ? m.annotation(MethodPriority.class).value() : 0);
|
||||||
|
|
||||||
//representative method
|
//representative method
|
||||||
Smethod first = entry.value.first();
|
Smethod first = entry.value.first();
|
||||||
//build method using same params/returns
|
//build method using same params/returns
|
||||||
@@ -261,18 +259,8 @@ public class EntityProcess extends BaseProcessor{
|
|||||||
Array<Stype> getDependencies(Stype component){
|
Array<Stype> getDependencies(Stype component){
|
||||||
if(!componentDependencies.containsKey(component)){
|
if(!componentDependencies.containsKey(component)){
|
||||||
ObjectSet<Stype> out = new ObjectSet<>();
|
ObjectSet<Stype> out = new ObjectSet<>();
|
||||||
out.addAll(component.superclasses());
|
//add base component interfaces
|
||||||
//TODO extreme confusion
|
out.addAll(component.interfaces().select(this::isCompInterface).map(this::interfaceToComp));
|
||||||
//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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//out now contains the base dependencies; finish constructing the tree
|
//out now contains the base dependencies; finish constructing the tree
|
||||||
ObjectSet<Stype> result = new ObjectSet<>();
|
ObjectSet<Stype> result = new ObjectSet<>();
|
||||||
@@ -291,6 +279,15 @@ public class EntityProcess extends BaseProcessor{
|
|||||||
return componentDependencies.get(component);
|
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){
|
boolean isComponent(Stype type){
|
||||||
return type.annotation(Component.class) != null;
|
return type.annotation(Component.class) != null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import mindustry.annotations.*;
|
|||||||
|
|
||||||
import javax.lang.model.element.*;
|
import javax.lang.model.element.*;
|
||||||
import javax.lang.model.type.*;
|
import javax.lang.model.type.*;
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
public class Selement<T extends Element>{
|
public class Selement<T extends Element>{
|
||||||
public final T e;
|
public final T e;
|
||||||
@@ -13,6 +14,14 @@ public class Selement<T extends Element>{
|
|||||||
this.e = e;
|
this.e = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public <A extends Annotation> A annotation(Class<A> annotation){
|
||||||
|
return e.getAnnotation(annotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <A extends Annotation> boolean has(Class<A> annotation){
|
||||||
|
return e.getAnnotation(annotation) != null;
|
||||||
|
}
|
||||||
|
|
||||||
public Element up(){
|
public Element up(){
|
||||||
return e.getEnclosingElement();
|
return e.getEnclosingElement();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import mindustry.annotations.*;
|
|||||||
|
|
||||||
import javax.lang.model.element.*;
|
import javax.lang.model.element.*;
|
||||||
import javax.lang.model.type.*;
|
import javax.lang.model.type.*;
|
||||||
import java.lang.annotation.*;
|
|
||||||
|
|
||||||
public class Stype extends Selement<TypeElement>{
|
public class Stype extends Selement<TypeElement>{
|
||||||
|
|
||||||
@@ -35,10 +34,6 @@ public class Stype extends Selement<TypeElement>{
|
|||||||
return new Stype((TypeElement)BaseProcessor.typeu.asElement(BaseProcessor.typeu.directSupertypes(mirror()).get(0)));
|
return new Stype((TypeElement)BaseProcessor.typeu.asElement(BaseProcessor.typeu.directSupertypes(mirror()).get(0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public <A extends Annotation> A annotation(Class<A> annotation){
|
|
||||||
return e.getAnnotation(annotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Array<Svar> fields(){
|
public Array<Svar> fields(){
|
||||||
return Array.with(e.getEnclosedElements()).select(e -> e instanceof VariableElement).map(e -> new Svar((VariableElement)e));
|
return Array.with(e.getEnclosedElements()).select(e -> e instanceof VariableElement).map(e -> new Svar((VariableElement)e));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -189,7 +189,7 @@ public class Vars implements Loadable{
|
|||||||
public static EntityGroup<Fire> fireGroup;
|
public static EntityGroup<Fire> fireGroup;
|
||||||
public static EntityGroup<BaseUnit> unitGroup;
|
public static EntityGroup<BaseUnit> unitGroup;
|
||||||
|
|
||||||
public static Player player;
|
public static Unitc player;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void loadAsync(){
|
public void loadAsync(){
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import mindustry.annotations.Annotations.*;
|
|||||||
import mindustry.core.GameState.*;
|
import mindustry.core.GameState.*;
|
||||||
import mindustry.ctype.*;
|
import mindustry.ctype.*;
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
import mindustry.entities.traits.*;
|
|
||||||
import mindustry.entities.type.*;
|
import mindustry.entities.type.*;
|
||||||
import mindustry.entities.units.*;
|
import mindustry.entities.units.*;
|
||||||
import mindustry.game.EventType.*;
|
import mindustry.game.EventType.*;
|
||||||
@@ -365,8 +364,8 @@ public class NetClient implements ApplicationListener{
|
|||||||
if(created && entity.getInterpolator() != null && entity.getInterpolator().target != null){
|
if(created && entity.getInterpolator() != null && entity.getInterpolator().target != null){
|
||||||
//set initial starting position
|
//set initial starting position
|
||||||
entity.setNet(entity.getInterpolator().target.x, entity.getInterpolator().target.y);
|
entity.setNet(entity.getInterpolator().target.x, entity.getInterpolator().target.y);
|
||||||
if(entity instanceof Unit && entity.getInterpolator().targets.length > 0){
|
if(entity instanceof Unitc && entity.getInterpolator().targets.length > 0){
|
||||||
((Unit)entity).rotation = entity.getInterpolator().targets[0];
|
((Unitc)entity).rotation = entity.getInterpolator().targets[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import arc.scene.ui.layout.*;
|
|||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.core.GameState.*;
|
import mindustry.core.GameState.*;
|
||||||
import mindustry.entities.traits.*;
|
|
||||||
import mindustry.entities.type.*;
|
import mindustry.entities.type.*;
|
||||||
import mindustry.game.EventType.*;
|
import mindustry.game.EventType.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
@@ -306,7 +305,7 @@ public class Renderer implements ApplicationListener{
|
|||||||
Draw.color(0, 0, 0, 0.4f);
|
Draw.color(0, 0, 0, 0.4f);
|
||||||
float rad = 1.6f;
|
float rad = 1.6f;
|
||||||
|
|
||||||
Cons<Unit> draw = u -> {
|
Cons<Unitc> draw = u -> {
|
||||||
float size = Math.max(u.getIconRegion().getWidth(), u.getIconRegion().getHeight()) * Draw.scl;
|
float size = Math.max(u.getIconRegion().getWidth(), u.getIconRegion().getHeight()) * Draw.scl;
|
||||||
Draw.rect("circle-shadow", u.x, u.y, size * rad, size * rad);
|
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){
|
private void drawAllTeams(boolean flying){
|
||||||
unitGroup.draw(u -> u.isFlying() == flying && !u.isDead(), Unit::drawUnder);
|
unitGroup.draw(u -> u.isFlying() == flying && !u.isDead(), Unitc::drawUnder);
|
||||||
playerGroup.draw(p -> p.isFlying() == flying && !p.isDead(), Unit::drawUnder);
|
playerGroup.draw(p -> p.isFlying() == flying && !p.isDead(), Unitc::drawUnder);
|
||||||
|
|
||||||
unitGroup.draw(u -> u.isFlying() == flying && !u.isDead(), Unit::drawAll);
|
unitGroup.draw(u -> u.isFlying() == flying && !u.isDead(), Unitc::drawAll);
|
||||||
playerGroup.draw(p -> p.isFlying() == flying, Unit::drawAll);
|
playerGroup.draw(p -> p.isFlying() == flying, Unitc::drawAll);
|
||||||
|
|
||||||
unitGroup.draw(u -> u.isFlying() == flying && !u.isDead(), Unit::drawOver);
|
unitGroup.draw(u -> u.isFlying() == flying && !u.isDead(), Unitc::drawOver);
|
||||||
playerGroup.draw(p -> p.isFlying() == flying, Unit::drawOver);
|
playerGroup.draw(p -> p.isFlying() == flying, Unitc::drawOver);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void scaleCamera(float amount){
|
public void scaleCamera(float amount){
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import arc.math.*;
|
|||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.entities.Effects.*;
|
|
||||||
import mindustry.entities.effect.*;
|
import mindustry.entities.effect.*;
|
||||||
import mindustry.entities.type.*;
|
import mindustry.entities.type.*;
|
||||||
import mindustry.game.EventType.*;
|
import mindustry.game.EventType.*;
|
||||||
@@ -125,7 +124,7 @@ public class Damage{
|
|||||||
rect.width += expand * 2;
|
rect.width += expand * 2;
|
||||||
rect.height += expand * 2;
|
rect.height += expand * 2;
|
||||||
|
|
||||||
Cons<Unit> cons = e -> {
|
Cons<Unitc> cons = e -> {
|
||||||
e.hitbox(hitrect);
|
e.hitbox(hitrect);
|
||||||
Rect other = hitrect;
|
Rect other = hitrect;
|
||||||
other.y -= expand;
|
other.y -= expand;
|
||||||
@@ -146,8 +145,8 @@ public class Damage{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Damages all entities and blocks in a radius that are enemies of the team. */
|
/** 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<Unit> predicate, Cons<Unit> acceptor){
|
public static void damageUnits(Team team, float x, float y, float size, float damage, Boolf<Unitc> predicate, Cons<Unitc> acceptor){
|
||||||
Cons<Unit> cons = entity -> {
|
Cons<Unitc> cons = entity -> {
|
||||||
if(!predicate.get(entity)) return;
|
if(!predicate.get(entity)) return;
|
||||||
|
|
||||||
entity.hitbox(hitrect);
|
entity.hitbox(hitrect);
|
||||||
@@ -178,7 +177,7 @@ public class Damage{
|
|||||||
|
|
||||||
/** Damages all entities and blocks in a radius that are enemies of the team. */
|
/** 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){
|
public static void damage(Team team, float x, float y, float radius, float damage, boolean complete){
|
||||||
Cons<Unit> cons = entity -> {
|
Cons<Unitc> cons = entity -> {
|
||||||
if(entity.getTeam() == team || entity.dst(x, y) > radius){
|
if(entity.getTeam() == team || entity.dst(x, y) > radius){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package mindustry.entities;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marks an entity as serializable.
|
||||||
|
*/
|
||||||
|
public interface SaveTrait extends Saveable{
|
||||||
|
byte version();
|
||||||
|
}
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package mindustry.entities.traits;
|
package mindustry.entities;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
|
||||||
@@ -3,7 +3,6 @@ package mindustry.entities;
|
|||||||
import arc.func.*;
|
import arc.func.*;
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import mindustry.entities.traits.*;
|
|
||||||
import mindustry.entities.type.*;
|
import mindustry.entities.type.*;
|
||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
@@ -13,7 +12,7 @@ import static mindustry.Vars.*;
|
|||||||
/** Utility class for unit and team interactions.*/
|
/** Utility class for unit and team interactions.*/
|
||||||
public class Units{
|
public class Units{
|
||||||
private static Rect hitrect = new Rect();
|
private static Rect hitrect = new Rect();
|
||||||
private static Unit result;
|
private static Unitc result;
|
||||||
private static float cdist;
|
private static float cdist;
|
||||||
private static boolean boolResult;
|
private static boolean boolResult;
|
||||||
|
|
||||||
@@ -41,7 +40,7 @@ public class Units{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** See {@link #invalidateTarget(TargetTrait, Team, float, float, float)} */
|
/** 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());
|
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. */
|
/** Returns the closest target enemy. First, units are checked, then tile entities. */
|
||||||
public static TargetTrait closestTarget(Team team, float x, float y, float range){
|
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. */
|
/** 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<Unit> unitPred){
|
public static TargetTrait closestTarget(Team team, float x, float y, float range, Boolf<Unitc> unitPred){
|
||||||
return closestTarget(team, x, y, range, unitPred, t -> true);
|
return closestTarget(team, x, y, range, unitPred, t -> true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the closest target enemy. First, units are checked, then tile entities. */
|
/** 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<Unit> unitPred, Boolf<Tile> tilePred){
|
public static TargetTrait closestTarget(Team team, float x, float y, float range, Boolf<Unitc> unitPred, Boolf<Tile> tilePred){
|
||||||
if(team == Team.derelict) return null;
|
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){
|
if(unit != null){
|
||||||
return unit;
|
return unit;
|
||||||
}else{
|
}else{
|
||||||
@@ -109,7 +108,7 @@ public class Units{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the closest enemy of this team. Filter by predicate. */
|
/** Returns the closest enemy of this team. Filter by predicate. */
|
||||||
public static Unit closestEnemy(Team team, float x, float y, float range, Boolf<Unit> predicate){
|
public static Unitc closestEnemy(Team team, float x, float y, float range, Boolf<Unitc> predicate){
|
||||||
if(team == Team.derelict) return null;
|
if(team == Team.derelict) return null;
|
||||||
|
|
||||||
result = null;
|
result = null;
|
||||||
@@ -129,7 +128,7 @@ public class Units{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the closest ally of this team. Filter by predicate. */
|
/** Returns the closest ally of this team. Filter by predicate. */
|
||||||
public static Unit closest(Team team, float x, float y, float range, Boolf<Unit> predicate){
|
public static Unitc closest(Team team, float x, float y, float range, Boolf<Unitc> predicate){
|
||||||
result = null;
|
result = null;
|
||||||
cdist = 0f;
|
cdist = 0f;
|
||||||
|
|
||||||
@@ -147,7 +146,7 @@ public class Units{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Iterates over all units in a rectangle. */
|
/** Iterates over all units in a rectangle. */
|
||||||
public static void nearby(Team team, float x, float y, float width, float height, Cons<Unit> cons){
|
public static void nearby(Team team, float x, float y, float width, float height, Cons<Unitc> cons){
|
||||||
unitGroup.intersect(x, y, width, height, u -> {
|
unitGroup.intersect(x, y, width, height, u -> {
|
||||||
if(u.getTeam() == team){
|
if(u.getTeam() == team){
|
||||||
cons.get(u);
|
cons.get(u);
|
||||||
@@ -161,7 +160,7 @@ public class Units{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Iterates over all units in a circle around this position. */
|
/** Iterates over all units in a circle around this position. */
|
||||||
public static void nearby(Team team, float x, float y, float radius, Cons<Unit> cons){
|
public static void nearby(Team team, float x, float y, float radius, Cons<Unitc> cons){
|
||||||
unitGroup.intersect(x - radius, y - radius, radius*2f, radius*2f, unit -> {
|
unitGroup.intersect(x - radius, y - radius, radius*2f, radius*2f, unit -> {
|
||||||
if(unit.getTeam() == team && unit.withinDst(x, y, radius)){
|
if(unit.getTeam() == team && unit.withinDst(x, y, radius)){
|
||||||
cons.get(unit);
|
cons.get(unit);
|
||||||
@@ -176,18 +175,18 @@ public class Units{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Iterates over all units in a rectangle. */
|
/** Iterates over all units in a rectangle. */
|
||||||
public static void nearby(float x, float y, float width, float height, Cons<Unit> cons){
|
public static void nearby(float x, float y, float width, float height, Cons<Unitc> cons){
|
||||||
unitGroup.intersect(x, y, width, height, cons);
|
unitGroup.intersect(x, y, width, height, cons);
|
||||||
playerGroup.intersect(x, y, width, height, cons);
|
playerGroup.intersect(x, y, width, height, cons);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Iterates over all units in a rectangle. */
|
/** Iterates over all units in a rectangle. */
|
||||||
public static void nearby(Rect rect, Cons<Unit> cons){
|
public static void nearby(Rect rect, Cons<Unitc> cons){
|
||||||
nearby(rect.x, rect.y, rect.width, rect.height, cons);
|
nearby(rect.x, rect.y, rect.width, rect.height, cons);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Iterates over all units that are enemies of this team. */
|
/** 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<Unit> cons){
|
public static void nearbyEnemies(Team team, float x, float y, float width, float height, Cons<Unitc> cons){
|
||||||
unitGroup.intersect(x, y, width, height, u -> {
|
unitGroup.intersect(x, y, width, height, u -> {
|
||||||
if(team.isEnemy(u.getTeam())){
|
if(team.isEnemy(u.getTeam())){
|
||||||
cons.get(u);
|
cons.get(u);
|
||||||
@@ -202,12 +201,12 @@ public class Units{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Iterates over all units that are enemies of this team. */
|
/** Iterates over all units that are enemies of this team. */
|
||||||
public static void nearbyEnemies(Team team, Rect rect, Cons<Unit> cons){
|
public static void nearbyEnemies(Team team, Rect rect, Cons<Unitc> cons){
|
||||||
nearbyEnemies(team, rect.x, rect.y, rect.width, rect.height, cons);
|
nearbyEnemies(team, rect.x, rect.y, rect.width, rect.height, cons);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Iterates over all units. */
|
/** Iterates over all units. */
|
||||||
public static void all(Cons<Unit> cons){
|
public static void all(Cons<Unitc> cons){
|
||||||
unitGroup.all().each(cons);
|
unitGroup.all().each(cons);
|
||||||
playerGroup.all().each(cons);
|
playerGroup.all().each(cons);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
package mindustry.entities.def;
|
package mindustry.entities.def;
|
||||||
|
|
||||||
|
import arc.*;
|
||||||
import arc.graphics.*;
|
import arc.graphics.*;
|
||||||
import arc.graphics.g2d.*;
|
import arc.graphics.g2d.*;
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
|
import arc.scene.ui.layout.*;
|
||||||
import arc.struct.Bits;
|
import arc.struct.Bits;
|
||||||
|
import arc.struct.Queue;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.ArcAnnotate.*;
|
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
|
import arc.util.ArcAnnotate.*;
|
||||||
import arc.util.pooling.*;
|
import arc.util.pooling.*;
|
||||||
import mindustry.*;
|
import mindustry.*;
|
||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
@@ -15,64 +18,154 @@ import mindustry.content.*;
|
|||||||
import mindustry.ctype.*;
|
import mindustry.ctype.*;
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
import mindustry.entities.bullet.*;
|
import mindustry.entities.bullet.*;
|
||||||
import mindustry.entities.def.EntityComps.MinerComp.*;
|
|
||||||
import mindustry.entities.effect.*;
|
import mindustry.entities.effect.*;
|
||||||
import mindustry.entities.traits.*;
|
|
||||||
import mindustry.entities.type.*;
|
import mindustry.entities.type.*;
|
||||||
import mindustry.entities.units.*;
|
import mindustry.entities.units.*;
|
||||||
|
import mindustry.game.EventType.*;
|
||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
|
import mindustry.graphics.*;
|
||||||
import mindustry.net.*;
|
import mindustry.net.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
|
import mindustry.ui.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
|
import mindustry.world.blocks.*;
|
||||||
import mindustry.world.blocks.BuildBlock.*;
|
import mindustry.world.blocks.BuildBlock.*;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
import static arc.math.Mathf.dst;
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
import static mindustry.entities.traits.BuilderTrait.BuildDataStatic.tmptr;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public class EntityComps{
|
public class EntityComps{
|
||||||
|
|
||||||
@Component({HealthComp.class, VelComp.class, StatusComp.class, TeamComp.class, ItemsComp.class})
|
@Component
|
||||||
class UnitComp{
|
abstract class UnitComp implements Healthc, Velc, Statusc, Teamc, Itemsc, Hitboxc, Rotc{
|
||||||
UnitDef type;
|
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{
|
class OwnerComp{
|
||||||
Entityc owner;
|
Entityc owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({TimedComp.class, DamageComp.class, HitboxComp.class})
|
@Component
|
||||||
class BulletComp{
|
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;
|
BulletType bullet;
|
||||||
|
|
||||||
float getDamage(){
|
public float getDamage(){
|
||||||
return bullet.damage;
|
return bullet.damage;
|
||||||
}
|
}
|
||||||
|
|
||||||
void init(){
|
public void init(){
|
||||||
//TODO
|
//TODO
|
||||||
bullet.init(null);
|
bullet.init(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove(){
|
public void remove(){
|
||||||
//TODO
|
//TODO
|
||||||
bullet.despawned(null);
|
bullet.despawned(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
class DamageComp{
|
abstract class DamageComp{
|
||||||
native float getDamage();
|
abstract float getDamage();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
abstract class TimedComp extends EntityComp implements Scaled{
|
abstract class TimedComp implements Entityc, Scaled{
|
||||||
float time, lifetime;
|
float time, lifetime;
|
||||||
|
|
||||||
void update(){
|
public void update(){
|
||||||
time = Math.min(time + Time.delta(), lifetime);
|
time = Math.min(time + Time.delta(), lifetime);
|
||||||
|
|
||||||
if(time >= lifetime){
|
if(time >= lifetime){
|
||||||
@@ -87,16 +180,22 @@ public class EntityComps{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
class HealthComp{
|
abstract class HealthComp implements Entityc{
|
||||||
|
static final float hitDuration = 9f;
|
||||||
|
|
||||||
float health, maxHealth, hitTime;
|
float health, maxHealth, hitTime;
|
||||||
boolean dead;
|
boolean dead;
|
||||||
|
|
||||||
|
boolean isValid(){
|
||||||
|
return !dead && isAdded();
|
||||||
|
}
|
||||||
|
|
||||||
float healthf(){
|
float healthf(){
|
||||||
return health / maxHealth;
|
return health / maxHealth;
|
||||||
}
|
}
|
||||||
|
|
||||||
void update(){
|
public void update(){
|
||||||
hitTime -= Time.delta() / 9f;
|
hitTime -= Time.delta() / hitDuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
void killed(){
|
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(){
|
void clampHealth(){
|
||||||
health = Mathf.clamp(health, 0, maxHealth);
|
health = Mathf.clamp(health, 0, maxHealth);
|
||||||
}
|
}
|
||||||
@@ -136,23 +249,67 @@ public class EntityComps{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
class FlyingComp{
|
abstract class FlyingComp implements Posc, Velc, Healthc{
|
||||||
boolean flying;
|
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
|
@Component
|
||||||
class LegsComp{
|
abstract class LegsComp implements Posc, Flyingc{
|
||||||
float baseRotation;
|
float baseRotation;
|
||||||
float drownTime;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
class RotComp{
|
class RotComp{
|
||||||
float rotation;
|
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
|
@Component
|
||||||
abstract class TeamComp{
|
abstract class TeamComp implements Posc{
|
||||||
transient float x, y;
|
transient float x, y;
|
||||||
|
|
||||||
Team team = Team.sharded;
|
Team team = Team.sharded;
|
||||||
@@ -162,8 +319,8 @@ public class EntityComps{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({RotComp.class, PosComp.class})
|
@Component
|
||||||
abstract static class WeaponsComp implements Teamc{
|
abstract static class WeaponsComp implements Teamc, Posc, Rotc{
|
||||||
transient float x, y, rotation;
|
transient float x, y, rotation;
|
||||||
|
|
||||||
/** 1 */
|
/** 1 */
|
||||||
@@ -184,7 +341,7 @@ public class EntityComps{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Aim at something. This will make all mounts point at it. */
|
/** 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);
|
Tmp.v1.set(x, y).sub(this.x, this.y);
|
||||||
if(Tmp.v1.len() < minAimDst) Tmp.v1.setLength(minAimDst);
|
if(Tmp.v1.len() < minAimDst) Tmp.v1.setLength(minAimDst);
|
||||||
|
|
||||||
@@ -198,12 +355,12 @@ public class EntityComps{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Update shooting and rotation for this unit. */
|
/** Update shooting and rotation for this unit. */
|
||||||
void update(Unit unit){
|
public void update(){
|
||||||
for(WeaponMount mount : mounts){
|
for(WeaponMount mount : mounts){
|
||||||
Weapon weapon = mount.weapon;
|
Weapon weapon = mount.weapon;
|
||||||
mount.reload -= Time.delta();
|
mount.reload -= Time.delta();
|
||||||
|
|
||||||
float rotation = unit.rotation - 90;
|
float rotation = this.rotation - 90;
|
||||||
|
|
||||||
//rotate if applicable
|
//rotate if applicable
|
||||||
if(weapon.rotate){
|
if(weapon.rotate){
|
||||||
@@ -294,39 +451,115 @@ public class EntityComps{
|
|||||||
|
|
||||||
private void bullet(Weapon weapon, float x, float y, float angle){
|
private void bullet(Weapon weapon, float x, float y, float angle){
|
||||||
Tmp.v1.trns(angle, 3f);
|
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
|
@Component
|
||||||
class DrawComp{
|
abstract static class DrawShadowComp implements Drawc, Rotc, Flyingc{
|
||||||
//TODO ponder.
|
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(){
|
void draw(){
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component(PosComp.class)
|
@Component
|
||||||
abstract class SyncComp extends PosComp{
|
abstract class SyncComp implements Posc{
|
||||||
|
transient float x, y;
|
||||||
|
|
||||||
Interpolator interpolator = new Interpolator();
|
Interpolator interpolator = new Interpolator();
|
||||||
|
|
||||||
void setNet(float x, float y){
|
void setNet(float x, float y){
|
||||||
set(x, y);
|
set(x, y);
|
||||||
|
|
||||||
//TODO change interpolator API
|
//TODO change interpolator API
|
||||||
if(interpolator != null){
|
interpolator.target.set(x, y);
|
||||||
interpolator.target.set(x, y);
|
interpolator.last.set(x, y);
|
||||||
interpolator.last.set(x, y);
|
interpolator.pos.set(0, 0);
|
||||||
interpolator.pos.set(0, 0);
|
interpolator.updateSpacing = 16;
|
||||||
interpolator.updateSpacing = 16;
|
interpolator.lastUpdated = 0;
|
||||||
interpolator.lastUpdated = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void update(){
|
public void update(){
|
||||||
if(Vars.net.client() && !isLocal()){
|
if(Vars.net.client() && !isLocal()){
|
||||||
interpolate();
|
interpolate();
|
||||||
}
|
}
|
||||||
@@ -340,7 +573,35 @@ public class EntityComps{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Component
|
@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;
|
float x, y;
|
||||||
|
|
||||||
void set(float x, float y){
|
void set(float x, float y){
|
||||||
@@ -359,19 +620,31 @@ public class EntityComps{
|
|||||||
int tileY(){
|
int tileY(){
|
||||||
return Vars.world.toTile(getY());
|
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 abstract class MinerComp implements Itemsc, Posc, Teamc, Rotc{
|
||||||
static float miningRange = 70f;
|
static float miningRange = 70f;
|
||||||
|
|
||||||
|
transient float x, y, rotation;
|
||||||
|
|
||||||
@Nullable Tile mineTile;
|
@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(){
|
boolean isMining(){
|
||||||
return mineTile != null;
|
return mineTile != null;
|
||||||
@@ -381,7 +654,7 @@ public class EntityComps{
|
|||||||
TileEntity core = getClosestCore();
|
TileEntity core = getClosestCore();
|
||||||
|
|
||||||
if(core != null && mineTile != null && mineTile.drop() != null && !acceptsItem(mineTile.drop()) && dst(core) < mineTransferRange){
|
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){
|
if(accepted > 0){
|
||||||
Call.transferItemTo(item(), accepted,
|
Call.transferItemTo(item(), accepted,
|
||||||
mineTile.worldx() + Mathf.range(tilesize / 2f),
|
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(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,
|
Call.transferItemTo(item, 1,
|
||||||
mineTile.worldx() + Mathf.range(tilesize / 2f),
|
mineTile.worldx() + Mathf.range(tilesize / 2f),
|
||||||
mineTile.worldy() + Mathf.range(tilesize / 2f), core.tile);
|
mineTile.worldy() + Mathf.range(tilesize / 2f), core.tile);
|
||||||
@@ -408,7 +681,7 @@ public class EntityComps{
|
|||||||
ItemTransfer.transferItemToUnit(item,
|
ItemTransfer.transferItemToUnit(item,
|
||||||
mineTile.worldx() + Mathf.range(tilesize / 2f),
|
mineTile.worldx() + Mathf.range(tilesize / 2f),
|
||||||
mineTile.worldy() + 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
|
@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<BuildRequest> requests = new Queue<>();
|
Queue<BuildRequest> requests = new Queue<>();
|
||||||
float buildSpeed = 1f;
|
float buildSpeed = 1f;
|
||||||
//boolean building;
|
//boolean building;
|
||||||
|
|
||||||
|
void updateBuilding(){
|
||||||
|
float finalPlaceDst = state.rules.infiniteResources ? Float.MAX_VALUE : placeDistance;
|
||||||
|
|
||||||
|
Iterator<BuildRequest> 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){
|
void removeBuild(int x, int y, boolean breaking){
|
||||||
//remove matching request
|
//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){
|
if(idx != -1){
|
||||||
player.buildQueue().removeIndex(idx);
|
requests.removeIndex(idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -475,10 +865,47 @@ public class EntityComps{
|
|||||||
@Nullable BuildRequest buildRequest(){
|
@Nullable BuildRequest buildRequest(){
|
||||||
return requests.size == 0 ? null : requests.first();
|
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)
|
@Component
|
||||||
class ShielderComp{
|
abstract class ShielderComp implements Damagec{
|
||||||
|
|
||||||
void absorb(){
|
void absorb(){
|
||||||
|
|
||||||
@@ -486,12 +913,16 @@ public class EntityComps{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
class ItemsComp{
|
abstract class ItemsComp{
|
||||||
ItemStack stack = new ItemStack();
|
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;
|
return stack.item;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -508,47 +939,50 @@ public class EntityComps{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component(VelComp.class)
|
@Component
|
||||||
class MassComp{
|
abstract class MassComp implements Velc{
|
||||||
float mass;
|
float mass;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({PosComp.class, DrawComp.class, TimedComp.class})
|
@Component
|
||||||
class EffectComp extends EntityComp{
|
abstract class EffectComp implements Posc, Drawc, Timedc{
|
||||||
Effect effect;
|
Effect effect;
|
||||||
Color color = new Color(Color.white);
|
Color color = new Color(Color.white);
|
||||||
Object data;
|
Object data;
|
||||||
float rotation = 0f;
|
float rotation = 0f;
|
||||||
|
|
||||||
void draw(){
|
public void draw(){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void update(){
|
public void update(){
|
||||||
//TODO fix effects, make everything poolable
|
//TODO fix effects, make everything poolable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
abstract class VelComp extends PosComp{
|
abstract class VelComp implements Posc{
|
||||||
|
transient float x, y;
|
||||||
|
|
||||||
final Vec2 vel = new Vec2();
|
final Vec2 vel = new Vec2();
|
||||||
float drag = 0f;
|
float drag = 0f;
|
||||||
|
|
||||||
void update(){
|
public void update(){
|
||||||
|
//TODO handle solidity
|
||||||
x += vel.x;
|
x += vel.x;
|
||||||
y += vel.y;
|
y += vel.y;
|
||||||
vel.scl(1f - drag * Time.delta());
|
vel.scl(1f - drag * Time.delta());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component(PosComp.class)
|
@Component
|
||||||
class HitboxComp{
|
abstract class HitboxComp implements Posc{
|
||||||
transient float x, y;
|
transient float x, y;
|
||||||
|
|
||||||
float hitSize;
|
float hitSize;
|
||||||
float lastX, lastY;
|
float lastX, lastY;
|
||||||
|
|
||||||
void update(){
|
public void update(){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -575,8 +1009,8 @@ public class EntityComps{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component(PosComp.class)
|
@Component
|
||||||
class StatusComp{
|
abstract class StatusComp implements Posc{
|
||||||
private Array<StatusEntry> statuses = new Array<>();
|
private Array<StatusEntry> statuses = new Array<>();
|
||||||
private Bits applied = new Bits(content.getBy(ContentType.status).size);
|
private Bits applied = new Bits(content.getBy(ContentType.status).size);
|
||||||
|
|
||||||
@@ -584,6 +1018,11 @@ public class EntityComps{
|
|||||||
private float damageMultiplier;
|
private float damageMultiplier;
|
||||||
private float armorMultiplier;
|
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){
|
void apply(StatusEffect effect, float duration){
|
||||||
if(effect == StatusEffects.none || effect == null || isImmune(effect)) return; //don't apply empty or immune effects
|
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
|
}else if(entry.effect.reactsWith(effect)){ //find opposite
|
||||||
StatusEntry.tmp.effect = entry.effect;
|
StatusEntry.tmp.effect = entry.effect;
|
||||||
//TODO unit cannot be null here
|
//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;
|
entry.time = StatusEntry.tmp.time;
|
||||||
|
|
||||||
if(StatusEntry.tmp.effect != entry.effect){
|
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);
|
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();
|
applied.clear();
|
||||||
speedMultiplier = damageMultiplier = armorMultiplier = 1f;
|
speedMultiplier = damageMultiplier = armorMultiplier = 1f;
|
||||||
|
|
||||||
@@ -651,8 +1101,8 @@ public class EntityComps{
|
|||||||
speedMultiplier *= entry.effect.speedMultiplier;
|
speedMultiplier *= entry.effect.speedMultiplier;
|
||||||
armorMultiplier *= entry.effect.armorMultiplier;
|
armorMultiplier *= entry.effect.armorMultiplier;
|
||||||
damageMultiplier *= entry.effect.damageMultiplier;
|
damageMultiplier *= entry.effect.damageMultiplier;
|
||||||
//TODO unit can't be null
|
//TODO ugly casting
|
||||||
entry.effect.update(null, entry.time);
|
entry.effect.update((mindustry.gen.Unitc)this, entry.time);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -694,6 +1144,10 @@ public class EntityComps{
|
|||||||
class EntityComp{
|
class EntityComp{
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
|
boolean isAdded(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void init(){}
|
void init(){}
|
||||||
|
|
||||||
void update(){}
|
void update(){}
|
||||||
@@ -707,8 +1161,7 @@ public class EntityComps{
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean isLocal(){
|
boolean isLocal(){
|
||||||
//TODO fix
|
return this == Vars.player;
|
||||||
return this == (Object)Vars.player;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<T> T as(Class<T> type){
|
<T> T as(Class<T> type){
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package mindustry.entities.effect;
|
|||||||
import arc.graphics.g2d.Draw;
|
import arc.graphics.g2d.Draw;
|
||||||
import arc.math.Mathf;
|
import arc.math.Mathf;
|
||||||
import mindustry.entities.EntityGroup;
|
import mindustry.entities.EntityGroup;
|
||||||
import mindustry.entities.type.TimedEntity;
|
|
||||||
import mindustry.graphics.Pal;
|
import mindustry.graphics.Pal;
|
||||||
|
|
||||||
import static mindustry.Vars.groundEffectGroup;
|
import static mindustry.Vars.groundEffectGroup;
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import arc.math.geom.*;
|
|||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
import mindustry.entities.traits.*;
|
|
||||||
import mindustry.entities.type.*;
|
import mindustry.entities.type.*;
|
||||||
import mindustry.game.EventType.*;
|
import mindustry.game.EventType.*;
|
||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import mindustry.Vars;
|
|||||||
import mindustry.entities.Effects;
|
import mindustry.entities.Effects;
|
||||||
import mindustry.entities.Effects.Effect;
|
import mindustry.entities.Effects.Effect;
|
||||||
import mindustry.entities.Effects.EffectRenderer;
|
import mindustry.entities.Effects.EffectRenderer;
|
||||||
import mindustry.entities.type.EffectEntity;
|
|
||||||
import mindustry.world.Tile;
|
import mindustry.world.Tile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,22 +1,19 @@
|
|||||||
package mindustry.entities.effect;
|
package mindustry.entities.effect;
|
||||||
|
|
||||||
import mindustry.annotations.Annotations.Loc;
|
|
||||||
import mindustry.annotations.Annotations.Remote;
|
|
||||||
import arc.graphics.g2d.*;
|
import arc.graphics.g2d.*;
|
||||||
import arc.math.Interpolation;
|
import arc.math.*;
|
||||||
import arc.math.Mathf;
|
import arc.math.geom.*;
|
||||||
import arc.math.geom.Position;
|
import arc.util.*;
|
||||||
import arc.math.geom.Vec2;
|
import arc.util.pooling.*;
|
||||||
import arc.util.Time;
|
import mindustry.annotations.Annotations.*;
|
||||||
import arc.util.pooling.Pools;
|
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
import mindustry.entities.type.TimedEntity;
|
import mindustry.entities.type.*;
|
||||||
import mindustry.entities.type.Unit;
|
import mindustry.gen.*;
|
||||||
import mindustry.graphics.Pal;
|
import mindustry.graphics.*;
|
||||||
import mindustry.type.Item;
|
import mindustry.type.*;
|
||||||
import mindustry.world.Tile;
|
import mindustry.world.*;
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.effectGroup;
|
||||||
|
|
||||||
public class ItemTransfer extends TimedEntity implements DrawTrait{
|
public class ItemTransfer extends TimedEntity implements DrawTrait{
|
||||||
private Vec2 from = new Vec2();
|
private Vec2 from = new Vec2();
|
||||||
@@ -31,14 +28,14 @@ public class ItemTransfer extends TimedEntity implements DrawTrait{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Remote(called = Loc.server, unreliable = true)
|
@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;
|
if(to == null) return;
|
||||||
create(item, x, y, to, () -> {
|
create(item, x, y, to, () -> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Remote(called = Loc.server, unreliable = true)
|
@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;
|
if(to == null) return;
|
||||||
create(item, x, y, to, () -> to.addItem(item));
|
create(item, x, y, to, () -> to.addItem(item));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,8 +13,6 @@ import mindustry.content.Bullets;
|
|||||||
import mindustry.entities.EntityGroup;
|
import mindustry.entities.EntityGroup;
|
||||||
import mindustry.entities.Units;
|
import mindustry.entities.Units;
|
||||||
import mindustry.entities.type.Bullet;
|
import mindustry.entities.type.Bullet;
|
||||||
import mindustry.entities.type.TimedEntity;
|
|
||||||
import mindustry.entities.type.Unit;
|
|
||||||
import mindustry.game.Team;
|
import mindustry.game.Team;
|
||||||
import mindustry.gen.Call;
|
import mindustry.gen.Call;
|
||||||
import mindustry.graphics.Pal;
|
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 Rand random = new Rand();
|
||||||
private static final Rect rect = new Rect();
|
private static final Rect rect = new Rect();
|
||||||
private static final Array<Unit> entities = new Array<>();
|
private static final Array<Unitc> entities = new Array<>();
|
||||||
private static final IntSet hit = new IntSet();
|
private static final IntSet hit = new IntSet();
|
||||||
private static final int maxChain = 8;
|
private static final int maxChain = 8;
|
||||||
private static final float hitRange = 30f;
|
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){
|
if(furthest != null){
|
||||||
hit.add(furthest.getID());
|
hit.add(furthest.getID());
|
||||||
|
|||||||
@@ -11,8 +11,6 @@ import arc.util.pooling.Pool.*;
|
|||||||
import arc.util.pooling.*;
|
import arc.util.pooling.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
import mindustry.entities.traits.*;
|
|
||||||
import mindustry.entities.type.*;
|
|
||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
|
|||||||
@@ -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<BuildRequest> 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<BuildRequest> 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.<BuildEntity>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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
package mindustry.entities.traits;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Marks an entity as serializable.
|
|
||||||
*/
|
|
||||||
public interface SaveTrait extends Entity, TypeTrait, Saveable{
|
|
||||||
byte version();
|
|
||||||
}
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -11,7 +11,6 @@ import mindustry.*;
|
|||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.ctype.ContentType;
|
import mindustry.ctype.ContentType;
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
import mindustry.entities.traits.*;
|
|
||||||
import mindustry.entities.units.*;
|
import mindustry.entities.units.*;
|
||||||
import mindustry.game.EventType.*;
|
import mindustry.game.EventType.*;
|
||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
@@ -31,7 +30,7 @@ import java.io.*;
|
|||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
/** Base class for AI units. */
|
/** 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 int timerIndex = 0;
|
||||||
|
|
||||||
protected static final int timerTarget = timerIndex++;
|
protected static final int timerTarget = timerIndex++;
|
||||||
@@ -151,7 +150,7 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void updateTargeting(){
|
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 instanceof TileEntity && ((TileEntity)target).tile.entity == null)){
|
||||||
target = null;
|
target = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import arc.util.pooling.*;
|
|||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
import mindustry.entities.bullet.*;
|
import mindustry.entities.bullet.*;
|
||||||
import mindustry.entities.effect.*;
|
import mindustry.entities.effect.*;
|
||||||
import mindustry.entities.traits.*;
|
|
||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
@@ -122,8 +121,8 @@ public class Bullet extends SolidEntity implements DamageTrait, Scaled, Poolable
|
|||||||
}
|
}
|
||||||
|
|
||||||
public float damageMultiplier(){
|
public float damageMultiplier(){
|
||||||
if(owner instanceof Unit){
|
if(owner instanceof Unitc){
|
||||||
return ((Unit)owner).getDamageMultipler();
|
return ((Unitc)owner).getDamageMultipler();
|
||||||
}
|
}
|
||||||
return 1f;
|
return 1f;
|
||||||
}
|
}
|
||||||
@@ -166,7 +165,7 @@ public class Bullet extends SolidEntity implements DamageTrait, Scaled, Poolable
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean collides(SolidTrait other){
|
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
|
@Override
|
||||||
@@ -174,8 +173,8 @@ public class Bullet extends SolidEntity implements DamageTrait, Scaled, Poolable
|
|||||||
if(!type.pierce) remove();
|
if(!type.pierce) remove();
|
||||||
type.hit(this, x, y);
|
type.hit(this, x, y);
|
||||||
|
|
||||||
if(other instanceof Unit){
|
if(other instanceof Unitc){
|
||||||
Unit unit = (Unit)other;
|
Unitc unit = (Unitc)other;
|
||||||
unit.velocity().add(Tmp.v3.set(other.getX(), other.getY()).sub(x, y).setLength(type.knockback / unit.mass()));
|
unit.velocity().add(Tmp.v3.set(other.getX(), other.getY()).sub(x, y).setLength(type.knockback / unit.mass()));
|
||||||
unit.applyEffect(type.status, type.statusDuration);
|
unit.applyEffect(type.status, type.statusDuration);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -34,7 +34,7 @@ import java.io.*;
|
|||||||
|
|
||||||
import static mindustry.Vars.*;
|
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 timerSync = 2;
|
||||||
public static final int timerAbility = 3;
|
public static final int timerAbility = 3;
|
||||||
private static final float liftoffBoost = 0.2f;
|
private static final float liftoffBoost = 0.2f;
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import java.io.*;
|
|||||||
|
|
||||||
import static mindustry.Vars.*;
|
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
|
public static final float timeToSleep = 60f * 1; //1 second to fall asleep
|
||||||
private static final ObjectSet<Tile> tmpTiles = new ObjectSet<>();
|
private static final ObjectSet<Tile> tmpTiles = new ObjectSet<>();
|
||||||
/** This value is only used for debugging. */
|
/** 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(){
|
public boolean isDead(){
|
||||||
return dead || tile.entity != this;
|
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
|
@Override
|
||||||
public void onDeath(){
|
public void onDeath(){
|
||||||
if(!dead){
|
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
|
@Override
|
||||||
public void update(){
|
public void update(){
|
||||||
timeScaleDuration -= Time.delta();
|
timeScaleDuration -= Time.delta();
|
||||||
@@ -339,11 +305,6 @@ public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{
|
|||||||
return !isDead() && tile.entity == this;
|
return !isDead() && tile.entity == this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityGroup targetGroup(){
|
|
||||||
return tileGroup;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString(){
|
public String toString(){
|
||||||
return "TileEntity{" +
|
return "TileEntity{" +
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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<? extends Unit> 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -3,7 +3,6 @@ package mindustry.entities.type.base;
|
|||||||
import arc.math.Mathf;
|
import arc.math.Mathf;
|
||||||
import arc.util.Structs;
|
import arc.util.Structs;
|
||||||
import mindustry.content.Blocks;
|
import mindustry.content.Blocks;
|
||||||
import mindustry.entities.traits.MinerTrait;
|
|
||||||
import mindustry.entities.type.TileEntity;
|
import mindustry.entities.type.TileEntity;
|
||||||
import mindustry.entities.units.UnitState;
|
import mindustry.entities.units.UnitState;
|
||||||
import mindustry.gen.Call;
|
import mindustry.gen.Call;
|
||||||
|
|||||||
@@ -7,8 +7,7 @@ import arc.util.*;
|
|||||||
import arc.util.pooling.*;
|
import arc.util.pooling.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.ctype.ContentType;
|
import mindustry.ctype.ContentType;
|
||||||
import mindustry.entities.traits.*;
|
import mindustry.entities.*;
|
||||||
import mindustry.entities.type.*;
|
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
@@ -27,7 +26,7 @@ public class Statuses implements Saveable{
|
|||||||
private float damageMultiplier;
|
private float damageMultiplier;
|
||||||
private float armorMultiplier;
|
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(effect == StatusEffects.none || effect == null || unit.isImmune(effect)) return; //don't apply empty or immune effects
|
||||||
|
|
||||||
if(statuses.size > 0){
|
if(statuses.size > 0){
|
||||||
@@ -76,7 +75,7 @@ public class Statuses implements Saveable{
|
|||||||
statuses.clear();
|
statuses.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update(Unit unit){
|
public void update(Unitc unit){
|
||||||
applied.clear();
|
applied.clear();
|
||||||
speedMultiplier = damageMultiplier = armorMultiplier = 1f;
|
speedMultiplier = damageMultiplier = armorMultiplier = 1f;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package mindustry.entities.units;
|
||||||
|
|
||||||
|
//TODO rename
|
||||||
|
public class UnitController{
|
||||||
|
}
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
package mindustry.game;
|
package mindustry.game;
|
||||||
|
|
||||||
import arc.util.ArcAnnotate.*;
|
import arc.util.ArcAnnotate.*;
|
||||||
import mindustry.core.GameState.State;
|
import mindustry.core.GameState.*;
|
||||||
import mindustry.ctype.UnlockableContent;
|
import mindustry.ctype.*;
|
||||||
import mindustry.entities.traits.BuilderTrait;
|
|
||||||
import mindustry.entities.type.*;
|
import mindustry.entities.type.*;
|
||||||
import mindustry.entities.units.*;
|
import mindustry.entities.units.*;
|
||||||
|
import mindustry.gen.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
import mindustry.world.Tile;
|
import mindustry.world.*;
|
||||||
|
|
||||||
public class EventType{
|
public class EventType{
|
||||||
|
|
||||||
@@ -280,10 +280,10 @@ public class EventType{
|
|||||||
public static class BuildSelectEvent{
|
public static class BuildSelectEvent{
|
||||||
public final Tile tile;
|
public final Tile tile;
|
||||||
public final Team team;
|
public final Team team;
|
||||||
public final BuilderTrait builder;
|
public final Builderc builder;
|
||||||
public final boolean breaking;
|
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.tile = tile;
|
||||||
this.team = team;
|
this.team = team;
|
||||||
this.builder = builder;
|
this.builder = builder;
|
||||||
@@ -302,17 +302,17 @@ public class EventType{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class UnitDestroyEvent{
|
public static class UnitDestroyEvent{
|
||||||
public final Unit unit;
|
public final Unitc unit;
|
||||||
|
|
||||||
public UnitDestroyEvent(Unit unit){
|
public UnitDestroyEvent(Unitc unit){
|
||||||
this.unit = unit;
|
this.unit = unit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class UnitCreateEvent{
|
public static class UnitCreateEvent{
|
||||||
public final BaseUnit unit;
|
public final Unitc unit;
|
||||||
|
|
||||||
public UnitCreateEvent(BaseUnit unit){
|
public UnitCreateEvent(Unitc unit){
|
||||||
this.unit = unit;
|
this.unit = unit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import static mindustry.Vars.*;
|
|||||||
|
|
||||||
public class MinimapRenderer implements Disposable{
|
public class MinimapRenderer implements Disposable{
|
||||||
private static final float baseSize = 16f;
|
private static final float baseSize = 16f;
|
||||||
private final Array<Unit> units = new Array<>();
|
private final Array<Unitc> units = new Array<>();
|
||||||
private Pixmap pixmap;
|
private Pixmap pixmap;
|
||||||
private Texture texture;
|
private Texture texture;
|
||||||
private TextureRegion region;
|
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);
|
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;
|
if(unit.isDead()) continue;
|
||||||
float rx = !withLabels ? (unit.x - rect.x) / rect.width * w : unit.x / (world.width() * tilesize) * w;
|
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;
|
float ry = !withLabels ? (unit.y - rect.y) / rect.width * h : unit.y / (world.height() * tilesize) * h;
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import mindustry.*;
|
|||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.core.GameState.*;
|
import mindustry.core.GameState.*;
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
import mindustry.entities.traits.*;
|
|
||||||
import mindustry.entities.type.*;
|
import mindustry.entities.type.*;
|
||||||
import mindustry.entities.units.*;
|
import mindustry.entities.units.*;
|
||||||
import mindustry.game.EventType.*;
|
import mindustry.game.EventType.*;
|
||||||
@@ -69,7 +68,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
|
|
||||||
/** Check and assign targets for a specific position. */
|
/** Check and assign targets for a specific position. */
|
||||||
void checkTargets(float x, float y){
|
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){
|
if(unit != null){
|
||||||
player.setMineTile(null);
|
player.setMineTile(null);
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import mindustry.core.*;
|
|||||||
import mindustry.ctype.*;
|
import mindustry.ctype.*;
|
||||||
import mindustry.ctype.ContentType;
|
import mindustry.ctype.ContentType;
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
import mindustry.entities.traits.*;
|
|
||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
import mindustry.game.Teams.*;
|
import mindustry.game.Teams.*;
|
||||||
import mindustry.maps.*;
|
import mindustry.maps.*;
|
||||||
|
|||||||
@@ -42,8 +42,8 @@ public class TypeIO{
|
|||||||
return id == -1 ? null : playerGroup.getByID(id);
|
return id == -1 ? null : playerGroup.getByID(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@WriteClass(Unit.class)
|
@WriteClass(Unitc.class)
|
||||||
public static void writeUnit(ByteBuffer buffer, Unit unit){
|
public static void writeUnit(ByteBuffer buffer, Unitc unit){
|
||||||
if(unit.getGroup() == null){
|
if(unit.getGroup() == null){
|
||||||
buffer.put((byte)-1);
|
buffer.put((byte)-1);
|
||||||
return;
|
return;
|
||||||
@@ -52,12 +52,12 @@ public class TypeIO{
|
|||||||
buffer.putInt(unit.getID());
|
buffer.putInt(unit.getID());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ReadClass(Unit.class)
|
@ReadClass(Unitc.class)
|
||||||
public static Unit readUnit(ByteBuffer buffer){
|
public static Unitc readUnit(ByteBuffer buffer){
|
||||||
byte gid = buffer.get();
|
byte gid = buffer.get();
|
||||||
if(gid == -1) return null;
|
if(gid == -1) return null;
|
||||||
int id = buffer.getInt();
|
int id = buffer.getInt();
|
||||||
return (Unit)entities.get(gid).getByID(id);
|
return (Unitc)entities.get(gid).getByID(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@WriteClass(ShooterTrait.class)
|
@WriteClass(ShooterTrait.class)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package mindustry.io.versions;
|
package mindustry.io.versions;
|
||||||
|
|
||||||
import arc.func.*;
|
import arc.func.*;
|
||||||
import mindustry.entities.traits.*;
|
import mindustry.entities.*;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package mindustry.io.versions;
|
package mindustry.io.versions;
|
||||||
|
|
||||||
import mindustry.ctype.ContentType;
|
import mindustry.ctype.ContentType;
|
||||||
import mindustry.entities.traits.*;
|
import mindustry.entities.*;
|
||||||
import mindustry.io.*;
|
import mindustry.io.*;
|
||||||
import mindustry.type.TypeID;
|
import mindustry.type.TypeID;
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,14 @@
|
|||||||
package mindustry.type;
|
package mindustry.type;
|
||||||
|
|
||||||
import arc.struct.*;
|
|
||||||
import arc.graphics.*;
|
import arc.graphics.*;
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
|
import arc.struct.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.ctype.*;
|
import mindustry.ctype.*;
|
||||||
import mindustry.ctype.ContentType;
|
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
import mindustry.entities.Effects.*;
|
|
||||||
import mindustry.entities.type.*;
|
|
||||||
import mindustry.entities.units.*;
|
import mindustry.entities.units.*;
|
||||||
|
import mindustry.gen.*;
|
||||||
|
|
||||||
public class StatusEffect extends MappableContent{
|
public class StatusEffect extends MappableContent{
|
||||||
/** Damage dealt by the unit with the effect. */
|
/** 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. */
|
/** 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){
|
if(damage > 0){
|
||||||
unit.damagePeriodic(damage);
|
unit.damageContinuous(damage);
|
||||||
}else if(damage < 0){ //heal unit
|
}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)){
|
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 time The current status effect time
|
||||||
* @param newTime The time that the new status effect will last
|
* @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)){
|
if(transitions.containsKey(to)){
|
||||||
transitions.get(to).handle(unit, time, newTime, result);
|
transitions.get(to).handle(unit, time, newTime, result);
|
||||||
return result;
|
return result;
|
||||||
@@ -98,6 +96,6 @@ public class StatusEffect extends MappableContent{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public interface TransitionHandler{
|
public interface TransitionHandler{
|
||||||
void handle(Unit unit, float time, float newTime, StatusEntry result);
|
void handle(Unitc unit, float time, float newTime, StatusEntry result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ public class UnitDef extends UnlockableContent{
|
|||||||
public Sound deathSound = Sounds.bang;
|
public Sound deathSound = Sounds.bang;
|
||||||
|
|
||||||
public Array<Weapon> weapons = new Array<>();
|
public Array<Weapon> weapons = new Array<>();
|
||||||
public TextureRegion baseRegion, legRegion, region;
|
public TextureRegion baseRegion, legRegion, region, cellRegion;
|
||||||
|
|
||||||
public UnitDef(String name){
|
public UnitDef(String name){
|
||||||
super(name);
|
super(name);
|
||||||
@@ -87,6 +87,7 @@ public class UnitDef extends UnlockableContent{
|
|||||||
region = Core.atlas.find(name);
|
region = Core.atlas.find(name);
|
||||||
legRegion = Core.atlas.find(name + "-leg");
|
legRegion = Core.atlas.find(name + "-leg");
|
||||||
baseRegion = Core.atlas.find(name + "-base");
|
baseRegion = Core.atlas.find(name + "-base");
|
||||||
|
cellRegion = Core.atlas.find(name + "-cell", Core.atlas.find("power-cell"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -96,13 +97,13 @@ public class UnitDef extends UnlockableContent{
|
|||||||
|
|
||||||
//TODO remove methods below!
|
//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){
|
if(drawCell){
|
||||||
float health = player.healthf();
|
float health = player.healthf();
|
||||||
Draw.color(Color.black, player.getTeam().color, health + Mathf.absin(Time.time(), health * 5f, 1f - health));
|
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;
|
return 0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO remove
|
//TODO remove
|
||||||
public float spreadX(Unit player){
|
public float spreadX(Unitc player){
|
||||||
return 0f;
|
return 0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO remove
|
//TODO remove
|
||||||
public float getRotationAlpha(Unit player){
|
public float getRotationAlpha(Unitc player){
|
||||||
return 1f;
|
return 1f;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canShoot(Unit player){
|
public boolean canShoot(Unitc player){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onLand(Unit player){
|
public void onLand(Unitc player){
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import arc.scene.ui.*;
|
|||||||
import arc.scene.ui.layout.*;
|
import arc.scene.ui.layout.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.core.GameState.*;
|
import mindustry.core.GameState.*;
|
||||||
import mindustry.entities.type.*;
|
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
import mindustry.net.*;
|
import mindustry.net.*;
|
||||||
@@ -66,7 +65,7 @@ public class PlayerListFragment extends Fragment{
|
|||||||
|
|
||||||
float h = 74f;
|
float h = 74f;
|
||||||
|
|
||||||
playerGroup.all().sort(Structs.comparing(Unit::getTeam));
|
playerGroup.all().sort(Structs.comparing(Unitc::getTeam));
|
||||||
playerGroup.all().each(user -> {
|
playerGroup.all().each(user -> {
|
||||||
NetConnection connection = user.con;
|
NetConnection connection = user.con;
|
||||||
|
|
||||||
|
|||||||
@@ -358,11 +358,11 @@ public class Block extends BlockStorage{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Called every frame a unit is on this tile. */
|
/** 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. */
|
/** 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. */
|
/** Returns whether ot not this block can be place on the specified tile. */
|
||||||
|
|||||||
@@ -1,21 +1,18 @@
|
|||||||
package mindustry.world;
|
package mindustry.world;
|
||||||
|
|
||||||
import arc.struct.Array;
|
import arc.math.*;
|
||||||
import arc.math.Mathf;
|
import arc.math.geom.*;
|
||||||
import arc.math.geom.Vec2;
|
import arc.struct.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.Vars;
|
import mindustry.*;
|
||||||
import mindustry.content.Fx;
|
import mindustry.content.*;
|
||||||
import mindustry.entities.Effects;
|
import mindustry.ctype.*;
|
||||||
import mindustry.entities.effect.Puddle;
|
import mindustry.entities.effect.*;
|
||||||
import mindustry.entities.type.TileEntity;
|
import mindustry.entities.type.*;
|
||||||
import mindustry.entities.type.Unit;
|
import mindustry.gen.*;
|
||||||
import mindustry.ctype.UnlockableContent;
|
import mindustry.type.*;
|
||||||
import mindustry.type.Item;
|
import mindustry.world.consumers.*;
|
||||||
import mindustry.type.Liquid;
|
import mindustry.world.meta.*;
|
||||||
import mindustry.world.consumers.Consumers;
|
|
||||||
import mindustry.world.meta.BlockBars;
|
|
||||||
import mindustry.world.meta.BlockStats;
|
|
||||||
|
|
||||||
public abstract class BlockStorage extends UnlockableContent{
|
public abstract class BlockStorage extends UnlockableContent{
|
||||||
public boolean hasItems;
|
public boolean hasItems;
|
||||||
@@ -51,7 +48,7 @@ public abstract class BlockStorage extends UnlockableContent{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the amount of items this block can accept. */
|
/** 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())){
|
if(acceptItem(item, tile, tile) && hasItems && (source == null || source.getTeam() == tile.getTeam())){
|
||||||
return Math.min(getMaximumAccepted(tile, item) - tile.entity.items.get(item), amount);
|
return Math.min(getMaximumAccepted(tile, item) - tile.entity.items.get(item), amount);
|
||||||
}else{
|
}else{
|
||||||
@@ -73,7 +70,7 @@ public abstract class BlockStorage extends UnlockableContent{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Handle a stack input. */
|
/** 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.noSleep();
|
||||||
tile.entity.items.add(item, amount);
|
tile.entity.items.add(item, amount);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -217,7 +217,7 @@ public class BuildBlock extends Block{
|
|||||||
private float[] accumulator;
|
private float[] accumulator;
|
||||||
private float[] totalAccumulator;
|
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){
|
if(cblock == null){
|
||||||
kill();
|
kill();
|
||||||
return false;
|
return false;
|
||||||
@@ -238,10 +238,7 @@ public class BuildBlock extends Block{
|
|||||||
maxProgress = core == null ? maxProgress : checkRequired(core.items, maxProgress, true);
|
maxProgress = core == null ? maxProgress : checkRequired(core.items, maxProgress, true);
|
||||||
|
|
||||||
progress = Mathf.clamp(progress + maxProgress);
|
progress = Mathf.clamp(progress + maxProgress);
|
||||||
|
builderID = builder.getId();
|
||||||
if(builder instanceof Player){
|
|
||||||
builderID = builder.getID();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(progress >= 1f || state.rules.infiniteResources){
|
if(progress >= 1f || state.rules.infiniteResources){
|
||||||
constructed(tile, cblock, builderID, tile.rotation(), builder.getTeam(), configured);
|
constructed(tile, cblock, builderID, tile.rotation(), builder.getTeam(), configured);
|
||||||
@@ -250,7 +247,7 @@ public class BuildBlock extends Block{
|
|||||||
return false;
|
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;
|
float deconstructMultiplier = 0.5f;
|
||||||
|
|
||||||
if(cblock != null){
|
if(cblock != null){
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
package mindustry.world.blocks;
|
package mindustry.world.blocks;
|
||||||
|
|
||||||
import arc.*;
|
import arc.*;
|
||||||
import arc.struct.*;
|
|
||||||
import arc.graphics.*;
|
import arc.graphics.*;
|
||||||
import arc.graphics.g2d.*;
|
import arc.graphics.g2d.*;
|
||||||
import arc.graphics.g2d.TextureAtlas.*;
|
import arc.graphics.g2d.TextureAtlas.*;
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
|
import arc.struct.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.entities.Effects.*;
|
import mindustry.entities.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
import mindustry.graphics.MultiPacker.*;
|
import mindustry.graphics.MultiPacker.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
|
|||||||
@@ -9,9 +9,7 @@ import arc.math.geom.*;
|
|||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
import mindustry.entities.traits.*;
|
|
||||||
import mindustry.entities.type.*;
|
import mindustry.entities.type.*;
|
||||||
import mindustry.entities.type.BaseEntity;
|
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
import mindustry.world.consumers.*;
|
import mindustry.world.consumers.*;
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import arc.graphics.g2d.Draw;
|
|||||||
import arc.graphics.g2d.Fill;
|
import arc.graphics.g2d.Fill;
|
||||||
import arc.math.Mathf;
|
import arc.math.Mathf;
|
||||||
import mindustry.entities.effect.Lightning;
|
import mindustry.entities.effect.Lightning;
|
||||||
import mindustry.entities.type.Unit;
|
|
||||||
import mindustry.graphics.Layer;
|
import mindustry.graphics.Layer;
|
||||||
import mindustry.graphics.Pal;
|
import mindustry.graphics.Pal;
|
||||||
import mindustry.world.Block;
|
import mindustry.world.Block;
|
||||||
@@ -49,7 +48,7 @@ public class ShockMine extends Block{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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)){
|
if(unit.getTeam() != tile.getTeam() && tile.entity.timer.get(timerDamage, cooldown)){
|
||||||
for(int i = 0; i < tendrils; i++){
|
for(int i = 0; i < tendrils; i++){
|
||||||
Lightning.create(tile.getTeam(), Pal.lancerLaser, damage, tile.drawx(), tile.drawy(), Mathf.random(360f), length);
|
Lightning.create(tile.getTeam(), Pal.lancerLaser, damage, tile.drawx(), tile.drawy(), Mathf.random(360f), length);
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ public class ItemTurret extends CooledTurret{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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();
|
TurretEntity entity = tile.ent();
|
||||||
|
|
||||||
BulletType type = ammo.get(item);
|
BulletType type = ammo.get(item);
|
||||||
@@ -97,7 +97,7 @@ public class ItemTurret extends CooledTurret{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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++){
|
for(int i = 0; i < amount; i++){
|
||||||
handleItem(item, tile, null);
|
handleItem(item, tile, null);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ public class Conveyor extends Block implements Autotiler{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unitOn(Tile tile, Unit unit){
|
public void unitOn(Tile tile, Unitc unit){
|
||||||
ConveyorEntity entity = tile.ent();
|
ConveyorEntity entity = tile.ent();
|
||||||
|
|
||||||
if(entity.clogHeat > 0.5f){
|
if(entity.clogHeat > 0.5f){
|
||||||
@@ -256,13 +256,13 @@ public class Conveyor extends Block implements Autotiler{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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();
|
ConveyorEntity entity = tile.ent();
|
||||||
return Math.min((int)(entity.minitem / itemSpace), amount);
|
return Math.min((int)(entity.minitem / itemSpace), amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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();
|
ConveyorEntity e = tile.ent();
|
||||||
|
|
||||||
for(int i = amount - 1; i >= 0; i--){
|
for(int i = amount - 1; i >= 0; i--){
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package mindustry.world.blocks.distribution;
|
|||||||
|
|
||||||
import arc.util.Time;
|
import arc.util.Time;
|
||||||
import mindustry.entities.type.TileEntity;
|
import mindustry.entities.type.TileEntity;
|
||||||
import mindustry.entities.type.Unit;
|
|
||||||
import mindustry.gen.BufferItem;
|
import mindustry.gen.BufferItem;
|
||||||
import mindustry.type.Item;
|
import mindustry.type.Item;
|
||||||
import mindustry.world.Block;
|
import mindustry.world.Block;
|
||||||
@@ -31,7 +30,7 @@ public class Junction extends Block{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import arc.graphics.g2d.*;
|
|||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.entities.*;
|
|
||||||
import mindustry.entities.traits.*;
|
import mindustry.entities.traits.*;
|
||||||
import mindustry.entities.type.*;
|
import mindustry.entities.type.*;
|
||||||
import mindustry.game.EventType.*;
|
import mindustry.game.EventType.*;
|
||||||
@@ -239,7 +238,7 @@ public class CoreBlock extends StorageBlock{
|
|||||||
protected int storageCapacity;
|
protected int storageCapacity;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasUnit(Unit unit){
|
public boolean hasUnit(Unitc unit){
|
||||||
return unit == spawnPlayer;
|
return unit == spawnPlayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,13 +9,11 @@ import arc.math.geom.*;
|
|||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import arc.util.ArcAnnotate.*;
|
import arc.util.ArcAnnotate.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.entities.*;
|
|
||||||
import mindustry.entities.traits.*;
|
import mindustry.entities.traits.*;
|
||||||
import mindustry.entities.type.*;
|
import mindustry.entities.type.*;
|
||||||
import mindustry.game.EventType.*;
|
import mindustry.game.EventType.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
import mindustry.type.*;
|
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
import mindustry.world.blocks.*;
|
import mindustry.world.blocks.*;
|
||||||
import mindustry.world.meta.*;
|
import mindustry.world.meta.*;
|
||||||
@@ -143,7 +141,7 @@ public class MechPad extends Block{
|
|||||||
float heat;
|
float heat;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasUnit(Unit unit){
|
public boolean hasUnit(Unitc unit){
|
||||||
return unit == player;
|
return unit == player;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import arc.math.geom.Rect;
|
|||||||
import arc.util.Time;
|
import arc.util.Time;
|
||||||
import mindustry.entities.Units;
|
import mindustry.entities.Units;
|
||||||
import mindustry.entities.type.TileEntity;
|
import mindustry.entities.type.TileEntity;
|
||||||
import mindustry.entities.type.Unit;
|
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
import mindustry.world.Block;
|
import mindustry.world.Block;
|
||||||
import mindustry.world.Tile;
|
import mindustry.world.Tile;
|
||||||
@@ -141,7 +140,7 @@ public class RepairPoint extends Block{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public class RepairPointEntity extends TileEntity{
|
public class RepairPointEntity extends TileEntity{
|
||||||
public Unit target;
|
public Unitc target;
|
||||||
public float strength, rotation = 90;
|
public float strength, rotation = 90;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ public class UnitFactory extends Block{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unitRemoved(Tile tile, Unit unit){
|
public void unitRemoved(Tile tile, Unitc unit){
|
||||||
UnitFactoryEntity entity = tile.ent();
|
UnitFactoryEntity entity = tile.ent();
|
||||||
entity.spawned--;
|
entity.spawned--;
|
||||||
entity.spawned = Math.max(entity.spawned, 0);
|
entity.spawned = Math.max(entity.spawned, 0);
|
||||||
|
|||||||
Reference in New Issue
Block a user