More cleanup

This commit is contained in:
Anuken
2020-02-03 20:24:49 -05:00
parent 88d2ec5be8
commit a942ed2cad
141 changed files with 2213 additions and 1819 deletions

View File

@@ -5,6 +5,7 @@ import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.math.geom.*;
import arc.math.geom.QuadTree.*;
import arc.scene.ui.layout.*;
import arc.struct.Bits;
import arc.struct.Queue;
@@ -19,7 +20,6 @@ import mindustry.ctype.*;
import mindustry.entities.*;
import mindustry.entities.bullet.*;
import mindustry.entities.effect.*;
import mindustry.entities.type.*;
import mindustry.entities.units.*;
import mindustry.game.EventType.*;
import mindustry.game.*;
@@ -31,18 +31,19 @@ import mindustry.ui.*;
import mindustry.world.*;
import mindustry.world.blocks.*;
import mindustry.world.blocks.BuildBlock.*;
import mindustry.world.consumers.*;
import mindustry.world.modules.*;
import java.io.*;
import java.util.*;
import static mindustry.Vars.*;
import static mindustry.entities.traits.BuilderTrait.BuildDataStatic.tmptr;
@SuppressWarnings("unused")
public class EntityComps{
@Component
abstract class UnitComp implements Healthc, Velc, Statusc, Teamc, Itemsc, Hitboxc, Rotc{
abstract class UnitComp implements Healthc, Velc, Statusc, Teamc, Itemsc, Hitboxc, Rotc, Massc{
UnitDef type;
UnitController controller;
@@ -138,8 +139,8 @@ public class EntityComps{
}
@Component
abstract class BulletComp implements Timedc, Damagec, Hitboxc, Teamc{
private boolean supressCollision, supressOnce, deflected;
abstract class BulletComp implements Timedc, Damagec, Hitboxc, Teamc, Posc, Drawc, Shielderc, Ownerc, Velc, Bulletc{
private float lifeScl;
Object data;
BulletType type;
@@ -148,196 +149,91 @@ public class EntityComps{
return type.damage;
}
public void init(){
//TODO
type.init((Bulletc)this);
public void add(){
type.init(this);
setDrag(type.drag);
setHitSize(type.hitSize);
setLifetime(lifeScl * type.lifetime);
}
public void remove(){
//TODO
type.despawned((Bulletc)this);
type.despawned(this);
}
public float getLifetime(){
return type.lifetime;
}
void deflect(){
supressCollision = true;
supressOnce = true;
deflected = true;
}
public boolean isDeflected(){
return deflected;
}
public float damageMultiplier(){
if(owner instanceof Unitc){
return ((Unitc)owner).getDamageMultipler();
if(getOwner() instanceof Unitc){
return ((Unitc)getOwner()).getDamageMultiplier();
}
return 1f;
}
@Override
public void killed(Entity other){
if(owner instanceof KillerTrait){
((KillerTrait)owner).killed(other);
}
}
@Override
public void absorb(){
supressCollision = true;
//TODO
remove();
}
@Override
public float drawSize(){
public float clipSize(){
return type.drawSize;
}
@Override
public float damage(){
if(owner instanceof Lightning && data instanceof Float){
return (Float)data;
}
return type.damage * damageMultiplier();
}
@Override
public Team getTeam(){
return team;
}
@Override
public float getShieldDamage(){
return Math.max(damage(), type.splashDamage);
}
@Override
public boolean collides(SolidTrait other){
return type.collides && (other != owner && !(other instanceof DamageTrait)) && !supressCollision && !(other instanceof Unitc && ((Unitc)other).isFlying() && !type.collidesAir);
}
@Override
public void collision(SolidTrait other, float x, float y){
public void collision(Hitboxc other, float x, float y){
if(!type.pierce) remove();
type.hit(this, x, y);
if(other instanceof Unitc){
Unitc unit = (Unitc)other;
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.getVel().add(Tmp.v3.set(other.getX(), other.getY()).sub(x, y).setLength(type.knockback / unit.getMass()));
unit.apply(type.status, type.statusDuration);
}
}
@Override
public void update(){
type.update(this);
x += velocity.x * Time.delta();
y += velocity.y * Time.delta();
velocity.scl(Mathf.clamp(1f - type.drag * Time.delta()));
time += Time.delta() * 1f / (lifeScl);
time = Mathf.clamp(time, 0, type.lifetime);
if(time >= type.lifetime){
if(!supressCollision) type.despawned(this);
remove();
}
if(type.hitTiles && collidesTiles() && !supressCollision && initialized){
world.raycastEach(world.toTile(lastPosition().x), world.toTile(lastPosition().y), world.toTile(x), world.toTile(y), (x, y) -> {
if(type.hitTiles){
world.raycastEach(world.toTile(getLastX()), world.toTile(getLastY()), tileX(), tileY(), (x, y) -> {
Tile tile = world.ltile(x, y);
if(tile == null) return false;
if(tile.entity != null && tile.entity.collide(this) && type.collides(this, tile) && !tile.entity.isDead() && (type.collidesTeam || tile.getTeam() != team)){
if(tile.getTeam() != team){
if(tile.entity != null && tile.entity.collide(this) && type.collides(this, tile) && !tile.entity.isDead() && (type.collidesTeam || tile.getTeam() != getTeam())){
if(tile.getTeam() != getTeam()){
tile.entity.collision(this);
}
if(!supressCollision){
type.hitTile(this, tile);
remove();
}
type.hitTile(this, tile);
remove();
return true;
}
return false;
});
}
if(supressOnce){
supressCollision = false;
supressOnce = false;
}
initialized = true;
}
@Override
public void reset(){
type = null;
owner = null;
velocity.setZero();
time = 0f;
timer.clear();
lifeScl = 1f;
team = null;
data = null;
supressCollision = false;
supressOnce = false;
deflected = false;
initialized = false;
}
@Override
public void hitbox(Rect rect){
rect.setSize(type.hitSize).setCenter(x, y);
}
@Override
public void hitboxTile(Rect rect){
rect.setSize(type.hitSize).setCenter(x, y);
}
@Override
public void draw(){
type.draw(this);
renderer.lights.add(x, y, 16f, Pal.powerLight, 0.3f);
}
@Override
public float fin(){
return time / type.lifetime;
}
@Override
public Vec2 velocity(){
return velocity;
}
public void velocity(float speed, float angle){
velocity.set(0, speed).setAngle(angle);
}
public void limit(float f){
velocity.limit(f);
//TODO refactor
renderer.lights.add(getX(), getY(), 16f, Pal.powerLight, 0.3f);
}
/** Sets the bullet's rotation in degrees. */
public void rot(float angle){
velocity.setAngle(angle);
public void setRotation(float angle){
getVel().setAngle(angle);
}
/** @return the bullet's rotation. */
public float rot(){
float angle = Mathf.atan2(velocity.x, velocity.y) * Mathf.radiansToDegrees;
public float getRotation(){
float angle = Mathf.atan2(getVel().x, getVel().y) * Mathf.radiansToDegrees;
if(angle < 0) angle += 360;
return angle;
}
@@ -491,17 +387,218 @@ public class EntityComps{
}
@Component
abstract class TileComp implements Posc, Teamc{
static abstract class TileComp implements Posc, Teamc, Healthc, Tilec{
static final float timeToSleep = 60f * 1;
static final ObjectSet<Tile> tmpTiles = new ObjectSet<>();
static int sleepingEntities = 0;
Tile tile;
Block block;
Array<Tile> proximity = new Array<>(8);
PowerModule power;
ItemModule items;
LiquidModule liquids;
ConsumeModule cons;
private Interval timer;
private float timeScale = 1f, timeScaleDuration;
private @Nullable SoundLoop sound;
private boolean sleeping;
private float sleepTime;
/** Sets this tile entity data to this tile, and adds it if necessary. */
public Tilec init(Tile tile, boolean shouldAdd){
this.tile = tile;
this.block = tile.block();
set(tile.drawx(), tile.drawy());
if(block.activeSound != Sounds.none){
sound = new SoundLoop(block.activeSound, block.activeSoundVolume);
}
setHealth(block.health);
setMaxHealth(block.health);
timer = new Interval(block.timers);
if(shouldAdd){
add();
}
return this;
}
public float getTimeScale(){
return timeScale;
}
public boolean consValid(){
return cons.valid();
}
public void consume(){
cons.trigger();
}
public boolean timer(int id, float time){
return timer.get(id, time);
}
/** Scaled delta. */
public float delta(){
return Time.delta() * timeScale;
}
/** Base efficiency. If this entity has non-buffered power, returns the power %, otherwise returns 1. */
public float efficiency(){
return power != null && (block.consumes.has(ConsumeType.power) && !block.consumes.getPower().buffered) ? power.status : 1f;
}
/** Call when nothing is happening to the entity. This increments the internal sleep timer. */
public void sleep(){
sleepTime += Time.delta();
if(!sleeping && sleepTime >= timeToSleep){
remove();
sleeping = true;
sleepingEntities++;
}
}
/** Call when this entity is updating. This wakes it up. */
public void noSleep(){
sleepTime = 0f;
if(sleeping){
add();
sleeping = false;
sleepingEntities--;
}
}
/** Returns the version of this TileEntity IO code.*/
public byte version(){
return 0;
}
public boolean collide(Bulletc other){
return true;
}
public void collision(Bulletc other){
block.handleBulletHit(this, other);
}
//TODO Implement damage!
public void removeFromProximity(){
block.onProximityRemoved(tile);
Point2[] nearby = Edges.getEdges(block.size);
for(Point2 point : nearby){
Tile other = world.ltile(tile.x + point.x, tile.y + point.y);
//remove this tile from all nearby tile's proximities
if(other != null){
other.block().onProximityUpdate(other);
if(other.entity != null){
other.entity.getProximity().remove(tile, true);
}
}
}
}
public void updateProximity(){
tmpTiles.clear();
proximity.clear();
Point2[] nearby = Edges.getEdges(block.size);
for(Point2 point : nearby){
Tile other = world.ltile(tile.x + point.x, tile.y + point.y);
if(other == null) continue;
if(other.entity == null || !(other.interactable(tile.getTeam()))) continue;
//add this tile to proximity of nearby tiles
if(!other.entity.getProximity().contains(tile, true)){
other.entity.getProximity().add(tile);
}
tmpTiles.add(other);
}
//using a set to prevent duplicates
for(Tile tile : tmpTiles){
proximity.add(tile);
}
block.onProximityAdded(tile);
block.onProximityUpdate(tile);
for(Tile other : tmpTiles){
other.block().onProximityUpdate(other);
}
}
public Array<Tile> proximity(){
return proximity;
}
/** Tile configuration. Defaults to 0. Used for block rebuilding. */
public int config(){
return 0;
}
public void remove(){
if(sound != null){
sound.stop();
}
}
public void killed(){
Events.fire(new BlockDestroyEvent(tile));
block.breakSound.at(tile);
block.onDestroyed(tile);
tile.remove();
}
public void update(){
timeScaleDuration -= Time.delta();
if(timeScaleDuration <= 0f || !block.canOverdrive){
timeScale = 1f;
}
if(sound != null){
sound.update(getX(), getY(), block.shouldActiveSound(tile));
}
if(block.idleSound != Sounds.none && block.shouldIdleSound(tile)){
loops.play(block.idleSound, this, block.idleSoundVolume);
}
block.update(tile);
if(liquids != null){
liquids.update();
}
if(cons != null){
cons.update();
}
if(power != null){
power.graph.update();
}
}
}
@Component
abstract class TeamComp implements Posc{
abstract class TeamComp implements Posc, Healthc{
transient float x, y;
Team team = Team.sharded;
public @Nullable TileEntity getClosestCore(){
public @Nullable Tilec getClosestCore(){
return state.teams.closestCore(x, y, team);
}
}
@@ -838,14 +935,14 @@ public class EntityComps{
}
void updateMining(){
TileEntity core = getClosestCore();
Tilec core = getClosestCore();
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, this);
int accepted = core.getTile().block().acceptStack(item(), getStack().amount, core.getTile(), this);
if(accepted > 0){
Call.transferItemTo(item(), accepted,
mineTile.worldx() + Mathf.range(tilesize / 2f),
mineTile.worldy() + Mathf.range(tilesize / 2f), core.tile);
mineTile.worldy() + Mathf.range(tilesize / 2f), core.getTile());
clearItem();
}
}
@@ -859,10 +956,10 @@ public class EntityComps{
if(Mathf.chance(Time.delta() * (0.06 - item.hardness * 0.01) * getMiningSpeed())){
if(dst(core) < mineTransferRange && core.tile.block().acceptStack(item, 1, core.tile, this) == 1 && offloadImmediately()){
if(dst(core) < mineTransferRange && core.getTile().block().acceptStack(item, 1, core.getTile(), this) == 1 && offloadImmediately()){
Call.transferItemTo(item, 1,
mineTile.worldx() + Mathf.range(tilesize / 2f),
mineTile.worldy() + Mathf.range(tilesize / 2f), core.tile);
mineTile.worldy() + Mathf.range(tilesize / 2f), core.getTile());
}else if(acceptsItem(item)){
//this is clientside, since items are synced anyway
ItemTransfer.transferItemToUnit(item,
@@ -927,7 +1024,7 @@ public class EntityComps{
}
}
TileEntity core = getClosestCore();
Tilec core = getClosestCore();
//nothing to build.
if(buildRequest() == null) return;
@@ -996,10 +1093,10 @@ public class EntityComps{
}
/** @return whether this request should be skipped, in favor of the next one. */
boolean shouldSkip(BuildRequest request, @Nullable TileEntity core){
boolean shouldSkip(BuildRequest request, @Nullable Tilec 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);
return request.stuck && !core.getItems().has(request.block.requirements);
}
void removeBuild(int x, int y, boolean breaking){
@@ -1163,7 +1260,7 @@ public class EntityComps{
}
@Component
abstract class HitboxComp implements Posc{
abstract class HitboxComp implements Posc, QuadTreeObject{
transient float x, y;
float hitSize;
@@ -1178,7 +1275,7 @@ public class EntityComps{
lastY = y;
}
void collision(Hitboxc other){
void collision(Hitboxc other, float x, float y){
}
@@ -1194,6 +1291,15 @@ public class EntityComps{
return Intersector.overlapsRect(x - hitSize/2f, y - hitSize/2f, hitSize, hitSize,
other.getX() - other.getHitSize()/2f, other.getY() - other.getHitSize()/2f, other.getHitSize(), other.getHitSize());
}
public void hitbox(Rect rect){
rect.setCentered(x, y, hitSize, hitSize);
}
public void hitboxTile(Rect rect){
float scale = 0.6f;
rect.setCentered(x, y, hitSize * scale, hitSize * scale);
}
}
@Component
@@ -1201,9 +1307,9 @@ public class EntityComps{
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;
float speedMultiplier;
float damageMultiplier;
float armorMultiplier;
/** @return damage taken based on status armor multipliers */
float getDamage(float amount){
@@ -1329,10 +1435,11 @@ public class EntityComps{
@Component
@BaseComponent
class EntityComp{
private boolean added;
int id;
boolean isAdded(){
return true;
return added;
}
void init(){}
@@ -1340,11 +1447,11 @@ public class EntityComps{
void update(){}
void remove(){
added = false;
}
void add(){
added = true;
}
boolean isLocal(){