Fixed compile errors, unitification

This commit is contained in:
Anuken 2018-03-15 21:42:23 -04:00
parent 807c4688c2
commit 52c0a8e573
35 changed files with 392 additions and 347 deletions

View File

@ -0,0 +1,18 @@
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif
uniform sampler2D u_texture;
varying vec4 v_color;
varying vec2 v_texCoord;
void main() {
vec4 c = texture2D(u_texture, v_texCoord.xy);
c = mix(c, vec4(1.0, 1.0, 1.0, c.a), v_color.a);
gl_FragColor = c * vec4(v_color.rgb, 1.0);
}

View File

@ -35,9 +35,6 @@ void main() {
if(any){
gl_FragColor = u_color;
}else{
if((c.r < 0.01 && c.g < 0.01 && c.b < 0.01)){
c = vec4(0.0);
}
gl_FragColor = mix(c, vec4(1.0, 1.0, 1.0, c.a), c.a) * v_color;
gl_FragColor = c * v_color;
}
}

View File

@ -1,7 +1,7 @@
#Autogenerated file. Do not modify.
#Thu Mar 15 12:56:43 EDT 2018
#Thu Mar 15 21:41:26 EDT 2018
version=release
androidBuildCode=523
androidBuildCode=524
name=Mindustry
code=3.4
build=custom build

View File

