New generators, projectors, status system, sprites renamed
This commit is contained in:
@@ -142,7 +142,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait {
|
||||
|
||||
@Override
|
||||
public float getArmor() {
|
||||
return 0f;
|
||||
return mech.armor;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -172,7 +172,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait {
|
||||
|
||||
@Override
|
||||
public void damage(float amount){
|
||||
CallEntity.onPlayerDamage(this, amount);
|
||||
CallEntity.onPlayerDamage(this, calculateDamage(amount));
|
||||
|
||||
if(health <= 0 && !dead && isLocal){
|
||||
CallEntity.onPlayerDeath(this);
|
||||
|
||||
@@ -1,69 +1,136 @@
|
||||
package io.anuke.mindustry.entities;
|
||||
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.Pools;
|
||||
import io.anuke.mindustry.content.StatusEffects;
|
||||
import io.anuke.mindustry.entities.traits.Saveable;
|
||||
import io.anuke.mindustry.type.StatusEffect;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
/**Class for controlling status effects on an entity.*/
|
||||
public class StatusController {
|
||||
private static final TransitionResult globalResult = new TransitionResult();
|
||||
public class StatusController implements Saveable{
|
||||
private static final StatusEntry globalResult = new StatusEntry();
|
||||
private static final Array<StatusEntry> removals = new Array<>();
|
||||
|
||||
private io.anuke.mindustry.type.StatusEffect current = StatusEffects.none;
|
||||
private float time;
|
||||
private Array<StatusEntry> statuses = new Array<>();
|
||||
|
||||
public void handleApply(Unit unit, io.anuke.mindustry.type.StatusEffect effect, float intensity){
|
||||
private float speedMultiplier;
|
||||
private float damageMultiplier;
|
||||
private float armorMultiplier;
|
||||
|
||||
public void handleApply(Unit unit, StatusEffect effect, float intensity){
|
||||
if(effect == StatusEffects.none) return; //don't apply empty effects
|
||||
|
||||
float newTime = effect.baseDuration*intensity;
|
||||
|
||||
if(effect == current){
|
||||
time = Math.max(time, newTime);
|
||||
}else {
|
||||
if(statuses.size > 0){
|
||||
//check for opposite effects
|
||||
for(StatusEntry entry : statuses){
|
||||
//extend effect
|
||||
if(entry.effect == effect) {
|
||||
entry.time = Math.max(entry.time, newTime);
|
||||
return;
|
||||
}else if(entry.effect.isOpposite(effect)){ //find opposite
|
||||
entry.effect.getTransition(unit, effect, entry.time, newTime, globalResult);
|
||||
entry.time = globalResult.time;
|
||||
|
||||
current.getTransition(unit, effect, time, newTime, globalResult);
|
||||
time = globalResult.time;
|
||||
if (globalResult.effect != entry.effect) {
|
||||
entry.effect.onTransition(unit, globalResult.effect);
|
||||
entry.effect = globalResult.effect;
|
||||
}
|
||||
|
||||
if (globalResult.result != current) {
|
||||
current.onTransition(unit, globalResult.result);
|
||||
current = globalResult.result;
|
||||
//stop looking when one is found
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//otherwise, no opposites found, add direct effect
|
||||
StatusEntry entry = Pools.obtain(StatusEntry.class);
|
||||
entry.set(effect, newTime);
|
||||
statuses.add(entry);
|
||||
}
|
||||
|
||||
public void clear(){
|
||||
current = StatusEffects.none;
|
||||
time = 0f;
|
||||
statuses.clear();
|
||||
}
|
||||
|
||||
public void update(Unit unit){
|
||||
time = Math.max(time - Timers.delta(), 0);
|
||||
speedMultiplier = damageMultiplier = armorMultiplier = 1f;
|
||||
|
||||
if(time <= 0){
|
||||
current = StatusEffects.none;
|
||||
}else{
|
||||
current.update(unit, time);
|
||||
if(statuses.size == 0) return;
|
||||
|
||||
removals.clear();
|
||||
|
||||
for(StatusEntry entry : statuses){
|
||||
entry.time = Math.max(entry.time - Timers.delta(), 0);
|
||||
|
||||
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 void set(io.anuke.mindustry.type.StatusEffect current, float time){
|
||||
this.current = current;
|
||||
this.time = time;
|
||||
public float getSpeedMultiplier(){
|
||||
return speedMultiplier;
|
||||
}
|
||||
|
||||
public io.anuke.mindustry.type.StatusEffect current() {
|
||||
return current;
|
||||
public float getDamageMultiplier(){
|
||||
return damageMultiplier;
|
||||
}
|
||||
|
||||
public float getTime() {
|
||||
return time;
|
||||
public float getArmorMultiplier() {
|
||||
return armorMultiplier;
|
||||
}
|
||||
|
||||
public static class TransitionResult{
|
||||
public io.anuke.mindustry.type.StatusEffect result;
|
||||
public boolean hasEffect(StatusEffect effect){
|
||||
for(StatusEntry entry : statuses){
|
||||
if(entry.effect == effect) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeSave(DataOutput stream) throws IOException {
|
||||
stream.writeByte(statuses.size);
|
||||
for(StatusEntry entry : statuses){
|
||||
stream.writeByte(entry.effect.id);
|
||||
stream.writeShort((short)(entry.time * 2));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readSave(DataInput stream) throws IOException {
|
||||
byte amount = stream.readByte();
|
||||
for (int i = 0; i < amount; i++) {
|
||||
byte id = stream.readByte();
|
||||
float time = stream.readShort() / 2f;
|
||||
StatusEntry entry = Pools.obtain(StatusEntry.class);
|
||||
entry.set(StatusEffect.getByID(id), time);
|
||||
statuses.add(entry);
|
||||
}
|
||||
}
|
||||
|
||||
public static class StatusEntry {
|
||||
public StatusEffect effect;
|
||||
public float time;
|
||||
|
||||
public TransitionResult set(StatusEffect effect, float time){
|
||||
this.result = effect;
|
||||
public StatusEntry set(StatusEffect effect, float time){
|
||||
this.effect = effect;
|
||||
this.time = time;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
||||
|
||||
@Override
|
||||
public void damage(float amount){
|
||||
super.damage(amount * Mathf.clamp(1f-getArmor()/100f));
|
||||
super.damage(calculateDamage(amount));
|
||||
hitTime = hitDuration;
|
||||
}
|
||||
|
||||
@@ -117,17 +117,15 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
||||
byte yv = stream.readByte();
|
||||
float rotation = stream.readShort()/2f;
|
||||
int health = stream.readShort();
|
||||
byte effect = stream.readByte();
|
||||
float etime = stream.readShort()/2f;
|
||||
|
||||
this.inventory.read(stream);
|
||||
this.status.readSave(stream);
|
||||
this.inventory.readSave(stream);
|
||||
this.team = Team.values()[team];
|
||||
this.health = health;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.velocity.set(xv / velocityPercision, yv / velocityPercision);
|
||||
this.rotation = rotation;
|
||||
this.status.set(StatusEffect.getByID(effect), etime);
|
||||
}
|
||||
|
||||
public void writeSave(DataOutput stream, boolean net) throws IOException {
|
||||
@@ -138,13 +136,20 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
||||
stream.writeByte((byte)(Mathf.clamp(velocity.y, -maxAbsVelocity, maxAbsVelocity) * velocityPercision));
|
||||
stream.writeShort((short)(rotation*2));
|
||||
stream.writeShort((short)health);
|
||||
stream.writeByte(status.current().id);
|
||||
stream.writeShort((short)(status.getTime()*2));
|
||||
inventory.write(stream);
|
||||
status.writeSave(stream);
|
||||
inventory.writeSave(stream);
|
||||
}
|
||||
|
||||
public StatusEffect getStatus(){
|
||||
return status.current();
|
||||
public float calculateDamage(float amount){
|
||||
return amount * Mathf.clamp(1f-getArmor()/100f*status.getArmorMultiplier());
|
||||
}
|
||||
|
||||
public float getDamageMultipler(){
|
||||
return status.getDamageMultiplier();
|
||||
}
|
||||
|
||||
public boolean hasEffect(StatusEffect effect){
|
||||
return status.hasEffect(effect);
|
||||
}
|
||||
|
||||
public TileEntity getClosestCore(){
|
||||
@@ -178,10 +183,10 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
||||
Floor floor = getFloorOn();
|
||||
Tile tile = world.tileWorld(x, y);
|
||||
|
||||
velocity.limit(maxVelocity);
|
||||
|
||||
status.update(this);
|
||||
|
||||
velocity.limit(maxVelocity).scl(status.getSpeedMultiplier());
|
||||
|
||||
if(isFlying()) {
|
||||
x += velocity.x / getMass() * Timers.delta();
|
||||
y += velocity.y / getMass() * Timers.delta();
|
||||
|
||||
@@ -2,6 +2,7 @@ package io.anuke.mindustry.entities;
|
||||
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import io.anuke.mindustry.content.Items;
|
||||
import io.anuke.mindustry.entities.traits.Saveable;
|
||||
import io.anuke.mindustry.type.AmmoEntry;
|
||||
import io.anuke.mindustry.type.AmmoType;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
@@ -9,7 +10,7 @@ import io.anuke.mindustry.type.ItemStack;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public class UnitInventory {
|
||||
public class UnitInventory implements Saveable{
|
||||
private Array<AmmoEntry> ammos = new Array<>();
|
||||
private int totalAmmo;
|
||||
private ItemStack item = new ItemStack(Items.stone, 0);
|
||||
@@ -30,7 +31,8 @@ public class UnitInventory {
|
||||
infiniteAmmo = infinite;
|
||||
}
|
||||
|
||||
public void write(DataOutput stream) throws IOException {
|
||||
@Override
|
||||
public void writeSave(DataOutput stream) throws IOException {
|
||||
stream.writeShort(item.amount);
|
||||
stream.writeByte(item.item.id);
|
||||
stream.writeBoolean(infiniteAmmo);
|
||||
@@ -42,7 +44,8 @@ public class UnitInventory {
|
||||
}
|
||||
}
|
||||
|
||||
public void read(DataInput stream) throws IOException {
|
||||
@Override
|
||||
public void readSave(DataInput stream) throws IOException {
|
||||
short iamount = stream.readShort();
|
||||
byte iid = stream.readByte();
|
||||
infiniteAmmo = stream.readBoolean();
|
||||
|
||||
@@ -100,6 +100,15 @@ public class Bullet extends BulletEntity<BulletType> implements TeamTrait, SyncT
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getDamage(){
|
||||
if(owner instanceof Unit){
|
||||
return super.getDamage() * ((Unit) owner).getDamageMultipler();
|
||||
}
|
||||
|
||||
return super.getDamage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTypeID() {
|
||||
return typeID;
|
||||
|
||||
@@ -89,7 +89,7 @@ public class Lightning extends TimedEntity implements Poolable, DrawTrait{
|
||||
if(hitrect.contains(x2, y2) || hitrect.contains(fx, fy)){
|
||||
float result = damage;
|
||||
|
||||
if(entity.getStatus() == StatusEffects.wet)
|
||||
if(entity.hasEffect(StatusEffects.wet))
|
||||
result = (result * wetDamageMultiplier);
|
||||
|
||||
entity.damage(result);
|
||||
|
||||
@@ -2,12 +2,6 @@ package io.anuke.mindustry.entities.traits;
|
||||
|
||||
import io.anuke.ucore.entities.trait.Entity;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
/**Marks an entity as serializable.*/
|
||||
public interface SaveTrait extends Entity, TypeTrait{
|
||||
void writeSave(DataOutput stream) throws IOException;
|
||||
void readSave(DataInput stream) throws IOException;
|
||||
public interface SaveTrait extends Entity, TypeTrait, Saveable{
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package io.anuke.mindustry.entities.traits;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
public interface Saveable {
|
||||
void writeSave(DataOutput stream) throws IOException;
|
||||
void readSave(DataInput stream) throws IOException;
|
||||
}
|
||||
Reference in New Issue
Block a user