Added sandbox mode and new fortress enemy

This commit is contained in:
Anuken 2017-11-26 22:40:43 -05:00
parent 07ac552495
commit d9a66278ff
25 changed files with 510 additions and 286 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 451 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 447 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 470 B

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 50 KiB

View File

@ -31,6 +31,7 @@ public class Mindustry extends ModuleCore {
}
};
//always initialize blocks in this order, otherwise there are ID errors
public Block[] blockClasses = {
Blocks.air,

View File

@ -82,7 +82,7 @@ public class Pathfind{
for(SpawnPoint point : Vars.control.getSpawnPoints()){
if(!point.request.pathFound){
if(point.finder.search(point.request, ms*2)){
if(point.finder.search(point.request, ms)){
smoother.smoothPath(point.path);
point.pathTiles = point.path.nodes.toArray(Tile.class);
}

View File

@ -36,7 +36,7 @@ import io.anuke.ucore.util.Profiler;
public class Control extends Module{
int targetscale = baseCameraScale;
public Tutorial tutorial = new Tutorial();
Tutorial tutorial = new Tutorial();
boolean hiscore = false;
final Array<Weapon> weapons = new Array<>();
@ -51,6 +51,7 @@ public class Control extends Module{
float wavetime;
float extrawavetime;
int enemies = 0;
GameMode mode = GameMode.waves;
Tile core;
Array<SpawnPoint> spawnpoints = new Array<>();
@ -162,7 +163,7 @@ public class Control extends Module{
public void reset(){
weapons.clear();
Vars.renderer.clearTiles();
renderer.clearTiles();
weapons.add(Weapon.blaster);
player.weapon = weapons.first();
@ -187,7 +188,7 @@ public class Control extends Module{
}
public void play(){
Vars.renderer.clearTiles();
renderer.clearTiles();
player.x = core.worldx();
player.y = core.worldy() - Vars.tilesize*2 - ((int)(Gdx.graphics.getWidth() / (float)Core.cameraScale * 2) % 2 == 0 ? 0.5f : 0);
@ -232,6 +233,14 @@ public class Control extends Module{
});
}
public GameMode getMode(){
return mode;
}
public void setMode(GameMode mode){
this.mode = mode;
}
public boolean hasWeapon(Weapon weapon){
return weapons.contains(weapon, true);
}
@ -443,7 +452,7 @@ public class Control extends Module{
if(Inputs.keyDown(Keys.SHIFT_LEFT)){
new HealerEnemy(0).set(player.x, player.y).add();
}else{
new TitanEnemy(0).set(player.x, player.y).add();
new FortressEnemy(0).set(player.x, player.y).add();
}
}
}
@ -479,17 +488,19 @@ public class Control extends Module{
}
}
if(!tutorial.active()){
if(tutorial.active()){
tutorial.update();
}
if(!tutorial.active() && mode != GameMode.sandbox){
extrawavetime -= delta();
if(enemies <= 0){
wavetime -= delta();
}
}else{
tutorial.update();
}
if(wavetime <= 0 || (debug && Inputs.keyUp(Keys.F)) || extrawavetime <= 0){
if(wavetime <= 0){
runWave();
}

View File

@ -20,6 +20,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
static Color lightRed = Hue.mix(Color.WHITE, Color.FIREBRICK, 0.1f);
static Color lightOrange = Color.valueOf("f68021");
static Color whiteOrange = Hue.mix(lightOrange, Color.WHITE, 0.6f);
static Color whiteYellow = Hue.mix(Color.YELLOW, Color.WHITE, 0.6f);
public static final BulletType
@ -128,7 +129,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
Effects.effect(Fx.shellsmoke, b);
Effects.effect(Fx.shellexplosion, b);
DamageArea.damage(b.owner instanceof Enemy, b.x, b.y, 25f, (int)(damage * 2f/3f));
DamageArea.damage(!(b.owner instanceof Enemy), b.x, b.y, 25f, (int)(damage * 2f/3f));
}
},
titanshell = new BulletType(1.8f, 60){
@ -162,6 +163,37 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
DamageArea.damage(!(b.owner instanceof Enemy), b.x, b.y, 25f, (int)(damage * 2f/3f));
}
},
yellowshell = new BulletType(1.2f, 20){
{
lifetime = 60f;
hitsize = 11f;
}
public void draw(Bullet b){
Draw.color(whiteYellow);
Draw.rect("titanshell", b.x, b.y, b.angle());
Draw.reset();
}
public void update(Bullet b){
if(Timers.get(b, "smoke", 4)){
Effects.effect(Fx.smoke, b.x + Mathf.range(2), b.y + Mathf.range(2));
}
}
public void despawned(Bullet b){
removed(b);
}
public void removed(Bullet b){
Effects.shake(3f, 3f, b);
Effects.effect(Fx.shellsmoke, b);
Effects.effect(Fx.shockwaveSmall, b);
DamageArea.damage(!(b.owner instanceof Enemy), b.x, b.y, 25f, (int)(damage * 2f/3f));
}
},
blast = new BulletType(1.1f, 80){
{
lifetime = 0f;

View File

@ -14,7 +14,7 @@ public class DamageArea{
public static void damage(boolean enemies, float x, float y, float radius, int damage){
if(enemies){
Entities.getNearby(x, y, radius*2, entity->{
Entities.getNearby(Entities.getGroup(Enemy.class), x, y, radius*2, entity->{
if(entity instanceof Enemy){
Enemy enemy = (Enemy)entity;
if(enemy.distanceTo(x, y) > radius){

View File

@ -13,6 +13,7 @@ public class Fx{
static Color lightRed = Hue.mix(Color.WHITE, Color.FIREBRICK, 0.1f);
static Color lightOrange = Color.valueOf("f68021");
static Color whiteOrange = Hue.mix(lightOrange, Color.WHITE, 0.6f);
static Color whiteYellow = Hue.mix(Color.YELLOW, Color.WHITE, 0.6f);
public static final Effect
@ -34,6 +35,28 @@ public class Fx{
Draw.reset();
}),
mortarshot = new Effect(10f, e -> {
Draw.color(Color.WHITE, Color.DARK_GRAY, e.ifract());
Draw.thick(e.fract()*6f);
Draw.lineAngle(e.x, e.y, e.rotation, e.fract()*10f);
Draw.thick(e.fract()*5f);
Draw.lineAngle(e.x, e.y, e.rotation, e.fract()*14f);
Draw.thick(e.fract()*1f);
Draw.lineAngle(e.x, e.y, e.rotation, e.fract()*16f);
Draw.reset();
}),
railshot = new Effect(9f, e -> {
Draw.color(Color.WHITE, Color.DARK_GRAY, e.ifract());
Draw.thick(e.fract()*5f);
Draw.lineAngle(e.x, e.y, e.rotation, e.fract()*8f);
Draw.thick(e.fract()*4f);
Draw.lineAngle(e.x, e.y, e.rotation, e.fract()*12f);
Draw.thick(e.fract()*1f);
Draw.lineAngle(e.x, e.y, e.rotation, e.fract()*14f);
Draw.reset();
}),
titanshot = new Effect(12f, e -> {
Draw.color(Color.WHITE, lightOrange, e.ifract());
Draw.thick(e.fract()*7f);
@ -45,6 +68,17 @@ public class Fx{
Draw.reset();
}),
largeCannonShot = new Effect(11f, e -> {
Draw.color(Color.WHITE, whiteYellow, e.ifract());
Draw.thick(e.fract()*6f);
Draw.lineAngle(e.x, e.y, e.rotation, e.fract()*12f);
Draw.thick(e.fract()*3f);
Draw.lineAngle(e.x, e.y, e.rotation, e.fract()*16f);
Draw.thick(e.fract()*1f);
Draw.lineAngle(e.x, e.y, e.rotation, e.fract()*18f);
Draw.reset();
}),
shockwave = new Effect(10f, e -> {
Draw.color(Color.WHITE, Color.LIGHT_GRAY, e.ifract());
Draw.thick(e.fract()*2f + 0.2f);

View File

@ -11,8 +11,10 @@ import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.effect.Fx;
import io.anuke.mindustry.entities.effect.Shaders;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.UCore;
import io.anuke.ucore.core.*;
import io.anuke.ucore.entities.*;
import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Tmp;
@ -24,18 +26,21 @@ public class Enemy extends DestructibleEntity{
protected float reload = 32;
protected float range = 60;
protected float length = 4;
protected float rotatespeed = 7f;
protected float rotatespeed = 0.1f;
protected float turretrotatespeed = 0.2f;
protected boolean alwaysRotate = false;
protected BulletType bullet = BulletType.small;
protected String shootsound = "enemyshoot";
protected int damage;
protected Enemy spawner;
protected int spawned = 0;
protected float angle;
protected boolean targetCore = false;
public int spawn;
public int node = -1;
public Tile[] path;
public Vector2 direction = new Vector2();
public float xvelocity, yvelocity;
public Entity target;
public int tier = 1;
@ -63,7 +68,7 @@ public class Enemy extends DestructibleEntity{
if(nearCore){
vec = Tmp.v2.setZero();
target = core.entity;
if(targetCore) target = core.entity;
}else{
vec = Vars.world.pathfinder().find(this);
vec.sub(x, y).setLength(speed);
@ -94,7 +99,6 @@ public class Enemy extends DestructibleEntity{
move(vec.x * Timers.delta(), vec.y * Timers.delta());
updateTargeting(nearCore);
}
@ -107,6 +111,10 @@ public class Enemy extends DestructibleEntity{
target = Entities.getClosest(Entities.defaultGroup(), x, y, range, e -> e instanceof Player);
}
}
if(target instanceof Enemy){
UCore.log(target);
}
if(target != null && bullet != null){
updateShooting();
@ -125,8 +133,8 @@ public class Enemy extends DestructibleEntity{
}
void shoot(BulletType bullet, float rotation){
vector.set(length, 0).rotate(direction.angle() + rotation);
Bullet out = new Bullet(bullet, this, x + vector.x, y + vector.y, direction.angle() + rotation).add();
Angles.translation(angle + rotation, length);
Bullet out = new Bullet(bullet, this, x + Angles.x(), y + Angles.y(), this.angle + rotation).add();
out.damage = (int) (damage * Vars.multiplier);
}
@ -195,6 +203,9 @@ public class Enemy extends DestructibleEntity{
public void removed(){
if(!dead){
Vars.control.enemyDeath();
if(spawner != null){
spawner.spawned --;
}
}
}
@ -208,11 +219,9 @@ public class Enemy extends DestructibleEntity{
yvelocity = (y - lasty) / Timers.delta();
if(target == null || alwaysRotate){
direction.add(xvelocity * Timers.delta() / 3f, yvelocity * Timers.delta() / 3f);
direction.limit(speed * rotatespeed);
angle = Mathf.slerp(angle, 180f+Mathf.atan2(xvelocity, yvelocity), rotatespeed * Timers.delta());
}else{
float angle = angleTo(target);
direction.lerp(vector.set(1f, 0f).rotate(angle), turretrotatespeed * Timers.delta());
angle = Mathf.slerp(angle, angleTo(target), turretrotatespeed * Timers.delta());
}
}
@ -226,7 +235,7 @@ public class Enemy extends DestructibleEntity{
Shaders.outline.apply();
Draw.color();
Draw.rect(region, x, y, direction.angle() - 90);
Draw.rect(region, x, y, this.angle - 90);
Graphics.flush();

View File

@ -0,0 +1,62 @@
package io.anuke.mindustry.entities.enemies;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.entities.BulletType;
import io.anuke.mindustry.entities.effect.Fx;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.util.Angles;
public class FortressEnemy extends Enemy{
static int maxSpawn = 6;
float spawnTime = 240;
boolean deployed;
public FortressEnemy(int spawn) {
super(spawn);
speed = 0.1f;
reload = 90;
maxhealth = 700;
range = 70f;
bullet = BulletType.yellowshell;
hitbox.setSize(9f);
turretrotatespeed = rotatespeed = 0.08f;
length = 7f;
heal();
}
@Override
public void move(){
super.move();
if(deployed){
if(Timers.get(this, "spawn", spawnTime) && spawned < maxSpawn){
Angles.translation(angle, 20f);
FastEnemy enemy = new FastEnemy(spawn);
enemy.tier = this.tier;
enemy.spawner = this;
enemy.set(x + Angles.x(), y + Angles.y());
Effects.effect(Fx.spawn, enemy);
enemy.add();
spawned ++;
}
}else if(distanceTo(Vars.control.getCore().worldx(),
Vars.control.getCore().worldy()) <= 120f){
deployed = true;
speed = 0.001f;
}
}
@Override
public void shoot(BulletType type){
super.shoot(bullet);
Effects.effect(Fx.largeCannonShot, x + Angles.x(), y + Angles.y(), angle);
Effects.shake(3f, 3f, this);
}
}

View File

@ -23,6 +23,7 @@ public class HealerEnemy extends Enemy{
bullet = BulletType.shot;
range = 30f;
alwaysRotate = false;
targetCore = false;
heal();
}

View File

@ -18,9 +18,9 @@ public class TankEnemy extends Enemy{
}
void shoot(){
vector.set(length, 0).rotate(direction.angle());
Angles.translation(angle, 8f);
Angles.shotgun(3, 8f, direction.angle(), f->{
Angles.shotgun(3, 8f, angle, f->{
Bullet out = new Bullet(bullet, this, x+vector.x, y+vector.y, f).add();
out.damage = (int)(damage*Vars.multiplier);
});

View File

@ -19,9 +19,7 @@ import io.anuke.mindustry.Vars;
import io.anuke.mindustry.entities.enemies.*;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.Weapon;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Map;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.*;
import io.anuke.mindustry.world.blocks.Blocks;
import io.anuke.ucore.core.Core;
import io.anuke.ucore.entities.Entities;
@ -38,6 +36,8 @@ import io.anuke.ucore.entities.Entities;
* Wave (int)
* Wave countdown time (float)
*
* Gamemode Ordinal (byte)
*
* Player X (float)
* Player Y (float)
* Player health (int)
@ -82,7 +82,7 @@ import io.anuke.ucore.entities.Entities;
*/
public class SaveIO{
/**Save file version ID. Should be incremented every breaking release.*/
private static final int fileVersionID = 9;
private static final int fileVersionID = 10;
//TODO automatic registration of types?
private static final Array<Class<? extends Enemy>> enemyIDs = Array.with(
@ -135,9 +135,21 @@ public class SaveIO{
public static int getWave(int slot){
try(DataInputStream stream = new DataInputStream(fileFor(slot).read())){
stream.readInt();
stream.readLong();
return stream.readInt();
stream.readInt(); //read version
stream.readLong(); //read last saved time
stream.readByte(); //read the gamemode
return stream.readInt(); //read the wave
}catch (IOException e){
throw new RuntimeException(e);
}
}
public static GameMode getMode(int slot){
try(DataInputStream stream = new DataInputStream(fileFor(slot).read())){
stream.readInt(); //read version
stream.readLong(); //read last saved time
return GameMode.values()[stream.readByte()]; //read the gamemode
}catch (IOException e){
throw new RuntimeException(e);
}
@ -151,10 +163,13 @@ public class SaveIO{
try(DataOutputStream stream = new DataOutputStream(file.write(false))){
//--META--
stream.writeInt(fileVersionID); //version id
stream.writeLong(TimeUtils.millis());
stream.writeLong(TimeUtils.millis()); //last saved
//--GENERAL STATE--
stream.writeByte(Vars.control.getMode().ordinal()); //gamemode
stream.writeInt(Vars.control.getWave()); //wave
stream.writeFloat(Vars.control.getWaveCountdown()); //wave countdown
@ -270,6 +285,7 @@ public class SaveIO{
}
//general state
byte mode = stream.readByte();
int wave = stream.readInt();
float wavetime = stream.readFloat();
@ -282,6 +298,7 @@ public class SaveIO{
Vars.player.x = playerx;
Vars.player.y = playery;
Vars.player.health = playerhealth;
Vars.control.setMode(GameMode.values()[mode]);
Core.camera.position.set(playerx, playery, 0);
//weapons

View File

@ -3,15 +3,16 @@ package io.anuke.mindustry.ui;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.world.GameMode;
import io.anuke.mindustry.world.Map;
import io.anuke.ucore.core.Core;
import io.anuke.ucore.core.Settings;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.function.StringSupplier;
import io.anuke.ucore.scene.ui.ImageButton;
import io.anuke.ucore.scene.ui.ScrollPane;
import io.anuke.ucore.scene.ui.*;
import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.scene.ui.layout.Unit;
import io.anuke.ucore.scene.utils.Elements;
public class LevelDialog extends FloatingDialog{
private Map selectedMap = Map.delta;
@ -31,6 +32,21 @@ public class LevelDialog extends FloatingDialog{
int maxwidth = 4;
Table selmode = new Table();
ButtonGroup<TextButton> group = new ButtonGroup<>();
selmode.add("Gamemode: ").padRight(10f).units(Unit.dp);
for(GameMode mode : GameMode.values()){
TextButton b = Elements.newButton(mode.toString(), "toggle", ()->{
Vars.control.setMode(mode);
});
group.add(b);
selmode.add(b).size(130f, 54f).units(Unit.dp);
}
content().add(selmode);
content().row();
for(int i = 0; i < Map.values().length; i ++){
Map map = Map.values()[i];
@ -61,7 +77,7 @@ public class LevelDialog extends FloatingDialog{
maps.add(image).width(170).pad(4f).units(Unit.dp);
}
content().add(pane);
content().add(pane).uniformX();
shown(()->{
//this is necessary for some reason?

View File

@ -46,8 +46,8 @@ public class LoadDialog extends FloatingDialog{
button.row();
Label info = new Label("[gray]" + (!SaveIO.isSaveValid(i) ? "<empty>" : "Wave " +
SaveIO.getWave(slot)+"\nLast Saved: " + SaveIO.getTimeString(i)));
Label info = new Label("[gray]" + (!SaveIO.isSaveValid(i) ? "<empty>" : SaveIO.getMode(slot) + ", Wave " +
SaveIO.getWave(slot) + "\nLast Saved: " + SaveIO.getTimeString(i)));
info.setAlignment(Align.center, Align.center);
button.add(info).padBottom(2).padTop(6);

View File

@ -100,7 +100,7 @@ public class BlocksFragment implements Fragment{
image.update(()->{
boolean canPlace = !control.tutorial.active() || control.tutorial.canPlace();
boolean canPlace = !control.getTutorial().active() || control.getTutorial().canPlace();
boolean has = control.hasItems(r.requirements) && canPlace;
//image.setDisabled(!has);
image.setChecked(player.recipe == r);

View File

@ -12,6 +12,7 @@ import io.anuke.mindustry.core.GameState;
import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.enemies.Enemy;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.world.GameMode;
import io.anuke.ucore.core.Core;
import io.anuke.ucore.core.Draw;
import io.anuke.ucore.core.Settings;
@ -73,9 +74,9 @@ public class HudFragment implements Fragment{
//ui table
new table(){{
control.tutorial.buildUI(this);
control.getTutorial().buildUI(this);
visible(()->control.tutorial.active());
visible(()->control.getTutorial().active());
}}.end();
//paused table
@ -92,6 +93,13 @@ public class HudFragment implements Fragment{
new table(){{
atop();
aright();
float uheight = 72f;
new imagebutton("icon-play", Unit.dp.inPixels(30f), ()->{
Vars.control.runWave();
}).size(uheight).uniformY().units(Unit.dp)
.visible(()-> Vars.control.getMode() == GameMode.sandbox && Vars.control.getEnemiesRemaining() <= 0);
new table("button"){{
@ -101,11 +109,11 @@ public class HudFragment implements Fragment{
new label(()-> control.getEnemiesRemaining() > 0 ?
control.getEnemiesRemaining() + " Enemies remaining" :
control.tutorial.active() ? "waiting..." : "New wave in " + (int) (control.getWaveCountdown() / 60f))
(control.getTutorial().active() || Vars.control.getMode() == GameMode.sandbox) ? "waiting..." : "New wave in " + (int) (control.getWaveCountdown() / 60f))
.minWidth(150);
get().pad(Unit.dp.inPixels(12));
}};
}}.height(uheight).units(Unit.dp);
visible(()->!GameState.is(State.menu));
}}.end();

View File

@ -0,0 +1,5 @@
package io.anuke.mindustry.world;
public enum GameMode{
waves, sandbox;
}

View File

@ -103,6 +103,7 @@ public class WeaponBlocks{
bullet = BulletType.sniper;
ammo = Item.steel;
health = 70;
shootEffect = Fx.railshot;
fullDescription = "Advanced long-range turret. Uses steel for ammo. Very high damage, but low fire rate. "
+ "Expensive to use, but can be placed far away from enemy lines due to its range.";
}
@ -121,6 +122,8 @@ public class WeaponBlocks{
fullDescription = "Advanced splash-damage turret. Uses coal for ammo. "
+ "Very slow fire rate and bullets, but very high single-target and splash damage. "
+ "Useful for large crowds of enemies.";
shootEffect = Fx.mortarshot;
shootShake = 2f;
}
},
@ -189,6 +192,7 @@ public class WeaponBlocks{
shots = 2;
fullDescription = "The ultimate rapid-fire turret. Uses uranium as ammo. Shoots large slugs at a high fire rate. "
+ "Medium range. Spans multiple tiles. Extremely tough.";
shootEffect = Fx.chainshot;
}
//TODO specify turret shoot effect in turret instead of doing it manually
@ -203,7 +207,7 @@ public class WeaponBlocks{
for(int i = -1; i < 1; i ++){
Angles.vector.set(len, Mathf.sign(i) * space).rotate(entity.rotation);
bullet(tile, entity.rotation);
Effects.effect(Fx.chainshot, tile.worldx() + Angles.x() + offset.x,
Effects.effect(shootEffect, tile.worldx() + Angles.x() + offset.x,
tile.worldy()+ Angles.y() + offset.y, entity.rotation);
}
@ -225,19 +229,8 @@ public class WeaponBlocks{
shootCone = 9f;
fullDescription = "The ultimate long-range turret. Uses uranium as ammo. Shoots large splash-damage shells at a medium rate of fire. "
+ "Long range. Spans multiple tiles. Extremely tough.";
}
@Override
protected void shoot(Tile tile){
TurretEntity entity = tile.entity();
Vector2 offset = getPlaceOffset();
Angles.translation(entity.rotation, 14f);
bullet(tile, entity.rotation);
Effects.effect(Fx.titanshot, tile.worldx() + Angles.x() + offset.x,
tile.worldy()+ Angles.y() + offset.y, entity.rotation);
Effects.shake(3f, 3f, tile.worldx(), tile.worldy());
shootEffect = Fx.titanshot;
shootShake = 3f;
}
};
}

View File

@ -19,6 +19,7 @@ import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Draw;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.Entities;
import io.anuke.ucore.util.Angles;
@ -41,6 +42,8 @@ public class Turret extends Block{
protected int maxammo = 400;
protected float rotatespeed = 0.2f;
protected float shootCone = 5f;
protected Effect shootEffect = null;
protected float shootShake = 0f;
public Turret(String name) {
super(name);
@ -216,6 +219,8 @@ public class Turret extends Block{
protected void shoot(Tile tile){
TurretEntity entity = tile.entity();
Vector2 offset = getPlaceOffset();
Angles.translation(entity.rotation, width * Vars.tilesize / 2f);
for(int i = 0; i < shots; i ++){
@ -228,12 +233,21 @@ public class Turret extends Block{
}
}
if(shootEffect != null){
Effects.effect(shootEffect, tile.worldx() + Angles.x() + offset.x,
tile.worldy()+ Angles.y() + offset.y, entity.rotation);
}
if(shootShake > 0){
Effects.shake(shootShake, shootShake, tile.entity);
}
}
protected void bullet(Tile tile, float angle){
Vector2 offset = getPlaceOffset();
Bullet out = new Bullet(bullet, tile.entity, tile.worldx() + Angles.x() + offset.x, tile.worldy() + Angles.y() + offset.y, angle).add();
out.damage = (int)(bullet.damage*Vars.multiplier);
Bullet out = new Bullet(bullet, tile.entity, tile.worldx() + Angles.x() + offset.x, tile.worldy() + Angles.y() + offset.y, angle).add();
out.damage = (int)(bullet.damage*Vars.multiplier);
}
public static class TurretEntity extends TileEntity{

Binary file not shown.

Binary file not shown.