This commit is contained in:
Anuken
2019-01-04 15:27:39 -05:00
484 changed files with 10025 additions and 9800 deletions

View File

@@ -1,20 +1,26 @@
package io.anuke.mindustry;
import io.anuke.arc.ApplicationCore;
import io.anuke.arc.Core;
import io.anuke.arc.Events;
import io.anuke.arc.util.Log;
import io.anuke.arc.util.Time;
import io.anuke.mindustry.core.*;
import io.anuke.mindustry.game.EventType.GameLoadEvent;
import io.anuke.mindustry.io.BundleLoader;
import io.anuke.ucore.core.Events;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.modules.ModuleCore;
import io.anuke.ucore.util.Log;
import static io.anuke.mindustry.Vars.*;
public class Mindustry extends ModuleCore{
public class Mindustry extends ApplicationCore{
@Override
public void init(){
Timers.mark();
public void setup(){
Time.setDeltaProvider(() -> {
float result = Core.graphics.getDeltaTime() * 60f;
return Float.isNaN(result) || Float.isInfinite(result) ? 1f : Math.min(result, 60f / 10f);
});
Time.mark();
Vars.init();
@@ -22,26 +28,42 @@ public class Mindustry extends ModuleCore{
BundleLoader.load();
content.load();
module(logic = new Logic());
module(world = new World());
module(control = new Control());
module(renderer = new Renderer());
module(ui = new UI());
module(netServer = new NetServer());
module(netClient = new NetClient());
add(logic = new Logic());
add(world = new World());
add(control = new Control());
add(renderer = new Renderer());
add(ui = new UI());
add(netServer = new NetServer());
add(netClient = new NetClient());
}
@Override
public void postInit(){
Log.info("Time to load [total]: {0}", Timers.elapsed());
public void init(){
super.init();
Log.info("Time to load [total]: {0}", Time.elapsed());
Events.fire(new GameLoadEvent());
}
@Override
public void render(){
threads.handleBeginRender();
super.render();
threads.handleEndRender();
public void update(){
long lastFrameTime = Time.millis();
super.update();
int fpsCap = Core.settings.getInt("fpscap", 125);
if(fpsCap <= 120){
long target = 1000/fpsCap;
long elapsed = Time.timeSinceMillis(lastFrameTime);
if(elapsed < target){
try{
Thread.sleep(target - elapsed);
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
}

View File

@@ -1,9 +1,13 @@
package io.anuke.mindustry;
import com.badlogic.gdx.Application.ApplicationType;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Color;
import io.anuke.arc.Application.ApplicationType;
import io.anuke.arc.Core;
import io.anuke.arc.entities.Entities;
import io.anuke.arc.entities.EntityGroup;
import io.anuke.arc.entities.impl.EffectEntity;
import io.anuke.arc.entities.trait.DrawTrait;
import io.anuke.arc.files.FileHandle;
import io.anuke.arc.graphics.Color;
import io.anuke.mindustry.core.*;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.TileEntity;
@@ -17,42 +21,45 @@ import io.anuke.mindustry.game.Version;
import io.anuke.mindustry.gen.Serialization;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.world.blocks.defense.ForceProjector.ShieldEntity;
import io.anuke.ucore.core.Settings;
import io.anuke.ucore.entities.Entities;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.entities.impl.EffectEntity;
import io.anuke.ucore.entities.trait.DrawTrait;
import io.anuke.ucore.scene.ui.layout.Unit;
import io.anuke.ucore.util.Translator;
import java.util.Arrays;
import java.util.Locale;
@SuppressWarnings("unchecked")
public class Vars{
/**main application name, capitalized*/
public static final String appName = "Mindustry";
/**URL for discord invite.*/
public static final String discordURL = "https://discord.gg/mindustry";
/**URL for Github API for releases*/
public static final String releasesURL = "https://api.github.com/repos/Anuken/Mindustry/releases";
/**URL for Github API for contributors*/
public static final String contributorsURL = "https://api.github.com/repos/Anuken/Mindustry/contributors";
/**URL for sending crash reports to*/
public static final String crashReportURL = "http://mindustry.us.to/report";
//time between waves in frames (on normal mode)
/**time between waves in ticks (on normal mode)*/
public static final float wavespace = 60 * 60 * 1.5f;
/**maximum distance between mine and core that supports automatic transferring*/
public static final float mineTransferRange = 220f;
//set ridiculously high for now
/**maximum distance from core that the player can be before it is no longer used for building*/
public static final float coreBuildRange = 999999f;
//team of the player by default
/**team of the player by default*/
public static final Team defaultTeam = Team.blue;
//team of the enemy in waves
/**team of the enemy in waves/sectors*/
public static final Team waveTeam = Team.red;
public static final float unlockResourceScaling = 1f;
/**max chat message length*/
public static final int maxTextLength = 150;
/**max player name length in bytes*/
public static final int maxNameLength = 40;
/**displayed item size when ingame, TODO remove.*/
public static final float itemSize = 5f;
/**size of tiles in units*/
public static final int tilesize = 8;
/**size of sectors in tiles*/
public static final int sectorSize = 256;
/**specific number indicating 'invalid' sector*/
public static final int invalidSector = Integer.MAX_VALUE;
public static Locale[] locales;
/**all choosable player colors in join/host dialog*/
public static final Color[] playerColors = {
Color.valueOf("82759a"),
Color.valueOf("c0c1c5"),
@@ -71,36 +78,38 @@ public class Vars{
Color.valueOf("4b5ef1"),
Color.valueOf("2cabfe"),
};
//server port
/**default server port*/
public static final int port = 6567;
/**if true, UI is not drawn*/
public static boolean disableUI;
/**if true, game is set up in mobile mode, even on desktop. used for debugging*/
public static boolean testMobile;
//shorthand for whether or not this is running on android or ios
/**whether the game is running on a mobile device*/
public static boolean mobile;
/**whether the game is running on an iOS device*/
public static boolean ios;
/**whether the game is running on an Android device*/
public static boolean android;
//main data directory
/**whether the game is running on a headless server*/
public static boolean headless;
/**application data directory, equivalent to {@link io.anuke.arc.Settings#getDataDirectory()}*/
public static FileHandle dataDirectory;
//subdirectory for screenshots
/**data subdirectory used for screenshots*/
public static FileHandle screenshotDirectory;
//directory for user-created map data
/**data subdirectory used for custom mmaps*/
public static FileHandle customMapDirectory;
//save file directory
/**data subdirectory used for saves*/
public static FileHandle saveDirectory;
public static String mapExtension = "mmap";
public static String saveExtension = "msav";
//camera zoom displayed on startup
public static int baseCameraScale;
public static boolean showBlockDebug = false;
public static boolean showFog = true;
public static boolean headless = false;
public static float controllerMin = 0.25f;
public static float baseControllerSpeed = 11f;
public static boolean snapCamera = true;
/**map file extension*/
public static final String mapExtension = "mmap";
/**save file extension*/
public static final String saveExtension = "msav";
/**list of all locales that can be switched to*/
public static Locale[] locales;
public static ContentLoader content;
public static GameState state;
public static ThreadHandler threads;
public static Control control;
public static Logic logic;
@@ -110,8 +119,6 @@ public class Vars{
public static NetServer netServer;
public static NetClient netClient;
public static Player[] players = {};
public static EntityGroup<Player> playerGroup;
public static EntityGroup<TileEntity> tileGroup;
public static EntityGroup<Bullet> bulletGroup;
@@ -122,13 +129,14 @@ public class Vars{
public static EntityGroup<Fire> fireGroup;
public static EntityGroup<BaseUnit>[] unitGroups;
public static final Translator[] tmptr = new Translator[]{new Translator(), new Translator(), new Translator(), new Translator()};
/**all local players, currently only has one player. may be used for local co-op in the future*/
public static Player[] players = {};
public static void init(){
Serialization.init();
//load locales
String[] stra = Gdx.files.internal("locales").readString().split("\n");
String[] stra = Core.files.internal("locales").readString().split("\n");
locales = new Locale[stra.length];
for(int i = 0; i < locales.length; i++){
String code = stra[i];
@@ -167,16 +175,16 @@ public class Vars{
}
state = new GameState();
threads = new ThreadHandler();
mobile = Gdx.app.getType() == ApplicationType.Android || Gdx.app.getType() == ApplicationType.iOS || testMobile;
ios = Gdx.app.getType() == ApplicationType.iOS;
android = Gdx.app.getType() == ApplicationType.Android;
mobile = Core.app.getType() == ApplicationType.Android || Core.app.getType() == ApplicationType.iOS || testMobile;
ios = Core.app.getType() == ApplicationType.iOS;
android = Core.app.getType() == ApplicationType.Android;
dataDirectory = Settings.getDataDirectory(appName);
Core.settings.setAppName(appName);
dataDirectory = Core.settings.getDataDirectory();
screenshotDirectory = dataDirectory.child("screenshots/");
customMapDirectory = dataDirectory.child("maps/");
saveDirectory = dataDirectory.child("saves/");
baseCameraScale = Math.round(Unit.dp.scl(4));
}
}

View File

@@ -1,7 +1,10 @@
package io.anuke.mindustry.ai;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.*;
import io.anuke.arc.Events;
import io.anuke.arc.collection.*;
import io.anuke.arc.function.Predicate;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.geom.Geometry;
import io.anuke.mindustry.content.blocks.Blocks;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.game.EventType.TileChangeEvent;
@@ -11,12 +14,6 @@ import io.anuke.mindustry.game.Teams.TeamData;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.meta.BlockFlag;
import io.anuke.ucore.core.Events;
import io.anuke.ucore.function.Predicate;
import io.anuke.ucore.util.EnumSet;
import io.anuke.ucore.util.Geometry;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.ThreadArray;
import static io.anuke.mindustry.Vars.*;
@@ -47,7 +44,7 @@ public class BlockIndexer{
/**Empty set used for returning.*/
private ObjectSet<Tile> emptySet = new ObjectSet<>();
/**Array used for returning and reusing.*/
private Array<Tile> returnArray = new ThreadArray<>();
private Array<Tile> returnArray = new Array<>();
public BlockIndexer(){
Events.on(TileChangeEvent.class, event -> {
@@ -176,7 +173,7 @@ public class BlockIndexer{
TileEntity e = other.entity;
float ndst = Vector2.dst(x, y, e.x, e.y);
float ndst = Mathf.dst(x, y, e.x, e.y);
if(ndst < range && (closest == null || ndst < dst)){
dst = ndst;
closest = e;

View File

@@ -1,9 +1,12 @@
package io.anuke.mindustry.ai;
import com.badlogic.gdx.math.GridPoint2;
import com.badlogic.gdx.utils.IntArray;
import com.badlogic.gdx.utils.Queue;
import com.badlogic.gdx.utils.TimeUtils;
import io.anuke.arc.Events;
import io.anuke.arc.collection.IntArray;
import io.anuke.arc.collection.Queue;
import io.anuke.arc.math.geom.Geometry;
import io.anuke.arc.math.geom.Point2;
import io.anuke.arc.util.Structs;
import io.anuke.arc.util.Time;
import io.anuke.mindustry.game.EventType.TileChangeEvent;
import io.anuke.mindustry.game.EventType.WorldLoadEvent;
import io.anuke.mindustry.game.Team;
@@ -11,16 +14,12 @@ import io.anuke.mindustry.game.Teams.TeamData;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.meta.BlockFlag;
import io.anuke.ucore.core.Events;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.util.Geometry;
import io.anuke.ucore.util.Structs;
import static io.anuke.mindustry.Vars.state;
import static io.anuke.mindustry.Vars.world;
public class Pathfinder{
private long maxUpdate = TimeUtils.millisToNanos(4);
private long maxUpdate = Time.millisToNanos(4);
private PathData[] paths;
private IntArray blocked = new IntArray();
@@ -63,7 +62,7 @@ public class Pathfinder{
Tile target = null;
float tl = 0f;
for(GridPoint2 point : Geometry.d8){
for(Point2 point : Geometry.d8){
int dx = tile.x + point.x, dy = tile.y + point.y;
Tile other = world.tile(dx, dy);
@@ -105,7 +104,7 @@ public class Pathfinder{
//increment search, clear frontier
path.search++;
path.frontier.clear();
path.lastSearchTime = TimeUtils.millis();
path.lastSearchTime = Time.millis();
//add all targets to the frontier
for(Tile other : world.indexer.getEnemy(team, BlockFlag.target)){
@@ -144,14 +143,14 @@ public class Pathfinder{
private void updateFrontier(Team team, long nsToRun){
PathData path = paths[team.ordinal()];
long start = TimeUtils.nanoTime();
long start = Time.nanoTime();
while(path.frontier.size > 0 && (nsToRun < 0 || TimeUtils.timeSinceNanos(start) <= nsToRun)){
while(path.frontier.size > 0 && (nsToRun < 0 || Time.timeSinceNanos(start) <= nsToRun)){
Tile tile = path.frontier.removeLast();
float cost = path.weights[tile.x][tile.y];
if(cost < Float.MAX_VALUE){
for(GridPoint2 point : Geometry.d4){
for(Point2 point : Geometry.d4){
int dx = tile.x + point.x, dy = tile.y + point.y;
Tile other = world.tile(dx, dy);
@@ -168,7 +167,7 @@ public class Pathfinder{
}
private void clear(){
Timers.mark();
Time.mark();
paths = new PathData[Team.all.length];
blocked.clear();

View File

@@ -1,6 +1,10 @@
package io.anuke.mindustry.ai;
import com.badlogic.gdx.utils.Array;
import io.anuke.arc.Events;
import io.anuke.arc.collection.Array;
import io.anuke.arc.collection.GridBits;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.util.Structs;
import io.anuke.mindustry.content.blocks.Blocks;
import io.anuke.mindustry.entities.units.BaseUnit;
import io.anuke.mindustry.entities.units.Squad;
@@ -9,10 +13,6 @@ import io.anuke.mindustry.game.SpawnGroup;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.game.Waves;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Events;
import io.anuke.ucore.util.GridBits;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Structs;
import java.io.DataInput;
import java.io.DataOutput;
@@ -32,7 +32,7 @@ public class WaveSpawner{
private Array<GroundSpawn> groundSpawns = new Array<>();
public WaveSpawner(){
Events.on(WorldLoadEvent.class, this::reset);
Events.on(WorldLoadEvent.class, e -> reset());
}
public void write(DataOutput output) throws IOException{
@@ -115,8 +115,8 @@ public class WaveSpawner{
FlyerSpawn spawn = flySpawns.get(flyCount);
float margin = 40f; //how far away from the edge flying units spawn
spawnX = world.width() * tilesize / 2f + Mathf.sqrwavex(spawn.angle) * (world.width() / 2f * tilesize + margin);
spawnY = world.height() * tilesize / 2f + Mathf.sqrwavey(spawn.angle) * (world.height() / 2f * tilesize + margin);
spawnX = world.width() * tilesize / 2f + sqrwavex(spawn.angle) * (world.width() / 2f * tilesize + margin);
spawnY = world.height() * tilesize / 2f + sqrwavey(spawn.angle) * (world.height() / 2f * tilesize + margin);
spread = margin / 1.5f;
flyCount++;
@@ -172,7 +172,7 @@ public class WaveSpawner{
}
}
private void reset(WorldLoadEvent event){
private void reset(){
dynamicSpawn = false;
flySpawns.clear();
groundSpawns.clear();
@@ -223,7 +223,7 @@ public class WaveSpawner{
int shellWidth = quadWidth() * 2 + quadHeight() * 2 * 6;
shellWidth = Math.min(quadWidth() * quadHeight() / 4, shellWidth);
Mathf.traverseSpiral(quadWidth(), quadHeight(), Mathf.random(shellWidth), (x, y) -> {
traverseSpiral(quadWidth(), quadHeight(), Mathf.random(shellWidth), (x, y) -> {
if(getQuad(x, y)){
spawn.x = x;
spawn.y = y;
@@ -256,4 +256,57 @@ public class WaveSpawner{
//quadrant spawn coordinates
int x, y;
}
//utility methods
float sqrwavex(float degrees){
degrees = Mathf.mod(degrees, 360f);
if(degrees < 45){
return 1;
}else if(degrees < 135){
return 1f - (degrees - 45f) / 90f;
}else if(degrees < 225){
return -1f;
}else if(degrees < 315){
return (degrees - 225) / 90f;
}else{
return 1f;
}
}
float sqrwavey(float degrees){
return sqrwavex(degrees + 90f);
}
void traverseSpiral(int width, int height, int offset, SpiralTraverser con){
int directionIdx = 0;
int curRow = 0, curCol = 0;
for(int i = 0; i < height * width; i++){
if(i >= offset && con.accept(curCol, curRow)) break;
int same = 1, row = curRow, col = curCol;
if(row > height - 1 - row){
row = height - 1 - row;
same = 0;
}
if(col >= width - 1 - col){
col = width - 1 - col;
same = 0;
}
row -= same;
if(row == col){
directionIdx = (directionIdx + 1) % 4;
}
curRow += directions[directionIdx][0];
curCol += directions[directionIdx][1];
}
}
interface SpiralTraverser{
boolean accept(int x, int y);
}
private static int[][] directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
}

View File

@@ -1,6 +1,6 @@
package io.anuke.mindustry.content;
import com.badlogic.gdx.graphics.Color;
import io.anuke.arc.graphics.Color;
import io.anuke.mindustry.game.ContentList;
import io.anuke.mindustry.type.ContentType;
import io.anuke.mindustry.type.Item;

View File

@@ -1,6 +1,6 @@
package io.anuke.mindustry.content;
import com.badlogic.gdx.graphics.Color;
import io.anuke.arc.graphics.Color;
import io.anuke.mindustry.game.ContentList;
import io.anuke.mindustry.type.ContentType;
import io.anuke.mindustry.type.Liquid;

View File

@@ -1,30 +1,24 @@
package io.anuke.mindustry.content;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Rectangle;
import io.anuke.arc.Core;
import io.anuke.arc.entities.Effects;
import io.anuke.arc.graphics.Blending;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.TextureRegion;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.geom.Rectangle;
import io.anuke.arc.util.Time;
import io.anuke.mindustry.content.fx.BulletFx;
import io.anuke.mindustry.content.fx.UnitFx;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.entities.effect.Lightning;
import io.anuke.mindustry.entities.units.BaseUnit;
import io.anuke.mindustry.entities.units.types.AlphaDrone;
import io.anuke.mindustry.game.ContentList;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.graphics.Shaders;
import io.anuke.mindustry.maps.TutorialSector;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.type.ContentType;
import io.anuke.mindustry.type.Mech;
import io.anuke.ucore.core.Core;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Graphics;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.util.Mathf;
import static io.anuke.mindustry.Vars.unitGroups;
public class Mechs implements ContentList{
public static Mech alpha, delta, tau, omega, dart, javelin, trident, glaive;
@@ -36,8 +30,6 @@ public class Mechs implements ContentList{
public void load(){
alpha = new Mech("alpha-mech", false){
int maxDrones = 3;
float buildTime = 20f;
{
drillPower = 1;
@@ -53,28 +45,6 @@ public class Mechs implements ContentList{
@Override
public void updateAlt(Player player){
if(player.isShooting && getDrones(player) < maxDrones && !TutorialSector.supressDrone()){
player.timer.get(Player.timerAbility, buildTime);
if(player.timer.getTime(Player.timerAbility) > buildTime/2f){
if(!Net.client()){
AlphaDrone drone = (AlphaDrone) UnitTypes.alphaDrone.create(player.getTeam());
drone.leader = player;
drone.set(player.x, player.y);
drone.add();
Effects.effect(UnitFx.unitLand, player);
}
}
}
}
int getDrones(Player player){
int sum = 0;
for(BaseUnit unit : unitGroups[player.getTeam().ordinal()].all()){
if(unit instanceof AlphaDrone && ((AlphaDrone) unit).leader == player) sum ++;
}
return sum;
}
};
@@ -100,7 +70,7 @@ public class Mechs implements ContentList{
Effects.shake(1f, 1f, player);
Effects.effect(UnitFx.landShock, player);
for(int i = 0; i < 8; i++){
Timers.run(Mathf.random(8f), () -> Lightning.create(player.getTeam(), Palette.lancerLaser, 17f, player.x, player.y, Mathf.random(360f), 14));
Time.run(Mathf.random(8f), () -> Lightning.create(player.getTeam(), Palette.lancerLaser, 17f, player.x, player.y, Mathf.random(360f), 14));
}
}
}
@@ -137,7 +107,7 @@ public class Mechs implements ContentList{
rect.setSize(healRange*2f).setCenter(player.x, player.y);
Units.getNearby(player.getTeam(), rect, unit -> {
if(unit.distanceTo(player) <= healRange){
if(unit.dst(player) <= healRange){
if(unit.health < unit.maxHealth()){
Effects.effect(UnitFx.heal, unit);
wasHealed = true;
@@ -184,7 +154,7 @@ public class Mechs implements ContentList{
@Override
public void load(){
super.load();
armorRegion = Draw.region(name + "-armor");
armorRegion = Core.atlas.find(name + "-armor");
}
@Override
@@ -202,15 +172,15 @@ public class Mechs implements ContentList{
public void draw(Player player){
if(player.shootHeat <= 0.01f) return;
float alpha = Core.batch.getColor().a;
float alpha = Draw.getColor().a;
Shaders.build.progress = player.shootHeat;
Shaders.build.region = armorRegion;
Shaders.build.time = Timers.time() / 10f;
Shaders.build.time = Time.time() / 10f;
Shaders.build.color.set(Palette.accent).a = player.shootHeat;
Graphics.shader(Shaders.build);
Draw.shader(Shaders.build);
Draw.alpha(1f);
Draw.rect(armorRegion, player.snappedX(), player.snappedY(), player.rotation);
Graphics.shader(Shaders.mix);
Draw.rect(armorRegion, player.x, player.y, player.rotation);
Draw.shader(Shaders.mix);
Draw.color(1f, 1f, 1f, alpha);
}
};
@@ -246,7 +216,7 @@ public class Mechs implements ContentList{
@Override
public void load(){
super.load();
shield = Draw.region(name + "-shield");
shield = Core.atlas.find(name + "-shield");
}
@Override
@@ -257,7 +227,7 @@ public class Mechs implements ContentList{
@Override
public void updateAlt(Player player){
float scl = scld(player);
if(Mathf.chance(Timers.delta() * (0.15*scl))){
if(Mathf.chance(Time.delta() * (0.15*scl))){
Effects.effect(BulletFx.hitLancer, Palette.lancerLaser, player.x, player.y);
Lightning.create(player.getTeam(), Palette.lancerLaser, 10f,
player.x + player.getVelocity().x, player.y + player.getVelocity().y, player.rotation, 14);
@@ -268,14 +238,14 @@ public class Mechs implements ContentList{
public void draw(Player player){
float scl = scld(player);
if(scl < 0.01f) return;
float alpha = Core.batch.getColor().a;
Graphics.shader();
Graphics.setAdditiveBlending();
float alpha = Draw.getColor().a;
Draw.shader();
Draw.color(Palette.lancerLaser);
Draw.alpha(scl/2f);
Draw.rect(shield, player.snappedX() + Mathf.range(scl/2f), player.snappedY() + Mathf.range(scl/2f), player.rotation - 90);
Graphics.setNormalBlending();
Graphics.shader(Shaders.mix);
Draw.blend(Blending.additive);
Draw.rect(shield, player.x + Mathf.range(scl/2f), player.y + Mathf.range(scl/2f), player.rotation - 90);
Draw.blend();
Draw.shader(Shaders.mix);
Draw.color();
Draw.alpha(alpha);
}

View File

@@ -45,10 +45,9 @@ public class Recipes implements ContentList{
new Recipe(effect, StorageBlocks.container, new ItemStack(Items.densealloy, 200));
new Recipe(effect, StorageBlocks.vault, new ItemStack(Items.densealloy, 500), new ItemStack(Items.thorium, 250));
//core disabled due to being broken
new Recipe(effect, StorageBlocks.core,
new ItemStack(Items.copper, 2000), new ItemStack(Items.densealloy, 1500),
new ItemStack(Items.silicon, 1500), new ItemStack(Items.thorium, 500),
new ItemStack(Items.copper, 2000), new ItemStack(Items.densealloy, 2000),
new ItemStack(Items.silicon, 1750), new ItemStack(Items.thorium, 1000),
new ItemStack(Items.surgealloy, 500), new ItemStack(Items.phasefabric, 750)
);

View File

@@ -1,14 +1,14 @@
package io.anuke.mindustry.content;
import io.anuke.arc.entities.Effects;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.util.Time;
import io.anuke.mindustry.content.fx.EnvironmentFx;
import io.anuke.mindustry.entities.StatusController.StatusEntry;
import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.game.ContentList;
import io.anuke.mindustry.type.ContentType;
import io.anuke.mindustry.type.StatusEffect;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.util.Mathf;
public class StatusEffects implements ContentList{
public static StatusEffect none, burning, freezing, wet, melting, tarred, overdrive, shielded, shocked;
@@ -38,7 +38,7 @@ public class StatusEffects implements ContentList{
public void update(Unit unit, float time){
unit.damagePeriodic(0.04f);
if(Mathf.chance(Timers.delta() * 0.2f)){
if(Mathf.chance(Time.delta() * 0.2f)){
Effects.effect(EnvironmentFx.burning, unit.x + Mathf.range(unit.getSize() / 2f), unit.y + Mathf.range(unit.getSize() / 2f));
}
}
@@ -54,7 +54,7 @@ public class StatusEffects implements ContentList{
@Override
public void update(Unit unit, float time){
if(Mathf.chance(Timers.delta() * 0.15f)){
if(Mathf.chance(Time.delta() * 0.15f)){
Effects.effect(EnvironmentFx.freezing, unit.x + Mathf.range(unit.getSize() / 2f), unit.y + Mathf.range(unit.getSize() / 2f));
}
}
@@ -79,7 +79,7 @@ public class StatusEffects implements ContentList{
@Override
public void update(Unit unit, float time){
if(Mathf.chance(Timers.delta() * 0.15f)){
if(Mathf.chance(Time.delta() * 0.15f)){
Effects.effect(EnvironmentFx.wet, unit.x + Mathf.range(unit.getSize() / 2f), unit.y + Mathf.range(unit.getSize() / 2f));
}
}
@@ -105,7 +105,7 @@ public class StatusEffects implements ContentList{
public void update(Unit unit, float time){
unit.damagePeriodic(0.3f);
if(Mathf.chance(Timers.delta() * 0.2f)){
if(Mathf.chance(Time.delta() * 0.2f)){
Effects.effect(EnvironmentFx.melting, unit.x + Mathf.range(unit.getSize() / 2f), unit.y + Mathf.range(unit.getSize() / 2f));
}
}
@@ -118,7 +118,7 @@ public class StatusEffects implements ContentList{
@Override
public void update(Unit unit, float time){
if(Mathf.chance(Timers.delta() * 0.15f)){
if(Mathf.chance(Time.delta() * 0.15f)){
Effects.effect(EnvironmentFx.oily, unit.x + Mathf.range(unit.getSize() / 2f), unit.y + Mathf.range(unit.getSize() / 2f));
}
}
@@ -143,9 +143,9 @@ public class StatusEffects implements ContentList{
@Override
public void update(Unit unit, float time){
//idle regen boosted
unit.health += 0.01f * Timers.delta();
unit.health += 0.01f * Time.delta();
if(Mathf.chance(Timers.delta() * 0.25f)){
if(Mathf.chance(Time.delta() * 0.25f)){
Effects.effect(EnvironmentFx.overdriven, unit.x + Mathf.range(unit.getSize() / 2f), unit.y + Mathf.range(unit.getSize() / 2f), 0f, unit);
}
}

View File

@@ -1,7 +1,6 @@
package io.anuke.mindustry.content;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.utils.ObjectSet;
import io.anuke.arc.collection.ObjectSet;
import io.anuke.mindustry.entities.units.UnitType;
import io.anuke.mindustry.entities.units.types.*;
import io.anuke.mindustry.game.ContentList;
@@ -10,32 +9,11 @@ import io.anuke.mindustry.type.ContentType;
public class UnitTypes implements ContentList{
public static UnitType
spirit, phantom,
alphaDrone,
wraith, ghoul, revenant,
dagger, titan, fortress;
@Override
public void load(){
alphaDrone = new UnitType("alpha-drone", AlphaDrone.class, AlphaDrone::new){
{
isFlying = true;
drag = 0.005f;
speed = 0.6f;
maxVelocity = 1.7f;
range = 40f;
health = 45;
hitsize = 4f;
mass = 0.1f;
weapon = Weapons.droneBlaster;
trailColor = Color.valueOf("ffd37f");
}
@Override
public boolean isHidden() {
return true;
}
};
spirit = new UnitType("spirit", Spirit.class, Spirit::new){{
weapon = Weapons.healBlasterDrone;
isFlying = true;

View File

@@ -1,6 +1,6 @@
package io.anuke.mindustry.content.blocks;
import com.badlogic.gdx.graphics.Color;
import io.anuke.arc.graphics.Color;
import io.anuke.mindustry.content.Items;
import io.anuke.mindustry.content.Liquids;
import io.anuke.mindustry.content.StatusEffects;
@@ -10,13 +10,14 @@ import io.anuke.mindustry.type.ItemStack;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.*;
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 io.anuke.arc.util.Time;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.Lines;
import io.anuke.arc.math.Mathf;
public class Blocks extends BlockList implements ContentList{
public static Block air, blockpart, spawn, space, metalfloor, deepwater, water, lava, tar, stone, blackstone, dirt, sand, ice, snow, grass, shrub, rock, icerock, blackrock;
public static Block air, blockpart, spawn, space, metalfloor, deepwater, water, lava, tar, stone,
blackstone, dirt, sand, ice, snow, grass, shrub, rock, icerock, blackrock;
@Override
@@ -40,7 +41,7 @@ public class Blocks extends BlockList implements ContentList{
public void draw(Tile tile){
Draw.color(Color.SCARLET);
Lines.circle(tile.worldx(), tile.worldy(), 4f +Mathf.absin(Timers.time(), 6f, 6f));
Lines.circle(tile.worldx(), tile.worldy(), 4f +Mathf.absin(Time.time(), 6f, 6f));
Draw.color();
}
};
@@ -90,6 +91,7 @@ public class Blocks extends BlockList implements ContentList{
}};
lava = new Floor("lava"){{
drownTime = 100f;
liquidColor = Color.valueOf("ed5334");
speedMultiplier = 0.2f;
damageTaken = 0.5f;
@@ -103,6 +105,7 @@ public class Blocks extends BlockList implements ContentList{
}};
tar = new Floor("tar"){{
drownTime = 150f;
liquidColor = Color.valueOf("292929");
status = StatusEffects.tarred;
statusIntensity = 1f;
@@ -157,9 +160,7 @@ public class Blocks extends BlockList implements ContentList{
minimapColor = Color.valueOf("549d5b");
}};
shrub = new Rock("shrub"){{
shadow = "shrubshadow";
}};
shrub = new Rock("shrub");
rock = new Rock("rock"){{
variants = 2;

View File

@@ -1,6 +1,6 @@
package io.anuke.mindustry.content.blocks;
import com.badlogic.gdx.graphics.Color;
import io.anuke.arc.graphics.Color;
import io.anuke.mindustry.content.Items;
import io.anuke.mindustry.content.Liquids;
import io.anuke.mindustry.content.fx.BlockFx;
@@ -23,7 +23,7 @@ public class CraftingBlocks extends BlockList implements ContentList{
burnDuration = 46f;
useFlux = true;
consumes.items(new ItemStack[]{new ItemStack(Items.copper, 1), new ItemStack(Items.lead, 2)});
consumes.items(new ItemStack(Items.copper, 1), new ItemStack(Items.lead, 2));
consumes.item(Items.coal).optional(true);
}};
@@ -37,7 +37,7 @@ public class CraftingBlocks extends BlockList implements ContentList{
useFlux = true;
fluxNeeded = 2;
consumes.items(new ItemStack[]{new ItemStack(Items.copper, 1), new ItemStack(Items.lead, 2)});
consumes.items(new ItemStack(Items.copper, 1), new ItemStack(Items.lead, 2));
consumes.power(0.1f);
}};
@@ -46,12 +46,11 @@ public class CraftingBlocks extends BlockList implements ContentList{
craftEffect = BlockFx.smeltsmoke;
result = Items.silicon;
craftTime = 40f;
powerCapacity = 20f;
size = 2;
hasLiquids = false;
flameColor = Color.valueOf("ffef99");
consumes.items(new ItemStack[]{new ItemStack(Items.coal, 1), new ItemStack(Items.sand, 2)});
consumes.items(new ItemStack(Items.coal, 1), new ItemStack(Items.sand, 2));
consumes.power(0.05f);
}};
@@ -61,7 +60,6 @@ public class CraftingBlocks extends BlockList implements ContentList{
craftTime = 60f;
output = Items.plastanium;
itemCapacity = 30;
powerCapacity = 40f;
size = 2;
health = 320;
hasPower = hasLiquids = true;
@@ -77,10 +75,9 @@ public class CraftingBlocks extends BlockList implements ContentList{
craftEffect = BlockFx.smeltsmoke;
result = Items.phasefabric;
craftTime = 120f;
powerCapacity = 50f;
size = 2;
consumes.items(new ItemStack[]{new ItemStack(Items.thorium, 4), new ItemStack(Items.sand, 10)});
consumes.items(new ItemStack(Items.thorium, 4), new ItemStack(Items.sand, 10));
consumes.power(0.5f);
}};
@@ -88,14 +85,13 @@ public class CraftingBlocks extends BlockList implements ContentList{
craftEffect = BlockFx.smeltsmoke;
result = Items.surgealloy;
craftTime = 75f;
powerCapacity = 60f;
size = 2;
useFlux = true;
fluxNeeded = 3;
consumes.power(0.4f);
consumes.items(new ItemStack[]{new ItemStack(Items.titanium, 2), new ItemStack(Items.lead, 4), new ItemStack(Items.silicon, 3), new ItemStack(Items.copper, 3)});
consumes.items(new ItemStack(Items.titanium, 2), new ItemStack(Items.lead, 4), new ItemStack(Items.silicon, 3), new ItemStack(Items.copper, 3));
}};
cryofluidmixer = new LiquidMixer("cryofluidmixer"){{
@@ -133,7 +129,7 @@ public class CraftingBlocks extends BlockList implements ContentList{
size = 2;
consumes.power(0.02f);
consumes.items(new ItemStack[]{new ItemStack(Items.coal, 1), new ItemStack(Items.lead, 2), new ItemStack(Items.sand, 2)});
consumes.items(new ItemStack(Items.coal, 1), new ItemStack(Items.lead, 2), new ItemStack(Items.sand, 2));
}};
melter = new PowerCrafter("melter"){{

View File

@@ -1,6 +1,6 @@
package io.anuke.mindustry.content.blocks;
import com.badlogic.gdx.utils.Array;
import io.anuke.arc.collection.Array;
import io.anuke.annotations.Annotations.Loc;
import io.anuke.annotations.Annotations.Remote;
import io.anuke.mindustry.content.Liquids;
@@ -10,17 +10,16 @@ import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.game.ContentList;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.Liquid;
import io.anuke.mindustry.world.BarType;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.PowerBlock;
import io.anuke.mindustry.world.blocks.distribution.Sorter;
import io.anuke.mindustry.world.blocks.power.PowerNode;
import io.anuke.mindustry.world.meta.BlockStat;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.scene.ui.ButtonGroup;
import io.anuke.ucore.scene.ui.ImageButton;
import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.scene.ui.ButtonGroup;
import io.anuke.arc.scene.ui.ImageButton;
import io.anuke.arc.scene.ui.layout.Table;
import java.io.DataInput;
import java.io.DataOutput;
@@ -40,36 +39,26 @@ public class DebugBlocks extends BlockList implements ContentList{
public void load(){
powerVoid = new PowerBlock("powervoid"){
{
powerCapacity = Float.MAX_VALUE;
shadow = "shadow-round-1";
}
@Override
public void setBars(){
super.setBars();
bars.remove(BarType.power);
consumes.power(Float.MAX_VALUE);
}
@Override
public void init(){
super.init();
stats.remove(BlockStat.powerCapacity);
stats.remove(BlockStat.powerUse);
}
};
powerInfinite = new PowerNode("powerinfinite"){
{
powerCapacity = 10000f;
maxNodes = 100;
outputsPower = true;
consumesPower = false;
shadow = "shadow-round-1";
}
@Override
public void update(Tile tile){
super.update(tile);
tile.entity.power.amount = powerCapacity;
public float getPowerProduction(Tile tile){
return 10000f;
}
};
@@ -83,12 +72,6 @@ public class DebugBlocks extends BlockList implements ContentList{
return true;
}
@Override
public void setBars(){
super.setBars();
bars.remove(BarType.inventory);
}
@Override
public void update(Tile tile){
SorterEntity entity = tile.entity();

View File

@@ -71,19 +71,18 @@ public class DefenseBlocks extends BlockList implements ContentList{
}};
mendProjector = new MendProjector("mend-projector"){{
consumes.power(0.2f);
consumes.power(0.2f, 1.0f);
size = 2;
consumes.item(Items.phasefabric).optional(true);
}};
overdriveProjector = new OverdriveProjector("overdrive-projector"){{
consumes.power(0.35f);
consumes.power(0.35f, 1.0f);
size = 2;
consumes.item(Items.phasefabric).optional(true);
}};
forceProjector = new ForceProjector("force-projector"){{
consumes.power(0.2f);
size = 3;
consumes.item(Items.phasefabric).optional(true);
}};

View File

@@ -35,7 +35,7 @@ public class DistributionBlocks extends BlockList implements ContentList{
phaseConveyor = new ItemBridge("phase-conveyor"){{
range = 12;
hasPower = true;
consumes.power(0.03f);
consumes.power(0.03f, 1.0f);
}};
sorter = new Sorter("sorter");

View File

@@ -12,29 +12,24 @@ public class LiquidBlocks extends BlockList implements ContentList{
public void load(){
mechanicalPump = new Pump("mechanical-pump"){{
shadow = "shadow-round-1";
pumpAmount = 0.1f;
tier = 0;
}};
rotaryPump = new Pump("rotary-pump"){{
shadow = "shadow-rounded-2";
pumpAmount = 0.2f;
consumes.power(0.015f);
liquidCapacity = 30f;
powerCapacity = 20f;
hasPower = true;
size = 2;
tier = 1;
}};
thermalPump = new Pump("thermal-pump"){{
shadow = "shadow-rounded-2";
pumpAmount = 0.275f;
consumes.power(0.03f);
liquidCapacity = 40f;
hasPower = true;
powerCapacity = 20f;
size = 2;
tier = 2;
}};
@@ -69,7 +64,7 @@ public class LiquidBlocks extends BlockList implements ContentList{
phaseConduit = new LiquidBridge("phase-conduit"){{
range = 12;
hasPower = true;
consumes.power(0.03f);
consumes.power(0.03f, 1.0f);
}};
}
}

View File

@@ -1,6 +1,6 @@
package io.anuke.mindustry.content.blocks;
import com.badlogic.gdx.utils.ObjectMap;
import io.anuke.arc.collection.ObjectMap;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.blocks.Floor;

View File

@@ -4,6 +4,7 @@ import io.anuke.mindustry.content.Liquids;
import io.anuke.mindustry.content.fx.BlockFx;
import io.anuke.mindustry.game.ContentList;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.power.*;
public class PowerBlocks extends BlockList implements ContentList{
@@ -13,48 +14,43 @@ public class PowerBlocks extends BlockList implements ContentList{
@Override
public void load(){
combustionGenerator = new BurnerGenerator("combustion-generator"){{
powerOutput = 0.09f;
powerCapacity = 40f;
powerProduction = 0.09f;
itemDuration = 40f;
}};
thermalGenerator = new LiquidHeatGenerator("thermal-generator"){{
maxLiquidGenerate = 2f;
powerCapacity = 40f;
powerPerLiquid = 0.35f;
powerProduction = 2f;
generateEffect = BlockFx.redgeneratespark;
size = 2;
}};
turbineGenerator = new TurbineGenerator("turbine-generator"){{
powerOutput = 0.28f;
powerCapacity = 40f;
powerProduction = 0.28f;
itemDuration = 30f;
powerPerLiquid = 0.7f;
consumes.liquid(Liquids.water, 0.05f);
size = 2;
}};
rtgGenerator = new DecayGenerator("rtg-generator"){{
powerCapacity = 40f;
size = 2;
powerOutput = 0.3f;
powerProduction = 0.3f;
itemDuration = 220f;
}};
solarPanel = new SolarGenerator("solar-panel"){{
generation = 0.0045f;
powerProduction = 0.0045f;
}};
largeSolarPanel = new SolarGenerator("solar-panel-large"){{
size = 3;
generation = 0.055f;
powerProduction = 0.055f;
}};
thoriumReactor = new NuclearReactor("thorium-reactor"){{
size = 3;
health = 700;
powerMultiplier = 1.1f;
powerProduction = 1.1f;
}};
fusionReactor = new FusionReactor("fusion-reactor"){{
@@ -63,16 +59,15 @@ public class PowerBlocks extends BlockList implements ContentList{
}};
battery = new Battery("battery"){{
powerCapacity = 320f;
consumes.powerBuffered(320f, 1f);
}};
batteryLarge = new Battery("battery-large"){{
size = 3;
powerCapacity = 2000f;
consumes.powerBuffered(2000f, 1f);
}};
powerNode = new PowerNode("power-node"){{
shadow = "shadow-round-1";
maxNodes = 4;
laserRange = 6;
}};
@@ -81,7 +76,6 @@ public class PowerBlocks extends BlockList implements ContentList{
size = 2;
maxNodes = 6;
laserRange = 9.5f;
shadow = "shadow-round-2";
}};
}

View File

@@ -1,6 +1,6 @@
package io.anuke.mindustry.content.blocks;
import com.badlogic.gdx.graphics.Color;
import io.anuke.arc.graphics.Color;
import io.anuke.mindustry.content.Items;
import io.anuke.mindustry.content.Liquids;
import io.anuke.mindustry.content.fx.BlockFx;

View File

@@ -1,16 +1,17 @@
package io.anuke.mindustry.content.blocks;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import io.anuke.arc.Core;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.g2d.TextureRegion;
import io.anuke.mindustry.content.AmmoTypes;
import io.anuke.mindustry.content.fx.ShootFx;
import io.anuke.mindustry.type.AmmoType;
import io.anuke.mindustry.game.ContentList;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.blocks.defense.turrets.*;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.math.Angles;
import io.anuke.arc.math.Mathf;
public class TurretBlocks extends BlockList implements ContentList{
public static Block duo, /*scatter,*/
@@ -46,7 +47,7 @@ public class TurretBlocks extends BlockList implements ContentList{
@Override
public void load(){
super.load();
shootRegion = Draw.region(name + "-shoot");
shootRegion = Core.atlas.find(name + "-shoot");
}
{
@@ -91,8 +92,8 @@ public class TurretBlocks extends BlockList implements ContentList{
recoil = 2f;
reload = 100f;
cooldown = 0.03f;
powerUsed = 20f;
powerCapacity = 60f;
powerUsed = 1 / 3f;
consumes.powerBuffered(60f);
shootShake = 2f;
shootEffect = ShootFx.lancerLaserShoot;
smokeEffect = ShootFx.lancerLaserShootSmoke;
@@ -110,8 +111,8 @@ public class TurretBlocks extends BlockList implements ContentList{
shootShake = 1f;
shootCone = 40f;
rotatespeed = 8f;
powerUsed = 10f;
powerCapacity = 30f;
powerUsed = 1f / 3f;
consumes.powerBuffered(30f);
range = 150f;
shootEffect = ShootFx.lightningShoot;
heatColor = Color.RED;
@@ -137,8 +138,8 @@ public class TurretBlocks extends BlockList implements ContentList{
@Override
public void load() {
super.load();
panels[0] = Draw.region(name + "-panel-left");
panels[1] = Draw.region(name + "-panel-right");
panels[0] = Core.atlas.find(name + "-panel-left");
panels[1] = Core.atlas.find(name + "-panel-right");
}
{
@@ -157,8 +158,8 @@ public class TurretBlocks extends BlockList implements ContentList{
drawer = (tile, entity) -> {
Draw.rect(region, tile.drawx() + tr2.x, tile.drawy() + tr2.y, entity.rotation - 90);
float offsetx = (int) (Mathf.abscurve(Mathf.curve(entity.reload / reload, 0.3f, 0.2f)) * 3f);
float offsety = -(int) (Mathf.abscurve(Mathf.curve(entity.reload / reload, 0.3f, 0.2f)) * 2f);
float offsetx = (int) (abscurve(Mathf.curve(entity.reload / reload, 0.3f, 0.2f)) * 3f);
float offsety = -(int) (abscurve(Mathf.curve(entity.reload / reload, 0.3f, 0.2f)) * 2f);
for(int i : Mathf.signs){
float rot = entity.rotation + 90 * i;
@@ -170,6 +171,11 @@ public class TurretBlocks extends BlockList implements ContentList{
health = 360;
}
/** Converts a value range from 0-1 to a value range 0-1-0. */
float abscurve(float f){
return 1f - Math.abs(f - 0.5f) * 2f;
}
};
ripple = new ArtilleryTurret("ripple"){{
@@ -243,8 +249,8 @@ public class TurretBlocks extends BlockList implements ContentList{
recoil = 4f;
size = 4;
shootShake = 2f;
powerUsed = 60f;
powerCapacity = 120f;
powerUsed = 0.5f;
consumes.powerBuffered(120f);
range = 160f;
reload = 200f;
firingMoveFract = 0.1f;

View File

@@ -45,7 +45,6 @@ public class UnitBlocks extends BlockList implements ContentList{
produceTime = 3600;
size = 3;
consumes.power(0.2f);
shadow = "shadow-round-3";
consumes.items(new ItemStack(Items.silicon, 30), new ItemStack(Items.titanium, 30), new ItemStack(Items.plastanium, 20));
}};
@@ -54,7 +53,6 @@ public class UnitBlocks extends BlockList implements ContentList{
produceTime = 8000;
size = 4;
consumes.power(0.3f);
shadow = "shadow-round-4";
consumes.items(new ItemStack(Items.silicon, 80), new ItemStack(Items.titanium, 80), new ItemStack(Items.plastanium, 50));
}};
@@ -71,7 +69,6 @@ public class UnitBlocks extends BlockList implements ContentList{
produceTime = 3400;
size = 3;
consumes.power(0.15f);
shadow = "shadow-round-3";
consumes.items(new ItemStack(Items.silicon, 20), new ItemStack(Items.thorium, 30));
}};
@@ -80,12 +77,10 @@ public class UnitBlocks extends BlockList implements ContentList{
produceTime = 5000;
size = 3;
consumes.power(0.2f);
shadow = "shadow-round-3";
consumes.items(new ItemStack(Items.silicon, 40), new ItemStack(Items.thorium, 50));
}};
repairPoint = new RepairPoint("repair-point"){{
shadow = "shadow-round-1";
repairSpeed = 0.1f;
}};

View File

@@ -9,56 +9,53 @@ public class UpgradeBlocks extends BlockList{
@Override
public void load(){
alphaPad = new MechPad("alpha-mech-pad"){{
mech = Mechs.alpha;
size = 2;
powerCapacity = 50f;
consumes.powerBuffered(50f);
}};
deltaPad = new MechPad("delta-mech-pad"){{
mech = Mechs.delta;
size = 2;
powerCapacity = 70f;
consumes.powerBuffered(70f);
}};
tauPad = new MechPad("tau-mech-pad"){{
mech = Mechs.tau;
size = 2;
powerCapacity = 100f;
consumes.powerBuffered(100f);
}};
omegaPad = new MechPad("omega-mech-pad"){{
mech = Mechs.omega;
size = 3;
powerCapacity = 120f;
consumes.powerBuffered(120f);
}};
dartPad = new MechPad("dart-ship-pad"){{
mech = Mechs.dart;
size = 2;
powerCapacity = 50f;
shadow = "shadow-rounded-2";
consumes.powerBuffered(50f);
}};
javelinPad = new MechPad("javelin-ship-pad"){{
mech = Mechs.javelin;
size = 2;
powerCapacity = 80f;
shadow = "shadow-rounded-2";
consumes.powerBuffered(80f);
}};
tridentPad = new MechPad("trident-ship-pad"){{
mech = Mechs.trident;
size = 2;
powerCapacity = 100f;
shadow = "shadow-rounded-2";
consumes.powerBuffered(100f);
}};
glaivePad = new MechPad("glaive-ship-pad"){{
mech = Mechs.glaive;
size = 3;
powerCapacity = 120f;
shadow = "shadow-round-3";
consumes.powerBuffered(120f);
}};
}
}

View File

@@ -7,7 +7,7 @@ import io.anuke.mindustry.entities.bullet.FlakBulletType;
import io.anuke.mindustry.entities.effect.Lightning;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.game.ContentList;
import io.anuke.ucore.util.Mathf;
import io.anuke.arc.math.Mathf;
public class FlakBullets extends BulletList implements ContentList{
public static BulletType plastic, explosive, surge;

View File

@@ -1,6 +1,6 @@
package io.anuke.mindustry.content.bullets;
import com.badlogic.gdx.graphics.Color;
import io.anuke.arc.graphics.Color;
import io.anuke.mindustry.content.fx.BulletFx;
import io.anuke.mindustry.entities.bullet.Bullet;
import io.anuke.mindustry.entities.bullet.BulletType;
@@ -8,8 +8,8 @@ import io.anuke.mindustry.entities.bullet.MissileBulletType;
import io.anuke.mindustry.entities.effect.Lightning;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.game.ContentList;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.util.Mathf;
import io.anuke.arc.util.Time;
import io.anuke.arc.math.Mathf;
public class MissileBullets extends BulletList implements ContentList{
public static BulletType explosive, incindiary, surge, javelin, swarm;
@@ -92,7 +92,7 @@ public class MissileBullets extends BulletList implements ContentList{
@Override
public void update(Bullet b){
super.update(b);
b.getVelocity().rotate(Mathf.sin(Timers.time() + b.id * 4422, 8f, 2f));
b.getVelocity().rotate(Mathf.sin(Time.time() + b.id * 4422, 8f, 2f));
}
};
@@ -117,7 +117,7 @@ public class MissileBullets extends BulletList implements ContentList{
@Override
public void update(Bullet b){
super.update(b);
b.getVelocity().rotate(Mathf.sin(Timers.time() + b.id * 4422, 8f, 2f));
b.getVelocity().rotate(Mathf.sin(Time.time() + b.id * 4422, 8f, 2f));
}
};
}

View File

@@ -1,6 +1,6 @@
package io.anuke.mindustry.content.bullets;
import com.badlogic.gdx.graphics.Color;
import io.anuke.arc.graphics.Color;
import io.anuke.mindustry.content.fx.BulletFx;
import io.anuke.mindustry.entities.bullet.BasicBulletType;
import io.anuke.mindustry.entities.bullet.BulletType;

View File

@@ -1,6 +1,14 @@
package io.anuke.mindustry.content.bullets;
import com.badlogic.gdx.graphics.Color;
import io.anuke.arc.entities.Effects;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.g2d.CapStyle;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.Fill;
import io.anuke.arc.graphics.g2d.Lines;
import io.anuke.arc.math.Angles;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.util.Time;
import io.anuke.mindustry.content.Liquids;
import io.anuke.mindustry.content.StatusEffects;
import io.anuke.mindustry.content.fx.BlockFx;
@@ -15,14 +23,10 @@ import io.anuke.mindustry.entities.effect.Fire;
import io.anuke.mindustry.entities.effect.Lightning;
import io.anuke.mindustry.game.ContentList;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.graphics.Shapes;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.BuildBlock;
import io.anuke.mindustry.world.blocks.distribution.MassDriver.DriverBulletData;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.*;
import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf;
import static io.anuke.mindustry.Vars.content;
import static io.anuke.mindustry.Vars.world;
@@ -105,18 +109,18 @@ public class TurretBullets extends BulletList implements ContentList{
@Override
public void update(Bullet b){
if(Mathf.chance(0.04 * Timers.delta())){
if(Mathf.chance(0.04 * Time.delta())){
Tile tile = world.tileWorld(b.x, b.y);
if(tile != null){
Fire.create(tile);
}
}
if(Mathf.chance(0.1 * Timers.delta())){
if(Mathf.chance(0.1 * Time.delta())){
Effects.effect(EnvironmentFx.fireballsmoke, b.x, b.y);
}
if(Mathf.chance(0.1 * Timers.delta())){
if(Mathf.chance(0.1 * Time.delta())){
Effects.effect(EnvironmentFx.ballfire, b.x, b.y);
}
}
@@ -213,10 +217,10 @@ public class TurretBullets extends BulletList implements ContentList{
Lines.lineAngle(b.x, b.y, b.angle(), baseLen);
for(int s = 0; s < colors.length; s++){
Draw.color(tmpColor.set(colors[s]).mul(1f + Mathf.absin(Timers.time(), 1f, 0.1f)));
Draw.color(tmpColor.set(colors[s]).mul(1f + Mathf.absin(Time.time(), 1f, 0.1f)));
for(int i = 0; i < tscales.length; i++){
vector.trns(b.angle() + 180f, (lenscales[i] - 1f) * 35f);
Lines.stroke((9f + Mathf.absin(Timers.time(), 0.8f, 1.5f)) * b.fout() * strokes[s] * tscales[i]);
Lines.stroke((9f + Mathf.absin(Time.time(), 0.8f, 1.5f)) * b.fout() * strokes[s] * tscales[i]);
Lines.lineAngle(b.x + vector.x, b.y + vector.y, b.angle(), baseLen * lenscales[i], CapStyle.none);
}
}
@@ -367,9 +371,9 @@ public class TurretBullets extends BulletList implements ContentList{
return;
}
float baseDst = data.from.distanceTo(data.to);
float dst1 = b.distanceTo(data.from);
float dst2 = b.distanceTo(data.to);
float baseDst = data.from.dst(data.to);
float dst1 = b.dst(data.from);
float dst2 = b.dst(data.to);
boolean intersect = false;
@@ -379,7 +383,7 @@ public class TurretBullets extends BulletList implements ContentList{
float baseAngle = data.to.angleTo(data.from);
//if angles are nearby, then yes, it did
if(Mathf.angNear(angleTo, baseAngle, 2f)){
if(Angles.near(angleTo, baseAngle, 2f)){
intersect = true;
//snap bullet position back; this is used for low-FPS situations
b.set(data.to.x + Angles.trnsx(baseAngle, hitDst), data.to.y + Angles.trnsy(baseAngle, hitDst));

View File

@@ -1,6 +1,6 @@
package io.anuke.mindustry.content.bullets;
import com.badlogic.gdx.graphics.Color;
import io.anuke.arc.graphics.Color;
import io.anuke.mindustry.content.Liquids;
import io.anuke.mindustry.content.fx.BlockFx;
import io.anuke.mindustry.content.fx.BulletFx;
@@ -12,7 +12,7 @@ import io.anuke.mindustry.entities.effect.Fire;
import io.anuke.mindustry.entities.effect.Puddle;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.util.Mathf;
import io.anuke.arc.math.Mathf;
import static io.anuke.mindustry.Vars.world;

View File

@@ -1,17 +1,16 @@
package io.anuke.mindustry.content.fx;
import com.badlogic.gdx.graphics.Color;
import io.anuke.arc.graphics.Color;
import io.anuke.mindustry.entities.effect.GroundEffectEntity.GroundEffect;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.game.ContentList;
import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Fill;
import io.anuke.ucore.graphics.Hue;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Tmp;
import io.anuke.arc.entities.Effects.Effect;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.Fill;
import io.anuke.arc.graphics.g2d.Lines;
import io.anuke.arc.math.Angles;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.util.Tmp;
import static io.anuke.mindustry.Vars.tilesize;
@@ -236,7 +235,7 @@ public class BlockFx extends FxList implements ContentList{
Lines.stroke(e.fout() * 2f);
Angles.randLenVectors(e.id, 30, 4f + 40f * e.fin(), (x, y) -> {
Lines.lineAngle(e.x + x, e.y + y, Mathf.atan2(x, y), e.fin() * 4f + 1f);
Lines.lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), e.fin() * 4f + 1f);
});
Draw.reset();
@@ -247,7 +246,7 @@ public class BlockFx extends FxList implements ContentList{
Lines.circle(e.x, e.y, 7f + e.fout() * 8f);
Angles.randLenVectors(e.id, 20, 6f + 20f * e.fout(), (x, y) -> {
Lines.lineAngle(e.x + x, e.y + y, Mathf.atan2(x, y), e.fin() * 4f + 1f);
Lines.lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), e.fin() * 4f + 1f);
});
Draw.reset();
@@ -258,20 +257,20 @@ public class BlockFx extends FxList implements ContentList{
Lines.circle(e.x, e.y, 7f + e.fin() * 8f);
Angles.randLenVectors(e.id, 20, 4f + 20f * e.fin(), (x, y) -> {
Lines.lineAngle(e.x + x, e.y + y, Mathf.atan2(x, y), e.fslope() * 4f + 1f);
Lines.lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), e.fslope() * 4f + 1f);
});
Draw.reset();
});
ripple = new GroundEffect(false, 30, e -> {
Draw.color(Hue.shift(Tmp.c1.set(e.color), 2, 0.1f));
Draw.color(Tmp.c1.set(e.color).shiftValue(0.1f));
Lines.stroke(e.fout() + 0.4f);
Lines.circle(e.x, e.y, 2f + e.fin() * 4f);
Draw.reset();
});
bubble = new Effect(20, e -> {
Draw.color(Hue.shift(Tmp.c1.set(e.color), 2, 0.1f));
Draw.color(Tmp.c1.set(e.color).shiftValue(0.1f));
Lines.stroke(e.fout() + 0.2f);
Angles.randLenVectors(e.id, 2, 8f, (x, y) -> {
Lines.circle(e.x + x, e.y + y, 1f + e.fin() * 3f);
@@ -310,7 +309,7 @@ public class BlockFx extends FxList implements ContentList{
healBlockFull = new Effect(20, e -> {
Draw.color(e.color);
Draw.alpha(e.fout());
Fill.square(e.x, e.y, e.rotation * tilesize);
Fill.square(e.x, e.y, e.rotation * tilesize / 2f);
Draw.color();
});

View File

@@ -1,14 +1,14 @@
package io.anuke.mindustry.content.fx;
import com.badlogic.gdx.graphics.Color;
import io.anuke.arc.graphics.Color;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.game.ContentList;
import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Fill;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf;
import io.anuke.arc.entities.Effects.Effect;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.Fill;
import io.anuke.arc.graphics.g2d.Lines;
import io.anuke.arc.math.Angles;
import io.anuke.arc.math.Mathf;
public class BulletFx extends FxList implements ContentList{
public static Effect hitBulletSmall, hitFuse, hitBulletBig, hitFlameSmall, hitLiquid, hitLaser, hitLancer, hitMeltdown, despawn, flakExplosion, blastExplosion, plasticExplosion,
@@ -29,7 +29,7 @@ public class BulletFx extends FxList implements ContentList{
Lines.stroke(0.5f + e.fout());
Angles.randLenVectors(e.id, 5, e.fin() * 15f, (x, y) -> {
float ang = Mathf.atan2(x, y);
float ang = Mathf.angle(x, y);
Lines.lineAngle(e.x + x, e.y + y, ang, e.fout() * 3 + 1f);
});
@@ -48,7 +48,7 @@ public class BulletFx extends FxList implements ContentList{
Lines.stroke(0.5f + e.fout());
Angles.randLenVectors(e.id, 6, e.fin() * 15f, (x, y) -> {
float ang = Mathf.atan2(x, y);
float ang = Mathf.angle(x, y);
Lines.lineAngle(e.x + x, e.y + y, ang, e.fout() * 3 + 1f);
});
@@ -60,7 +60,7 @@ public class BulletFx extends FxList implements ContentList{
Lines.stroke(0.5f + e.fout() * 1.5f);
Angles.randLenVectors(e.id, 8, e.finpow() * 30f, e.rotation, 50f, (x, y) -> {
float ang = Mathf.atan2(x, y);
float ang = Mathf.angle(x, y);
Lines.lineAngle(e.x + x, e.y + y, ang, e.fout() * 4 + 1.5f);
});
@@ -72,7 +72,7 @@ public class BulletFx extends FxList implements ContentList{
Lines.stroke(0.5f + e.fout());
Angles.randLenVectors(e.id, 5, e.fin() * 15f, e.rotation, 50f, (x, y) -> {
float ang = Mathf.atan2(x, y);
float ang = Mathf.angle(x, y);
Lines.lineAngle(e.x + x, e.y + y, ang, e.fout() * 3 + 1f);
});
@@ -94,7 +94,7 @@ public class BulletFx extends FxList implements ContentList{
Lines.stroke(e.fout() * 1.5f);
Angles.randLenVectors(e.id, 8, e.finpow() * 17f, e.rotation, 360f, (x, y) -> {
float ang = Mathf.atan2(x, y);
float ang = Mathf.angle(x, y);
Lines.lineAngle(e.x + x, e.y + y, ang, e.fout() * 4 + 1f);
});
@@ -106,7 +106,7 @@ public class BulletFx extends FxList implements ContentList{
Lines.stroke(e.fout() * 2f);
Angles.randLenVectors(e.id, 6, e.finpow() * 18f, e.rotation, 360f, (x, y) -> {
float ang = Mathf.atan2(x, y);
float ang = Mathf.angle(x, y);
Lines.lineAngle(e.x + x, e.y + y, ang, e.fout() * 4 + 1f);
});
@@ -125,7 +125,7 @@ public class BulletFx extends FxList implements ContentList{
Lines.stroke(e.fout());
Angles.randLenVectors(e.id, 7, e.fin() * 7f, e.rotation, 40f, (x, y) -> {
float ang = Mathf.atan2(x, y);
float ang = Mathf.angle(x, y);
Lines.lineAngle(e.x + x, e.y + y, ang, e.fout() * 2 + 1f);
});
@@ -150,7 +150,7 @@ public class BulletFx extends FxList implements ContentList{
Lines.stroke(1f * e.fout());
Angles.randLenVectors(e.id + 1, 4, 1f + 23f * e.finpow(), (x, y) -> {
Lines.lineAngle(e.x + x, e.y + y, Mathf.atan2(x, y), 1f + e.fout() * 3f);
Lines.lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), 1f + e.fout() * 3f);
});
Draw.reset();
@@ -174,7 +174,7 @@ public class BulletFx extends FxList implements ContentList{
Lines.stroke(1f * e.fout());
Angles.randLenVectors(e.id + 1, 4, 1f + 25f * e.finpow(), (x, y) -> {
Lines.lineAngle(e.x + x, e.y + y, Mathf.atan2(x, y), 1f + e.fout() * 3f);
Lines.lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), 1f + e.fout() * 3f);
});
Draw.reset();
@@ -198,7 +198,7 @@ public class BulletFx extends FxList implements ContentList{
Lines.stroke(1f * e.fout());
Angles.randLenVectors(e.id + 1, 4, 1f + 30f * e.finpow(), (x, y) -> {
Lines.lineAngle(e.x + x, e.y + y, Mathf.atan2(x, y), 1f + e.fout() * 3f);
Lines.lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), 1f + e.fout() * 3f);
});
Draw.reset();
@@ -222,7 +222,7 @@ public class BulletFx extends FxList implements ContentList{
Lines.stroke(1f * e.fout());
Angles.randLenVectors(e.id + 1, 4, 1f + 23f * e.finpow(), (x, y) -> {
Lines.lineAngle(e.x + x, e.y + y, Mathf.atan2(x, y), 1f + e.fout() * 3f);
Lines.lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), 1f + e.fout() * 3f);
});
Draw.reset();
@@ -271,7 +271,7 @@ public class BulletFx extends FxList implements ContentList{
Lines.stroke(1f * e.fout());
Angles.randLenVectors(e.id + 1, 4, 1f + 23f * e.finpow(), (x, y) -> {
Lines.lineAngle(e.x + x, e.y + y, Mathf.atan2(x, y), 1f + e.fout() * 3f);
Lines.lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), 1f + e.fout() * 3f);
});
Draw.reset();

View File

@@ -1,15 +1,15 @@
package io.anuke.mindustry.content.fx;
import com.badlogic.gdx.graphics.Color;
import io.anuke.arc.entities.Effects.Effect;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.Fill;
import io.anuke.arc.math.Angles;
import io.anuke.arc.math.Mathf;
import io.anuke.mindustry.content.Liquids;
import io.anuke.mindustry.game.ContentList;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.type.Item;
import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Fill;
import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf;
public class EnvironmentFx extends FxList implements ContentList{
public static Effect burning, fire, smoke, steam, fireballsmoke, ballfire, freezing, melting, wet, oily, overdriven, dropItem;

View File

@@ -1,14 +1,14 @@
package io.anuke.mindustry.content.fx;
import com.badlogic.gdx.graphics.Color;
import io.anuke.arc.graphics.Color;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.game.ContentList;
import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Fill;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf;
import io.anuke.arc.entities.Effects.Effect;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.Fill;
import io.anuke.arc.graphics.g2d.Lines;
import io.anuke.arc.math.Angles;
import io.anuke.arc.math.Mathf;
public class ExplosionFx extends FxList implements ContentList{
public static Effect shockwave, bigShockwave, nuclearShockwave, explosion, blockExplosion, blockExplosionSmoke;
@@ -54,7 +54,7 @@ public class ExplosionFx extends FxList implements ContentList{
Lines.stroke(1.5f * e.fout());
Angles.randLenVectors(e.id + 1, 8, 1f + 23f * e.finpow(), (x, y) -> {
Lines.lineAngle(e.x + x, e.y + y, Mathf.atan2(x, y), 1f + e.fout() * 3f);
Lines.lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), 1f + e.fout() * 3f);
});
Draw.reset();
@@ -77,7 +77,7 @@ public class ExplosionFx extends FxList implements ContentList{
Lines.stroke(1.7f * e.fout());
Angles.randLenVectors(e.id + 1, 9, 1f + 23f * e.finpow(), (x, y) -> {
Lines.lineAngle(e.x + x, e.y + y, Mathf.atan2(x, y), 1f + e.fout() * 3f);
Lines.lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), 1f + e.fout() * 3f);
});
Draw.reset();

View File

@@ -1,13 +1,13 @@
package io.anuke.mindustry.content.fx;
import com.badlogic.gdx.graphics.Color;
import io.anuke.arc.graphics.Color;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.game.ContentList;
import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Fill;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.util.Angles;
import io.anuke.arc.entities.Effects.Effect;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.Fill;
import io.anuke.arc.graphics.g2d.Lines;
import io.anuke.arc.math.Angles;
import static io.anuke.mindustry.Vars.tilesize;

View File

@@ -1,16 +1,17 @@
package io.anuke.mindustry.content.fx;
import com.badlogic.gdx.graphics.Color;
import io.anuke.arc.Core;
import io.anuke.arc.entities.Effects.Effect;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.Fill;
import io.anuke.arc.graphics.g2d.Lines;
import io.anuke.arc.math.Angles;
import io.anuke.arc.math.Mathf;
import io.anuke.mindustry.entities.effect.GroundEffectEntity.GroundEffect;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.game.ContentList;
import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Fill;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.graphics.Shapes;
import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.graphics.Shapes;
public class ShootFx extends FxList implements ContentList{
public static Effect shootSmall, shootHeal, shootSmallSmoke, shootBig, shootBig2, shootBigSmoke, shootBigSmoke2, shootSmallFlame, shootLiquid, shellEjectSmall, shellEjectMedium, shellEjectBig, lancerLaserShoot, lancerLaserShootSmoke, lancerLaserCharge, lancerLaserChargeBegin, lightningCharge, lightningShoot;
@@ -108,8 +109,7 @@ public class ShootFx extends FxList implements ContentList{
float len = (2f + e.finpow() * 6f) * i;
float lr = rot + e.fin() * 30f * i;
Draw.rect("white",
e.x + Angles.trnsx(lr, len) + Mathf.randomSeedRange(e.id + i + 7, 3f * e.fin()),
Fill.rect(e.x + Angles.trnsx(lr, len) + Mathf.randomSeedRange(e.id + i + 7, 3f * e.fin()),
e.y + Angles.trnsy(lr, len) + Mathf.randomSeedRange(e.id + i + 8, 3f * e.fin()),
1f, 2f, rot + e.fin() * 50f * i);
@@ -122,7 +122,7 @@ public class ShootFx extends FxList implements ContentList{
for(int i : Mathf.signs){
float len = (2f + e.finpow() * 10f) * i;
float lr = rot + e.fin() * 20f * i;
Draw.rect("casing",
Draw.rect(Core.atlas.find("casing"),
e.x + Angles.trnsx(lr, len) + Mathf.randomSeedRange(e.id + i + 7, 3f * e.fin()),
e.y + Angles.trnsy(lr, len) + Mathf.randomSeedRange(e.id + i + 8, 3f * e.fin()),
2f, 3f, rot);
@@ -145,11 +145,11 @@ public class ShootFx extends FxList implements ContentList{
for(int i : Mathf.signs){
float len = (4f + e.finpow() * 8f) * i;
float lr = rot + Mathf.randomSeedRange(e.id + i + 6, 20f * e.fin()) * i;
Draw.rect("casing",
Draw.rect(Core.atlas.find("casing"),
e.x + Angles.trnsx(lr, len) + Mathf.randomSeedRange(e.id + i + 7, 3f * e.fin()),
e.y + Angles.trnsy(lr, len) + Mathf.randomSeedRange(e.id + i + 8, 3f * e.fin()),
2.5f, 4f,
rot + e.fin() * 30f * i + Mathf.randomSeedRange(e.id + i + 9, 40f * e.fin()));
rot + e.fin() * 30f * i + Mathf.randomSeedRange(e.id + i + 9, 40f * e.fin()));
}
Draw.color(Color.LIGHT_GRAY);
@@ -177,7 +177,7 @@ public class ShootFx extends FxList implements ContentList{
Draw.color(Palette.lancerLaser);
Angles.randLenVectors(e.id, 7, 80f, e.rotation, 0f, (x, y) -> {
Lines.lineAngle(e.x + x, e.y + y, Mathf.atan2(x, y), e.fout() * 9f);
Lines.lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), e.fout() * 9f);
});
Draw.reset();
@@ -187,7 +187,7 @@ public class ShootFx extends FxList implements ContentList{
Draw.color(Palette.lancerLaser);
Angles.randLenVectors(e.id, 2, 1f + 20f * e.fout(), e.rotation, 120f, (x, y) -> {
Lines.lineAngle(e.x + x, e.y + y, Mathf.atan2(x, y), e.fslope() * 3f + 1f);
Lines.lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), e.fslope() * 3f + 1f);
});
Draw.reset();
@@ -205,7 +205,7 @@ public class ShootFx extends FxList implements ContentList{
Draw.color(Palette.lancerLaser);
Angles.randLenVectors(e.id, 2, 1f + 20f * e.fout(), e.rotation, 120f, (x, y) -> {
Shapes.tri(e.x + x, e.y + y, e.fslope() * 3f + 1, e.fslope() * 3f + 1, Mathf.atan2(x, y));
Shapes.tri(e.x + x, e.y + y, e.fslope() * 3f + 1, e.fslope() * 3f + 1, Mathf.angle(x, y));
});
Draw.reset();
@@ -216,7 +216,7 @@ public class ShootFx extends FxList implements ContentList{
Lines.stroke(e.fout() * 1.2f + 0.5f);
Angles.randLenVectors(e.id, 7, 25f * e.finpow(), e.rotation, 50f, (x, y) -> {
Lines.lineAngle(e.x + x, e.y + y, Mathf.atan2(x, y), e.fin() * 5f + 2f);
Lines.lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), e.fin() * 5f + 2f);
});
Draw.reset();

View File

@@ -3,12 +3,12 @@ package io.anuke.mindustry.content.fx;
import io.anuke.mindustry.entities.effect.GroundEffectEntity.GroundEffect;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.game.ContentList;
import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Fill;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf;
import io.anuke.arc.entities.Effects.Effect;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.Fill;
import io.anuke.arc.graphics.g2d.Lines;
import io.anuke.arc.math.Angles;
import io.anuke.arc.math.Mathf;
public class UnitFx extends FxList implements ContentList{
public static Effect vtolHover, unitDrop, unitPickup, unitLand, pickup, healWave, heal, landShock;

View File

@@ -1,8 +1,10 @@
package io.anuke.mindustry.core;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.ObjectMap;
import com.badlogic.gdx.utils.ObjectSet;
import io.anuke.arc.collection.Array;
import io.anuke.arc.collection.ObjectMap;
import io.anuke.arc.collection.ObjectSet;
import io.anuke.arc.function.Consumer;
import io.anuke.arc.util.Log;
import io.anuke.mindustry.content.*;
import io.anuke.mindustry.content.blocks.*;
import io.anuke.mindustry.content.bullets.*;
@@ -24,9 +26,6 @@ import io.anuke.mindustry.type.Recipe;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.ColorMapper;
import io.anuke.mindustry.world.LegacyColorMapper;
import io.anuke.ucore.function.Consumer;
import io.anuke.ucore.util.Log;
import io.anuke.ucore.util.ThreadArray;
/**
* Loads all game content.
@@ -114,7 +113,7 @@ public class ContentLoader{
registerTypes();
for(ContentType type : ContentType.values()){
contentMap[type.ordinal()] = new ThreadArray<>();
contentMap[type.ordinal()] = new Array<>();
contentNameMap[type.ordinal()] = new ObjectMap<>();
}

View File

@@ -1,10 +1,18 @@
package io.anuke.mindustry.core;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.utils.ObjectMap;
import com.badlogic.gdx.utils.TimeUtils;
import io.anuke.arc.ApplicationListener;
import io.anuke.arc.Core;
import io.anuke.arc.Events;
import io.anuke.arc.entities.Effects;
import io.anuke.arc.entities.EntityQuery;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.TextureAtlas;
import io.anuke.arc.input.KeyCode;
import io.anuke.arc.scene.ui.TextField;
import io.anuke.arc.util.Interval;
import io.anuke.arc.util.Strings;
import io.anuke.arc.util.Time;
import io.anuke.mindustry.content.Mechs;
import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.Player;
@@ -14,7 +22,7 @@ import io.anuke.mindustry.game.EventType.*;
import io.anuke.mindustry.game.Saves;
import io.anuke.mindustry.game.Unlocks;
import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.input.DefaultKeybinds;
import io.anuke.mindustry.input.Binding;
import io.anuke.mindustry.input.DesktopInput;
import io.anuke.mindustry.input.InputHandler;
import io.anuke.mindustry.input.MobileInput;
@@ -23,16 +31,10 @@ import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.type.ItemStack;
import io.anuke.mindustry.type.Recipe;
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
import io.anuke.ucore.core.*;
import io.anuke.ucore.entities.EntityQuery;
import io.anuke.ucore.modules.Module;
import io.anuke.ucore.util.Atlas;
import io.anuke.ucore.util.Bundles;
import io.anuke.ucore.util.Strings;
import io.anuke.ucore.util.Timer;
import java.io.IOException;
import static io.anuke.arc.Core.scene;
import static io.anuke.mindustry.Vars.*;
/**
@@ -41,51 +43,37 @@ import static io.anuke.mindustry.Vars.*;
* Should <i>not</i> handle any logic-critical state.
* This class is not created in the headless server.
*/
public class Control extends Module{
/** Minimum period of time between the same sound being played.*/
private static final long minSoundPeriod = 100;
public class Control implements ApplicationListener{
public final Saves saves;
public final Unlocks unlocks;
private Timer timerRPC= new Timer(), timerUnlock = new Timer();
private Interval timerRPC = new Interval(), timerUnlock = new Interval();
private boolean hiscore = false;
private boolean wasPaused = false;
private InputHandler[] inputs = {};
private ObjectMap<Sound, Long> soundMap = new ObjectMap<>();
private Throwable error;
public Control(){
saves = new Saves();
unlocks = new Unlocks();
Inputs.useControllers(true);
Gdx.input.setCatchBackKey(true);
Core.input.setCatch(KeyCode.BACK, true);
Effects.setShakeFalloff(10000f);
content.initialize(Content::init);
Core.atlas = new Atlas("sprites.atlas");
Core.atlas.setErrorRegion("error");
Core.atlas = new TextureAtlas("sprites/sprites.atlas");
Draw.scl = 1f / Core.atlas.find("scale_marker").getWidth();
content.initialize(Content::load);
if(Core.atlas.getTextures().size != 1){
throw new IllegalStateException("Atlas must be exactly one texture. " +
"If more textures are used, the map editor will not display them correctly.");
}
unlocks.load();
Sounds.setFalloff(9000f);
Sounds.setPlayer((sound, volume) -> {
long time = TimeUtils.millis();
long value = soundMap.get(sound, 0L);
if(TimeUtils.timeSinceMillis(value) >= minSoundPeriod){
threads.runGraphics(() -> sound.play(volume));
soundMap.put(sound, time);
}
});
DefaultKeybinds.load();
Settings.defaultList(
Core.settings.setAppName(appName);
Core.settings.defaults(
"ip", "localhost",
"color-0", Color.rgba8888(playerColors[8]),
"color-1", Color.rgba8888(playerColors[11]),
@@ -95,15 +83,13 @@ public class Control extends Module{
"lastBuild", 0
);
KeyBinds.load();
addPlayer(0);
saves.load();
Events.on(StateChangeEvent.class, event -> {
if((event.from == State.playing && event.to == State.menu) || (event.from == State.menu && event.to != State.menu)){
Timers.runTask(5f, Platform.instance::updateRPC);
Time.runTask(5f, Platform.instance::updateRPC);
}
});
@@ -115,9 +101,9 @@ public class Control extends Module{
state.set(State.playing);
});
Events.on(WorldLoadGraphicsEvent.class, event -> {
Events.on(WorldLoadEvent.class, event -> {
if(mobile){
Gdx.app.postRunnable(() -> Core.camera.position.set(players[0].x, players[0].y, 0));
Core.app.post(() -> Core.camera.position.set(players[0]));
}
});
@@ -133,11 +119,11 @@ public class Control extends Module{
Events.on(WaveEvent.class, event -> {
int last = Settings.getInt("hiscore" + world.getMap().name, 0);
int last = Core.settings.getInt("hiscore" + world.getMap().name, 0);
if(state.wave > last && !state.mode.infiniteResources && !state.mode.disableWaveTimer && world.getSector() == null){
Settings.putInt("hiscore" + world.getMap().name, state.wave);
Settings.save();
Core.settings.put("hiscore" + world.getMap().name, state.wave);
Core.settings.save();
hiscore = true;
}
@@ -149,12 +135,9 @@ public class Control extends Module{
if(world.getSector() != null && world.getSector().hasSave()){
world.getSector().getSave().delete();
}
threads.runGraphics(() -> {
Effects.shake(5, 6, Core.camera.position.x, Core.camera.position.y);
//the restart dialog can show info for any number of scenarios
Call.onGameOver(event.winner);
});
Effects.shake(5, 6, Core.camera.position.x, Core.camera.position.y);
//the restart dialog can show info for any number of scenarios
Call.onGameOver(event.winner);
});
//autohost for pvp sectors
@@ -164,13 +147,11 @@ public class Control extends Module{
Net.host(port);
players[0].isAdmin = true;
}catch(IOException e){
ui.showError(Bundles.format("text.server.error", Strings.parseException(e, false)));
threads.runDelay(() -> state.set(State.menu));
ui.showError(Core.bundle.format("text.server.error", Strings.parseException(e, false)));
Core.app.post(() -> state.set(State.menu));
}
}
});
Events.on(WorldLoadEvent.class, event -> threads.runGraphics(() -> Events.fire(new WorldLoadGraphicsEvent())));
}
public void addPlayer(int index){
@@ -189,9 +170,9 @@ public class Control extends Module{
Player setTo = (index == 0 ? null : players[0]);
Player player = new Player();
player.name = Settings.getString("name");
player.name = Core.settings.getString("name");
player.mech = mobile ? Mechs.starterMobile : Mechs.starterDesktop;
player.color.set(Settings.getInt("color-" + index));
player.color.set(Core.settings.getInt("color-" + index));
player.isLocal = true;
player.playerIndex = index;
player.isMobile = mobile;
@@ -214,7 +195,7 @@ public class Control extends Module{
}
inputs[index] = input;
Inputs.addProcessor(input);
Core.input.addProcessor(input);
}
public void removePlayer(){
@@ -230,10 +211,6 @@ public class Control extends Module{
System.arraycopy(oldi, 0, inputs, 0, inputs.length);
}
public void setError(Throwable error){
this.error = error;
}
public InputHandler input(int index){
return inputs[index];
}
@@ -266,7 +243,7 @@ public class Control extends Module{
Recipe recipe = content.recipes().get(i);
if(!recipe.isHidden() && recipe.requirements != null){
for(ItemStack stack : recipe.requirements){
if(!entity.items.has(stack.item, Math.min((int) (stack.amount * unlockResourceScaling), 2000))) continue outer;
if(!entity.items.has(stack.item, Math.min((int) (stack.amount), 2000))) continue outer;
}
if(unlocks.unlockContent(recipe)){
@@ -305,16 +282,16 @@ public class Control extends Module{
Platform.instance.updateRPC();
if(!Settings.getBool("4.0-warning-2", false)){
if(!Core.settings.getBool("4.0-warning-2", false)){
Timers.run(5f, () -> {
FloatingDialog dialog = new FloatingDialog("[accent]WARNING![]");
Time.run(5f, () -> {
FloatingDialog dialog = new FloatingDialog("WARNING!");
dialog.buttons().addButton("$text.ok", () -> {
dialog.hide();
Settings.putBool("4.0-warning-2", true);
Settings.save();
Core.settings.put("4.0-warning-2", true);
Core.settings.save();
}).size(100f, 60f);
dialog.content().add("Reminder: The beta version you are about to play is very unstable, and is [accent]not representative of the final 4.0 release.[]\n\n " +
dialog.content().add("Reminder: The alpha version you are about to play is very unstable, and is [accent]not representative of the final 4.0 release.[]\n\n " +
"\nThere is currently[scarlet] no sound implemented[]; this is intentional.\n" +
"All current art and UI is temporary, and will be re-drawn before release. " +
"\n\n[accent]Saves and maps may be corrupted without warning between updates.").wrap().width(400f);
@@ -323,18 +300,8 @@ public class Control extends Module{
}
}
/** Called from main logic thread.*/
public void runUpdateLogic(){
if(!state.is(State.menu)){
renderer.minimap.updateUnitArray();
}
}
@Override
public void update(){
if(error != null){
throw new RuntimeException(error);
}
saves.update();
@@ -362,26 +329,26 @@ public class Control extends Module{
}
}
if(Inputs.keyTap("pause") && !ui.restart.isShown() && (state.is(State.paused) || state.is(State.playing))){
if(Core.input.keyTap(Binding.pause) && !ui.restart.isShown() && (state.is(State.paused) || state.is(State.playing))){
state.set(state.is(State.playing) ? State.paused : State.playing);
}
if(Inputs.keyTap("menu") && !ui.restart.isShown()){
if(Core.input.keyTap(Binding.menu) && !ui.restart.isShown()){
if(ui.chatfrag.chatOpen()){
ui.chatfrag.hide();
}else if(!ui.paused.isShown() && !ui.hasDialog()){
}else if(!ui.paused.isShown() && !scene.hasDialog()){
ui.paused.show();
state.set(State.paused);
}
}
if(!mobile && Inputs.keyTap("screenshot") && !ui.chatfrag.chatOpen()){
if(!mobile && Core.input.keyTap(Binding.screenshot) && !(scene.getKeyboardFocus() instanceof TextField) && !ui.chatfrag.chatOpen()){
renderer.takeMapScreenshot();
}
}else{
if(!state.isPaused()){
Timers.update();
Time.update();
}
}
}

View File

@@ -5,7 +5,7 @@ import io.anuke.mindustry.game.EventType.StateChangeEvent;
import io.anuke.mindustry.game.GameMode;
import io.anuke.mindustry.game.Teams;
import io.anuke.mindustry.net.Net;
import io.anuke.ucore.core.Events;
import io.anuke.arc.Events;
import static io.anuke.mindustry.Vars.unitGroups;
import static io.anuke.mindustry.Vars.waveTeam;

View File

@@ -1,9 +1,14 @@
package io.anuke.mindustry.core;
import com.badlogic.gdx.utils.Array;
import io.anuke.annotations.Annotations.Loc;
import io.anuke.annotations.Annotations.Remote;
import io.anuke.mindustry.Vars;
import io.anuke.arc.ApplicationListener;
import io.anuke.arc.Events;
import io.anuke.arc.collection.Array;
import io.anuke.arc.entities.Entities;
import io.anuke.arc.entities.EntityGroup;
import io.anuke.arc.entities.EntityQuery;
import io.anuke.arc.util.Time;
import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.game.EventType.*;
@@ -16,12 +21,6 @@ import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.type.ItemStack;
import io.anuke.mindustry.type.Recipe;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Events;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.Entities;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.entities.EntityQuery;
import io.anuke.ucore.modules.Module;
import static io.anuke.mindustry.Vars.*;
@@ -33,7 +32,7 @@ import static io.anuke.mindustry.Vars.*;
* <p>
* This class should <i>not</i> call any outside methods to change state of modules, but instead fire events.
*/
public class Logic extends Module{
public class Logic implements ApplicationListener{
public Logic(){
Events.on(TileChangeEvent.class, event -> {
@@ -85,7 +84,7 @@ public class Logic extends Module{
state.gameOver = false;
state.teams = new Teams();
Timers.clear();
Time.clear();
Entities.clear();
TileEntity.sleepingEntities = 0;
@@ -141,7 +140,7 @@ public class Logic extends Module{
@Remote(called = Loc.both)
public static void onGameOver(Team winner){
threads.runGraphics(() -> ui.restart.show(winner));
ui.restart.show(winner);
netClient.setQuiet();
}
@@ -172,17 +171,13 @@ public class Logic extends Module{
@Override
public void update(){
if(Vars.control != null){
control.runUpdateLogic();
}
if(!state.is(State.menu)){
if(!state.isPaused()){
Timers.update();
Time.update();
if(!state.mode.disableWaveTimer && !state.mode.disableWaves && !state.gameOver){
state.wavetime -= Timers.delta();
state.wavetime -= Time.delta();
}
if(!Net.client() && state.wavetime <= 0 && !state.mode.disableWaves){

View File

@@ -1,14 +1,20 @@
package io.anuke.mindustry.core;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.utils.Base64Coder;
import com.badlogic.gdx.utils.IntSet;
import com.badlogic.gdx.utils.TimeUtils;
import io.anuke.annotations.Annotations.Loc;
import io.anuke.annotations.Annotations.PacketPriority;
import io.anuke.annotations.Annotations.Remote;
import io.anuke.annotations.Annotations.Variant;
import io.anuke.arc.ApplicationListener;
import io.anuke.arc.Core;
import io.anuke.arc.collection.IntSet;
import io.anuke.arc.entities.Entities;
import io.anuke.arc.entities.EntityGroup;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.util.Interval;
import io.anuke.arc.util.Log;
import io.anuke.arc.util.Time;
import io.anuke.arc.util.io.ReusableByteArrayInputStream;
import io.anuke.arc.util.serialization.Base64Coder;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.Player;
@@ -25,16 +31,6 @@ import io.anuke.mindustry.net.Packets.*;
import io.anuke.mindustry.net.ValidateException;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.modules.ItemModule;
import io.anuke.ucore.core.Core;
import io.anuke.ucore.core.Settings;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.Entities;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.io.ReusableByteArrayInputStream;
import io.anuke.ucore.modules.Module;
import io.anuke.ucore.util.Log;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Timer;
import java.io.DataInputStream;
import java.io.IOException;
@@ -43,12 +39,12 @@ import java.util.zip.InflaterInputStream;
import static io.anuke.mindustry.Vars.*;
public class NetClient extends Module{
public class NetClient implements ApplicationListener{
private final static float dataTimeout = 60 * 18;
private final static float playerSyncTime = 2;
public final static float viewScale = 2f;
private Timer timer = new Timer(5);
private Interval timer = new Interval(5);
/**Whether the client is currently connecting.*/
private boolean connecting = false;
/**If true, no message will be shown on disconnect.*/
@@ -58,16 +54,6 @@ public class NetClient extends Module{
/**Last sent client snapshot ID.*/
private int lastSent;
/**Last snapshot ID recieved.*/
private int lastSnapshotBaseID = -1;
/**Current snapshot that is being built from chinks.*/
private byte[] currentSnapshot;
/**Counter of how many chunks have been recieved.*/
private int recievedChunkCounter;
/**ID of snapshot that is currently being constructed.*/
private int currentSnapshotID = -1;
/**List of entities that were removed, and need not be added while syncing.*/
private IntSet removed = new IntSet();
/**Byte stream for reading in snapshots.*/
@@ -114,7 +100,7 @@ public class NetClient extends Module{
Net.handleClient(Disconnect.class, packet -> {
if(quiet) return;
Timers.runTask(3f, ui.loadfrag::hide);
Time.runTask(3f, ui.loadfrag::hide);
state.set(State.menu);
@@ -168,21 +154,19 @@ public class NetClient extends Module{
netClient.disconnectQuietly();
state.set(State.menu);
threads.runGraphics(() -> {
if(!reason.quiet){
if(reason.extraText() != null){
ui.showText(reason.toString(), reason.extraText());
}else{
ui.showText("$text.disconnect", reason.toString());
}
if(!reason.quiet){
if(reason.extraText() != null){
ui.showText(reason.toString(), reason.extraText());
}else{
ui.showText("$text.disconnect", reason.toString());
}
ui.loadfrag.hide();
});
}
ui.loadfrag.hide();
}
@Remote(variants = Variant.both)
public static void onInfoMessage(String message){
threads.runGraphics(() -> ui.showText("", message));
ui.showText("", message);
}
@Remote(variants = Variant.both)
@@ -193,15 +177,13 @@ public class NetClient extends Module{
ui.chatfrag.clearMessages();
Net.setClientLoaded(false);
threads.runGraphics(() -> {
ui.loadfrag.show("$text.connecting.data");
ui.loadfrag.show("$text.connecting.data");
ui.loadfrag.setButton(() -> {
ui.loadfrag.hide();
netClient.connecting = false;
netClient.quiet = true;
Net.disconnect();
});
ui.loadfrag.setButton(() -> {
ui.loadfrag.hide();
netClient.connecting = false;
netClient.quiet = true;
Net.disconnect();
});
}
@@ -217,97 +199,11 @@ public class NetClient extends Module{
}
@Remote(variants = Variant.one, priority = PacketPriority.low, unreliable = true)
public static void onSnapshot(byte[] chunk, int snapshotID, short chunkID, int totalLength, int uncompressedLength){
int totalChunks = Mathf.ceil((float) totalLength / NetServer.maxSnapshotSize);
if(NetServer.debugSnapshots)
Log.info("Recieved snapshot: len {0} ID {1} chunkID {2} / "+totalChunks+" totalLength {3} bclient-base {4}", chunk.length, snapshotID, chunkID, totalLength, netClient.lastSnapshotBaseID);
//skip snapshot IDs that have already been recieved OR snapshots that are too far in front
if(snapshotID < netClient.lastSnapshotBaseID){
if(NetServer.debugSnapshots) Log.info("//SKIP SNAPSHOT");
return;
}
public static void onEntitySnapshot(byte groupID, short amount, short dataLen, byte[] data){
try{
byte[] snapshot;
//total length exceeds that needed to hold one snapshot, therefore, it is split into chunks
if(totalLength > NetServer.maxSnapshotSize){
//total amount of chunks to recieve
//reset status when a new snapshot sending begins
if(netClient.currentSnapshotID != snapshotID || netClient.currentSnapshot == null){
netClient.currentSnapshotID = snapshotID;
netClient.currentSnapshot = new byte[totalLength];
netClient.recievedChunkCounter = 0;
}
netClient.recievedChunkCounter++; //update recieved status
//copy the recieved bytes into the holding array
System.arraycopy(chunk, 0, netClient.currentSnapshot, chunkID * NetServer.maxSnapshotSize,
Math.min(NetServer.maxSnapshotSize, totalLength - chunkID * NetServer.maxSnapshotSize));
//when all chunks have been recieved, begin
if(netClient.recievedChunkCounter >= totalChunks && netClient.currentSnapshot != null){
snapshot = netClient.currentSnapshot;
}else{
return;
}
}else{
snapshot = chunk;
}
if(NetServer.debugSnapshots)
Log.info("Finished recieving snapshot ID {0} length {1}", snapshotID, chunk.length);
byte[] result = Net.decompressSnapshot(snapshot, uncompressedLength);
int length = result.length;
netClient.lastSnapshotBaseID = snapshotID;
//set stream bytes to begin snapshot reading
netClient.byteStream.setBytes(result, 0, length);
//get data input for reading from the stream
netClient.byteStream.setBytes(Net.decompressSnapshot(data, dataLen));
DataInputStream input = netClient.dataStream;
netClient.readSnapshot(input);
//confirm that snapshot has been recieved
netClient.lastSnapshotBaseID = snapshotID;
}catch(Exception e){
throw new RuntimeException(e);
}
}
public void readSnapshot(DataInputStream input) throws IOException{
//read wave info
state.wavetime = input.readFloat();
state.wave = input.readInt();
state.enemies = input.readInt();
byte cores = input.readByte();
for(int i = 0; i < cores; i++){
int pos = input.readInt();
Tile tile = world.tile(pos);
if(tile != null && tile.entity != null){
tile.entity.items.read(input);
}else{
new ItemModule().read(input);
}
}
long timestamp = input.readLong();
byte totalGroups = input.readByte();
//for each group...
for(int i = 0; i < totalGroups; i++){
//read group info
byte groupID = input.readByte();
short amount = input.readShort();
EntityGroup group = Entities.getGroup(groupID);
//go through each entity
@@ -328,13 +224,41 @@ public class NetClient extends Module{
}
//read the entity
entity.read(input, timestamp);
entity.read(input);
if(add){
entity.add();
netClient.addRemovedEntity(entity.getID());
}
}
}catch(IOException e){
throw new RuntimeException(e);
}
}
@Remote(variants = Variant.one, priority = PacketPriority.low, unreliable = true)
public static void onStateSnapshot(float waveTime, int wave, int enemies, short coreDataLen, byte[] coreData){
try{
state.wavetime = waveTime;
state.wave = wave;
state.enemies = enemies;
netClient.byteStream.setBytes(Net.decompressSnapshot(coreData, coreDataLen));
DataInputStream input = netClient.dataStream;
byte cores = input.readByte();
for(int i = 0; i < cores; i++){
int pos = input.readInt();
Tile tile = world.tile(pos);
if(tile != null && tile.entity != null){
tile.entity.items.read(input);
}else{
new ItemModule().read(input);
}
}
}catch(IOException e){
throw new RuntimeException(e);
}
}
@@ -347,7 +271,7 @@ public class NetClient extends Module{
}else if(!connecting){
Net.disconnect();
}else{ //...must be connecting
timeoutTime += Timers.delta();
timeoutTime += Time.delta();
if(timeoutTime > dataTimeout){
Log.err("Failed to load data!");
ui.loadfrag.hide();
@@ -369,8 +293,8 @@ public class NetClient extends Module{
ui.loadfrag.hide();
ui.join.hide();
Net.setClientLoaded(true);
Gdx.app.postRunnable(Call::connectConfirm);
Timers.runTask(40f, Platform.instance::updateRPC);
Core.app.post(Call::connectConfirm);
Time.runTask(40f, Platform.instance::updateRPC);
}
private void reset(){
@@ -380,9 +304,6 @@ public class NetClient extends Module{
connecting = true;
quiet = false;
lastSent = 0;
currentSnapshot = null;
currentSnapshotID = -1;
lastSnapshotBaseID = -1;
Entities.clear();
ui.chatfrag.clearMessages();
@@ -416,19 +337,21 @@ public class NetClient extends Module{
Player player = players[0];
BuildRequest[] requests;
//limit to 10 to prevent buffer overflows
int usedRequests = Math.min(player.getPlaceQueue().size, 10);
requests = new BuildRequest[player.getPlaceQueue().size];
for(int i = 0; i < requests.length; i++){
requests = new BuildRequest[usedRequests];
for(int i = 0; i < usedRequests; i++){
requests[i] = player.getPlaceQueue().get(i);
}
Call.onClientShapshot(lastSent++, TimeUtils.millis(), player.x, player.y,
Call.onClientShapshot(lastSent++, Time.millis(), player.x, player.y,
player.pointerX, player.pointerY, player.rotation, player.baseRotation,
player.getVelocity().x, player.getVelocity().y,
player.getMineTile(),
player.isBoosting, player.isShooting, requests,
Core.camera.position.x, Core.camera.position.y,
Core.camera.viewportWidth * Core.camera.zoom * viewScale, Core.camera.viewportHeight * Core.camera.zoom * viewScale);
Core.camera.width * viewScale, Core.camera.height * viewScale);
}
if(timer.get(1, 60)){
@@ -437,14 +360,14 @@ public class NetClient extends Module{
}
String getUsid(String ip){
if(Settings.getString("usid-" + ip, null) != null){
return Settings.getString("usid-" + ip, null);
if(Core.settings.getString("usid-" + ip, null) != null){
return Core.settings.getString("usid-" + ip, null);
}else{
byte[] bytes = new byte[8];
new Random().nextBytes(bytes);
String result = new String(Base64Coder.encode(bytes));
Settings.putString("usid-" + ip, result);
Settings.save();
Core.settings.put("usid-" + ip, result);
Core.settings.save();
return result;
}
}

View File

@@ -1,15 +1,26 @@
package io.anuke.mindustry.core;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Colors;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.IntMap;
import com.badlogic.gdx.utils.ObjectSet;
import com.badlogic.gdx.utils.TimeUtils;
import io.anuke.annotations.Annotations.Loc;
import io.anuke.annotations.Annotations.Remote;
import io.anuke.arc.ApplicationListener;
import io.anuke.arc.Events;
import io.anuke.arc.collection.Array;
import io.anuke.arc.collection.IntMap;
import io.anuke.arc.collection.ObjectSet;
import io.anuke.arc.entities.Entities;
import io.anuke.arc.entities.EntityGroup;
import io.anuke.arc.entities.EntityQuery;
import io.anuke.arc.entities.trait.Entity;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.Colors;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.geom.Rectangle;
import io.anuke.arc.math.geom.Vector2;
import io.anuke.arc.util.Log;
import io.anuke.arc.util.Structs;
import io.anuke.arc.util.Time;
import io.anuke.arc.util.io.ByteBufferOutput;
import io.anuke.arc.util.io.CountableByteArrayOutputStream;
import io.anuke.mindustry.content.Mechs;
import io.anuke.mindustry.content.blocks.Blocks;
import io.anuke.mindustry.core.GameState.State;
@@ -21,35 +32,25 @@ import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.game.Version;
import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.gen.RemoteReadServer;
import io.anuke.mindustry.net.*;
import io.anuke.mindustry.net.Administration;
import io.anuke.mindustry.net.Administration.PlayerInfo;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.NetConnection;
import io.anuke.mindustry.net.NetworkIO;
import io.anuke.mindustry.net.Packets.*;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Events;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.Entities;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.entities.EntityQuery;
import io.anuke.ucore.entities.trait.Entity;
import io.anuke.ucore.io.ByteBufferOutput;
import io.anuke.ucore.io.CountableByteArrayOutputStream;
import io.anuke.ucore.modules.Module;
import io.anuke.ucore.util.Structs;
import io.anuke.ucore.util.Log;
import io.anuke.ucore.util.Mathf;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.zip.DeflaterOutputStream;
import static io.anuke.mindustry.Vars.*;
public class NetServer extends Module{
public final static int maxSnapshotSize = 2047;
public class NetServer implements ApplicationListener{
public final static int maxSnapshotSize = 430;
public final static boolean debugSnapshots = false;
public final static float maxSnapshotDelay = 200;
@@ -122,7 +123,7 @@ public class NetServer extends Module{
return;
}
if(TimeUtils.millis() - info.lastKicked < kickDuration){
if(Time.millis() - info.lastKicked < kickDuration){
kick(id, KickReason.recentKick);
return;
}
@@ -224,45 +225,6 @@ public class NetServer extends Module{
});
}
/** Sends a raw byte[] snapshot to a client, splitting up into chunks when needed.*/
private static void sendSplitSnapshot(int userid, byte[] bytes, int snapshotID, int uncompressedLength){
if(bytes.length < maxSnapshotSize){
scheduleSnapshot(() -> Call.onSnapshot(userid, bytes, snapshotID, (short) 0, bytes.length, uncompressedLength));
}else{
int remaining = bytes.length;
int offset = 0;
int chunkid = 0;
while(remaining > 0){
int used = Math.min(remaining, maxSnapshotSize);
byte[] toSend;
//re-use sent byte arrays when possible
if(used == maxSnapshotSize && !debugSnapshots){
toSend = reusableSnapArray;
System.arraycopy(bytes, offset, toSend, 0, Math.min(offset + maxSnapshotSize, bytes.length) - offset);
}else{
toSend = Arrays.copyOfRange(bytes, offset, Math.min(offset + maxSnapshotSize, bytes.length));
}
short fchunk = (short)chunkid;
scheduleSnapshot(() -> Call.onSnapshot(userid, toSend, snapshotID, fchunk, bytes.length, uncompressedLength));
remaining -= used;
offset += used;
chunkid++;
}
}
}
private static void scheduleSnapshot(Runnable r){
if(debugSnapshots){
if(!Mathf.chance(snapshotDropchance)){
Timers.run(maxSnapshotDelay / 1000f * 60f, r);
}
}else{
r.run();
}
}
public void sendWorldData(Player player, int clientID){
ByteArrayOutputStream stream = new ByteArrayOutputStream();
DeflaterOutputStream def = new DeflaterOutputStream(stream);
@@ -311,14 +273,14 @@ public class NetServer extends Module{
boolean verifyPosition = !player.isDead() && netServer.admins.getStrict() && headless && player.getCarrier() == null;
if(connection.lastRecievedClientTime == 0) connection.lastRecievedClientTime = TimeUtils.millis() - 16;
if(connection.lastRecievedClientTime == 0) connection.lastRecievedClientTime = Time.millis() - 16;
connection.viewX = viewX;
connection.viewY = viewY;
connection.viewWidth = viewWidth;
connection.viewHeight = viewHeight;
long elapsed = TimeUtils.timeSinceMillis(connection.lastRecievedClientTime);
long elapsed = Time.timeSinceMillis(connection.lastRecievedClientTime);
float maxSpeed = boosting && !player.mech.flying ? player.mech.boostSpeed : player.mech.speed;
float maxMove = elapsed / 1000f * 60f * Math.min(compound(maxSpeed, player.mech.drag) * 1.25f, player.mech.maxSpeed * 1.1f);
@@ -357,7 +319,7 @@ public class NetServer extends Module{
player.y = prevy;
newx = x;
newy = y;
}else if(Vector2.dst(x, y, newx, newy) > correctDist){
}else if(Mathf.dst(x, y, newx, newy) > correctDist){
Call.onPositionSet(player.con.id, newx, newy); //teleport and correct position when necessary
}
@@ -370,7 +332,7 @@ public class NetServer extends Module{
player.getVelocity().set(xVelocity, yVelocity); //only for visual calculation purposes, doesn't actually update the player
connection.lastRecievedClientSnapshot = snapshotID;
connection.lastRecievedClientTime = TimeUtils.millis();
connection.lastRecievedClientTime = Time.millis();
}
@Remote(targets = Loc.client, called = Loc.server)
@@ -436,8 +398,8 @@ public class NetServer extends Module{
if(!headless && !closing && Net.server() && state.is(State.menu)){
closing = true;
threads.runGraphics(() -> ui.loadfrag.show("$text.server.closing"));
Timers.runTask(5f, () -> {
ui.loadfrag.show("$text.server.closing");
Time.runTask(5f, () -> {
Net.closeServer();
ui.loadfrag.hide();
closing = false;
@@ -469,45 +431,34 @@ public class NetServer extends Module{
if(player != null && (reason == KickReason.kick || reason == KickReason.banned) && player.uuid != null){
PlayerInfo info = admins.getInfo(player.uuid);
info.timesKicked++;
info.lastKicked = TimeUtils.millis();
info.lastKicked = Time.millis();
}
Call.onKick(connection, reason);
Timers.runTask(2f, con::close);
Time.runTask(2f, con::close);
admins.save();
}
public void writeSnapshot(Player player, DataOutputStream dataStream) throws IOException{
viewport.setSize(player.con.viewWidth, player.con.viewHeight).setCenter(player.con.viewX, player.con.viewY);
//write wave datas
dataStream.writeFloat(state.wavetime);
dataStream.writeInt(state.wave);
dataStream.writeInt(state.enemies());
public void writeSnapshot(Player player) throws IOException{
syncStream.reset();
ObjectSet<Tile> cores = state.teams.get(player.getTeam()).cores;
dataStream.writeByte(cores.size);
//write all core inventory data
for(Tile tile : cores){
dataStream.writeInt(tile.pos());
tile.entity.items.write(dataStream);
}
//write timestamp
dataStream.writeLong(TimeUtils.millis());
dataStream.close();
byte[] stateBytes = syncStream.toByteArray();
int totalGroups = 0;
//write basic state data.
Call.onStateSnapshot(player.con.id, state.wavetime, state.wave, state.enemies, (short)stateBytes.length, Net.compressSnapshot(stateBytes));
for(EntityGroup<?> group : Entities.getAllGroups()){
if(!group.isEmpty() && (group.all().get(0) instanceof SyncTrait)) totalGroups++;
}
//write total amount of serializable groups
dataStream.writeByte(totalGroups);
viewport.setSize(player.con.viewWidth, player.con.viewHeight).setCenter(player.con.viewX, player.con.viewY);
//check for syncable groups
for(EntityGroup<?> group : Entities.getAllGroups()){
@@ -535,15 +486,32 @@ public class NetServer extends Module{
}
}
//write group ID + group size
dataStream.writeByte(group.getID());
dataStream.writeShort(returnArray.size);
syncStream.reset();
int sent = 0;
for(Entity entity : returnArray){
//write all entities now
dataStream.writeInt(entity.getID()); //write id
dataStream.writeByte(((SyncTrait) entity).getTypeID()); //write type ID
((SyncTrait) entity).write(dataStream); //write entity
sent ++;
if(syncStream.position() > maxSnapshotSize){
dataStream.close();
byte[] syncBytes = syncStream.toByteArray();
Call.onEntitySnapshot(player.con.id, (byte)group.getID(), (short)sent, (short)syncBytes.length, Net.compressSnapshot(syncBytes));
sent = 0;
syncStream.reset();
}
}
if(sent > 0){
dataStream.close();
byte[] syncBytes = syncStream.toByteArray();
Call.onEntitySnapshot(player.con.id, (byte)group.getID(), (short)sent, (short)syncBytes.length, Net.compressSnapshot(syncBytes));
}
}
}
@@ -617,21 +585,7 @@ public class NetServer extends Module{
if(!player.timer.get(Player.timerSync, serverSyncTime) || !connection.hasConnected) continue;
//reset stream to begin writing
Timers.mark();
syncStream.reset();
writeSnapshot(player, dataStream);
dataStream.close();
byte[] bytes = syncStream.toByteArray();
int uncompressed = bytes.length;
bytes = Net.compressSnapshot(bytes);
int snapid = connection.lastSentSnapshotID ++;
if(debugSnapshots) Log.info("Sent snapshot: {0} bytes.", bytes.length);
sendSplitSnapshot(connection.id, bytes, snapid, uncompressed);
writeSnapshot(player);
}
}catch(IOException e){

View File

@@ -1,15 +1,11 @@
package io.anuke.mindustry.core;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.utils.Base64Coder;
import io.anuke.ucore.core.Core;
import io.anuke.ucore.core.Settings;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.function.Consumer;
import io.anuke.ucore.scene.ui.Dialog;
import io.anuke.ucore.scene.ui.TextField;
import io.anuke.arc.Core;
import io.anuke.arc.Input.TextInput;
import io.anuke.arc.files.FileHandle;
import io.anuke.arc.function.Consumer;
import io.anuke.arc.scene.ui.TextField;
import io.anuke.arc.util.serialization.Base64Coder;
import java.util.Random;
@@ -28,40 +24,16 @@ public abstract class Platform {
if(!mobile) return; //this is mobile only, desktop doesn't need dialogs
field.tapped(() -> {
Dialog dialog = new Dialog("", "dialog");
dialog.setFillParent(true);
dialog.content().top();
dialog.content().defaults().height(65f);
TextField[] use = {null};
dialog.content().addImageButton("icon-copy", "clear", 16*3, () -> use[0].copy())
.visible(() -> !use[0].getSelection().isEmpty()).width(65f);
dialog.content().addImageButton("icon-paste", "clear", 16*3, () ->
use[0].paste(Gdx.app.getClipboard().getContents(), false))
.visible(() -> Gdx.app.getClipboard() != null && Gdx.app.getClipboard().getContents() != null && !Gdx.app.getClipboard().getContents().isEmpty()).width(65f);
TextField to = dialog.content().addField(field.getText(), t-> {}).pad(15).width(250f).get();
to.setMaxLength(maxLength);
to.keyDown(Keys.ENTER, () -> dialog.content().find("okb").fireClick());
use[0] = to;
dialog.content().addButton("$text.ok", () -> {
TextInput input = new TextInput();
input.text = field.getText();
input.maxLength = maxLength;
input.accepted = text -> {
field.clearText();
field.appendText(to.getText());
field.appendText(text);
field.change();
dialog.hide();
Gdx.input.setOnscreenKeyboardVisible(false);
}).width(90f).name("okb");
dialog.show();
Timers.runTask(1f, () -> {
to.setCursorPosition(to.getText().length());
Core.scene.setKeyboardFocus(to);
Gdx.input.setOnscreenKeyboardVisible(true);
});
Core.input.setOnscreenKeyboardVisible(false);
};
Core.input.getTextInput(input);
});
}
/**Update discord RPC.*/
@@ -76,13 +48,13 @@ public abstract class Platform {
}
/**Must be a base64 string 8 bytes in length.*/
public String getUUID(){
String uuid = Settings.getString("uuid", "");
String uuid = Core.settings.getString("uuid", "");
if(uuid.isEmpty()){
byte[] result = new byte[8];
new Random().nextBytes(result);
uuid = new String(Base64Coder.encode(result));
Settings.putString("uuid", uuid);
Settings.save();
Core.settings.put("uuid", uuid);
Core.settings.save();
return uuid;
}
return uuid;

View File

@@ -1,16 +1,26 @@
package io.anuke.mindustry.core;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.PixmapIO;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.BufferUtils;
import com.badlogic.gdx.utils.ScreenUtils;
import com.badlogic.gdx.utils.TimeUtils;
import io.anuke.arc.ApplicationListener;
import io.anuke.arc.Core;
import io.anuke.arc.entities.Effects;
import io.anuke.arc.entities.EntityDraw;
import io.anuke.arc.entities.EntityGroup;
import io.anuke.arc.entities.impl.EffectEntity;
import io.anuke.arc.entities.trait.DrawTrait;
import io.anuke.arc.entities.trait.Entity;
import io.anuke.arc.function.Consumer;
import io.anuke.arc.function.Predicate;
import io.anuke.arc.graphics.Camera;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.Lines;
import io.anuke.arc.graphics.g2d.SpriteBatch;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.geom.Rectangle;
import io.anuke.arc.math.geom.Vector2;
import io.anuke.arc.util.ScreenRecorder;
import io.anuke.arc.util.Time;
import io.anuke.arc.util.pooling.Pools;
import io.anuke.mindustry.content.fx.Fx;
import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.Player;
@@ -22,62 +32,45 @@ import io.anuke.mindustry.entities.traits.BelowLiquidTrait;
import io.anuke.mindustry.entities.units.BaseUnit;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.graphics.*;
import io.anuke.mindustry.world.blocks.defense.ForceProjector.ShieldEntity;
import io.anuke.ucore.core.Core;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Graphics;
import io.anuke.ucore.core.Settings;
import io.anuke.ucore.entities.EntityDraw;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.entities.impl.EffectEntity;
import io.anuke.ucore.entities.trait.DrawTrait;
import io.anuke.ucore.entities.trait.Entity;
import io.anuke.ucore.function.Consumer;
import io.anuke.ucore.function.Predicate;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.graphics.Surface;
import io.anuke.ucore.modules.RendererModule;
import io.anuke.ucore.scene.utils.Cursors;
import io.anuke.ucore.util.Bundles;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Pooling;
import io.anuke.ucore.util.Translator;
import static io.anuke.arc.Core.*;
import static io.anuke.mindustry.Vars.*;
import static io.anuke.ucore.core.Core.batch;
import static io.anuke.ucore.core.Core.camera;
public class Renderer extends RendererModule{
public final Surface effectSurface;
public class Renderer implements ApplicationListener{
public final BlockRenderer blocks = new BlockRenderer();
public final MinimapRenderer minimap = new MinimapRenderer();
public final OverlayRenderer overlays = new OverlayRenderer();
public final FogRenderer fog = new FogRenderer();
private int targetscale = baseCameraScale;
private Color clearColor;
private float targetscale = io.anuke.arc.scene.ui.layout.Unit.dp.scl(4);
private float camerascale = targetscale;
private Rectangle rect = new Rectangle(), rect2 = new Rectangle();
private Vector2 avgPosition = new Translator();
private Vector2 avgPosition = new Vector2();
private float shakeIntensity, shaketime;
public Renderer(){
Core.batch = new SpriteBatch(4096);
batch = new SpriteBatch(4096);
camera = new Camera();
Lines.setCircleVertices(14);
Shaders.init();
Core.cameraScale = baseCameraScale;
Effects.setScreenShakeProvider((intensity, duration) -> {
shakeIntensity = Math.max(intensity, shakeIntensity);
shaketime = Math.max(shaketime, duration);
});
Effects.setEffectProvider((effect, color, x, y, rotation, data) -> {
if(effect == Fx.none) return;
if(Settings.getBool("effects")){
Rectangle view = rect.setSize(camera.viewportWidth, camera.viewportHeight)
if(Core.settings.getBool("effects")){
Rectangle view = rect.setSize(camera.width, camera.height)
.setCenter(camera.position.x, camera.position.y);
Rectangle pos = rect2.setSize(effect.size).setCenter(x, y);
if(view.overlaps(pos)){
if(!(effect instanceof GroundEffect)){
EffectEntity entity = Pooling.obtain(EffectEntity.class, EffectEntity::new);
EffectEntity entity = Pools.obtain(EffectEntity.class, EffectEntity::new);
entity.effect = effect;
entity.color = color;
entity.rotation = rotation;
@@ -87,9 +80,9 @@ public class Renderer extends RendererModule{
if(data instanceof Entity){
entity.setParent((Entity) data);
}
threads.runGraphics(() -> effectGroup.add(entity));
effectGroup.add(entity);
}else{
GroundEffectEntity entity = Pooling.obtain(GroundEffectEntity.class, GroundEffectEntity::new);
GroundEffectEntity entity = Pools.obtain(GroundEffectEntity.class, GroundEffectEntity::new);
entity.effect = effect;
entity.color = color;
entity.rotation = rotation;
@@ -99,30 +92,13 @@ public class Renderer extends RendererModule{
if(data instanceof Entity){
entity.setParent((Entity) data);
}
threads.runGraphics(() -> groundEffectGroup.add(entity));
groundEffectGroup.add(entity);
}
}
}
});
Cursors.cursorScaling = 3;
Cursors.outlineColor = Color.valueOf("444444");
Cursors.arrow = Cursors.loadCursor("cursor");
Cursors.hand = Cursors.loadCursor("hand");
Cursors.ibeam = Cursors.loadCursor("ibar");
Cursors.restoreCursor();
Cursors.loadCustom("drill");
Cursors.loadCustom("unload");
clearColor = new Color(0f, 0f, 0f, 1f);
effectSurface = Graphics.createSurface(Core.cameraScale);
pixelSurface = Graphics.createSurface(Core.cameraScale);
}
@Override
public void init(){
}
@Override
@@ -130,113 +106,77 @@ public class Renderer extends RendererModule{
//TODO hack, find source of this bug
Color.WHITE.set(1f, 1f, 1f, 1f);
if(Core.cameraScale != targetscale){
float targetzoom = (float) Core.cameraScale / targetscale;
camera.zoom = Mathf.lerpDelta(camera.zoom, targetzoom, 0.2f);
if(Mathf.in(camera.zoom, targetzoom, 0.005f)){
camera.zoom = 1f;
Graphics.setCameraScale(targetscale);
for(Player player : players){
control.input(player.playerIndex).resetCursor();
}
}
}else{
camera.zoom = Mathf.lerpDelta(camera.zoom, 1f, 0.2f);
}
camerascale = Mathf.lerpDelta(camerascale, targetscale, 0.1f);
camera.width = graphics.getWidth() / camerascale;
camera.height = graphics.getHeight() / camerascale;
if(state.is(State.menu)){
Graphics.clear(Color.BLACK);
graphics.clear(Color.BLACK);
}else{
Vector2 position = averagePosition();
if(players[0].isDead()){
TileEntity core = players[0].getClosestCore();
if(core != null && players[0].spawner == Unit.noSpawner){
smoothCamera(core.x, core.y, 0.08f);
camera.position.lerpDelta(core.x, core.y, 0.08f);
}else{
smoothCamera(position.x + 0.0001f, position.y + 0.0001f, 0.08f);
camera.position.lerpDelta(position, 0.08f);
}
}else if(!mobile){
setCamera(position.x + 0.0001f, position.y + 0.0001f);
camera.position.lerpDelta(position, 0.08f);
}
camera.position.x = Mathf.clamp(camera.position.x, -tilesize / 2f, world.width() * tilesize - tilesize / 2f);
camera.position.y = Mathf.clamp(camera.position.y, -tilesize / 2f, world.height() * tilesize - tilesize / 2f);
float prex = camera.position.x, prey = camera.position.y;
updateShake(0.75f);
float deltax = camera.position.x - prex, deltay = camera.position.y - prey;
float lastx = camera.position.x, lasty = camera.position.y;
if(snapCamera){
camera.position.set((int) camera.position.x, (int) camera.position.y, 0);
}
if(Gdx.graphics.getHeight() / Core.cameraScale % 2 == 1){
camera.position.add(0, -0.5f, 0);
}
if(Gdx.graphics.getWidth() / Core.cameraScale % 2 == 1){
camera.position.add(-0.5f, 0, 0);
}
draw();
camera.position.set(lastx - deltax, lasty - deltay, 0);
}
if(!ui.chatfrag.chatOpen()){
renderer.record(); //this only does something if GdxGifRecorder is on the class path, which it usually isn't
ScreenRecorder.record(); //this only does something if CoreGifRecorder is on the class path, which it usually isn't
}
}
void updateShake(float scale){
if(shaketime > 0){
float intensity = shakeIntensity * (settings.getInt("screenshake", 4) / 4f) * scale;
camera.position.add(Mathf.range(intensity), Mathf.range(intensity));
shakeIntensity -= 0.25f * Time.delta();
shaketime -= Time.delta();
shakeIntensity = Mathf.clamp(shakeIntensity, 0f, 100f);
}else{
shakeIntensity = 0f;
}
}
@Override
public void draw(){
camera.update();
if(Float.isNaN(Core.camera.position.x) || Float.isNaN(Core.camera.position.y)){
Core.camera.position.x = players[0].x;
Core.camera.position.y = players[0].y;
if(Float.isNaN(camera.position.x) || Float.isNaN(camera.position.y)){
camera.position.x = players[0].x;
camera.position.y = players[0].y;
}
Graphics.clear(clearColor);
graphics.clear(clearColor);
batch.setProjectionMatrix(camera.combined);
Draw.proj(camera.projection());
Graphics.surface(pixelSurface, false);
Graphics.clear(clearColor);
blocks.drawFloor();
blocks.floor.drawFloor();
drawAndInterpolate(groundEffectGroup, e -> e instanceof BelowLiquidTrait);
drawAndInterpolate(puddleGroup);
drawAndInterpolate(groundEffectGroup, e -> !(e instanceof BelowLiquidTrait));
blocks.processBlocks();
blocks.drawShadows();
for(Team team : Team.all){
if(blocks.isTeamShown(team)){
boolean outline = team != players[0].getTeam() && team != Team.none;
blocks.drawBlocks(Layer.block);
if(outline){
Shaders.outline.color.set(team.color);
Shaders.outline.color.a = 0.8f;
Graphics.beginShaders(Shaders.outline);
}
blocks.drawTeamBlocks(Layer.block, team);
if(outline){
Graphics.endShaders();
}
}
}
blocks.skipLayer(Layer.block);
Graphics.shader(Shaders.blockbuild, false);
Draw.shader(Shaders.blockbuild, true);
blocks.drawBlocks(Layer.placement);
Graphics.shader();
Draw.shader();
blocks.drawBlocks(Layer.overlay);
@@ -255,39 +195,34 @@ public class Renderer extends RendererModule{
overlays.drawBottom();
drawAndInterpolate(playerGroup, p -> true, Player::drawBuildRequests);
Graphics.beginShaders(Shaders.shield);
EntityDraw.draw(shieldGroup);
EntityDraw.drawWith(shieldGroup, shield -> true, shield -> ((ShieldEntity)shield).drawOver());
Draw.color(Palette.accent);
Graphics.endShaders();
Draw.color();
//TODO shield
/*
if(shieldGroup.size() > 0){
Graphics.beginShaders(Shaders.shield);
EntityDraw.draw(shieldGroup);
EntityDraw.drawWith(shieldGroup, shield -> true, shield -> ((ShieldEntity)shield).drawOver());
Draw.color(Palette.accent);
Graphics.endShaders();
Draw.color();
}
*/
overlays.drawTop();
if(showFog){
Graphics.surface();
}else{
Graphics.flushSurface();
}
batch.end();
if(showFog){
fog.draw();
}
Graphics.beginCam();
EntityDraw.setClip(false);
drawAndInterpolate(playerGroup, p -> !p.isDead() && !p.isLocal, Player::drawName);
EntityDraw.setClip(true);
Graphics.end();
Draw.color();
Draw.flush();
}
private void drawFlyerShadows(){
Graphics.surface(effectSurface, true, false);
//TODO fix flyer shadows
//Graphics.surface(effectSurface, true, false);
float trnsX = -12, trnsY = -13;
Draw.color(0, 0, 0, 0.15f);
for(EntityGroup<? extends BaseUnit> group : unitGroups){
if(!group.isEmpty()){
@@ -299,8 +234,8 @@ public class Renderer extends RendererModule{
drawAndInterpolate(playerGroup, unit -> unit.isFlying() && !unit.isDead(), player -> player.drawShadow(trnsX, trnsY));
}
Draw.color(0, 0, 0, 0.15f);
Graphics.flushSurface();
//Draw.color(0, 0, 0, 0.15f);
//Graphics.flushSurface();
Draw.color();
}
@@ -317,13 +252,13 @@ public class Renderer extends RendererModule{
Shaders.outline.color.set(team.color);
Shaders.mix.color.set(Color.WHITE);
Graphics.beginShaders(Shaders.outline);
Graphics.shader(Shaders.mix, true);
//Graphics.beginShaders(Shaders.outline);
Draw.shader(Shaders.mix, true);
drawAndInterpolate(unitGroups[team.ordinal()], u -> u.isFlying() == flying && !u.isDead(), Unit::drawAll);
drawAndInterpolate(playerGroup, p -> p.isFlying() == flying && p.getTeam() == team, Unit::drawAll);
Graphics.shader();
Draw.shader();
blocks.drawTeamBlocks(Layer.turret, team);
Graphics.endShaders();
//Graphics.endShaders();
drawAndInterpolate(unitGroups[team.ordinal()], u -> u.isFlying() == flying && !u.isDead(), Unit::drawOver);
drawAndInterpolate(playerGroup, p -> p.isFlying() == flying && p.getTeam() == team, Unit::drawOver);
@@ -342,20 +277,8 @@ public class Renderer extends RendererModule{
EntityDraw.drawWith(group, toDraw, drawer);
}
@Override
public void resize(int width, int height){
float lastX = camera.position.x, lastY = camera.position.y;
super.resize(width, height);
for(Player player : players){
control.input(player.playerIndex).resetCursor();
}
camera.update();
camera.position.set(lastX, lastY, 0f);
}
@Override
public void dispose(){
fog.dispose();
public float cameraScale(){
return camerascale;
}
public Vector2 averagePosition(){
@@ -367,43 +290,35 @@ public class Renderer extends RendererModule{
return avgPosition;
}
public void setCameraScale(int amount){
targetscale = amount;
public void scaleCamera(float amount){
targetscale += amount;
clampScale();
//scale up all surfaces in preparation for the zoom
for(Surface surface : Graphics.getSurfaces()){
surface.setScale(targetscale);
}
}
public void scaleCamera(int amount){
setCameraScale(targetscale + amount);
}
public void clampScale(){
float s = io.anuke.ucore.scene.ui.layout.Unit.dp.scl(1f);
targetscale = Mathf.clamp(targetscale, Math.round(s * 2), Math.round(s * 5));
float s = io.anuke.arc.scene.ui.layout.Unit.dp.scl(1f);
targetscale = Mathf.clamp(targetscale, s * 2.5f, Math.round(s * 7));
}
public void takeMapScreenshot(){
float vpW = Core.camera.viewportWidth, vpH = Core.camera.viewportHeight;
//TODO fix/implement
/*
float vpW = camera.width, vpH = camera.height;
int w = world.width()*tilesize, h = world.height()*tilesize;
int pw = pixelSurface.width(), ph = pixelSurface.height();
showFog = false;
disableUI = true;
pixelSurface.setSize(w, h, true);
Graphics.getEffectSurface().setSize(w, h, true);
Core.camera.viewportWidth = w;
Core.camera.viewportHeight = h;
Core.camera.position.x = w/2f + tilesize/2f;
Core.camera.position.y = h/2f + tilesize/2f;
camera.width = w;
camera.height = h;
camera.position.x = w/2f + tilesize/2f;
camera.position.y = h/2f + tilesize/2f;
draw();
showFog = true;
disableUI = false;
Core.camera.viewportWidth = vpW;
Core.camera.viewportHeight = vpH;
camera.width = vpW;
camera.height = vpH;
pixelSurface.getBuffer().begin();
byte[] lines = ScreenUtils.getFrameBufferPixels(0, 0, w, h, true);
@@ -415,14 +330,14 @@ public class Renderer extends RendererModule{
Pixmap fullPixmap = new Pixmap(w, h, Pixmap.Format.RGBA8888);
BufferUtils.copy(lines, 0, fullPixmap.getPixels(), lines.length);
FileHandle file = screenshotDirectory.child("screenshot-" + TimeUtils.millis() + ".png");
FileHandle file = screenshotDirectory.child("screenshot-" + Time.millis() + ".png");
PixmapIO.writePNG(file, fullPixmap);
fullPixmap.dispose();
pixelSurface.setSize(pw, ph, false);
Graphics.getEffectSurface().setSize(pw, ph, false);
ui.showInfoFade(Bundles.format("text.screenshot", file.toString()));
ui.showInfoFade(Core.bundle.format("text.screenshot", file.toString()));*/
}
}

View File

@@ -1,54 +0,0 @@
package io.anuke.mindustry.core;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.utils.TimeUtils;
import io.anuke.ucore.core.Settings;
import io.anuke.ucore.core.Timers;
public class ThreadHandler{
private long lastFrameTime;
public ThreadHandler(){
Timers.setDeltaProvider(() -> {
float result = Gdx.graphics.getDeltaTime() * 60f;
return Float.isNaN(result) || Float.isInfinite(result) ? 1f : Math.min(result, 60f / 10f);
});
}
public void run(Runnable r){
r.run();
}
public void runGraphics(Runnable r){
r.run();
}
public void runDelay(Runnable r){
Gdx.app.postRunnable(r);
}
public long getFrameID(){
return Gdx.graphics.getFrameId();
}
public void handleBeginRender(){
lastFrameTime = TimeUtils.millis();
}
public void handleEndRender(){
int fpsCap = Settings.getInt("fpscap", 125);
if(fpsCap <= 120){
long target = 1000/fpsCap;
long elapsed = TimeUtils.timeSinceMillis(lastFrameTime);
if(elapsed < target){
try{
Thread.sleep(target - elapsed);
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
}

View File

@@ -1,47 +1,50 @@
package io.anuke.mindustry.core;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Colors;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator.FreeTypeFontParameter;
import com.badlogic.gdx.math.Interpolation;
import com.badlogic.gdx.utils.Align;
import io.anuke.arc.ApplicationListener;
import io.anuke.arc.Core;
import io.anuke.arc.Events;
import io.anuke.arc.Graphics.Cursor;
import io.anuke.arc.Graphics.Cursor.SystemCursor;
import io.anuke.arc.freetype.FreeTypeFontGenerator;
import io.anuke.arc.freetype.FreeTypeFontGenerator.FreeTypeFontParameter;
import io.anuke.arc.function.Consumer;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.Colors;
import io.anuke.arc.graphics.g2d.BitmapFont;
import io.anuke.arc.input.KeyCode;
import io.anuke.arc.math.Interpolation;
import io.anuke.arc.scene.Group;
import io.anuke.arc.scene.Scene;
import io.anuke.arc.scene.Skin;
import io.anuke.arc.scene.actions.Actions;
import io.anuke.arc.scene.ui.Dialog;
import io.anuke.arc.scene.ui.TextField;
import io.anuke.arc.scene.ui.TextField.TextFieldFilter;
import io.anuke.arc.scene.ui.TooltipManager;
import io.anuke.arc.scene.ui.layout.Table;
import io.anuke.arc.scene.ui.layout.Unit;
import io.anuke.arc.util.Align;
import io.anuke.arc.util.Strings;
import io.anuke.arc.util.Time;
import io.anuke.mindustry.editor.MapEditorDialog;
import io.anuke.mindustry.game.EventType.ResizeEvent;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.input.InputHandler;
import io.anuke.mindustry.ui.dialogs.*;
import io.anuke.mindustry.ui.fragments.*;
import io.anuke.ucore.core.*;
import io.anuke.ucore.function.Consumer;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.modules.SceneModule;
import io.anuke.ucore.scene.Group;
import io.anuke.ucore.scene.Skin;
import io.anuke.ucore.scene.actions.Actions;
import io.anuke.ucore.scene.ui.Dialog;
import io.anuke.ucore.scene.ui.TextField;
import io.anuke.ucore.scene.ui.TextField.TextFieldFilter;
import io.anuke.ucore.scene.ui.TooltipManager;
import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.scene.ui.layout.Unit;
import io.anuke.ucore.util.Strings;
import static io.anuke.mindustry.Vars.*;
import static io.anuke.ucore.scene.actions.Actions.*;
import static io.anuke.arc.scene.actions.Actions.*;
import static io.anuke.mindustry.Vars.control;
import static io.anuke.mindustry.Vars.disableUI;
public class UI extends SceneModule{
public class UI implements ApplicationListener{
private FreeTypeFontGenerator generator;
public final MenuFragment menufrag = new MenuFragment();
public final HudFragment hudfrag = new HudFragment();
public final ChatFragment chatfrag = new ChatFragment();
public final PlayerListFragment listfrag = new PlayerListFragment();
public final BackgroundFragment backfrag = new BackgroundFragment();
public final LoadingFragment loadfrag = new LoadingFragment();
public MenuFragment menufrag;
public HudFragment hudfrag;
public ChatFragment chatfrag;
public PlayerListFragment listfrag;
public BackgroundFragment backfrag;
public LoadingFragment loadfrag;
public AboutDialog about;
public RestartDialog restart;
@@ -66,11 +69,24 @@ public class UI extends SceneModule{
public SectorsDialog sectors;
public MissionDialog missions;
public Cursor drillCursor, unloadCursor;
public UI(){
Skin skin = new Skin(Core.atlas);
generateFonts(skin);
skin.load(Core.files.internal("ui/uiskin.json"));
for(BitmapFont font : skin.getAll(BitmapFont.class).values()){
font.setUseIntegerPositions(true);
}
Core.scene = new Scene(skin);
Core.input.addProcessor(Core.scene);
Dialog.setShowAction(() -> sequence(
alpha(0f),
originCenter(),
moveToAligned(Gdx.graphics.getWidth() / 2f, Gdx.graphics.getHeight() / 2f, Align.center),
moveToAligned(Core.graphics.getWidth() / 2f, Core.graphics.getHeight() / 2f, Align.center),
scaleTo(0.0f, 1f),
parallel(
scaleTo(1f, 1f, 0.1f, Interpolation.fade),
@@ -87,16 +103,31 @@ public class UI extends SceneModule{
TooltipManager.getInstance().animations = false;
Settings.setErrorHandler(() -> Timers.run(1f, () -> showError("[crimson]Failed to access local storage.\nSettings will not be saved.")));
Dialog.closePadR = -1;
Dialog.closePadT = 5;
Core.settings.setErrorHandler(e -> {
e.printStackTrace();
Core.app.post(() -> showError("Failed to access local storage.\nSettings will not be saved."));
});
Colors.put("accent", Palette.accent);
loadCursors();
}
void loadCursors(){
int cursorScaling = 3;
Color outlineColor = Color.valueOf("444444");
drillCursor = Core.graphics.newCursor("drill", cursorScaling, outlineColor);
unloadCursor = Core.graphics.newCursor("unload", cursorScaling, outlineColor);
SystemCursor.arrow.set(Core.graphics.newCursor("cursor", cursorScaling, outlineColor));
SystemCursor.hand.set(Core.graphics.newCursor("hand", cursorScaling, outlineColor));
SystemCursor.ibeam.set(Core.graphics.newCursor("ibeam", cursorScaling, outlineColor));
Core.graphics.restoreCursor();
}
void generateFonts(){
generator = new FreeTypeFontGenerator(Gdx.files.internal("fonts/pixel.ttf"));
void generateFonts(Skin skin){
generator = new FreeTypeFontGenerator(Core.files.internal("fonts/pixel.ttf"));
FreeTypeFontParameter param = new FreeTypeFontParameter();
param.size = (int)(14*2 * Math.max(Unit.dp.scl(1f), 0.5f));
param.shadowColor = Color.DARK_GRAY;
@@ -109,46 +140,23 @@ public class UI extends SceneModule{
skin.getFont("default-font").setOwnsTexture(false);
}
@Override
protected void loadSkin(){
skin = new Skin(Core.atlas);
generateFonts();
skin.load(Gdx.files.internal("ui/uiskin.json"));
for(BitmapFont font : skin.getAll(BitmapFont.class).values()){
font.setUseIntegerPositions(true);
//font.getData().setScale(Vars.fontScale);
}
}
@Override
public void update(){
if(disableUI) return;
if(Graphics.drawing()) Graphics.end();
act();
Graphics.begin();
for(int i = 0; i < players.length; i++){
InputHandler input = control.input(i);
if(input.isCursorVisible()){
Draw.color();
float scl = Unit.dp.scl(3f);
Draw.rect("controller-cursor", input.getMouseX(), Gdx.graphics.getHeight() - input.getMouseY(), 16 * scl, 16 * scl);
}
}
Graphics.end();
Draw.color();
Core.scene.act();
Core.scene.draw();
}
@Override
public void init(){
menufrag = new MenuFragment();
hudfrag = new HudFragment();
chatfrag = new ChatFragment();
listfrag = new PlayerListFragment();
backfrag = new BackgroundFragment();
loadfrag = new LoadingFragment();
editor = new MapEditorDialog();
controls = new ControlsDialog();
restart = new RestartDialog();
@@ -172,10 +180,10 @@ public class UI extends SceneModule{
sectors = new SectorsDialog();
missions = new MissionDialog();
Group group = Core.scene.getRoot();
Group group = Core.scene.root;
backfrag.build(group);
control.input(0).getFrag().build(Core.scene.getRoot());
control.input(0).getFrag().build(group);
hudfrag.build(group);
menufrag.build(group);
chatfrag.container().build(group);
@@ -185,14 +193,12 @@ public class UI extends SceneModule{
@Override
public void resize(int width, int height){
super.resize(width, height);
Core.scene.resize(width, height);
Events.fire(new ResizeEvent());
}
@Override
public void dispose(){
super.dispose();
generator.dispose();
}
@@ -202,7 +208,7 @@ public class UI extends SceneModule{
public void loadGraphics(String text, Runnable call){
loadfrag.show(text);
Timers.runTask(7f, () -> {
Time.runTask(7f, () -> {
call.run();
loadfrag.hide();
});
@@ -214,10 +220,10 @@ public class UI extends SceneModule{
public void loadLogic(String text, Runnable call){
loadfrag.show(text);
Timers.runTask(7f, () ->
threads.run(() -> {
Time.runTask(7f, () ->
Core.app.post(() -> {
call.run();
threads.runGraphics(loadfrag::hide);
loadfrag.hide();
}));
}
@@ -292,8 +298,8 @@ public class UI extends SceneModule{
dialog.hide();
confirmed.run();
});
dialog.keyDown(Keys.ESCAPE, dialog::hide);
dialog.keyDown(Keys.BACK, dialog::hide);
dialog.keyDown(KeyCode.ESCAPE, dialog::hide);
dialog.keyDown(KeyCode.BACK, dialog::hide);
dialog.show();
}

View File

@@ -1,8 +1,17 @@
package io.anuke.mindustry.core;
import com.badlogic.gdx.math.GridPoint2;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.ObjectMap;
import io.anuke.arc.ApplicationListener;
import io.anuke.arc.Core;
import io.anuke.arc.Events;
import io.anuke.arc.collection.Array;
import io.anuke.arc.collection.ObjectMap;
import io.anuke.arc.entities.EntityQuery;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.geom.Point2;
import io.anuke.arc.util.Log;
import io.anuke.arc.util.Structs;
import io.anuke.arc.util.Time;
import io.anuke.arc.util.Tmp;
import io.anuke.mindustry.ai.BlockIndexer;
import io.anuke.mindustry.ai.Pathfinder;
import io.anuke.mindustry.ai.WaveSpawner;
@@ -18,15 +27,10 @@ import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Pos;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.OreBlock;
import io.anuke.ucore.core.Events;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.EntityQuery;
import io.anuke.ucore.modules.Module;
import io.anuke.ucore.util.*;
import static io.anuke.mindustry.Vars.*;
public class World extends Module{
public class World implements ApplicationListener{
public final Maps maps = new Maps();
public final Sectors sectors = new Sectors();
public final WorldGenerator generator = new WorldGenerator();
@@ -38,7 +42,7 @@ public class World extends Module{
private Sector currentSector;
private Tile[][] tiles;
private Array<Tile> tempTiles = new ThreadArray<>();
private Array<Tile> tempTiles = new Array<>();
private boolean generating, invalidMap;
public World(){
@@ -121,11 +125,11 @@ public class World extends Module{
}
public Tile tileWorld(float x, float y){
return tile(Mathf.scl2(x, tilesize), Mathf.scl2(y, tilesize));
return tile(Math.round(x / tilesize), Math.round(y / tilesize));
}
public int toTile(float coord){
return Mathf.scl2(coord, tilesize);
return Math.round(coord / tilesize);
}
public Tile[][] getTiles(){
@@ -209,8 +213,8 @@ public class World extends Module{
currentSector = sector;
state.difficulty = sectors.getDifficulty(sector);
state.mode = sector.currentMission().getMode();
Timers.mark();
Timers.mark();
Time.mark();
Time.mark();
logic.reset();
@@ -247,7 +251,7 @@ public class World extends Module{
Log.err(e);
if(!headless){
ui.showError("$text.map.invalid");
threads.runDelay(() -> state.set(State.menu));
Core.app.post(() -> state.set(State.menu));
invalidMap = true;
}
generating = false;
@@ -277,13 +281,13 @@ public class World extends Module{
invalidMap = false;
}
if(invalidMap) threads.runDelay(() -> state.set(State.menu));
if(invalidMap) Core.app.post(() -> state.set(State.menu));
}
public void notifyChanged(Tile tile){
if(!generating){
threads.runDelay(() -> Events.fire(new TileChangeEvent(tile)));
Core.app.post(() -> Events.fire(new TileChangeEvent(tile)));
}
}
@@ -334,9 +338,9 @@ public class World extends Module{
/**
* Raycast, but with world coordinates.
*/
public GridPoint2 raycastWorld(float x, float y, float x2, float y2){
return raycast(Mathf.scl2(x, tilesize), Mathf.scl2(y, tilesize),
Mathf.scl2(x2, tilesize), Mathf.scl2(y2, tilesize));
public Point2 raycastWorld(float x, float y, float x2, float y2){
return raycast(Math.round(x / tilesize), Math.round(y / tilesize),
Math.round(x2 / tilesize), Math.round(y2 / tilesize));
}
/**
@@ -344,7 +348,7 @@ public class World extends Module{
*
* @return null if no collisions found, block position otherwise.
*/
public GridPoint2 raycast(int x0f, int y0f, int x1, int y1){
public Point2 raycast(int x0f, int y0f, int x1, int y1){
int x0 = x0f;
int y0 = y0f;
int dx = Math.abs(x1 - x0);

View File

@@ -1,10 +1,10 @@
package io.anuke.mindustry.editor;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.IntSet;
import io.anuke.arc.collection.Array;
import io.anuke.arc.collection.IntSet;
import io.anuke.arc.util.Pack;
import io.anuke.mindustry.maps.MapTileData;
import io.anuke.mindustry.maps.MapTileData.TileDataMarker;
import io.anuke.ucore.util.Bits;
public class DrawOperation{
/**
@@ -29,7 +29,7 @@ public class DrawOperation{
}
public boolean checkDuplicate(short x, short y){
int i = Bits.packInt(x, y);
int i = Pack.shortInt(x, y);
if(checks.contains(i)) return true;
checks.add(i);

View File

@@ -1,15 +1,15 @@
package io.anuke.mindustry.editor;
import com.badlogic.gdx.utils.IntArray;
import io.anuke.arc.collection.IntArray;
import io.anuke.arc.function.IntPositionConsumer;
import io.anuke.arc.util.Pack;
import io.anuke.arc.util.Structs;
import io.anuke.mindustry.content.blocks.Blocks;
import io.anuke.mindustry.maps.MapTileData;
import io.anuke.mindustry.maps.MapTileData.DataPosition;
import io.anuke.mindustry.maps.MapTileData.TileDataMarker;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.blocks.Floor;
import io.anuke.ucore.function.IntPositionConsumer;
import io.anuke.ucore.util.Structs;
import io.anuke.ucore.util.Bits;
import static io.anuke.mindustry.Vars.content;
import static io.anuke.mindustry.Vars.ui;
@@ -24,8 +24,8 @@ public enum EditorTool{
byte link = editor.getMap().read(x, y, DataPosition.link);
if(link != 0){
x -= (Bits.getLeftByte(link) - 8);
y -= (Bits.getRightByte(link) - 8);
x -= (Pack.leftByte(link) - 8);
y -= (Pack.rightByte(link) - 8);
bf = editor.getMap().read(x, y, DataPosition.floor);
bw = editor.getMap().read(x, y, DataPosition.wall);
}
@@ -101,7 +101,7 @@ public enum EditorTool{
byte bw = data.read(x, y, DataPosition.wall);
be = data.read(x, y, DataPosition.elevation);
boolean synth = editor.getDrawBlock().synthetic();
byte brt = Bits.packByte((byte) editor.getDrawRotation(), (byte) editor.getDrawTeam().ordinal());
byte brt = Pack.byteByte((byte) editor.getDrawRotation(), (byte) editor.getDrawTeam().ordinal());
dest = floor ? bf : bw;
byte draw = editor.getDrawBlock().id;

View File

@@ -1,6 +1,9 @@
package io.anuke.mindustry.editor;
import com.badlogic.gdx.utils.ObjectMap;
import io.anuke.arc.collection.ObjectMap;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.util.Pack;
import io.anuke.arc.util.Structs;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.content.blocks.Blocks;
import io.anuke.mindustry.editor.DrawOperation.TileOperation;
@@ -10,10 +13,9 @@ import io.anuke.mindustry.maps.MapTileData.DataPosition;
import io.anuke.mindustry.maps.MapTileData.TileDataMarker;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.blocks.Floor;
import io.anuke.ucore.util.Structs;
import io.anuke.ucore.util.Bits;
import io.anuke.ucore.util.Mathf;
import static io.anuke.mindustry.Vars.content;
public class MapEditor{
public static final int[] brushSizes = {1, 2, 3, 4, 5, 9, 15};
@@ -103,7 +105,7 @@ public class MapEditor{
byte writeID = drawBlock.id;
byte partID = Blocks.blockpart.id;
byte rotationTeam = Bits.packByte(drawBlock.rotate ? (byte) rotation : 0, drawBlock.synthetic() ? (byte) drawTeam.ordinal() : 0);
byte rotationTeam = Pack.byteByte(drawBlock.rotate ? (byte)rotation : 0, drawBlock.synthetic() ? (byte)drawTeam.ordinal() : 0);
boolean isfloor = drawBlock instanceof Floor && drawBlock != Blocks.air;
@@ -126,13 +128,13 @@ public class MapEditor{
if(i == 1){
map.write(worldx, worldy, DataPosition.wall, partID);
map.write(worldx, worldy, DataPosition.rotationTeam, rotationTeam);
map.write(worldx, worldy, DataPosition.link, Bits.packByte((byte) (dx + offsetx + 8), (byte) (dy + offsety + 8)));
map.write(worldx, worldy, DataPosition.link, Pack.byteByte((byte) (dx + offsetx + 8), (byte) (dy + offsety + 8)));
}else{
byte link = map.read(worldx, worldy, DataPosition.link);
byte block = map.read(worldx, worldy, DataPosition.wall);
if(link != 0){
removeLinked(worldx - (Bits.getLeftByte(link) - 8), worldy - (Bits.getRightByte(link) - 8));
removeLinked(worldx - (Pack.leftByte(link) - 8), worldy - (Pack.rightByte(link) - 8));
}else if(content.block(block).isMultiblock()){
removeLinked(worldx, worldy);
}
@@ -170,7 +172,7 @@ public class MapEditor{
if(content.block(map.read(wx, wy, DataPosition.wall)).isMultiblock()){
removeLinked(wx, wy);
}else if(link != 0){
removeLinked(wx - (Bits.getLeftByte(link) - 8), wy - (Bits.getRightByte(link) - 8));
removeLinked(wx - (Pack.leftByte(link) - 8), wy - (Pack.rightByte(link) - 8));
}
}

View File

@@ -1,15 +1,22 @@
package io.anuke.mindustry.editor;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.Disposable;
import com.badlogic.gdx.utils.ObjectMap;
import io.anuke.arc.Core;
import io.anuke.arc.collection.ObjectMap;
import io.anuke.arc.files.FileHandle;
import io.anuke.arc.function.Consumer;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.Pixmap;
import io.anuke.arc.graphics.g2d.TextureRegion;
import io.anuke.arc.input.KeyCode;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.geom.Vector2;
import io.anuke.arc.scene.actions.Actions;
import io.anuke.arc.scene.ui.*;
import io.anuke.arc.scene.ui.layout.Stack;
import io.anuke.arc.scene.ui.layout.Table;
import io.anuke.arc.scene.ui.layout.Unit;
import io.anuke.arc.scene.utils.UIUtils;
import io.anuke.arc.util.*;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.content.blocks.StorageBlocks;
import io.anuke.mindustry.core.Platform;
@@ -21,26 +28,8 @@ import io.anuke.mindustry.maps.MapTileData;
import io.anuke.mindustry.type.Recipe;
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
import io.anuke.mindustry.world.Block;
import io.anuke.ucore.core.Core;
import io.anuke.ucore.core.Graphics;
import io.anuke.ucore.core.Inputs;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.function.Consumer;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.input.Input;
import io.anuke.ucore.scene.actions.Actions;
import io.anuke.ucore.scene.ui.*;
import io.anuke.ucore.scene.ui.layout.Stack;
import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.scene.ui.layout.Unit;
import io.anuke.ucore.scene.utils.UIUtils;
import io.anuke.ucore.util.Bundles;
import io.anuke.ucore.util.Log;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Strings;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import static io.anuke.mindustry.Vars.*;
@@ -96,26 +85,24 @@ public class MapEditorDialog extends Dialog implements Disposable{
t.addImageTextButton("$text.editor.import", "icon-load-map", isize, () ->
createDialog("$text.editor.import",
"$text.editor.importmap", "$text.editor.importmap.description", "icon-load-map", (Runnable) loadDialog::show,
"$text.editor.importfile", "$text.editor.importfile.description", "icon-file", (Runnable) () -> {
Platform.instance.showFileChooser("$text.loadimage", "Map Files", file -> {
ui.loadGraphics(() -> {
try{
DataInputStream stream = new DataInputStream(file.read());
"$text.editor.importfile", "$text.editor.importfile.description", "icon-file", (Runnable) () ->
Platform.instance.showFileChooser("$text.loadimage", "Map Files", file -> ui.loadGraphics(() -> {
try{
DataInputStream stream = new DataInputStream(file.read());
MapMeta meta = MapIO.readMapMeta(stream);
MapTileData data = MapIO.readTileData(stream, meta, false);
MapMeta meta = MapIO.readMapMeta(stream);
MapTileData data = MapIO.readTileData(stream, meta, false);
editor.beginEdit(data, meta.tags, false);
view.clearStack();
}catch(Exception e){
ui.showError(Bundles.format("text.editor.errorimageload", Strings.parseException(e, false)));
Log.err(e);
}
});
}, true, mapExtension);
},
"$text.editor.importimage", "$text.editor.importimage.description", "icon-file-image", (Runnable)() -> {
Platform.instance.showFileChooser("$text.loadimage", "Image Files", file -> {
editor.beginEdit(data, meta.tags, false);
view.clearStack();
}catch(Exception e){
ui.showError(Core.bundle.format("text.editor.errorimageload", Strings.parseException(e, false)));
Log.err(e);
}
}), true, mapExtension),
"$text.editor.importimage", "$text.editor.importimage.description", "icon-file-image", (Runnable)() ->
Platform.instance.showFileChooser("$text.loadimage", "Image Files", file ->
ui.loadGraphics(() -> {
try{
MapTileData data = MapIO.readLegacyPixmap(new Pixmap(file));
@@ -123,15 +110,14 @@ public class MapEditorDialog extends Dialog implements Disposable{
editor.beginEdit(data, editor.getTags(), false);
view.clearStack();
}catch (Exception e){
ui.showError(Bundles.format("text.editor.errorimageload", Strings.parseException(e, false)));
ui.showError(Core.bundle.format("text.editor.errorimageload", Strings.parseException(e, false)));
Log.err(e);
}
});
}, true, "png");
}));
}), true, "png")
));
t.addImageTextButton("$text.editor.export", "icon-save-map", isize, () -> createDialog("$text.editor.export",
"$text.editor.exportfile", "$text.editor.exportfile.description", "icon-file", (Runnable) () -> {
"$text.editor.exportfile", "$text.editor.exportfile.description", "icon-file", (Runnable) () ->
Platform.instance.showFileChooser("$text.saveimage", "Map Files", file -> {
file = file.parent().child(file.nameWithoutExtension() + "." + mapExtension);
FileHandle result = file;
@@ -143,12 +129,11 @@ public class MapEditorDialog extends Dialog implements Disposable{
}
MapIO.writeMap(result.write(false), editor.getTags(), editor.getMap());
}catch(Exception e){
ui.showError(Bundles.format("text.editor.errorimagesave", Strings.parseException(e, false)));
ui.showError(Core.bundle.format("text.editor.errorimagesave", Strings.parseException(e, false)));
Log.err(e);
}
});
}, false, mapExtension);
}));
}, false, mapExtension)));
t.row();
@@ -171,8 +156,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
}
});
loadDialog = new MapLoadDialog(map -> {
loadDialog = new MapLoadDialog(map ->
ui.loadGraphics(() -> {
try(DataInputStream stream = new DataInputStream(map.stream.get())){
MapMeta meta = MapIO.readMapMeta(stream);
@@ -180,12 +164,11 @@ public class MapEditorDialog extends Dialog implements Disposable{
editor.beginEdit(data, meta.tags, false);
view.clearStack();
}catch(IOException e){
ui.showError(Bundles.format("text.editor.errormapload", Strings.parseException(e, false)));
}catch(Exception e){
ui.showError(Core.bundle.format("text.editor.errormapload", Strings.parseException(e, false)));
Log.err(e);
}
});
});
}));
setFillParent(true);
@@ -198,7 +181,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
return;
}
Vector2 v = pane.stageToLocalCoordinates(Graphics.mouse());
Vector2 v = pane.stageToLocalCoordinates(Core.input.mouse());
if(v.x >= 0 && v.y >= 0 && v.x <= pane.getWidth() && v.y <= pane.getHeight()){
Core.scene.setScrollFocus(pane);
@@ -221,7 +204,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
}
shownWithMap = false;
Timers.runTask(10f, Platform.instance::updateRPC);
Time.runTask(10f, Platform.instance::updateRPC);
});
hidden(() -> {
@@ -231,8 +214,8 @@ public class MapEditorDialog extends Dialog implements Disposable{
}
@Override
protected void drawBackground(Batch batch, float parentAlpha, float x, float y){
drawDefaultBackground(batch, parentAlpha, x, y);
protected void drawBackground(float x, float y){
drawDefaultBackground(x, y);
}
private void save(){
@@ -261,7 +244,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
* 2) icon name
* 3) listener
*/
private FloatingDialog createDialog(String title, Object... arguments){
private void createDialog(String title, Object... arguments){
FloatingDialog dialog = new FloatingDialog(title);
float h = 90f;
@@ -278,18 +261,15 @@ public class MapEditorDialog extends Dialog implements Disposable{
listenable.run();
dialog.hide();
menu.hide();
}).left().get();
}).left().margin(0).get();
button.clearChildren();
button.table("button", t -> {
t.addImage(iconname).size(16 * 3);
t.update(() -> t.background(button.getClickListener().isOver() ? "button-over" : "button"));
}).padLeft(-10).padBottom(-3).size(h);
button.addImage(iconname).size(16 * 3).padLeft(10);
button.table(t -> {
t.add(name).growX().wrap();
t.row();
t.add(description).color(Color.GRAY).growX().wrap();
}).growX().padLeft(8);
}).growX().pad(10f).padLeft(5);
button.row();
@@ -298,8 +278,6 @@ public class MapEditorDialog extends Dialog implements Disposable{
dialog.addCloseButton();
dialog.show();
return dialog;
}
@Override
@@ -323,7 +301,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
show();
}catch(Exception e){
Log.err(e);
ui.showError(Bundles.format("text.editor.errorimageload", Strings.parseException(e, false)));
ui.showError(Core.bundle.format("text.editor.errorimageload", Strings.parseException(e, false)));
}
});
}
@@ -353,8 +331,8 @@ public class MapEditorDialog extends Dialog implements Disposable{
public void build(){
float amount = 10f, baseSize = 60f;
float size = mobile ? (int) (Math.min(Gdx.graphics.getHeight(), Gdx.graphics.getWidth()) / amount / Unit.dp.scl(1f)) :
Math.min(Gdx.graphics.getDisplayMode().height / amount, baseSize);
float size = mobile ? (int) (Math.min(Core.graphics.getHeight(), Core.graphics.getWidth()) / amount / Unit.dp.scl(1f)) :
Math.min(Core.graphics.getDisplayMode().height / amount, baseSize);
clearChildren();
table(cont -> {
@@ -421,7 +399,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
tools.row();
tools.table("underline", t -> t.add("$text.editor.teams"))
.colspan(3).height(40).width(size * 3f).padBottom(3);
.colspan(3).height(40).width(size * 3f + 3f).padBottom(3);
tools.row();
@@ -459,7 +437,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
mid.row();
mid.table("underline", t -> t.add("$text.editor.elevation"))
.colspan(3).height(40).width(size * 3f);
.colspan(3).height(40).width(size * 3f + 3f);
mid.row();
@@ -472,8 +450,8 @@ public class MapEditorDialog extends Dialog implements Disposable{
.size(size).get().setAlignment(Align.center, Align.center);
t.addImageButton("icon-arrow-right", "clear-partial", 16 * 2f, () -> editor.setDrawElevation(editor.getDrawElevation() + 1))
.disabled(b -> editor.getDrawElevation() >= 63).size(size);
}).colspan(3).height(size).width(size * 3f);
.disabled(b -> editor.getDrawElevation() >= 63).size(size).name("aaaaa");
}).colspan(3).height(size).width(size * 3f + 3f);
}).margin(0).left().growY();
@@ -488,35 +466,35 @@ public class MapEditorDialog extends Dialog implements Disposable{
private void doInput(){
//tool select
for(int i = 0; i < EditorTool.values().length; i++){
if(Inputs.keyTap(Input.valueOf("NUM_" + (i + 1)))){
if(Core.input.keyTap(KeyCode.valueOf("NUM_" + (i + 1)))){
view.setTool(EditorTool.values()[i]);
break;
}
}
if(Inputs.keyTap(Input.R)){
if(Core.input.keyTap(KeyCode.R)){
editor.setDrawRotation((editor.getDrawRotation() + 1) % 4);
}
if(Inputs.keyTap(Input.E)){
if(Core.input.keyTap(KeyCode.E)){
editor.setDrawRotation(Mathf.mod((editor.getDrawRotation() + 1), 4));
}
//ctrl keys (undo, redo, save)
if(UIUtils.ctrl()){
if(Inputs.keyTap(Input.Z)){
if(Core.input.keyTap(KeyCode.Z)){
view.undo();
}
if(Inputs.keyTap(Input.Y)){
if(Core.input.keyTap(KeyCode.Y)){
view.redo();
}
if(Inputs.keyTap(Input.S)){
if(Core.input.keyTap(KeyCode.S)){
save();
}
if(Inputs.keyTap(Input.G)){
if(Core.input.keyTap(KeyCode.G)){
view.setGrid(!view.isGrid());
}
}
@@ -551,7 +529,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
continue;
}
if(regions.length == 0 || regions[0] == Draw.region("jjfgj")) continue;
if(regions.length == 0 || regions[0] == Core.atlas.find("jjfgj")) continue;
Stack stack = new Stack();
@@ -562,9 +540,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
ImageButton button = new ImageButton("white", "clear-toggle");
button.clicked(() -> editor.setDrawBlock(block));
button.resizeImage(8 * 4f);
button.getImageCell().setActor(stack);
button.addChild(stack);
button.getImage().remove();
button.replaceImage(stack);
button.update(() -> button.setChecked(editor.getDrawBlock() == block));
group.add(button);
content.add(button).size(50f);

View File

@@ -1,11 +1,11 @@
package io.anuke.mindustry.editor;
import com.badlogic.gdx.utils.ObjectMap;
import io.anuke.arc.Core;
import io.anuke.arc.collection.ObjectMap;
import io.anuke.arc.scene.ui.TextArea;
import io.anuke.arc.scene.ui.TextField;
import io.anuke.mindustry.core.Platform;
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
import io.anuke.ucore.core.Settings;
import io.anuke.ucore.scene.ui.TextArea;
import io.anuke.ucore.scene.ui.TextField;
public class MapInfoDialog extends FloatingDialog{
private final MapEditor editor;
@@ -53,10 +53,10 @@ public class MapInfoDialog extends FloatingDialog{
content().add("$text.editor.author").padRight(8).left();
author = content().addField(tags.get("author", Settings.getString("mapAuthor", "")), text -> {
author = content().addField(tags.get("author", Core.settings.getString("mapAuthor", "")), text -> {
tags.put("author", text);
Settings.putString("mapAuthor", text);
Settings.save();
Core.settings.put("mapAuthor", text);
Core.settings.save();
}).size(400, 55f).get();
author.setMessageText("$text.unknown");

View File

@@ -1,14 +1,14 @@
package io.anuke.mindustry.editor;
import com.badlogic.gdx.utils.Scaling;
import io.anuke.arc.util.Scaling;
import io.anuke.mindustry.maps.Map;
import io.anuke.mindustry.ui.BorderImage;
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
import io.anuke.ucore.function.Consumer;
import io.anuke.ucore.scene.ui.ButtonGroup;
import io.anuke.ucore.scene.ui.ScrollPane;
import io.anuke.ucore.scene.ui.TextButton;
import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.arc.function.Consumer;
import io.anuke.arc.scene.ui.ButtonGroup;
import io.anuke.arc.scene.ui.ScrollPane;
import io.anuke.arc.scene.ui.TextButton;
import io.anuke.arc.scene.ui.layout.Table;
import static io.anuke.mindustry.Vars.world;

View File

@@ -1,21 +1,20 @@
package io.anuke.mindustry.editor;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.GridPoint2;
import com.badlogic.gdx.utils.Disposable;
import com.badlogic.gdx.utils.IntSet;
import com.badlogic.gdx.utils.IntSet.IntSetIterator;
import io.anuke.arc.Core;
import io.anuke.arc.collection.IntSet;
import io.anuke.arc.collection.IntSet.IntSetIterator;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.TextureRegion;
import io.anuke.arc.math.geom.Geometry;
import io.anuke.arc.math.geom.Point2;
import io.anuke.arc.util.Disposable;
import io.anuke.arc.util.Pack;
import io.anuke.arc.util.Structs;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.graphics.IndexedRenderer;
import io.anuke.mindustry.maps.MapTileData.DataPosition;
import io.anuke.mindustry.world.Block;
import io.anuke.ucore.core.Core;
import io.anuke.ucore.core.Graphics;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.IndexedRenderer;
import io.anuke.ucore.util.Structs;
import io.anuke.ucore.util.Bits;
import io.anuke.ucore.util.Geometry;
import static io.anuke.mindustry.Vars.content;
import static io.anuke.mindustry.Vars.tilesize;
@@ -56,7 +55,7 @@ public class MapRenderer implements Disposable{
public void draw(float tx, float ty, float tw, float th){
Graphics.end();
Draw.flush();
IntSetIterator it = updates.iterator();
while(it.hasNext){
@@ -79,15 +78,12 @@ public class MapRenderer implements Disposable{
mesh = chunks[x][y];
}
mesh.getTransformMatrix().setToTranslation(tx, ty, 0).scl(tw / (width * tilesize),
th / (height * tilesize), 1f);
mesh.setProjectionMatrix(Core.batch.getProjectionMatrix());
mesh.getTransformMatrix().setToTranslation(tx, ty).scale(tw / (width * tilesize), th / (height * tilesize));
mesh.setProjectionMatrix(Draw.proj());
mesh.render(Core.atlas.getTextures().first());
}
}
Graphics.begin();
}
public void updatePoint(int x, int y){
@@ -111,8 +107,8 @@ public class MapRenderer implements Disposable{
byte bw = editor.getMap().read(wx, wy, DataPosition.wall);
byte btr = editor.getMap().read(wx, wy, DataPosition.rotationTeam);
byte elev = editor.getMap().read(wx, wy, DataPosition.elevation);
byte rotation = Bits.getLeftByte(btr);
Team team = Team.all[Bits.getRightByte(btr)];
byte rotation = Pack.leftByte(btr);
Team team = Team.all[Pack.rightByte(btr)];
Block floor = content.block(bf);
Block wall = content.block(bw);
@@ -125,12 +121,12 @@ public class MapRenderer implements Disposable{
if(wall.rotate){
mesh.draw((wx % chunksize) + (wy % chunksize) * chunksize, region,
wx * tilesize + wall.offset(), wy * tilesize + wall.offset(),
region.getRegionWidth(), region.getRegionHeight(), rotation * 90 - 90);
region.getWidth() * Draw.scl, region.getHeight() * Draw.scl, rotation * 90 - 90);
}else{
mesh.draw((wx % chunksize) + (wy % chunksize) * chunksize, region,
wx * tilesize + wall.offset() + (tilesize - region.getRegionWidth())/2f,
wy * tilesize + wall.offset() + (tilesize - region.getRegionHeight())/2f,
region.getRegionWidth(), region.getRegionHeight());
wx * tilesize + wall.offset() + (tilesize - region.getWidth() * Draw.scl)/2f,
wy * tilesize + wall.offset() + (tilesize - region.getHeight() * Draw.scl)/2f,
region.getWidth() * Draw.scl, region.getHeight() * Draw.scl);
}
}else{
region = floor.getEditorIcon();
@@ -142,24 +138,24 @@ public class MapRenderer implements Disposable{
if(wall.update || wall.destructible){
mesh.setColor(team.color);
region = Draw.region("block-border");
region = Core.atlas.find("block-border");
}else if(elev > 0 && check){
mesh.setColor(tmpColor.fromHsv((360f * elev / 127f * 4f) % 360f, 0.5f + (elev / 4f) % 0.5f, 1f));
region = Draw.region("block-elevation");
region = Core.atlas.find("block-elevation");
}else if(elev == -1){
region = Draw.region("block-slope");
region = Core.atlas.find("block-slope");
}else{
region = Draw.region("clear");
region = Core.atlas.find("clear");
}
mesh.draw((wx % chunksize) + (wy % chunksize) * chunksize + chunksize * chunksize, region,
wx * tilesize - (wall.size/3) * tilesize, wy * tilesize - (wall.size/3) * tilesize,
region.getRegionWidth(), region.getRegionHeight());
region.getWidth() * Draw.scl, region.getHeight() * Draw.scl);
mesh.setColor(Color.WHITE);
}
private boolean checkElevation(byte elev, int x, int y){
for(GridPoint2 p : Geometry.d4){
for(Point2 p : Geometry.d4){
int wx = x + p.x, wy = y + p.y;
if(!Structs.inBounds(wx, wy, editor.getMap().width(), editor.getMap().height())){
return true;

View File

@@ -2,11 +2,11 @@ package io.anuke.mindustry.editor;
import io.anuke.mindustry.maps.MapTileData;
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
import io.anuke.ucore.function.BiConsumer;
import io.anuke.ucore.scene.ui.ButtonGroup;
import io.anuke.ucore.scene.ui.TextButton;
import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.util.Mathf;
import io.anuke.arc.function.BiConsumer;
import io.anuke.arc.scene.ui.ButtonGroup;
import io.anuke.arc.scene.ui.TextButton;
import io.anuke.arc.scene.ui.layout.Table;
import io.anuke.arc.math.Mathf;
public class MapResizeDialog extends FloatingDialog{
int[] validMapSizes = {200, 300, 400, 500};

View File

@@ -3,9 +3,9 @@ package io.anuke.mindustry.editor;
import io.anuke.mindustry.core.Platform;
import io.anuke.mindustry.maps.Map;
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
import io.anuke.ucore.function.Consumer;
import io.anuke.ucore.scene.ui.TextButton;
import io.anuke.ucore.scene.ui.TextField;
import io.anuke.arc.function.Consumer;
import io.anuke.arc.scene.ui.TextButton;
import io.anuke.arc.scene.ui.TextField;
import static io.anuke.mindustry.Vars.ui;
import static io.anuke.mindustry.Vars.world;

View File

@@ -1,32 +1,27 @@
package io.anuke.mindustry.editor;
import com.badlogic.gdx.Input.Buttons;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.input.GestureDetector;
import com.badlogic.gdx.input.GestureDetector.GestureListener;
import com.badlogic.gdx.math.Bresenham2;
import com.badlogic.gdx.math.GridPoint2;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
import io.anuke.arc.Core;
import io.anuke.arc.collection.Array;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.Lines;
import io.anuke.arc.graphics.g2d.ScissorStack;
import io.anuke.arc.input.GestureDetector;
import io.anuke.arc.input.GestureDetector.GestureListener;
import io.anuke.arc.input.KeyCode;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.geom.*;
import io.anuke.arc.scene.Element;
import io.anuke.arc.scene.event.InputEvent;
import io.anuke.arc.scene.event.InputListener;
import io.anuke.arc.scene.event.Touchable;
import io.anuke.arc.scene.ui.TextField;
import io.anuke.arc.scene.ui.layout.Unit;
import io.anuke.arc.util.Tmp;
import io.anuke.mindustry.editor.DrawOperation.TileOperation;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.input.Binding;
import io.anuke.mindustry.ui.GridImage;
import io.anuke.ucore.core.Core;
import io.anuke.ucore.core.Graphics;
import io.anuke.ucore.core.Inputs;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.scene.Element;
import io.anuke.ucore.scene.event.InputEvent;
import io.anuke.ucore.scene.event.InputListener;
import io.anuke.ucore.scene.event.Touchable;
import io.anuke.ucore.scene.ui.TextField;
import io.anuke.ucore.scene.ui.layout.Unit;
import io.anuke.ucore.util.Geometry;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Tmp;
import static io.anuke.mindustry.Vars.mobile;
import static io.anuke.mindustry.Vars.ui;
@@ -57,11 +52,11 @@ public class MapView extends Element implements GestureListener{
for(int i = 0; i < MapEditor.brushSizes.length; i++){
float size = MapEditor.brushSizes[i];
brushPolygons[i] = Geometry.pixelCircle(size, (index, x, y) -> Vector2.dst(x, y, index, index) <= index - 0.5f);
brushPolygons[i] = Geometry.pixelCircle(size, (index, x, y) -> Mathf.dst(x, y, index, index) <= index - 0.5f);
}
Inputs.addProcessor(0, new GestureDetector(20, 0.5f, 2, 0.15f, this));
setTouchable(Touchable.enabled);
Core.input.getInputProcessors().insert(0, new GestureDetector(20, 0.5f, 2, 0.15f, this));
touchable(Touchable.enabled);
addListener(new InputListener(){
@@ -74,16 +69,16 @@ public class MapView extends Element implements GestureListener{
}
@Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button){
public boolean touchDown(InputEvent event, float x, float y, int pointer, KeyCode button){
if(pointer != 0){
return false;
}
if(!mobile && button != Buttons.LEFT && button != Buttons.MIDDLE){
if(!mobile && button != KeyCode.MOUSE_LEFT && button != KeyCode.MOUSE_MIDDLE){
return true;
}
if(button == Buttons.MIDDLE){
if(button == KeyCode.MOUSE_MIDDLE){
lastTool = tool;
tool = EditorTool.zoom;
}
@@ -95,7 +90,7 @@ public class MapView extends Element implements GestureListener{
updated = false;
GridPoint2 p = project(x, y);
Point2 p = project(x, y);
lastx = p.x;
lasty = p.y;
startx = p.x;
@@ -112,19 +107,19 @@ public class MapView extends Element implements GestureListener{
}
@Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button){
if(!mobile && button != Buttons.LEFT && button != Buttons.MIDDLE){
public void touchUp(InputEvent event, float x, float y, int pointer, KeyCode button){
if(!mobile && button != KeyCode.MOUSE_LEFT && button != KeyCode.MOUSE_MIDDLE){
return;
}
drawing = false;
GridPoint2 p = project(x, y);
Point2 p = project(x, y);
if(tool == EditorTool.line){
ui.editor.resetSaved();
Array<GridPoint2> points = br.line(startx, starty, p.x, p.y);
for(GridPoint2 point : points){
Array<Point2> points = br.line(startx, starty, p.x, p.y);
for(Point2 point : points){
editor.draw(point.x, point.y);
}
updated = true;
@@ -149,12 +144,12 @@ public class MapView extends Element implements GestureListener{
mousex = x;
mousey = y;
GridPoint2 p = project(x, y);
Point2 p = project(x, y);
if(drawing && tool.draggable){
ui.editor.resetSaved();
Array<GridPoint2> points = br.line(lastx, lasty, p.x, p.y);
for(GridPoint2 point : points){
Array<Point2> points = br.line(lastx, lasty, p.x, p.y);
for(Point2 point : points){
tool.touched(editor, point.x, point.y);
}
updated = true;
@@ -214,16 +209,16 @@ public class MapView extends Element implements GestureListener{
super.act(delta);
if(Core.scene.getKeyboardFocus() == null || !(Core.scene.getKeyboardFocus() instanceof TextField) &&
!Inputs.keyDown(io.anuke.ucore.input.Input.CONTROL_LEFT)){
float ax = Inputs.getAxis("move_x");
float ay = Inputs.getAxis("move_y");
!Core.input.keyDown(KeyCode.CONTROL_LEFT)){
float ax = Core.input.axis(Binding.move_x);
float ay = Core.input.axis(Binding.move_y);
offsetx -= ax * 15f / zoom;
offsety -= ay * 15f / zoom;
}
if(ui.editor.hasPane()) return;
zoom += Inputs.scroll() / 10f * zoom;
zoom += Core.input.axis(KeyCode.SCROLL) / 10f * zoom;
clampZoom();
}
@@ -231,7 +226,7 @@ public class MapView extends Element implements GestureListener{
zoom = Mathf.clamp(zoom, 0.2f, 12f);
}
private GridPoint2 project(float x, float y){
private Point2 project(float x, float y){
float ratio = 1f / ((float) editor.getMap().width() / editor.getMap().height());
float size = Math.min(width, height);
float sclwidth = size * zoom;
@@ -258,7 +253,7 @@ public class MapView extends Element implements GestureListener{
}
@Override
public void draw(Batch batch, float alpha){
public void draw(){
float ratio = 1f / ((float) editor.getMap().width() / editor.getMap().height());
float size = Math.min(width, height);
float sclwidth = size * zoom;
@@ -268,7 +263,9 @@ public class MapView extends Element implements GestureListener{
image.setImageSize(editor.getMap().width(), editor.getMap().height());
Graphics.beginClip(x, y, width, height);
if(!ScissorStack.pushScissors(rect.set(x, y, width, height))){
return;
}
Draw.color(Palette.remove);
Lines.stroke(2f);
@@ -279,7 +276,7 @@ public class MapView extends Element implements GestureListener{
if(grid){
Draw.color(Color.GRAY);
image.setBounds(centerx - sclwidth / 2, centery - sclheight / 2, sclwidth, sclheight);
image.draw(batch, alpha);
image.draw();
Draw.color();
}
@@ -307,13 +304,13 @@ public class MapView extends Element implements GestureListener{
}
if(tool.edit && (!mobile || drawing)){
GridPoint2 p = project(mousex, mousey);
Point2 p = project(mousex, mousey);
Vector2 v = unproject(p.x, p.y).add(x, y);
Lines.poly(brushPolygons[index], v.x, v.y, scaling);
}
}else{
if((tool.edit || tool == EditorTool.line) && (!mobile || drawing)){
GridPoint2 p = project(mousex, mousey);
Point2 p = project(mousex, mousey);
Vector2 v = unproject(p.x, p.y).add(x, y);
float offset = (editor.getDrawBlock().size % 2 == 0 ? scaling / 2f : 0f);
Lines.square(
@@ -323,51 +320,26 @@ public class MapView extends Element implements GestureListener{
}
}
Graphics.endClip();
Draw.color(Palette.accent);
Lines.stroke(Unit.dp.scl(3f));
Lines.rect(x, y, width, height);
Draw.reset();
ScissorStack.popScissors();
}
private boolean active(){
return Core.scene.getKeyboardFocus() != null
&& Core.scene.getKeyboardFocus().isDescendantOf(ui.editor)
&& ui.editor.isShown() && tool == EditorTool.zoom &&
Core.scene.hit(Graphics.mouse().x, Graphics.mouse().y, true) == this;
}
@Override
public boolean touchDown(float x, float y, int pointer, int button){
return false;
}
@Override
public boolean tap(float x, float y, int count, int button){
return false;
}
@Override
public boolean longPress(float x, float y){
return false;
}
@Override
public boolean fling(float velocityX, float velocityY, int button){
return false;
Core.scene.hit(Core.input.mouse().x, Core.input.mouse().y, true) == this;
}
@Override
public boolean pan(float x, float y, float deltaX, float deltaY){
if(!active()) return false;
offsetx += deltaX / zoom;
offsety -= deltaY / zoom;
return false;
}
@Override
public boolean panStop(float x, float y, int pointer, int button){
offsety += deltaY / zoom;
return false;
}

View File

@@ -1,6 +1,6 @@
package io.anuke.mindustry.editor;
import com.badlogic.gdx.utils.Array;
import io.anuke.arc.collection.Array;
public class OperationStack{
private final static int maxSize = 10;
@@ -22,7 +22,7 @@ public class OperationStack{
stack.add(action);
if(stack.size > maxSize){
stack.removeIndex(0);
stack.remove(0);
}
}

View File

@@ -1,11 +1,17 @@
package io.anuke.mindustry.entities;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import io.anuke.arc.entities.Effects;
import io.anuke.arc.entities.Effects.Effect;
import io.anuke.arc.function.Consumer;
import io.anuke.arc.function.Predicate;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.geom.Geometry;
import io.anuke.arc.math.geom.Rectangle;
import io.anuke.arc.math.geom.Vector2;
import io.anuke.arc.util.Time;
import io.anuke.mindustry.content.bullets.TurretBullets;
import io.anuke.mindustry.content.fx.ExplosionFx;
import io.anuke.mindustry.content.fx.Fx;
import io.anuke.mindustry.entities.bullet.Bullet;
import io.anuke.mindustry.entities.effect.Fire;
import io.anuke.mindustry.entities.effect.Lightning;
@@ -13,14 +19,6 @@ import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.function.Consumer;
import io.anuke.ucore.function.Predicate;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Physics;
import io.anuke.ucore.util.Translator;
import static io.anuke.mindustry.Vars.*;
@@ -28,26 +26,26 @@ import static io.anuke.mindustry.Vars.*;
public class Damage{
private static Rectangle rect = new Rectangle();
private static Rectangle hitrect = new Rectangle();
private static Translator tr = new Translator();
private static Vector2 tr = new Vector2();
/**Creates a dynamic explosion based on specified parameters.*/
public static void dynamicExplosion(float x, float y, float flammability, float explosiveness, float power, float radius, Color color){
for(int i = 0; i < Mathf.clamp(power / 20, 0, 6); i++){
int branches = 5 + Mathf.clamp((int) (power / 30), 1, 20);
Timers.run(i * 2f + Mathf.random(4f), () -> Lightning.create(Team.none, Palette.power, 3,
Time.run(i * 2f + Mathf.random(4f), () -> Lightning.create(Team.none, Palette.power, 3,
x, y, Mathf.random(360f), branches + Mathf.range(2)));
}
for(int i = 0; i < Mathf.clamp(flammability / 4, 0, 30); i++){
Timers.run(i / 2f, () -> Call.createBullet(TurretBullets.fireball, x, y, Mathf.random(360f)));
Time.run(i / 2f, () -> Call.createBullet(TurretBullets.fireball, x, y, Mathf.random(360f)));
}
int waves = Mathf.clamp((int) (explosiveness / 4), 0, 30);
for(int i = 0; i < waves; i++){
int f = i;
Timers.run(i * 2f, () -> {
threads.run(() -> Damage.damage(x, y, Mathf.clamp(radius + explosiveness, 0, 50f) * ((f + 1f) / waves), explosiveness / 2f));
Time.run(i * 2f, () -> {
Damage.damage(x, y, Mathf.clamp(radius + explosiveness, 0, 50f) * ((f + 1f) / waves), explosiveness / 2f);
Effects.effect(ExplosionFx.blockExplosionSmoke, x + Mathf.range(radius), y + Mathf.range(radius));
});
}
@@ -119,7 +117,7 @@ public class Damage{
other.width += expand * 2;
other.height += expand * 2;
Vector2 vec = Physics.raycastRect(x, y, x2, y2, other);
Vector2 vec = Geometry.raycastRect(x, y, x2, y2, other);
if(vec != null){
Effects.effect(effect, vec.x, vec.y);
@@ -160,7 +158,7 @@ public class Damage{
/**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, float damage){
Consumer<Unit> cons = entity -> {
if(entity.team == team || entity.distanceTo(x, y) > radius){
if(entity.team == team || entity.dst(x, y) > radius){
return;
}
float amount = calculateDamage(x, y, entity.x, entity.y, radius, damage);
@@ -180,8 +178,8 @@ public class Damage{
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 || state.teams.areEnemies(team, tile.getTeam())) && Vector2.dst(dx, dy, 0, 0) <= trad){
Tile tile = world.tile(Math.round(x / tilesize) + dx, Math.round(y / tilesize) + dy);
if(tile != null && tile.entity != null && (team == null || state.teams.areEnemies(team, tile.getTeam())) && Mathf.dst(dx, dy, 0, 0) <= trad){
float amount = calculateDamage(x, y, tile.worldx(), tile.worldy(), radius, damage);
tile.entity.damage(amount);
}
@@ -191,7 +189,7 @@ public class Damage{
}
private static float calculateDamage(float x, float y, float tx, float ty, float radius, float damage){
float dist = Vector2.dst(x, y, tx, ty);
float dist = Mathf.dst(x, y, tx, ty);
float falloff = 0.4f;
float scaled = Mathf.lerp(1f - dist / radius, 1f, falloff);
return damage * scaled;

View File

@@ -1,13 +1,24 @@
package io.anuke.mindustry.entities;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.GlyphLayout;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Queue;
import io.anuke.annotations.Annotations.Loc;
import io.anuke.annotations.Annotations.Remote;
import io.anuke.arc.Core;
import io.anuke.arc.collection.Queue;
import io.anuke.arc.entities.Effects;
import io.anuke.arc.entities.EntityGroup;
import io.anuke.arc.entities.EntityQuery;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.g2d.*;
import io.anuke.arc.math.Angles;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.geom.Geometry;
import io.anuke.arc.math.geom.Rectangle;
import io.anuke.arc.math.geom.Vector2;
import io.anuke.arc.util.Align;
import io.anuke.arc.util.Interval;
import io.anuke.arc.util.Pack;
import io.anuke.arc.util.Time;
import io.anuke.arc.util.pooling.Pools;
import io.anuke.mindustry.content.Mechs;
import io.anuke.mindustry.content.fx.UnitFx;
import io.anuke.mindustry.entities.effect.ScorchDecal;
@@ -15,7 +26,7 @@ import io.anuke.mindustry.entities.traits.*;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.graphics.Trail;
import io.anuke.mindustry.input.Binding;
import io.anuke.mindustry.io.TypeIO;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.NetConnection;
@@ -24,13 +35,6 @@ import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.Floor;
import io.anuke.mindustry.world.blocks.storage.CoreBlock.CoreEntity;
import io.anuke.ucore.core.*;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.entities.EntityQuery;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Hue;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.util.*;
import java.io.DataInput;
import java.io.DataOutput;
@@ -63,7 +67,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
public NetConnection con;
public int playerIndex = 0;
public boolean isLocal = false;
public Timer timer = new Timer(4);
public Interval timer = new Interval(4);
public TargetTrait target;
public TargetTrait moveTarget;
@@ -71,8 +75,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
private Queue<BuildRequest> placeQueue = new Queue<>();
private Tile mining;
private CarriableTrait carrying;
private Trail trail = new Trail(12);
private Vector2 movement = new Translator();
private Vector2 movement = new Vector2();
private boolean moved;
//endregion
@@ -112,7 +115,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
}
@Override
public Timer getTimer(){
public Interval getTimer(){
return timer;
}
@@ -150,7 +153,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
}
if(interpolator.target.dst(interpolator.last) > 1f){
walktime += Timers.delta();
walktime += Time.delta();
}
}
@@ -282,18 +285,15 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
@Override
public void drawShadow(float offsetX, float offsetY){
float x = snappedX(), y = snappedY();
float scl = mech.flying ? 1f : boostHeat/2f;
float scl = mech.flying ? 1f : boostHeat / 2f;
Draw.rect(mech.iconRegion, x + offsetX*scl, y + offsetY*scl, rotation - 90);
Draw.rect(mech.iconRegion, x + offsetX * scl, y + offsetY * scl, rotation - 90);
}
@Override
public void draw(){
if(dead) return;
float x = snappedX(), y = snappedY();
if(!movement.isZero() && moved && !state.isPaused()){
walktime += movement.len() / 0.7f * getFloorOn().speedMultiplier;
baseRotation = Mathf.slerpDelta(baseRotation, movement.angle(), 0.13f);
@@ -317,9 +317,11 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
for(int i : Mathf.signs){
Draw.rect(mech.legRegion,
x + Angles.trnsx(baseRotation, ft * i + boostTrnsY, -boostTrnsX * i),
y + Angles.trnsy(baseRotation, ft * i + boostTrnsY, -boostTrnsX * i),
mech.legRegion.getRegionWidth() * i, mech.legRegion.getRegionHeight() - Mathf.clamp(ft * i, 0, 2), baseRotation - 90 + boostAng * i);
x + Angles.trnsx(baseRotation, ft * i + boostTrnsY, -boostTrnsX * i),
y + Angles.trnsy(baseRotation, ft * i + boostTrnsY, -boostTrnsX * i),
mech.legRegion.getWidth() * i * Draw.scl,
(mech.legRegion.getHeight() - Mathf.clamp(ft * i, 0, 2)) * Draw.scl,
baseRotation - 90 + boostAng * i);
}
Draw.rect(mech.baseRegion, x, y, baseRotation - 90);
@@ -337,10 +339,13 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
for(int i : Mathf.signs){
float tra = rotation - 90, trY = -mech.weapon.getRecoil(this, i > 0) + mech.weaponOffsetY;
float w = i > 0 ? -mech.weapon.equipRegion.getRegionWidth() : mech.weapon.equipRegion.getRegionWidth();
float w = i > 0 ? -mech.weapon.equipRegion.getWidth() : mech.weapon.equipRegion.getWidth();
Draw.rect(mech.weapon.equipRegion,
x + Angles.trnsx(tra, (mech.weaponOffsetX + mech.spreadX(this)) * i, trY),
y + Angles.trnsy(tra, (mech.weaponOffsetX + mech.spreadX(this)) * i, trY), w, mech.weapon.equipRegion.getRegionHeight(), rotation - 90);
x + Angles.trnsx(tra, (mech.weaponOffsetX + mech.spreadX(this)) * i, trY),
y + Angles.trnsy(tra, (mech.weaponOffsetX + mech.spreadX(this)) * i, trY),
w * Draw.scl,
mech.weapon.equipRegion.getHeight() * Draw.scl,
rotation - 90);
}
float backTrns = 4f, itemSize = 5f;
@@ -352,9 +357,9 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
float angT = i == 0 ? 0 : Mathf.randomSeedRange(i + 1, 60f);
float lenT = i == 0 ? 0 : Mathf.randomSeedRange(i + 2, 1f) - 1f;
Draw.rect(stack.item.region,
x + Angles.trnsx(rotation + 180f + angT, backTrns + lenT),
y + Angles.trnsy(rotation + 180f + angT, backTrns + lenT),
itemSize, itemSize, rotation);
x + Angles.trnsx(rotation + 180f + angT, backTrns + lenT),
y + Angles.trnsy(rotation + 180f + angT, backTrns + lenT),
itemSize, itemSize, rotation);
}
}
@@ -363,9 +368,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
@Override
public void drawStats(){
float x = snappedX(), y = snappedY();
Draw.color(Color.BLACK, team.color, healthf() + Mathf.absin(Timers.time(), healthf()*5f, 1f - healthf()));
Draw.color(Color.BLACK, team.color, healthf() + Mathf.absin(Time.time(), healthf() * 5f, 1f - healthf()));
Draw.alpha(hitTime / hitDuration);
Draw.rect(getPowerCellRegion(), x + Angles.trnsx(rotation, mech.cellTrnsY, 0f), y + Angles.trnsy(rotation, mech.cellTrnsY, 0f), rotation - 90);
Draw.color();
@@ -376,53 +379,38 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
if(dead) return;
drawBuilding(this);
if(mech.flying || boostHeat > 0.001f){
float wobblyness = 0.6f;
if(!state.isPaused()) trail.update(x + Angles.trnsx(rotation + 180f, 5f) + Mathf.range(wobblyness),
y + Angles.trnsy(rotation + 180f, 5f) + Mathf.range(wobblyness));
trail.draw(Hue.mix(mech.trailColor, mech.trailColorTo, mech.flying ? 0f : boostHeat, Tmp.c1), 5f * (isFlying() ? 1f : boostHeat));
}else{
trail.clear();
}
}
public float snappedX(){
return snapCamera && isLocal ? (int) (x + 0.0001f) : x;
}
public float snappedY(){
return snapCamera && isLocal ? (int) (y + 0.0001f) : y;
}
public void drawName(){
GlyphLayout layout = Pooling.obtain(GlyphLayout.class, GlyphLayout::new);
BitmapFont font = Core.scene.skin.getFont("default-font");
GlyphLayout layout = Pools.obtain(GlyphLayout.class, GlyphLayout::new);
boolean ints = Core.font.usesIntegerPositions();
Core.font.setUseIntegerPositions(false);
Draw.tscl(0.25f / io.anuke.ucore.scene.ui.layout.Unit.dp.scl(1f));
layout.setText(Core.font, name);
boolean ints = font.usesIntegerPositions();
font.setUseIntegerPositions(false);
font.getData().setScale(0.25f / io.anuke.arc.scene.ui.layout.Unit.dp.scl(1f));
layout.setText(font, name);
Draw.color(0f, 0f, 0f, 0.3f);
Draw.rect("blank", x, y + 8 - layout.height / 2, layout.width + 2, layout.height + 3);
Fill.rect(x, y + 8 - layout.height / 2, layout.width + 2, layout.height + 3);
Draw.color();
Draw.tcolor(color);
Draw.text(name, x, y + 8);
font.setColor(color);
font.draw(name, x, y + 8, 0, Align.center, false);
if(isAdmin){
float s = 3f;
Draw.color(color.r * 0.5f, color.g * 0.5f, color.b * 0.5f, 1f);
Draw.rect("icon-admin-small", x + layout.width / 2f + 2 + 1, y + 6.5f, s, s);
Draw.rect(Core.atlas.find("icon-admin-small"), x + layout.width / 2f + 2 + 1, y + 6.5f, s, s);
Draw.color(color);
Draw.rect("icon-admin-small", x + layout.width / 2f + 2 + 1, y + 7f, s, s);
Draw.rect(Core.atlas.find("icon-admin-small"), x + layout.width / 2f + 2 + 1, y + 7f, s, s);
}
Draw.reset();
Pooling.free(layout);
Draw.tscl(1f);
Core.font.setUseIntegerPositions(ints);
Pools.free(layout);
font.getData().setScale(1f);
font.setUseIntegerPositions(ints);
}
/**Draw all current build requests. Does not draw the beam effect, only the positions.*/
/** Draw all current build requests. Does not draw the beam effect, only the positions. */
public void drawBuildRequests(){
for(BuildRequest request : getPlaceQueue()){
if(getCurrentRequest() == request) continue;
@@ -431,42 +419,38 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
Block block = world.tile(request.x, request.y).target().block();
//draw removal request
Lines.stroke(2f);
Lines.stroke(2f, Palette.removeBack);
Draw.color(Palette.removeBack);
float rad = Mathf.absin(Timers.time(), 7f, 1f) + block.size * tilesize / 2f - 1;
float rad = Mathf.absin(Time.time(), 7f, 1f) + block.size * tilesize / 2f - 1;
Lines.square(
request.x * tilesize + block.offset(),
request.y * tilesize + block.offset() - 1,
rad);
request.x * tilesize + block.offset(),
request.y * tilesize + block.offset() - 1,
rad);
Draw.color(Palette.remove);
Lines.square(
request.x * tilesize + block.offset(),
request.y * tilesize + block.offset(),
rad);
request.x * tilesize + block.offset(),
request.y * tilesize + block.offset(),
rad);
}else{
//draw place request
Lines.stroke(2f);
Lines.stroke(2f, Palette.accentBack);
Draw.color(Palette.accentBack);
float rad = Mathf.absin(Timers.time(), 7f, 1f) - 2f + request.recipe.result.size * tilesize / 2f;
float rad = Mathf.absin(Time.time(), 7f, 1f) - 2f + request.recipe.result.size * tilesize / 2f;
Lines.square(
request.x * tilesize + request.recipe.result.offset(),
request.y * tilesize + request.recipe.result.offset() - 1,
rad);
request.x * tilesize + request.recipe.result.offset(),
request.y * tilesize + request.recipe.result.offset() - 1,
rad);
Draw.color(Palette.accent);
Lines.square(
request.x * tilesize + request.recipe.result.offset(),
request.y * tilesize + request.recipe.result.offset(),
rad);
request.x * tilesize + request.recipe.result.offset(),
request.y * tilesize + request.recipe.result.offset(),
rad);
}
}
@@ -479,7 +463,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
@Override
public void update(){
hitTime -= Timers.delta();
hitTime -= Time.delta();
if(Float.isNaN(x) || Float.isNaN(y)){
velocity.set(0f, 0f);
@@ -552,14 +536,14 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
updateBuilding(this);
x = Mathf.clamp(x, tilesize, world.width() * tilesize - tilesize);
y = Mathf.clamp(y, tilesize, world.height() * tilesize - tilesize);
x = Mathf.clamp(x, 0, world.width() * tilesize - tilesize);
y = Mathf.clamp(y, 0, world.height() * tilesize - tilesize);
}
protected void updateMech(){
Tile tile = world.tileWorld(x, y);
isBoosting = Inputs.keyDown("dash") && !mech.flying;
isBoosting = Core.input.keyDown(Binding.dash) && !mech.flying;
//if player is in solid block
if(tile != null && tile.solid()){
@@ -579,7 +563,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
}
//drop from carrier on key press
if(!ui.chatfrag.chatOpen() && Inputs.keyTap("drop_unit")){
if(!ui.chatfrag.chatOpen() && Core.input.keyTap(Binding.drop_unit)){
if(!mech.flying){
if(getCarrier() != null){
Call.dropSelf(this);
@@ -597,20 +581,19 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
movement.setZero();
String section = control.input(playerIndex).section;
float xa = Core.input.axis(Binding.move_x);
float ya = Core.input.axis(Binding.move_y);
if(!Core.input.keyDown(Binding.gridMode)){
movement.y += ya * speed;
movement.x += xa * speed;
}
float xa = Inputs.getAxis(section, "move_x");
float ya = Inputs.getAxis(section, "move_y");
movement.y += ya * speed;
movement.x += xa * speed;
Vector2 vec = Graphics.world(control.input(playerIndex).getMouseX(), control.input(playerIndex).getMouseY());
Vector2 vec = Core.input.mouseWorld(control.input(playerIndex).getMouseX(), control.input(playerIndex).getMouseY());
pointerX = vec.x;
pointerY = vec.y;
updateShooting();
movement.limit(speed).scl(Timers.delta());
movement.limit(speed).scl(Time.delta());
if(getCarrier() == null){
if(!ui.chatfrag.chatOpen()){
@@ -618,7 +601,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
}
float prex = x, prey = y;
updateVelocityStatus();
moved = distanceTo(prex, prey) > 0.001f;
moved = dst(prex, prey) > 0.001f;
}else{
velocity.setZero();
x = Mathf.lerpDelta(x, getCarrier().getX(), 0.1f);
@@ -646,7 +629,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
protected void updateFlying(){
if(Units.invalidateTarget(target, this) && !(target instanceof TileEntity && ((TileEntity) target).damaged() && target.getTeam() == team &&
mech.canHeal && distanceTo(target) < getWeapon().getAmmo().getRange())){
mech.canHeal && dst(target) < getWeapon().getAmmo().getRange())){
target = null;
}
@@ -663,7 +646,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
velocity.setAngle(Mathf.slerpDelta(velocity.angle(), angleTo(moveTarget), 0.1f));
}
if(distanceTo(moveTarget) < 2f){
if(dst(moveTarget) < 2f){
if(moveTarget instanceof CarriableTrait){
carry((CarriableTrait) moveTarget);
}else if(tapping){
@@ -686,7 +669,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
movement.set(targetX - x, targetY - y).limit(isBoosting && !mech.flying ? mech.boostSpeed : mech.speed);
movement.setAngle(Mathf.slerp(movement.angle(), velocity.angle(), 0.05f));
if(distanceTo(targetX, targetY) < attractDst){
if(dst(targetX, targetY) < attractDst){
movement.setZero();
}
@@ -695,27 +678,27 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
getHitbox(rect);
rect.x -= expansion;
rect.y -= expansion;
rect.width += expansion*2f;
rect.height += expansion*2f;
rect.width += expansion * 2f;
rect.height += expansion * 2f;
isBoosting = EntityQuery.collisions().overlapsTile(rect) || distanceTo(targetX, targetY) > 85f;
isBoosting = EntityQuery.collisions().overlapsTile(rect) || dst(targetX, targetY) > 85f;
velocity.add(movement.scl(Timers.delta()));
velocity.add(movement.scl(Time.delta()));
if(velocity.len() <= 0.2f && mech.flying){
rotation += Mathf.sin(Timers.time() + id * 99, 10f, 1f);
rotation += Mathf.sin(Time.time() + id * 99, 10f, 1f);
}else if(target == null){
rotation = Mathf.slerpDelta(rotation, velocity.angle(), velocity.len() / 10f);
}
float lx = x, ly = y;
updateVelocityStatus();
moved = distanceTo(lx, ly) > 0.001f && !isCarried();
moved = dst(lx, ly) > 0.001f && !isCarried();
if(mech.flying){
//hovering effect
x += Mathf.sin(Timers.time() + id * 999, 25f, 0.08f);
y += Mathf.cos(Timers.time() + id * 999, 25f, 0.08f);
x += Mathf.sin(Time.time() + id * 999, 25f, 0.08f);
y += Mathf.cos(Time.time() + id * 999, 25f, 0.08f);
}
//update shooting if not building, not mining and there's ammo left
@@ -725,15 +708,15 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
if(mobile){
if(target == null){
isShooting = false;
if(Settings.getBool("autotarget")){
if(Core.settings.getBool("autotarget")){
target = Units.getClosestTarget(team, x, y, getWeapon().getAmmo().getRange());
if(mech.canHeal && target == null){
target = Geometry.findClosest(x, y, world.indexer.getDamaged(Team.blue));
if(target != null && distanceTo(target) > getWeapon().getAmmo().getRange()){
if(target != null && dst(target) > getWeapon().getAmmo().getRange()){
target = null;
}else if(target != null){
target = ((Tile)target).entity;
target = ((Tile) target).entity;
}
}
@@ -742,14 +725,14 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
}
}
}else if(target.isValid() || (target instanceof TileEntity && ((TileEntity) target).damaged() && target.getTeam() == team &&
mech.canHeal && distanceTo(target) < getWeapon().getAmmo().getRange())){
mech.canHeal && dst(target) < getWeapon().getAmmo().getRange())){
//rotate toward and shoot the target
if(mech.turnCursor){
rotation = Mathf.slerpDelta(rotation, angleTo(target), 0.2f);
}
Vector2 intercept =
Predict.intercept(x, y, target.getX(), target.getY(), target.getVelocity().x - velocity.x, target.getVelocity().y - velocity.y, getWeapon().getAmmo().bullet.speed);
Predict.intercept(x, y, target.getX(), target.getY(), target.getVelocity().x - velocity.x, target.getVelocity().y - velocity.y, getWeapon().getAmmo().bullet.speed);
pointerX = intercept.x;
pointerY = intercept.y;
@@ -759,8 +742,8 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
}
}else if(isShooting()){
Vector2 vec = Graphics.world(control.input(playerIndex).getMouseX(),
control.input(playerIndex).getMouseY());
Vector2 vec = Core.input.mouseWorld(control.input(playerIndex).getMouseX(),
control.input(playerIndex).getMouseY());
pointerX = vec.x;
pointerY = vec.y;
@@ -773,7 +756,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
//region utility methods
/** Resets all values of the player.*/
/** Resets all values of the player. */
public void reset(){
resetNoAdd();
@@ -786,7 +769,8 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
inventory.clear();
placeQueue.clear();
dead = true;
trail.clear();
target = null;
moveTarget = null;
carrier = null;
health = maxHealth();
boostHeat = drownTime = hitTime = 0f;
@@ -869,7 +853,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
public void write(DataOutput buffer) throws IOException{
super.writeSave(buffer, !isLocal);
TypeIO.writeStringData(buffer, name); //TODO writing strings is very inefficient
buffer.writeByte(Bits.toByte(isAdmin) | (Bits.toByte(dead) << 1) | (Bits.toByte(isBoosting) << 2));
buffer.writeByte(Pack.byteValue(isAdmin) | (Pack.byteValue(dead) << 1) | (Pack.byteValue(isBoosting) << 2));
buffer.writeInt(Color.rgba8888(color));
buffer.writeByte(mech.id);
buffer.writeInt(mining == null ? -1 : mining.pos());
@@ -880,7 +864,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
}
@Override
public void read(DataInput buffer, long time) throws IOException{
public void read(DataInput buffer) throws IOException{
float lastx = x, lasty = y, lastrot = rotation;
super.readSave(buffer);
name = TypeIO.readStringData(buffer);
@@ -896,7 +880,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
readBuilding(buffer, !isLocal);
interpolator.read(lastx, lasty, x, y, time, rotation, baseRotation);
interpolator.read(lastx, lasty, x, y, rotation, baseRotation);
rotation = lastrot;
if(isLocal){

View File

@@ -1,8 +1,8 @@
package io.anuke.mindustry.entities;
import com.badlogic.gdx.math.Vector2;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.geom.Vector2;
import io.anuke.mindustry.entities.traits.TargetTrait;
import io.anuke.ucore.util.Mathf;
/**
* Class for predicting shoot angles based on velocities of targets.

View File

@@ -1,15 +1,14 @@
package io.anuke.mindustry.entities;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.utils.Array;
import io.anuke.arc.collection.Array;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.util.Time;
import io.anuke.arc.util.Tmp;
import io.anuke.arc.util.pooling.Pools;
import io.anuke.mindustry.content.StatusEffects;
import io.anuke.mindustry.entities.traits.Saveable;
import io.anuke.mindustry.type.ContentType;
import io.anuke.mindustry.type.StatusEffect;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.util.Pooling;
import io.anuke.ucore.util.ThreadArray;
import io.anuke.ucore.util.Tmp;
import java.io.DataInput;
import java.io.DataOutput;
@@ -21,9 +20,9 @@ import static io.anuke.mindustry.Vars.content;
*/
public class StatusController implements Saveable{
private static final StatusEntry globalResult = new StatusEntry();
private static final Array<StatusEntry> removals = new ThreadArray<>();
private static final Array<StatusEntry> removals = new Array<>();
private Array<StatusEntry> statuses = new ThreadArray<>();
private Array<StatusEntry> statuses = new Array<>();
private float speedMultiplier;
private float damageMultiplier;
@@ -57,7 +56,7 @@ public class StatusController implements Saveable{
}
//otherwise, no opposites found, add direct effect
StatusEntry entry = Pooling.obtain(StatusEntry.class, StatusEntry::new);
StatusEntry entry = Pools.obtain(StatusEntry.class, StatusEntry::new);
entry.set(effect, newTime);
statuses.add(entry);
}
@@ -88,10 +87,10 @@ public class StatusController implements Saveable{
removals.clear();
for(StatusEntry entry : statuses){
entry.time = Math.max(entry.time - Timers.delta(), 0);
entry.time = Math.max(entry.time - Time.delta(), 0);
if(entry.time <= 0){
Pooling.free(entry);
Pools.free(entry);
removals.add(entry);
}else{
speedMultiplier *= entry.effect.speedMultiplier;
@@ -137,7 +136,7 @@ public class StatusController implements Saveable{
@Override
public void readSave(DataInput stream) throws IOException{
for(StatusEntry effect : statuses){
Pooling.free(effect);
Pools.free(effect);
}
statuses.clear();
@@ -146,7 +145,7 @@ public class StatusController implements Saveable{
for(int i = 0; i < amount; i++){
byte id = stream.readByte();
float time = stream.readShort() / 2f;
StatusEntry entry = Pooling.obtain(StatusEntry.class, StatusEntry::new);
StatusEntry entry = Pools.obtain(StatusEntry.class, StatusEntry::new);
entry.set(content.getByID(ContentType.status, id), time);
statuses.add(entry);
}

View File

@@ -1,11 +1,18 @@
package io.anuke.mindustry.entities;
import com.badlogic.gdx.math.GridPoint2;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.ObjectSet;
import io.anuke.annotations.Annotations.Loc;
import io.anuke.annotations.Annotations.Remote;
import io.anuke.arc.collection.Array;
import io.anuke.arc.collection.ObjectSet;
import io.anuke.arc.entities.Effects;
import io.anuke.arc.entities.EntityGroup;
import io.anuke.arc.entities.impl.BaseEntity;
import io.anuke.arc.entities.trait.HealthTrait;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.geom.Point2;
import io.anuke.arc.math.geom.Vector2;
import io.anuke.arc.util.Interval;
import io.anuke.arc.util.Time;
import io.anuke.mindustry.content.fx.Fx;
import io.anuke.mindustry.entities.bullet.Bullet;
import io.anuke.mindustry.entities.traits.TargetTrait;
@@ -20,13 +27,6 @@ import io.anuke.mindustry.world.modules.ConsumeModule;
import io.anuke.mindustry.world.modules.ItemModule;
import io.anuke.mindustry.world.modules.LiquidModule;
import io.anuke.mindustry.world.modules.PowerModule;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.entities.impl.BaseEntity;
import io.anuke.ucore.entities.trait.HealthTrait;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Timer;
import java.io.DataInput;
import java.io.DataOutput;
@@ -42,7 +42,7 @@ public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{
public static int sleepingEntities = 0;
public Tile tile;
public Timer timer;
public Interval timer;
public float health;
public float timeScale = 1f, timeScaleDuration;
@@ -78,7 +78,7 @@ public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{
health = tile.block().health;
timer = new Timer(tile.block().timers);
timer = new Interval(tile.block().timers);
if(shouldAdd){
add();
@@ -89,12 +89,12 @@ public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{
/**Scaled delta.*/
public float delta(){
return Timers.delta() * timeScale;
return Time.delta() * timeScale;
}
/**Call when nothing is happening to the entity. This increments the internal sleep timer.*/
public void sleep(){
sleepTime += Timers.delta();
sleepTime += Time.delta();
if(!sleeping && sleepTime >= timeToSleep){
remove();
sleeping = true;
@@ -169,8 +169,8 @@ public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{
public void removeFromProximity(){
tile.block().onProximityRemoved(tile);
GridPoint2[] nearby = Edges.getEdges(tile.block().size);
for(GridPoint2 point : nearby){
Point2[] nearby = Edges.getEdges(tile.block().size);
for(Point2 point : nearby){
Tile other = world.tile(tile.x + point.x, tile.y + point.y);
//remove this tile from all nearby tile's proximities
if(other != null){
@@ -187,8 +187,8 @@ public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{
tmpTiles.clear();
proximity.clear();
GridPoint2[] nearby = Edges.getEdges(tile.block().size);
for(GridPoint2 point : nearby){
Point2[] nearby = Edges.getEdges(tile.block().size);
for(Point2 point : nearby){
Tile other = world.tile(tile.x + point.x, tile.y + point.y);
if(other == null) continue;
@@ -258,19 +258,19 @@ public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{
@Override
public Vector2 getVelocity(){
return Vector2.Zero;
return Vector2.ZERO;
}
@Override
public void update(){
//TODO better smoke effect, this one is awful
if(health != 0 && health < tile.block().health && !(tile.block() instanceof Wall) &&
Mathf.chance(0.009f * Timers.delta() * (1f - health / tile.block().health))){
Mathf.chance(0.009f * Time.delta() * (1f - health / tile.block().health))){
Effects.effect(Fx.smoke, x + Mathf.range(4), y + Mathf.range(4));
}
timeScaleDuration -= Timers.delta();
timeScaleDuration -= Time.delta();
if(timeScaleDuration <= 0f || !tile.block().canOverdrive){
timeScale = 1f;
}

View File

@@ -1,9 +1,20 @@
package io.anuke.mindustry.entities;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import io.anuke.arc.Core;
import io.anuke.arc.entities.Effects;
import io.anuke.arc.entities.impl.DestructibleEntity;
import io.anuke.arc.entities.trait.DamageTrait;
import io.anuke.arc.entities.trait.DrawTrait;
import io.anuke.arc.entities.trait.SolidTrait;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.Fill;
import io.anuke.arc.graphics.g2d.TextureRegion;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.geom.Geometry;
import io.anuke.arc.math.geom.Rectangle;
import io.anuke.arc.math.geom.Vector2;
import io.anuke.arc.util.Time;
import io.anuke.mindustry.content.blocks.Blocks;
import io.anuke.mindustry.entities.traits.*;
import io.anuke.mindustry.game.Team;
@@ -15,16 +26,6 @@ import io.anuke.mindustry.type.Weapon;
import io.anuke.mindustry.world.Pos;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.Floor;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.impl.DestructibleEntity;
import io.anuke.ucore.entities.trait.DamageTrait;
import io.anuke.ucore.entities.trait.DrawTrait;
import io.anuke.ucore.entities.trait.SolidTrait;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Fill;
import io.anuke.ucore.util.Geometry;
import io.anuke.ucore.util.Mathf;
import java.io.DataInput;
import java.io.DataOutput;
@@ -194,7 +195,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
Units.getNearby(queryRect, t -> {
if(t == this || t.getCarrier() == this || getCarrier() == t || t.isFlying() != isFlying()) return;
float dst = distanceTo(t);
float dst = dst(t);
moveVector.set(x, y).sub(t.getX(), t.getY()).setLength(1f * (1f - (dst / queryRect.getWidth())));
applyImpulse(moveVector.x, moveVector.y);
});
@@ -235,11 +236,11 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
status.update(this);
velocity.limit(getMaxVelocity()).scl(1f + (status.getSpeedMultiplier()-1f) * Timers.delta());
velocity.limit(getMaxVelocity()).scl(1f + (status.getSpeedMultiplier()-1f) * Time.delta());
if(isFlying()){
x += velocity.x * Timers.delta();
y += velocity.y * Timers.delta();
x += velocity.x * Time.delta();
y += velocity.y * Time.delta();
}else{
boolean onLiquid = floor.isLiquid;
@@ -255,7 +256,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
}
}
if(onLiquid && velocity.len() > 0.4f && Mathf.chance((velocity.len() * floor.speedMultiplier) * 0.06f * Timers.delta())){
if(onLiquid && velocity.len() > 0.4f && Mathf.chance((velocity.len() * floor.speedMultiplier) * 0.06f * Time.delta())){
Effects.effect(floor.walkEffect, floor.liquidColor, x, y);
}
@@ -268,8 +269,8 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
}
if(onLiquid && floor.drownTime > 0){
drownTime += Timers.delta() * 1f / floor.drownTime;
if(Mathf.chance(Timers.delta() * 0.05f)){
drownTime += Time.delta() * 1f / floor.drownTime;
if(Mathf.chance(Time.delta() * 0.05f)){
Effects.effect(floor.drownUpdateEffect, floor.liquidColor, x, y);
}
}else{
@@ -283,12 +284,12 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
}
float px = x, py = y;
move(velocity.x * floor.speedMultiplier * Timers.delta(), velocity.y * floor.speedMultiplier * Timers.delta());
move(velocity.x * floor.speedMultiplier * Time.delta(), velocity.y * floor.speedMultiplier * Time.delta());
if(Math.abs(px - x) <= 0.0001f) velocity.x = 0f;
if(Math.abs(py - y) <= 0.0001f) velocity.y = 0f;
}
velocity.scl(Mathf.clamp(1f - getDrag() * (isFlying() ? 1f : floor.dragMultiplier) * Timers.delta()));
velocity.scl(Mathf.clamp(1f - getDrag() * (isFlying() ? 1f : floor.dragMultiplier) * Time.delta()));
}
public void applyEffect(StatusEffect effect, float intensity){
@@ -297,7 +298,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
}
public void damagePeriodic(float amount){
damage(amount * Timers.delta(), hitTime <= -20 + hitDuration);
damage(amount * Time.delta(), hitTime <= -20 + hitDuration);
}
public void damage(float amount, boolean withEffect){
@@ -317,14 +318,14 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
}
public void drawStats(){
Draw.color(Color.BLACK, team.color, healthf() + Mathf.absin(Timers.time(), healthf()*5f, 1f - healthf()));
Draw.color(Color.BLACK, team.color, healthf() + Mathf.absin(Time.time(), healthf()*5f, 1f - healthf()));
Draw.alpha(hitTime);
Draw.rect(getPowerCellRegion(), x, y, rotation - 90);
Draw.color();
}
public TextureRegion getPowerCellRegion(){
return Draw.region("power-cell");
return Core.atlas.find("power-cell");
}
public void drawAll(){

View File

@@ -1,18 +1,18 @@
package io.anuke.mindustry.entities;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import io.anuke.arc.collection.EnumSet;
import io.anuke.arc.entities.EntityGroup;
import io.anuke.arc.entities.EntityQuery;
import io.anuke.arc.function.Consumer;
import io.anuke.arc.function.Predicate;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.geom.Geometry;
import io.anuke.arc.math.geom.Rectangle;
import io.anuke.mindustry.entities.traits.TargetTrait;
import io.anuke.mindustry.entities.units.BaseUnit;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.entities.EntityQuery;
import io.anuke.ucore.function.Consumer;
import io.anuke.ucore.function.Predicate;
import io.anuke.ucore.util.EnumSet;
import io.anuke.ucore.util.Geometry;
import static io.anuke.mindustry.Vars.*;
@@ -38,7 +38,7 @@ public class Units{
* @return whether the target is invalid
*/
public static boolean invalidateTarget(TargetTrait target, Team team, float x, float y, float range){
return target == null || (range != Float.MAX_VALUE && target.distanceTo(x, y) > range) || target.getTeam() == team || !target.isValid();
return target == null || (range != Float.MAX_VALUE && target.dst(x, y) > range) || target.getTeam() == team || !target.isValid();
}
/**See {@link #invalidateTarget(TargetTrait, Team, float, float, float)}*/
@@ -165,7 +165,7 @@ public class Units{
if(e.isDead() || !predicate.test(e))
return;
float dist = Vector2.dst(e.x, e.y, x, y);
float dist = Mathf.dst(e.x, e.y, x, y);
if(dist < range){
if(result == null || dist < cdist){
result = e;
@@ -188,7 +188,7 @@ public class Units{
if(!predicate.test(e))
return;
float dist = Vector2.dst(e.x, e.y, x, y);
float dist = Mathf.dst(e.x, e.y, x, y);
if(dist < range){
if(result == null || dist < cdist){
result = e;
@@ -221,7 +221,7 @@ public class Units{
EntityGroup<BaseUnit> group = unitGroups[team.ordinal()];
if(!group.isEmpty()){
EntityQuery.getNearby(group, rect, entity -> {
if(entity.distanceTo(x, y) <= radius){
if(entity.dst(x, y) <= radius){
cons.accept((Unit) entity);
}
});
@@ -229,7 +229,7 @@ public class Units{
//now check all players
EntityQuery.getNearby(playerGroup, rect, player -> {
if(((Unit) player).team == team && player.distanceTo(x, y) <= radius){
if(((Unit) player).team == team && player.dst(x, y) <= radius){
cons.accept((Unit) player);
}
});

View File

@@ -1,9 +1,9 @@
package io.anuke.mindustry.entities.bullet;
import io.anuke.mindustry.content.fx.BulletFx;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.graphics.Draw;
import io.anuke.arc.entities.Effects;
import io.anuke.arc.entities.Effects.Effect;
import io.anuke.arc.graphics.g2d.Draw;
//TODO scale velocity depending on fslope()
public class ArtilleryBulletType extends BasicBulletType{

View File

@@ -1,16 +1,17 @@
package io.anuke.mindustry.entities.bullet;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import io.anuke.arc.Core;
import io.anuke.arc.entities.Effects;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.TextureRegion;
import io.anuke.arc.math.Angles;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.util.Time;
import io.anuke.mindustry.entities.Damage;
import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.entities.traits.TargetTrait;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf;
/**
* A BulletType for most ammo-based bullets shot from turrets and units.
@@ -47,8 +48,8 @@ public class BasicBulletType extends BulletType{
@Override
public void load(){
backRegion = Draw.region(bulletSprite + "-back");
frontRegion = Draw.region(bulletSprite);
backRegion = Core.atlas.find(bulletSprite + "-back");
frontRegion = Core.atlas.find(bulletSprite);
}
@Override
@@ -69,7 +70,7 @@ public class BasicBulletType extends BulletType{
if(homingPower > 0.0001f){
TargetTrait target = Units.getClosestTarget(b.getTeam(), b.x, b.y, homingRange);
if(target != null){
b.getVelocity().setAngle(Angles.moveToward(b.getVelocity().angle(), b.angleTo(target), homingPower * Timers.delta()));
b.getVelocity().setAngle(Angles.moveToward(b.getVelocity().angle(), b.angleTo(target), homingPower * Time.delta()));
}
}
}

View File

@@ -1,8 +1,17 @@
package io.anuke.mindustry.entities.bullet;
import com.badlogic.gdx.math.Vector2;
import io.anuke.annotations.Annotations.Loc;
import io.anuke.annotations.Annotations.Remote;
import io.anuke.arc.entities.EntityGroup;
import io.anuke.arc.entities.impl.BulletEntity;
import io.anuke.arc.entities.trait.Entity;
import io.anuke.arc.entities.trait.SolidTrait;
import io.anuke.arc.entities.trait.VelocityTrait;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.geom.Vector2;
import io.anuke.arc.util.Interval;
import io.anuke.arc.util.Time;
import io.anuke.arc.util.pooling.Pools;
import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.entities.effect.Lightning;
import io.anuke.mindustry.entities.traits.AbsorbTrait;
@@ -10,15 +19,6 @@ import io.anuke.mindustry.entities.traits.SyncTrait;
import io.anuke.mindustry.entities.traits.TeamTrait;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.entities.impl.BulletEntity;
import io.anuke.ucore.entities.trait.Entity;
import io.anuke.ucore.entities.trait.SolidTrait;
import io.anuke.ucore.entities.trait.VelocityTrait;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Pooling;
import io.anuke.ucore.util.Timer;
import java.io.DataInput;
import java.io.DataOutput;
@@ -28,7 +28,7 @@ import static io.anuke.mindustry.Vars.*;
public class Bullet extends BulletEntity<BulletType> implements TeamTrait, SyncTrait, AbsorbTrait{
private static Vector2 vector = new Vector2();
public Timer timer = new Timer(3);
public Interval timer = new Interval(3);
private float lifeScl;
private Team team;
private Object data;
@@ -55,21 +55,21 @@ public class Bullet extends BulletEntity<BulletType> implements TeamTrait, SyncT
}
public static Bullet create(BulletType type, Entity owner, Team team, float x, float y, float angle, float velocityScl, float lifetimeScl, Object data){
Bullet bullet = Pooling.obtain(Bullet.class, Bullet::new);
Bullet bullet = Pools.obtain(Bullet.class, Bullet::new);
bullet.type = type;
bullet.owner = owner;
bullet.data = data;
bullet.velocity.set(0, type.speed).setAngle(angle).scl(velocityScl);
if(type.keepVelocity){
bullet.velocity.add(owner instanceof VelocityTrait ? ((VelocityTrait) owner).getVelocity() : Vector2.Zero);
bullet.velocity.add(owner instanceof VelocityTrait ? ((VelocityTrait) owner).getVelocity() : Vector2.ZERO);
}
bullet.team = team;
bullet.type = type;
bullet.lifeScl = lifetimeScl;
bullet.set(x - bullet.velocity.x * Timers.delta(), y - bullet.velocity.y * Timers.delta());
bullet.set(x - bullet.velocity.x * Time.delta(), y - bullet.velocity.y * Time.delta());
bullet.add();
return bullet;
@@ -158,7 +158,7 @@ public class Bullet extends BulletEntity<BulletType> implements TeamTrait, SyncT
}
@Override
public void read(DataInput data, long time) throws IOException{
public void read(DataInput data) throws IOException{
x = data.readFloat();
y = data.readFloat();
velocity.x = data.readFloat();
@@ -236,7 +236,7 @@ public class Bullet extends BulletEntity<BulletType> implements TeamTrait, SyncT
@Override
protected void updateLife(){
time += Timers.delta() * 1f/(lifeScl);
time += Time.delta() * 1f/(lifeScl);
time = Mathf.clamp(time, 0, type.lifetime());
if(time >= type.lifetime){
@@ -259,7 +259,7 @@ public class Bullet extends BulletEntity<BulletType> implements TeamTrait, SyncT
@Override
public void removed(){
Pooling.free(this);
Pools.free(this);
}
@Override

View File

@@ -1,15 +1,15 @@
package io.anuke.mindustry.entities.bullet;
import io.anuke.arc.entities.Effects;
import io.anuke.arc.entities.Effects.Effect;
import io.anuke.arc.entities.impl.BaseBulletType;
import io.anuke.arc.math.geom.Vector2;
import io.anuke.mindustry.content.StatusEffects;
import io.anuke.mindustry.content.fx.BulletFx;
import io.anuke.mindustry.game.Content;
import io.anuke.mindustry.type.ContentType;
import io.anuke.mindustry.type.StatusEffect;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.entities.impl.BaseBulletType;
import io.anuke.ucore.util.Translator;
public abstract class BulletType extends Content implements BaseBulletType<Bullet>{
public float lifetime;
@@ -45,7 +45,7 @@ public abstract class BulletType extends Content implements BaseBulletType<Bulle
/**Whether velocity is inherited from the shooter.*/
public boolean keepVelocity = true;
protected Translator vector = new Translator();
protected Vector2 vector = new Vector2();
public BulletType(float speed, float damage){
this.speed = speed;

View File

@@ -1,9 +1,9 @@
package io.anuke.mindustry.entities.bullet;
import com.badlogic.gdx.math.Rectangle;
import io.anuke.arc.math.geom.Rectangle;
import io.anuke.mindustry.content.fx.BulletFx;
import io.anuke.mindustry.entities.Units;
import io.anuke.ucore.core.Timers;
import io.anuke.arc.util.Time;
public abstract class FlakBulletType extends BasicBulletType{
protected static Rectangle rect = new Rectangle();
@@ -27,9 +27,9 @@ public abstract class FlakBulletType extends BasicBulletType{
Units.getNearbyEnemies(b.getTeam(), rect.setSize(explodeRange*2f).setCenter(b.x, b.y), unit -> {
if(b.getData() instanceof Float) return;
if(unit.distanceTo(b) < explodeRange){
if(unit.dst(b) < explodeRange){
b.setData(0);
Timers.run(5f, () -> {
Time.run(5f, () -> {
if(b.getData() instanceof Integer){
b.time(b.lifetime());
}

View File

@@ -1,18 +1,18 @@
package io.anuke.mindustry.entities.bullet;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.GridPoint2;
import io.anuke.arc.entities.Effects;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.Fill;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.geom.Geometry;
import io.anuke.arc.math.geom.Point2;
import io.anuke.mindustry.content.fx.BulletFx;
import io.anuke.mindustry.content.fx.Fx;
import io.anuke.mindustry.entities.effect.Fire;
import io.anuke.mindustry.entities.effect.Puddle;
import io.anuke.mindustry.type.Liquid;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Fill;
import io.anuke.ucore.util.Geometry;
import io.anuke.ucore.util.Mathf;
import static io.anuke.mindustry.Vars.tilesize;
import static io.anuke.mindustry.Vars.world;
@@ -60,7 +60,7 @@ public class LiquidBulletType extends BulletType{
if(liquid.temperature <= 0.5f && liquid.flammability < 0.3f){
float intensity = 400f;
Fire.extinguish(world.tileWorld(hitx, hity), intensity);
for(GridPoint2 p : Geometry.d4){
for(Point2 p : Geometry.d4){
Fire.extinguish(world.tileWorld(hitx + p.x * tilesize, hity + p.y * tilesize), intensity);
}
}

View File

@@ -1,11 +1,11 @@
package io.anuke.mindustry.entities.bullet;
import com.badlogic.gdx.graphics.Color;
import io.anuke.arc.graphics.Color;
import io.anuke.mindustry.content.fx.BulletFx;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.util.Mathf;
import io.anuke.arc.entities.Effects;
import io.anuke.arc.util.Time;
import io.anuke.arc.math.Mathf;
public class MissileBulletType extends BasicBulletType{
protected Color trailColor = Palette.missileYellowBack;
@@ -21,7 +21,7 @@ public class MissileBulletType extends BasicBulletType{
public void update(Bullet b){
super.update(b);
if(Mathf.chance(Timers.delta() * 0.2)){
if(Mathf.chance(Time.delta() * 0.2)){
Effects.effect(BulletFx.missileTrail, trailColor, b.x, b.y, 2f);
}
}

View File

@@ -1,12 +1,12 @@
package io.anuke.mindustry.entities.effect;
import com.badlogic.gdx.graphics.Color;
import io.anuke.arc.graphics.Color;
import io.anuke.mindustry.entities.traits.BelowLiquidTrait;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.entities.impl.TimedEntity;
import io.anuke.ucore.entities.trait.DrawTrait;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.util.Mathf;
import io.anuke.arc.entities.EntityGroup;
import io.anuke.arc.entities.impl.TimedEntity;
import io.anuke.arc.entities.trait.DrawTrait;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.math.Mathf;
import static io.anuke.mindustry.Vars.groundEffectGroup;

View File

@@ -1,10 +1,18 @@
package io.anuke.mindustry.entities.effect;
import com.badlogic.gdx.math.GridPoint2;
import com.badlogic.gdx.utils.IntMap;
import com.badlogic.gdx.utils.Pool.Poolable;
import io.anuke.annotations.Annotations.Loc;
import io.anuke.annotations.Annotations.Remote;
import io.anuke.arc.collection.IntMap;
import io.anuke.arc.entities.Effects;
import io.anuke.arc.entities.EntityGroup;
import io.anuke.arc.entities.impl.TimedEntity;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.geom.Geometry;
import io.anuke.arc.math.geom.Point2;
import io.anuke.arc.util.Structs;
import io.anuke.arc.util.Time;
import io.anuke.arc.util.pooling.Pool.Poolable;
import io.anuke.arc.util.pooling.Pools;
import io.anuke.mindustry.content.StatusEffects;
import io.anuke.mindustry.content.bullets.TurretBullets;
import io.anuke.mindustry.content.fx.EnvironmentFx;
@@ -16,14 +24,6 @@ import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.entities.impl.TimedEntity;
import io.anuke.ucore.util.Structs;
import io.anuke.ucore.util.Geometry;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Pooling;
import java.io.DataInput;
import java.io.DataOutput;
@@ -51,7 +51,7 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable{
Fire fire = map.get(tile.pos());
if(fire == null){
fire = Pooling.obtain(Fire.class, Fire::new);
fire = Pools.obtain(Fire.class, Fire::new);
fire.tile = tile;
fire.lifetime = baseLifetime;
fire.set(tile.worldx(), tile.worldy());
@@ -76,7 +76,7 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable{
*/
public static void extinguish(Tile tile, float intensity){
if(tile != null && map.containsKey(tile.pos())){
map.get(tile.pos()).time += intensity * Timers.delta();
map.get(tile.pos()).time += intensity * Time.delta();
}
}
@@ -92,11 +92,11 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable{
@Override
public void update(){
if(Mathf.chance(0.1 * Timers.delta())){
if(Mathf.chance(0.1 * Time.delta())){
Effects.effect(EnvironmentFx.fire, x + Mathf.range(4f), y + Mathf.range(4f));
}
if(Mathf.chance(0.05 * Timers.delta())){
if(Mathf.chance(0.05 * Time.delta())){
Effects.effect(EnvironmentFx.smoke, x + Mathf.range(4f), y + Mathf.range(4f));
}
@@ -104,7 +104,7 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable{
return;
}
time = Mathf.clamp(time + Timers.delta(), 0, lifetime());
time = Mathf.clamp(time + Time.delta(), 0, lifetime());
if(time >= lifetime() || tile == null){
Call.onFireRemoved(getID());
@@ -118,7 +118,7 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable{
float flammability = baseFlammability + puddleFlammability;
if(!damage && flammability <= 0){
time += Timers.delta() * 8;
time += Time.delta() * 8;
}
if(baseFlammability < 0 || block != tile.block()){
@@ -127,20 +127,20 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable{
}
if(damage){
lifetime += Mathf.clamp(flammability / 8f, 0f, 0.6f) * Timers.delta();
lifetime += Mathf.clamp(flammability / 8f, 0f, 0.6f) * Time.delta();
}
if(flammability > 1f && Mathf.chance(spreadChance * Timers.delta() * Mathf.clamp(flammability / 5f, 0.3f, 2f))){
GridPoint2 p = Mathf.select(Geometry.d4);
if(flammability > 1f && Mathf.chance(spreadChance * Time.delta() * Mathf.clamp(flammability / 5f, 0.3f, 2f))){
Point2 p = Geometry.d4[Mathf.random(3)];
Tile other = world.tile(tile.x + p.x, tile.y + p.y);
create(other);
if(Mathf.chance(fireballChance * Timers.delta() * Mathf.clamp(flammability / 10.0))){
if(Mathf.chance(fireballChance * Time.delta() * Mathf.clamp(flammability / 10f))){
Call.createBullet(TurretBullets.fireball, x, y, Mathf.random(360f));
}
}
if(Mathf.chance(0.1 * Timers.delta())){
if(Mathf.chance(0.1 * Time.delta())){
Puddle p = Puddle.getPuddle(tile);
if(p != null){
puddleFlammability = p.getFlammability() / 3f;
@@ -177,7 +177,7 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable{
}
@Override
public void read(DataInput data, long time) throws IOException{
public void read(DataInput data) throws IOException{
x = data.readFloat();
y = data.readFloat();
}

View File

@@ -1,13 +1,13 @@
package io.anuke.mindustry.entities.effect;
import io.anuke.arc.entities.Effects;
import io.anuke.arc.entities.Effects.Effect;
import io.anuke.arc.entities.Effects.EffectRenderer;
import io.anuke.arc.entities.impl.EffectEntity;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.util.Time;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.impl.EffectEntity;
import io.anuke.ucore.core.Effects.EffectRenderer;
import io.anuke.ucore.util.Mathf;
/**
* A ground effect contains an effect that is rendered on the ground layer as opposed to the top layer.
@@ -20,7 +20,7 @@ public class GroundEffectEntity extends EffectEntity{
GroundEffect effect = (GroundEffect) this.effect;
if(effect.isStatic){
time += Timers.delta();
time += Time.delta();
time = Mathf.clamp(time, 0, effect.staticLife);

View File

@@ -1,26 +1,25 @@
package io.anuke.mindustry.entities.effect;
import com.badlogic.gdx.math.Interpolation;
import com.badlogic.gdx.math.Vector2;
import io.anuke.annotations.Annotations.Loc;
import io.anuke.annotations.Annotations.Remote;
import io.anuke.arc.entities.EntityGroup;
import io.anuke.arc.entities.impl.TimedEntity;
import io.anuke.arc.entities.trait.DrawTrait;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.Fill;
import io.anuke.arc.graphics.g2d.Lines;
import io.anuke.arc.math.Interpolation;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.geom.Position;
import io.anuke.arc.math.geom.Vector2;
import io.anuke.arc.util.Time;
import io.anuke.arc.util.pooling.Pools;
import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.entities.impl.TimedEntity;
import io.anuke.ucore.entities.trait.DrawTrait;
import io.anuke.ucore.entities.trait.PosTrait;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Fill;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Pooling;
import static io.anuke.mindustry.Vars.effectGroup;
import static io.anuke.mindustry.Vars.threads;
public class ItemTransfer extends TimedEntity implements DrawTrait{
private Vector2 from = new Vector2();
@@ -28,7 +27,7 @@ public class ItemTransfer extends TimedEntity implements DrawTrait{
private Vector2 tovec = new Vector2();
private Item item;
private float seed;
private PosTrait to;
private Position to;
private Runnable done;
public ItemTransfer(){
@@ -51,14 +50,14 @@ public class ItemTransfer extends TimedEntity implements DrawTrait{
public static void transferItemTo(Item item, int amount, float x, float y, Tile tile){
if(tile == null || tile.entity == null || tile.entity.items == null) return;
for(int i = 0; i < Mathf.clamp(amount / 3, 1, 8); i++){
Timers.run(i * 3, () -> create(item, x, y, tile, () -> {
Time.run(i * 3, () -> create(item, x, y, tile, () -> {
}));
}
tile.entity.items.add(item, amount);
}
public static void create(Item item, float fromx, float fromy, PosTrait to, Runnable done){
ItemTransfer tr = Pooling.obtain(ItemTransfer.class, ItemTransfer::new);
public static void create(Item item, float fromx, float fromy, Position to, Runnable done){
ItemTransfer tr = Pools.obtain(ItemTransfer.class, ItemTransfer::new);
tr.item = item;
tr.from.set(fromx, fromy);
tr.to = to;
@@ -86,9 +85,9 @@ public class ItemTransfer extends TimedEntity implements DrawTrait{
@Override
public void removed(){
if(done != null){
threads.run(done);
done.run();
}
Pooling.free(this);
Pools.free(this);
}
@Override
@@ -108,8 +107,7 @@ public class ItemTransfer extends TimedEntity implements DrawTrait{
public void draw(){
float length = fslope() * 6f;
float angle = current.set(x, y).sub(from).angle();
Draw.color(Palette.accent);
Lines.stroke(fslope() * 2f);
Lines.stroke(fslope() * 2f, Palette.accent);
Lines.circle(x, y, fslope() * 2f);
Lines.lineAngleCenter(x, y, angle, length);

View File

@@ -1,11 +1,24 @@
package io.anuke.mindustry.entities.effect;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.IntSet;
import io.anuke.annotations.Annotations.Loc;
import io.anuke.annotations.Annotations.Remote;
import io.anuke.arc.collection.Array;
import io.anuke.arc.collection.IntSet;
import io.anuke.arc.entities.EntityGroup;
import io.anuke.arc.entities.impl.TimedEntity;
import io.anuke.arc.entities.trait.DrawTrait;
import io.anuke.arc.entities.trait.TimeTrait;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.Lines;
import io.anuke.arc.math.Angles;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.RandomXS128;
import io.anuke.arc.math.geom.Geometry;
import io.anuke.arc.math.geom.Position;
import io.anuke.arc.math.geom.Rectangle;
import io.anuke.arc.math.geom.Vector2;
import io.anuke.arc.util.pooling.Pools;
import io.anuke.mindustry.content.bullets.TurretBullets;
import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.entities.Units;
@@ -14,14 +27,6 @@ import io.anuke.mindustry.entities.traits.SyncTrait;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.entities.impl.TimedEntity;
import io.anuke.ucore.entities.trait.DrawTrait;
import io.anuke.ucore.entities.trait.PosTrait;
import io.anuke.ucore.entities.trait.TimeTrait;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.util.*;
import java.io.DataInput;
import java.io.DataOutput;
@@ -31,7 +36,7 @@ import static io.anuke.mindustry.Vars.bulletGroup;
public class Lightning extends TimedEntity implements DrawTrait, SyncTrait, TimeTrait{
public static final float lifetime = 10f;
private static final SeedRandom random = new SeedRandom();
private static final RandomXS128 random = new RandomXS128();
private static final Rectangle rect = new Rectangle();
private static final Array<Unit> entities = new Array<>();
private static final IntSet hit = new IntSet();
@@ -39,7 +44,7 @@ public class Lightning extends TimedEntity implements DrawTrait, SyncTrait, Time
private static final float hitRange = 30f;
private static int lastSeed = 0;
private Array<PosTrait> lines = new Array<>();
private Array<Position> lines = new Array<>();
private Color color = Palette.lancerLaser;
/**For pooling use only. Do not call directly!*/
@@ -55,7 +60,7 @@ public class Lightning extends TimedEntity implements DrawTrait, SyncTrait, Time
@Remote(called = Loc.server)
public static void createLighting(int seed, Team team, Color color, float damage, float x, float y, float rotation, int length){
Lightning l = Pooling.obtain(Lightning.class, Lightning::new);
Lightning l = Pools.obtain(Lightning.class, Lightning::new);
Float dmg = damage;
l.x = x;
@@ -68,7 +73,7 @@ public class Lightning extends TimedEntity implements DrawTrait, SyncTrait, Time
for (int i = 0; i < length/2; i++) {
Bullet.create(TurretBullets.damageLightning, l, team, x, y, 0f, 1f, 1f, dmg);
l.lines.add(new Translator(x + Mathf.range(3f), y + Mathf.range(3f)));
l.lines.add(new Vector2(x + Mathf.range(3f), y + Mathf.range(3f)));
rect.setSize(hitRange).setCenter(x, y);
entities.clear();
@@ -103,7 +108,7 @@ public class Lightning extends TimedEntity implements DrawTrait, SyncTrait, Time
public void write(DataOutput data){}
@Override
public void read(DataInput data, long time){}
public void read(DataInput data){}
@Override
public float lifetime(){
@@ -120,15 +125,17 @@ public class Lightning extends TimedEntity implements DrawTrait, SyncTrait, Time
@Override
public void removed(){
super.removed();
Pooling.free(this);
Pools.free(this);
}
@Override
public void draw(){
float lx = x, ly = y;
Draw.color(color, Color.WHITE, fin());
//TODO this is really, really bad rendering
/*
for(int i = 0; i < lines.size; i++){
PosTrait v = lines.get(i);
Position v = lines.get(i);
float f = (float) i / lines.size;
@@ -143,11 +150,10 @@ public class Lightning extends TimedEntity implements DrawTrait, SyncTrait, Time
Lines.line(lx, ly, v.getX(), v.getY());
Lines.stroke(3f * fout() * (1f - f));
// Lines.lineAngleCenter(lx, ly, Angles.angle(lx, ly, v.getX(), v.getY()) + 90f, 20f);
lx = v.getX();
ly = v.getY();
}
}*/
Draw.color();
}

View File

@@ -1,12 +1,23 @@
package io.anuke.mindustry.entities.effect;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.GridPoint2;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.utils.IntMap;
import com.badlogic.gdx.utils.Pool.Poolable;
import io.anuke.annotations.Annotations.Loc;
import io.anuke.annotations.Annotations.Remote;
import io.anuke.arc.collection.IntMap;
import io.anuke.arc.entities.Effects;
import io.anuke.arc.entities.EntityGroup;
import io.anuke.arc.entities.impl.SolidEntity;
import io.anuke.arc.entities.trait.DrawTrait;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.Fill;
import io.anuke.arc.math.Angles;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.geom.Geometry;
import io.anuke.arc.math.geom.Point2;
import io.anuke.arc.math.geom.Rectangle;
import io.anuke.arc.util.Time;
import io.anuke.arc.util.pooling.Pool.Poolable;
import io.anuke.arc.util.pooling.Pools;
import io.anuke.mindustry.content.Liquids;
import io.anuke.mindustry.content.blocks.Blocks;
import io.anuke.mindustry.content.bullets.TurretBullets;
@@ -19,18 +30,6 @@ import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.type.Liquid;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.entities.impl.SolidEntity;
import io.anuke.ucore.entities.trait.DrawTrait;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Fill;
import io.anuke.ucore.graphics.Hue;
import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Geometry;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Pooling;
import java.io.DataInput;
import java.io.DataOutput;
@@ -85,10 +84,10 @@ public class Puddle extends SolidEntity implements SaveTrait, Poolable, DrawTrai
Puddle p = map.get(tile.pos());
if(generation == 0 && p != null && p.lastRipple <= Timers.time() - 40f){
if(generation == 0 && p != null && p.lastRipple <= Time.time() - 40f){
Effects.effect(BlockFx.ripple, tile.floor().liquidDrop.color,
(tile.worldx() + source.worldx()) / 2f, (tile.worldy() + source.worldy()) / 2f);
p.lastRipple = Timers.time();
p.lastRipple = Time.time();
}
return;
}
@@ -97,7 +96,7 @@ public class Puddle extends SolidEntity implements SaveTrait, Poolable, DrawTrai
if(p == null){
if(Net.client()) return; //not clientside.
Puddle puddle = Pooling.obtain(Puddle.class, Puddle::new);
Puddle puddle = Pools.obtain(Puddle.class, Puddle::new);
puddle.tile = tile;
puddle.liquid = liquid;
puddle.amount = amount;
@@ -108,9 +107,9 @@ public class Puddle extends SolidEntity implements SaveTrait, Poolable, DrawTrai
}else if(p.liquid == liquid){
p.accepting = Math.max(amount, p.accepting);
if(generation == 0 && p.lastRipple <= Timers.time() - 40f && p.amount >= maxLiquid / 2f){
if(generation == 0 && p.lastRipple <= Time.time() - 40f && p.amount >= maxLiquid / 2f){
Effects.effect(BlockFx.ripple, p.liquid.color, (tile.worldx() + source.worldx()) / 2f, (tile.worldy() + source.worldy()) / 2f);
p.lastRipple = Timers.time();
p.lastRipple = Time.time();
}
}else{
p.amount += reactPuddle(p.liquid, liquid, amount, p.tile, p.x, p.y);
@@ -176,14 +175,14 @@ public class Puddle extends SolidEntity implements SaveTrait, Poolable, DrawTrai
//update code
float addSpeed = accepting > 0 ? 3f : 0f;
amount -= Timers.delta() * (1f - liquid.viscosity) / (5f + addSpeed);
amount -= Time.delta() * (1f - liquid.viscosity) / (5f + addSpeed);
amount += accepting;
accepting = 0f;
if(amount >= maxLiquid / 1.5f && generation < maxGeneration){
float deposited = Math.min((amount - maxLiquid / 1.5f) / 4f, 0.3f) * Timers.delta();
for(GridPoint2 point : Geometry.d4){
float deposited = Math.min((amount - maxLiquid / 1.5f) / 4f, 0.3f) * Time.delta();
for(Point2 point : Geometry.d4){
Tile other = world.tile(tile.x + point.x, tile.y + point.y);
if(other != null && other.block() == Blocks.air && !other.hasCliffs()){
deposit(other, tile, liquid, deposited, generation + 1);
@@ -214,14 +213,14 @@ public class Puddle extends SolidEntity implements SaveTrait, Poolable, DrawTrai
}
});
if(liquid.temperature > 0.7f && tile.entity != null && Mathf.chance(0.3 * Timers.delta())){
if(liquid.temperature > 0.7f && tile.entity != null && Mathf.chance(0.3 * Time.delta())){
Fire.create(tile);
}
updateTime = 20f;
}
updateTime -= Timers.delta();
updateTime -= Time.delta();
}
@Override
@@ -232,11 +231,11 @@ public class Puddle extends SolidEntity implements SaveTrait, Poolable, DrawTrai
float smag = onLiquid ? 0.8f : 0f;
float sscl = 20f;
Draw.color(Hue.shift(tmp.set(liquid.color), 2, -0.05f));
Fill.circle(x + Mathf.sin(Timers.time() + seeds * 532, sscl, smag), y + Mathf.sin(Timers.time() + seeds * 53, sscl, smag), f * 8f);
Draw.color(tmp.set(liquid.color).shiftValue(-0.05f));
Fill.circle(x + Mathf.sin(Time.time() + seeds * 532, sscl, smag), y + Mathf.sin(Time.time() + seeds * 53, sscl, smag), f * 8f);
Angles.randLenVectors(id, 3, f * 6f, (ex, ey) -> {
Fill.circle(x + ex + Mathf.sin(Timers.time() + seeds * 532, sscl, smag),
y + ey + Mathf.sin(Timers.time() + seeds * 53, sscl, smag), f * 5f);
Fill.circle(x + ex + Mathf.sin(Time.time() + seeds * 532, sscl, smag),
y + ey + Mathf.sin(Time.time() + seeds * 53, sscl, smag), f * 5f);
seeds++;
});
Draw.color();
@@ -302,7 +301,7 @@ public class Puddle extends SolidEntity implements SaveTrait, Poolable, DrawTrai
}
@Override
public void read(DataInput data, long time) throws IOException{
public void read(DataInput data) throws IOException{
x = data.readFloat();
y = data.readFloat();
liquid = content.liquid(data.readByte());

View File

@@ -1,7 +1,8 @@
package io.anuke.mindustry.entities.effect;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.util.Mathf;
import io.anuke.arc.Core;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.math.Mathf;
public class RubbleDecal extends Decal{
private int size;
@@ -20,7 +21,7 @@ public class RubbleDecal extends Decal{
public void drawDecal(){
String region = "rubble-" + size + "-" + Mathf.randomSeed(id, 0, 1);
if(!Draw.hasRegion(region)){
if(!Core.atlas.has(region)){
remove();
return;
}

View File

@@ -1,10 +1,11 @@
package io.anuke.mindustry.entities.effect;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import io.anuke.arc.Core;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.TextureRegion;
import io.anuke.arc.math.Angles;
import io.anuke.arc.math.Mathf;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf;
import static io.anuke.mindustry.Vars.world;
@@ -15,7 +16,7 @@ public class ScorchDecal extends Decal{
public static void create(float x, float y){
if(regions[0] == null){
for(int i = 0; i < regions.length; i++){
regions[i] = Draw.region("scorch" + (i + 1));
regions[i] = Core.atlas.find("scorch" + (i + 1));
}
}
@@ -35,7 +36,7 @@ public class ScorchDecal extends Decal{
TextureRegion region = regions[Mathf.randomSeed(id - i, 0, scorches - 1)];
float rotation = Mathf.randomSeed(id + i, 0, 360);
float space = 1.5f + Mathf.randomSeed(id + i + 1, 0, 20) / 10f;
Draw.grect(region, x + Angles.trnsx(rotation, space), y + Angles.trnsy(rotation, space), rotation - 90);
Draw.rect(region, x + Angles.trnsx(rotation, space), y + Angles.trnsy(rotation, space) + region.getHeight()/2f, region.getWidth()/2f, 0, rotation - 90);
}
}
}

View File

@@ -1,7 +1,7 @@
package io.anuke.mindustry.entities.traits;
import io.anuke.ucore.entities.trait.DamageTrait;
import io.anuke.ucore.entities.trait.Entity;
import io.anuke.arc.entities.trait.DamageTrait;
import io.anuke.arc.entities.trait.Entity;
public interface AbsorbTrait extends Entity, TeamTrait, DamageTrait{
void absorb();

View File

@@ -1,9 +1,19 @@
package io.anuke.mindustry.entities.traits;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Queue;
import io.anuke.arc.Core;
import io.anuke.arc.Events;
import io.anuke.arc.collection.Array;
import io.anuke.arc.collection.Queue;
import io.anuke.arc.entities.Effects;
import io.anuke.arc.entities.trait.Entity;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.Fill;
import io.anuke.arc.graphics.g2d.Lines;
import io.anuke.arc.math.Angles;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.geom.Vector2;
import io.anuke.arc.util.Time;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.content.blocks.Blocks;
import io.anuke.mindustry.content.fx.BlockFx;
@@ -13,6 +23,7 @@ import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.game.EventType.BuildSelectEvent;
import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.graphics.Shapes;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.Recipe;
@@ -21,16 +32,6 @@ import io.anuke.mindustry.world.Pos;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.BuildBlock;
import io.anuke.mindustry.world.blocks.BuildBlock.BuildEntity;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Events;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.trait.Entity;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Fill;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.graphics.Shapes;
import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf;
import java.io.DataInput;
import java.io.DataOutput;
@@ -44,6 +45,7 @@ import static io.anuke.mindustry.Vars.*;
*/
public interface BuilderTrait extends Entity{
//these are not instance variables!
Vector2[] tmptr = new Vector2[]{new Vector2(), new Vector2(), new Vector2(), new Vector2()};
float placeDistance = 150f;
float mineDistance = 70f;
Array<BuildRequest> removal = new Array<>();
@@ -173,15 +175,19 @@ public interface BuilderTrait extends Entity{
default void updateBuilding(Unit unit){
//remove already completed build requests
removal.clear();
for(BuildRequest request : getPlaceQueue()){
if((request.breaking && world.tile(request.x, request.y).block() == Blocks.air) ||
(!request.breaking && world.tile(request.x, request.y).block() == request.recipe.result)){
removal.add(request);
}
for(BuildRequest req : getPlaceQueue()){
removal.add(req);
}
for(BuildRequest req : removal){
getPlaceQueue().removeValue(req, true);
getPlaceQueue().clear();
for(BuildRequest request : removal){
if(!((request.breaking && world.tile(request.x, request.y).block() == Blocks.air) ||
(!request.breaking &&
(world.tile(request.x, request.y).getRotation() == request.rotation || !request.recipe.result.rotate)
&& world.tile(request.x, request.y).block() == request.recipe.result))){
getPlaceQueue().addLast(request);
}
}
BuildRequest current = getCurrentRequest();
@@ -198,7 +204,7 @@ public interface BuilderTrait extends Entity{
Tile tile = world.tile(current.x, current.y);
if(unit.distanceTo(tile) > placeDistance){
if(unit.dst(tile) > placeDistance){
return;
}
@@ -228,7 +234,7 @@ public interface BuilderTrait extends Entity{
return;
}
if(unit.distanceTo(tile) <= placeDistance){
if(unit.dst(tile) <= placeDistance){
unit.rotation = Mathf.slerpDelta(unit.rotation, unit.angleTo(entity), 0.4f);
}
@@ -236,9 +242,9 @@ public interface BuilderTrait extends Entity{
if(!Net.client()){
//deconstructing is 2x as fast
if(current.breaking){
entity.deconstruct(unit, core, 2f / entity.buildCost * Timers.delta() * getBuildPower(tile));
entity.deconstruct(unit, core, 2f / entity.buildCost * Time.delta() * getBuildPower(tile));
}else{
entity.construct(unit, core, 1f / entity.buildCost * Timers.delta() * getBuildPower(tile));
entity.construct(unit, core, 1f / entity.buildCost * Time.delta() * getBuildPower(tile));
}
current.progress = entity.progress();
@@ -247,7 +253,7 @@ public interface BuilderTrait extends Entity{
}
if(!current.initialized){
Gdx.app.postRunnable(() -> Events.fire(new BuildSelectEvent(tile, unit.getTeam(), this, current.breaking)));
Core.app.post(() -> Events.fire(new BuildSelectEvent(tile, unit.getTeam(), this, current.breaking)));
current.initialized = true;
}
}
@@ -257,16 +263,16 @@ public interface BuilderTrait extends Entity{
Tile tile = getMineTile();
TileEntity core = unit.getClosestCore();
if(core == null || tile.block() != Blocks.air || unit.distanceTo(tile.worldx(), tile.worldy()) > mineDistance
if(core == null || tile.block() != Blocks.air || unit.dst(tile.worldx(), tile.worldy()) > mineDistance
|| tile.floor().drops == null || !unit.inventory.canAcceptItem(tile.floor().drops.item) || !canMine(tile.floor().drops.item)){
setMineTile(null);
}else{
Item item = tile.floor().drops.item;
unit.rotation = Mathf.slerpDelta(unit.rotation, unit.angleTo(tile.worldx(), tile.worldy()), 0.4f);
if(Mathf.chance(Timers.delta() * (0.06 - item.hardness * 0.01) * getMinePower())){
if(Mathf.chance(Time.delta() * (0.06 - item.hardness * 0.01) * getMinePower())){
if(unit.distanceTo(core) < mineTransferRange && core.tile.block().acceptStack(item, 1, core.tile, unit) == 1){
if(unit.dst(core) < mineTransferRange && core.tile.block().acceptStack(item, 1, core.tile, unit) == 1){
Call.transferItemTo(item, 1,
tile.worldx() + Mathf.range(tilesize / 2f),
tile.worldy() + Mathf.range(tilesize / 2f), core.tile);
@@ -278,7 +284,7 @@ public interface BuilderTrait extends Entity{
}
}
if(Mathf.chance(0.06 * Timers.delta())){
if(Mathf.chance(0.06 * Time.delta())){
Effects.effect(BlockFx.pulverizeSmall,
tile.worldx() + Mathf.range(tilesize / 2f),
tile.worldy() + Mathf.range(tilesize / 2f), 0f, item.color);
@@ -300,12 +306,12 @@ public interface BuilderTrait extends Entity{
Tile tile = world.tile(request.x, request.y);
if(unit.distanceTo(tile) > placeDistance){
if(unit.dst(tile) > placeDistance){
return;
}
Draw.color(Palette.accent);
float focusLen = 3.8f + Mathf.absin(Timers.time(), 1.1f, 0.6f);
Lines.stroke(1f, Palette.accent);
float focusLen = 3.8f + Mathf.absin(Time.time(), 1.1f, 0.6f);
float px = unit.x + Angles.trnsx(unit.rotation, focusLen);
float py = unit.y + Angles.trnsy(unit.rotation, focusLen);
@@ -318,7 +324,7 @@ public interface BuilderTrait extends Entity{
tmptr[3].set(tile.drawx() + sz, tile.drawy() + sz);
Arrays.sort(tmptr, (a, b) -> -Float.compare(Angles.angleDist(Angles.angle(unit.x, unit.y, a.x, a.y), ang),
Angles.angleDist(Angles.angle(unit.x, unit.y, b.x, b.y), ang)));
Angles.angleDist(Angles.angle(unit.x, unit.y, b.x, b.y), ang)));
float x1 = tmptr[0].x, y1 = tmptr[0].y,
x3 = tmptr[1].x, y3 = tmptr[1].y;
@@ -328,7 +334,7 @@ public interface BuilderTrait extends Entity{
Lines.line(px, py, x1, y1);
Lines.line(px, py, x3, y3);
Fill.circle(px, py, 1.6f + Mathf.absin(Timers.time(), 0.8f, 1.5f));
Fill.circle(px, py, 1.6f + Mathf.absin(Time.time(), 0.8f, 1.5f));
Draw.color();
}
@@ -339,22 +345,23 @@ public interface BuilderTrait extends Entity{
if(tile == null) return;
float focusLen = 4f + Mathf.absin(Timers.time(), 1.1f, 0.5f);
float focusLen = 4f + Mathf.absin(Time.time(), 1.1f, 0.5f);
float swingScl = 12f, swingMag = tilesize / 8f;
float flashScl = 0.3f;
float px = unit.x + Angles.trnsx(unit.rotation, focusLen);
float py = unit.y + Angles.trnsy(unit.rotation, focusLen);
float ex = tile.worldx() + Mathf.sin(Timers.time() + 48, swingScl, swingMag);
float ey = tile.worldy() + Mathf.sin(Timers.time() + 48, swingScl + 2f, swingMag);
float ex = tile.worldx() + Mathf.sin(Time.time() + 48, swingScl, swingMag);
float ey = tile.worldy() + Mathf.sin(Time.time() + 48, swingScl + 2f, swingMag);
Draw.color(Color.LIGHT_GRAY, Color.WHITE, 1f - flashScl + Mathf.absin(Time.time(), 0.5f, flashScl));
Draw.color(Color.LIGHT_GRAY, Color.WHITE, 1f - flashScl + Mathf.absin(Timers.time(), 0.5f, flashScl));
Shapes.laser("minelaser", "minelaser-end", px, py, ex, ey);
if(unit instanceof Player && ((Player) unit).isLocal){
Draw.color(Palette.accent);
Lines.poly(tile.worldx(), tile.worldy(), 4, tilesize / 2f * Mathf.sqrt2, Timers.time());
Lines.stroke(1f, Palette.accent);
Lines.poly(tile.worldx(), tile.worldy(), 4, tilesize / 2f * Mathf.sqrt2, Time.time());
}
Draw.color();

View File

@@ -1,6 +1,6 @@
package io.anuke.mindustry.entities.traits;
import io.anuke.ucore.entities.trait.SolidTrait;
import io.anuke.arc.entities.trait.SolidTrait;
public interface CarriableTrait extends TeamTrait, TargetTrait, SolidTrait{

View File

@@ -5,8 +5,8 @@ import io.anuke.annotations.Annotations.Remote;
import io.anuke.mindustry.content.fx.UnitFx;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.gen.Call;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.entities.trait.SolidTrait;
import io.anuke.arc.entities.Effects;
import io.anuke.arc.entities.trait.SolidTrait;
public interface CarryTrait extends TeamTrait, SolidTrait, TargetTrait{

View File

@@ -1,6 +1,6 @@
package io.anuke.mindustry.entities.traits;
import io.anuke.ucore.entities.trait.Entity;
import io.anuke.arc.entities.trait.Entity;
/**
* Marks an entity as serializable.

View File

@@ -1,12 +1,12 @@
package io.anuke.mindustry.entities.traits;
import io.anuke.arc.entities.trait.VelocityTrait;
import io.anuke.arc.util.Interval;
import io.anuke.mindustry.type.Weapon;
import io.anuke.ucore.entities.trait.VelocityTrait;
import io.anuke.ucore.util.Timer;
public interface ShooterTrait extends VelocityTrait, TeamTrait, InventoryTrait{
Timer getTimer();
Interval getTimer();
int getShootTimer(boolean left);

View File

@@ -2,9 +2,9 @@ package io.anuke.mindustry.entities.traits;
import io.anuke.mindustry.core.NetClient;
import io.anuke.mindustry.net.Interpolator;
import io.anuke.ucore.core.Core;
import io.anuke.ucore.entities.trait.Entity;
import io.anuke.ucore.util.Tmp;
import io.anuke.arc.Core;
import io.anuke.arc.entities.trait.Entity;
import io.anuke.arc.util.Tmp;
import java.io.DataInput;
import java.io.DataOutput;
@@ -33,8 +33,7 @@ public interface SyncTrait extends Entity, TypeTrait{
if(isClipped()){
//move off screen when no longer in bounds
Tmp.r1.setSize(Core.camera.viewportWidth * Core.camera.zoom * NetClient.viewScale,
Core.camera.viewportHeight * Core.camera.zoom * NetClient.viewScale)
Tmp.r1.setSize(Core.camera.width * NetClient.viewScale, Core.camera.height * NetClient.viewScale)
.setCenter(Core.camera.position.x, Core.camera.position.y);
if(!Tmp.r1.contains(getX(), getY()) && !Tmp.r1.contains(getInterpolator().last.x, getInterpolator().last.y)){
@@ -67,5 +66,5 @@ public interface SyncTrait extends Entity, TypeTrait{
//Read and write sync data, usually position
void write(DataOutput data) throws IOException;
void read(DataInput data, long time) throws IOException;
void read(DataInput data) throws IOException;
}

View File

@@ -1,14 +1,14 @@
package io.anuke.mindustry.entities.traits;
import io.anuke.arc.entities.trait.SolidTrait;
import io.anuke.arc.entities.trait.VelocityTrait;
import io.anuke.arc.math.geom.Position;
import io.anuke.mindustry.game.Team;
import io.anuke.ucore.entities.trait.PosTrait;
import io.anuke.ucore.entities.trait.SolidTrait;
import io.anuke.ucore.entities.trait.VelocityTrait;
/**
* Base interface for targetable entities.
*/
public interface TargetTrait extends PosTrait, VelocityTrait{
public interface TargetTrait extends Position, VelocityTrait{
boolean isDead();

View File

@@ -1,7 +1,7 @@
package io.anuke.mindustry.entities.traits;
import io.anuke.mindustry.game.Team;
import io.anuke.ucore.entities.trait.Entity;
import io.anuke.arc.entities.trait.Entity;
public interface TeamTrait extends Entity{
Team getTeam();

View File

@@ -1,8 +1,8 @@
package io.anuke.mindustry.entities.traits;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.ObjectIntMap;
import io.anuke.ucore.function.Supplier;
import io.anuke.arc.collection.Array;
import io.anuke.arc.collection.ObjectIntMap;
import io.anuke.arc.function.Supplier;
public interface TypeTrait{
int[] lastRegisteredID = {0};

View File

@@ -1,9 +1,18 @@
package io.anuke.mindustry.entities.units;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Rectangle;
import io.anuke.annotations.Annotations.Loc;
import io.anuke.annotations.Annotations.Remote;
import io.anuke.arc.Core;
import io.anuke.arc.entities.Effects;
import io.anuke.arc.entities.EntityGroup;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.TextureRegion;
import io.anuke.arc.math.Angles;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.geom.Geometry;
import io.anuke.arc.math.geom.Rectangle;
import io.anuke.arc.util.Interval;
import io.anuke.arc.util.Time;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.content.fx.ExplosionFx;
import io.anuke.mindustry.entities.Damage;
@@ -24,11 +33,6 @@ import io.anuke.mindustry.type.Weapon;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.units.CommandCenter.CommandCenterEntity;
import io.anuke.mindustry.world.meta.BlockFlag;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.util.*;
import java.io.DataInput;
import java.io.DataOutput;
@@ -46,7 +50,7 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
protected static final int timerShootRight = timerIndex++;
protected UnitType type;
protected Timer timer = new Timer(5);
protected Interval timer = new Interval(5);
protected StateMachine state = new StateMachine();
protected TargetTrait target;
@@ -77,7 +81,7 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
Effects.shake(2f, 2f, unit);
//must run afterwards so the unit's group is not null when sending the removal packet
threads.runDelay(unit::remove);
Core.app.post(unit::remove);
}
@Override
@@ -222,7 +226,7 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
}
@Override
public Timer getTimer(){
public Interval getTimer(){
return timer;
}
@@ -282,7 +286,7 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
@Override
public void update(){
hitTime -= Timers.delta();
hitTime -= Time.delta();
if(isDead()){
updateRespawning();
@@ -393,12 +397,12 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
}
@Override
public void read(DataInput data, long time) throws IOException{
public void read(DataInput data) throws IOException{
float lastx = x, lasty = y, lastrot = rotation;
super.readSave(data);
this.type = content.getByID(ContentType.unit, data.readByte());
interpolator.read(lastx, lasty, x, y, time, rotation);
interpolator.read(lastx, lasty, x, y, rotation);
rotation = lastrot;
}

View File

@@ -1,26 +1,25 @@
package io.anuke.mindustry.entities.units;
import com.badlogic.gdx.math.Vector2;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.math.Angles;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.geom.Geometry;
import io.anuke.arc.math.geom.Vector2;
import io.anuke.arc.util.Time;
import io.anuke.mindustry.entities.Predict;
import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.entities.traits.CarriableTrait;
import io.anuke.mindustry.entities.traits.CarryTrait;
import io.anuke.mindustry.graphics.Trail;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.type.AmmoType;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.meta.BlockFlag;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.util.*;
import static io.anuke.mindustry.Vars.world;
public abstract class FlyingUnit extends BaseUnit implements CarryTrait{
protected static Translator vec = new Translator();
protected static float wobblyness = 0.6f;
protected static Vector2 vec = new Vector2();
protected Trail trail = new Trail(8);
protected CarriableTrait carrying;
protected final UnitState
@@ -75,8 +74,8 @@ public abstract class FlyingUnit extends BaseUnit implements CarryTrait{
}else{
attack(150f);
if((Mathf.angNear(angleTo(target), rotation, 15f) || !getWeapon().getAmmo().bullet.keepVelocity) //bombers don't care about rotation
&& distanceTo(target) < Math.max(getWeapon().getAmmo().getRange(), type.range)){
if((Angles.near(angleTo(target), rotation, 15f) || !getWeapon().getAmmo().bullet.keepVelocity) //bombers don't care about rotation
&& dst(target) < Math.max(getWeapon().getAmmo().getRange(), type.range)){
AmmoType ammo = getWeapon().getAmmo();
Vector2 to = Predict.intercept(FlyingUnit.this, target, ammo.bullet.speed);
@@ -99,7 +98,7 @@ public abstract class FlyingUnit extends BaseUnit implements CarryTrait{
});
if(target != null){
circle(60f + Mathf.absin(Timers.time() + id * 23525, 70f, 1200f));
circle(60f + Mathf.absin(Time.time() + id * 23525, 70f, 1200f));
}
}
},
@@ -153,9 +152,6 @@ public abstract class FlyingUnit extends BaseUnit implements CarryTrait{
updateRotation();
wobble();
}
trail.update(x + Angles.trnsx(rotation + 180f, 6f) + Mathf.range(wobblyness),
y + Angles.trnsy(rotation + 180f, 6f) + Mathf.range(wobblyness));
}
@Override
@@ -169,11 +165,6 @@ public abstract class FlyingUnit extends BaseUnit implements CarryTrait{
Draw.alpha(1f);
}
@Override
public void drawOver(){
trail.draw(type.trailColor, 5f);
}
@Override
public void behavior(){
if(health <= health * type.retreatPercent && !isCommanded() &&
@@ -200,11 +191,11 @@ public abstract class FlyingUnit extends BaseUnit implements CarryTrait{
protected void wobble(){
if(Net.client()) return;
x += Mathf.sin(Timers.time() + id * 999, 25f, 0.08f)*Timers.delta();
y += Mathf.cos(Timers.time() + id * 999, 25f, 0.08f)*Timers.delta();
x += Mathf.sin(Time.time() + id * 999, 25f, 0.08f)*Time.delta();
y += Mathf.cos(Time.time() + id * 999, 25f, 0.08f)*Time.delta();
if(velocity.len() <= 0.05f){
rotation += Mathf.sin(Timers.time() + id * 99, 10f, 2.5f)*Timers.delta();
rotation += Mathf.sin(Time.time() + id * 99, 10f, 2.5f)*Time.delta();
}
}
@@ -225,7 +216,7 @@ public abstract class FlyingUnit extends BaseUnit implements CarryTrait{
vec.rotate((circleLength - vec.len()) / circleLength * 180f);
}
vec.setLength(speed * Timers.delta());
vec.setLength(speed * Time.delta());
velocity.add(vec);
}
@@ -235,9 +226,9 @@ public abstract class FlyingUnit extends BaseUnit implements CarryTrait{
vec.set(target.getX() - x, target.getY() - y);
float length = circleLength <= 0.001f ? 1f : Mathf.clamp((distanceTo(target) - circleLength) / 100f, -1f, 1f);
float length = circleLength <= 0.001f ? 1f : Mathf.clamp((dst(target) - circleLength) / 100f, -1f, 1f);
vec.setLength(type.speed * Timers.delta() * length);
vec.setLength(type.speed * Time.delta() * length);
if(length < 0) vec.rotate(180f);
velocity.add(vec);
@@ -255,7 +246,7 @@ public abstract class FlyingUnit extends BaseUnit implements CarryTrait{
vec.setAngle(Mathf.slerpDelta(velocity.angle(), vec.angle(), 0.44f));
}
vec.setLength(type.speed * Timers.delta());
vec.setLength(type.speed * Time.delta());
velocity.add(vec);
}

View File

@@ -1,7 +1,11 @@
package io.anuke.mindustry.entities.units;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.Vector2;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.math.Angles;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.geom.Vector2;
import io.anuke.arc.util.Time;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.entities.Predict;
import io.anuke.mindustry.entities.TileEntity;
@@ -12,11 +16,6 @@ import io.anuke.mindustry.type.ContentType;
import io.anuke.mindustry.type.Weapon;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.Floor;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Translator;
import java.io.DataInput;
import java.io.DataOutput;
@@ -26,7 +25,7 @@ import static io.anuke.mindustry.Vars.content;
import static io.anuke.mindustry.Vars.world;
public abstract class GroundUnit extends BaseUnit{
protected static Translator vec = new Translator();
protected static Vector2 vec = new Vector2();
protected float walkTime;
protected float stuckTime;
@@ -42,7 +41,7 @@ public abstract class GroundUnit extends BaseUnit{
public void update(){
TileEntity core = getClosestEnemyCore();
float dst = core == null ? 0 : distanceTo(core);
float dst = core == null ? 0 : dst(core);
if(core != null && dst < getWeapon().getAmmo().getRange() / 1.1f){
target = core;
@@ -57,7 +56,7 @@ public abstract class GroundUnit extends BaseUnit{
public void update(){
TileEntity target = getClosestCore();
if(target != null){
if(distanceTo(target) > 400f){
if(dst(target) > 400f){
moveAwayFromCore();
}else{
patrol();
@@ -105,7 +104,7 @@ public abstract class GroundUnit extends BaseUnit{
@Override
public void move(float x, float y){
if(Mathf.dst(x, y) > 0.01f){
baseRotation = Mathf.slerpDelta(baseRotation, Mathf.atan2(x, y), type.baseRotateSpeed);
baseRotation = Mathf.slerpDelta(baseRotation, Mathf.angle(x, y), type.baseRotateSpeed);
}
super.move(x, y);
}
@@ -119,14 +118,14 @@ public abstract class GroundUnit extends BaseUnit{
public void update(){
super.update();
stuckTime = !vec.set(x, y).sub(lastPosition()).isZero(0.0001f) ? 0f : stuckTime + Timers.delta();
stuckTime = !vec.set(x, y).sub(lastPosition()).isZero(0.0001f) ? 0f : stuckTime + Time.delta();
if(!velocity.isZero()){
baseRotation = Mathf.slerpDelta(baseRotation, velocity.angle(), 0.05f);
}
if(stuckTime < 1f){
walkTime += Timers.delta();
walkTime += Time.delta();
}
}
@@ -188,10 +187,10 @@ public abstract class GroundUnit extends BaseUnit{
}
if(!Units.invalidateTarget(target, this)){
if(distanceTo(target) < getWeapon().getAmmo().getRange()){
if(dst(target) < getWeapon().getAmmo().getRange()){
rotate(angleTo(target));
if(Mathf.angNear(angleTo(target), rotation, 13f)){
if(Angles.near(angleTo(target), rotation, 13f)){
AmmoType ammo = getWeapon().getAmmo();
Vector2 to = Predict.intercept(GroundUnit.this, target, ammo.bullet.speed);
@@ -220,8 +219,8 @@ public abstract class GroundUnit extends BaseUnit{
}
@Override
public void read(DataInput data, long time) throws IOException{
super.read(data, time);
public void read(DataInput data) throws IOException{
super.read(data);
weapon = content.getByID(ContentType.weapon, data.readByte());
}
@@ -238,12 +237,12 @@ public abstract class GroundUnit extends BaseUnit{
}
protected void patrol(){
vec.trns(baseRotation, type.speed * Timers.delta());
vec.trns(baseRotation, type.speed * Time.delta());
velocity.add(vec.x, vec.y);
vec.trns(baseRotation, type.hitsizeTile);
Tile tile = world.tileWorld(x + vec.x, y + vec.y);
if((tile == null || tile.solid() || tile.floor().drownTime > 0) || stuckTime > 10f){
baseRotation += Mathf.sign(id % 2 - 0.5f) * Timers.delta() * 3f;
baseRotation += Mathf.sign(id % 2 - 0.5f) * Time.delta() * 3f;
}
rotation = Mathf.slerpDelta(rotation, velocity.angle(), type.rotatespeed);
@@ -258,7 +257,7 @@ public abstract class GroundUnit extends BaseUnit{
vec.rotate((circleLength - vec.len()) / circleLength * 180f);
}
vec.setLength(type.speed * Timers.delta());
vec.setLength(type.speed * Time.delta());
velocity.add(vec);
}
@@ -272,7 +271,7 @@ public abstract class GroundUnit extends BaseUnit{
float angle = angleTo(targetTile);
velocity.add(vec.trns(angleTo(targetTile), type.speed*Timers.delta()));
velocity.add(vec.trns(angleTo(targetTile), type.speed*Time.delta()));
rotation = Mathf.slerpDelta(rotation, angle, type.rotatespeed);
}
@@ -292,11 +291,11 @@ public abstract class GroundUnit extends BaseUnit{
Tile targetTile = world.pathfinder.getTargetTile(enemy, tile);
TileEntity core = getClosestCore();
if(tile == targetTile || core == null || distanceTo(core) < 90f) return;
if(tile == targetTile || core == null || dst(core) < 90f) return;
float angle = angleTo(targetTile);
velocity.add(vec.trns(angleTo(targetTile), type.speed*Timers.delta()));
velocity.add(vec.trns(angleTo(targetTile), type.speed*Time.delta()));
rotation = Mathf.slerpDelta(rotation, angle, type.rotatespeed);
}
}

View File

@@ -1,24 +1,22 @@
package io.anuke.mindustry.entities.units;
import com.badlogic.gdx.math.Vector2;
import io.anuke.ucore.util.Translator;
import static io.anuke.mindustry.Vars.threads;
import io.anuke.arc.Core;
import io.anuke.arc.math.geom.Vector2;
/**
* Used to group entities together, for formations and such.
* Usually, squads are used by units spawned in the same wave.
*/
public class Squad{
public Vector2 direction = new Translator();
public Vector2 direction = new Vector2();
public int units;
private long lastUpdated;
protected void update(){
if(threads.getFrameID() != lastUpdated){
if(Core.graphics.getFrameId() != lastUpdated){
direction.setZero();
lastUpdated = threads.getFrameID();
lastUpdated = Core.graphics.getFrameId();
}
}
}

View File

@@ -1,6 +1,6 @@
package io.anuke.mindustry.entities.units;
import io.anuke.ucore.util.Bundles;
import io.anuke.arc.Core;
public enum UnitCommand{
attack, retreat, patrol;
@@ -8,7 +8,7 @@ public enum UnitCommand{
private final String localized;
UnitCommand(){
localized = Bundles.get("command." + name());
localized = Core.bundle.get("command." + name());
}
public String localized(){

View File

@@ -5,7 +5,7 @@ import io.anuke.mindustry.content.Items;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.type.Item;
import io.anuke.ucore.util.Mathf;
import io.anuke.arc.math.Mathf;
public class UnitDrops{
private static Item[] dropTable;

View File

@@ -1,8 +1,13 @@
package io.anuke.mindustry.entities.units;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.utils.ObjectSet;
import io.anuke.arc.Core;
import io.anuke.arc.collection.ObjectSet;
import io.anuke.arc.function.Supplier;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.g2d.TextureRegion;
import io.anuke.arc.scene.ui.layout.Table;
import io.anuke.arc.util.Log;
import io.anuke.arc.util.Strings;
import io.anuke.mindustry.content.Items;
import io.anuke.mindustry.content.Weapons;
import io.anuke.mindustry.entities.traits.TypeTrait;
@@ -12,12 +17,6 @@ import io.anuke.mindustry.type.ContentType;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.Weapon;
import io.anuke.mindustry.ui.ContentDisplay;
import io.anuke.ucore.function.Supplier;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.util.Bundles;
import io.anuke.ucore.util.Log;
import io.anuke.ucore.util.Strings;
public class UnitType extends UnlockableContent{
protected final Supplier<? extends BaseUnit> constructor;
@@ -51,11 +50,11 @@ public class UnitType extends UnlockableContent{
public <T extends BaseUnit> UnitType(String name, Class<T> type, Supplier<T> mainConstructor){
this.name = name;
this.constructor = mainConstructor;
this.description = Bundles.getOrNull("unit." + name + ".description");
this.description = Core.bundle.getOrNull("unit." + name + ".description");
TypeTrait.registerType(type, mainConstructor);
if(!Bundles.has("unit." + this.name + ".name")){
if(!Core.bundle.has("unit." + this.name + ".name")){
Log.err("Warning: unit '" + name + "' is missing a localized name. Add the follow to bundle.properties:");
Log.err("unit." + this.name + ".name=" + Strings.capitalize(name.replace('-', '_')));
}
@@ -68,7 +67,7 @@ public class UnitType extends UnlockableContent{
@Override
public String localizedName(){
return Bundles.get("unit." + name + ".name");
return Core.bundle.get("unit." + name + ".name");
}
@Override
@@ -78,12 +77,12 @@ public class UnitType extends UnlockableContent{
@Override
public void load(){
iconRegion = Draw.region("unit-icon-" + name);
region = Draw.region(name);
iconRegion = Core.atlas.find("unit-icon-" + name);
region = Core.atlas.find(name);
if(!isFlying){
legRegion = Draw.region(name + "-leg");
baseRegion = Draw.region(name + "-base");
legRegion = Core.atlas.find(name + "-leg");
baseRegion = Core.atlas.find(name + "-base");
}
}

View File

@@ -1,113 +0,0 @@
package io.anuke.mindustry.entities.units.types;
import com.badlogic.gdx.math.Vector2;
import io.anuke.annotations.Annotations.Loc;
import io.anuke.annotations.Annotations.Remote;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.content.fx.UnitFx;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.Predict;
import io.anuke.mindustry.entities.traits.TargetTrait;
import io.anuke.mindustry.entities.units.BaseUnit;
import io.anuke.mindustry.entities.units.FlyingUnit;
import io.anuke.mindustry.entities.units.UnitCommand;
import io.anuke.mindustry.entities.units.UnitState;
import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.type.AmmoType;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.util.Mathf;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import static io.anuke.mindustry.Vars.*;
public class AlphaDrone extends FlyingUnit {
static final float followDistance = 80f;
public Player leader;
public final UnitState attack = new UnitState() {
@Override
public void update() {
if(leader == null || leader.isDead() || !leader.isAdded()){
damage(99999f);
return;
}
TargetTrait last = target;
target = leader;
if(last == null){
circle(leader.isShooting ? 60f : 0f);
}
target = last;
if(distanceTo(leader) < followDistance){
targetClosest();
}else{
target = null;
}
if(target != null){
attack(50f);
if((Mathf.angNear(angleTo(target), rotation, 15f) && distanceTo(target) < getWeapon().getAmmo().getRange())){
AmmoType ammo = getWeapon().getAmmo();
Vector2 to = Predict.intercept(AlphaDrone.this, target, ammo.bullet.speed);
getWeapon().update(AlphaDrone.this, to.x, to.y);
}
}
if(!leader.isShooting && distanceTo(leader) < 7f){
Call.onAlphaDroneFade(AlphaDrone.this);
}
}
};
@Remote(called = Loc.server)
public static void onAlphaDroneFade(BaseUnit drone){
if(drone == null) return;
Effects.effect(UnitFx.pickup, drone);
//must run afterwards so the unit's group is not null when sending the removal packet
threads.runDelay(drone::remove);
}
@Override
public void onCommand(UnitCommand command){
//nuh
}
@Override
public void behavior(){
//nope
}
@Override
public UnitState getStartState() {
return attack;
}
@Override
public void write(DataOutput stream) throws IOException {
super.write(stream);
stream.writeInt(leader == null ? -1 : leader.id);
}
@Override
public void read(DataInput stream, long time) throws IOException {
super.read(stream, time);
leader = Vars.playerGroup.getByID(stream.readInt());
}
@Override
public void readSave(DataInput stream) throws IOException{
super.readSave(stream);
if(!Net.active() && !headless){
leader = players[0];
}
}
}

View File

@@ -1,6 +1,11 @@
package io.anuke.mindustry.entities.units.types;
import com.badlogic.gdx.utils.Queue;
import io.anuke.arc.Events;
import io.anuke.arc.collection.Queue;
import io.anuke.arc.entities.EntityGroup;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.geom.Geometry;
import io.anuke.arc.util.Structs;
import io.anuke.mindustry.content.blocks.Blocks;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.TileEntity;
@@ -12,7 +17,6 @@ import io.anuke.mindustry.entities.units.UnitCommand;
import io.anuke.mindustry.entities.units.UnitState;
import io.anuke.mindustry.game.EventType.BuildSelectEvent;
import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.ItemStack;
import io.anuke.mindustry.type.ItemType;
@@ -20,11 +24,6 @@ import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.BuildBlock;
import io.anuke.mindustry.world.blocks.BuildBlock.BuildEntity;
import io.anuke.mindustry.world.meta.BlockFlag;
import io.anuke.ucore.core.Events;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.util.Geometry;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Structs;
import java.io.DataInput;
import java.io.DataOutput;
@@ -63,7 +62,7 @@ public class Drone extends FlyingUnit implements BuilderTrait{
if(core == null) return;
if((entity.progress() < 1f || entity.progress() > 0f) && entity.tile.block() instanceof BuildBlock){ //building is valid
if(!isBuilding() && distanceTo(target) < placeDistance * 0.9f){ //within distance, begin placing
if(!isBuilding() && dst(target) < placeDistance * 0.9f){ //within distance, begin placing
if(isBreaking){
getPlaceQueue().addLast(new BuildRequest(entity.tile.x, entity.tile.y));
}else{
@@ -108,7 +107,7 @@ public class Drone extends FlyingUnit implements BuilderTrait{
if(target == null) return;
if(target.distanceTo(Drone.this) > type.range){
if(target.dst(Drone.this) > type.range){
circle(type.range*0.9f);
}else{
getWeapon().update(Drone.this, target.getX(), target.getY());
@@ -158,7 +157,7 @@ public class Drone extends FlyingUnit implements BuilderTrait{
if(target instanceof Tile){
moveTo(type.range / 1.5f);
if(distanceTo(target) < type.range && mineTile != target){
if(dst(target) < type.range && mineTile != target){
setMineTile((Tile) target);
}
@@ -196,7 +195,7 @@ public class Drone extends FlyingUnit implements BuilderTrait{
TileEntity tile = (TileEntity) target;
if(distanceTo(target) < type.range){
if(dst(target) < type.range){
if(tile.tile.block().acceptStack(inventory.getItem().item, inventory.getItem().amount, tile.tile, Drone.this) == inventory.getItem().amount){
Call.transferItemTo(inventory.getItem().item, inventory.getItem().amount, x, y, tile.tile);
inventory.clearItem();
@@ -254,7 +253,7 @@ public class Drone extends FlyingUnit implements BuilderTrait{
}
private void notifyPlaced(BuildEntity entity, boolean isBreaking){
float dist = Math.min(entity.distanceTo(x, y) - placeDistance, 0);
float dist = Math.min(entity.dst(x, y) - placeDistance, 0);
if(!state.is(build) && dist / type.maxVelocity < entity.buildCost * 0.9f){
target = entity;
@@ -311,7 +310,7 @@ public class Drone extends FlyingUnit implements BuilderTrait{
@Override
protected void updateRotation(){
if(target != null && ((state.is(repair) && target.distanceTo(this) < type.range) || state.is(mine))){
if(target != null && ((state.is(repair) && target.dst(this) < type.range) || state.is(mine))){
rotation = Mathf.slerpDelta(rotation, angleTo(target), 0.3f);
}else{
rotation = Mathf.slerpDelta(rotation, velocity.angle(), 0.3f);
@@ -333,7 +332,6 @@ public class Drone extends FlyingUnit implements BuilderTrait{
@Override
public void drawOver(){
trail.draw(Palette.lightTrail, 3f);
drawBuilding(this);
}
@@ -364,8 +362,8 @@ public class Drone extends FlyingUnit implements BuilderTrait{
}
@Override
public void read(DataInput data, long time) throws IOException{
super.read(data, time);
public void read(DataInput data) throws IOException{
super.read(data);
int mined = data.readInt();
int repairing = data.readInt();

View File

@@ -1,6 +1,6 @@
package io.anuke.mindustry.game;
import io.anuke.ucore.util.Bundles;
import io.anuke.arc.Core;
public enum Difficulty{
training(3f, 3f),
@@ -24,7 +24,7 @@ public enum Difficulty{
@Override
public String toString(){
if(value == null){
value = Bundles.get("setting.difficulty." + name());
value = Core.bundle.get("setting.difficulty." + name());
}
return value;
}

View File

@@ -1,9 +1,9 @@
package io.anuke.mindustry.game;
import io.anuke.arc.Events.Event;
import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.traits.BuilderTrait;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Events.Event;
public class EventType{
@@ -11,6 +11,7 @@ public class EventType{
}
/**Called when the game is first loaded.*/
public static class GameLoadEvent implements Event{
}
@@ -35,22 +36,11 @@ public class EventType{
}
}
/**
* This event is called from the logic thread.
* DO NOT INITIALIZE GRAPHICS HERE.
*/
/**Called when a game begins and the world is loaded.*/
public static class WorldLoadEvent implements Event{
}
/**
* Called after the WorldLoadEvent is, and all logic has been loaded.
* It is safe to intialize graphics here.
*/
public static class WorldLoadGraphicsEvent implements Event{
}
/**Called from the logic thread. Do not access graphics here!*/
public static class TileChangeEvent implements Event{
public final Tile tile;

Some files were not shown because too many files have changed in this diff Show More