mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-01-30 17:34:23 +07:00
Implemented unstable fusion reactor, mending core, liquid cooled turrets
This commit is contained in:
parent
6bdd960623
commit
0304512b8a
@ -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));
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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){
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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{
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user