Added item drops, fixed various bugs

This commit is contained in:
Anuken
2018-06-04 16:17:24 -04:00
parent a6225962b0
commit 2a5118326a
35 changed files with 233 additions and 81 deletions
@@ -11,6 +11,7 @@ import io.anuke.mindustry.Vars;
import io.anuke.mindustry.content.Mechs;
import io.anuke.mindustry.content.Weapons;
import io.anuke.mindustry.entities.effect.DamageArea;
import io.anuke.mindustry.entities.effect.ItemDrop;
import io.anuke.mindustry.entities.traits.BuilderTrait;
import io.anuke.mindustry.entities.traits.TargetTrait;
import io.anuke.mindustry.game.Team;
@@ -22,7 +23,7 @@ import io.anuke.mindustry.world.blocks.types.Floor;
import io.anuke.mindustry.world.blocks.types.storage.CoreBlock.CoreEntity;
import io.anuke.ucore.core.*;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.entities.component.SolidTrait;
import io.anuke.ucore.entities.trait.SolidTrait;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Fill;
import io.anuke.ucore.graphics.Lines;
@@ -145,10 +146,10 @@ public class Player extends Unit implements BuilderTrait {
}
@Override
public boolean collides(SolidTrait other){
return !isDead() && super.collides(other) && !mech.flying;
public boolean collides(SolidTrait other) {
return super.collides(other) || other instanceof ItemDrop;
}
@Override
public void onDeath(){
dead = true;
@@ -1,16 +1,17 @@
package io.anuke.mindustry.entities;
import io.anuke.mindustry.content.StatusEffects;
import io.anuke.mindustry.type.StatusEffect;
import io.anuke.ucore.core.Timers;
/**Class for controlling status effects on an entity.*/
public class StatusController {
private static final TransitionResult globalResult = new TransitionResult();
private StatusEffect current = StatusEffects.none;
private io.anuke.mindustry.type.StatusEffect current = StatusEffects.none;
private float time;
public void handleApply(Unit unit, StatusEffect effect, float intensity){
public void handleApply(Unit unit, io.anuke.mindustry.type.StatusEffect effect, float intensity){
if(effect == StatusEffects.none) return; //don't apply empty effects
float newTime = effect.baseDuration*intensity;
@@ -44,12 +45,12 @@ public class StatusController {
}
}
public void set(StatusEffect current, float time){
public void set(io.anuke.mindustry.type.StatusEffect current, float time){
this.current = current;
this.time = time;
}
public StatusEffect current() {
public io.anuke.mindustry.type.StatusEffect current() {
return current;
}
@@ -58,7 +59,7 @@ public class StatusController {
}
public static class TransitionResult{
public StatusEffect result;
public io.anuke.mindustry.type.StatusEffect result;
public float time;
public TransitionResult set(StatusEffect effect, float time){
@@ -1,61 +0,0 @@
package io.anuke.mindustry.entities;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.ObjectSet;
import io.anuke.mindustry.entities.StatusController.TransitionResult;
public class StatusEffect{
private static final Array<StatusEffect> array = new Array<>();
private static int lastid;
/**Duration of this status effect in ticks at maximum power.*/
public final float baseDuration;
public final int id;
/**Set of 'opposite' effects, which will decrease the duration of this effect when applied.*/
protected ObjectSet<StatusEffect> opposites = new ObjectSet<>();
/**The strength of time decrease when met with an opposite effect, as a fraction of the other's duration.*/
protected float oppositeScale = 0.5f;
public StatusEffect(float baseDuration){
this.baseDuration = baseDuration;
id = lastid++;
array.add(this);
}
/**Runs every tick on the affected unit while time is greater than 0.*/
public void update(Unit unit, float time){}
/**Called when transitioning between two status effects.
* @param to The state to transition to
* @param time The current status effect time
* @param newTime The time that the new status effect will last*/
public TransitionResult getTransition(Unit unit, StatusEffect to, float time, float newTime, TransitionResult result){
if(opposites.contains(to)){
time -= newTime*oppositeScale;
if(time > 0) {
return result.set(this, time);
}
}
return result.set(to, newTime);
}
/**Called when this effect transitions to a new status effect.*/
public void onTransition(Unit unit, StatusEffect to){}
public void setOpposites(StatusEffect... effects){
for(StatusEffect e : effects){
opposites.add(e);
}
}
public static StatusEffect getByID(int id){
return array.get(id);
}
public static Array<StatusEffect> getAllEffects(){
return array;
}
}
@@ -2,7 +2,6 @@ package io.anuke.mindustry.entities;
import com.badlogic.gdx.math.Vector2;
import io.anuke.mindustry.content.blocks.Blocks;
import io.anuke.mindustry.entities.bullet.Bullet;
import io.anuke.mindustry.entities.traits.SaveTrait;
import io.anuke.mindustry.entities.traits.SyncTrait;
import io.anuke.mindustry.entities.traits.TargetTrait;
@@ -11,12 +10,14 @@ import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.game.TeamInfo.TeamData;
import io.anuke.mindustry.net.Interpolator;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.StatusEffect;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.Floor;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.component.DrawTrait;
import io.anuke.ucore.entities.component.SolidTrait;
import io.anuke.ucore.entities.trait.DamageTrait;
import io.anuke.ucore.entities.trait.DrawTrait;
import io.anuke.ucore.entities.trait.SolidTrait;
import io.anuke.ucore.entities.impl.DestructibleEntity;
import io.anuke.ucore.util.Geometry;
import io.anuke.ucore.util.Mathf;
@@ -70,7 +71,8 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
@Override
public boolean collides(SolidTrait other){
return other instanceof Bullet && state.teams.areEnemies((((Bullet) other).team), team);
return other instanceof DamageTrait && other
instanceof TeamTrait && state.teams.areEnemies((((TeamTrait) other).getTeam()), team) && !isDead();
}
@Override
@@ -110,10 +112,10 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
this.health = health;
this.x = x;
this.y = y;
this.status.set(StatusEffect.getByID(effect), etime);
this.status.set(io.anuke.mindustry.type.StatusEffect.getByID(effect), etime);
}
public StatusEffect getStatus(){
public io.anuke.mindustry.type.StatusEffect getStatus(){
return status.current();
}
@@ -27,10 +27,6 @@ public class UnitInventory {
return item != null && item.amount >= capacity;
}
public boolean isInfiniteAmmo() {
return infiniteAmmo;
}
public void setInfiniteAmmo(boolean infinite){
infiniteAmmo = infinite;
}
@@ -137,6 +133,10 @@ public class UnitInventory {
return !hasItem() || (item.item == type && capacity - item.amount > 0);
}
public boolean canAcceptItem(Item type, int amount){
return !hasItem() || (item.item == type && item.amount + amount <= capacity);
}
public void clear(){
item = null;
ammos.clear();
@@ -7,16 +7,16 @@ import io.anuke.mindustry.entities.traits.TeamTrait;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.entities.component.Entity;
import io.anuke.ucore.entities.component.SolidTrait;
import io.anuke.ucore.entities.component.VelocityTrait;
import io.anuke.ucore.entities.trait.Entity;
import io.anuke.ucore.entities.trait.SolidTrait;
import io.anuke.ucore.entities.trait.VelocityTrait;
import io.anuke.ucore.entities.impl.BulletEntity;
import io.anuke.ucore.util.Timer;
import static io.anuke.mindustry.Vars.bulletGroup;
import static io.anuke.mindustry.Vars.world;
public class Bullet extends BulletEntity<BulletType>{
public class Bullet extends BulletEntity<BulletType> implements TeamTrait{
private static Vector2 vector = new Vector2();
public Timer timer = new Timer(3);
@@ -52,6 +52,11 @@ public class Bullet extends BulletEntity<BulletType>{
return true; //TODO make artillery and such not do this
}
@Override
public Team getTeam() {
return team;
}
@Override
public void draw(){
type.draw(this);
@@ -3,7 +3,7 @@ package io.anuke.mindustry.entities.bullet;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.content.StatusEffects;
import io.anuke.mindustry.content.fx.BulletFx;
import io.anuke.mindustry.entities.StatusEffect;
import io.anuke.mindustry.type.StatusEffect;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.entities.impl.BaseBulletType;
@@ -13,7 +13,7 @@ import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.entities.component.DrawTrait;
import io.anuke.ucore.entities.trait.DrawTrait;
import io.anuke.ucore.entities.impl.TimedEntity;
import io.anuke.ucore.util.Geometry;
import io.anuke.ucore.util.Mathf;
@@ -32,6 +32,7 @@ public class Fire extends TimedEntity implements SaveTrait, Poolable, DrawTrait
private Tile tile;
private Block block;
private float baseFlammability = -1, puddleFlammability;
private float lifetime;
/**Start a fire on the tile. If there already is a file there, refreshes its lifetime..*/
public static void create(Tile tile){
@@ -59,6 +60,11 @@ public class Fire extends TimedEntity implements SaveTrait, Poolable, DrawTrait
/**Deserialization use only!*/
public Fire(){}
@Override
public float lifetime() {
return lifetime;
}
@Override
public void update() {
super.update();
@@ -153,6 +159,6 @@ public class Fire extends TimedEntity implements SaveTrait, Poolable, DrawTrait
@Override
public EntityGroup targetGroup() {
return airItemGroup;
return fireGroup;
}
}
@@ -22,7 +22,7 @@ public class GroundEffectEntity extends EffectEntity {
time = Mathf.clamp(time, 0, effect.staticLife);
if (!once && time >= lifetime) {
if (!once && time >= lifetime()) {
once = true;
time = 0f;
Tile tile = Vars.world.tileWorld(x, y);
@@ -42,7 +42,7 @@ public class GroundEffectEntity extends EffectEntity {
GroundEffect effect = (GroundEffect)this.effect;
if(once && effect.isStatic)
Effects.renderEffect(id, effect, color, lifetime, rotation, x, y, data);
Effects.renderEffect(id, effect, color, lifetime(), rotation, x, y, data);
else
Effects.renderEffect(id, effect, color, time, rotation, x, y, data);
}
@@ -1,28 +1,133 @@
package io.anuke.mindustry.entities.effect;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Pool.Poolable;
import com.badlogic.gdx.utils.Pools;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.traits.SyncTrait;
import io.anuke.mindustry.net.Interpolator;
import io.anuke.mindustry.type.Item;
import io.anuke.ucore.entities.component.DrawTrait;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.entities.impl.SolidEntity;
import io.anuke.ucore.entities.trait.DrawTrait;
import io.anuke.ucore.entities.trait.SolidTrait;
import io.anuke.ucore.entities.trait.TimeTrait;
import io.anuke.ucore.entities.trait.VelocityTrait;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.util.Mathf;
import java.nio.ByteBuffer;
public class ItemDrop extends SolidEntity implements SyncTrait, DrawTrait {
import static io.anuke.mindustry.Vars.itemGroup;
import static io.anuke.mindustry.Vars.itemSize;
import static io.anuke.mindustry.Vars.world;
public class ItemDrop extends SolidEntity implements SyncTrait, DrawTrait, VelocityTrait, TimeTrait, Poolable {
private static final float sinkLifetime = 80f;
private Interpolator interpolator = new Interpolator();
private Item item;
private int amount;
public static ItemDrop create(Item item, float x, float y){
private Vector2 velocity = new Vector2();
private float time;
private float sinktime;
public static ItemDrop create(Item item, int amount, float x, float y, float angle){
ItemDrop drop = Pools.obtain(ItemDrop.class);
drop.item = item;
drop.amount = amount;
drop.velocity.set(4f, 0f).rotate(angle);
drop.set(x, y);
drop.add();
return drop;
}
/**Internal use only!*/
public ItemDrop(){}
public ItemDrop(){
hitbox.setSize(5f);
}
@Override
public float lifetime() {
return 60*60;
}
@Override
public void time(float time) {
this.time = time;
}
@Override
public float time() {
return time;
}
@Override
public Vector2 getVelocity() {
return velocity;
}
@Override
public boolean collides(SolidTrait other) {
return other instanceof Player && time > 20f;
}
@Override
public void collision(SolidTrait other, float x, float y) {
Player player = (Player)other;
if(player.inventory.canAcceptItem(item, amount)){
player.inventory.addItem(item, amount);
remove();
}
}
@Override
public void draw() {
float size = itemSize * (1f - sinktime/sinkLifetime);
Tile tile = world.tileWorld(x, y);
Draw.color(Color.WHITE, tile == null || !tile.floor().liquid ? Color.WHITE : tile.floor().liquidColor, sinktime/sinkLifetime);
Draw.rect(item.region, x, y, size, size);
int stored = Mathf.clamp(amount / 6, 1, 8);
for(int i = 0; i < stored; i ++) {
float px = Mathf.randomSeedRange(i + 1, 4f);
float py = Mathf.randomSeedRange(i + 2, 4f);
Draw.rect(item.region, x + px, y + py, size, size);
}
Draw.color();
}
@Override
public void update() {
updateVelocity(0.2f);
updateTime();
Tile tile = world.tileWorld(x, y);
if(tile.floor().liquid){
sinktime += Timers.delta();
if(Mathf.chance(0.04 * Timers.delta())){
Effects.effect(tile.floor().drownUpdateEffect, tile.floor().liquidColor, x, y);
}
if(sinktime >= sinkLifetime){
remove();
}
}else{
sinktime = 0f;
}
}
@Override
public void removed() {
@@ -30,8 +135,8 @@ public class ItemDrop extends SolidEntity implements SyncTrait, DrawTrait {
}
@Override
public void draw() {
public void reset() {
time = 0f;
}
@Override
@@ -44,6 +149,11 @@ public class ItemDrop extends SolidEntity implements SyncTrait, DrawTrait {
return 10;
}
@Override
public EntityGroup targetGroup() {
return itemGroup;
}
@Override
public void write(ByteBuffer data) {
data.putFloat(x);
@@ -52,6 +162,7 @@ public class ItemDrop extends SolidEntity implements SyncTrait, DrawTrait {
@Override
public void read(ByteBuffer data, long time) {
x = data.getFloat();
y = data.getFloat();
}
}
@@ -6,14 +6,14 @@ import com.badlogic.gdx.utils.Pools;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.type.Item;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.entities.component.DrawTrait;
import io.anuke.ucore.entities.trait.DrawTrait;
import io.anuke.ucore.entities.impl.TimedEntity;
import io.anuke.ucore.function.Callable;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Fill;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Position;
import io.anuke.ucore.entities.trait.PosTrait;
import static io.anuke.mindustry.Vars.effectGroup;
@@ -23,22 +23,26 @@ public class ItemTransfer extends TimedEntity implements DrawTrait{
private Vector2 tovec = new Vector2();
private Item item;
private float seed;
private Position to;
private PosTrait to;
private Callable done;
public static void create(Item item, float fromx, float fromy, Position to, Callable done){
public static void create(Item item, float fromx, float fromy, PosTrait to, Callable done){
ItemTransfer tr = Pools.obtain(ItemTransfer.class);
tr.item = item;
tr.from.set(fromx, fromy);
tr.to = to;
tr.done = done;
tr.lifetime = 60f;
tr.seed = Mathf.range(1f);
tr.add();
}
public ItemTransfer(){}
@Override
public float lifetime() {
return 60;
}
@Override
public void reset() {
super.reset();
@@ -13,7 +13,7 @@ import io.anuke.mindustry.graphics.Palette;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.entities.component.SolidTrait;
import io.anuke.ucore.entities.trait.SolidTrait;
import io.anuke.ucore.entities.impl.TimedEntity;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Lines;
@@ -39,7 +39,6 @@ public class Lightning extends TimedEntity implements Poolable{
l.x = x;
l.y = y;
l.lifetime = 10f;
l.color = color;
float step = 3f;
@@ -100,6 +99,11 @@ public class Lightning extends TimedEntity implements Poolable{
/**For pooling use only. Do not call directly!*/
public Lightning(){}
@Override
public float lifetime() {
return 10;
}
@Override
public void reset() {
color = Palette.lancerLaser;
@@ -20,7 +20,7 @@ import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.entities.component.DrawTrait;
import io.anuke.ucore.entities.trait.DrawTrait;
import io.anuke.ucore.entities.impl.BaseEntity;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Fill;
@@ -22,8 +22,9 @@ public class Rubble extends TimedEntity implements BelowLiquidTrait {
rubble.add();
}
public Rubble(){
lifetime = 7000f;
@Override
public float lifetime() {
return 7000f;
}
@Override
@@ -1,6 +1,6 @@
package io.anuke.mindustry.entities.traits;
import io.anuke.ucore.entities.component.Entity;
import io.anuke.ucore.entities.trait.Entity;
import java.io.DataInputStream;
import java.io.DataOutputStream;
@@ -2,7 +2,7 @@ package io.anuke.mindustry.entities.traits;
import com.badlogic.gdx.Gdx;
import io.anuke.mindustry.net.Interpolator;
import io.anuke.ucore.entities.component.Entity;
import io.anuke.ucore.entities.trait.Entity;
import java.nio.ByteBuffer;
@@ -1,11 +1,11 @@
package io.anuke.mindustry.entities.traits;
import io.anuke.mindustry.game.Team;
import io.anuke.ucore.entities.component.VelocityTrait;
import io.anuke.ucore.util.Position;
import io.anuke.ucore.entities.trait.VelocityTrait;
import io.anuke.ucore.entities.trait.PosTrait;
/**Base interface for targetable entities.*/
public interface TargetTrait extends Position, VelocityTrait {
public interface TargetTrait extends PosTrait, VelocityTrait {
boolean isDead();
Team getTeam();
@@ -1,7 +1,7 @@
package io.anuke.mindustry.entities.traits;
import io.anuke.mindustry.game.Team;
import io.anuke.ucore.entities.component.Entity;
import io.anuke.ucore.entities.trait.Entity;
public interface TeamTrait extends Entity {
Team getTeam();