@ -158,6 +158,7 @@ public class Control extends Module{
Events.on(ResetEvent.class, () -> {
upgrades.reset();
player.weaponLeft = player.weaponRight = Weapon.blaster;
player.team = state.team;
player.add();
player.heal();

View File

@ -1,9 +1,11 @@
package io.anuke.mindustry.core;
import com.badlogic.gdx.utils.ObjectSet;
import io.anuke.mindustry.game.Difficulty;
import io.anuke.mindustry.game.EventType.StateChangeEvent;
import io.anuke.mindustry.game.GameMode;
import io.anuke.mindustry.game.Inventory;
import io.anuke.mindustry.game.Team;
import io.anuke.ucore.core.Events;
public class GameState{
@ -20,6 +22,9 @@ public class GameState{
public GameMode mode = GameMode.waves;
public Difficulty difficulty = Difficulty.normal;
public boolean friendlyFire;
public Team team = Team.none; //the team that the player is on
public ObjectSet<Team> enemyTeams = new ObjectSet<>(), //enemies to the player team
allyTeams = new ObjectSet<>(); //allies to the player team
public void set(State astate){
Events.fire(StateChangeEvent.class, state, astate);

View File

@ -7,6 +7,7 @@ import io.anuke.mindustry.game.EventType.GameOverEvent;
import io.anuke.mindustry.game.EventType.PlayEvent;
import io.anuke.mindustry.game.EventType.ResetEvent;
import io.anuke.mindustry.game.EventType.WaveEvent;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.game.WaveCreator;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.NetEvents;
@ -53,6 +54,10 @@ public class Logic extends Module {
state.lastUpdated = -1;
state.gameOver = false;
state.inventory.clearItems();
state.allyTeams.clear();
state.enemyTeams.clear();
state.enemyTeams.add(Team.red);
state.team = Team.none;
Timers.clear();
Entities.clear();

View File

@ -4,7 +4,6 @@ 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.Bullet;
import io.anuke.mindustry.entities.BulletType;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.SyncEntity;
@ -22,7 +21,6 @@ import io.anuke.mindustry.world.blocks.ProductionBlocks;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.BaseBulletType;
import io.anuke.ucore.entities.Entities;
import io.anuke.ucore.entities.Entity;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.modules.Module;
import io.anuke.ucore.util.Log;
@ -33,15 +31,20 @@ import java.nio.ByteBuffer;
import static io.anuke.mindustry.Vars.*;
public class NetClient extends Module {
private final static float dataTimeout = 60*18; //18 seconds timeout
private final static float dataTimeout = 60*18;
private final static float playerSyncTime = 2;
private Timer timer = new Timer(5);
/**Whether the client is currently conencting.*/
private boolean connecting = false;
private boolean kicked = false;
/**If true, no message will be shown on disconnect.*/
private boolean quiet = false;
/**List of all recieved entitity IDs, to prevent duplicates.*/
private IntSet recieved = new IntSet();
private IntMap<Entity> recent = new IntMap<>();
private float timeoutTime = 0f; //data timeout counter
/**List of recently recieved entities that have not been added to the queue yet.*/
private IntMap<SyncEntity> recent = new IntMap<>();
/**Counter for data timeout.*/
private float timeoutTime = 0f;
public NetClient(){
@ -53,7 +56,7 @@ public class NetClient extends Module {
recent.clear();
timeoutTime = 0f;
connecting = true;
kicked = false;
quiet = false;
ui.chatfrag.clearMessages();
ui.loadfrag.hide();
@ -78,7 +81,7 @@ public class NetClient extends Module {
});
Net.handleClient(Disconnect.class, packet -> {
if (kicked) return;
if (quiet) return;
Timers.runTask(3f, ui.loadfrag::hide);
@ -187,23 +190,29 @@ public class NetClient extends Module {
Log.info("Recieved entity {0}", packet.entity.id);
});
Net.handleClient(EnemyDeathPacket.class, packet -> {
BaseUnit enemy = enemyGroup.getByID(packet.id);
if (enemy != null){
enemy.type.onDeath(enemy, true);
}else if(recent.get(packet.id) != null){
recent.get(packet.id).remove();
}else{
Log.err("Got remove for null entity! {0}", packet.id);
}
Net.handleClient(EntityDeathPacket.class, packet -> {
EntityGroup group = Entities.getGroup(packet.group);
SyncEntity entity = (SyncEntity) group.getByID(packet.id);
recieved.add(packet.id);
if(entity != null) {
entity.onRemoteDeath();
}else{
if(recent.get(packet.id) != null){
recent.get(packet.id).onRemoteDeath();
}else{
Log.err("Got remove for null entity! {0} / group type {1}", packet.id, group.getType());
}
}
});
Net.handleClient(BulletPacket.class, packet -> {
//TODO shoot effects for enemies, clientside as well as serverside
BulletType type = (BulletType) BaseBulletType.getByID(packet.type);
Entity owner = enemyGroup.getByID(packet.owner);
new Bullet(type, owner, packet.x, packet.y, packet.angle).add();
Net.handleClient(EntityShootPacket.class, packet -> {
BulletType type = BaseBulletType.getByID(packet.bulletid);
EntityGroup group = Entities.getGroup(packet.groupid);
SyncEntity owner = (SyncEntity) group.getByID(packet.entityid);
owner.onRemoteShoot(type, packet.x, packet.y, packet.rotation, packet.data);
});
Net.handleClient(BlockDestroyPacket.class, packet -> {
@ -231,7 +240,7 @@ public class NetClient extends Module {
});
Net.handleClient(KickPacket.class, packet -> {
kicked = true;
quiet = true;
Net.disconnect();
state.set(State.menu);
if(!packet.reason.quiet) ui.showError("$text.server.kicked." + packet.reason.name());
@ -243,7 +252,7 @@ public class NetClient extends Module {
world.getCore().entity != null){
world.getCore().entity.onDeath(true);
}
kicked = true;
quiet = true;
ui.restart.show();
});
@ -279,7 +288,7 @@ public class NetClient extends Module {
if(timeoutTime > dataTimeout){
Log.err("Failed to load data!");
ui.loadfrag.hide();
kicked = true;
quiet = true;
ui.showError("$text.disconnect.data");
Net.disconnect();
timeoutTime = 0f;
@ -306,7 +315,7 @@ public class NetClient extends Module {
}
public void disconnectQuietly(){
kicked = true;
quiet = true;
Net.disconnect();
}

View File

@ -3,9 +3,11 @@ package io.anuke.mindustry.core;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.Net.SendMode;
import io.anuke.mindustry.net.Packets.*;
import io.anuke.mindustry.net.Packets.BlockConfigPacket;
import io.anuke.mindustry.net.Packets.BlockTapPacket;
import io.anuke.mindustry.net.Packets.ChatPacket;
import io.anuke.mindustry.net.Packets.WeaponSwitchPacket;
import io.anuke.mindustry.resource.Upgrade;
import io.anuke.mindustry.resource.Weapon;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.modules.Module;
@ -15,13 +17,6 @@ public class NetCommon extends Module {
public NetCommon(){
Net.handle(ShootPacket.class, (packet) -> {
Player player = playerGroup.getByID(packet.playerid);
Weapon weapon = (Weapon) Upgrade.getByID(packet.weaponid);
weapon.shoot(player, packet.x, packet.y, packet.rotation);
});
Net.handle(ChatPacket.class, (packet) -> {
ui.chatfrag.addMessage(packet.text, colorizeName(packet.id, packet.name));
});
@ -31,8 +26,8 @@ public class NetCommon extends Module {
if (player == null) return;
player.weaponLeft = (Weapon) Upgrade.getByID(packet.left);
player.weaponRight = (Weapon) Upgrade.getByID(packet.right);
player.weaponLeft = Upgrade.getByID(packet.left);
player.weaponRight = Upgrade.getByID(packet.right);
});
Net.handle(BlockTapPacket.class, (packet) -> {
@ -44,13 +39,6 @@ public class NetCommon extends Module {
Tile tile = world.tile(packet.position);
if (tile != null) tile.block().configure(tile, packet.data);
});
Net.handle(PlayerDeathPacket.class, (packet) -> {
Player player = playerGroup.getByID(packet.id);
if(player == null) return;
player.doRespawn();
});
}
public void sendMessage(String message){

View File

@ -2,6 +2,7 @@ package io.anuke.mindustry.core;
import com.badlogic.gdx.utils.*;
import io.anuke.mindustry.core.GameState.State;
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;
@ -17,6 +18,7 @@ import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Placement;
import io.anuke.ucore.core.Events;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.BaseBulletType;
import io.anuke.ucore.entities.Entities;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.modules.Module;
@ -157,8 +159,15 @@ public class NetServer extends Module{
//...don't do anything here as it's already handled by the packet itself
});
Net.handleServer(ShootPacket.class, (id, packet) -> {
packet.playerid = connections.get(id).id;
Net.handleServer(EntityShootPacket.class, (id, packet) -> {
Player player = connections.get(id);
BulletType type = BaseBulletType.getByID(packet.bulletid);
player.onRemoteShoot(type, packet.x, packet.y, packet.rotation, packet.data);
packet.entityid = player.id;
packet.groupid = (byte)player.getGroup().getID();
Net.sendExcept(id, packet, SendMode.udp);
});
@ -201,7 +210,7 @@ public class NetServer extends Module{
});
Net.handleServer(ChatPacket.class, (id, packet) -> {
if(!Timers.get("chatFlood" + id, 20)){
if(!Timers.get("chatFlood" + id, 30)){
ChatPacket warn = new ChatPacket();
warn.text = "[scarlet]You are sending messages too quickly.";
Net.sendTo(id, warn, SendMode.tcp);
@ -249,8 +258,9 @@ public class NetServer extends Module{
}
});
Net.handleServer(PlayerDeathPacket.class, (id, packet) -> {
Net.handleServer(EntityDeathPacket.class, (id, packet) -> {
packet.id = connections.get(id).id;
packet.group = (byte)connections.get(id).getGroup().getID();
Net.sendExcept(id, packet, SendMode.tcp);
});

View File

@ -217,7 +217,9 @@ public class Renderer extends RendererModule{
Shaders.outline.color.set(team.color);
Graphics.beginShaders(Shaders.outline);
//Graphics.shader(Shaders.hit);
drawTeam(team, flying);
//Graphics.shader();
Graphics.endShaders();
}
}

View File

@ -1,6 +1,7 @@
package io.anuke.mindustry.entities;
import io.anuke.mindustry.entities.units.BaseUnit;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.entities.BulletEntity;
import io.anuke.ucore.entities.Entity;
@ -39,6 +40,10 @@ public class Bullet extends BulletEntity{
public boolean collidesTiles(){
return owner instanceof BaseUnit;
}
public Team team(){
return ((Unit)owner).team;
}
@Override
public void update(){

View File

@ -3,12 +3,11 @@ package io.anuke.mindustry.entities;
import com.badlogic.gdx.graphics.Color;
import io.anuke.mindustry.entities.effect.DamageArea;
import io.anuke.mindustry.entities.effect.EMP;
import io.anuke.mindustry.entities.units.BaseUnit;
import io.anuke.mindustry.graphics.Fx;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.BaseBulletType;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf;
@ -122,7 +121,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
Effects.effect(Fx.shellsmoke, b);
Effects.effect(Fx.shellexplosion, b);
DamageArea.damage(!(b.owner instanceof BaseUnit), b.x, b.y, 25f, (int)(damage * 2f/3f));
DamageArea.damage(b.team(), b.x, b.y, 25f, (int)(damage * 2f/3f));
}
},
flak = new BulletType(2.9f, 8) {
@ -202,7 +201,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
Effects.effect(Fx.shellsmoke, b);
Effects.effect(Fx.shockwaveSmall, b);
DamageArea.damage(!(b.owner instanceof BaseUnit), b.x, b.y, 50f, (int)(damage * 2f/3f));
DamageArea.damage(b.team(), b.x, b.y, 50f, (int)(damage * 2f/3f));
}
},
yellowshell = new BulletType(1.2f, 20){
@ -233,7 +232,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
Effects.effect(Fx.shellsmoke, b);
Effects.effect(Fx.shockwaveSmall, b);
DamageArea.damage(!(b.owner instanceof BaseUnit), b.x, b.y, 25f, (int)(damage * 2f/3f));
DamageArea.damage(b.team(), b.x, b.y, 25f, (int)(damage * 2f/3f));
}
},
blast = new BulletType(1.1f, 90){
@ -371,7 +370,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
Effects.effect(Fx.clusterbomb, b);
DamageArea.damage(!(b.owner instanceof BaseUnit), b.x, b.y, 35f, damage);
DamageArea.damage(b.team(), b.x, b.y, 35f, damage);
}
},
vulcan = new BulletType(4.5f, 12) {
@ -450,7 +449,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
}
public void init(Bullet b) {
DamageArea.damageLine(b.owner, Fx.beamhit, b.x, b.y, b.angle(), length, damage);
DamageArea.damageLine(b.team(), Fx.beamhit, b.x, b.y, b.angle(), length, damage);
}
public void draw(Bullet b) {

View File

@ -57,6 +57,13 @@ public class Player extends Unit{
heal();
}
@Override
public void onRemoteShoot(BulletType type, float x, float y, float rotation, short data) {
//TODO shoot!
Weapon weapon = Upgrade.getByID((byte)data);
weapon.shoot(player, x, y, rotation);
}
@Override
public float getMass(){
return mech.mass;
@ -105,8 +112,8 @@ public class Player extends Unit{
ui.hudfrag.fadeRespawn(true);
}
/**called when a remote player death event is recieved*/
public void doRespawn(){
@Override
public void onRemoteDeath(){
dead = true;
Effects.effect(Fx.explosion, this);
Effects.shake(4f, 5f, this);
@ -136,7 +143,7 @@ public class Player extends Unit{
float ft = Mathf.sin(walktime, 6f, 2f);
Draw.alpha(hitTime / hitDuration);
//Draw.alpha(hitTime / hitDuration);
for(int i : Mathf.signs){
tr.trns(footRotation, ft * i);
@ -154,7 +161,7 @@ public class Player extends Unit{
Draw.rect(weapon.name + "-equip", x + tr.x, y + tr.y, w, 8, rotation - 90);
}
Draw.alpha(1f);
//Draw.alpha(1f);
x = px;
y = py;

View File

@ -14,15 +14,24 @@ import static io.anuke.mindustry.Vars.threads;
/**Base class for any entity that needs to be synced across clients.*/
public abstract class SyncEntity extends DestructibleEntity{
protected transient Interpolator interpolator = new Interpolator();
/**Interpolator, used for smoothing position.*/
protected Interpolator interpolator = new Interpolator();
/**smoothed position and rotation*/
private Vector3 spos = new Vector3();
/**the general rotation.*/
public float rotation;
/**Called when a death event is recieved remotely.*/
public abstract void onRemoteDeath();
/**Called when a shoot event is recieved remotely.*/
public abstract void onRemoteShoot(BulletType type, float x, float y, float rotation, short data);
//Read and write spawn data, which is sent when the entity is requested
public abstract void writeSpawn(ByteBuffer data);
public abstract void readSpawn(ByteBuffer data);
//Read and write sync data, usually position
public abstract void write(ByteBuffer data);
public abstract void read(ByteBuffer data, long time);
@ -101,6 +110,7 @@ public abstract class SyncEntity extends DestructibleEntity{
}
public void update(){
//TODO prevent rubberbanding from getting too bad, clamp values?
time += 1f / spacing * Math.min(Timers.delta(), 1f);

View File

@ -1,18 +1,24 @@
package io.anuke.mindustry.entities;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.ObjectSet;
import io.anuke.mindustry.entities.units.BaseUnit;
import io.anuke.mindustry.game.Team;
import io.anuke.ucore.entities.Entities;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.function.Consumer;
import io.anuke.ucore.function.Predicate;
import static io.anuke.mindustry.Vars.playerGroup;
import static io.anuke.mindustry.Vars.unitGroups;
import static io.anuke.mindustry.Vars.*;
/**Utility class for unit-based interactions.*/
/**Utility class for unit and team interactions.*/
public class Units {
private static Rectangle rect = new Rectangle();
/**Iterates over all units on all teams, including players.*/
public static void allUnits(Consumer<Unit> cons){
//check all unit groups first
for(EntityGroup<BaseUnit> group : unitGroups){
if(!group.isEmpty()){
for(BaseUnit unit : group.all()){
@ -21,12 +27,73 @@ public class Units {
}
}
//then check all player groups
for(Player player : playerGroup.all()){
cons.accept(player);
}
}
public static void getNearbyEnemies(Team team, Rectangle rect, Consumer<Unit> cons){
public static Unit getClosestEnemies(Team team, float x, float y, float range, Predicate<Unit> predicate){
Unit[] result = {null};
float[] cdist = {0};
getNearbyEnemies(team, rect, e -> {
if (!predicate.test(e))
return;
float dist = Vector2.dst(e.x, e.y, x, y);
if (dist < range) {
if (result[0] == null || dist < cdist[0]) {
result[0] = e;
cdist[0] = dist;
}
}
});
return result[0];
}
/**Iterates over all units in a rectangle.*/
public static void getNearby(Rectangle rect, Consumer<Unit> cons){
for(Team team : Team.values()){
EntityGroup<BaseUnit> group = unitGroups[team.ordinal()];
if(!group.isEmpty()){
Entities.getNearby(group, rect, entity -> cons.accept((Unit)entity));
}
}
//now check all enemy players
Entities.getNearby(playerGroup, rect, player -> cons.accept((Unit)player));
}
/**Iterates over all units that are enemies of this team.*/
public static void getNearbyEnemies(Team team, Rectangle rect, Consumer<Unit> cons){
//check if it's an ally team to the 'main team'
boolean ally = state.team == team || state.allyTeams.contains(team);
ObjectSet<Team> targets = ally ? state.enemyTeams : state.allyTeams;
for(Team other : targets){
EntityGroup<BaseUnit> group = unitGroups[other.ordinal()];
if(!group.isEmpty()){
Entities.getNearby(group, rect, entity -> cons.accept((Unit)entity));
}
}
//now check all enemy players
Entities.getNearby(playerGroup, rect, player -> {
if(targets.contains(((Player)player).team)){
cons.accept((Unit)player);
}
});
}
/**Returns whether these two teams are enemies.*/
public static boolean areEnemies(Team team, Team other){
if(team == other) return false; //fast fail to be more efficient
boolean ally = state.team == team || state.allyTeams.contains(team);
boolean ally2 = state.team == other || state.allyTeams.contains(other);
return ally == ally2;
}
}

View File

@ -2,27 +2,27 @@ package io.anuke.mindustry.entities.effect;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.entities.DestructibleEntity;
import io.anuke.ucore.entities.Entities;
import io.anuke.ucore.entities.Entity;
import io.anuke.ucore.entities.SolidEntity;
import io.anuke.ucore.function.Consumer;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Physics;
import io.anuke.ucore.util.Translator;
import static io.anuke.mindustry.Vars.*;
import static io.anuke.mindustry.Vars.tilesize;
import static io.anuke.mindustry.Vars.world;
public class DamageArea{
private static Rectangle rect = new Rectangle();
private static Translator tr = new Translator();
//only for entities, not tiles (yet!)
public static void damageLine(Entity owner, Effect effect, float x, float y, float angle, float length, int damage){
/**Damages entities in a line.
* Only enemies of the specified team are damaged.*/
public static void damageLine(Team team, Effect effect, float x, float y, float angle, float length, int damage){
tr.trns(angle, length);
rect.setPosition(x, y).setSize(tr.x, tr.y);
float x2 = tr.x + x, y2 = tr.y + y;
@ -44,10 +44,8 @@ public class DamageArea{
rect.width += expand*2;
rect.height += expand*2;
Consumer<SolidEntity> cons = e -> {
if(e == owner) return;
DestructibleEntity enemy = (DestructibleEntity) e;
Rectangle other = enemy.hitbox.getRect(enemy.x, enemy.y);
Consumer<Unit> cons = e -> {
Rectangle other = e.hitbox.getRect(e.x, e.y);
other.y -= expand;
other.x -= expand;
other.width += expand * 2;
@ -57,53 +55,49 @@ public class DamageArea{
if (vec != null) {
Effects.effect(effect, vec.x, vec.y);
enemy.damage(damage);
e.damage(damage);
}
};
Entities.getNearby(enemyGroup, rect, cons);
if(state.friendlyFire) Entities.getNearby(playerGroup, rect, cons);
Units.getNearbyEnemies(team, rect, cons);
}
public static void damageEntities(float x, float y, float radius, int damage){
damage(true, x, y, radius, damage);
for(Player player : playerGroup.all()){
//if(player.isAndroid) continue;
int amount = calculateDamage(x, y, player.x, player.y, radius, damage);
player.damage(amount);
}
/**Damages everything in a radius.*/
public static void damage(float x, float y, float radius, int damage){
damage(null, x, y, radius, damage);
}
public static void damage(boolean enemies, float x, float y, float radius, int damage){
Consumer<SolidEntity> cons = entity -> {
DestructibleEntity enemy = (DestructibleEntity)entity;
if(enemy.distanceTo(x, y) > radius){
/**Damages all entities and blocks in a radius that are enemies of the team.*/
public static void damage(Team team, float x, float y, float radius, int damage){
Consumer<Unit> cons = entity -> {
if(entity.distanceTo(x, y) > radius){
return;
}
int amount = calculateDamage(x, y, enemy.x, enemy.y, radius, damage);
enemy.damage(amount);
int amount = calculateDamage(x, y, entity.x, entity.y, radius, damage);
entity.damage(amount);
};
if(enemies){
Entities.getNearby(enemyGroup, x, y, radius*2, cons);
rect.setSize(radius *2).setCenter(x, y);
if(team != null) {
Units.getNearbyEnemies(team, rect, cons);
}else{
int trad = (int)(radius / tilesize);
for(int dx = -trad; dx <= trad; dx ++){
for(int dy= -trad; dy <= trad; dy ++){
Tile tile = world.tile(Mathf.scl2(x, tilesize) + dx, Mathf.scl2(y, tilesize) + dy);
if(tile != null && tile.entity != null && Vector2.dst(dx, dy, 0, 0) <= trad){
int amount = calculateDamage(x, y, tile.worldx(), tile.worldy(), radius, damage);
tile.entity.damage(amount);
}
Units.getNearby(rect, cons);
}
int trad = (int)(radius / tilesize);
for(int dx = -trad; dx <= trad; dx ++){
for(int dy= -trad; dy <= trad; dy ++){
Tile tile = world.tile(Mathf.scl2(x, tilesize) + dx, Mathf.scl2(y, tilesize) + dy);
if(tile != null && tile.entity != null && (team == null || Units.areEnemies(team, tile.getTeam())) && Vector2.dst(dx, dy, 0, 0) <= trad){
int amount = calculateDamage(x, y, tile.worldx(), tile.worldy(), radius, damage);
tile.entity.damage(amount);
}
}
Entities.getNearby(playerGroup, x, y, radius*2, cons);
}
}
static int calculateDamage(float x, float y, float tx, float ty, float radius, int damage){
private static int calculateDamage(float x, float y, float tx, float ty, float radius, int damage){
float dist = Vector2.dst(x, y, tx, ty);
float scaled = 1f - dist/radius;
return (int)(damage * scaled);

View File

@ -1,40 +1,45 @@
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;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.Entities;
import io.anuke.ucore.entities.Entity;
import io.anuke.ucore.entities.SolidEntity;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.util.Mathf;
import static io.anuke.mindustry.Vars.enemyGroup;
public class TeslaOrb extends Entity{
private Array<Vector2> points = new Array<>();
private ObjectSet<BaseUnit> hit = new ObjectSet<>();
private int damage = 0;
private float range = 0;
private float lifetime = 30f;
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 Vector2 vector = new Vector2();
private float curx = x, cury = y;
private boolean done = false;
public TeslaOrb(float x, float y, float range, int damage){
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 curx = x, cury = y;
float shake = 3f;
int max = 7;
@ -43,19 +48,19 @@ public class TeslaOrb extends Entity{
if(Mathf.chance(stopchance)){
break;
}
Array<SolidEntity> enemies = Entities.getNearby(enemyGroup, curx, cury, range*2f);
for(SolidEntity entity : enemies){
if(entity != null && entity.distanceTo(curx, cury) < range && !hit.contains((BaseUnit)entity)){
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;
break;
done = true;
}
}
});
}
if(points.size == 0){
@ -107,11 +112,6 @@ public class TeslaOrb extends Entity{
Draw.rect("circle", x, y, rad, rad);
}
//Draw.color(Color.WHITE);
//Draw.stroke(2f - life/lifetime*2f);
//Draw.line(x1, y1, x2, y2);
Draw.reset();
previous = enemy;

View File

@ -1,6 +1,7 @@
package io.anuke.mindustry.entities.units;
import io.anuke.mindustry.entities.Bullet;
import io.anuke.mindustry.entities.BulletType;
import io.anuke.mindustry.entities.Unit;
import io.anuke.ucore.entities.Entity;
import io.anuke.ucore.entities.SolidEntity;
@ -63,9 +64,19 @@ public class BaseUnit extends Unit {
hitTime = hitDuration;
}
@Override
public void onRemoteShoot(BulletType type, float x, float y, float rotation, short data) {
new Bullet(type, this, x, y, rotation).add().damage = data;
}
@Override
public void onDeath(){
type.onDeath(this, false);
type.onDeath(this);
}
@Override
public void onRemoteDeath(){
type.onRemoteDeath(this);
}
@Override

View File

@ -67,7 +67,11 @@ public class UnitType {
//TODO
}
public void onDeath(BaseUnit enemy, boolean force){
public void onDeath(BaseUnit enemy){
//TODO
}
public void onRemoteDeath(BaseUnit enemy){
//TODO
}

View File

@ -3,7 +3,7 @@ package io.anuke.mindustry.game;
import com.badlogic.gdx.graphics.Color;
public enum Team {
none(Color.GRAY),
none(Color.DARK_GRAY),
blue(Color.BLUE),
red(Color.RED);

View File

@ -15,6 +15,7 @@ public class Shaders{
public static final SurfaceShader water = new SurfaceShader("water");
public static final SurfaceShader lava = new SurfaceShader("lava");
public static final SurfaceShader oil = new SurfaceShader("oil");
public static final Shader hit = new Shader("hit", "default") { protected void apply() {}};
private static final Vector2 vec = new Vector2();

View File

@ -6,6 +6,7 @@ import io.anuke.mindustry.entities.units.BaseUnit;
import io.anuke.mindustry.entities.units.UnitType;
import io.anuke.mindustry.game.Difficulty;
import io.anuke.mindustry.game.GameMode;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.io.SaveFileVersion;
import io.anuke.mindustry.io.SaveMeta;
import io.anuke.mindustry.resource.Item;
@ -18,7 +19,7 @@ import io.anuke.mindustry.world.blocks.Blocks;
import io.anuke.mindustry.world.blocks.types.BlockPart;
import io.anuke.mindustry.world.blocks.types.Rock;
import io.anuke.ucore.core.Core;
import io.anuke.ucore.entities.EntityGroup.EntityContainer;
import io.anuke.ucore.entities.EntityGroup;
import java.io.DataInputStream;
import java.io.DataOutputStream;
@ -84,7 +85,6 @@ public class Save16 extends SaveFileVersion {
Core.camera.position.set(playerx, playery, 0);
//weapons
control.upgrades().getWeapons().clear();
control.upgrades().getWeapons().add(Weapon.blaster);
player.weaponLeft = player.weaponRight = Weapon.blaster;
@ -117,26 +117,28 @@ public class Save16 extends SaveFileVersion {
//enemies
int enemies = stream.readInt();
byte teams = stream.readByte();
for(int i = 0; i < enemies; i ++){
byte type = stream.readByte();
float x = stream.readFloat();
float y = stream.readFloat();
int health = stream.readShort();
for(int i = 0; i < teams; i ++){
EntityGroup<BaseUnit> group = unitGroups[i];
int amount = stream.readInt();
for(int j = 0; j < amount; j ++){
byte type = stream.readByte();
float x = stream.readFloat();
float y = stream.readFloat();
int health = stream.readShort();
try{
BaseUnit enemy = new BaseUnit(UnitType.getByID(type));
enemy.health = health;
enemy.x = x;
enemy.y = y;
enemy.add(enemyGroup);
}catch (Exception e){
throw new RuntimeException(e);
enemy.add(group);
}
}
state.enemies = enemies;
state.enemies = 0; //TODO display enemies correctly!
state.wave = wave;
state.wavetime = wavetime;
@ -186,9 +188,11 @@ public class Save16 extends SaveFileVersion {
}
if(tile.entity != null){
byte team = stream.readByte();
byte rotation = stream.readByte();
short health = stream.readShort();
tile.setTeam(Team.values()[team]);
tile.entity.health = health;
tile.setRotation(rotation);
@ -265,17 +269,18 @@ public class Save16 extends SaveFileVersion {
}
//--ENEMIES--
stream.writeByte(Team.values().length); //amount of total teams (backwards compatibility)
EntityContainer<BaseUnit> enemies = enemyGroup.all();
for(Team team : Team.values()){
EntityGroup<BaseUnit> group = unitGroups[team.ordinal()];
stream.writeInt(group.size()); //amount of units in the team group
stream.writeInt(enemies.size()); //enemy amount
for(int i = 0; i < enemies.size(); i ++){
BaseUnit enemy = enemies.get(i);
stream.writeByte(enemy.type.id); //type
stream.writeFloat(enemy.x); //x
stream.writeFloat(enemy.y); //y
stream.writeShort(enemy.health); //health
for(BaseUnit unit : group.all()){
stream.writeByte(unit.type.id); //type
stream.writeFloat(unit.x); //x
stream.writeFloat(unit.y); //y
stream.writeShort(unit.health); //health
}
}
//--MAP DATA--
@ -329,6 +334,7 @@ public class Save16 extends SaveFileVersion {
if(tile.block() instanceof BlockPart) stream.writeByte(tile.link);
if(tile.entity != null){
stream.writeByte(tile.getTeam().ordinal());
stream.writeByte(tile.getRotation()); //rotation
stream.writeShort((short)tile.entity.health); //health

View File

@ -1,16 +1,15 @@
package io.anuke.mindustry.net;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.entities.BulletType;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.SyncEntity;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.entities.units.BaseUnit;
import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.net.Net.SendMode;
import io.anuke.mindustry.net.Packets.*;
import io.anuke.mindustry.resource.Weapon;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.entities.Entity;
import static io.anuke.mindustry.Vars.*;
@ -29,20 +28,11 @@ public class NetEvents {
Net.send(new GameOverPacket(), SendMode.tcp);
}
public static void handleBullet(BulletType type, Entity owner, float x, float y, float angle, short damage){
BulletPacket packet = new BulletPacket();
packet.x = x;
packet.y = y;
packet.angle = angle;
packet.damage = damage;
packet.owner = owner.id;
packet.type = type.id;
Net.send(packet, SendMode.udp);
}
public static void handleEnemyDeath(BaseUnit enemy){
EnemyDeathPacket packet = new EnemyDeathPacket();
public static void handleUnitDeath(Unit enemy){
EntityDeathPacket packet = new EntityDeathPacket();
packet.id = enemy.id;
packet.group = (byte)enemy.getGroup().getID();
Net.send(packet, SendMode.tcp);
}
@ -60,7 +50,7 @@ public class NetEvents {
}
public static void handlePlayerDeath(){
PlayerDeathPacket packet = new PlayerDeathPacket();
EntityDeathPacket packet = new EntityDeathPacket();
packet.id = Vars.player.id;
Net.send(packet, SendMode.tcp);
}
@ -100,13 +90,14 @@ public class NetEvents {
Net.send(packet, SendMode.tcp);
}
public static void handleShoot(Weapon weapon, float x, float y, float angle){
ShootPacket packet = new ShootPacket();
packet.weaponid = weapon.id;
public static void handleShoot(SyncEntity entity, float x, float y, float angle, short data){
EntityShootPacket packet = new EntityShootPacket();
packet.groupid = (byte)entity.getGroup().getID();
packet.x = x;
packet.y = y;
packet.data = data;
packet.rotation = angle;
packet.playerid = Vars.player.id;
packet.entityid = entity.id;
Net.send(packet, SendMode.udp);
}

View File

@ -161,60 +161,31 @@ public class Packets {
}
}
//not a real packet.
public static class EffectPacket{
public int id;
public static class EntityShootPacket implements Packet{
public float x, y, rotation;
public int color;
}
public static class ShootPacket implements Packet{
public byte weaponid;
public float x, y, rotation;
public int playerid;
public short bulletid;
public byte groupid;
public short data;
public int entityid;
@Override
public void write(ByteBuffer buffer) {
buffer.put(weaponid);
buffer.put(groupid);
buffer.putInt(entityid);
buffer.putFloat(x);
buffer.putFloat(y);
buffer.putFloat(rotation);
buffer.putInt(playerid);
buffer.putShort(bulletid);
}
@Override
public void read(ByteBuffer buffer) {
weaponid = buffer.get();
groupid = buffer.get();
entityid = buffer.getInt();
x = buffer.getFloat();
y = buffer.getFloat();
rotation = buffer.getFloat();
playerid = buffer.getInt();
}
}
public static class BulletPacket implements Packet{
public int type, owner;
public float x, y, angle;
public short damage;
@Override
public void write(ByteBuffer buffer) {
buffer.putShort((short)type);
buffer.putInt(owner);
buffer.putFloat(x);
buffer.putFloat(y);
buffer.putFloat(angle);
buffer.putShort(damage);
}
@Override
public void read(ByteBuffer buffer) {
type = buffer.getShort();
owner = buffer.getInt();
x = buffer.getFloat();
y = buffer.getFloat();
angle = buffer.getFloat();
damage = buffer.getShort();
bulletid = buffer.getShort();
}
}
@ -289,16 +260,19 @@ public class Packets {
}
}
public static class EnemyDeathPacket implements Packet{
public static class EntityDeathPacket implements Packet{
public byte group;
public int id;
@Override
public void write(ByteBuffer buffer) {
buffer.put(group);
buffer.putInt(id);
}
@Override
public void read(ByteBuffer buffer) {
group = buffer.get();
id = buffer.getInt();
}
}
@ -496,20 +470,6 @@ public class Packets {
}
}
public static class PlayerDeathPacket implements Packet{
public int id;
@Override
public void write(ByteBuffer buffer) {
buffer.putInt(id);
}
@Override
public void read(ByteBuffer buffer) {
id = buffer.getInt();
}
}
public static class CustomMapPacket extends Streamable{
}

View File

@ -8,40 +8,38 @@ import io.anuke.mindustry.net.Streamable.StreamChunk;
public class Registrator {
private static Class<?>[] classes = {
StreamBegin.class,
StreamChunk.class,
WorldData.class,
SyncPacket.class,
PositionPacket.class,
ShootPacket.class,
PlacePacket.class,
BreakPacket.class,
StateSyncPacket.class,
BlockSyncPacket.class,
BulletPacket.class,
EnemyDeathPacket.class,
BlockUpdatePacket.class,
BlockDestroyPacket.class,
ConnectPacket.class,
DisconnectPacket.class,
ChatPacket.class,
KickPacket.class,
UpgradePacket.class,
WeaponSwitchPacket.class,
BlockTapPacket.class,
BlockConfigPacket.class,
EntityRequestPacket.class,
ConnectConfirmPacket.class,
GameOverPacket.class,
FriendlyFireChangePacket.class,
PlayerDeathPacket.class,
CustomMapPacket.class,
MapAckPacket.class,
EntitySpawnPacket.class,
NetErrorPacket.class,
PlayerAdminPacket.class,
AdministerRequestPacket.class,
TracePacket.class,
StreamBegin.class,
StreamChunk.class,
WorldData.class,
SyncPacket.class,
PositionPacket.class,
EntityShootPacket.class,
PlacePacket.class,
BreakPacket.class,
StateSyncPacket.class,
BlockSyncPacket.class,
EntityDeathPacket.class,
BlockUpdatePacket.class,
BlockDestroyPacket.class,
ConnectPacket.class,
DisconnectPacket.class,
ChatPacket.class,
KickPacket.class,
UpgradePacket.class,
WeaponSwitchPacket.class,
BlockTapPacket.class,
BlockConfigPacket.class,
EntityRequestPacket.class,
ConnectConfirmPacket.class,
GameOverPacket.class,
FriendlyFireChangePacket.class,
CustomMapPacket.class,
MapAckPacket.class,
EntitySpawnPacket.class,
NetErrorPacket.class,
PlayerAdminPacket.class,
AdministerRequestPacket.class,
TracePacket.class,
};
private static ObjectIntMap<Class<?>> ids = new ObjectIntMap<>();

View File

@ -121,7 +121,7 @@ public class Weapon extends Upgrade{
shootInternal(p, x, y, angle);
if(Net.active() && p == Vars.player){
NetEvents.handleShoot(this, x, y, angle);
NetEvents.handleShoot(Vars.player, x, y, angle, id);
}
}

View File

@ -58,12 +58,6 @@ public class DebugFragment implements Fragment {
row();
new button("time max", () -> Timers.resetTime(1080000 - 60*10));
row();
new button("clear", () -> {
enemyGroup.clear();
state.enemies = 0;
netClient.clearRecieved();
});
row();
}}.end();
row();
@ -126,7 +120,6 @@ public class DebugFragment implements Fragment {
"chat.messages: " + ui.chatfrag.getMessagesSize() + "\n" +
"client.connecting: " + netClient.isConnecting() + "\n" : "",
"players: " + playerGroup.size(),
"enemies: " + enemyGroup.size(),
"tiles: " + tileGroup.size(),
"time: " + Timers.time(),
world.getCore() != null && world.getCore().entity != null ? "core.health: " + world.getCore().entity.health : "",

View File

@ -4,6 +4,7 @@ import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.game.SpawnPoint;
import io.anuke.mindustry.graphics.Fx;
import io.anuke.mindustry.resource.ItemStack;
@ -13,7 +14,6 @@ import io.anuke.mindustry.world.blocks.Blocks;
import io.anuke.mindustry.world.blocks.ProductionBlocks;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.entities.Entities;
import io.anuke.ucore.entities.SolidEntity;
import static io.anuke.mindustry.Vars.*;
@ -107,14 +107,19 @@ public class Placement {
rect.setCenter(offset.x + x * tilesize, offset.y + y * tilesize);
synchronized (Entities.entityLock) {
for (SolidEntity e : Entities.getNearby(enemyGroup, x * tilesize, y * tilesize, tilesize * 2f)) {
if (e == null) continue; //not sure why this happens?
rect.setSize(tilesize*2f).setCenter(x*tilesize, y*tilesize);
boolean[] result = {false};
Units.getNearby(rect, e -> {
if (e == null) return; //not sure why this happens?
Rectangle rect = e.hitbox.getRect(e.x, e.y);
if (Placement.rect.overlaps(rect)) {
return false;
result[0] = true;
}
}
});
if(result[0]) return false;
}
if(type.solid || type.solidifes) {

View File

@ -1,7 +1,6 @@
package io.anuke.mindustry.world;
import com.badlogic.gdx.math.GridPoint2;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.reflect.ClassReflection;
import io.anuke.mindustry.entities.TileEntity;
@ -12,7 +11,6 @@ import io.anuke.mindustry.world.blocks.types.modules.LiquidModule;
import io.anuke.mindustry.world.blocks.types.modules.PowerModule;
import io.anuke.ucore.function.Consumer;
import io.anuke.ucore.util.Bits;
import io.anuke.ucore.util.Mathf;
import static io.anuke.mindustry.Vars.tilesize;
import static io.anuke.mindustry.Vars.world;
@ -86,20 +84,6 @@ public class Tile{
return (T)entity;
}
public void damageNearby(int rad, int amount, float falloff){
for(int dx = -rad; dx <= rad; dx ++){
for(int dy = -rad; dy <= rad; dy ++){
float dst = Vector2.dst(dx, dy, 0, 0);
if(dst > rad || (dx == 0 && dy == 0)) continue;
Tile other = world.tile(x + dx, y + dy);
if(other != null && other.entity != null){
other.entity.damage((int)(amount * Mathf.lerp(1f-dst/rad, 1f, falloff)));
}
}
}
}
public int id(){
return x + y * world.width();
}

View File

@ -117,7 +117,7 @@ public class WeaponBlocks{
float len = 4f;
new TeslaOrb(tile.drawx() + Angles.trnsx(entity.rotation, len), tile.drawy() + Angles.trnsy(entity.rotation, len), range, 9).add();
new TeslaOrb(tile.getTeam(), tile.drawx() + Angles.trnsx(entity.rotation, len), tile.drawy() + Angles.trnsy(entity.rotation, len), range, 9).add();
}
},

View File

@ -2,21 +2,20 @@ package io.anuke.mindustry.world.blocks.types.defense;
import com.badlogic.gdx.math.Rectangle;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.graphics.Fx;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.Wall;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.entities.Entities;
import io.anuke.ucore.entities.SolidEntity;
import io.anuke.ucore.graphics.Draw;
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 Door extends Wall{
protected final Rectangle rect = new Rectangle();
@ -68,24 +67,17 @@ public class Door extends Wall{
Block type = tile.block();
rect.setSize(type.size * tilesize, type.size * tilesize);
rect.setCenter(tile.drawx(), tile.drawy());
for(SolidEntity e : Entities.getNearby(enemyGroup, x * tilesize, y * tilesize, tilesize * 2f)){
Rectangle rect = e.hitbox.getRect(e.x, e.y);
if(this.rect.overlaps(rect)){
return true;
boolean[] value = new boolean[1];
Units.getNearby(rect, unit -> {
if(value[0]) return;
if(unit.hitbox.getRect(unit.x, unit.y).overlaps(rect)){
value[0] = true;
}
}
for(SolidEntity e : Entities.getNearby(playerGroup, x * tilesize, y * tilesize, tilesize * 2f)){
Rectangle rect = e.hitbox.getRect(e.x, e.y);
if(this.rect.overlaps(rect)){
return true;
}
}
});
return false;
return value[0];
}
@Override

View File

@ -2,15 +2,14 @@ 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.units.BaseUnit;
import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.graphics.Fx;
import io.anuke.mindustry.world.Layer;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.core.Effects;
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;
@ -32,7 +31,7 @@ public class LaserTurret extends PowerTurret{
@Override
public void shoot(Tile tile){
TurretEntity entity = tile.entity();
BaseUnit enemy = entity.target;
Unit enemy = entity.target;
if(Angles.angleDist(entity.rotation, Angles.angle(tile.drawx(), tile.drawy(), enemy.x, enemy.y)) < cone){
enemy.damage(damage);
@ -43,7 +42,7 @@ public class LaserTurret extends PowerTurret{
@Override
public void drawLayer2(Tile tile){
TurretEntity entity = tile.entity();
BaseUnit enemy = entity.target;
Unit enemy = entity.target;
if(enemy != null &&
Angles.angleDist(entity.rotation, Angles.angle(tile.drawx(), tile.drawy(), enemy.x, enemy.y)) <= cone){

View File

@ -1,17 +1,13 @@
package io.anuke.mindustry.world.blocks.types.defense;
import com.badlogic.gdx.graphics.Color;
import io.anuke.mindustry.entities.Bullet;
import io.anuke.mindustry.entities.BulletType;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.entities.units.BaseUnit;
import io.anuke.mindustry.entities.*;
import io.anuke.mindustry.graphics.Fx;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.world.*;
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.graphics.Draw;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.util.Angles;
@ -131,8 +127,8 @@ public class Turret extends Block{
if(hasAmmo(tile) || (debug && infiniteAmmo)){
if(entity.timer.get(timerTarget, targetInterval)){
entity.target = (BaseUnit)Entities.getClosest(enemyGroup,
tile.worldx(), tile.worldy(), range, e-> e instanceof BaseUnit && !((BaseUnit)e).isDead());
entity.target = Units.getClosestEnemies(tile.getTeam(),
tile.worldx(), tile.worldy(), range, e -> !e.isDead());
}
if(entity.target != null){
@ -240,7 +236,7 @@ public class Turret extends Block{
public TileEntity blockTarget;
public int ammo;
public float rotation = 90;
public BaseUnit target;
public Unit target;
@Override
public void write(DataOutputStream stream) throws IOException{

View File

@ -124,9 +124,7 @@ public class Generator extends PowerBlock{
Effects.effect(Fx.generatorexplosion, x, y);
Effects.effect(Fx.shockwave, x, y);
Timers.run(12f + Mathf.random(20f), () -> {
tile.damageNearby(4, 60, 0f);
});
//TODO better explosion effect!
Effects.sound(explosionSound, x, y);
});

View File

@ -130,16 +130,6 @@ public class NuclearReactor extends LiquidPowerGenerator{
if(fuel < 5 && entity.heat < 0.5f) return;
int waves = 6;
float delay = 8f;
for(int i = 0; i < waves; i ++){
float rad = (float)i /waves * explosionRadius;
Timers.run(i * delay, ()->{
tile.damageNearby((int)rad, explosionDamage / waves, 0.4f);
});
}
Effects.shake(6f, 16f, tile.worldx(), tile.worldy());
Effects.effect(explosionEffect, tile.worldx(), tile.worldy());
for(int i = 0; i < 6; i ++){
@ -148,7 +138,7 @@ public class NuclearReactor extends LiquidPowerGenerator{
});
}
DamageArea.damageEntities(tile.worldx(), tile.worldy(), explosionRadius * tilesize, explosionDamage * 4);
DamageArea.damage(tile.worldx(), tile.worldy(), explosionRadius * tilesize, explosionDamage * 4);
for(int i = 0; i < 20; i ++){