Mass-deletion of enemy code
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.world.Tile" />
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.io.Maps" />
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.entities.Player" />
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.entities.enemies.Enemy" />
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.entities.enemies.BaseUnit" />
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.world.Map" />
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.game.EnemySpawn" />
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.core.GameState" />
|
||||
|
||||
@@ -9,7 +9,7 @@ import io.anuke.mindustry.entities.Bullet;
|
||||
import io.anuke.mindustry.entities.Player;
|
||||
import io.anuke.mindustry.entities.TileEntity;
|
||||
import io.anuke.mindustry.entities.effect.Shield;
|
||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||
import io.anuke.mindustry.entities.enemies.BaseUnit;
|
||||
import io.anuke.mindustry.io.Platform;
|
||||
import io.anuke.mindustry.net.ClientDebug;
|
||||
import io.anuke.mindustry.net.ServerDebug;
|
||||
@@ -136,7 +136,7 @@ public class Vars{
|
||||
public static Player player;
|
||||
|
||||
public static final EntityGroup<Player> playerGroup = Entities.addGroup(Player.class).enableMapping();
|
||||
public static final EntityGroup<Enemy> enemyGroup = Entities.addGroup(Enemy.class).enableMapping();
|
||||
public static final EntityGroup<BaseUnit> enemyGroup = Entities.addGroup(BaseUnit.class).enableMapping();
|
||||
public static final EntityGroup<TileEntity> tileGroup = Entities.addGroup(TileEntity.class, false);
|
||||
public static final EntityGroup<Bullet> bulletGroup = Entities.addGroup(Bullet.class);
|
||||
public static final EntityGroup<Shield> shieldGroup = Entities.addGroup(Shield.class, false);
|
||||
|
||||
@@ -4,15 +4,14 @@ import com.badlogic.gdx.ai.pfa.PathFinderRequest;
|
||||
import com.badlogic.gdx.ai.pfa.PathSmoother;
|
||||
import com.badlogic.gdx.math.MathUtils;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||
import io.anuke.mindustry.entities.enemies.BaseUnit;
|
||||
import io.anuke.mindustry.game.SpawnPoint;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.util.Angles;
|
||||
import io.anuke.ucore.util.Log;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
import static io.anuke.mindustry.Vars.state;
|
||||
import static io.anuke.mindustry.Vars.world;
|
||||
|
||||
public class Pathfind{
|
||||
/**Maximum time taken per frame on pathfinding for a single path.*/
|
||||
@@ -33,91 +32,9 @@ public class Pathfind{
|
||||
* If the path is not yet calculated, this returns the enemy's position (i. e. "don't move")
|
||||
* @param enemy The enemy to find a path for
|
||||
* @return The position the enemy should move to.*/
|
||||
public Vector2 find(Enemy enemy){
|
||||
//TODO fix -1/-2 node usage
|
||||
if(enemy.node == -1 || enemy.node == -2){
|
||||
findNode(enemy);
|
||||
}
|
||||
|
||||
if(enemy.node == -2){
|
||||
enemy.node = -1;
|
||||
}
|
||||
|
||||
if(enemy.node < 0 || world.getSpawns().get(enemy.lane).pathTiles == null){
|
||||
return vector.set(enemy.x, enemy.y);
|
||||
}
|
||||
|
||||
Tile[] path = world.getSpawns().get(enemy.lane).pathTiles;
|
||||
|
||||
if(enemy.node >= path.length){
|
||||
enemy.node = -1;
|
||||
return vector.set(enemy.x, enemy.y);
|
||||
}
|
||||
|
||||
if(enemy.node <= -1){
|
||||
return vector.set(enemy.x, enemy.y);
|
||||
}
|
||||
|
||||
//TODO documentation on what this does
|
||||
Tile prev = path[enemy.node - 1];
|
||||
|
||||
Tile target = path[enemy.node];
|
||||
|
||||
//a bridge has been broken, re-path
|
||||
if(!world.passable(target.x, target.y)){
|
||||
remakePath();
|
||||
return vector.set(enemy.x, enemy.y);
|
||||
}
|
||||
|
||||
float projectLen = Vector2.dst(prev.worldx(), prev.worldy(), target.worldx(), target.worldy()) / 6f;
|
||||
|
||||
Vector2 projection = projectPoint(prev.worldx(), prev.worldy(),
|
||||
target.worldx(), target.worldy(), enemy.x, enemy.y);
|
||||
|
||||
boolean canProject = true;
|
||||
|
||||
if(projectLen < 8 || !onLine(projection, prev.worldx(), prev.worldy(), target.worldx(), target.worldy())){
|
||||
canProject = false;
|
||||
}else{
|
||||
projection.add(v1.set(projectLen, 0).rotate(Angles.angle(prev.worldx(), prev.worldy(),
|
||||
target.worldx(), target.worldy())));
|
||||
}
|
||||
|
||||
float dst = Vector2.dst(enemy.x, enemy.y, target.worldx(), target.worldy());
|
||||
float nlinedist = enemy.node >= path.length - 1 ? 9999 :
|
||||
pointLineDist(path[enemy.node].worldx(), path[enemy.node].worldy(),
|
||||
path[enemy.node + 1].worldx(), path[enemy.node + 1].worldy(), enemy.x, enemy.y);
|
||||
|
||||
if(dst < 8 || nlinedist < 8){
|
||||
if(enemy.node <= path.length-2)
|
||||
enemy.node ++;
|
||||
|
||||
target = path[enemy.node];
|
||||
}
|
||||
|
||||
if(canProject && projection.dst(enemy.x, enemy.y) < Vector2.dst(target.x, target.y, enemy.x, enemy.y)){
|
||||
vector.set(projection);
|
||||
}else{
|
||||
vector.set(target.worldx(), target.worldy());
|
||||
}
|
||||
|
||||
//near the core, stop
|
||||
if(enemy.node == path.length - 1){
|
||||
vector.set(target.worldx(), target.worldy());
|
||||
}
|
||||
|
||||
return vector;
|
||||
|
||||
}
|
||||
|
||||
/**Re-calculate paths for all enemies. Runs when a path changes while moving.*/
|
||||
private void remakePath(){
|
||||
for(int i = 0; i < enemyGroup.size(); i ++){
|
||||
Enemy enemy = enemyGroup.all().get(i);
|
||||
enemy.node = -1;
|
||||
}
|
||||
|
||||
resetPaths();
|
||||
public Vector2 find(BaseUnit enemy){
|
||||
//TODO!
|
||||
return v1.set(enemy.x, enemy.y);
|
||||
}
|
||||
|
||||
/**Update the pathfinders and continue calculating the path if it hasn't been calculated yet.
|
||||
@@ -185,28 +102,6 @@ public class Pathfind{
|
||||
point.request.statusChanged = true; //IMPORTANT!
|
||||
}
|
||||
|
||||
/**For an enemy that was just loaded from a save, find the node in the path it should be following.*/
|
||||
void findNode(Enemy enemy){
|
||||
if(enemy.lane >= world.getSpawns().size || enemy.lane < 0){
|
||||
enemy.lane = 0;
|
||||
}
|
||||
|
||||
if(world.getSpawns().get(enemy.lane).pathTiles == null){
|
||||
return;
|
||||
}
|
||||
|
||||
Tile[] path = world.getSpawns().get(enemy.lane).pathTiles;
|
||||
|
||||
int closest = findClosest(path, enemy.x, enemy.y);
|
||||
|
||||
closest = Mathf.clamp(closest, 1, path.length-1);
|
||||
if(closest == -1){
|
||||
return;
|
||||
}
|
||||
|
||||
enemy.node = closest;
|
||||
}
|
||||
|
||||
/**Finds the closest tile to a position, in an array of tiles.*/
|
||||
private int findClosest(Tile[] tiles, float x, float y){
|
||||
int cindex = -2;
|
||||
|
||||
@@ -17,6 +17,7 @@ import io.anuke.mindustry.io.Platform;
|
||||
import io.anuke.mindustry.io.Saves;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.mindustry.resource.Item;
|
||||
import io.anuke.mindustry.resource.Mech;
|
||||
import io.anuke.mindustry.resource.Weapon;
|
||||
import io.anuke.mindustry.world.Map;
|
||||
import io.anuke.ucore.UCore;
|
||||
@@ -132,7 +133,7 @@ public class Control extends Module{
|
||||
|
||||
player = new Player();
|
||||
player.name = Settings.getString("name");
|
||||
player.isAndroid = android;
|
||||
player.mech = android ? Mech.standardShip : Mech.standard;
|
||||
player.color.set(Settings.getInt("color"));
|
||||
player.isLocal = true;
|
||||
|
||||
|
||||
@@ -2,25 +2,19 @@ package io.anuke.mindustry.core;
|
||||
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import io.anuke.mindustry.core.GameState.State;
|
||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||
import io.anuke.mindustry.game.EnemySpawn;
|
||||
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.SpawnPoint;
|
||||
import io.anuke.mindustry.game.WaveCreator;
|
||||
import io.anuke.mindustry.graphics.Fx;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.mindustry.net.NetEvents;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.mindustry.world.blocks.ProductionBlocks;
|
||||
import io.anuke.ucore.core.Effects;
|
||||
import io.anuke.ucore.core.Events;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.entities.Entities;
|
||||
import io.anuke.ucore.modules.Module;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
@@ -73,30 +67,7 @@ public class Logic extends Module {
|
||||
}
|
||||
|
||||
for(EnemySpawn spawn : spawns){
|
||||
Array<SpawnPoint> spawns = world.getSpawns();
|
||||
|
||||
for(int lane = 0; lane < spawns.size; lane ++){
|
||||
int fl = lane;
|
||||
Tile tile = spawns.get(lane).start;
|
||||
int spawnamount = spawn.evaluate(state.wave, lane);
|
||||
|
||||
for(int i = 0; i < spawnamount; i ++){
|
||||
float range = 12f;
|
||||
|
||||
Timers.runTask(i*5f, () -> {
|
||||
|
||||
Enemy enemy = new Enemy(spawn.type);
|
||||
enemy.set(tile.worldx() + Mathf.range(range), tile.worldy() + Mathf.range(range));
|
||||
enemy.lane = fl;
|
||||
enemy.tier = spawn.tier(state.wave, fl);
|
||||
enemy.add();
|
||||
|
||||
Effects.effect(Fx.spawn, enemy);
|
||||
|
||||
state.enemies ++;
|
||||
});
|
||||
}
|
||||
}
|
||||
//TODO spawn enemies for that spawnpoint
|
||||
}
|
||||
|
||||
state.wave ++;
|
||||
|
||||
@@ -9,7 +9,7 @@ import io.anuke.mindustry.entities.Bullet;
|
||||
import io.anuke.mindustry.entities.BulletType;
|
||||
import io.anuke.mindustry.entities.Player;
|
||||
import io.anuke.mindustry.entities.SyncEntity;
|
||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||
import io.anuke.mindustry.entities.enemies.BaseUnit;
|
||||
import io.anuke.mindustry.io.Platform;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.mindustry.net.Net.SendMode;
|
||||
@@ -139,7 +139,7 @@ public class NetClient extends Module {
|
||||
SyncEntity entity = (SyncEntity) group.getByID(id);
|
||||
|
||||
if(entity instanceof Player) players ++;
|
||||
if(entity instanceof Enemy) enemies ++;
|
||||
if(entity instanceof BaseUnit) enemies ++;
|
||||
|
||||
if (entity == null || id == player.id) {
|
||||
if (id != player.id) {
|
||||
@@ -199,7 +199,7 @@ public class NetClient extends Module {
|
||||
});
|
||||
|
||||
Net.handleClient(EnemyDeathPacket.class, packet -> {
|
||||
Enemy enemy = enemyGroup.getByID(packet.id);
|
||||
BaseUnit enemy = enemyGroup.getByID(packet.id);
|
||||
if (enemy != null){
|
||||
enemy.type.onDeath(enemy, true);
|
||||
}else if(recent.get(packet.id) != null){
|
||||
|
||||
@@ -85,7 +85,7 @@ public class NetServer extends Module{
|
||||
player.isAdmin = admins.isAdmin(Net.getConnection(id).address);
|
||||
player.clientid = id;
|
||||
player.name = packet.name;
|
||||
player.isAndroid = packet.android;
|
||||
player.mech = packet.android ? Mech.standardShip : Mech.standard;
|
||||
player.set(world.getSpawnX(), world.getSpawnY());
|
||||
player.setNet(player.x, player.y);
|
||||
player.setNet(player.x, player.y);
|
||||
@@ -219,7 +219,7 @@ public class NetServer extends Module{
|
||||
Net.handleServer(UpgradePacket.class, (id, packet) -> {
|
||||
Player player = connections.get(id);
|
||||
|
||||
Weapon weapon = (Weapon) Upgrade.getByID(packet.id);
|
||||
Weapon weapon = Upgrade.getByID(packet.id);
|
||||
|
||||
if (!weapons.containsKey(player.name)) weapons.put(player.name, new ByteArray());
|
||||
if (!weapons.get(player.name).contains(weapon.id)) weapons.get(player.name).add(weapon.id);
|
||||
|
||||
@@ -15,7 +15,7 @@ import com.badlogic.gdx.utils.Pools;
|
||||
import io.anuke.mindustry.core.GameState.State;
|
||||
import io.anuke.mindustry.entities.Player;
|
||||
import io.anuke.mindustry.entities.SyncEntity;
|
||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||
import io.anuke.mindustry.entities.enemies.BaseUnit;
|
||||
import io.anuke.mindustry.game.SpawnPoint;
|
||||
import io.anuke.mindustry.graphics.BlockRenderer;
|
||||
import io.anuke.mindustry.graphics.Shaders;
|
||||
@@ -282,7 +282,7 @@ public class Renderer extends RendererModule{
|
||||
Graphics.surface(indicatorSurface);
|
||||
Draw.color(Color.RED);
|
||||
|
||||
for(Enemy enemy : enemyGroup.all()) {
|
||||
for(BaseUnit enemy : enemyGroup.all()) {
|
||||
|
||||
if (rect.setSize(camera.viewportWidth, camera.viewportHeight).setCenter(camera.position.x, camera.position.y)
|
||||
.overlaps(enemy.hitbox.getRect(enemy.x, enemy.y))) {
|
||||
@@ -503,7 +503,7 @@ public class Renderer extends RendererModule{
|
||||
if((!debug || showUI) && Settings.getBool("healthbars")){
|
||||
|
||||
//draw entity health bars
|
||||
for(Enemy entity : enemyGroup.all()){
|
||||
for(BaseUnit entity : enemyGroup.all()){
|
||||
drawHealth(entity);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package io.anuke.mindustry.entities;
|
||||
|
||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||
import io.anuke.mindustry.entities.enemies.BaseUnit;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.ucore.entities.BulletEntity;
|
||||
import io.anuke.ucore.entities.Entity;
|
||||
@@ -37,7 +37,7 @@ public class Bullet extends BulletEntity{
|
||||
}
|
||||
|
||||
public boolean collidesTiles(){
|
||||
return owner instanceof Enemy;
|
||||
return owner instanceof BaseUnit;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -3,7 +3,7 @@ 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.enemies.Enemy;
|
||||
import io.anuke.mindustry.entities.enemies.BaseUnit;
|
||||
import io.anuke.mindustry.graphics.Fx;
|
||||
import io.anuke.ucore.graphics.Draw;
|
||||
import io.anuke.ucore.core.Effects;
|
||||
@@ -122,7 +122,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
|
||||
Effects.effect(Fx.shellsmoke, b);
|
||||
Effects.effect(Fx.shellexplosion, b);
|
||||
|
||||
DamageArea.damage(!(b.owner instanceof Enemy), b.x, b.y, 25f, (int)(damage * 2f/3f));
|
||||
DamageArea.damage(!(b.owner instanceof BaseUnit), b.x, b.y, 25f, (int)(damage * 2f/3f));
|
||||
}
|
||||
},
|
||||
flak = new BulletType(2.9f, 8) {
|
||||
@@ -202,7 +202,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
|
||||
Effects.effect(Fx.shellsmoke, b);
|
||||
Effects.effect(Fx.shockwaveSmall, b);
|
||||
|
||||
DamageArea.damage(!(b.owner instanceof Enemy), b.x, b.y, 50f, (int)(damage * 2f/3f));
|
||||
DamageArea.damage(!(b.owner instanceof BaseUnit), b.x, b.y, 50f, (int)(damage * 2f/3f));
|
||||
}
|
||||
},
|
||||
yellowshell = new BulletType(1.2f, 20){
|
||||
@@ -233,7 +233,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
|
||||
Effects.effect(Fx.shellsmoke, b);
|
||||
Effects.effect(Fx.shockwaveSmall, b);
|
||||
|
||||
DamageArea.damage(!(b.owner instanceof Enemy), b.x, b.y, 25f, (int)(damage * 2f/3f));
|
||||
DamageArea.damage(!(b.owner instanceof BaseUnit), b.x, b.y, 25f, (int)(damage * 2f/3f));
|
||||
}
|
||||
},
|
||||
blast = new BulletType(1.1f, 90){
|
||||
@@ -371,7 +371,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
|
||||
|
||||
Effects.effect(Fx.clusterbomb, b);
|
||||
|
||||
DamageArea.damage(!(b.owner instanceof Enemy), b.x, b.y, 35f, damage);
|
||||
DamageArea.damage(!(b.owner instanceof BaseUnit), b.x, b.y, 35f, damage);
|
||||
}
|
||||
},
|
||||
vulcan = new BulletType(4.5f, 12) {
|
||||
|
||||
@@ -23,17 +23,14 @@ import java.nio.ByteBuffer;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class Player extends SyncEntity{
|
||||
public class Player extends Unit{
|
||||
static final float speed = 1.1f;
|
||||
static final float dashSpeed = 1.8f;
|
||||
|
||||
static final int timerDash = 0;
|
||||
static final int timerShootLeft = 1;
|
||||
static final int timerShootRight = 2;
|
||||
static final int timerRegen = 3;
|
||||
|
||||
public String name = "name";
|
||||
public boolean isAndroid;
|
||||
public boolean isAdmin;
|
||||
public Color color = new Color();
|
||||
|
||||
@@ -60,9 +57,14 @@ public class Player extends SyncEntity{
|
||||
heal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getMass(){
|
||||
return mech.mass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void damage(int amount){
|
||||
if(debug || isAndroid) return;
|
||||
if(debug || mech.flying) return;
|
||||
|
||||
health -= amount;
|
||||
if(health <= 0 && !dead && isLocal){ //remote players don't die normally
|
||||
@@ -79,7 +81,7 @@ public class Player extends SyncEntity{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return !isDead() && super.collides(other) && !isAndroid;
|
||||
return !isDead() && super.collides(other) && !mech.flying;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -113,34 +115,33 @@ public class Player extends SyncEntity{
|
||||
|
||||
@Override
|
||||
public void drawSmooth(){
|
||||
if((debug && (!showPlayer || !showUI)) || (isAndroid && isLocal) || dead) return;
|
||||
if((debug && (!showPlayer || !showUI)) || dead) return;
|
||||
boolean snap = snapCamera && Settings.getBool("smoothcam") && Settings.getBool("pixelate") && isLocal;
|
||||
|
||||
String part = isAndroid ? "ship" : "mech";
|
||||
String mname = "mech-" + mech.name;
|
||||
|
||||
Shaders.outline.color.set(getColor());
|
||||
Shaders.outline.lighten = 0f;
|
||||
Shaders.outline.region = Draw.region(part + "-" + mech.name);
|
||||
Shaders.outline.region = Draw.region(mname);
|
||||
|
||||
Shaders.outline.apply();
|
||||
|
||||
if(!isAndroid) {
|
||||
for (int i : Mathf.signs) {
|
||||
Weapon weapon = i < 0 ? weaponLeft : weaponRight;
|
||||
tr.trns(angle - 90, 3*i, 2);
|
||||
float w = i > 0 ? -8 : 8;
|
||||
if(snap){
|
||||
Draw.rect(weapon.name + "-equip", (int)x + tr.x, (int)y + tr.y, w, 8, angle - 90);
|
||||
}else{
|
||||
Draw.rect(weapon.name + "-equip", x + tr.x, y + tr.y, w, 8, angle - 90);
|
||||
}
|
||||
for (int i : Mathf.signs) {
|
||||
Weapon weapon = i < 0 ? weaponLeft : weaponRight;
|
||||
tr.trns(rotation - 90, 3*i, 2);
|
||||
float w = i > 0 ? -8 : 8;
|
||||
if(snap){
|
||||
Draw.rect(weapon.name + "-equip", (int)x + tr.x, (int)y + tr.y, w, 8, rotation - 90);
|
||||
}else{
|
||||
Draw.rect(weapon.name + "-equip", x + tr.x, y + tr.y, w, 8, rotation - 90);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(snap){
|
||||
Draw.rect(part + "-" + mech.name, (int)x, (int)y, angle-90);
|
||||
Draw.rect(mname, (int)x, (int)y, rotation -90);
|
||||
}else{
|
||||
Draw.rect(part + "-" + mech.name, x, y, angle-90);
|
||||
Draw.rect(mname, x, y, rotation -90);
|
||||
}
|
||||
|
||||
Graphics.flush();
|
||||
@@ -148,16 +149,25 @@ public class Player extends SyncEntity{
|
||||
|
||||
@Override
|
||||
public void update(){
|
||||
if(!isLocal || isAndroid){
|
||||
if(isAndroid && isLocal){
|
||||
angle = Mathf.slerpDelta(angle, targetAngle, 0.2f);
|
||||
}
|
||||
if(!isLocal) interpolate();
|
||||
if(!isLocal){
|
||||
interpolate();
|
||||
return;
|
||||
}
|
||||
|
||||
if(isDead()) return;
|
||||
|
||||
if(mech.flying){
|
||||
updateFlying();
|
||||
}else{
|
||||
updateMech();
|
||||
}
|
||||
|
||||
x = Mathf.clamp(x, 0, world.width() * tilesize);
|
||||
y = Mathf.clamp(y, 0, world.height() * tilesize);
|
||||
}
|
||||
|
||||
protected void updateMech(){
|
||||
|
||||
Tile tile = world.tileWorld(x, y);
|
||||
|
||||
//if player is in solid block
|
||||
@@ -175,14 +185,14 @@ public class Player extends SyncEntity{
|
||||
if(ui.chatfrag.chatOpen()) return;
|
||||
|
||||
dashing = Inputs.keyDown("dash");
|
||||
|
||||
|
||||
float speed = dashing ? (debug ? Player.dashSpeed * 5f : Player.dashSpeed) : Player.speed;
|
||||
|
||||
|
||||
if(health < maxhealth && timer.get(timerRegen, 20))
|
||||
health ++;
|
||||
|
||||
health = Mathf.clamp(health, -1, maxhealth);
|
||||
|
||||
|
||||
movement.set(0, 0);
|
||||
|
||||
float xa = Inputs.getAxis("move_x");
|
||||
@@ -192,7 +202,7 @@ public class Player extends SyncEntity{
|
||||
|
||||
movement.y += ya*speed;
|
||||
movement.x += xa*speed;
|
||||
|
||||
|
||||
boolean shooting = !Inputs.keyDown("dash") && Inputs.keyDown("shoot") && control.input().recipe == null
|
||||
&& !ui.hasMouse() && !control.input().onConfigurable();
|
||||
|
||||
@@ -200,30 +210,31 @@ public class Player extends SyncEntity{
|
||||
weaponLeft.update(player, true);
|
||||
weaponRight.update(player, false);
|
||||
}
|
||||
|
||||
|
||||
if(dashing && timer.get(timerDash, 3) && movement.len() > 0){
|
||||
Effects.effect(Fx.dashsmoke, x + Angles.trnsx(angle + 180f, 3f), y + Angles.trnsy(angle + 180f, 3f));
|
||||
Effects.effect(Fx.dashsmoke, x + Angles.trnsx(rotation + 180f, 3f), y + Angles.trnsy(rotation + 180f, 3f));
|
||||
}
|
||||
|
||||
|
||||
movement.limit(speed);
|
||||
|
||||
|
||||
if(!noclip){
|
||||
move(movement.x*Timers.delta(), movement.y*Timers.delta());
|
||||
}else{
|
||||
x += movement.x*Timers.delta();
|
||||
y += movement.y*Timers.delta();
|
||||
}
|
||||
|
||||
|
||||
if(!shooting){
|
||||
if(!movement.isZero())
|
||||
angle = Mathf.slerpDelta(angle, movement.angle(), 0.13f);
|
||||
rotation = Mathf.slerpDelta(rotation, movement.angle(), 0.13f);
|
||||
}else{
|
||||
float angle = Angles.mouseAngle(x, y);
|
||||
this.angle = Mathf.slerpDelta(this.angle, angle, 0.1f);
|
||||
this.rotation = Mathf.slerpDelta(this.rotation, angle, 0.1f);
|
||||
}
|
||||
}
|
||||
|
||||
x = Mathf.clamp(x, 0, world.width() * tilesize);
|
||||
y = Mathf.clamp(y, 0, world.height() * tilesize);
|
||||
protected void updateFlying(){
|
||||
rotation = Mathf.slerpDelta(rotation, targetAngle, 0.2f);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -233,7 +244,7 @@ public class Player extends SyncEntity{
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Player{" + id + ", android=" + isAndroid + ", local=" + isLocal + ", " + x + ", " + y + "}\n";
|
||||
return "Player{" + id + ", mech=" + mech.name + ", local=" + isLocal + ", " + x + ", " + y + "}\n";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -242,7 +253,7 @@ public class Player extends SyncEntity{
|
||||
buffer.put(name.getBytes());
|
||||
buffer.put(weaponLeft.id);
|
||||
buffer.put(weaponRight.id);
|
||||
buffer.put(isAndroid ? 1 : (byte)0);
|
||||
buffer.put(mech.id);
|
||||
buffer.put(isAdmin ? 1 : (byte)0);
|
||||
buffer.putInt(Color.rgba8888(color));
|
||||
buffer.putFloat(x);
|
||||
@@ -255,9 +266,9 @@ public class Player extends SyncEntity{
|
||||
byte[] n = new byte[nlength];
|
||||
buffer.get(n);
|
||||
name = new String(n);
|
||||
weaponLeft = (Weapon) Upgrade.getByID(buffer.get());
|
||||
weaponRight = (Weapon) Upgrade.getByID(buffer.get());
|
||||
isAndroid = buffer.get() == 1;
|
||||
weaponLeft = Upgrade.getByID(buffer.get());
|
||||
weaponRight = Upgrade.getByID(buffer.get());
|
||||
mech = Upgrade.getByID(buffer.get());
|
||||
isAdmin = buffer.get() == 1;
|
||||
color.set(buffer.getInt());
|
||||
x = buffer.getFloat();
|
||||
@@ -274,7 +285,7 @@ public class Player extends SyncEntity{
|
||||
data.putFloat(interpolator.target.x);
|
||||
data.putFloat(interpolator.target.y);
|
||||
}
|
||||
data.putFloat(angle);
|
||||
data.putFloat(rotation);
|
||||
data.putShort((short)health);
|
||||
data.put((byte)(dashing ? 1 : 0));
|
||||
}
|
||||
@@ -299,10 +310,10 @@ public class Player extends SyncEntity{
|
||||
|
||||
Interpolator i = interpolator;
|
||||
|
||||
float tx = x + Angles.trnsx(angle + 180f, 4f);
|
||||
float ty = y + Angles.trnsy(angle + 180f, 4f);
|
||||
float tx = x + Angles.trnsx(rotation + 180f, 4f);
|
||||
float ty = y + Angles.trnsy(rotation + 180f, 4f);
|
||||
|
||||
if(isAndroid && i.target.dst(i.last) > 2f && timer.get(timerDash, 1)){
|
||||
if(mech.flying && i.target.dst(i.last) > 2f && timer.get(timerDash, 1)){
|
||||
Effects.effect(Fx.dashsmoke, tx, ty);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,9 +3,7 @@ package io.anuke.mindustry.entities;
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.math.Vector3;
|
||||
import com.badlogic.gdx.utils.ObjectIntMap;
|
||||
import com.badlogic.gdx.utils.TimeUtils;
|
||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.entities.DestructibleEntity;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
@@ -14,24 +12,13 @@ import java.nio.ByteBuffer;
|
||||
|
||||
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{
|
||||
private static ObjectIntMap<Class<? extends SyncEntity>> writeSizes = new ObjectIntMap<>();
|
||||
|
||||
protected transient Interpolator interpolator = new Interpolator();
|
||||
|
||||
//smoothed position/angle
|
||||
/**smoothed position and rotation*/
|
||||
private Vector3 spos = new Vector3();
|
||||
|
||||
public float angle;
|
||||
|
||||
static{
|
||||
setWriteSize(Enemy.class, 4 + 4 + 2 + 2);
|
||||
setWriteSize(Player.class, 4 + 4 + 4 + 2 + 1);
|
||||
}
|
||||
|
||||
public static boolean isSmoothing(){
|
||||
return threads.isEnabled() && threads.getFPS() <= Gdx.graphics.getFramesPerSecond() / 2f;
|
||||
}
|
||||
/**the general rotation.*/
|
||||
public float rotation;
|
||||
|
||||
public abstract void writeSpawn(ByteBuffer data);
|
||||
public abstract void readSpawn(ByteBuffer data);
|
||||
@@ -39,56 +26,47 @@ public abstract class SyncEntity extends DestructibleEntity{
|
||||
public abstract void write(ByteBuffer data);
|
||||
public abstract void read(ByteBuffer data, long time);
|
||||
|
||||
/**Interpolate everything needed. Should be called in update() for non-local entities.*/
|
||||
public void interpolate(){
|
||||
interpolator.update();
|
||||
|
||||
x = interpolator.pos.x;
|
||||
y = interpolator.pos.y;
|
||||
angle = interpolator.angle;
|
||||
rotation = interpolator.rotation;
|
||||
}
|
||||
|
||||
/**Same as draw, but for interpolated drawing at low tick speeds.*/
|
||||
public abstract void drawSmooth();
|
||||
|
||||
/**Do not override, use drawSmooth instead.*/
|
||||
@Override
|
||||
public final void draw(){
|
||||
final float x = this.x, y = this.y, angle = this.angle;
|
||||
final float x = this.x, y = this.y, rotation = this.rotation;
|
||||
|
||||
//interpolates data at low tick speeds.
|
||||
if(isSmoothing()){
|
||||
if(Vector2.dst(spos.x, spos.y, x, y) > 128){
|
||||
spos.set(x, y, angle);
|
||||
spos.set(x, y, rotation);
|
||||
}
|
||||
|
||||
this.x = spos.x = Mathf.lerpDelta(spos.x, x, 0.2f);
|
||||
this.y = spos.y = Mathf.lerpDelta(spos.y, y, 0.2f);
|
||||
this.angle = spos.z = Mathf.slerpDelta(spos.z, angle, 0.3f);
|
||||
this.rotation = spos.z = Mathf.slerpDelta(spos.z, rotation, 0.3f);
|
||||
}
|
||||
|
||||
drawSmooth();
|
||||
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.angle = angle;
|
||||
this.rotation = rotation;
|
||||
}
|
||||
|
||||
/**Returns smoothed position. x = x, y = y, z = rotation.*/
|
||||
public Vector3 getDrawPosition(){
|
||||
return isSmoothing() ? spos : spos.set(x, y, angle);
|
||||
}
|
||||
|
||||
public void drawSmooth(){}
|
||||
|
||||
public int getWriteSize(){
|
||||
return getWriteSize(getClass());
|
||||
}
|
||||
|
||||
public static int getWriteSize(Class<? extends SyncEntity> type){
|
||||
int i = writeSizes.get(type, -1);
|
||||
if(i == -1) throw new RuntimeException("Write size for class \"" + type + "\" is not defined!");
|
||||
return i;
|
||||
}
|
||||
|
||||
protected static void setWriteSize(Class<? extends SyncEntity> type, int size){
|
||||
writeSizes.put(type, size);
|
||||
return isSmoothing() ? spos : spos.set(x, y, rotation);
|
||||
}
|
||||
|
||||
/**Set position and interpolator position.*/
|
||||
public <T extends SyncEntity> T setNet(float x, float y){
|
||||
set(x, y);
|
||||
interpolator.target.set(x, y);
|
||||
@@ -98,6 +76,10 @@ public abstract class SyncEntity extends DestructibleEntity{
|
||||
return (T)this;
|
||||
}
|
||||
|
||||
private static boolean isSmoothing(){
|
||||
return threads.isEnabled() && threads.getFPS() <= Gdx.graphics.getFramesPerSecond() / 2f;
|
||||
}
|
||||
|
||||
public static class Interpolator {
|
||||
//used for movement
|
||||
public Vector2 target = new Vector2();
|
||||
@@ -108,7 +90,7 @@ public abstract class SyncEntity extends DestructibleEntity{
|
||||
|
||||
//current state
|
||||
public Vector2 pos = new Vector2();
|
||||
public float angle;
|
||||
public float rotation;
|
||||
|
||||
public void read(float cx, float cy, float x, float y, float angle, long sent){
|
||||
targetrot = angle;
|
||||
@@ -124,7 +106,7 @@ public abstract class SyncEntity extends DestructibleEntity{
|
||||
|
||||
Mathf.lerp2(pos.set(last), target, time);
|
||||
|
||||
angle = Mathf.slerpDelta(angle, targetrot, 0.6f);
|
||||
rotation = Mathf.slerpDelta(rotation, targetrot, 0.6f);
|
||||
|
||||
if(target.dst(pos) > 128){
|
||||
pos.set(target);
|
||||
|
||||
15
core/src/io/anuke/mindustry/entities/Unit.java
Normal file
15
core/src/io/anuke/mindustry/entities/Unit.java
Normal file
@@ -0,0 +1,15 @@
|
||||
package io.anuke.mindustry.entities;
|
||||
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
|
||||
public abstract class Unit extends SyncEntity {
|
||||
//total duration of hit effect
|
||||
public static final float hitDuration = 5f;
|
||||
|
||||
public Team team = Team.blue;
|
||||
public Vector2 velocity = new Vector2();
|
||||
public float hitTime;
|
||||
|
||||
public abstract float getMass();
|
||||
}
|
||||
@@ -45,7 +45,7 @@ public class DamageArea{
|
||||
rect.height += expand*2;
|
||||
|
||||
Consumer<SolidEntity> cons = e -> {
|
||||
if(e == owner || (e instanceof Player && ((Player)e).isAndroid)) return;
|
||||
if(e == owner) return;
|
||||
DestructibleEntity enemy = (DestructibleEntity) e;
|
||||
Rectangle other = enemy.hitbox.getRect(enemy.x, enemy.y);
|
||||
other.y -= expand;
|
||||
@@ -69,7 +69,7 @@ public class DamageArea{
|
||||
damage(true, x, y, radius, damage);
|
||||
|
||||
for(Player player : playerGroup.all()){
|
||||
if(player.isAndroid) continue;
|
||||
//if(player.isAndroid) continue;
|
||||
int amount = calculateDamage(x, y, player.x, player.y, radius, damage);
|
||||
player.damage(amount);
|
||||
}
|
||||
@@ -78,7 +78,7 @@ public class DamageArea{
|
||||
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 || (entity instanceof Player && ((Player)entity).isAndroid)){
|
||||
if(enemy.distanceTo(x, y) > radius){
|
||||
return;
|
||||
}
|
||||
int amount = calculateDamage(x, y, enemy.x, enemy.y, radius, damage);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.anuke.mindustry.entities.effect;
|
||||
|
||||
import com.badlogic.gdx.math.Interpolation;
|
||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||
import io.anuke.mindustry.entities.enemies.BaseUnit;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.mindustry.world.blocks.types.defense.ShieldBlock;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
@@ -55,7 +55,7 @@ public class Shield extends Entity{
|
||||
|
||||
Entities.getNearby(bulletGroup, x, y, block.shieldRadius * 2*uptime + 10, entity->{
|
||||
BulletEntity bullet = (BulletEntity)entity;
|
||||
if((bullet.owner instanceof Enemy || hitPlayers)){
|
||||
if((bullet.owner instanceof BaseUnit || hitPlayers)){
|
||||
|
||||
float dst = entity.distanceTo(this);
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.ObjectSet;
|
||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||
import io.anuke.mindustry.entities.enemies.BaseUnit;
|
||||
import io.anuke.mindustry.graphics.Fx;
|
||||
import io.anuke.ucore.core.Effects;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
@@ -19,7 +19,7 @@ import static io.anuke.mindustry.Vars.enemyGroup;
|
||||
|
||||
public class TeslaOrb extends Entity{
|
||||
private Array<Vector2> points = new Array<>();
|
||||
private ObjectSet<Enemy> hit = new ObjectSet<>();
|
||||
private ObjectSet<BaseUnit> hit = new ObjectSet<>();
|
||||
private int damage = 0;
|
||||
private float range = 0;
|
||||
private float lifetime = 30f;
|
||||
@@ -47,10 +47,10 @@ public class TeslaOrb extends Entity{
|
||||
Array<SolidEntity> enemies = Entities.getNearby(enemyGroup, curx, cury, range*2f);
|
||||
|
||||
for(SolidEntity entity : enemies){
|
||||
if(entity != null && entity.distanceTo(curx, cury) < range && !hit.contains((Enemy)entity)){
|
||||
hit.add((Enemy)entity);
|
||||
if(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((Enemy)entity);
|
||||
damageEnemy((BaseUnit)entity);
|
||||
curx = entity.x;
|
||||
cury = entity.y;
|
||||
break;
|
||||
@@ -63,7 +63,7 @@ public class TeslaOrb extends Entity{
|
||||
}
|
||||
}
|
||||
|
||||
void damageEnemy(Enemy enemy){
|
||||
void damageEnemy(BaseUnit enemy){
|
||||
enemy.damage(damage);
|
||||
Effects.effect(Fx.laserhit, enemy.x + Mathf.range(2f), enemy.y + Mathf.range(2f));
|
||||
}
|
||||
|
||||
@@ -1,50 +1,31 @@
|
||||
package io.anuke.mindustry.entities.enemies;
|
||||
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import io.anuke.mindustry.entities.Bullet;
|
||||
import io.anuke.mindustry.entities.BulletType;
|
||||
import io.anuke.mindustry.entities.SyncEntity;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.mindustry.net.NetEvents;
|
||||
import io.anuke.mindustry.entities.Unit;
|
||||
import io.anuke.ucore.entities.Entity;
|
||||
import io.anuke.ucore.entities.SolidEntity;
|
||||
import io.anuke.ucore.graphics.Draw;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
import io.anuke.ucore.util.Timer;
|
||||
import io.anuke.ucore.util.Translator;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import static io.anuke.mindustry.Vars.enemyGroup;
|
||||
|
||||
public class Enemy extends SyncEntity {
|
||||
public EnemyType type;
|
||||
|
||||
public class BaseUnit extends Unit {
|
||||
public UnitType type;
|
||||
public Timer timer = new Timer(5);
|
||||
public float idletime = 0f;
|
||||
public int lane;
|
||||
public int node = -1;
|
||||
|
||||
public Enemy spawner;
|
||||
public int spawned;
|
||||
|
||||
public Vector2 velocity = new Vector2();
|
||||
public Vector2 totalMove = new Vector2();
|
||||
public Vector2 tpos = new Vector2(-999, -999);
|
||||
public Entity target;
|
||||
public float hitTime;
|
||||
public int tier = 1;
|
||||
|
||||
public TextureRegion region;
|
||||
public Translator tr = new Translator();
|
||||
|
||||
public Enemy(EnemyType type){
|
||||
public BaseUnit(UnitType type){
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**internal constructor used for deserialization, DO NOT USE*/
|
||||
public Enemy(){}
|
||||
public BaseUnit(){}
|
||||
|
||||
@Override
|
||||
public float getMass() {
|
||||
return type.mass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(){
|
||||
@@ -68,13 +49,13 @@ public class Enemy extends SyncEntity {
|
||||
|
||||
@Override
|
||||
public boolean collides(SolidEntity other){
|
||||
return (other instanceof Bullet) && !(((Bullet) other).owner instanceof Enemy);
|
||||
return (other instanceof Bullet) && !(((Bullet) other).owner instanceof BaseUnit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void damage(int amount){
|
||||
super.damage(amount);
|
||||
hitTime = EnemyType.hitDuration;
|
||||
hitTime = hitDuration;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -91,22 +72,16 @@ public class Enemy extends SyncEntity {
|
||||
public void added(){
|
||||
hitbox.setSize(type.hitsize);
|
||||
hitboxTile.setSize(type.hitsizeTile);
|
||||
maxhealth = type.health * tier;
|
||||
region = Draw.region(type.name + "-t" + Mathf.clamp(tier, 1, 3));
|
||||
|
||||
heal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enemy add(){
|
||||
public BaseUnit add(){
|
||||
return add(enemyGroup);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeSpawn(ByteBuffer buffer) {
|
||||
buffer.put(type.id);
|
||||
buffer.put((byte)lane);
|
||||
buffer.put((byte)tier);
|
||||
buffer.putFloat(x);
|
||||
buffer.putFloat(y);
|
||||
buffer.putShort((short)health);
|
||||
@@ -114,9 +89,7 @@ public class Enemy extends SyncEntity {
|
||||
|
||||
@Override
|
||||
public void readSpawn(ByteBuffer buffer) {
|
||||
type = EnemyType.getByID(buffer.get());
|
||||
lane = buffer.get();
|
||||
tier = buffer.get();
|
||||
type = UnitType.getByID(buffer.get());
|
||||
x = buffer.getFloat();
|
||||
y = buffer.getFloat();
|
||||
health = buffer.getShort();
|
||||
@@ -127,38 +100,18 @@ public class Enemy extends SyncEntity {
|
||||
public void write(ByteBuffer data) {
|
||||
data.putFloat(x);
|
||||
data.putFloat(y);
|
||||
data.putShort((short)(angle*2));
|
||||
data.putShort((short)(rotation *2));
|
||||
data.putShort((short)health);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(ByteBuffer data, long time) {
|
||||
|
||||
float x = data.getFloat();
|
||||
float y = data.getFloat();
|
||||
short angle = data.getShort();
|
||||
short health = data.getShort();
|
||||
|
||||
this.health = health;
|
||||
|
||||
interpolator.read(this.x, this.y, x, y, angle/2f, time);
|
||||
}
|
||||
|
||||
public void shoot(BulletType bullet){
|
||||
shoot(bullet, 0);
|
||||
}
|
||||
|
||||
public void shoot(BulletType bullet, float rotation){
|
||||
|
||||
if(!(Net.client())) {
|
||||
tr.trns(angle + rotation, type.length);
|
||||
Bullet out = new Bullet(bullet, this, x + tr.x, y + tr.y, this.angle + rotation).add();
|
||||
out.damage = (int) ((bullet.damage * (1 + (tier - 1) * 1f)));
|
||||
type.onShoot(this, bullet, rotation);
|
||||
|
||||
if(Net.server()){
|
||||
NetEvents.handleBullet(bullet, this, x + tr.x, y + tr.y, this.angle + rotation, (short)out.damage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,289 +0,0 @@
|
||||
package io.anuke.mindustry.entities.enemies;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import io.anuke.mindustry.entities.BulletType;
|
||||
import io.anuke.mindustry.entities.Player;
|
||||
import io.anuke.mindustry.entities.TileEntity;
|
||||
import io.anuke.mindustry.graphics.Fx;
|
||||
import io.anuke.mindustry.graphics.Shaders;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.mindustry.net.NetEvents;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.mindustry.world.blocks.Blocks;
|
||||
import io.anuke.ucore.core.Effects;
|
||||
import io.anuke.ucore.core.Graphics;
|
||||
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.Mathf;
|
||||
import io.anuke.ucore.util.Strings;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class EnemyType {
|
||||
|
||||
//TODO documentation, comments
|
||||
private static byte lastid = 0;
|
||||
private static Array<EnemyType> types = new Array<>();
|
||||
|
||||
public final static Color[] tierColors = {
|
||||
Color.valueOf("ffe451"), Color.valueOf("f48e20"), Color.valueOf("ff6757"),
|
||||
Color.valueOf("ff2d86"), Color.valueOf("cb2dff"), Color.valueOf("362020") };
|
||||
public final static int maxtier = tierColors.length;
|
||||
public final static float maxIdleLife = 60f*2f; //2 seconds idle = death
|
||||
public final static float hitDuration = 5f;
|
||||
|
||||
public final String name;
|
||||
public final byte id;
|
||||
|
||||
protected int timeid;
|
||||
protected int health = 60;
|
||||
protected float hitsize = 5f;
|
||||
protected float hitsizeTile = 4f;
|
||||
protected float speed = 0.4f;
|
||||
protected float reload = 32;
|
||||
protected float range = 60;
|
||||
protected float length = 4;
|
||||
protected float rotatespeed = 0.1f;
|
||||
protected float turretrotatespeed = 0.2f;
|
||||
protected boolean alwaysRotate = false;
|
||||
protected BulletType bullet = BulletType.small;
|
||||
protected String shootsound = "enemyshoot";
|
||||
protected boolean targetCore = false;
|
||||
protected boolean stopNearCore = true;
|
||||
protected boolean targetClient = false;
|
||||
protected float mass = 1f;
|
||||
|
||||
protected final int timerTarget = timeid ++;
|
||||
protected final int timerReload = timeid ++;
|
||||
protected final int timerReset = timeid ++;
|
||||
|
||||
protected final Vector2 shift = new Vector2();
|
||||
protected final Vector2 move = new Vector2();
|
||||
protected final Vector2 calc = new Vector2();
|
||||
|
||||
public EnemyType(String name){
|
||||
this.id = lastid++;
|
||||
this.name = name;
|
||||
types.add(this);
|
||||
}
|
||||
|
||||
public void draw(Enemy enemy){
|
||||
Shaders.outline.color.set(tierColors[enemy.tier - 1]);
|
||||
Shaders.outline.lighten = Mathf.clamp(enemy.hitTime/hitDuration);
|
||||
Shaders.outline.region = enemy.region;
|
||||
|
||||
Shaders.outline.apply();
|
||||
|
||||
Draw.rect(enemy.region, enemy.x, enemy.y, enemy.angle - 90);
|
||||
Draw.color();
|
||||
|
||||
Graphics.flush();
|
||||
|
||||
if(isCalculating(enemy)){
|
||||
Draw.color(Color.SKY);
|
||||
Lines.polySeg(20, 0, 4, enemy.x, enemy.y, 11f, Timers.time() * 2f + enemy.id*52f);
|
||||
Lines.polySeg(20, 0, 4, enemy.x, enemy.y, 11f, Timers.time() * 2f + enemy.id*52f + 180f);
|
||||
Draw.color();
|
||||
}
|
||||
|
||||
if(showPaths){
|
||||
Draw.tscl(0.25f);
|
||||
Draw.text((int)enemy.idletime + " " + enemy.node + " " + enemy.id + "\n" + Strings.toFixed(enemy.totalMove.x, 2) + ", "
|
||||
+ Strings.toFixed(enemy.totalMove.x, 2), enemy.x, enemy.y);
|
||||
Draw.tscl(fontscale);
|
||||
}
|
||||
|
||||
Shaders.outline.lighten = 0f;
|
||||
}
|
||||
|
||||
public void drawOver(Enemy enemy){ }
|
||||
|
||||
public void update(Enemy enemy){
|
||||
float lastx = enemy.x, lasty = enemy.y;
|
||||
if(enemy.hitTime > 0){
|
||||
enemy.hitTime -= Timers.delta();
|
||||
}
|
||||
|
||||
if(enemy.lane >= world.getSpawns().size || enemy.lane < 0) enemy.lane = 0;
|
||||
|
||||
boolean waiting = enemy.lane >= world.getSpawns().size || enemy.lane < 0
|
||||
|| world.getSpawns().get(enemy.lane).pathTiles == null || enemy.node <= 0;
|
||||
|
||||
move(enemy);
|
||||
|
||||
enemy.velocity.set(enemy.x - lastx, enemy.y - lasty).scl(1f / Timers.delta());
|
||||
enemy.totalMove.add(enemy.velocity);
|
||||
|
||||
float minv = 0.07f;
|
||||
|
||||
if(enemy.timer.get(timerReset, 80)){
|
||||
enemy.totalMove.setZero();
|
||||
}
|
||||
|
||||
if(enemy.velocity.len() < minv && !waiting && enemy.target == null){
|
||||
enemy.idletime += Timers.delta();
|
||||
}else{
|
||||
enemy.idletime = 0;
|
||||
}
|
||||
|
||||
if(enemy.timer.getTime(timerReset) > 50 && enemy.totalMove.len() < 0.2f && !waiting && enemy.target == null){
|
||||
enemy.idletime = 999999f;
|
||||
}
|
||||
|
||||
Tile tile = world.tileWorld(enemy.x, enemy.y);
|
||||
if(tile != null && tile.floor().liquid && tile.block() == Blocks.air){
|
||||
enemy.damage(enemy.health+1); //drown
|
||||
}
|
||||
|
||||
if(Float.isNaN(enemy.angle)){
|
||||
enemy.angle = 0;
|
||||
}
|
||||
|
||||
if(enemy.target == null || alwaysRotate){
|
||||
enemy.angle = Mathf.slerpDelta(enemy.angle, enemy.velocity.angle(), rotatespeed);
|
||||
}else{
|
||||
enemy.angle = Mathf.slerpDelta(enemy.angle, enemy.angleTo(enemy.target), turretrotatespeed);
|
||||
}
|
||||
|
||||
enemy.x = Mathf.clamp(enemy.x, 0, world.width() * tilesize);
|
||||
enemy.y = Mathf.clamp(enemy.y, 0, world.height() * tilesize);
|
||||
}
|
||||
|
||||
public void move(Enemy enemy){
|
||||
if(Net.client()){
|
||||
enemy.interpolate();
|
||||
if(targetClient) updateTargeting(enemy, false);
|
||||
return;
|
||||
}
|
||||
|
||||
float speed = this.speed + 0.04f * enemy.tier;
|
||||
float range = this.range + enemy.tier * 5;
|
||||
|
||||
Tile core = world.getCore();
|
||||
|
||||
if(core == null) return;
|
||||
|
||||
if(enemy.idletime > maxIdleLife && enemy.node > 0){
|
||||
enemy.onDeath();
|
||||
return;
|
||||
}
|
||||
|
||||
boolean nearCore = enemy.distanceTo(core.worldx(), core.worldy()) <= range - 18f && stopNearCore;
|
||||
Vector2 vec;
|
||||
|
||||
if(nearCore){
|
||||
vec = move.setZero();
|
||||
if(targetCore) enemy.target = core.entity;
|
||||
}else{
|
||||
vec = world.pathfinder().find(enemy);
|
||||
vec.sub(enemy.x, enemy.y).limit(speed);
|
||||
}
|
||||
|
||||
shift.setZero();
|
||||
float shiftRange = enemy.hitbox.width + 2f;
|
||||
float avoidRange = shiftRange + 4f;
|
||||
float attractRange = avoidRange + 7f;
|
||||
float avoidSpeed = this.speed/2.7f;
|
||||
|
||||
Entities.getNearby(enemyGroup, enemy.x, enemy.y, range, en -> {
|
||||
Enemy other = (Enemy)en;
|
||||
if(other == enemy) return;
|
||||
float dst = other.distanceTo(enemy);
|
||||
|
||||
if(dst < shiftRange){
|
||||
float scl = Mathf.clamp(1.4f - dst / shiftRange) * mass * 1f/mass;
|
||||
shift.add((enemy.x - other.x) * scl, (enemy.y - other.y) * scl);
|
||||
}else if(dst < avoidRange){
|
||||
calc.set((enemy.x - other.x), (enemy.y - other.y)).setLength(avoidSpeed);
|
||||
shift.add(calc.scl(1.1f));
|
||||
}else if(dst < attractRange && !nearCore && !isCalculating(enemy)){
|
||||
calc.set((enemy.x - other.x), (enemy.y - other.y)).setLength(avoidSpeed);
|
||||
shift.add(calc.scl(-1));
|
||||
}
|
||||
});
|
||||
|
||||
shift.limit(1f);
|
||||
vec.add(shift.scl(0.5f));
|
||||
|
||||
enemy.move(vec.x * Timers.delta(), vec.y * Timers.delta());
|
||||
|
||||
updateTargeting(enemy, nearCore);
|
||||
|
||||
behavior(enemy);
|
||||
}
|
||||
|
||||
public void behavior(Enemy enemy){}
|
||||
|
||||
public void updateTargeting(Enemy enemy, boolean nearCore){
|
||||
if(enemy.target != null && enemy.target instanceof TileEntity && ((TileEntity)enemy.target).dead){
|
||||
enemy.target = null;
|
||||
}
|
||||
|
||||
if(enemy.timer.get(timerTarget, 15) && !nearCore){
|
||||
enemy.target = world.findTileTarget(enemy.x, enemy.y, null, range, false);
|
||||
|
||||
//no tile found
|
||||
if(enemy.target == null){
|
||||
enemy.target = Entities.getClosest(playerGroup, enemy.x, enemy.y, range, e -> !((Player)e).isAndroid &&
|
||||
!((Player)e).isDead());
|
||||
}
|
||||
}else if(nearCore){
|
||||
enemy.target = world.getCore().entity;
|
||||
}
|
||||
|
||||
if(enemy.target != null && bullet != null){
|
||||
updateShooting(enemy);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateShooting(Enemy enemy){
|
||||
float reload = this.reload / Math.max(enemy.tier / 1.5f, 1f);
|
||||
|
||||
if(enemy.timer.get(timerReload, reload)){
|
||||
shoot(enemy);
|
||||
}
|
||||
}
|
||||
|
||||
public void shoot(Enemy enemy){
|
||||
enemy.shoot(bullet);
|
||||
if(shootsound != null) Effects.sound(shootsound, enemy);
|
||||
}
|
||||
|
||||
public void onShoot(Enemy enemy, BulletType type, float rotation){}
|
||||
|
||||
public void onDeath(Enemy enemy, boolean force){
|
||||
if(Net.server()){
|
||||
NetEvents.handleEnemyDeath(enemy);
|
||||
}
|
||||
|
||||
if(!Net.client() || force) {
|
||||
Effects.effect(Fx.explosion, enemy);
|
||||
Effects.shake(3f, 4f, enemy);
|
||||
Effects.sound("bang2", enemy);
|
||||
enemy.remove();
|
||||
enemy.dead = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void removed(Enemy enemy){
|
||||
if(!enemy.dead){
|
||||
if(enemy.spawner != null){
|
||||
enemy.spawner.spawned --;
|
||||
}else{
|
||||
state.enemies --;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isCalculating(Enemy enemy){
|
||||
return enemy.node < 0 && !Net.client();
|
||||
}
|
||||
|
||||
public static EnemyType getByID(byte id){
|
||||
return types.get(id);
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package io.anuke.mindustry.entities.enemies;
|
||||
|
||||
import io.anuke.mindustry.entities.enemies.types.BlastType;
|
||||
import io.anuke.mindustry.entities.enemies.types.EmpType;
|
||||
import io.anuke.mindustry.entities.enemies.types.FastType;
|
||||
import io.anuke.mindustry.entities.enemies.types.FlamerType;
|
||||
import io.anuke.mindustry.entities.enemies.types.FortressType;
|
||||
import io.anuke.mindustry.entities.enemies.types.HealerType;
|
||||
import io.anuke.mindustry.entities.enemies.types.MortarType;
|
||||
import io.anuke.mindustry.entities.enemies.types.RapidType;
|
||||
import io.anuke.mindustry.entities.enemies.types.*;
|
||||
import io.anuke.mindustry.entities.enemies.types.TankType;
|
||||
import io.anuke.mindustry.entities.enemies.types.TargetType;
|
||||
import io.anuke.mindustry.entities.enemies.types.TitanType;
|
||||
|
||||
public class EnemyTypes {
|
||||
public static final EnemyType
|
||||
|
||||
standard = new StandardType(),
|
||||
fast = new FastType(),
|
||||
rapid = new RapidType(),
|
||||
flamer = new FlamerType(),
|
||||
tank = new TankType(),
|
||||
blast = new BlastType(),
|
||||
mortar = new MortarType(),
|
||||
healer = new HealerType(),
|
||||
titan = new TitanType(),
|
||||
emp = new EmpType(),
|
||||
fortress = new FortressType(),
|
||||
target = new TargetType();
|
||||
|
||||
}
|
||||
81
core/src/io/anuke/mindustry/entities/enemies/UnitType.java
Normal file
81
core/src/io/anuke/mindustry/entities/enemies/UnitType.java
Normal file
@@ -0,0 +1,81 @@
|
||||
package io.anuke.mindustry.entities.enemies;
|
||||
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import io.anuke.mindustry.entities.BulletType;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
|
||||
import static io.anuke.mindustry.Vars.tilesize;
|
||||
import static io.anuke.mindustry.Vars.world;
|
||||
|
||||
public class UnitType {
|
||||
private static byte lastid = 0;
|
||||
private static Array<UnitType> types = new Array<>();
|
||||
|
||||
public final String name;
|
||||
public final byte id;
|
||||
|
||||
protected int health = 60;
|
||||
protected float hitsize = 5f;
|
||||
protected float hitsizeTile = 4f;
|
||||
protected float speed = 0.4f;
|
||||
protected float range = 60;
|
||||
protected float rotatespeed = 0.1f;
|
||||
protected float mass = 1f;
|
||||
protected boolean isFlying;
|
||||
|
||||
public UnitType(String name){
|
||||
this.id = lastid++;
|
||||
this.name = name;
|
||||
types.add(this);
|
||||
}
|
||||
|
||||
public void draw(BaseUnit enemy){
|
||||
//TODO
|
||||
}
|
||||
|
||||
public void drawOver(BaseUnit enemy){
|
||||
//TODO
|
||||
}
|
||||
|
||||
public void update(BaseUnit enemy){
|
||||
//TODO
|
||||
enemy.x = Mathf.clamp(enemy.x, 0, world.width() * tilesize);
|
||||
enemy.y = Mathf.clamp(enemy.y, 0, world.height() * tilesize);
|
||||
}
|
||||
|
||||
public void move(BaseUnit enemy){
|
||||
//TODO
|
||||
}
|
||||
|
||||
public void behavior(BaseUnit enemy){
|
||||
//TODO
|
||||
}
|
||||
|
||||
public void updateTargeting(BaseUnit enemy){
|
||||
//TODO
|
||||
}
|
||||
|
||||
public void updateShooting(BaseUnit enemy){
|
||||
//TODO
|
||||
}
|
||||
|
||||
public void shoot(BaseUnit enemy){
|
||||
//TODO
|
||||
}
|
||||
|
||||
public void onShoot(BaseUnit enemy, BulletType type, float rotation){
|
||||
//TODO
|
||||
}
|
||||
|
||||
public void onDeath(BaseUnit enemy, boolean force){
|
||||
//TODO
|
||||
}
|
||||
|
||||
public void removed(BaseUnit enemy){
|
||||
//TODO
|
||||
}
|
||||
|
||||
public static UnitType getByID(byte id){
|
||||
return types.get(id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package io.anuke.mindustry.entities.enemies;
|
||||
|
||||
public class UnitTypes {
|
||||
//TODO list types here.
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
package io.anuke.mindustry.entities.enemies.types;
|
||||
|
||||
import io.anuke.mindustry.entities.Bullet;
|
||||
import io.anuke.mindustry.entities.BulletType;
|
||||
import io.anuke.mindustry.entities.TileEntity;
|
||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||
|
||||
import static io.anuke.mindustry.Vars.tilesize;
|
||||
|
||||
public class BlastType extends EnemyType {
|
||||
|
||||
public BlastType() {
|
||||
super("blastenemy");
|
||||
health = 30;
|
||||
speed = 0.8f;
|
||||
bullet = null;
|
||||
turretrotatespeed = 0f;
|
||||
mass = 0.8f;
|
||||
stopNearCore = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void behavior(Enemy enemy){
|
||||
|
||||
float range = 10f;
|
||||
float ox = 0, oy = 0;
|
||||
|
||||
if(enemy.target instanceof TileEntity){
|
||||
TileEntity e = (TileEntity)enemy.target;
|
||||
range = (e.tile.block().size * tilesize) /2f + 8f;
|
||||
ox = e.tile.block().getPlaceOffset().x;
|
||||
oy = e.tile.block().getPlaceOffset().y;
|
||||
}
|
||||
|
||||
if(enemy.target != null && enemy.target.distanceTo(enemy.x - ox, enemy.y - oy) < range){
|
||||
explode(enemy);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeath(Enemy enemy, boolean force){
|
||||
if(force) explode(enemy);
|
||||
super.onDeath(enemy, force);
|
||||
}
|
||||
|
||||
void explode(Enemy enemy){
|
||||
Bullet b = new Bullet(BulletType.blast, enemy, enemy.x, enemy.y, 0).add();
|
||||
b.damage = BulletType.blast.damage + (enemy.tier-1) * 40;
|
||||
enemy.damage(999);
|
||||
enemy.remove();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package io.anuke.mindustry.entities.enemies.types;
|
||||
|
||||
import io.anuke.mindustry.entities.BulletType;
|
||||
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||
|
||||
public class EmpType extends EnemyType {
|
||||
|
||||
public EmpType() {
|
||||
super("empenemy");
|
||||
|
||||
speed = 0.3f;
|
||||
reload = 70;
|
||||
health = 210;
|
||||
range = 80f;
|
||||
bullet = BulletType.emp;
|
||||
turretrotatespeed = 0.1f;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package io.anuke.mindustry.entities.enemies.types;
|
||||
|
||||
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||
|
||||
public class FastType extends EnemyType {
|
||||
|
||||
public FastType() {
|
||||
super("fastenemy");
|
||||
|
||||
speed = 0.73f;
|
||||
reload = 20;
|
||||
mass = 0.2f;
|
||||
|
||||
health = 50;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package io.anuke.mindustry.entities.enemies.types;
|
||||
|
||||
import io.anuke.mindustry.entities.BulletType;
|
||||
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||
|
||||
public class FlamerType extends EnemyType {
|
||||
|
||||
public FlamerType() {
|
||||
super("flamerenemy");
|
||||
|
||||
speed = 0.35f;
|
||||
health = 150;
|
||||
reload = 6;
|
||||
bullet = BulletType.flameshot;
|
||||
shootsound = "flame";
|
||||
mass = 1.5f;
|
||||
range = 40;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
package io.anuke.mindustry.entities.enemies.types;
|
||||
|
||||
import io.anuke.mindustry.entities.BulletType;
|
||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||
import io.anuke.mindustry.entities.enemies.EnemyTypes;
|
||||
import io.anuke.mindustry.graphics.Fx;
|
||||
import io.anuke.ucore.core.Effects;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.util.Angles;
|
||||
|
||||
import static io.anuke.mindustry.Vars.world;
|
||||
|
||||
public class FortressType extends EnemyType {
|
||||
final int maxSpawn = 6;
|
||||
final float spawnTime = 190;
|
||||
|
||||
public FortressType() {
|
||||
super("fortressenemy");
|
||||
|
||||
speed = 0.25f;
|
||||
reload = 90;
|
||||
health = 700;
|
||||
range = 70f;
|
||||
bullet = BulletType.yellowshell;
|
||||
hitsize = 10f;
|
||||
turretrotatespeed = rotatespeed = 0.08f;
|
||||
length = 7f;
|
||||
mass = 7f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void behavior(Enemy enemy){
|
||||
if(enemy.distanceTo(world.getCore().worldx(),
|
||||
world.getCore().worldy()) <= 90f){
|
||||
|
||||
if(Timers.get(this, "spawn", spawnTime) && enemy.spawned < maxSpawn){
|
||||
enemy.tr.trns(enemy.angle, 20f);
|
||||
|
||||
Enemy s = new Enemy(EnemyTypes.fast);
|
||||
s.lane = enemy.lane;
|
||||
s.tier = enemy.tier;
|
||||
s.spawner = enemy;
|
||||
s.set(enemy.x + enemy.tr.x, enemy.y + enemy.tr.y);
|
||||
s.add();
|
||||
|
||||
Effects.effect(Fx.spawn, enemy);
|
||||
enemy.spawned ++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void onShoot(Enemy enemy, BulletType type, float rotation){
|
||||
Effects.effect(Fx.largeCannonShot, enemy.x + enemy.tr.x, enemy.y + enemy.tr.y, enemy.angle);
|
||||
Effects.shake(3f, 3f, enemy);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
package io.anuke.mindustry.entities.enemies.types;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.math.MathUtils;
|
||||
import io.anuke.mindustry.entities.Bullet;
|
||||
import io.anuke.mindustry.entities.BulletType;
|
||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||
import io.anuke.mindustry.graphics.Fx;
|
||||
import io.anuke.mindustry.graphics.Shaders;
|
||||
import io.anuke.ucore.core.Effects;
|
||||
import io.anuke.ucore.core.Graphics;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.entities.Entities;
|
||||
import io.anuke.ucore.graphics.Draw;
|
||||
import io.anuke.ucore.graphics.Hue;
|
||||
import io.anuke.ucore.graphics.Shapes;
|
||||
|
||||
import static io.anuke.mindustry.Vars.enemyGroup;
|
||||
|
||||
public class HealerType extends EnemyType {
|
||||
|
||||
public HealerType() {
|
||||
super("healerenemy");
|
||||
speed = 0.25f;
|
||||
reload = 10;
|
||||
health = 200;
|
||||
bullet = BulletType.shot;
|
||||
range = 40f;
|
||||
alwaysRotate = false;
|
||||
targetCore = false;
|
||||
stopNearCore = true;
|
||||
targetClient = true;
|
||||
mass = 1.1f;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void behavior(Enemy enemy){
|
||||
|
||||
if(enemy.idletime > 60f*3){ //explode after 3 seconds of stillness
|
||||
explode(enemy);
|
||||
Effects.effect(Fx.shellexplosion, enemy);
|
||||
Effects.effect(Fx.shellsmoke, enemy);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTargeting(Enemy enemy, boolean nearCore){
|
||||
if(enemy.timer.get(timerTarget, 15)){
|
||||
enemy.target = Entities.getClosest(enemyGroup,
|
||||
enemy.x, enemy.y, range, e -> e instanceof Enemy && e != enemy && ((Enemy)e).healthfrac() < 1f);
|
||||
}
|
||||
|
||||
if(enemy.target != null){
|
||||
updateShooting(enemy);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void updateShooting(Enemy enemy){
|
||||
Enemy target = (Enemy)enemy.target;
|
||||
|
||||
if(target.health < target.maxhealth && enemy.timer.get(timerReload, reload)){
|
||||
target.health ++;
|
||||
enemy.idletime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawOver(Enemy enemy){
|
||||
Enemy target = (Enemy)enemy.target;
|
||||
|
||||
if(target == null) return;
|
||||
|
||||
enemy.tr.trns(enemy.angleTo(target), 5f);
|
||||
|
||||
Shaders.outline.color.set(Color.CLEAR);
|
||||
Shaders.outline.apply();
|
||||
|
||||
if(target.health < target.maxhealth){
|
||||
Draw.color(Hue.rgb(138, 244, 138, (MathUtils.sin(Timers.time()) + 1f) / 13f));
|
||||
Draw.alpha(0.9f);
|
||||
Shapes.laser("laser", "laserend", enemy.x + enemy.tr.x, enemy.y + enemy.tr.y, target.x - enemy.tr.x/1.5f, target.y - enemy.tr.y/1.5f);
|
||||
Draw.color();
|
||||
}
|
||||
|
||||
Graphics.flush();
|
||||
}
|
||||
|
||||
void explode(Enemy enemy){
|
||||
Bullet b = new Bullet(BulletType.blast, enemy, enemy.x, enemy.y, 0).add();
|
||||
b.damage = BulletType.blast.damage + (enemy.tier-1) * 30;
|
||||
enemy.damage(999);
|
||||
enemy.remove();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
package io.anuke.mindustry.entities.enemies.types;
|
||||
|
||||
import io.anuke.mindustry.entities.BulletType;
|
||||
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||
|
||||
public class MortarType extends EnemyType {
|
||||
|
||||
public MortarType() {
|
||||
super("mortarenemy");
|
||||
|
||||
health = 200;
|
||||
speed = 0.25f;
|
||||
reload = 100f;
|
||||
bullet = BulletType.shell;
|
||||
turretrotatespeed = 0.15f;
|
||||
rotatespeed = 0.05f;
|
||||
range = 120f;
|
||||
mass = 1.2f;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
package io.anuke.mindustry.entities.enemies.types;
|
||||
|
||||
import io.anuke.mindustry.entities.BulletType;
|
||||
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||
|
||||
public class RapidType extends EnemyType {
|
||||
|
||||
public RapidType() {
|
||||
super("rapidenemy");
|
||||
|
||||
reload = 8;
|
||||
bullet = BulletType.purple;
|
||||
rotatespeed = 0.08f;
|
||||
health = 260;
|
||||
speed = 0.33f;
|
||||
hitsize = 8f;
|
||||
mass = 3f;
|
||||
range = 70;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package io.anuke.mindustry.entities.enemies.types;
|
||||
|
||||
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||
|
||||
public class StandardType extends EnemyType {
|
||||
|
||||
public StandardType(){
|
||||
super("standardenemy");
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package io.anuke.mindustry.entities.enemies.types;
|
||||
|
||||
import io.anuke.mindustry.entities.BulletType;
|
||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||
import io.anuke.ucore.util.Angles;
|
||||
|
||||
public class TankType extends EnemyType {
|
||||
|
||||
public TankType() {
|
||||
super("tankenemy");
|
||||
|
||||
health = 350;
|
||||
speed = 0.24f;
|
||||
reload = 90f;
|
||||
rotatespeed = 0.06f;
|
||||
bullet = BulletType.small;
|
||||
length = 3f;
|
||||
mass = 1.4f;
|
||||
length = 8f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shoot(Enemy enemy){
|
||||
super.shoot(enemy);
|
||||
|
||||
Angles.shotgun(3, 8f, enemy.angle, f -> enemy.shoot(bullet, f));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
package io.anuke.mindustry.entities.enemies.types;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||
import io.anuke.mindustry.entities.enemies.EnemyTypes;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.graphics.Draw;
|
||||
import io.anuke.ucore.graphics.Lines;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
|
||||
import static io.anuke.mindustry.Vars.control;
|
||||
|
||||
public class TargetType extends EnemyType {
|
||||
|
||||
public TargetType(){
|
||||
super("targetenemy");
|
||||
|
||||
speed = 0f;
|
||||
health = 40;
|
||||
shootsound = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void move(Enemy enemy){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shoot(Enemy enemy){
|
||||
//do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removed(Enemy enemy){
|
||||
//don't call enemy death since this is only a target
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Enemy enemy){
|
||||
super.draw(enemy);
|
||||
|
||||
Draw.color(Color.YELLOW);
|
||||
|
||||
if(control.tutorial().showTarget()){
|
||||
Lines.spikes(enemy.x, enemy.y, 11f + Mathf.sin(Timers.time(), 7f, 1f), 4f, 8, Timers.time());
|
||||
}
|
||||
|
||||
Draw.color();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeath(Enemy enemy, boolean force){
|
||||
super.onDeath(enemy, force);
|
||||
Timers.run(100f, ()->{
|
||||
new Enemy(EnemyTypes.target).set(enemy.x, enemy.y).add();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCalculating(Enemy enemy){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
package io.anuke.mindustry.entities.enemies.types;
|
||||
|
||||
import io.anuke.mindustry.entities.BulletType;
|
||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.util.Angles;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
|
||||
public class TitanType extends EnemyType {
|
||||
|
||||
public TitanType() {
|
||||
super("titanenemy");
|
||||
|
||||
speed = 0.26f;
|
||||
reload = 30;
|
||||
health = 430;
|
||||
range = 60f;
|
||||
bullet = BulletType.small;
|
||||
hitsize = 7f;
|
||||
mass = 4f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateShooting(Enemy enemy){
|
||||
Timers.get(enemy, "salvo", 240);
|
||||
|
||||
if(Timers.getTime(enemy, "salvo") < 60){
|
||||
if(Timers.get(enemy, "salvoShoot", 6)){
|
||||
enemy.shoot(BulletType.flameshot, Mathf.range(20f));
|
||||
}
|
||||
}
|
||||
|
||||
if(Timers.get(enemy, "shotgun", 80)){
|
||||
Angles.shotgun(5, 10f, 0f, f->{
|
||||
enemy.shoot(BulletType.smallSlow, f);
|
||||
});
|
||||
}
|
||||
|
||||
if(Timers.get(enemy, "circle", 200)){
|
||||
Angles.circle(8, f->{
|
||||
enemy.shoot(BulletType.smallSlow, f);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
package io.anuke.mindustry.game;
|
||||
|
||||
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||
import io.anuke.mindustry.entities.enemies.UnitType;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
|
||||
import static io.anuke.mindustry.Vars.state;
|
||||
|
||||
public class EnemySpawn{
|
||||
/**The enemy type spawned*/
|
||||
public final EnemyType type;
|
||||
public final UnitType type;
|
||||
/**When this spawns should end*/
|
||||
protected int before = Integer.MAX_VALUE;
|
||||
/**When this spawns should start*/
|
||||
@@ -27,7 +27,7 @@ public class EnemySpawn{
|
||||
/**Amount of enemies spawned initially, with no scaling*/
|
||||
protected int amount = 1;
|
||||
|
||||
public EnemySpawn(EnemyType type){
|
||||
public EnemySpawn(UnitType type){
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@@ -41,6 +41,6 @@ public class EnemySpawn{
|
||||
}
|
||||
|
||||
public int tier(int wave, int lane){
|
||||
return Mathf.clamp(tier + (wave-after)/tierscale, 1, EnemyType.maxtier);
|
||||
return Mathf.clamp(tier + (wave-after)/tierscale, 1, UnitType.maxtier);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package io.anuke.mindustry.game;
|
||||
import io.anuke.mindustry.core.GameState.State;
|
||||
import io.anuke.mindustry.entities.BulletType;
|
||||
import io.anuke.mindustry.entities.TileEntity;
|
||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||
import io.anuke.mindustry.entities.enemies.BaseUnit;
|
||||
import io.anuke.mindustry.resource.Weapon;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
@@ -41,7 +41,7 @@ public class EventType {
|
||||
}
|
||||
|
||||
public interface EnemyDeathEvent extends Event{
|
||||
void handle(Enemy enemy);
|
||||
void handle(BaseUnit enemy);
|
||||
}
|
||||
|
||||
public interface BlockDestroyEvent extends Event{
|
||||
|
||||
15
core/src/io/anuke/mindustry/game/Team.java
Normal file
15
core/src/io/anuke/mindustry/game/Team.java
Normal file
@@ -0,0 +1,15 @@
|
||||
package io.anuke.mindustry.game;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
|
||||
public enum Team {
|
||||
none(Color.GRAY),
|
||||
blue(Color.BLUE),
|
||||
red(Color.RED);
|
||||
|
||||
public final Color color;
|
||||
|
||||
Team(Color color){
|
||||
this.color = color;
|
||||
}
|
||||
}
|
||||
@@ -1,130 +1,12 @@
|
||||
package io.anuke.mindustry.game;
|
||||
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import io.anuke.mindustry.entities.enemies.EnemyTypes;
|
||||
|
||||
public class WaveCreator{
|
||||
|
||||
public static Array<EnemySpawn> getSpawns(){
|
||||
|
||||
return Array.with(
|
||||
new EnemySpawn(EnemyTypes.standard){{
|
||||
scaling = 1;
|
||||
before = 3;
|
||||
}},
|
||||
|
||||
new EnemySpawn(EnemyTypes.fast){{
|
||||
scaling = 1;
|
||||
after = 3;
|
||||
spacing = 5;
|
||||
amount = 3;
|
||||
tierscaleback = 0;
|
||||
}},
|
||||
|
||||
new EnemySpawn(EnemyTypes.blast){{
|
||||
after = 4;
|
||||
amount = 2;
|
||||
spacing = 5;
|
||||
scaling = 2;
|
||||
tierscaleback = 1;
|
||||
}},
|
||||
|
||||
new EnemySpawn(EnemyTypes.tank){{
|
||||
after = 5;
|
||||
spacing = 5;
|
||||
scaling = 2;
|
||||
amount = 2;
|
||||
}},
|
||||
|
||||
new EnemySpawn(EnemyTypes.rapid){{
|
||||
after = 7;
|
||||
spacing = 5;
|
||||
scaling = 2;
|
||||
amount = 3;
|
||||
}},
|
||||
|
||||
new EnemySpawn(EnemyTypes.healer){{
|
||||
after = 5;
|
||||
spacing = 5;
|
||||
scaling = 1;
|
||||
amount = 1;
|
||||
}},
|
||||
|
||||
new EnemySpawn(EnemyTypes.standard){{
|
||||
scaling = 3;
|
||||
after = 8;
|
||||
spacing = 4;
|
||||
tier = 2;
|
||||
}},
|
||||
|
||||
new EnemySpawn(EnemyTypes.titan){{
|
||||
after = 6;
|
||||
amount = 2;
|
||||
spacing = 5;
|
||||
scaling = 3;
|
||||
}},
|
||||
|
||||
new EnemySpawn(EnemyTypes.flamer){{
|
||||
after = 12;
|
||||
amount = 2;
|
||||
spacing = 5;
|
||||
scaling = 3;
|
||||
}},
|
||||
|
||||
new EnemySpawn(EnemyTypes.emp){{
|
||||
after = 15;
|
||||
amount = 1;
|
||||
spacing = 5;
|
||||
scaling = 2;
|
||||
}},
|
||||
|
||||
new EnemySpawn(EnemyTypes.blast){{
|
||||
after = 4 + 5 + 5;
|
||||
amount = 3;
|
||||
spacing = 5;
|
||||
scaling = 2;
|
||||
tierscaleback = 0;
|
||||
}},
|
||||
//boss wave
|
||||
new EnemySpawn(EnemyTypes.fortress){{
|
||||
after = 16;
|
||||
amount = 1;
|
||||
spacing = 5;
|
||||
scaling = 1;
|
||||
}},
|
||||
|
||||
new EnemySpawn(EnemyTypes.titan){{
|
||||
after = 16;
|
||||
amount = 1;
|
||||
spacing = 5;
|
||||
scaling = 3;
|
||||
tierscaleback = 0;
|
||||
}},
|
||||
|
||||
new EnemySpawn(EnemyTypes.healer){{
|
||||
after = 16;
|
||||
spacing = 5;
|
||||
scaling = 2;
|
||||
amount = 2;
|
||||
}},
|
||||
//end boss wave
|
||||
|
||||
//enchanced boss wave
|
||||
new EnemySpawn(EnemyTypes.mortar){{
|
||||
after = 16 + 5;
|
||||
amount = 1;
|
||||
spacing = 5;
|
||||
scaling = 3;
|
||||
}},
|
||||
|
||||
new EnemySpawn(EnemyTypes.emp){{
|
||||
after = 16 + 5;
|
||||
amount = 1;
|
||||
spacing = 5;
|
||||
scaling = 3;
|
||||
}}
|
||||
//end enchanced boss wave
|
||||
);
|
||||
//TODO
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void testWaves(int from, int to){
|
||||
|
||||
@@ -5,7 +5,6 @@ import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.GL20;
|
||||
import com.badlogic.gdx.graphics.OrthographicCamera;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import io.anuke.mindustry.core.GameState.State;
|
||||
import io.anuke.mindustry.game.SpawnPoint;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.Layer;
|
||||
@@ -86,10 +85,7 @@ public class BlockRenderer{
|
||||
}
|
||||
|
||||
if(!(block instanceof StaticBlock)){
|
||||
if(block == Blocks.air){
|
||||
if(!state.is(State.paused)) tile.floor().update(tile);
|
||||
}else{
|
||||
|
||||
if(block != Blocks.air){
|
||||
if(!expanded){
|
||||
addRequest(tile, Layer.block);
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ package io.anuke.mindustry.io.versions;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.IntMap;
|
||||
import com.badlogic.gdx.utils.TimeUtils;
|
||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||
import io.anuke.mindustry.entities.enemies.BaseUnit;
|
||||
import io.anuke.mindustry.entities.enemies.UnitType;
|
||||
import io.anuke.mindustry.game.Difficulty;
|
||||
import io.anuke.mindustry.game.GameMode;
|
||||
import io.anuke.mindustry.io.SaveFileVersion;
|
||||
@@ -120,7 +120,7 @@ public class Save16 extends SaveFileVersion {
|
||||
|
||||
int enemies = stream.readInt();
|
||||
|
||||
Array<Enemy> enemiesToUpdate = new Array<>();
|
||||
Array<BaseUnit> enemiesToUpdate = new Array<>();
|
||||
|
||||
for(int i = 0; i < enemies; i ++){
|
||||
byte type = stream.readByte();
|
||||
@@ -131,7 +131,7 @@ public class Save16 extends SaveFileVersion {
|
||||
int health = stream.readShort();
|
||||
|
||||
try{
|
||||
Enemy enemy = new Enemy(EnemyType.getByID(type));
|
||||
BaseUnit enemy = new BaseUnit(UnitType.getByID(type));
|
||||
enemy.lane = lane;
|
||||
enemy.health = health;
|
||||
enemy.x = x;
|
||||
@@ -158,7 +158,7 @@ public class Save16 extends SaveFileVersion {
|
||||
world.loadMap(world.maps().getMap(mapid), seed);
|
||||
if(!headless) renderer.clearTiles();
|
||||
|
||||
for(Enemy enemy : enemiesToUpdate){
|
||||
for(BaseUnit enemy : enemiesToUpdate){
|
||||
enemy.node = -2;
|
||||
}
|
||||
|
||||
@@ -278,12 +278,12 @@ public class Save16 extends SaveFileVersion {
|
||||
|
||||
//--ENEMIES--
|
||||
|
||||
EntityContainer<Enemy> enemies = enemyGroup.all();
|
||||
EntityContainer<BaseUnit> enemies = enemyGroup.all();
|
||||
|
||||
stream.writeInt(enemies.size()); //enemy amount
|
||||
|
||||
for(int i = 0; i < enemies.size(); i ++){
|
||||
Enemy enemy = enemies.get(i);
|
||||
BaseUnit enemy = enemies.get(i);
|
||||
stream.writeByte(enemy.type.id); //type
|
||||
stream.writeByte(enemy.lane); //lane
|
||||
stream.writeFloat(enemy.x); //x
|
||||
|
||||
@@ -4,7 +4,7 @@ import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.entities.BulletType;
|
||||
import io.anuke.mindustry.entities.Player;
|
||||
import io.anuke.mindustry.entities.TileEntity;
|
||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||
import io.anuke.mindustry.entities.enemies.BaseUnit;
|
||||
import io.anuke.mindustry.net.Net.SendMode;
|
||||
import io.anuke.mindustry.net.Packets.*;
|
||||
import io.anuke.mindustry.resource.Weapon;
|
||||
@@ -40,7 +40,7 @@ public class NetEvents {
|
||||
Net.send(packet, SendMode.udp);
|
||||
}
|
||||
|
||||
public static void handleEnemyDeath(Enemy enemy){
|
||||
public static void handleEnemyDeath(BaseUnit enemy){
|
||||
EnemyDeathPacket packet = new EnemyDeathPacket();
|
||||
packet.id = enemy.id;
|
||||
Net.send(packet, SendMode.tcp);
|
||||
|
||||
@@ -34,8 +34,8 @@ public class ServerDebug {
|
||||
build.append(player.clientid);
|
||||
build.append(" / player '");
|
||||
build.append(player.name);
|
||||
build.append(" android: ");
|
||||
build.append(player.isAndroid);
|
||||
build.append(" mech: ");
|
||||
build.append(player.mech);
|
||||
build.append("'\n");
|
||||
|
||||
for(Class<?> type : map.orderedKeys()){
|
||||
|
||||
@@ -3,9 +3,14 @@ package io.anuke.mindustry.resource;
|
||||
public class Mech extends Upgrade{
|
||||
public static final Mech
|
||||
|
||||
standard = new Mech("standard");
|
||||
standard = new Mech("standard", false),
|
||||
standardShip = new Mech("standard-ship", true);
|
||||
|
||||
public Mech(String name){
|
||||
public boolean flying;
|
||||
public float mass = 1f;
|
||||
|
||||
public Mech(String name, boolean flying){
|
||||
super(name);
|
||||
this.flying = flying;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,8 +23,8 @@ public abstract class Upgrade {
|
||||
return Bundles.get("upgrade." + name + ".name");
|
||||
}
|
||||
|
||||
public static Upgrade getByID(byte id){
|
||||
return upgrades.get(id);
|
||||
public static <T extends Upgrade> T getByID(byte id){
|
||||
return (T)upgrades.get(id);
|
||||
}
|
||||
|
||||
public static Array<Upgrade> getAllUpgrades() {
|
||||
|
||||
@@ -3,8 +3,8 @@ package io.anuke.mindustry.ui.fragments;
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
import io.anuke.mindustry.entities.Player;
|
||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||
import io.anuke.mindustry.entities.enemies.EnemyTypes;
|
||||
import io.anuke.mindustry.entities.enemies.BaseUnit;
|
||||
import io.anuke.mindustry.entities.enemies.UnitTypes;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.scene.builders.button;
|
||||
@@ -67,7 +67,7 @@ public class DebugFragment implements Fragment {
|
||||
});
|
||||
row();
|
||||
new button("spawn", () -> {
|
||||
new Enemy(EnemyTypes.healer).set(player.x, player.y).add();
|
||||
new BaseUnit(UnitTypes.healer).set(player.x, player.y).add();
|
||||
});
|
||||
row();
|
||||
}}.end();
|
||||
@@ -163,8 +163,8 @@ public class DebugFragment implements Fragment {
|
||||
result.append(", ");
|
||||
result.append(player.y);
|
||||
result.append("\n");
|
||||
result.append(" android: ");
|
||||
result.append(player.isAndroid);
|
||||
result.append(" mech: ");
|
||||
result.append(player.mech);
|
||||
result.append("\n");
|
||||
result.append(" local: ");
|
||||
result.append(player.isLocal);
|
||||
|
||||
@@ -5,6 +5,7 @@ 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;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.world.blocks.Blocks;
|
||||
import io.anuke.mindustry.world.blocks.types.modules.InventoryModule;
|
||||
import io.anuke.mindustry.world.blocks.types.modules.LiquidModule;
|
||||
@@ -25,6 +26,7 @@ public class Tile{
|
||||
private byte rotation;
|
||||
private byte dump;
|
||||
private byte extra;
|
||||
private byte team;
|
||||
/**The coordinates of the core tile this is linked to, in the form of two bytes packed into one.
|
||||
* This is relative to the block it is linked to; negate coords to find the link.*/
|
||||
public byte link = 0;
|
||||
@@ -125,6 +127,15 @@ public class Tile{
|
||||
public Block block(){
|
||||
return Block.getByID(getWallID());
|
||||
}
|
||||
|
||||
//TODO save team
|
||||
public Team getTeam(){
|
||||
return Team.values()[team];
|
||||
}
|
||||
|
||||
public void setTeam(Team team){
|
||||
this.team = (byte)team.ordinal();
|
||||
}
|
||||
|
||||
/**Returns the breaktime of the block, <i>or</i> the breaktime of the linked block, if this tile is linked.*/
|
||||
public float getBreakTime(){
|
||||
|
||||
@@ -5,8 +5,8 @@ import com.badlogic.gdx.graphics.Pixmap;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.ObjectMap;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||
import io.anuke.mindustry.entities.enemies.EnemyTypes;
|
||||
import io.anuke.mindustry.entities.enemies.BaseUnit;
|
||||
import io.anuke.mindustry.entities.enemies.UnitTypes;
|
||||
import io.anuke.mindustry.game.SpawnPoint;
|
||||
import io.anuke.mindustry.world.ColorMapper.BlockPair;
|
||||
import io.anuke.mindustry.world.blocks.Blocks;
|
||||
@@ -77,7 +77,7 @@ public class WorldGenerator {
|
||||
}
|
||||
|
||||
if(color == Hue.rgb(Color.PURPLE)){
|
||||
if(!Vars.android) new Enemy(EnemyTypes.target).set(x * tilesize, y * tilesize).add();
|
||||
if(!Vars.android) new BaseUnit(UnitTypes.target).set(x * tilesize, y * tilesize).add();
|
||||
floor = Blocks.stone;
|
||||
}
|
||||
|
||||
|
||||
@@ -180,7 +180,7 @@ public class ProductionBlocks{
|
||||
{
|
||||
resource = Blocks.uranium;
|
||||
result = Item.uranium;
|
||||
drillTime = 540;
|
||||
drillTime = 600;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ 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.enemies.Enemy;
|
||||
import io.anuke.mindustry.entities.enemies.BaseUnit;
|
||||
import io.anuke.mindustry.graphics.Fx;
|
||||
import io.anuke.mindustry.world.Layer;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
@@ -32,7 +32,7 @@ public class LaserTurret extends PowerTurret{
|
||||
@Override
|
||||
public void shoot(Tile tile){
|
||||
TurretEntity entity = tile.entity();
|
||||
Enemy enemy = entity.target;
|
||||
BaseUnit enemy = entity.target;
|
||||
|
||||
if(Angles.angleDist(entity.rotation, Angles.angle(tile.drawx(), tile.drawy(), enemy.x, enemy.y)) < cone){
|
||||
enemy.damage(damage);
|
||||
@@ -43,7 +43,7 @@ public class LaserTurret extends PowerTurret{
|
||||
@Override
|
||||
public void drawLayer2(Tile tile){
|
||||
TurretEntity entity = tile.entity();
|
||||
Enemy enemy = entity.target;
|
||||
BaseUnit enemy = entity.target;
|
||||
|
||||
if(enemy != null &&
|
||||
Angles.angleDist(entity.rotation, Angles.angle(tile.drawx(), tile.drawy(), enemy.x, enemy.y)) <= cone){
|
||||
|
||||
@@ -4,7 +4,7 @@ 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.enemies.Enemy;
|
||||
import io.anuke.mindustry.entities.enemies.BaseUnit;
|
||||
import io.anuke.mindustry.graphics.Fx;
|
||||
import io.anuke.mindustry.resource.Item;
|
||||
import io.anuke.mindustry.world.*;
|
||||
@@ -131,8 +131,8 @@ public class Turret extends Block{
|
||||
if(hasAmmo(tile) || (debug && infiniteAmmo)){
|
||||
|
||||
if(entity.timer.get(timerTarget, targetInterval)){
|
||||
entity.target = (Enemy)Entities.getClosest(enemyGroup,
|
||||
tile.worldx(), tile.worldy(), range, e-> e instanceof Enemy && !((Enemy)e).isDead());
|
||||
entity.target = (BaseUnit)Entities.getClosest(enemyGroup,
|
||||
tile.worldx(), tile.worldy(), range, e-> e instanceof BaseUnit && !((BaseUnit)e).isDead());
|
||||
}
|
||||
|
||||
if(entity.target != null){
|
||||
@@ -240,7 +240,7 @@ public class Turret extends Block{
|
||||
public TileEntity blockTarget;
|
||||
public int ammo;
|
||||
public float rotation = 90;
|
||||
public Enemy target;
|
||||
public BaseUnit target;
|
||||
|
||||
@Override
|
||||
public void write(DataOutputStream stream) throws IOException{
|
||||
|
||||
@@ -3,6 +3,8 @@ package io.anuke.mindustry.world.blocks.types.production;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
|
||||
public class Centrifuge extends LiquidCrafter {
|
||||
protected float powerUsed = 0.1f;
|
||||
protected float timeUsed = 360f;
|
||||
|
||||
public Centrifuge(String name) {
|
||||
super(name);
|
||||
|
||||
Reference in New Issue
Block a user