Major turret and bullet refactoring // New effects

This commit is contained in:
Anuken 2018-04-02 21:43:06 -04:00
parent 20b95fa063
commit 54d0cae450
41 changed files with 606 additions and 1100 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 B

After

Width:  |  Height:  |  Size: 169 B

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

After

Width:  |  Height:  |  Size: 102 KiB

View File

@ -1,7 +1,7 @@
#Autogenerated file. Do not modify.
#Sun Apr 01 16:18:18 EDT 2018
#Mon Apr 02 21:38:06 EDT 2018
version=release
androidBuildCode=811
androidBuildCode=815
name=Mindustry
code=3.4
build=custom build

View File

@ -1,4 +1,10 @@
package io.anuke.mindustry.content;
import io.anuke.mindustry.content.bullets.TurretBullets;
import io.anuke.mindustry.resource.AmmoType;
public class AmmoTypes {
public static final AmmoType
basicIron = new AmmoType(Items.iron, TurretBullets.basicIron, 5, 0.9f);
}

View File

@ -9,11 +9,12 @@ import io.anuke.ucore.util.Mathf;
public class UpgradeRecipes {
private static final ObjectMap<Upgrade, ItemStack[]> recipes = Mathf.map(
Weapons.triblaster, list(stack(Items.iron, 60), stack(Items.steel, 80)),
Weapons.clustergun, list(stack(Items.iron, 300), stack(Items.steel, 80)),
Weapons.vulcan, list(stack(Items.iron, 100), stack(Items.steel, 150), stack(Items.titanium, 80)),
Weapons.beam, list(stack(Items.steel, 260), stack(Items.titanium, 160), stack(Items.densealloy, 120)),
Weapons.shockgun, list(stack(Items.steel, 240), stack(Items.titanium, 160), stack(Items.densealloy, 160))
/*
Weapons.triblaster, list(stack(Items.iron, 60), stack(Items.steel, 80)),
Weapons.clustergun, list(stack(Items.iron, 300), stack(Items.steel, 80)),
Weapons.vulcan, list(stack(Items.iron, 100), stack(Items.steel, 150), stack(Items.titanium, 80)),
Weapons.beam, list(stack(Items.steel, 260), stack(Items.titanium, 160), stack(Items.densealloy, 120)),
Weapons.shockgun, list(stack(Items.steel, 240), stack(Items.titanium, 160), stack(Items.densealloy, 160))*/
);
private static final ItemStack[] empty = {};

View File

@ -1,60 +1,16 @@
package io.anuke.mindustry.content;
import io.anuke.mindustry.entities.bullets.BulletType;
import io.anuke.mindustry.content.bullets.TurretBullets;
import io.anuke.mindustry.graphics.fx.BulletFx;
import io.anuke.mindustry.resource.Weapon;
public class Weapons {
public static final Weapon
blaster = new Weapon("blaster", 12, BulletType.shot) {
blaster = new Weapon("blaster", 12, TurretBullets.basicIron) {
{
effect = BulletFx.laserShoot;
effect = BulletFx.shootSmall;
length = 2f;
}
},
triblaster = new Weapon("triblaster", 16, BulletType.spread) {
{
shots = 3;
effect = BulletFx.spreadShoot;
roundrobin = true;
}
},
clustergun = new Weapon("clustergun", 26f, BulletType.cluster) {
{
effect = BulletFx.clusterShoot;
inaccuracy = 17f;
roundrobin = true;
shots = 2;
spacing = 0;
}
},
beam = new Weapon("beam", 30f, BulletType.beamlaser) {
{
effect = BulletFx.beamShoot;
inaccuracy = 0;
roundrobin = true;
shake = 2f;
}
},
vulcan = new Weapon("vulcan", 5, BulletType.vulcan) {
{
effect = BulletFx.vulcanShoot;
inaccuracy = 5;
roundrobin = true;
shake = 1f;
inaccuracy = 4f;
}
},
shockgun = new Weapon("shockgun", 36, BulletType.shockshell) {
{
shootsound = "bigshot";
effect = BulletFx.shockShoot;
shake = 2f;
roundrobin = true;
shots = 7;
inaccuracy = 15f;
length = 3.5f;
}
};
}

View File

@ -1,235 +1,68 @@
package io.anuke.mindustry.content.blocks;
import com.badlogic.gdx.graphics.Color;
import io.anuke.mindustry.content.Items;
import io.anuke.mindustry.content.Liquids;
import io.anuke.mindustry.entities.bullets.BulletType;
import io.anuke.mindustry.entities.effect.TeslaOrb;
import io.anuke.mindustry.content.AmmoTypes;
import io.anuke.mindustry.graphics.fx.BulletFx;
import io.anuke.mindustry.resource.AmmoType;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.defense.LaserTurret;
import io.anuke.mindustry.world.blocks.types.defense.LiquidTurret;
import io.anuke.mindustry.world.blocks.types.defense.PowerTurret;
import io.anuke.mindustry.world.blocks.types.defense.Turret;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf;
import io.anuke.mindustry.world.blocks.types.defense.turrets.DoubleTurret;
import io.anuke.mindustry.world.blocks.types.defense.turrets.LiquidTurret;
import io.anuke.mindustry.world.blocks.types.defense.turrets.PowerTurret;
public class WeaponBlocks{
public static Block
doubleturret = new Turret("doubleturret"){
{
range = 44;
reload = 13f;
bullet = BulletType.stone;
ammo = Items.stone;
health = 45;
shots = 2;
}
@Override
protected void shoot(Tile tile){
TurretEntity entity = tile.entity();
for(int i : Mathf.signs){
tr.trns(entity.rotation, 4, -2 * i);
bullet(tile, entity.rotation);
}
}
},
doubleturret = new DoubleTurret("doubleturret"){{
ammoTypes = new AmmoType[]{AmmoTypes.basicIron};
reload = 40f;
shootEffect = BulletFx.shootSmall;
}},
gatlingturret = new Turret("gatlingturret"){
{
range = 65;
reload = 7f;
bullet = BulletType.iron;
ammo = Items.iron;
health = 65;
}
},
flameturret = new Turret("flameturret"){
{
range = 45f;
reload = 5f;
bullet = BulletType.flame;
ammo = Items.coal;
health = 90;
inaccuracy = 4f;
}
},
railgunturret = new Turret("railgunturret"){
{
shootsound = "railgun";
range = 120;
reload = 50f;
bullet = BulletType.sniper;
ammo = Items.steel;
health = 70;
shootEffect = BulletFx.railshot;
}
},
flakturret = new Turret("flakturret"){
{
shootsound = "bigshot";
rotatespeed = 0.2f;
range = 120;
reload = 55f;
bullet = BulletType.flak;
shots = 3;
inaccuracy = 9f;
ammo = Items.coal;
ammoMultiplier = 5;
health = 110;
shootEffect = BulletFx.mortarshot;
shootShake = 2f;
size = 2;
}
},
laserturret = new LaserTurret("laserturret"){
{
shootsound = "laser";
beamColor = Color.SKY;
range = 60;
reload = 4f;
damage = 10;
health = 110;
powerUsed = 0.2f;
}
},
teslaturret = new PowerTurret("teslaturret"){
{
shootsound = "tesla";
range = 70;
reload = 15f;
bullet = BulletType.shell;
health = 140;
}
@Override
public void shoot(Tile tile){
TurretEntity entity = tile.entity();
float len = 4f;
new TeslaOrb(tile.getTeam(), tile.drawx() + Angles.trnsx(entity.rotation, len), tile.drawy() + Angles.trnsy(entity.rotation, len), range, 9).add();
}
},
magmaturret = new LiquidTurret("magmaturret") {
{
shootsound = "flame2";
inaccuracy = 7f;
range = 90f;
reload = 7f;
bullet = BulletType.plasmaflame;
ammoLiquid = Liquids.lava;
liquidPerShot = 3f;
health = 180*3;
size = 2;
}
},
plasmaturret = new Turret("plasmaturret"){
{
shootsound = "flame2";
inaccuracy = 7f;
range = 60f;
reload = 3f;
bullet = BulletType.plasmaflame;
ammo = Items.coal;
health = 180;
ammoMultiplier = 40;
}
},
chainturret = new Turret("chainturret"){
{
shootsound = "bigshot";
inaccuracy = 8f;
range = 80f;
reload = 8f;
bullet = BulletType.chain;
ammo = Items.thorium;
health = 430;
size = 2;
shootCone = 9f;
ammoMultiplier = 8;
shots = 2;
shootEffect = BulletFx.chainshot;
}
@Override
protected void shoot(Tile tile){
TurretEntity entity = tile.entity();
float len = 8;
float space = 3.5f;
for(int i = -1; i < 1; i ++){
tr.trns(entity.rotation, len, Mathf.sign(i) * space);
bullet(tile, entity.rotation);
Effects.effect(shootEffect, tile.drawx() + tr.x,
tile.drawy() + tr.y, entity.rotation);
}
Effects.shake(1f, 1f, tile.worldx(), tile.worldy());
}
},
titanturret = new Turret("titancannon"){
{
shootsound = "blast";
range = 120f;
reload = 23f;
bullet = BulletType.titanshell;
ammo = Items.thorium;
health = 800;
ammoMultiplier = 4;
size = 3;
rotatespeed = 0.07f;
shootCone = 9f;
shootEffect = BulletFx.titanshot;
shootShake = 3f;
}
},
fornaxcannon = new PowerTurret("fornaxcannon") {
{
shootsound = "blast";
range = 120f;
reload = 23f;
bullet = BulletType.titanshell;
ammo = Items.thorium;
health = 800;
ammoMultiplier = 4;
size = 3;
rotatespeed = 0.07f;
shootCone = 9f;
shootEffect = BulletFx.titanshot;
shootShake = 3f;
}
},
missileturret = new PowerTurret("missileturret") {
{
shootsound = "blast";
range = 120f;
reload = 23f;
bullet = BulletType.titanshell;
ammo = Items.thorium;
health = 800;
ammoMultiplier = 4;
size = 2;
rotatespeed = 0.07f;
shootCone = 9f;
shootEffect = BulletFx.titanshot;
shootShake = 3f;
}
};
}

View File

@ -0,0 +1,19 @@
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.ucore.graphics.Draw;
public class TurretBullets {
public static final BulletType
basicIron = new BulletType(2f, 0) {
@Override
public void draw(Bullet b) {
Draw.color(Color.valueOf("f6e096"));
Draw.rect("bullet", b.x, b.y, b.angle() - 90);
Draw.color();
}
};
}

View File

@ -0,0 +1,4 @@
package io.anuke.mindustry.content.bullets;
public class UnitBullets {
}

View File

@ -0,0 +1,15 @@
package io.anuke.mindustry.content.bullets;
import io.anuke.mindustry.entities.Bullet;
import io.anuke.mindustry.entities.BulletType;
public class WeaponBullets {
public static final BulletType
none = new BulletType(0f, 0) {
@Override
public void draw(Bullet b) {
}
};
}

View File

@ -4,7 +4,7 @@ import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.utils.IntMap;
import com.badlogic.gdx.utils.IntSet;
import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.bullets.BulletType;
import io.anuke.mindustry.entities.BulletType;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.SyncEntity;
import io.anuke.mindustry.entities.units.BaseUnit;

View File

@ -5,7 +5,7 @@ import io.anuke.mindustry.content.Mechs;
import io.anuke.mindustry.content.Recipes;
import io.anuke.mindustry.content.UpgradeRecipes;
import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.bullets.BulletType;
import io.anuke.mindustry.entities.BulletType;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.SyncEntity;
import io.anuke.mindustry.game.EventType.GameOverEvent;

View File

@ -1,6 +1,5 @@
package io.anuke.mindustry.entities;
import io.anuke.mindustry.entities.bullets.BulletType;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.entities.BulletEntity;
@ -13,14 +12,14 @@ public class Bullet extends BulletEntity{
public Timer timer = new Timer(3);
public Team team;
public Bullet(io.anuke.mindustry.entities.bullets.BulletType type, Unit owner, float x, float y, float angle){
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);
}
public Bullet(io.anuke.mindustry.entities.bullets.BulletType type, Entity owner, Team team, float x, float y, float angle){
public Bullet(BulletType type, Entity owner, Team team, float x, float y, float angle){
super(type, owner, angle);
this.team = team;
this.type = type;

View File

@ -1,19 +1,20 @@
package io.anuke.mindustry.entities.bullets;
package io.anuke.mindustry.entities;
import io.anuke.mindustry.entities.Bullet;
import io.anuke.mindustry.graphics.fx.Fx;
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;
private BulletType(float speed, int damage){
public BulletType(float speed, int damage){
this.speed = speed;
this.damage = damage;
}
@Override
public void hit(Bullet b, float hitx, float hity){
Effects.effect(Fx.hit, hitx, hity);
Effects.effect(hitEffect, hitx, hity, b.angle());
}
}

View File

@ -5,7 +5,6 @@ import com.badlogic.gdx.math.Vector2;
import io.anuke.mindustry.content.Mechs;
import io.anuke.mindustry.content.Weapons;
import io.anuke.mindustry.content.blocks.Blocks;
import io.anuke.mindustry.entities.bullets.BulletType;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.graphics.fx.ExplosionFx;
import io.anuke.mindustry.graphics.fx.Fx;

View File

@ -4,7 +4,6 @@ import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.TimeUtils;
import io.anuke.mindustry.entities.bullets.BulletType;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.DestructibleEntity;
import io.anuke.ucore.util.Mathf;

View File

@ -1,4 +0,0 @@
package io.anuke.mindustry.entities.bullets;
public class TurretBullets {
}

View File

@ -1,4 +0,0 @@
package io.anuke.mindustry.entities.bullets;
public class UnitBullets {
}

View File

@ -1,4 +0,0 @@
package io.anuke.mindustry.entities.bullets;
public class WeaponBullets {
}

View File

@ -1,118 +0,0 @@
package io.anuke.mindustry.entities.effect;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.graphics.fx.BulletFx;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.entities.TimedEntity;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Translator;
import static io.anuke.mindustry.Vars.tilesize;
import static io.anuke.mindustry.Vars.world;
public class EMP extends TimedEntity{
static final int maxTargets = 8;
static Array<Tile> array = new Array<>();
static Translator tr = new Translator();
int radius = 4;
int damage = 6;
Array<Tile> targets = new Array<>(maxTargets);
public EMP(float x, float y, int damage){
this.damage = damage;
set(x, y);
lifetime = 30f;
int worldx = Mathf.scl2(x, tilesize);
int worldy = Mathf.scl2(y, tilesize);
array.clear();
for(int dx = -radius; dx <= radius; dx ++){
for(int dy = -radius; dy <= radius; dy ++){
if(Vector2.dst(dx, dy, 0, 0) < radius){
Tile tile = world.tile(worldx + dx, worldy + dy);
if(tile != null && tile.block().destructible){
array.add(tile);
}
}
}
}
array.shuffle();
for(int i = 0; i < array.size && i < maxTargets; i ++){
Tile tile = array.get(i);
targets.add(tile);
if(tile != null && tile.block().hasPower){
tile.entity.power.amount = 0f;
tile.entity.damage((int)(damage*2f)); //extra damage
}
if(tile == null) continue;
//entity may be null here, after the block is dead!
Effects.effect(BulletFx.empspark, tile.worldx(), tile.worldy());
if(tile.entity != null) tile.entity.damage(damage);
}
}
@Override
public void drawOver(){
Draw.color(Color.SKY);
for(int i = 0; i < targets.size; i ++){
Tile target = targets.get(i);
drawLine(target.worldx(), target.worldy());
float rad = 5f*fract();
Draw.rect("circle", target.worldx(), target.worldy(), rad, rad);
}
for(int i = 0; i < 14 - targets.size; i ++){
tr.trns(Mathf.randomSeed(i + id*77)*360f, radius * tilesize);
drawLine(x + tr.x, y + tr.y);
}
Lines.stroke(fract()*2f);
Lines.poly(x, y, 34, radius * tilesize);
Draw.reset();
}
private void drawLine(float targetx, float targety){
int joints = 3;
float r = 3f;
float lastx = x, lasty = y;
for(int seg = 0; seg < joints; seg ++){
float dx = Mathf.range(r),
dy = Mathf.range(r);
float frac = (seg+1f)/joints;
float tx = (targetx - x)*frac + x + dx,
ty = (targety - y)*frac + y + dy;
drawLaser(lastx, lasty, tx, ty);
lastx = tx;
lasty = ty;
}
}
private void drawLaser(float x, float y, float x2, float y2){
Lines.stroke(fract() * 2f);
Lines.line(x, y, x2, y2);
}
}

View File

@ -1,132 +0,0 @@
package io.anuke.mindustry.entities.effect;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.ObjectSet;
import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.entities.units.BaseUnit;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.graphics.fx.BulletFx;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.Entity;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.util.Mathf;
public class TeslaOrb extends Entity{
private final static Rectangle rect = new Rectangle();
private final Array<Vector2> points = new Array<>();
private final ObjectSet<BaseUnit> hit = new ObjectSet<>();
private final int damage;
private final float range;
private final float lifetime = 30f;
private final Vector2 vector = new Vector2();
private final Team team;
private float life = 0f;
private float curx = x, cury = y;
private boolean done = false;
public TeslaOrb(Team team, float x, float y, float range, int damage){
set(x, y);
this.team = team;
this.damage = damage;
this.range = range;
}
void shock(){
float stopchance = 0.1f;
float shake = 3f;
int max = 7;
while(points.size < max){
if(Mathf.chance(stopchance)){
break;
}
rect.setSize(range*2f).setCenter(curx, cury);
Units.getNearbyEnemies(team, rect, entity -> {
if(!done && entity != null && entity.distanceTo(curx, cury) < range && !hit.contains((BaseUnit)entity)){
hit.add((BaseUnit)entity);
points.add(new Vector2(entity.x + Mathf.range(shake), entity.y + Mathf.range(shake)));
damageEnemy((BaseUnit)entity);
curx = entity.x;
cury = entity.y;
done = true;
}
});
}
if(points.size == 0){
remove();
}
}
void damageEnemy(BaseUnit enemy){
enemy.damage(damage);
Effects.effect(BulletFx.laserhit, enemy.x + Mathf.range(2f), enemy.y + Mathf.range(2f));
}
@Override
public void update(){
life += Timers.delta();
if(life >= lifetime){
remove();
}
}
@Override
public void drawOver(){
if(points.size == 0) return;
float range = 1f;
Vector2 previous = vector.set(x, y);
for(Vector2 enemy : points){
float x1 = previous.x + Mathf.range(range),
y1 = previous.y + Mathf.range(range),
x2 = enemy.x + Mathf.range(range),
y2 = enemy.y + Mathf.range(range);
Draw.color(Color.WHITE);
Draw.alpha(1f-life/lifetime);
Lines.stroke(3f - life/lifetime*2f);
Lines.line(x1, y1, x2, y2);
float rad = 7f - life/lifetime*5f;
Draw.rect("circle", x2, y2, rad, rad);
if(previous.epsilonEquals(x, y, 0.001f)){
Draw.rect("circle", x, y, rad, rad);
}
Draw.reset();
previous = enemy;
}
}
@Override
public void added(){
Timers.run(1f, ()->{
shock();
});
}
@Override
public float drawSize(){
return 200;
}
}

View File

@ -1,7 +1,7 @@
package io.anuke.mindustry.entities.units;
import io.anuke.mindustry.entities.Bullet;
import io.anuke.mindustry.entities.bullets.BulletType;
import io.anuke.mindustry.entities.BulletType;
import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.game.Team;
import io.anuke.ucore.entities.Entity;

View File

@ -2,7 +2,6 @@ package io.anuke.mindustry.entities.units;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.ObjectSet;
import io.anuke.mindustry.entities.bullets.BulletType;
import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.game.TeamInfo.TeamData;
import io.anuke.mindustry.graphics.fx.Fx;
@ -66,7 +65,7 @@ public class FlyingUnitType extends UnitType {
unit.velocity.add(vec); //TODO clamp it so it doesn't glitch out at low fps
if(unit.timer.get(timerReload, reload) && len < range){
shoot(unit, BulletType.shot, ang, 4f);
//shoot(unit, BulletType.shot, ang, 4f);
}
}

View File

@ -2,7 +2,6 @@ package io.anuke.mindustry.entities.units;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.ObjectSet;
import io.anuke.mindustry.entities.bullets.BulletType;
import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.game.TeamInfo.TeamData;
@ -99,7 +98,7 @@ public abstract class GroundUnitType extends UnitType{
}
if(unit.timer.get(timerReload, reload)){
shoot(unit, BulletType.shot, tr2.angle(), 4f);
//shoot(unit, BulletType.shot, tr2.angle(), 4f);
}
}
}

View File

@ -2,7 +2,7 @@ package io.anuke.mindustry.entities.units;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.entities.Bullet;
import io.anuke.mindustry.entities.bullets.BulletType;
import io.anuke.mindustry.entities.BulletType;
import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.graphics.fx.ExplosionFx;

View File

@ -1,7 +1,7 @@
package io.anuke.mindustry.game;
import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.bullets.BulletType;
import io.anuke.mindustry.entities.BulletType;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.entities.units.BaseUnit;
import io.anuke.mindustry.resource.Weapon;

View File

@ -10,174 +10,34 @@ import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf;
public class BulletFx {
public static Color lightOrange = Color.valueOf("f68021");
public static Color lighterOrange = Color.valueOf("f6e096");
public static final Effect
chainshot = new Effect(9f, e -> {
Draw.color(Color.WHITE, Fx.lightOrange, e.ifract());
Lines.stroke(e.fract()*4f);
Lines.lineAngle(e.x, e.y, e.rotation, e.fract()*7f);
Lines.stroke(e.fract()*2f);
Lines.lineAngle(e.x, e.y, e.rotation, e.fract()*10f);
shootSmall = new Effect(8, e -> {
Draw.color(lighterOrange, lightOrange, e.ifract());
float w = 1f + 5 * e.fract();
Shapes.tri(e.x, e.y, w, 15f * e.fract(), e.rotation);
Shapes.tri(e.x, e.y, w, 3f * e.fract(), e.rotation + 180f);
Draw.reset();
}),
mortarshot = new Effect(10f, e -> {
Draw.color(Color.WHITE, Color.DARK_GRAY, e.ifract());
Lines.stroke(e.fract()*6f);
Lines.lineAngle(e.x, e.y, e.rotation, e.fract()*10f);
Lines.stroke(e.fract()*5f);
Lines.lineAngle(e.x, e.y, e.rotation, e.fract()*14f);
Lines.stroke(e.fract()*1f);
Lines.lineAngle(e.x, e.y, e.rotation, e.fract()*16f);
smokeParticleSmall = new Effect(20, e -> {
Draw.color(Color.GRAY);
Fill.circle(e.x, e.y, e.fract()*1.5f);
Draw.reset();
}),
railshot = new Effect(9f, e -> {
Draw.color(Color.WHITE, Color.DARK_GRAY, e.ifract());
Lines.stroke(e.fract()*5f);
Lines.lineAngle(e.x, e.y, e.rotation, e.fract()*8f);
Lines.stroke(e.fract()*4f);
Lines.lineAngle(e.x, e.y, e.rotation, e.fract()*12f);
Lines.stroke(e.fract()*1f);
Lines.lineAngle(e.x, e.y, e.rotation, e.fract()*14f);
Draw.reset();
}),
titanshot = new Effect(12f, e -> {
Draw.color(Color.WHITE, Fx.lightOrange, e.ifract());
Lines.stroke(e.fract()*7f);
Lines.lineAngle(e.x, e.y, e.rotation, e.fract()*12f);
Lines.stroke(e.fract()*4f);
Lines.lineAngle(e.x, e.y, e.rotation, e.fract()*16f);
Lines.stroke(e.fract()*2f);
Lines.lineAngle(e.x, e.y, e.rotation, e.fract()*18f);
Draw.reset();
}),
shockwaveSmall = new Effect(10f, e -> {
Draw.color(Color.WHITE, Color.LIGHT_GRAY, e.ifract());
Lines.stroke(e.fract()*2f + 0.1f);
Lines.circle(e.x, e.y, e.ifract()*15f);
Draw.reset();
}),
empshockwave = new Effect(7f, e -> {
Draw.color(Color.WHITE, Color.SKY, e.ifract());
Lines.stroke(e.fract()*2f);
Lines.circle(e.x, e.y, e.ifract()*40f);
Draw.reset();
}),
empspark = new Effect(13, e -> {
Angles.randLenVectors(e.id, 7, 1f + e.ifract()*12f, (x, y)->{
float len = 1f+e.fract()*6f;
Draw.color(Color.SKY);
Lines.lineAngle(e.x + x, e.y + y, Mathf.atan2(x, y), len);
Draw.reset();
});
}),
shellsmoke = new Effect(20, e -> {
Angles.randLenVectors(e.id, 8, 3f + e.ifract()*17f, (x, y)->{
float size = 2f+e.fract()*5f;
Draw.color(Color.LIGHT_GRAY, Color.DARK_GRAY, e.ifract());
Draw.rect("circle", e.x + x, e.y + y, size, size);
Draw.reset();
});
}),
shellexplosion = new Effect(9, e -> {
Lines.stroke(2f - e.ifract()*1.7f);
Draw.color(Color.WHITE, Color.LIGHT_GRAY, e.ifract());
Lines.circle(e.x, e.y, 3f + e.ifract() * 9f);
Draw.reset();
}),
blastexplosion = new Effect(14, e -> {
Lines.stroke(1.2f - e.ifract());
Draw.color(Color.WHITE, Fx.lightOrange, e.ifract());
Lines.circle(e.x, e.y, 1.5f + e.ifract() * 9f);
Draw.reset();
}),
laserhit = new Effect(10, e -> {
Lines.stroke(1f);
Draw.color(Color.WHITE, Color.SKY, e.ifract());
Lines.spikes(e.x, e.y, e.ifract() * 2f, 2, 6);
Draw.reset();
}),
shieldhit = new Effect(9, e -> {
Lines.stroke(1f);
Draw.color(Color.WHITE, Color.SKY, e.ifract());
Lines.spikes(e.x, e.y, e.ifract() * 5f, 2, 6);
Lines.stroke(4f*e.fract());
Lines.circle(e.x, e.y, e.ifract()*14f);
Draw.reset();
}),
laserShoot = new Effect(8, e -> {
Draw.color(Color.WHITE, Fx.lightOrange, e.ifract());
Shapes.lineShot(e.x, e.y, e.rotation, 3, e.fract(), 6f, 2f, 0.8f);
Draw.reset();
}),
spreadShoot = new Effect(12, e -> {
Draw.color(Color.WHITE, Color.PURPLE, e.ifract());
Shapes.lineShot(e.x, e.y, e.rotation, 3, e.fract(), 9f, 3.5f, 0.8f);
Draw.reset();
}),
clusterShoot = new Effect(12, e -> {
Draw.color(Color.WHITE, Fx.lightOrange, e.ifract());
Shapes.lineShot(e.x, e.y, e.rotation, 3, e.fract(), 10f, 2.5f, 0.7f);
Draw.reset();
}),
vulcanShoot = new Effect(8, e -> {
Draw.color(Fx.lighterOrange, Fx.lightOrange, e.ifract());
Shapes.lineShot(e.x, e.y, e.rotation, 3, e.fract(), 10f, 2f, 0.7f);
Draw.reset();
}),
shockShoot = new Effect(8, e -> {
Draw.color(Color.WHITE, Color.ORANGE, e.ifract());
Shapes.lineShot(e.x, e.y, e.rotation, 3, e.fract(), 14f, 4f, 0.8f);
Draw.reset();
}),
beamShoot = new Effect(8, e -> {
Draw.color(Fx.beamLight, Fx.beam, e.ifract());
Shapes.lineShot(e.x, e.y, e.rotation - 70, 3, e.fract(), 12f, 1f, 0.5f);
Shapes.lineShot(e.x, e.y, e.rotation + 70, 3, e.fract(), 12f, 1f, 0.5f);
Draw.reset();
}),
beamhit = new Effect(8, e -> {
Draw.color(Fx.beamLight, Fx.beam, e.ifract());
Lines.stroke(e.fract()*3f+0.5f);
Lines.circle(e.x, e.y, e.ifract()*8f);
Lines.spikes(e.x, e.y, e.ifract()*6f, 2f, 4, 45);
Draw.reset();
}),
blockexplosion = new Effect(13, e -> {
Angles.randLenVectors(e.id+1, 8, 5f + e.ifract()*11f, (x, y)->{
float size = 2f+e.fract()*8f;
Draw.color(Color.LIGHT_GRAY, Color.DARK_GRAY, e.ifract());
Draw.rect("circle", e.x + x, e.y + y, size, size);
Draw.reset();
hit = new Effect(14, e -> {
Draw.color(Color.WHITE, lighterOrange, 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);
});
Lines.stroke(2f*e.fract()+0.4f);
Draw.color(Color.WHITE, Color.ORANGE, e.powfract());
Lines.circle(e.x, e.y, 2f + e.powfract() * 9f);
Draw.color(e.ifract() < 0.5f ? Color.WHITE : Color.DARK_GRAY);
Angles.randLenVectors(e.id, 5, 8f, (x, y)->{
Fill.circle(e.x + x, e.y + y, e.fract()*5f + 1f);
});
Draw.reset();
}),
clusterbomb = new Effect(10f, e -> {
Draw.color(Color.WHITE, Fx.lightOrange, e.ifract());
Lines.stroke(e.fract()*1.5f);
Lines.poly(e.x, e.y, 4, e.fract()*8f);
Lines.circle(e.x, e.y, e.ifract()*14f);
Draw.reset();
}),
railsmoke = new Effect(30, e -> {
Draw.color(Color.LIGHT_GRAY, Color.WHITE, e.ifract());
float size = e.fract()*4f;
Draw.rect("circle", e.x, e.y, size, size);
Draw.reset();
}),
chainsmoke = new Effect(30, e -> {
Draw.color(Fx.lightGray);
float size = e.fract()*4f;
Draw.rect("circle", e.x, e.y, size, size);
Draw.reset();
});
}

View File

@ -13,7 +13,7 @@ public class ExplosionFx {
generatorexplosion = new Effect(28, 40f, e -> {
Angles.randLenVectors(e.id, 16, 10f + e.ifract()*8f, (x, y)->{
float size = e.fract()*12f + 1f;
Draw.color(Color.WHITE, Fx.lightOrange, e.ifract());
Draw.color(Color.WHITE, Color.PURPLE, e.ifract());
Draw.rect("circle", e.x + x, e.y + y, size, size);
Draw.reset();
});

View File

@ -4,21 +4,13 @@ import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Colors;
import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Hue;
import io.anuke.ucore.graphics.Lines;
import static io.anuke.mindustry.Vars.respawnduration;
import static io.anuke.mindustry.Vars.tilesize;
public class Fx{
public static Color lightOrange = Color.valueOf("f68021");
public static Color lighterOrange = Color.valueOf("f6e096");
public static Color whiteOrange = Hue.mix(lightOrange, Color.WHITE, 0.6f);
public static Color whiteYellow = Hue.mix(Color.YELLOW, Color.WHITE, 0.6f);
public static Color lightGray = Color.valueOf("b0b0b0");
public static Color glowy = Color.valueOf("fdc056");
public static Color beam = Color.valueOf("9bffbe");
public static Color beamLight = Color.valueOf("ddffe9");
public static Color stoneGray = Color.valueOf("8f8f8f");
public static final Effect
@ -38,13 +30,6 @@ public class Fx{
Draw.reset();
}),
hit = new Effect(10, e -> {
Lines.stroke(1f);
Draw.color(Color.WHITE, Color.ORANGE, e.ifract());
Lines.spikes(e.x, e.y, e.ifract() * 3f, 2, 8);
Draw.reset();
}),
smoke = new Effect(100, e -> {
Draw.color(Color.GRAY, new Color(0.3f, 0.3f, 0.3f, 1f), e.ifract());
float size = 7f-e.ifract()*7f;

View File

@ -1,15 +1,32 @@
package io.anuke.mindustry.resource;
import io.anuke.mindustry.entities.bullets.BulletType;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.entities.BulletType;
public class AmmoType {
private static int lastID = 0;
private static Array<AmmoType> allTypes = new Array<>();
public final byte id;
public final Item item;
public final BulletType bullet;
public final int multiplier;
public final int quantityMultiplier;
public final float speedMultiplier;
public AmmoType(Item item, BulletType result, int multiplier){
public AmmoType(Item item, BulletType result, int multiplier, float speedMultiplier){
this.item = item;
this.bullet = result;
this.multiplier = multiplier;
this.quantityMultiplier = multiplier;
this.speedMultiplier = speedMultiplier;
this.id = (byte)(lastID++);
allTypes.add(this);
}
public static Array<AmmoType> getAllTypes() {
return allTypes;
}
public static AmmoType getByID(byte id){
return allTypes.get(id);
}
}

View File

@ -2,7 +2,7 @@ package io.anuke.mindustry.resource;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.entities.Bullet;
import io.anuke.mindustry.entities.bullets.BulletType;
import io.anuke.mindustry.entities.BulletType;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.net.Net;

View File

@ -8,8 +8,8 @@ import com.badlogic.gdx.utils.reflect.ClassReflection;
import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.graphics.DrawLayer;
import io.anuke.mindustry.graphics.fx.BulletFx;
import io.anuke.mindustry.graphics.Layer;
import io.anuke.mindustry.graphics.fx.ExplosionFx;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.NetEvents;
import io.anuke.mindustry.resource.ItemStack;
@ -40,7 +40,7 @@ public class Block extends BaseBlock {
/**display name*/
public final String formalName;
/**played on destroy*/
public Effect explosionEffect = BulletFx.blockexplosion;
public Effect explosionEffect = ExplosionFx.generatorexplosion;
/**played on destroy*/
public String explosionSound = "break";
/**whether this block has a tile entity that updates*/

View File

@ -3,9 +3,10 @@ package io.anuke.mindustry.world.blocks.types.defense;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.MathUtils;
import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.graphics.fx.BulletFx;
import io.anuke.mindustry.graphics.Layer;
import io.anuke.mindustry.graphics.fx.Fx;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.defense.turrets.PowerTurret;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.core.Timers;
@ -15,9 +16,9 @@ import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Tmp;
public class LaserTurret extends PowerTurret{
public class LaserTurret extends PowerTurret {
protected Color beamColor = Color.WHITE.cpy();
protected Effect hiteffect = BulletFx.laserhit;
protected Effect hiteffect = Fx.none;
protected int damage = 4;
protected float cone = 15f;
@ -25,11 +26,11 @@ public class LaserTurret extends PowerTurret{
super(name);
shootsound = null;
layer2 = Layer.laser;
soundReload = 20;
//soundReload = 20;
}
@Override
public void shoot(Tile tile){
public void updateShooting(Tile tile){
TurretEntity entity = tile.entity();
Unit enemy = entity.target;

View File

@ -5,6 +5,7 @@ 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.types.defense.turrets.PowerTurret;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Hue;
@ -13,7 +14,7 @@ import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Strings;
public class RepairTurret extends PowerTurret{
public class RepairTurret extends PowerTurret {
protected float repairFrac = 1f / 135f;
public RepairTurret(String name) {
@ -56,7 +57,8 @@ public class RepairTurret extends PowerTurret{
int maxhealth = entity.blockTarget.tile.block().health;
if(entity.timer.get(timerReload, reload) && Angles.angleDist(target, entity.rotation) < shootCone){
//TODO
if(entity.timer.get(100, reload) && Angles.angleDist(target, entity.rotation) < shootCone){
entity.blockTarget.health += maxhealth * repairFrac;
if(entity.blockTarget.health > maxhealth)

View File

@ -3,10 +3,8 @@ package io.anuke.mindustry.world.blocks.types.defense;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.entities.effect.Shield;
import io.anuke.mindustry.graphics.fx.BulletFx;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.PowerBlock;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.BulletEntity;
import io.anuke.ucore.util.Mathf;
@ -75,7 +73,7 @@ public class ShieldBlock extends PowerBlock{
}
bullet.remove();
Effects.effect(bullet.damage > 5 ? BulletFx.shieldhit : BulletFx.laserhit, bullet);
//Effects.effect(bullet.damage > 5 ? BulletFx.shieldhit : BulletFx.laserhit, bullet);
if(!headless) renderer.addShieldHit(bullet.x, bullet.y);
entity.power.amount -= bullet.getDamage() * powerPerDamage;

View File

@ -1,10 +1,11 @@
package io.anuke.mindustry.world.blocks.types.defense;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.ObjectMap;
import io.anuke.mindustry.entities.*;
import io.anuke.mindustry.entities.bullets.BulletType;
import io.anuke.mindustry.graphics.fx.Fx;
import io.anuke.mindustry.graphics.Layer;
import io.anuke.mindustry.graphics.fx.Fx;
import io.anuke.mindustry.resource.AmmoType;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.world.*;
@ -13,42 +14,40 @@ import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Strings;
import io.anuke.ucore.util.Translator;
import io.anuke.ucore.util.*;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import static io.anuke.mindustry.Vars.*;
import static io.anuke.mindustry.Vars.tilesize;
public class Turret extends Block{
static final int targetInterval = 15;
static boolean drawDebug = false;
protected static final int targetInterval = 15;
protected final int timerTarget = timers++;
protected final int timerReload = timers++;
protected final int timerSound = timers++;
protected int maxammo = 100;
//TODO implement this!
/**A value of 'null' means this turret does not need ammo.*/
protected AmmoType[] ammoTypes;
protected ObjectMap<Item, AmmoType> ammoMap = new ObjectMap<>();
protected float range = 50f;
protected float reload = 10f;
protected float inaccuracy = 0f;
protected int shots = 1;
protected float shotTransation = 2;
protected float shotDelayScale = 0;
protected String shootsound = "shoot";
protected AmmoType[] ammoTypes;
protected int maxammo = 400;
protected float recoil = 1f;
protected float restitution = 0.02f;
protected float rotatespeed = 0.2f;
protected float shootCone = 5f;
protected Effect shootEffect = Fx.none;
protected float shootShake = 0f;
protected int soundReload = 0;
protected Translator tr = new Translator();
protected Translator tr2 = new Translator();
protected String base = null; //name of the region to draw under turret, usually null
protected ShootStyle style = ShootStyle.normal;
protected Effect shootEffect = Fx.none;
protected String shootsound = "shoot";
public Turret(String name) {
super(name);
@ -56,11 +55,27 @@ public class Turret extends Block{
solid = true;
layer = Layer.turret;
group = BlockGroup.turrets;
hasInventory = false;
}
@Override
public void init(){
super.init();
if(ammoTypes != null) {
for (AmmoType type : ammoTypes) {
if (ammoMap.containsKey(type.item)) {
throw new RuntimeException("Turret \"" + name + "\" has two conflicting ammo entries on item type " + type.item + "!");
} else {
ammoMap.put(type.item, type);
}
}
}
}
@Override
public void setBars(){
bars.replace(new BlockBar(BarType.inventory, true, tile -> (float)tile.<TurretEntity>entity().ammo / maxammo));
bars.replace(new BlockBar(BarType.inventory, true, tile -> (float)tile.<TurretEntity>entity().totalAmmo / maxammo));
}
@Override
@ -95,11 +110,9 @@ public class Turret extends Block{
public void drawLayer(Tile tile){
TurretEntity entity = tile.entity();
Draw.rect(name(), tile.drawx(), tile.drawy(), entity.rotation - 90);
if(debug && drawDebug){
drawTargeting(tile);
}
tr2.trns(entity.rotation, -entity.recoil);
Draw.rect(name(), tile.drawx() + tr2.x, tile.drawy() + tr2.y, entity.rotation - 90);
}
@Override
@ -115,25 +128,49 @@ public class Turret extends Block{
Lines.stroke(1f);
Lines.dashCircle(x * tilesize, y * tilesize, range);
}
@Override
@Override
public void handleItem(Item item, Tile tile, Tile source) {
TurretEntity entity = tile.entity();
AmmoType type = ammoMap.get(item);
entity.totalAmmo += type.quantityMultiplier;
//find ammo entry by type
for(int i = 0; i < entity.ammo.size; i ++){
AmmoEntry entry = entity.ammo.get(i);
//if found, put it to the right
if(entry.type == type){
entry.amount += type.quantityMultiplier;
entity.ammo.swap(i, entity.ammo.size-1);
return;
}
}
//must not be found
AmmoEntry entry = new AmmoEntry(type, type.quantityMultiplier);
entity.ammo.add(entry);
}
@Override
public boolean acceptItem(Item item, Tile tile, Tile source){
return item == ammo && tile.<TurretEntity>entity().ammo < maxammo;
TurretEntity entity = tile.entity();
return ammoMap != null && ammoMap.get(item) != null && entity.totalAmmo + ammoMap.get(item).quantityMultiplier <= maxammo;
}
@Override
public void update(Tile tile){
TurretEntity entity = tile.entity();
if(ammo != null && entity.inventory.hasItem(ammo)){
entity.ammo += ammoMultiplier;
entity.inventory.removeItem(ammo, 1);
}
if(entity.target != null && entity.target.isDead())
entity.target = null;
entity.recoil = Mathf.lerpDelta(entity.recoil, 0f, restitution);
if(hasAmmo(tile) || (debug && infiniteAmmo)){
if(hasAmmo(tile)){
if(entity.timer.get(timerTarget, targetInterval)){
entity.target = Units.getClosestEnemy(tile.getTeam(),
@ -141,9 +178,10 @@ public class Turret extends Block{
}
if(entity.target != null){
AmmoType type = peekAmmo(tile);
float targetRot = Angles.predictAngle(tile.worldx(), tile.worldy(),
entity.target.x, entity.target.y, entity.target.velocity.x, entity.target.velocity.y, bullet.speed);
entity.target.x, entity.target.y, entity.target.velocity.x, entity.target.velocity.y, type.bullet.speed);
if(Float.isNaN(entity.rotation)){
entity.rotation = 0;
@ -151,82 +189,70 @@ public class Turret extends Block{
entity.rotation = Mathf.slerpDelta(entity.rotation, targetRot,
rotatespeed);
if(Angles.angleDist(entity.rotation, targetRot) < shootCone/* && entity.timer.get(timerReload, reload)*/){
style.shoot(this, entity);
if(Angles.angleDist(entity.rotation, targetRot) < shootCone){
updateShooting(tile);
}
}
}
}
/**Consume ammo and return a type.*/
public AmmoType useAmmo(Tile tile){
TurretEntity entity = tile.entity();
AmmoEntry entry = entity.ammo.peek();
entry.amount --;
if(entry.amount == 0) entity.ammo.pop();
entity.totalAmmo --;
return entry.type;
}
/**Get the ammo type that will be returned if useAmmo is called.*/
public AmmoType peekAmmo(Tile tile){
TurretEntity entity = tile.entity();
return entity.ammo.peek().type;
}
/**Returns whether the turret has ammo.*/
public boolean hasAmmo(Tile tile){
TurretEntity entity = tile.entity();
return entity.ammo > 0;
return entity.ammo.size > 0 && entity.ammo.peek().amount > 0;
}
public void consumeAmmo(Tile tile){
protected void updateShooting(Tile tile){
TurretEntity entity = tile.entity();
entity.ammo --;
}
void drawTargeting(Tile tile){
TurretEntity entity = tile.entity();
if(entity.target == null) return;
float dst = entity.distanceTo(entity.target);
float hittime = dst / bullet.speed;
float angle = Angles.predictAngle(tile.worldx(), tile.worldy(),
entity.target.x, entity.target.y, entity.target.velocity.x, entity.target.velocity.y, bullet.speed);
float predictX = entity.target.x + entity.target.velocity.x * hittime,
predictY = entity.target.y + entity.target.velocity.y * hittime;
Draw.color(Color.GREEN);
Lines.line(tile.worldx(), tile.worldy(), entity.target.x, entity.target.y);
Draw.color(Color.RED);
Lines.line(tile.worldx(), tile.worldy(), entity.target.x + entity.target.velocity.x * hittime,
entity.target.y + entity.target.velocity.y * hittime);
Draw.color(Color.PURPLE);
Lines.stroke(2f);
Lines.lineAngle(tile.worldx(), tile.worldy(), angle, 7f);
Draw.reset();
if(Timers.getTime(tile, "reload") <= 0){
Timers.run(hittime, () -> Effects.effect(Fx.spawn, predictX, predictY));
if(entity.reload >= reload) {
AmmoType type = useAmmo(tile);
shoot(tile, type);
entity.reload = 0f;
}else{
entity.reload += Timers.delta() * peekAmmo(tile).speedMultiplier;
}
}
protected void shoot(Tile tile){
protected void shoot(Tile tile, AmmoType ammo){
TurretEntity entity = tile.entity();
tr.trns(entity.rotation, size * tilesize/2);
for(int i = 0; i < shots; i ++){
if(Mathf.zero(shotDelayScale)){
entity.recoil = recoil;
bullet(tile, entity.rotation + Mathf.range(inaccuracy));
}else{
Timers.run(i * shotDelayScale, () -> {
tr.trns(entity.rotation, size * tilesize/2f);
bullet(tile, entity.rotation + Mathf.range(inaccuracy));
});
}
tr.trns(entity.rotation, size * tilesize / 2);
for (int i = 0; i < shots; i++) {
bullet(tile, ammo.bullet, entity.rotation + Mathf.range(inaccuracy));
}
Effects.effect(shootEffect, tile.drawx() + tr.x,
tile.drawy() + tr.y, entity.rotation);
if(shootShake > 0){
tile.drawy() + tr.y, entity.rotation);
if (shootShake > 0) {
Effects.shake(shootShake, shootShake, tile.entity);
}
}
protected void bullet(Tile tile, float angle){
new Bullet(bullet, tile.entity, tile.getTeam(), tile.drawx() + tr.x, tile.drawy() + tr.y, angle).add();
protected void bullet(Tile tile, BulletType type, float angle){
new Bullet(type, tile.entity, tile.getTeam(), tile.drawx() + tr.x, tile.drawy() + tr.y, angle).add();
}
@Override
@ -234,46 +260,43 @@ public class Turret extends Block{
return new TurretEntity();
}
public enum ShootStyle{
normal{
void shoot(Turret turret, TurretEntity entity){
if(entity.timer.get(turret.timerReload, turret.reload)){
if(turret.shootsound != null && entity.timer.get(turret.timerSound, turret.soundReload))
Effects.sound(turret.shootsound, entity);
turret.consumeAmmo(entity.tile);
entity.ammo --;
public static class AmmoEntry{
public final AmmoType type;
public int amount;
turret.tr.trns(entity.rotation, turret.size * tilesize/2);
turret.bullet(entity.tile, entity.rotation + Mathf.range(turret.inaccuracy));
Effects.effect(turret.shootEffect, entity.tile.drawx() + turret.tr.x,
entity.tile.drawy() + turret.tr.y, entity.rotation);
if(turret.shootShake > 0){
Effects.shake(turret.shootShake, turret.shootShake, entity.tile.entity);
}
}
}
};
abstract void shoot(Turret turret, TurretEntity entity);
}
public AmmoEntry(AmmoType type, int amount) {
this.type = type;
this.amount = amount;
}
}
public static class TurretEntity extends TileEntity{
public TileEntity blockTarget;
public int ammo;
public Array<AmmoEntry> ammo = new Array<>();
public int totalAmmo;
public float reload;
public float rotation = 90;
public float recoil = 0f;
public Unit target;
@Override
public void write(DataOutputStream stream) throws IOException{
stream.writeInt(ammo);
stream.writeByte(ammo.size);
for(AmmoEntry entry : ammo){
stream.writeByte(entry.type.id);
stream.writeShort(entry.amount);
}
}
@Override
public void read(DataInputStream stream) throws IOException{
this.ammo = stream.readInt();
byte amount = stream.readByte();
for(int i = 0; i < amount; i ++){
AmmoType type = AmmoType.getByID(stream.readByte());
short ta = stream.readShort();
ammo.add(new AmmoEntry(type, ta));
totalAmmo += ta;
}
}
}
}

View File

@ -0,0 +1,43 @@
package io.anuke.mindustry.world.blocks.types.defense.turrets;
import io.anuke.mindustry.graphics.fx.BulletFx;
import io.anuke.mindustry.resource.AmmoType;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.defense.Turret;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.util.Mathf;
import static io.anuke.mindustry.Vars.tilesize;
public class DoubleTurret extends Turret {
protected float shotWidth = 2f;
public DoubleTurret(String name) {
super(name);
shots = 2;
}
@Override
protected void shoot(Tile tile, AmmoType ammo){
TurretEntity entity = tile.entity();
entity.recoil = recoil;
for (int i : Mathf.signs) {
for(int j = 0; j < 3; j ++){
tr.trns(entity.rotation - 90, shotWidth * i, size * tilesize / 2 + j);
Effects.effect(BulletFx.smokeParticleSmall, tile.drawx() + tr.x + Mathf.range(1f), tile.drawy() + tr.y + Mathf.range(1f));
}
tr.trns(entity.rotation - 90, shotWidth * i, size * tilesize / 2);
bullet(tile, ammo.bullet, entity.rotation + Mathf.range(inaccuracy));
Effects.effect(shootEffect, tile.drawx() + tr.x,
tile.drawy() + tr.y, entity.rotation);
}
if (shootShake > 0) {
Effects.shake(shootShake, shootShake, tile.entity);
}
}
}

View File

@ -1,10 +1,13 @@
package io.anuke.mindustry.world.blocks.types.defense;
package io.anuke.mindustry.world.blocks.types.defense.turrets;
import io.anuke.mindustry.content.Liquids;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.Liquid;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.defense.Turret;
public abstract class LiquidTurret extends Turret{
//TODO
public abstract class LiquidTurret extends Turret {
public Liquid ammoLiquid = Liquids.water;
public float liquidCapacity = 60f;
public float liquidPerShot = 1f;
@ -15,16 +18,21 @@ public abstract class LiquidTurret extends Turret{
}
@Override
public boolean hasAmmo(Tile tile){
TurretEntity entity = tile.entity();
return entity.liquid.amount > liquidPerShot;
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){

View File

@ -1,15 +1,15 @@
package io.anuke.mindustry.world.blocks.types.defense;
package io.anuke.mindustry.world.blocks.types.defense.turrets;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.AmmoType;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.defense.Turret;
import io.anuke.ucore.util.Strings;
public abstract class PowerTurret extends Turret{
public abstract class PowerTurret extends Turret {
public float powerUsed = 0.5f;
public PowerTurret(String name) {
super(name);
ammo = null;
hasPower = true;
}
@ -21,16 +21,12 @@ public abstract class PowerTurret extends Turret{
@Override
public boolean hasAmmo(Tile tile){
return tile.entity.power.amount >= powerUsed;
return tile.entity.power.amount >= powerUsed && super.hasAmmo(tile);
}
@Override
public void consumeAmmo(Tile tile){
public AmmoType useAmmo(Tile tile){
tile.entity.power.amount -= powerUsed;
}
@Override
public boolean acceptItem(Item item, Tile tile, Tile source){
return false;
return super.useAmmo(tile);
}
}

View File

@ -3,7 +3,6 @@ package io.anuke.mindustry.world.blocks.types.power;
import com.badlogic.gdx.math.GridPoint2;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.graphics.fx.BlockFx;
import io.anuke.mindustry.graphics.fx.BulletFx;
import io.anuke.mindustry.graphics.fx.ExplosionFx;
import io.anuke.mindustry.world.Edges;
import io.anuke.mindustry.world.Tile;
@ -63,7 +62,6 @@ public class PowerGenerator extends PowerBlock {
public void onDestroyed(Tile tile){
float x = tile.worldx(), y = tile.worldy();
Effects.effect(BulletFx.shellsmoke, x, y);
Effects.effect(BlockFx.blastsmoke, x, y);
Timers.run(Mathf.random(8f + Mathf.random(6f)), () -> {