Implemented unstable fusion reactor, mending core, liquid cooled turrets

This commit is contained in:
Anuken 2018-06-18 16:07:37 -04:00
parent 6bdd960623
commit 0304512b8a
10 changed files with 145 additions and 138 deletions

View File

@ -198,7 +198,7 @@ public abstract class InputHandler extends InputAdapter{
}
public void tryDropItems(Tile tile, float x, float y){
if(!droppingItem || !player.inventory.hasItem() || !tile.block().hasItems || canTapPlayer(x, y)){
if(!droppingItem || !player.inventory.hasItem() || canTapPlayer(x, y)){
droppingItem = false;
return;
}
@ -207,7 +207,7 @@ public abstract class InputHandler extends InputAdapter{
ItemStack stack = player.inventory.getItem();
if(tile.block().acceptStack(stack.item, stack.amount, tile, player) > 0){
if(tile.block().acceptStack(stack.item, stack.amount, tile, player) > 0 && tile.block().hasItems){
CallBlocks.transferInventory(player, tile);
}else{
CallEntity.dropItem(player, player.angleTo(x, y));

View File

@ -122,7 +122,7 @@ public abstract class BaseBlock {
next = next.target();
if(next.block().hasLiquids && tile.entity.liquids.amount > 0f){
if(next.entity.liquids.liquid == tile.entity.liquids.liquid) {
if(next.entity.liquids.liquid == tile.entity.liquids.liquid || next.entity.liquids.amount <= 0.01f) {
float ofract = next.entity.liquids.amount / next.block().liquidCapacity;
float fract = tile.entity.liquids.amount / liquidCapacity;
float flow = Math.min(Mathf.clamp((fract - ofract) * (1f)) * (liquidCapacity), tile.entity.liquids.amount);

View File

@ -1,98 +0,0 @@
package io.anuke.mindustry.world.blocks.defense;
import com.badlogic.gdx.math.MathUtils;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.graphics.Layer;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.defense.turrets.PowerTurret;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Hue;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf;
//TODO remove
public class RepairTurret extends PowerTurret {
protected float repairFrac = 1f / 135f;
public RepairTurret(String name) {
super(name);
powerUsed = 0.1f;
layer2 = Layer.laser;
}
@Override
public void setStats(){
super.setStats();
//stats.add("repairssecond", Strings.toFixed(60f/reload * repairFrac * 100, 1) + "%");
}
@Override
public void update(Tile tile){
TurretEntity entity = tile.entity();
if(entity.power.amount < powerUsed){
return;
}
if(entity.blockTarget != null && entity.blockTarget.isDead()){
entity.blockTarget = null;
}
if(entity.timer.get(timerTarget, targetInterval)){
entity.blockTarget = Units.findAllyTile(tile.getTeam(),tile.worldx(), tile.worldy(), range,
test -> test != tile && test.entity.health < test.block().health);
}
if(entity.blockTarget != null){
if(Float.isNaN(entity.rotation)){
entity.rotation = 0;
}
float target = entity.angleTo(entity.blockTarget);
entity.rotation = Mathf.slerpDelta(entity.rotation, target, 0.16f);
int maxhealth = entity.blockTarget.tile.block().health;
//TODO
if(entity.timer.get(100, reload) && Angles.angleDist(target, entity.rotation) < shootCone){
entity.blockTarget.health += maxhealth * repairFrac;
if(entity.blockTarget.health > maxhealth)
entity.blockTarget.health = maxhealth;
entity.power.amount -= powerUsed;
}
}
}
@Override
public void drawLayer2(Tile tile){
TurretEntity entity = tile.entity();
TileEntity target = entity.blockTarget;
if(entity.power.amount >= powerUsed && target != null && Angles.angleDist(entity.angleTo(target), entity.rotation) < 10){
Tile targetTile = target.tile;
float len = 4f;
float x = tile.drawx() + Angles.trnsx(entity.rotation, len), y = tile.drawy() + Angles.trnsy(entity.rotation, len);
float x2 = targetTile.drawx(), y2 = targetTile.drawy();
Draw.color(Hue.rgb(138, 244, 138, (MathUtils.sin(Timers.time()) + 1f) / 14f));
Draw.alpha(0.3f);
Lines.stroke(4f);
Lines.line(x, y, x2, y2);
Lines.stroke(2f);
Draw.rect("circle", x2, y2, 7f, 7f);
Draw.alpha(1f);
Lines.stroke(2f);
Lines.line(x, y, x2, y2);
Lines.stroke(1f);
Draw.rect("circle", x2, y2, 5f, 5f);
Draw.reset();
}
}
}

View File

@ -0,0 +1,50 @@
package io.anuke.mindustry.world.blocks.defense.turrets;
import io.anuke.mindustry.content.fx.BlockFx;
import io.anuke.mindustry.entities.effect.Fire;
import io.anuke.mindustry.type.Liquid;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.defense.Turret;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.util.Mathf;
import static io.anuke.mindustry.Vars.tilesize;
public class CooledTurret extends Turret {
/**How much reload is lowered by for each unit of liquid of heat capacity 1.*/
protected float coolantMultiplier = 1f;
protected float maxUsed = 1f;
protected Effect coolEffect = BlockFx.fuelburn;
public CooledTurret(String name) {
super(name);
hasLiquids = true;
}
@Override
protected void updateShooting(Tile tile) {
super.updateShooting(tile);
TurretEntity entity = tile.entity();
float used = Math.min(Math.min(entity.liquids.amount, maxUsed * Timers.delta()), ((reload - entity.reload) / coolantMultiplier) / entity.liquids.liquid.heatCapacity);
entity.reload += (used * entity.liquids.liquid.heatCapacity) / entity.liquids.liquid.heatCapacity;
entity.liquids.amount -= used;
if(Mathf.chance(0.04 * used)){
Effects.effect(coolEffect, tile.drawx() + Mathf.range(size * tilesize/2f), tile.drawy() + Mathf.range(size * tilesize/2f));
}
//don't use oil as coolant, thanks
if(Mathf.chance(entity.liquids.liquid.flammability / 10f * used)){
Fire.create(tile);
}
}
@Override
public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount) {
return super.acceptLiquid(tile, source, liquid, amount) && liquid.temperature <= 0.5f;
}
}

View File

@ -6,11 +6,10 @@ import io.anuke.mindustry.type.AmmoEntry;
import io.anuke.mindustry.type.AmmoType;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.BarType;
import io.anuke.mindustry.world.meta.BlockBar;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.defense.Turret;
import io.anuke.mindustry.world.meta.BlockBar;
public class ItemTurret extends Turret {
public class ItemTurret extends CooledTurret {
protected int maxAmmo = 100;
//TODO implement this!
/**A value of 'null' means this turret does not need ammo.*/
@ -73,6 +72,7 @@ public class ItemTurret extends Turret {
@Override
public void setBars(){
super.setBars();
bars.replace(new BlockBar(BarType.inventory, true, tile -> (float)tile.<TurretEntity>entity().totalAmmo / maxAmmo));
}

View File

@ -2,10 +2,9 @@ package io.anuke.mindustry.world.blocks.defense.turrets;
import io.anuke.mindustry.type.AmmoType;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.defense.Turret;
import io.anuke.mindustry.world.meta.BlockStat;
public abstract class PowerTurret extends Turret {
public abstract class PowerTurret extends CooledTurret {
protected float powerUsed = 0.5f;
protected AmmoType shootType;

View File

@ -7,8 +7,6 @@ import io.anuke.annotations.Annotations.Loc;
import io.anuke.annotations.Annotations.Remote;
import io.anuke.mindustry.content.Liquids;
import io.anuke.mindustry.content.fx.BlockFx;
import io.anuke.mindustry.content.fx.ExplosionFx;
import io.anuke.mindustry.entities.Damage;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.gen.CallBlocks;
@ -29,7 +27,6 @@ import io.anuke.ucore.scene.ui.ButtonGroup;
import io.anuke.ucore.scene.ui.ImageButton;
import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Translator;
import java.io.DataInputStream;
import java.io.DataOutputStream;
@ -295,34 +292,7 @@ public class WarpGate extends PowerBlock{
if(entity.activeScl < 0.5f) return;
float explosionRadius = 50f;
float explosionDamage = 20f;
Translator tr = new Translator();
Effects.shake(6f, 16f, tile.worldx(), tile.worldy());
Effects.effect(ExplosionFx.nuclearShockwave, tile.worldx(), tile.worldy());
for(int i = 0; i < 6; i ++){
Timers.run(Mathf.random(40), () -> {
Effects.effect(BlockFx.nuclearcloud, tile.worldx(), tile.worldy());
});
}
Damage.damage(tile.worldx(), tile.worldy(), explosionRadius * tilesize, explosionDamage * 4);
for(int i = 0; i < 20; i ++){
Timers.run(Mathf.random(50), ()->{
tr.rnd(Mathf.random(40f));
Effects.effect(ExplosionFx.explosion, tr.x + tile.worldx(), tr.y + tile.worldy());
});
}
for(int i = 0; i < 70; i ++){
Timers.run(Mathf.random(80), ()->{
tr.rnd(Mathf.random(120f));
Effects.effect(BlockFx.nuclearsmoke, tr.x + tile.worldx(), tr.y + tile.worldy());
});
}
//TODO catastrophic failure
}
private void catastrophicFailure(Tile tile){

View File

@ -0,0 +1,26 @@
package io.anuke.mindustry.world.blocks.effect;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Lines;
import static io.anuke.mindustry.Vars.tilesize;
public abstract class EffectCore extends Block{
protected int range = 7;
public EffectCore(String name) {
super(name);
update = true;
solid = true;
}
@Override
public void drawSelect(Tile tile) {
Draw.color(Palette.accent);
Lines.dashCircle(tile.drawx(), tile.drawy(), range * tilesize);
Draw.reset();
}
}

View File

@ -0,0 +1,30 @@
package io.anuke.mindustry.world.blocks.effect;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.util.Mathf;
import static io.anuke.mindustry.Vars.world;
public class MendingCore extends EffectCore {
/**Mending speed as a percentage of block health, per frame.*/
protected float mendSpeed = 0.8f;
public MendingCore(String name) {
super(name);
}
@Override
public void update(Tile tile) {
for (int dx = Math.max(-range + tile.x, 0); dx <= Math.min(range + tile.y, world.width() - 1); dx++) {
for (int dy = Math.max(-range + tile.y, 0); dy <= Math.min(range + tile.y, world.height() - 1); dy++) {
Tile other = world.tile(dx, dy);
if(other.entity != null){
other.entity.health = Mathf.clamp(other.entity.health + 1f / other.block().health * mendSpeed * Timers.delta(), 0, other.block().health);
}
}
}
}
}

View File

@ -47,13 +47,32 @@ public class FusionReactor extends PowerGenerator {
entity.warmup = Mathf.lerpDelta(entity.warmup, 0f, 0.01f);
}
float powerAdded = Math.min(powerCapacity - entity.power.amount, maxPowerProduced * Mathf.pow(entity.warmup, 3f) * Timers.delta());
float powerAdded = Math.min(powerCapacity - entity.power.amount, maxPowerProduced * Mathf.pow(entity.warmup, 4f) * Timers.delta());
entity.power.amount += powerAdded;
entity.totalProgress += entity.warmup * Timers.delta();
distributePower(tile);
}
@Override
public float handleDamage(Tile tile, float amount) {
FusionReactorEntity entity = tile.entity();
if(entity.warmup < 0.4f) return amount;
float healthFract = tile.entity.health/health;
//5% chance to explode when hit at <50% HP with a normal bullet
if(amount > 5f && healthFract <= 0.5f && Mathf.chance(0.05)){
return health;
//10% chance to explode when hit at <25% HP with a powerful bullet
}else if(amount > 8f && healthFract <= 0.2f && Mathf.chance(0.1)){
return health;
}
return amount;
}
@Override
public void draw(Tile tile) {
FusionReactorEntity entity = tile.entity();
@ -99,6 +118,17 @@ public class FusionReactor extends PowerGenerator {
return super.acceptLiquid(tile, source, liquid, amount) && liquid == inputLiquid;
}
@Override
public void onDestroyed(Tile tile) {
super.onDestroyed(tile);
FusionReactorEntity entity = tile.entity();
if(entity.warmup < 0.4f) return;
//TODO catastrophic failure
}
public static class FusionReactorEntity extends GenericCrafterEntity{
}