it is done
This commit is contained in:
24
core/src/mindustry/entities/units/StateMachine.java
Normal file
24
core/src/mindustry/entities/units/StateMachine.java
Normal file
@@ -0,0 +1,24 @@
|
||||
package mindustry.entities.units;
|
||||
|
||||
public class StateMachine{
|
||||
private UnitState state;
|
||||
|
||||
public void update(){
|
||||
if(state != null) state.update();
|
||||
}
|
||||
|
||||
public void set(UnitState next){
|
||||
if(next == state) return;
|
||||
if(state != null) state.exited();
|
||||
this.state = next;
|
||||
if(next != null) next.entered();
|
||||
}
|
||||
|
||||
public UnitState current(){
|
||||
return state;
|
||||
}
|
||||
|
||||
public boolean is(UnitState state){
|
||||
return this.state == state;
|
||||
}
|
||||
}
|
||||
160
core/src/mindustry/entities/units/Statuses.java
Normal file
160
core/src/mindustry/entities/units/Statuses.java
Normal file
@@ -0,0 +1,160 @@
|
||||
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.traits.*;
|
||||
import mindustry.entities.type.*;
|
||||
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(Unit 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(Unit 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);
|
||||
}
|
||||
}
|
||||
|
||||
public static class StatusEntry{
|
||||
public StatusEffect effect;
|
||||
public float time;
|
||||
|
||||
public StatusEntry set(StatusEffect effect, float time){
|
||||
this.effect = effect;
|
||||
this.time = time;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
18
core/src/mindustry/entities/units/UnitCommand.java
Normal file
18
core/src/mindustry/entities/units/UnitCommand.java
Normal file
@@ -0,0 +1,18 @@
|
||||
package mindustry.entities.units;
|
||||
|
||||
import arc.*;
|
||||
|
||||
public enum UnitCommand{
|
||||
attack, retreat, rally;
|
||||
|
||||
private final String localized;
|
||||
public static final UnitCommand[] all = values();
|
||||
|
||||
UnitCommand(){
|
||||
localized = Core.bundle.get("command." + name());
|
||||
}
|
||||
|
||||
public String localized(){
|
||||
return localized;
|
||||
}
|
||||
}
|
||||
47
core/src/mindustry/entities/units/UnitDrops.java
Normal file
47
core/src/mindustry/entities/units/UnitDrops.java
Normal file
@@ -0,0 +1,47 @@
|
||||
package mindustry.entities.units;
|
||||
|
||||
import arc.math.Mathf;
|
||||
import mindustry.Vars;
|
||||
import mindustry.content.Items;
|
||||
import mindustry.entities.type.BaseUnit;
|
||||
import mindustry.entities.type.TileEntity;
|
||||
import mindustry.gen.Call;
|
||||
import mindustry.type.Item;
|
||||
|
||||
public class UnitDrops{
|
||||
private static Item[] dropTable;
|
||||
|
||||
public static void dropItems(BaseUnit unit){
|
||||
//items only dropped in waves for enemy team
|
||||
if(unit.getTeam() != Vars.waveTeam || !Vars.state.rules.unitDrops){
|
||||
return;
|
||||
}
|
||||
|
||||
TileEntity 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
12
core/src/mindustry/entities/units/UnitState.java
Normal file
12
core/src/mindustry/entities/units/UnitState.java
Normal file
@@ -0,0 +1,12 @@
|
||||
package mindustry.entities.units;
|
||||
|
||||
public interface UnitState{
|
||||
default void entered(){
|
||||
}
|
||||
|
||||
default void exited(){
|
||||
}
|
||||
|
||||
default void update(){
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user