Unit factory limit / Removed overdrive block effects / BlockFlag cleanup

This commit is contained in:
Anuken
2019-02-02 14:33:13 -05:00
parent c0d6618808
commit 636bfdb530
13 changed files with 38 additions and 368 deletions

View File

@@ -215,7 +215,7 @@ public class BlockIndexer{
}
private void process(Tile tile){
if(tile.block().flags != null &&
if(tile.block().flags.size() > 0 &&
tile.getTeam() != Team.none){
ObjectSet<Tile>[] map = getFlagged(tile.getTeam());

View File

@@ -128,7 +128,7 @@ public class Pathfinder{
for(int y = 0; y < world.height(); y++){
Tile tile = world.tile(x, y);
if(tile.block().flags != null && state.teams.areEnemies(tile.getTeam(), team)
if(state.teams.areEnemies(tile.getTeam(), team)
&& tile.block().flags.contains(BlockFlag.target)){
path.frontier.addFirst(tile);
path.weights[x][y] = 0;

View File

@@ -23,7 +23,6 @@ import io.anuke.mindustry.world.blocks.storage.LaunchPad;
import io.anuke.mindustry.world.blocks.storage.SortedUnloader;
import io.anuke.mindustry.world.blocks.storage.Vault;
import io.anuke.mindustry.world.blocks.units.MechPad;
import io.anuke.mindustry.world.blocks.units.Reconstructor;
import io.anuke.mindustry.world.blocks.units.RepairPoint;
import io.anuke.mindustry.world.blocks.units.UnitFactory;
@@ -72,7 +71,7 @@ public class Blocks implements ContentList{
//units
spiritFactory, phantomFactory, wraithFactory, ghoulFactory, revenantFactory, daggerFactory, titanFactory,
fortressFactory, reconstructor, repairPoint,
fortressFactory, repairPoint,
//upgrades
alphaPad, deltaPad, tauPad, omegaPad, dartPad, javelinPad, tridentPad, glaivePad;
@@ -1344,10 +1343,6 @@ public class Blocks implements ContentList{
repairSpeed = 0.1f;
}};
reconstructor = new Reconstructor("reconstructor"){{
size = 2;
}};
//endregion
//region upgrades

View File

@@ -71,7 +71,7 @@ public class Renderer implements ApplicationListener{
if(!(effect instanceof GroundEffect)){
EffectEntity entity = Pools.obtain(EffectEntity.class, EffectEntity::new);
entity.effect = effect;
entity.color = color;
entity.color.set(color);
entity.rotation = rotation;
entity.data = data;
entity.id++;
@@ -83,7 +83,7 @@ public class Renderer implements ApplicationListener{
}else{
GroundEffectEntity entity = Pools.obtain(GroundEffectEntity.class, GroundEffectEntity::new);
entity.effect = effect;
entity.color = color;
entity.color.set(color);
entity.rotation = rotation;
entity.id++;
entity.data = data;

View File

@@ -129,11 +129,7 @@ public class Player extends Unit implements BuilderTrait, ShooterTrait{
@Override
public boolean collidesGrid(int x, int y){
Tile tile = world.tile(x, y);
if(!isFlying()) return true;
if(!mech.flying && tile != null && !tile.block().synthetic() && tile.block().solid){
return true;
}
return false;
return !isFlying() || (!mech.flying && tile != null && !tile.block().synthetic() && tile.block().solid);
}
@Override

View File

@@ -120,8 +120,7 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
}
public boolean targetHasFlag(BlockFlag flag){
return target instanceof TileEntity && ((TileEntity) target).tile.block().flags != null &&
((TileEntity) target).tile.block().flags.contains(flag);
return target instanceof TileEntity && ((TileEntity) target).tile.block().flags.contains(flag);
}
public void updateRespawning(){
@@ -324,6 +323,11 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
@Override
public void removed(){
Tile tile = world.tile(spawner);
if(tile != null){
tile.block().unitRemoved(tile, this);
}
spawner = noSpawner;
}

View File

@@ -90,7 +90,7 @@ public class Block extends BlockStorage{
/** The block group. Unless {@link #canReplace} is overriden, blocks in the same group can replace each other. */
public BlockGroup group = BlockGroup.none;
/** List of block flags. Used for AI indexing. */
public EnumSet<BlockFlag> flags;
public EnumSet<BlockFlag> flags = EnumSet.of();
/** Whether the block can be tapped and selected to configure. */
public boolean configurable;
/** Whether this block consumes touchDown events when tapped. */
@@ -235,6 +235,11 @@ public class Block extends BlockStorage{
public void unitOn(Tile tile, Unit unit){
}
/** Called when a unit that spawned at this tile is removed.*/
public void unitRemoved(Tile tile, Unit unit){
}
/** Returns whether ot not this block can be place on the specified tile. */
public boolean canPlaceOn(Tile tile){
return true;

View File

@@ -66,8 +66,6 @@ public class MendProjector extends Block{
if(entity.charge >= reload){
float realRange = range + entity.phaseHeat * phaseRangeBoost;
Effects.effect(Fx.healWaveMend, Tmp.c1.set(color).lerp(phase, entity.phaseHeat), tile.drawx(), tile.drawy(), realRange);
entity.charge = 0f;
int tileRange = (int)(realRange / tilesize);

View File

@@ -2,7 +2,6 @@ package io.anuke.mindustry.world.blocks.defense;
import io.anuke.arc.Core;
import io.anuke.arc.collection.IntSet;
import io.anuke.arc.entities.Effects;
import io.anuke.arc.graphics.Blending;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.g2d.Draw;
@@ -10,8 +9,6 @@ import io.anuke.arc.graphics.g2d.Lines;
import io.anuke.arc.graphics.g2d.TextureRegion;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.util.Time;
import io.anuke.arc.util.Tmp;
import io.anuke.mindustry.content.Fx;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
@@ -31,7 +28,7 @@ public class OverdriveProjector extends Block{
protected int timerUse = timers ++;
protected TextureRegion topRegion;
protected float reload = 260f;
protected float reload = 60f;
protected float range = 80f;
protected float speedBoost = 1.5f;
protected float speedBoostPhase = 0.75f;
@@ -69,7 +66,6 @@ public class OverdriveProjector extends Block{
float realRange = range + entity.phaseHeat * phaseRangeBoost;
float realBoost = (speedBoost + entity.phaseHeat*speedBoostPhase) * entity.power.satisfaction;
Effects.effect(Fx.overdriveWave, Tmp.c1.set(color).lerp(phase, entity.phaseHeat), tile.drawx(), tile.drawy(), realRange);
entity.charge = 0f;
int tileRange = (int)(realRange / tilesize);
@@ -87,8 +83,7 @@ public class OverdriveProjector extends Block{
if(other.getTeamID() == tile.getTeamID() && !healed.contains(other.pos()) && other.entity != null){
other.entity.timeScaleDuration = Math.max(other.entity.timeScaleDuration, reload + 1f);
other.entity.timeScale = Math.max(other.entity.timeScale, realBoost);
Effects.effect(Fx.overdriveBlockFull, Tmp.c1.set(color).lerp(phase, entity.phaseHeat), other.drawx(), other.drawy(), other.block().size);
healed.add(other.pos());
healed.add(other.pos());
}
}
}

View File

@@ -34,7 +34,7 @@ public class CoreBlock extends StorageBlock{
solid = true;
update = true;
hasItems = true;
flags = EnumSet.of(BlockFlag.resupplyPoint, BlockFlag.target);
flags = EnumSet.of(BlockFlag.target);
}
@Remote(called = Loc.server)

View File

@@ -1,331 +0,0 @@
package io.anuke.mindustry.world.blocks.units;
import io.anuke.annotations.Annotations.Loc;
import io.anuke.annotations.Annotations.Remote;
import io.anuke.arc.Core;
import io.anuke.arc.entities.Effects;
import io.anuke.arc.entities.Effects.Effect;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.Lines;
import io.anuke.arc.graphics.g2d.TextureRegion;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.util.Time;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.content.Fx;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.entities.traits.SpawnerTrait;
import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.graphics.Shaders;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import static io.anuke.mindustry.Vars.tilesize;
import static io.anuke.mindustry.Vars.world;
//TODO re-implement properly
public class Reconstructor extends Block{
protected float departTime = 30f;
protected float arriveTime = 40f;
/** Stores the percentage of buffered power to be used upon teleporting. */
protected float powerPerTeleport = 0.5f;
protected Effect arriveEffect = Fx.spawn;
protected TextureRegion openRegion;
public Reconstructor(String name){
super(name);
update = true;
solidifes = true;
hasPower = true;
configurable = true;
consumes.powerBuffered(30f);
}
protected static boolean checkValidTap(Tile tile, ReconstructorEntity entity, Player player){
return validLink(tile, entity.link) &&
Math.abs(player.x - tile.drawx()) <= tile.block().size * tilesize / 2f &&
Math.abs(player.y - tile.drawy()) <= tile.block().size * tilesize / 2f &&
entity.current == null && entity.power.satisfaction >= ((Reconstructor) tile.block()).powerPerTeleport;
}
protected static boolean validLink(Tile tile, int position){
Tile other = world.tile(position);
return other != tile && other != null && other.block() instanceof Reconstructor;
}
protected static void unlink(ReconstructorEntity entity){
Tile other = world.tile(entity.link);
if(other != null && other.block() instanceof Reconstructor){
ReconstructorEntity oe = other.entity();
if(oe.link == entity.tile.pos()){
oe.link = -1;
}
}
entity.link = -1;
}
@Remote(targets = Loc.both, called = Loc.server, forward = true)
public static void reconstructPlayer(Player player, Tile tile){
ReconstructorEntity entity = tile.entity();
if(!checkValidTap(tile, entity, player) || entity.power.satisfaction < ((Reconstructor) tile.block()).powerPerTeleport)
return;
entity.departing = true;
entity.current = player;
entity.solid = false;
entity.power.satisfaction -= Math.min(entity.power.satisfaction, ((Reconstructor) tile.block()).powerPerTeleport);
entity.updateTime = 1f;
entity.set(tile.drawx(), tile.drawy());
player.rotation = 90f;
player.baseRotation = 90f;
player.setDead(true);
// player.setRespawning(true);
//player.setRespawning();
}
@Remote(targets = Loc.both, called = Loc.server, forward = true)
public static void linkReconstructor(Player player, Tile tile, Tile other){
//just in case the client has invalid data
if(!(tile.entity instanceof ReconstructorEntity) || !(other.entity instanceof ReconstructorEntity)) return;
ReconstructorEntity entity = tile.entity();
ReconstructorEntity oe = other.entity();
unlink(entity);
unlink(oe);
entity.link = other.pos();
oe.link = tile.pos();
}
@Remote(targets = Loc.both, called = Loc.server, forward = true)
public static void unlinkReconstructor(Player player, Tile tile, Tile other){
//just in case the client has invalid data
if(!(tile.entity instanceof ReconstructorEntity) || !(other.entity instanceof ReconstructorEntity)) return;
ReconstructorEntity entity = tile.entity();
ReconstructorEntity oe = other.entity();
//called in main thread to prevent issues
unlink(entity);
unlink(oe);
}
@Override
public void load(){
super.load();
openRegion = Core.atlas.find(name + "-open");
}
@Override
public boolean isSolidFor(Tile tile){
ReconstructorEntity entity = tile.entity();
return entity.solid;
}
@Override
public void drawConfigure(Tile tile){
super.drawConfigure(tile);
ReconstructorEntity entity = tile.entity();
if(validLink(tile, entity.link)){
Tile target = world.tile(entity.link);
Draw.color(Palette.place);
Lines.square(target.drawx(), target.drawy(),
target.block().size * tilesize / 2f + 1f);
Draw.reset();
}
Draw.color(Palette.accent);
Draw.color();
}
@Override
public boolean onConfigureTileTapped(Tile tile, Tile other){
if(tile == other) return false;
ReconstructorEntity entity = tile.entity();
if(entity.link == other.pos()){
Call.unlinkReconstructor(null, tile, other);
return false;
}else if(other.block() instanceof Reconstructor){
Call.linkReconstructor(null, tile, other);
return false;
}
return true;
}
@Override
public boolean shouldShowConfigure(Tile tile, Player player){
ReconstructorEntity entity = tile.entity();
return !checkValidTap(tile, entity, player);
}
@Override
public boolean shouldHideConfigure(Tile tile, Player player){
ReconstructorEntity entity = tile.entity();
return checkValidTap(tile, entity, player);
}
@Override
public void draw(Tile tile){
ReconstructorEntity entity = tile.entity();
if(entity.solid){
Draw.rect(region, tile.drawx(), tile.drawy());
}else{
Draw.rect(openRegion, tile.drawx(), tile.drawy());
}
if(entity.current != null){
float progress = entity.departing ? entity.updateTime : (1f - entity.updateTime);
//Player player = entity.current;
TextureRegion region = entity.current.getIconRegion();
Shaders.build.region = region;
Shaders.build.progress = progress;
Shaders.build.color.set(Palette.accent);
Shaders.build.time = -entity.time / 10f;
Draw.shader(Shaders.build, false);
Shaders.build.apply();
Draw.rect(region, tile.drawx(), tile.drawy());
Draw.shader();
Draw.color(Palette.accent);
Lines.lineAngleCenter(
tile.drawx() + Mathf.sin(entity.time, 6f, Vars.tilesize / 3f * size),
tile.drawy(),
90,
size * Vars.tilesize / 2f);
Draw.reset();
}
}
@Override
public void update(Tile tile){
ReconstructorEntity entity = tile.entity();
boolean stayOpen = false;
if(entity.current != null){
entity.time += Time.delta();
entity.solid = true;
if(entity.departing){
//force respawn if there's suddenly nothing to link to
if(!validLink(tile, entity.link)){
//entity.current.setRespawning(false);
return;
}
ReconstructorEntity other = world.tile(entity.link).entity();
entity.updateTime -= Time.delta() / departTime;
if(entity.updateTime <= 0f){
//no power? death.
if(other.power.satisfaction < powerPerTeleport){
entity.current.setDead(true);
//entity.current.setRespawning(false);
entity.current = null;
return;
}
other.power.satisfaction -= Math.min(other.power.satisfaction, powerPerTeleport);
other.current = entity.current;
other.departing = false;
other.current.set(other.x, other.y);
other.updateTime = 1f;
entity.current = null;
}
}else{ //else, arriving
entity.updateTime -= Time.delta() / arriveTime;
if(entity.updateTime <= 0f){
entity.solid = false;
entity.current.setDead(false);
Effects.effect(arriveEffect, entity.current);
entity.current = null;
}
}
}else{
if(validLink(tile, entity.link)){
Tile other = world.tile(entity.link);
if(other.entity.power.satisfaction >= powerPerTeleport && Units.anyEntities(tile, 4f, unit -> unit.getTeam() == entity.getTeam() && unit instanceof Player) &&
entity.power.satisfaction >= powerPerTeleport){
entity.solid = false;
stayOpen = true;
}
}
if(!stayOpen && !entity.solid && !Units.anyEntities(tile)){
entity.solid = true;
}
}
}
@Override
public void tapped(Tile tile, Player player){
ReconstructorEntity entity = tile.entity();
if(!checkValidTap(tile, entity, player)) return;
Call.reconstructPlayer(player, tile);
}
@Override
public TileEntity newEntity(){
return new ReconstructorEntity();
}
public class ReconstructorEntity extends TileEntity implements SpawnerTrait{
Unit current;
float updateTime;
float time;
int link;
boolean solid = true, departing;
@Override
public void updateSpawning(Unit unit){
}
@Override
public float getSpawnProgress(){
return 0;
}
@Override
public void write(DataOutput stream) throws IOException{
stream.writeInt(link);
}
@Override
public void read(DataInput stream) throws IOException{
link = stream.readInt();
}
}
}

View File

@@ -12,6 +12,7 @@ import io.anuke.arc.math.Mathf;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.content.Fx;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.entities.units.BaseUnit;
import io.anuke.mindustry.entities.units.UnitType;
import io.anuke.mindustry.gen.Call;
@@ -41,6 +42,7 @@ public class UnitFactory extends Block{
protected float produceTime = 1000f;
protected float launchVelocity = 0f;
protected TextureRegion topRegion;
protected int maxSpawn = 4;
public UnitFactory(String name){
super(name);
@@ -61,6 +63,7 @@ public class UnitFactory extends Block{
UnitFactory factory = (UnitFactory) tile.block();
entity.buildTime = 0f;
entity.spawned ++;
Effects.shake(2f, 3f, entity);
Effects.effect(Fx.producesmoke, tile.drawx(), tile.drawy());
@@ -93,6 +96,12 @@ public class UnitFactory extends Block{
stats.add(BlockStat.craftSpeed, produceTime / 60f, StatUnit.seconds);
}
@Override
public void unitRemoved(Tile tile, Unit unit){
UnitFactoryEntity entity = tile.entity();
entity.spawned --;
}
@Override
public TextureRegion[] generateIcons(){
return new TextureRegion[]{Core.atlas.find(name), Core.atlas.find(name + "-top")};
@@ -136,6 +145,10 @@ public class UnitFactory extends Block{
entity.time += entity.delta() * entity.speedScl;
if(entity.spawned >= maxSpawn){
return;
}
if(tile.isEnemyCheat()){
entity.warmup += entity.delta();
}
@@ -211,17 +224,20 @@ public class UnitFactory extends Block{
public float time;
public float speedScl;
public float warmup; //only for enemy spawners
public int spawned;
@Override
public void write(DataOutput stream) throws IOException{
stream.writeFloat(buildTime);
stream.writeFloat(warmup);
stream.writeInt(spawned);
}
@Override
public void read(DataInput stream) throws IOException{
buildTime = stream.readFloat();
warmup = stream.readFloat();
spawned = stream.readInt();
}
}
}

View File

@@ -1,24 +1,16 @@
package io.anuke.mindustry.world.meta;
//TODO fix flagging system, currently doesn't really work
public enum BlockFlag{
/**General important target for all types of units.*/
target(0),
/**Point to resupply resources.*/
resupplyPoint(Float.MAX_VALUE),
/**Point to drop off resources.*/
dropPoint(Float.MAX_VALUE),
/**Producer of important goods.*/
producer(Float.MAX_VALUE),
/**Just a turret.*/
/**A turret.*/
turret(Float.MAX_VALUE),
/**Producer or storage unit of volatile materials.*/
explosive(Float.MAX_VALUE),
/**Repair point.*/
repair(Float.MAX_VALUE);
public final static BlockFlag[] all = values();
public final float cost;
BlockFlag(float cost){