UnitType cleanup

This commit is contained in:
Anuken
2020-02-04 11:40:56 -05:00
parent 006004fd70
commit 1d0cfd4435
14 changed files with 76 additions and 236 deletions

View File

@ -248,8 +248,8 @@ public class EntityProcess extends BaseProcessor{
if(method.name().length() <= 3) continue;
String var = Strings.camelize(method.name().substring(method.name().startsWith("is") ? 2 : 3));
//make sure it's a real variable
if(!Array.with(def.builder.fieldSpecs).contains(f -> f.name.equals(var))) continue;
//make sure it's a real variable AND that the component doesn't already implement it with custom logic
if(!Array.with(def.builder.fieldSpecs).contains(f -> f.name.equals(var)) || comp.methods().contains(m -> m.name().equals(method.name()))) continue;
if(method.name().startsWith("get") || method.name().startsWith("is")){
def.builder.addMethod(MethodSpec.overriding(method.e).addStatement("return " + var).build());

View File

@ -43,14 +43,37 @@ import static mindustry.Vars.*;
public class EntityComps{
@Component
abstract class UnitComp implements Healthc, Velc, Statusc, Teamc, Itemsc, Hitboxc, Rotc, Massc{
UnitDef type;
UnitController controller;
abstract class UnitComp implements Healthc, Velc, Statusc, Teamc, Itemsc, Hitboxc, Rotc, Massc, Unitc, Weaponsc{
private UnitController controller;
private UnitDef type;
float getBounds(){
public float getBounds(){
return getHitSize() * 2f;
}
public void setController(UnitController controller){
this.controller = controller;
controller.set(this);
}
public UnitController getController(){
return controller;
}
public void set(UnitDef def, UnitController controller){
setType(type);
setController(controller);
}
public void setType(UnitDef type){
this.type = type;
setupWeapons(type);
}
public UnitDef getType(){
return type;
}
public void update(){
//apply knockback based on spawns
//TODO move elsewhere
@ -97,7 +120,7 @@ public class EntityComps{
Damage.dynamicExplosion(getX(), getY(), flammability, explosiveness, 0f, getBounds() / 2f, Pal.darkFlame);
//TODO cleanup
ScorchDecal.create(getX(), getY());
//ScorchDecal.create(getX(), getY());
Fx.explosion.at(this);
Effects.shake(2f, 2f, this);
@ -617,7 +640,7 @@ public class EntityComps{
/** weapon mount array, never null */
WeaponMount[] mounts = {};
void init(UnitDef def){
void setupWeapons(UnitDef def){
mounts = new WeaponMount[def.weapons.size];
for(int i = 0; i < mounts.length; i++){
mounts[i] = new WeaponMount(def.weapons.get(i));
@ -811,6 +834,11 @@ public class EntityComps{
Draw.rect(region, getX(), getY(), getRotation());
Draw.color();
}
public float clipSize(){
return region.getWidth()*2;
}
}
@Component

View File

@ -9,7 +9,7 @@ import mindustry.world.meta.BlockFlag;
import static mindustry.Vars.*;
public abstract class BaseDrone extends FlyingUnit{
public final UnitState retreat = new UnitState(){
public final StateMachine.UnitState retreat = new StateMachine.UnitState(){
public void entered(){
target = null;
}
@ -63,6 +63,6 @@ public abstract class BaseDrone extends FlyingUnit{
}
@Override
public abstract UnitState getStartState();
public abstract StateMachine.UnitState getStartState();
}

View File

@ -27,9 +27,9 @@ public class BuilderDrone extends BaseDrone implements BuilderTrait{
protected boolean isBreaking;
protected Player playerTarget;
public final UnitState
public final StateMachine.UnitState
build = new UnitState(){
build = new StateMachine.UnitState(){
public void entered(){
if(!(target instanceof BuildEntity)){
@ -206,7 +206,7 @@ public class BuilderDrone extends BaseDrone implements BuilderTrait{
}
@Override
public UnitState getStartState(){
public StateMachine.UnitState getStartState(){
return build;
}

View File

@ -8,7 +8,6 @@ import arc.util.*;
import mindustry.*;
import mindustry.entities.*;
import mindustry.entities.bullet.*;
import mindustry.entities.type.*;
import mindustry.entities.units.*;
import mindustry.graphics.*;
import mindustry.world.*;
@ -19,9 +18,9 @@ import static mindustry.Vars.*;
public class FlyingUnit extends BaseUnit{
protected float[] weaponAngles = {0,0};
protected final UnitState
protected final StateMachine.UnitState
attack = new UnitState(){
attack = new StateMachine.UnitState(){
public void entered(){
target = null;
}
@ -75,7 +74,7 @@ public class FlyingUnit extends BaseUnit{
}
}
},
rally = new UnitState(){
rally = new StateMachine.UnitState(){
public void update(){
if(retarget()){
targetClosestAllyFlag(BlockFlag.rally);
@ -94,7 +93,7 @@ public class FlyingUnit extends BaseUnit{
}
}
},
retreat = new UnitState(){
retreat = new StateMachine.UnitState(){
public void entered(){
target = null;
}
@ -183,7 +182,7 @@ public class FlyingUnit extends BaseUnit{
}
@Override
public UnitState getStartState(){
public StateMachine.UnitState getStartState(){
return attack;
}

View File

@ -9,7 +9,6 @@ import mindustry.*;
import mindustry.ai.Pathfinder.*;
import mindustry.entities.*;
import mindustry.entities.bullet.*;
import mindustry.entities.type.*;
import mindustry.entities.units.*;
import mindustry.game.*;
import mindustry.world.*;
@ -25,9 +24,9 @@ public class GroundUnit extends BaseUnit{
protected float stuckTime;
protected float baseRotation;
public final UnitState
public final StateMachine.UnitState
attack = new UnitState(){
attack = new StateMachine.UnitState(){
public void entered(){
target = null;
}
@ -53,7 +52,7 @@ public class GroundUnit extends BaseUnit{
}
}
},
rally = new UnitState(){
rally = new StateMachine.UnitState(){
public void update(){
Tile target = getClosest(BlockFlag.rally);
@ -62,7 +61,7 @@ public class GroundUnit extends BaseUnit{
}
}
},
retreat = new UnitState(){
retreat = new StateMachine.UnitState(){
public void entered(){
target = null;
}
@ -99,7 +98,7 @@ public class GroundUnit extends BaseUnit{
}
@Override
public UnitState getStartState(){
public StateMachine.UnitState getStartState(){
return attack;
}

View File

@ -4,7 +4,7 @@ import arc.math.Mathf;
import arc.util.Structs;
import mindustry.content.Blocks;
import mindustry.gen.*;
import mindustry.entities.units.UnitState;
import mindustry.entities.units.StateMachine.UnitState;
import mindustry.gen.Call;
import mindustry.type.Item;
import mindustry.type.ItemType;

View File

@ -2,7 +2,7 @@ package mindustry.entities.type.base;
import mindustry.entities.Units;
import mindustry.gen.*;
import mindustry.entities.units.UnitState;
import mindustry.entities.units.StateMachine.UnitState;
import mindustry.world.Pos;
import mindustry.world.Tile;
import mindustry.world.blocks.*;

View File

@ -0,0 +1,4 @@
package mindustry.entities.units;
public class AIController extends UnitController{
}

View File

@ -21,4 +21,15 @@ public class StateMachine{
public boolean is(UnitState state){
return this.state == state;
}
public interface UnitState{
default void entered(){
}
default void exited(){
}
default void update(){
}
}
}

View File

@ -1,149 +0,0 @@
package mindustry.entities.units;
import arc.struct.Bits;
import arc.struct.*;
import arc.graphics.*;
import arc.util.*;
import arc.util.pooling.*;
import mindustry.content.*;
import mindustry.ctype.ContentType;
import mindustry.entities.*;
import mindustry.type.*;
import java.io.*;
import static mindustry.Vars.content;
/** Class for controlling status effects on an entity. */
public class Statuses implements Saveable{
private static final StatusEntry globalResult = new StatusEntry();
private static final Array<StatusEntry> removals = new Array<>();
private Array<StatusEntry> statuses = new Array<>();
private Bits applied = new Bits(content.getBy(ContentType.status).size);
private float speedMultiplier;
private float damageMultiplier;
private float armorMultiplier;
public void handleApply(Unitc unit, StatusEffect effect, float duration){
if(effect == StatusEffects.none || effect == null || unit.isImmune(effect)) return; //don't apply empty or immune effects
if(statuses.size > 0){
//check for opposite effects
for(StatusEntry entry : statuses){
//extend effect
if(entry.effect == effect){
entry.time = Math.max(entry.time, duration);
return;
}else if(entry.effect.reactsWith(effect)){ //find opposite
globalResult.effect = entry.effect;
entry.effect.getTransition(unit, effect, entry.time, duration, globalResult);
entry.time = globalResult.time;
if(globalResult.effect != entry.effect){
entry.effect = globalResult.effect;
}
//stop looking when one is found
return;
}
}
}
//otherwise, no opposites found, add direct effect
StatusEntry entry = Pools.obtain(StatusEntry.class, StatusEntry::new);
entry.set(effect, duration);
statuses.add(entry);
}
public Color getStatusColor(){
if(statuses.size == 0){
return Tmp.c1.set(Color.white);
}
float r = 0f, g = 0f, b = 0f;
for(StatusEntry entry : statuses){
r += entry.effect.color.r;
g += entry.effect.color.g;
b += entry.effect.color.b;
}
return Tmp.c1.set(r / statuses.size, g / statuses.size, b / statuses.size, 1f);
}
public void clear(){
statuses.clear();
}
public void update(Unitc unit){
applied.clear();
speedMultiplier = damageMultiplier = armorMultiplier = 1f;
if(statuses.size == 0) return;
removals.clear();
for(StatusEntry entry : statuses){
entry.time = Math.max(entry.time - Time.delta(), 0);
applied.set(entry.effect.id);
if(entry.time <= 0){
Pools.free(entry);
removals.add(entry);
}else{
speedMultiplier *= entry.effect.speedMultiplier;
armorMultiplier *= entry.effect.armorMultiplier;
damageMultiplier *= entry.effect.damageMultiplier;
entry.effect.update(unit, entry.time);
}
}
if(removals.size > 0){
statuses.removeAll(removals, true);
}
}
public float getSpeedMultiplier(){
return speedMultiplier;
}
public float getDamageMultiplier(){
return damageMultiplier;
}
public float getArmorMultiplier(){
return armorMultiplier;
}
public boolean hasEffect(StatusEffect effect){
return applied.get(effect.id);
}
@Override
public void writeSave(DataOutput stream) throws IOException{
stream.writeByte(statuses.size);
for(StatusEntry entry : statuses){
stream.writeByte(entry.effect.id);
stream.writeFloat(entry.time);
}
}
@Override
public void readSave(DataInput stream, byte version) throws IOException{
for(StatusEntry effect : statuses){
Pools.free(effect);
}
statuses.clear();
byte amount = stream.readByte();
for(int i = 0; i < amount; i++){
byte id = stream.readByte();
float time = stream.readFloat();
StatusEntry entry = Pools.obtain(StatusEntry.class, StatusEntry::new);
entry.set(content.getByID(ContentType.status, id), time);
statuses.add(entry);
}
}
}

View File

@ -1,5 +1,12 @@
package mindustry.entities.units;
import mindustry.gen.*;
//TODO rename
public class UnitController{
public abstract class UnitController{
protected Unitc unit;
public void set(Unitc unit){
this.unit = unit;
}
}

View File

@ -1,47 +0,0 @@
package mindustry.entities.units;
import arc.math.Mathf;
import mindustry.Vars;
import mindustry.content.Items;
import mindustry.gen.*;
import mindustry.gen.Call;
import mindustry.type.Item;
import static mindustry.Vars.*;
public class UnitDrops{
private static Item[] dropTable;
public static void dropItems(BaseUnit unit){
//items only dropped in waves for enemy team
if(unit.getTeam() != state.rules.waveTeam || !Vars.state.rules.unitDrops){
return;
}
Tilec core = unit.getClosestEnemyCore();
if(core == null || core.dst(unit) > Vars.mineTransferRange){
return;
}
if(dropTable == null){
dropTable = new Item[]{Items.titanium, Items.silicon, Items.lead, Items.copper};
}
for(int i = 0; i < 3; i++){
for(Item item : dropTable){
//only drop unlocked items
if(!Vars.headless && !Vars.data.isUnlocked(item)){
continue;
}
if(Mathf.chance(0.03)){
int amount = Mathf.random(20, 40);
amount = core.tile.block().acceptStack(item, amount, core.tile, null);
if(amount > 0){
Call.transferItemTo(item, amount, unit.x + Mathf.range(2f), unit.y + Mathf.range(2f), core.tile);
}
}
}
}
}
}

View File

@ -1,12 +0,0 @@
package mindustry.entities.units;
public interface UnitState{
default void entered(){
}
default void exited(){
}
default void update(){
}
}