Merging changes from private branch
This commit is contained in:
@@ -16,7 +16,6 @@ import arc.util.*;
|
||||
import arc.util.io.*;
|
||||
import mindustry.*;
|
||||
import mindustry.annotations.Annotations.*;
|
||||
import mindustry.audio.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.core.*;
|
||||
import mindustry.ctype.*;
|
||||
@@ -47,7 +46,7 @@ import java.util.*;
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
@EntityDef(value = {Buildingc.class}, isFinal = false, genio = false, serialize = false)
|
||||
@Component(base = true)
|
||||
@Component(base = true, genInterface = false)
|
||||
abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, QuadTreeObject, Displayable, Sized, Senseable, Controllable, Settable{
|
||||
//region vars and initialization
|
||||
static final float timeToSleep = 60f * 1, recentDamageTime = 60f * 5f;
|
||||
@@ -63,7 +62,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
|
||||
transient Tile tile;
|
||||
transient Block block;
|
||||
transient Seq<Building> proximity = new Seq<>(6);
|
||||
transient Seq<Building> proximity = new Seq<>(true, 6, Building.class);
|
||||
transient int cdump;
|
||||
transient int rotation;
|
||||
transient float payloadRotation;
|
||||
@@ -99,8 +98,6 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
private transient float timeScale = 1f, timeScaleDuration;
|
||||
private transient float dumpAccum;
|
||||
|
||||
private transient @Nullable SoundLoop sound;
|
||||
|
||||
private transient boolean sleeping;
|
||||
private transient float sleepTime;
|
||||
private transient boolean initialized;
|
||||
@@ -126,6 +123,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
add();
|
||||
}
|
||||
|
||||
checkAllowUpdate();
|
||||
created();
|
||||
|
||||
return self();
|
||||
@@ -136,10 +134,6 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
this.block = block;
|
||||
this.team = team;
|
||||
|
||||
if(block.loopSound != Sounds.none){
|
||||
sound = new SoundLoop(block.loopSound, block.loopSoundVolume);
|
||||
}
|
||||
|
||||
health = block.health;
|
||||
maxHealth(block.health);
|
||||
timer(new Interval(block.timers));
|
||||
@@ -342,13 +336,14 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
}
|
||||
|
||||
public @Nullable Tile findClosestEdge(Position to, Boolf<Tile> solid){
|
||||
if(to == null) return null;
|
||||
Tile best = null;
|
||||
float mindst = 0f;
|
||||
for(var point : Edges.getEdges(block.size)){
|
||||
Tile other = Vars.world.tile(tile.x + point.x, tile.y + point.y);
|
||||
if(other != null && !solid.get(other) && (best == null || to.dst2(other) < mindst)){
|
||||
best = other;
|
||||
mindst = other.dst2(other);
|
||||
mindst = other.dst2(to);
|
||||
}
|
||||
}
|
||||
return best;
|
||||
@@ -473,6 +468,15 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
return lastDamageTime + recentDamageTime >= Time.time;
|
||||
}
|
||||
|
||||
public void eachEdge(Cons<Tile> cons){
|
||||
for(var edge : block.getEdges()){
|
||||
Tile other = world.tile(tile.x + edge.x, tile.y + edge.y);
|
||||
if(other != null){
|
||||
cons.get(other);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Building nearby(int dx, int dy){
|
||||
return world.build(tile.x + dx, tile.y + dy);
|
||||
}
|
||||
@@ -809,6 +813,10 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canBeReplaced(Block other){
|
||||
return other.canReplace(block);
|
||||
}
|
||||
|
||||
public void handleItem(Building source, Item item){
|
||||
items.add(item, 1);
|
||||
}
|
||||
@@ -1066,7 +1074,10 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
}
|
||||
|
||||
public void incrementDump(int prox){
|
||||
cdump = ((cdump + 1) % prox);
|
||||
//this is possible if transferring an item changed a block
|
||||
if(prox != 0){
|
||||
cdump = ((cdump + 1) % prox);
|
||||
}
|
||||
}
|
||||
|
||||
/** Used for dumping items. */
|
||||
@@ -1092,6 +1103,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
}
|
||||
|
||||
/** Called after this building is created in the world. May be called multiple times, or when adjacent buildings change. */
|
||||
//TODO ??? this is just onProximityUpdate ?
|
||||
public void onProximityAdded(){
|
||||
if(power != null){
|
||||
updatePowerGraph();
|
||||
@@ -1156,16 +1168,6 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
return getProgressIncrease(1f) / edelta();
|
||||
}
|
||||
|
||||
/** @return whether this block should play its active sound.*/
|
||||
public boolean shouldActiveSound(){
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @return volume cale of active sound. */
|
||||
public float activeSoundVolume(){
|
||||
return 1f;
|
||||
}
|
||||
|
||||
/** @return whether this block should play its idle sound.*/
|
||||
public boolean shouldAmbientSound(){
|
||||
return shouldConsume();
|
||||
@@ -1315,14 +1317,23 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
public void onRemoved(){
|
||||
}
|
||||
|
||||
/** Called every frame a unit is on this */
|
||||
/** Called every frame a unit is on this. Hovering/flying/steppy units do not apply. */
|
||||
public void unitOn(Unit unit){
|
||||
}
|
||||
|
||||
/** Called every frame a unit is on this. Applies to any unit. */
|
||||
public void unitOnAny(Unit unit){
|
||||
}
|
||||
|
||||
/** Called when a unit that spawned at this tile is removed. */
|
||||
public void unitRemoved(Unit unit){
|
||||
}
|
||||
|
||||
/** Called when a puddle is on this building. Only called at an interval (40 ticks). */
|
||||
public void puddleOn(Puddle puddle){
|
||||
|
||||
}
|
||||
|
||||
/** Called when arbitrary configuration is applied to a tile. */
|
||||
public void configured(@Nullable Unit builder, @Nullable Object value){
|
||||
//null is of type void.class; anonymous classes use their superclass.
|
||||
@@ -1372,6 +1383,19 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
return block.itemCapacity;
|
||||
}
|
||||
|
||||
public void splashLiquid(Liquid liquid, float amount){
|
||||
float splash = Mathf.clamp(amount / 4f, 0f, 10f);
|
||||
|
||||
for(int i = 0; i < Mathf.clamp(amount / 5, 0, 30); i++){
|
||||
Time.run(i / 2f, () -> {
|
||||
Tile other = world.tileWorld(x + Mathf.range(block.size * tilesize / 2), y + Mathf.range(block.size * tilesize / 2));
|
||||
if(other != null){
|
||||
Puddles.deposit(other, liquid, splash);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/** Called when a block begins (not finishes!) deconstruction. The building is still present at this point. */
|
||||
public void onDeconstructed(@Nullable Unit builder){
|
||||
//deposit non-incinerable liquid on ground
|
||||
@@ -1383,9 +1407,6 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
|
||||
/** Called when the block is destroyed. The tile is still intact at this stage. */
|
||||
public void onDestroyed(){
|
||||
if(sound != null){
|
||||
sound.stop();
|
||||
}
|
||||
|
||||
float explosiveness = block.baseExplosiveness;
|
||||
float flammability = 0f;
|
||||
@@ -1411,22 +1432,11 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
|
||||
if(block.hasLiquids && state.rules.damageExplosions){
|
||||
|
||||
liquids.each((liquid, amount) -> {
|
||||
float splash = Mathf.clamp(amount / 4f, 0f, 10f);
|
||||
|
||||
for(int i = 0; i < Mathf.clamp(amount / 5, 0, 30); i++){
|
||||
Time.run(i / 2f, () -> {
|
||||
Tile other = world.tileWorld(x + Mathf.range(block.size * tilesize / 2), y + Mathf.range(block.size * tilesize / 2));
|
||||
if(other != null){
|
||||
Puddles.deposit(other, liquid, splash);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
liquids.each(this::splashLiquid);
|
||||
}
|
||||
|
||||
//cap explosiveness so fluid tanks/vaults don't instakill units
|
||||
Damage.dynamicExplosion(x, y, flammability, explosiveness * 3.5f, power, tilesize * block.size / 2f, state.rules.damageExplosions, block.destroyEffect);
|
||||
Damage.dynamicExplosion(x, y, flammability, explosiveness * 3.5f, power, tilesize * block.size / 2f, state.rules.damageExplosions, block.destroyEffect, block.baseShake);
|
||||
|
||||
if(block.createRubble && !floor().solid && !floor().isLiquid){
|
||||
Effect.rubble(x, y, block.size);
|
||||
@@ -1657,8 +1667,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
damage = Damage.applyArmor(damage, block.armor);
|
||||
}
|
||||
|
||||
damage(other.team, damage);
|
||||
Events.fire(bulletDamageEvent.set(self(), other));
|
||||
damage(other, other.team, damage);
|
||||
|
||||
if(health <= 0 && !wasDead){
|
||||
Events.fire(new BuildingBulletDestroyEvent(self(), other));
|
||||
@@ -1681,6 +1690,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
/** Changes this building's team in a safe manner. */
|
||||
public void changeTeam(Team next){
|
||||
if(this.team == next) return;
|
||||
if(block.forceTeam != null) team = block.forceTeam;
|
||||
|
||||
Team last = this.team;
|
||||
boolean was = isValid();
|
||||
@@ -1693,10 +1703,12 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
indexer.addIndex(tile);
|
||||
Events.fire(teamChangeEvent.set(last, self()));
|
||||
}
|
||||
|
||||
checkAllowUpdate();
|
||||
}
|
||||
|
||||
public boolean canPickup(){
|
||||
return true;
|
||||
return block.canPickup;
|
||||
}
|
||||
|
||||
/** Called right before this building is picked up. */
|
||||
@@ -1764,6 +1776,8 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
}
|
||||
}
|
||||
|
||||
public void onNearbyBuildAdded(Building other){}
|
||||
|
||||
public void consume(){
|
||||
for(Consume cons : block.consumers){
|
||||
cons.trigger(self());
|
||||
@@ -2094,22 +2108,11 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(){
|
||||
stopSound();
|
||||
}
|
||||
|
||||
public void stopSound(){
|
||||
if(sound != null){
|
||||
sound.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void killed(){
|
||||
dead = true;
|
||||
Events.fire(new BlockDestroyEvent(tile));
|
||||
block.destroySound.at(tile);
|
||||
block.destroySound.at(tile, Mathf.random(block.destroyPitchMin, block.destroyPitchMax));
|
||||
onDestroyed();
|
||||
if(tile != emptyTile){
|
||||
tile.remove();
|
||||
@@ -2118,48 +2121,44 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
afterDestroyed();
|
||||
}
|
||||
|
||||
public void checkAllowUpdate(){
|
||||
if(!allowUpdate()){
|
||||
enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Final
|
||||
@Replace
|
||||
@Override
|
||||
public void update(){
|
||||
//TODO should just avoid updating buildings instead
|
||||
if(state.isEditor()) return;
|
||||
|
||||
//TODO refactor to timestamp-based system?
|
||||
if((timeScaleDuration -= Time.delta) <= 0f || !block.canOverdrive){
|
||||
timeScale = 1f;
|
||||
}
|
||||
|
||||
if(!allowUpdate()){
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
if(!headless && !wasVisible && state.rules.fog && !inFogTo(player.team())){
|
||||
visibleFlags |= (1L << player.team().id);
|
||||
wasVisible = true;
|
||||
renderer.blocks.updateShadow(self());
|
||||
renderer.minimap.update(tile);
|
||||
}
|
||||
|
||||
//TODO separate system for sound? AudioSource, etc
|
||||
if(!headless){
|
||||
if(sound != null){
|
||||
sound.update(x, y, shouldActiveSound(), activeSoundVolume());
|
||||
}
|
||||
|
||||
if(block.ambientSound != Sounds.none && shouldAmbientSound()){
|
||||
control.sound.loop(block.ambientSound, self(), block.ambientSoundVolume * ambientVolume());
|
||||
}
|
||||
//TODO separate multithreaded system for sound? AudioSource, etc
|
||||
if(!headless && block.ambientSound != Sounds.none && shouldAmbientSound()){
|
||||
control.sound.loop(block.ambientSound, self(), block.ambientSoundVolume * ambientVolume());
|
||||
}
|
||||
|
||||
updateConsumption();
|
||||
|
||||
//TODO just handle per-block instead
|
||||
if(enabled || !block.noUpdateDisabled){
|
||||
updateTile();
|
||||
}
|
||||
}
|
||||
|
||||
/** When a block is newly revealed outside of camera view range, it is updated on the minimap. */
|
||||
public void updateFogVisibility(){
|
||||
if(!wasVisible && !inFogTo(player.team())){
|
||||
visibleFlags |= (1L << player.team().id);
|
||||
wasVisible = true;
|
||||
renderer.blocks.updateShadow(self());
|
||||
renderer.minimap.update(tile);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hitbox(Rect out){
|
||||
out.setCentered(x, y, block.size * tilesize, block.size * tilesize);
|
||||
|
||||
Reference in New Issue
Block a user