mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-02-10 18:57:39 +07:00
Fixed compile errors, unitification
This commit is contained in:
parent
807c4688c2
commit
52c0a8e573
18
core/assets/shaders/hit.fragment
Normal file
18
core/assets/shaders/hit.fragment
Normal 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);
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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){
|
||||
|
@ -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);
|
||||
});
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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(){
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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{
|
||||
|
||||
}
|
||||
|
@ -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<>();
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 : "",
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -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
|
||||
|
@ -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){
|
||||
|
@ -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{
|
||||
|
@ -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);
|
||||
});
|
||||
|
@ -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 ++){
|
||||
|
Loading…
Reference in New Issue
Block a user