Implemented liquid turrets with ammo / Implemented flamer turret

This commit is contained in:
Anuken
2018-04-03 23:06:39 -04:00
parent 636da8f95f
commit 397220e682
18 changed files with 355 additions and 130 deletions

View File

@@ -6,5 +6,7 @@ import io.anuke.mindustry.resource.AmmoType;
public class AmmoTypes {
public static final AmmoType
basicIron = new AmmoType(Items.iron, TurretBullets.basicIron, 5, 0.9f);
basicIron = new AmmoType(Items.iron, TurretBullets.basicIron, 5, 0.9f),
basicFlame = new AmmoType(Liquids.oil, TurretBullets.basicFlame, 0.3f, 0.9f);
}

View File

@@ -121,6 +121,7 @@ public class Recipes {
new Recipe(units, DebugBlocks.itemSource, stack(Items.steel, 10)).setDebug(),
new Recipe(units, DebugBlocks.itemVoid, stack(Items.steel, 10)).setDebug(),
new Recipe(units, DebugBlocks.liquidSource, stack(Items.steel, 10)).setDebug(),
new Recipe(units, DebugBlocks.powerVoid, stack(Items.steel, 10)).setDebug(),
new Recipe(units, DebugBlocks.powerInfinite, stack(Items.steel, 10), stack(Items.densealloy, 5)).setDebug()
);

View File

@@ -1,11 +1,23 @@
package io.anuke.mindustry.content.blocks;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.content.Liquids;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.Liquid;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.PowerBlock;
import io.anuke.mindustry.world.blocks.types.distribution.Sorter;
import io.anuke.mindustry.world.blocks.types.power.PowerDistributor;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.scene.ui.ButtonGroup;
import io.anuke.ucore.scene.ui.ImageButton;
import io.anuke.ucore.scene.ui.layout.Table;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class DebugBlocks {
public static final Block
@@ -43,6 +55,90 @@ public class DebugBlocks {
}
},
liquidSource = new Block("liquidsource"){
{
update = true;
solid = true;
hasLiquids = true;
liquidCapacity = 100f;
}
@Override
public boolean isConfigurable(Tile tile) {
return true;
}
@Override
public void update(Tile tile) {
LiquidSourceEntity entity = tile.entity();
tile.entity.liquid.amount = liquidCapacity;
tile.entity.liquid.liquid = entity.source;
tryDumpLiquid(tile);
}
@Override
public void draw(Tile tile){
super.draw(tile);
LiquidSourceEntity entity = tile.entity();
Draw.color(entity.source.color);
Draw.rect("blank", tile.worldx(), tile.worldy(), 4f, 4f);
Draw.color();
}
@Override
public void buildTable(Tile tile, Table table){
LiquidSourceEntity entity = tile.entity();
Array<Liquid> items = Liquid.getAllLiquids();
ButtonGroup<ImageButton> group = new ButtonGroup<>();
Table cont = new Table();
cont.margin(4);
cont.marginBottom(5);
cont.add().colspan(4).height(50f * (int)(items.size/4f + 1f));
cont.row();
for(int i = 0; i < items.size; i ++){
if(i == 0) continue;
final int f = i;
ImageButton button = cont.addImageButton("white", "toggle", 24, () -> {
entity.source = items.get(f);
}).size(38, 42).padBottom(-5.1f).group(group).get();
button.getStyle().imageUpColor = items.get(i).color;
button.setChecked(entity.source.id == f);
if(i%4 == 3){
cont.row();
}
}
table.add(cont);
}
@Override
public TileEntity getEntity(){
return new LiquidSourceEntity();
}
class LiquidSourceEntity extends TileEntity{
public Liquid source = Liquids.water;
@Override
public void write(DataOutputStream stream) throws IOException {
stream.writeByte(source.id);
}
@Override
public void read(DataInputStream stream) throws IOException {
source = Liquid.getByID(stream.readByte());
}
}
},
itemVoid = new Block("itemvoid"){
{
update = solid = true;

View File

@@ -35,9 +35,14 @@ public class WeaponBlocks{
ammoUseEffect = BulletFx.shellEjectSmall;
}},
flameturret = new Turret("flameturret"){
},
flameturret = new LiquidTurret("flameturret"){{
ammoTypes = new AmmoType[]{AmmoTypes.basicFlame};
recoil = 0f;
reload = 5f;
shootCone = 50f;
shootEffect = BulletFx.shootSmallFlame;
ammoUseEffect = BulletFx.shellEjectSmall;
}},
railgunturret = new Turret("railgunturret"){
@@ -55,9 +60,9 @@ public class WeaponBlocks{
},
magmaturret = new LiquidTurret("magmaturret") {
},
magmaturret = new LiquidTurret("magmaturret") {{
ammoTypes = new AmmoType[]{AmmoTypes.basicFlame};
}},
plasmaturret = new Turret("plasmaturret"){

View File

@@ -3,6 +3,8 @@ package io.anuke.mindustry.content.bullets;
import com.badlogic.gdx.graphics.Color;
import io.anuke.mindustry.entities.Bullet;
import io.anuke.mindustry.entities.BulletType;
import io.anuke.mindustry.graphics.fx.BulletFx;
import io.anuke.mindustry.graphics.fx.Fx;
import io.anuke.ucore.graphics.Draw;
public class TurretBullets {
@@ -15,5 +17,19 @@ public class TurretBullets {
Draw.rect("bullet", b.x, b.y, 9f, 5f + b.fract()*7f, b.angle() - 90);
Draw.color();
}
},
basicFlame = new BulletType(2f, 4) {
{
hitsize = 7f;
lifetime = 30f;
pierce = true;
drag = 0.07f;
hiteffect = BulletFx.hitFlameSmall;
despawneffect = Fx.none;
}
@Override
public void draw(Bullet b) {}
};
}

View File

@@ -43,6 +43,9 @@ public class ContentLoader {
//units
new UnitTypes(),
//ammotypes
new AmmoTypes(),
};
for(Block block : Block.getAllBlocks()){

View File

@@ -1,22 +1,22 @@
package io.anuke.mindustry.entities;
import com.badlogic.gdx.utils.IntSet;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.entities.BulletEntity;
import io.anuke.ucore.entities.Entity;
import io.anuke.ucore.entities.SolidEntity;
import io.anuke.ucore.util.Timer;
import static io.anuke.mindustry.Vars.*;
public class Bullet extends BulletEntity{
public IntSet collided;
public Timer timer = new Timer(3);
public Team team;
public Bullet(BulletType type, Unit owner, float x, float y, float angle){
super(type, owner, angle);
this.type = type;
this.team = owner.team;
set(x, y);
this(type, owner, owner.team, x, y, angle);
}
public Bullet(BulletType type, Entity owner, Team team, float x, float y, float angle){
@@ -24,6 +24,10 @@ public class Bullet extends BulletEntity{
this.team = team;
this.type = type;
set(x, y);
if(type.pierce){
collided = new IntSet();
}
}
public Bullet(BulletType type, Bullet parent, float x, float y, float angle){
@@ -44,7 +48,8 @@ public class Bullet extends BulletEntity{
type.draw(this);
}
}
@Override
public float drawSize(){
return 8;
}
@@ -53,6 +58,18 @@ public class Bullet extends BulletEntity{
return true;
}
@Override
public boolean collides(SolidEntity other){
return super.collides(other) && (!type.pierce || !collided.contains(other.id));
}
@Override
public void collision(SolidEntity other, float x, float y){
super.collision(other, x, y);
if(type.pierce)
collided.add(other.id);
}
@Override
public void update(){
super.update();

View File

@@ -2,26 +2,25 @@ package io.anuke.mindustry.entities;
import io.anuke.mindustry.graphics.fx.BulletFx;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.entities.BaseBulletType;
public abstract class BulletType extends BaseBulletType<Bullet>{
public Effect hitEffect = BulletFx.hit;
public Effect despawnEffect = BulletFx.despawn;
public BulletType(float speed, int damage){
this.speed = speed;
this.damage = damage;
lifetime = 40f;
hiteffect = BulletFx.hitBulletSmall;
despawneffect = BulletFx.despawn;
}
@Override
public void hit(Bullet b, float hitx, float hity){
Effects.effect(hitEffect, hitx, hity, b.angle());
Effects.effect(hiteffect, hitx, hity, b.angle());
}
@Override
public void despawned(Bullet b){
Effects.effect(despawnEffect, b.x, b.y, b.angle());
Effects.effect(despawneffect, b.x, b.y, b.angle());
}
}

View File

@@ -10,6 +10,8 @@ import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf;
public class BulletFx {
public static Color lightFlame = Color.valueOf("ffdd55");
public static Color darkFlame = Color.valueOf("db401c");
public static Color lightOrange = Color.valueOf("f68021");
public static Color lighterOrange = Color.valueOf("f6e096");
@@ -33,6 +35,16 @@ public class BulletFx {
Draw.reset();
}),
shootSmallFlame = new Effect(30f, e -> {
Draw.color(lightFlame, darkFlame, Color.GRAY, e.ifract());
Angles.randLenVectors(e.id, 8, e.powfract()*26f, e.rotation, 10f, (x, y) -> {
Fill.circle(e.x + x, e.y + y, 0.65f + e.fract()*1.5f);
});
Draw.reset();
}),
shellEjectSmall = new Effect(30f, e -> {
Draw.color(lightOrange, Color.LIGHT_GRAY, Color.GRAY, e.ifract());
Draw.alpha(e.fract());
@@ -45,7 +57,7 @@ public class BulletFx {
Draw.color();
}),
hit = new Effect(14, e -> {
hitBulletSmall = new Effect(14, e -> {
Draw.color(Color.WHITE, lightOrange, e.ifract());
Lines.stroke(0.5f + e.fract());
@@ -57,6 +69,18 @@ public class BulletFx {
Draw.reset();
}),
hitFlameSmall = new Effect(14, e -> {
Draw.color(lightFlame, darkFlame, e.ifract());
Lines.stroke(0.5f + e.fract());
Angles.randLenVectors(e.id, 5, e.ifract()*15f, e.rotation, 50f, (x, y) -> {
float ang = Mathf.atan2(x, y);
Lines.lineAngle(e.x + x, e.y + y, ang, e.fract()*3 + 1f);
});
Draw.reset();
}),
despawn = new Effect(12, e -> {
Draw.color(lighterOrange, Color.GRAY, e.ifract());
Lines.stroke(e.fract());

View File

@@ -8,18 +8,37 @@ public class AmmoType {
private static Array<AmmoType> allTypes = new Array<>();
public final byte id;
/**The item used. Always null if liquid isn't.*/
public final Item item;
/**The liquid used. Always null if item isn't.*/
public final Liquid liquid;
/**The resulting bullet.*/
public final BulletType bullet;
public final int quantityMultiplier;
/**For item ammo, this is amount given per ammo item.
* For liquid ammo, this is amount used per shot.*/
public final float quantityMultiplier;
/**Turret shoot speed multiplier.*/
public final float speedMultiplier;
public AmmoType(Item item, BulletType result, int multiplier, float speedMultiplier){
{
this.id = (byte)(lastID++);
allTypes.add(this);
}
public AmmoType(Item item, BulletType result, float multiplier, float speedMultiplier){
this.item = item;
this.liquid = null;
this.bullet = result;
this.quantityMultiplier = multiplier;
this.speedMultiplier = speedMultiplier;
}
public AmmoType(Liquid liquid, BulletType result, float multiplier, float speedMultiplier){
this.item = null;
this.liquid = liquid;
this.bullet = result;
this.quantityMultiplier = multiplier;
this.speedMultiplier = speedMultiplier;
this.id = (byte)(lastID++);
allTypes.add(this);
}
public static Array<AmmoType> getAllTypes() {

View File

@@ -68,6 +68,7 @@ public class Turret extends Block{
if(ammoTypes != null) {
for (AmmoType type : ammoTypes) {
if(type.item == null) continue;
if (ammoMap.containsKey(type.item)) {
throw new RuntimeException("Turret \"" + name + "\" has two conflicting ammo entries on item type " + type.item + "!");
} else {
@@ -153,9 +154,8 @@ public class Turret extends Block{
}
//must not be found
AmmoEntry entry = new AmmoEntry(type, type.quantityMultiplier);
AmmoEntry entry = new AmmoEntry(type, (int)type.quantityMultiplier);
entity.ammo.add(entry);
}
@Override

View File

@@ -0,0 +1,9 @@
package io.anuke.mindustry.world.blocks.types.defense.turrets;
import io.anuke.mindustry.world.blocks.types.defense.Turret;
public class ItemTurret extends Turret {
public ItemTurret(String name) {
super(name);
}
}

View File

@@ -1,43 +1,69 @@
package io.anuke.mindustry.world.blocks.types.defense.turrets;
import io.anuke.mindustry.content.Liquids;
import com.badlogic.gdx.utils.ObjectMap;
import io.anuke.mindustry.resource.AmmoType;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.Liquid;
import io.anuke.mindustry.world.BarType;
import io.anuke.mindustry.world.BlockBar;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.defense.Turret;
//TODO
public abstract class LiquidTurret extends Turret {
public Liquid ammoLiquid = Liquids.water;
public float liquidCapacity = 60f;
public float liquidPerShot = 1f;
protected ObjectMap<Liquid, AmmoType> liquidAmmoMap = new ObjectMap<>();
public LiquidTurret(String name) {
super(name);
hasLiquids = true;
}
@Override
public void setBars() {
super.setBars();
bars.remove(BarType.inventory);
bars.add(new BlockBar(BarType.liquid, true, tile -> tile.entity.liquid.amount / liquidCapacity));
}
@Override
public AmmoType useAmmo(Tile tile){
TurretEntity entity = tile.entity();
AmmoType type = liquidAmmoMap.get(entity.liquid.liquid);
entity.liquid.amount -= type.quantityMultiplier;
return type;
}
@Override
public AmmoType peekAmmo(Tile tile){
return liquidAmmoMap.get(tile.entity.liquid.liquid);
}
@Override
public boolean hasAmmo(Tile tile){
TurretEntity entity = tile.entity();
return liquidAmmoMap.get(entity.liquid.liquid) != null && entity.liquid.amount >= liquidAmmoMap.get(entity.liquid.liquid).quantityMultiplier;
}
@Override
public void init(){
super.init();
for (AmmoType type : ammoTypes) {
if (liquidAmmoMap.containsKey(type.liquid)) {
throw new RuntimeException("Turret \"" + name + "\" has two conflicting ammo entries on liquid type " + type.liquid + "!");
} else {
liquidAmmoMap.put(type.liquid, type);
}
}
}
@Override
public boolean acceptItem(Item item, Tile tile, Tile source) {
return false;
}
@Override
public void handleLiquid(Tile tile, Tile source, Liquid liquid, float amount) {
//TODO
}
/*
@Override
public void consumeAmmo(Tile tile){
TurretEntity entity = tile.entity();
entity.liquid.amount -= liquidPerShot;
}*/
@Override
public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){
return ammoLiquid == liquid && super.acceptLiquid(tile, source, liquid, amount);
return super.acceptLiquid(tile, source, liquid, amount) && liquidAmmoMap.get(liquid) != null;
}
}

View File

@@ -10,6 +10,7 @@ import java.io.IOException;
public class LiquidModule extends BlockModule {
public float amount;
/**Should never be null.*/
public Liquid liquid = Liquids.none;
@Override