Merge pull request #93 from Anuken/multithread-test-again
Multithreading Support
This commit is contained in:
@@ -9,8 +9,10 @@ import android.os.Bundle;
|
|||||||
import android.telephony.TelephonyManager;
|
import android.telephony.TelephonyManager;
|
||||||
import com.badlogic.gdx.backends.android.AndroidApplication;
|
import com.badlogic.gdx.backends.android.AndroidApplication;
|
||||||
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
|
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
|
||||||
|
import io.anuke.kryonet.DefaultThreadImpl;
|
||||||
import io.anuke.kryonet.KryoClient;
|
import io.anuke.kryonet.KryoClient;
|
||||||
import io.anuke.kryonet.KryoServer;
|
import io.anuke.kryonet.KryoServer;
|
||||||
|
import io.anuke.mindustry.core.ThreadHandler.ThreadProvider;
|
||||||
import io.anuke.mindustry.io.Platform;
|
import io.anuke.mindustry.io.Platform;
|
||||||
import io.anuke.mindustry.net.Net;
|
import io.anuke.mindustry.net.Net;
|
||||||
import io.anuke.ucore.scene.ui.TextField;
|
import io.anuke.ucore.scene.ui.TextField;
|
||||||
@@ -85,6 +87,11 @@ public class AndroidLauncher extends AndroidApplication{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ThreadProvider getThreadProvider() {
|
||||||
|
return new DefaultThreadImpl();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if(doubleScaleTablets && isTablet(this.getContext())){
|
if(doubleScaleTablets && isTablet(this.getContext())){
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ allprojects {
|
|||||||
appName = "Mindustry"
|
appName = "Mindustry"
|
||||||
gdxVersion = '1.9.8'
|
gdxVersion = '1.9.8'
|
||||||
aiVersion = '1.8.1'
|
aiVersion = '1.8.1'
|
||||||
uCoreVersion = 'f40fdf3'
|
uCoreVersion = 'a480029'
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
|
|||||||
@@ -217,6 +217,7 @@ setting.sensitivity.name=Controller Sensitivity
|
|||||||
setting.saveinterval.name=Autosave Interval
|
setting.saveinterval.name=Autosave Interval
|
||||||
setting.seconds={0} Seconds
|
setting.seconds={0} Seconds
|
||||||
setting.fullscreen.name=Fullscreen
|
setting.fullscreen.name=Fullscreen
|
||||||
|
setting.multithread.name=Multithreading [scarlet](extremely unstable!)
|
||||||
setting.fps.name=Show FPS
|
setting.fps.name=Show FPS
|
||||||
setting.vsync.name=VSync
|
setting.vsync.name=VSync
|
||||||
setting.lasers.name=Show Power Lasers
|
setting.lasers.name=Show Power Lasers
|
||||||
|
|||||||
@@ -28,4 +28,11 @@ public class Mindustry extends ModuleCore {
|
|||||||
module(netClient = new NetClient());
|
module(netClient = new NetClient());
|
||||||
module(netCommon = new NetCommon());
|
module(netCommon = new NetCommon());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(){
|
||||||
|
super.render();
|
||||||
|
threads.handleRender();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,9 +10,11 @@ import io.anuke.mindustry.entities.Player;
|
|||||||
import io.anuke.mindustry.entities.TileEntity;
|
import io.anuke.mindustry.entities.TileEntity;
|
||||||
import io.anuke.mindustry.entities.effect.Shield;
|
import io.anuke.mindustry.entities.effect.Shield;
|
||||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||||
|
import io.anuke.mindustry.io.Platform;
|
||||||
import io.anuke.mindustry.net.ClientDebug;
|
import io.anuke.mindustry.net.ClientDebug;
|
||||||
import io.anuke.mindustry.net.ServerDebug;
|
import io.anuke.mindustry.net.ServerDebug;
|
||||||
import io.anuke.ucore.UCore;
|
import io.anuke.ucore.UCore;
|
||||||
|
import io.anuke.ucore.entities.EffectEntity;
|
||||||
import io.anuke.ucore.entities.Entities;
|
import io.anuke.ucore.entities.Entities;
|
||||||
import io.anuke.ucore.entities.EntityGroup;
|
import io.anuke.ucore.entities.EntityGroup;
|
||||||
import io.anuke.ucore.scene.ui.layout.Unit;
|
import io.anuke.ucore.scene.ui.layout.Unit;
|
||||||
@@ -112,6 +114,7 @@ public class Vars{
|
|||||||
public static final int webPort = 6568;
|
public static final int webPort = 6568;
|
||||||
|
|
||||||
public static final GameState state = new GameState();
|
public static final GameState state = new GameState();
|
||||||
|
public static final ThreadHandler threads = new ThreadHandler(Platform.instance.getThreadProvider());
|
||||||
|
|
||||||
public static final ServerDebug serverDebug = new ServerDebug();
|
public static final ServerDebug serverDebug = new ServerDebug();
|
||||||
public static final ClientDebug clientDebug = new ClientDebug();
|
public static final ClientDebug clientDebug = new ClientDebug();
|
||||||
@@ -132,4 +135,5 @@ public class Vars{
|
|||||||
public static final EntityGroup<TileEntity> tileGroup = Entities.addGroup(TileEntity.class, false);
|
public static final EntityGroup<TileEntity> tileGroup = Entities.addGroup(TileEntity.class, false);
|
||||||
public static final EntityGroup<Bullet> bulletGroup = Entities.addGroup(Bullet.class);
|
public static final EntityGroup<Bullet> bulletGroup = Entities.addGroup(Bullet.class);
|
||||||
public static final EntityGroup<Shield> shieldGroup = Entities.addGroup(Shield.class);
|
public static final EntityGroup<Shield> shieldGroup = Entities.addGroup(Shield.class);
|
||||||
|
public static final EntityGroup<EffectEntity> effectGroup = Entities.addGroup(EffectEntity.class);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import io.anuke.ucore.core.Timers;
|
|||||||
import io.anuke.ucore.util.Angles;
|
import io.anuke.ucore.util.Angles;
|
||||||
import io.anuke.ucore.util.Log;
|
import io.anuke.ucore.util.Log;
|
||||||
import io.anuke.ucore.util.Mathf;
|
import io.anuke.ucore.util.Mathf;
|
||||||
import io.anuke.ucore.util.Tmp;
|
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
|
|
||||||
@@ -26,6 +25,10 @@ public class Pathfind{
|
|||||||
/**temporary vector2 for calculations*/
|
/**temporary vector2 for calculations*/
|
||||||
Vector2 vector = new Vector2();
|
Vector2 vector = new Vector2();
|
||||||
|
|
||||||
|
Vector2 v1 = new Vector2();
|
||||||
|
Vector2 v2 = new Vector2();
|
||||||
|
Vector2 v3 = new Vector2();
|
||||||
|
|
||||||
/**Finds the position on the path an enemy should move to.
|
/**Finds the position on the path an enemy should move to.
|
||||||
* If the path is not yet calculated, this returns the enemy's position (i. e. "don't move")
|
* If the path is not yet calculated, this returns the enemy's position (i. e. "don't move")
|
||||||
* @param enemy The enemy to find a path for
|
* @param enemy The enemy to find a path for
|
||||||
@@ -76,8 +79,8 @@ public class Pathfind{
|
|||||||
if(projectLen < 8 || !onLine(projection, prev.worldx(), prev.worldy(), target.worldx(), target.worldy())){
|
if(projectLen < 8 || !onLine(projection, prev.worldx(), prev.worldy(), target.worldx(), target.worldy())){
|
||||||
canProject = false;
|
canProject = false;
|
||||||
}else{
|
}else{
|
||||||
projection.add(Angles.translation(Angles.angle(prev.worldx(), prev.worldy(),
|
projection.add(v1.set(projectLen, 0).rotate(Angles.angle(prev.worldx(), prev.worldy(),
|
||||||
target.worldx(), target.worldy()), projectLen));
|
target.worldx(), target.worldy())));
|
||||||
}
|
}
|
||||||
|
|
||||||
float dst = Vector2.dst(enemy.x, enemy.y, target.worldx(), target.worldy());
|
float dst = Vector2.dst(enemy.x, enemy.y, target.worldx(), target.worldy());
|
||||||
@@ -122,7 +125,8 @@ public class Pathfind{
|
|||||||
public void update(){
|
public void update(){
|
||||||
|
|
||||||
//go through each spawnpoint, and if it's not found a path yet, update it
|
//go through each spawnpoint, and if it's not found a path yet, update it
|
||||||
for(SpawnPoint point : world.getSpawns()){
|
for(int i = 0; i < world.getSpawns().size; i ++){
|
||||||
|
SpawnPoint point = world.getSpawns().get(i);
|
||||||
if(point.request == null || point.finder == null){
|
if(point.request == null || point.finder == null){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -204,7 +208,7 @@ public class Pathfind{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**Finds the closest tile to a position, in an array of tiles.*/
|
/**Finds the closest tile to a position, in an array of tiles.*/
|
||||||
private static int findClosest(Tile[] tiles, float x, float y){
|
private int findClosest(Tile[] tiles, float x, float y){
|
||||||
int cindex = -2;
|
int cindex = -2;
|
||||||
float dst = Float.MAX_VALUE;
|
float dst = Float.MAX_VALUE;
|
||||||
|
|
||||||
@@ -222,23 +226,23 @@ public class Pathfind{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**Returns whether a point is on a line.*/
|
/**Returns whether a point is on a line.*/
|
||||||
private static boolean onLine(Vector2 vector, float x1, float y1, float x2, float y2){
|
private boolean onLine(Vector2 vector, float x1, float y1, float x2, float y2){
|
||||||
return MathUtils.isEqual(vector.dst(x1, y1) + vector.dst(x2, y2), Vector2.dst(x1, y1, x2, y2), 0.01f);
|
return MathUtils.isEqual(vector.dst(x1, y1) + vector.dst(x2, y2), Vector2.dst(x1, y1, x2, y2), 0.01f);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Returns distance from a point to a line segment.*/
|
/**Returns distance from a point to a line segment.*/
|
||||||
private static float pointLineDist(float x, float y, float x2, float y2, float px, float py){
|
private float pointLineDist(float x, float y, float x2, float y2, float px, float py){
|
||||||
float l2 = Vector2.dst2(x, y, x2, y2);
|
float l2 = Vector2.dst2(x, y, x2, y2);
|
||||||
float t = Math.max(0, Math.min(1, Vector2.dot(px - x, py - y, x2 - x, y2 - y) / l2));
|
float t = Math.max(0, Math.min(1, Vector2.dot(px - x, py - y, x2 - x, y2 - y) / l2));
|
||||||
Vector2 projection = Tmp.v1.set(x, y).add(Tmp.v2.set(x2, y2).sub(x, y).scl(t)); // Projection falls on the segment
|
Vector2 projection = v1.set(x, y).add(v2.set(x2, y2).sub(x, y).scl(t)); // Projection falls on the segment
|
||||||
return projection.dst(px, py);
|
return projection.dst(px, py);
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO documentation
|
//TODO documentation
|
||||||
private static Vector2 projectPoint(float x1, float y1, float x2, float y2, float pointx, float pointy){
|
private Vector2 projectPoint(float x1, float y1, float x2, float y2, float pointx, float pointy){
|
||||||
float px = x2-x1, py = y2-y1, dAB = px*px + py*py;
|
float px = x2-x1, py = y2-y1, dAB = px*px + py*py;
|
||||||
float u = ((pointx - x1) * px + (pointy - y1) * py) / dAB;
|
float u = ((pointx - x1) * px + (pointy - y1) * py) / dAB;
|
||||||
float x = x1 + u * px, y = y1 + u * py;
|
float x = x1 + u * px, y = y1 + u * py;
|
||||||
return Tmp.v3.set(x, y); //this is D
|
return v3.set(x, y); //this is D
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,12 +4,13 @@ import com.badlogic.gdx.ai.utils.Collision;
|
|||||||
import com.badlogic.gdx.ai.utils.Ray;
|
import com.badlogic.gdx.ai.utils.Ray;
|
||||||
import com.badlogic.gdx.ai.utils.RaycastCollisionDetector;
|
import com.badlogic.gdx.ai.utils.RaycastCollisionDetector;
|
||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
import io.anuke.ucore.util.Geometry;
|
import io.anuke.ucore.util.Geometry;
|
||||||
import io.anuke.ucore.util.Mathf;
|
import io.anuke.ucore.util.Mathf;
|
||||||
|
|
||||||
|
import static io.anuke.mindustry.Vars.tilesize;
|
||||||
|
import static io.anuke.mindustry.Vars.world;
|
||||||
|
|
||||||
public class Raycaster implements RaycastCollisionDetector<Vector2>{
|
public class Raycaster implements RaycastCollisionDetector<Vector2>{
|
||||||
private boolean found = false;
|
private boolean found = false;
|
||||||
|
|
||||||
@@ -75,7 +76,8 @@ public class Raycaster implements RaycastCollisionDetector<Vector2>{
|
|||||||
|
|
||||||
if(tile == null || tile.solid()) return true;
|
if(tile == null || tile.solid()) return true;
|
||||||
|
|
||||||
for(Tile near : tile.getNearby()){
|
for(int i = 0; i < 4; i ++){
|
||||||
|
Tile near = tile.getNearby(i);
|
||||||
if(near == null || near.solid()) return true;
|
if(near == null || near.solid()) return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,16 +3,15 @@ package io.anuke.mindustry.ai;
|
|||||||
import com.badlogic.gdx.ai.pfa.DefaultGraphPath;
|
import com.badlogic.gdx.ai.pfa.DefaultGraphPath;
|
||||||
import com.badlogic.gdx.ai.pfa.SmoothableGraphPath;
|
import com.badlogic.gdx.ai.pfa.SmoothableGraphPath;
|
||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
|
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
import io.anuke.ucore.util.Tmp;
|
|
||||||
|
|
||||||
public class SmoothGraphPath extends DefaultGraphPath<Tile> implements SmoothableGraphPath<Tile, Vector2>{
|
public class SmoothGraphPath extends DefaultGraphPath<Tile> implements SmoothableGraphPath<Tile, Vector2>{
|
||||||
|
private Vector2 vector = new Vector2();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Vector2 getNodePosition(int index){
|
public Vector2 getNodePosition(int index){
|
||||||
Tile tile = nodes.get(index);
|
Tile tile = nodes.get(index);
|
||||||
return Tmp.v3.set(tile.worldx(), tile.worldy());
|
return vector.set(tile.worldx(), tile.worldy());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -4,11 +4,12 @@ import io.anuke.mindustry.world.Tile;
|
|||||||
|
|
||||||
/**Tilegraph that ignores player-made tiles.*/
|
/**Tilegraph that ignores player-made tiles.*/
|
||||||
public class TileGraph implements OptimizedGraph<Tile> {
|
public class TileGraph implements OptimizedGraph<Tile> {
|
||||||
|
private Tile[] tiles = new Tile[4];
|
||||||
|
|
||||||
/**Used for the OptimizedPathFinder implementation.*/
|
/**Used for the OptimizedPathFinder implementation.*/
|
||||||
@Override
|
@Override
|
||||||
public Tile[] connectionsOf(Tile node){
|
public Tile[] connectionsOf(Tile node){
|
||||||
Tile[] nodes = node.getNearby();
|
Tile[] nodes = node.getNearby(tiles);
|
||||||
for(int i = 0; i < 4; i ++){
|
for(int i = 0; i < 4; i ++){
|
||||||
if(nodes[i] != null && !nodes[i].passable()){
|
if(nodes[i] != null && !nodes[i].passable()){
|
||||||
nodes[i] = null;
|
nodes[i] = null;
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ public class Control extends Module{
|
|||||||
|
|
||||||
int last = Settings.getInt("hiscore" + world.getMap().name);
|
int last = Settings.getInt("hiscore" + world.getMap().name);
|
||||||
|
|
||||||
if(state.wave > last && !state.mode.infiniteResources && !state.mode.toggleWaves){
|
if(state.wave > last && !state.mode.infiniteResources && !state.mode.disableWaveTimer){
|
||||||
Settings.putInt("hiscore" + world.getMap().name, state.wave);
|
Settings.putInt("hiscore" + world.getMap().name, state.wave);
|
||||||
Settings.save();
|
Settings.save();
|
||||||
hiscore = true;
|
hiscore = true;
|
||||||
@@ -345,6 +345,7 @@ public class Control extends Module{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!state.is(State.paused) || Net.active()){
|
if(!state.is(State.paused) || Net.active()){
|
||||||
|
Entities.update(effectGroup);
|
||||||
|
|
||||||
if(respawntime > 0){
|
if(respawntime > 0){
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package io.anuke.mindustry.core;
|
package io.anuke.mindustry.core;
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx;
|
|
||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.core.GameState.State;
|
import io.anuke.mindustry.core.GameState.State;
|
||||||
@@ -9,6 +8,7 @@ import io.anuke.mindustry.game.EnemySpawn;
|
|||||||
import io.anuke.mindustry.game.EventType.GameOverEvent;
|
import io.anuke.mindustry.game.EventType.GameOverEvent;
|
||||||
import io.anuke.mindustry.game.EventType.PlayEvent;
|
import io.anuke.mindustry.game.EventType.PlayEvent;
|
||||||
import io.anuke.mindustry.game.EventType.ResetEvent;
|
import io.anuke.mindustry.game.EventType.ResetEvent;
|
||||||
|
import io.anuke.mindustry.game.EventType.WaveEvent;
|
||||||
import io.anuke.mindustry.game.SpawnPoint;
|
import io.anuke.mindustry.game.SpawnPoint;
|
||||||
import io.anuke.mindustry.game.WaveCreator;
|
import io.anuke.mindustry.game.WaveCreator;
|
||||||
import io.anuke.mindustry.graphics.Fx;
|
import io.anuke.mindustry.graphics.Fx;
|
||||||
@@ -35,10 +35,6 @@ import static io.anuke.mindustry.Vars.*;
|
|||||||
public class Logic extends Module {
|
public class Logic extends Module {
|
||||||
private final Array<EnemySpawn> spawns = WaveCreator.getSpawns();
|
private final Array<EnemySpawn> spawns = WaveCreator.getSpawns();
|
||||||
|
|
||||||
public Logic(){
|
|
||||||
Timers.setDeltaProvider(() -> Math.min(Gdx.graphics.getDeltaTime()*60f, 60));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(){
|
public void init(){
|
||||||
Entities.initPhysics();
|
Entities.initPhysics();
|
||||||
@@ -107,17 +103,23 @@ public class Logic extends Module {
|
|||||||
state.wave ++;
|
state.wave ++;
|
||||||
state.wavetime = wavespace * state.difficulty.timeScaling;
|
state.wavetime = wavespace * state.difficulty.timeScaling;
|
||||||
state.extrawavetime = maxwavespace * state.difficulty.maxTimeScaling;
|
state.extrawavetime = maxwavespace * state.difficulty.maxTimeScaling;
|
||||||
|
|
||||||
|
Events.fire(WaveEvent.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(){
|
public void update(){
|
||||||
|
|
||||||
if(!state.is(State.paused) || Net.active()){
|
if(!state.is(State.paused) || Net.active()){
|
||||||
Timers.update();
|
Timers.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!state.is(State.menu)){
|
if(!state.is(State.menu)){
|
||||||
|
|
||||||
if(world.getCore().block() != ProductionBlocks.core && !state.gameOver){
|
if(!Net.client())
|
||||||
|
world.pathfinder().update();
|
||||||
|
|
||||||
|
if(world.getCore() != null && world.getCore().block() != ProductionBlocks.core && !state.gameOver){
|
||||||
state.gameOver = true;
|
state.gameOver = true;
|
||||||
NetEvents.handleGameOver();
|
NetEvents.handleGameOver();
|
||||||
Events.fire(GameOverEvent.class);
|
Events.fire(GameOverEvent.class);
|
||||||
@@ -125,7 +127,7 @@ public class Logic extends Module {
|
|||||||
|
|
||||||
if(!state.is(State.paused) || Net.active()){
|
if(!state.is(State.paused) || Net.active()){
|
||||||
|
|
||||||
if(!state.mode.toggleWaves){
|
if(!state.mode.disableWaveTimer){
|
||||||
|
|
||||||
if(state.enemies <= 0){
|
if(state.enemies <= 0){
|
||||||
state.wavetime -= delta();
|
state.wavetime -= delta();
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import com.badlogic.gdx.utils.FloatArray;
|
|||||||
import com.badlogic.gdx.utils.Pools;
|
import com.badlogic.gdx.utils.Pools;
|
||||||
import io.anuke.mindustry.core.GameState.State;
|
import io.anuke.mindustry.core.GameState.State;
|
||||||
import io.anuke.mindustry.entities.Player;
|
import io.anuke.mindustry.entities.Player;
|
||||||
|
import io.anuke.mindustry.entities.SyncEntity;
|
||||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||||
import io.anuke.mindustry.game.SpawnPoint;
|
import io.anuke.mindustry.game.SpawnPoint;
|
||||||
import io.anuke.mindustry.graphics.BlockRenderer;
|
import io.anuke.mindustry.graphics.BlockRenderer;
|
||||||
@@ -24,7 +25,6 @@ import io.anuke.mindustry.world.Tile;
|
|||||||
import io.anuke.mindustry.world.blocks.Blocks;
|
import io.anuke.mindustry.world.blocks.Blocks;
|
||||||
import io.anuke.mindustry.world.blocks.ProductionBlocks;
|
import io.anuke.mindustry.world.blocks.ProductionBlocks;
|
||||||
import io.anuke.ucore.core.*;
|
import io.anuke.ucore.core.*;
|
||||||
import io.anuke.ucore.entities.DestructibleEntity;
|
|
||||||
import io.anuke.ucore.entities.EffectEntity;
|
import io.anuke.ucore.entities.EffectEntity;
|
||||||
import io.anuke.ucore.entities.Entities;
|
import io.anuke.ucore.entities.Entities;
|
||||||
import io.anuke.ucore.function.Callable;
|
import io.anuke.ucore.function.Callable;
|
||||||
@@ -50,6 +50,7 @@ public class Renderer extends RendererModule{
|
|||||||
private int targetscale = baseCameraScale;
|
private int targetscale = baseCameraScale;
|
||||||
private FloatArray shieldHits = new FloatArray();
|
private FloatArray shieldHits = new FloatArray();
|
||||||
private Array<Callable> shieldDraws = new Array<>();
|
private Array<Callable> shieldDraws = new Array<>();
|
||||||
|
private Rectangle rect = new Rectangle(), rect2 = new Rectangle();
|
||||||
private BlockRenderer blocks = new BlockRenderer();
|
private BlockRenderer blocks = new BlockRenderer();
|
||||||
|
|
||||||
public Renderer() {
|
public Renderer() {
|
||||||
@@ -58,11 +59,11 @@ public class Renderer extends RendererModule{
|
|||||||
Core.cameraScale = baseCameraScale;
|
Core.cameraScale = baseCameraScale;
|
||||||
Effects.setEffectProvider((name, color, x, y, rotation) -> {
|
Effects.setEffectProvider((name, color, x, y, rotation) -> {
|
||||||
if(Settings.getBool("effects")){
|
if(Settings.getBool("effects")){
|
||||||
Rectangle view = Tmp.r1.setSize(camera.viewportWidth, camera.viewportHeight)
|
Rectangle view = rect.setSize(camera.viewportWidth, camera.viewportHeight)
|
||||||
.setCenter(camera.position.x, camera.position.y);
|
.setCenter(camera.position.x, camera.position.y);
|
||||||
Rectangle pos = Tmp.r2.setSize(name.size).setCenter(x, y);
|
Rectangle pos = rect2.setSize(name.size).setCenter(x, y);
|
||||||
if(view.overlaps(pos)){
|
if(view.overlaps(pos)){
|
||||||
new EffectEntity(name, color, rotation).set(x, y).add();
|
new EffectEntity(name, color, rotation).set(x, y).add(effectGroup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -190,6 +191,7 @@ public class Renderer extends RendererModule{
|
|||||||
Graphics.shader();
|
Graphics.shader();
|
||||||
|
|
||||||
Entities.draw(bulletGroup);
|
Entities.draw(bulletGroup);
|
||||||
|
Entities.draw(effectGroup);
|
||||||
|
|
||||||
drawShield();
|
drawShield();
|
||||||
|
|
||||||
@@ -242,13 +244,15 @@ public class Renderer extends RendererModule{
|
|||||||
Draw.color(Color.RED);
|
Draw.color(Color.RED);
|
||||||
for(Enemy enemy : enemyGroup.all()) {
|
for(Enemy enemy : enemyGroup.all()) {
|
||||||
|
|
||||||
if (Tmp.r1.setSize(camera.viewportWidth, camera.viewportHeight).setCenter(camera.position.x, camera.position.y).overlaps(enemy.hitbox.getRect(enemy.x, enemy.y))) {
|
if (rect.setSize(camera.viewportWidth, camera.viewportHeight).setCenter(camera.position.x, camera.position.y)
|
||||||
|
.overlaps(enemy.hitbox.getRect(enemy.x, enemy.y))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
float angle = Angles.angle(camera.position.x, camera.position.y, enemy.x, enemy.y);
|
float angle = Angles.angle(camera.position.x, camera.position.y, enemy.x, enemy.y);
|
||||||
Angles.translation(angle, Unit.dp.scl(20f));
|
float tx = Angles.trnsx(angle, Unit.dp.scl(20f));
|
||||||
Draw.rect("enemyarrow", camera.position.x + Angles.x(), camera.position.y + Angles.y(), angle);
|
float ty = Angles.trnsy(angle, Unit.dp.scl(20f));
|
||||||
|
Draw.rect("enemyarrow", camera.position.x + tx, camera.position.y + ty, angle);
|
||||||
}
|
}
|
||||||
|
|
||||||
Draw.color();
|
Draw.color();
|
||||||
@@ -445,11 +449,13 @@ public class Renderer extends RendererModule{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawHealth(DestructibleEntity dest){
|
void drawHealth(SyncEntity dest){
|
||||||
|
float x = dest.getDrawPosition().x;
|
||||||
|
float y = dest.getDrawPosition().y;
|
||||||
if(dest instanceof Player && snapCamera && Settings.getBool("smoothcam") && Settings.getBool("pixelate")){
|
if(dest instanceof Player && snapCamera && Settings.getBool("smoothcam") && Settings.getBool("pixelate")){
|
||||||
drawHealth((int) dest.x, (int) dest.y - 7f, dest.health, dest.maxhealth);
|
drawHealth((int) x, (int) y - 7f, dest.health, dest.maxhealth);
|
||||||
}else{
|
}else{
|
||||||
drawHealth(dest.x, dest.y - 7f, dest.health, dest.maxhealth);
|
drawHealth(x, y - 7f, dest.health, dest.maxhealth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
109
core/src/io/anuke/mindustry/core/ThreadHandler.java
Normal file
109
core/src/io/anuke/mindustry/core/ThreadHandler.java
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
package io.anuke.mindustry.core;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Gdx;
|
||||||
|
import com.badlogic.gdx.utils.TimeUtils;
|
||||||
|
import io.anuke.ucore.core.Timers;
|
||||||
|
import io.anuke.ucore.util.Log;
|
||||||
|
|
||||||
|
import static io.anuke.mindustry.Vars.logic;
|
||||||
|
|
||||||
|
public class ThreadHandler {
|
||||||
|
private final ThreadProvider impl;
|
||||||
|
private float delta = 1f;
|
||||||
|
private long frame = 0;
|
||||||
|
private float framesSinceUpdate;
|
||||||
|
private boolean enabled;
|
||||||
|
|
||||||
|
private final Object updateLock = new Object();
|
||||||
|
private boolean rendered = true;
|
||||||
|
|
||||||
|
public ThreadHandler(ThreadProvider impl){
|
||||||
|
this.impl = impl;
|
||||||
|
|
||||||
|
Timers.setDeltaProvider(() -> impl.isOnThread() ? delta : Gdx.graphics.getDeltaTime()*60f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFPS(){
|
||||||
|
return (int)(60/delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getFrameID(){
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getFramesSinceUpdate(){
|
||||||
|
return framesSinceUpdate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleRender(){
|
||||||
|
if(!enabled) return;
|
||||||
|
|
||||||
|
framesSinceUpdate += Timers.delta();
|
||||||
|
|
||||||
|
synchronized (updateLock) {
|
||||||
|
rendered = true;
|
||||||
|
updateLock.notify();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabled(boolean enabled){
|
||||||
|
if(enabled){
|
||||||
|
logic.doUpdate = false;
|
||||||
|
Timers.runTask(2f, () -> {
|
||||||
|
impl.start(this::runLogic);
|
||||||
|
this.enabled = true;
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
this.enabled = false;
|
||||||
|
impl.stop();
|
||||||
|
Timers.runTask(2f, () -> {
|
||||||
|
logic.doUpdate = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEnabled(){
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runLogic(){
|
||||||
|
try {
|
||||||
|
while (true) {
|
||||||
|
long time = TimeUtils.millis();
|
||||||
|
logic.update();
|
||||||
|
|
||||||
|
long elapsed = TimeUtils.timeSinceMillis(time);
|
||||||
|
long target = (long) (1000 / 60f);
|
||||||
|
|
||||||
|
delta = Math.max(elapsed, target) / 1000f * 60f;
|
||||||
|
|
||||||
|
if (elapsed < target) {
|
||||||
|
impl.sleep(target - elapsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized(updateLock) {
|
||||||
|
while(!rendered) {
|
||||||
|
updateLock.wait();
|
||||||
|
}
|
||||||
|
rendered = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
frame ++;
|
||||||
|
framesSinceUpdate = 0;
|
||||||
|
}
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
Log.info("Stopping logic thread.");
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Gdx.app.postRunnable(() -> {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ThreadProvider {
|
||||||
|
boolean isOnThread();
|
||||||
|
void sleep(long ms) throws InterruptedException;
|
||||||
|
void start(Runnable run);
|
||||||
|
void stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,7 +8,6 @@ import io.anuke.mindustry.ai.Pathfind;
|
|||||||
import io.anuke.mindustry.entities.TileEntity;
|
import io.anuke.mindustry.entities.TileEntity;
|
||||||
import io.anuke.mindustry.game.SpawnPoint;
|
import io.anuke.mindustry.game.SpawnPoint;
|
||||||
import io.anuke.mindustry.io.Maps;
|
import io.anuke.mindustry.io.Maps;
|
||||||
import io.anuke.mindustry.net.Net;
|
|
||||||
import io.anuke.mindustry.world.Block;
|
import io.anuke.mindustry.world.Block;
|
||||||
import io.anuke.mindustry.world.Map;
|
import io.anuke.mindustry.world.Map;
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
@@ -42,12 +41,6 @@ public class World extends Module{
|
|||||||
currentMap = maps.getMap(0);
|
currentMap = maps.getMap(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void update(){
|
|
||||||
if(!Net.client())
|
|
||||||
pathfind.update();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose(){
|
public void dispose(){
|
||||||
maps.dispose();
|
maps.dispose();
|
||||||
@@ -140,18 +133,6 @@ public class World extends Module{
|
|||||||
return tiles;
|
return tiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Tile[] getNearby(int x, int y){
|
|
||||||
return getNearby(x, y, temptiles);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Tile[] getNearby(int x, int y, Tile[] temptiles){
|
|
||||||
temptiles[0] = tile(x+1, y);
|
|
||||||
temptiles[1] = tile(x, y+1);
|
|
||||||
temptiles[2] = tile(x-1, y);
|
|
||||||
temptiles[3] = tile(x, y-1);
|
|
||||||
return temptiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createTiles(){
|
private void createTiles(){
|
||||||
for(int x = 0; x < tiles.length; x ++){
|
for(int x = 0; x < tiles.length; x ++){
|
||||||
for(int y = 0; y < tiles[0].length; y ++){
|
for(int y = 0; y < tiles[0].length; y ++){
|
||||||
|
|||||||
@@ -9,21 +9,26 @@ import io.anuke.ucore.util.Mathf;
|
|||||||
import static io.anuke.mindustry.Vars.*;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
|
|
||||||
public class Bullet extends BulletEntity{
|
public class Bullet extends BulletEntity{
|
||||||
public boolean absorbed = false;
|
|
||||||
|
|
||||||
public Bullet(BulletType type, Entity owner, float x, float y, float angle){
|
public Bullet(BulletType type, Entity owner, float x, float y, float angle){
|
||||||
super(type, owner, angle);
|
super(type, owner, angle);
|
||||||
set(x, y);
|
set(x, y);
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void absorb(){
|
|
||||||
absorbed = true;
|
|
||||||
remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void draw(){
|
public void draw(){
|
||||||
type.draw(this);
|
//interpolate position linearly at low tick speeds
|
||||||
|
if(SyncEntity.isSmoothing()){
|
||||||
|
x += threads.getFramesSinceUpdate() * velocity.x;
|
||||||
|
y += threads.getFramesSinceUpdate() * velocity.y;
|
||||||
|
|
||||||
|
type.draw(this);
|
||||||
|
|
||||||
|
x -= threads.getFramesSinceUpdate() * velocity.x;
|
||||||
|
y -= threads.getFramesSinceUpdate() * velocity.y;
|
||||||
|
}else{
|
||||||
|
type.draw(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float drawSize(){
|
public float drawSize(){
|
||||||
|
|||||||
@@ -252,10 +252,11 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
|
|||||||
|
|
||||||
Effects.effect(Fx.blastsmoke, b);
|
Effects.effect(Fx.blastsmoke, b);
|
||||||
Effects.effect(Fx.blastexplosion, b);
|
Effects.effect(Fx.blastexplosion, b);
|
||||||
|
|
||||||
Angles.circle(30, f->{
|
//TODO remove translation() usage
|
||||||
Angles.translation(f, 6f);
|
Angles.circleVectors(30, 6f, (x, y) -> {
|
||||||
Bullet o = new Bullet(blastshot, b.owner, b.x + Angles.x(), b.y + Angles.y(), f).add();
|
float ang = Mathf.atan2(x, y);
|
||||||
|
Bullet o = new Bullet(blastshot, b.owner, b.x + x, b.y + y, ang).add();
|
||||||
o.damage = b.damage/9;
|
o.damage = b.damage/9;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package io.anuke.mindustry.entities;
|
package io.anuke.mindustry.entities;
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.Color;
|
import com.badlogic.gdx.graphics.Color;
|
||||||
import com.badlogic.gdx.utils.TimeUtils;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
import io.anuke.mindustry.graphics.Fx;
|
import io.anuke.mindustry.graphics.Fx;
|
||||||
import io.anuke.mindustry.graphics.Shaders;
|
import io.anuke.mindustry.graphics.Shaders;
|
||||||
import io.anuke.mindustry.net.Net;
|
import io.anuke.mindustry.net.Net;
|
||||||
@@ -16,7 +16,7 @@ import io.anuke.ucore.entities.SolidEntity;
|
|||||||
import io.anuke.ucore.graphics.Draw;
|
import io.anuke.ucore.graphics.Draw;
|
||||||
import io.anuke.ucore.util.Angles;
|
import io.anuke.ucore.util.Angles;
|
||||||
import io.anuke.ucore.util.Mathf;
|
import io.anuke.ucore.util.Mathf;
|
||||||
import io.anuke.ucore.util.Tmp;
|
import io.anuke.ucore.util.Translator;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
@@ -34,13 +34,15 @@ public class Player extends SyncEntity{
|
|||||||
public Weapon weaponRight = Weapon.blaster;
|
public Weapon weaponRight = Weapon.blaster;
|
||||||
public Mech mech = Mech.standard;
|
public Mech mech = Mech.standard;
|
||||||
|
|
||||||
public float angle;
|
|
||||||
public float targetAngle = 0f;
|
public float targetAngle = 0f;
|
||||||
public float stucktime = 0f;
|
public float stucktime = 0f;
|
||||||
public boolean dashing = false;
|
public boolean dashing = false;
|
||||||
|
|
||||||
public int clientid;
|
public int clientid;
|
||||||
public boolean isLocal = false;
|
public boolean isLocal = false;
|
||||||
|
|
||||||
|
private Vector2 movement = new Vector2();
|
||||||
|
private Translator tr = new Translator();
|
||||||
|
|
||||||
public Player(){
|
public Player(){
|
||||||
hitbox.setSize(5);
|
hitbox.setSize(5);
|
||||||
@@ -102,7 +104,7 @@ public class Player extends SyncEntity{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(){
|
public void drawSmooth(){
|
||||||
if(isAndroid && isLocal){
|
if(isAndroid && isLocal){
|
||||||
angle = Mathf.lerpAngDelta(angle, targetAngle, 0.2f);
|
angle = Mathf.lerpAngDelta(angle, targetAngle, 0.2f);
|
||||||
}
|
}
|
||||||
@@ -121,12 +123,12 @@ public class Player extends SyncEntity{
|
|||||||
if(!isAndroid) {
|
if(!isAndroid) {
|
||||||
for (int i : Mathf.signs) {
|
for (int i : Mathf.signs) {
|
||||||
Weapon weapon = i < 0 ? weaponLeft : weaponRight;
|
Weapon weapon = i < 0 ? weaponLeft : weaponRight;
|
||||||
Angles.vector.set(3 * i, 2).rotate(angle - 90);
|
tr.trns(angle - 90, 3*i, 2);
|
||||||
float w = i > 0 ? -8 : 8;
|
float w = i > 0 ? -8 : 8;
|
||||||
if(snap){
|
if(snap){
|
||||||
Draw.rect(weapon.name + "-equip", (int)x + Angles.x(), (int)y + Angles.y(), w, 8, angle - 90);
|
Draw.rect(weapon.name + "-equip", (int)x + tr.x, (int)y + tr.y, w, 8, angle - 90);
|
||||||
}else{
|
}else{
|
||||||
Draw.rect(weapon.name + "-equip", x + Angles.x(), y + Angles.y(), w, 8, angle - 90);
|
Draw.rect(weapon.name + "-equip", x + tr.x, y + tr.y, w, 8, angle - 90);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -172,15 +174,15 @@ public class Player extends SyncEntity{
|
|||||||
|
|
||||||
health = Mathf.clamp(health, -1, maxhealth);
|
health = Mathf.clamp(health, -1, maxhealth);
|
||||||
|
|
||||||
vector.set(0, 0);
|
movement.set(0, 0);
|
||||||
|
|
||||||
float xa = Inputs.getAxis("move_x");
|
float xa = Inputs.getAxis("move_x");
|
||||||
float ya = Inputs.getAxis("move_y");
|
float ya = Inputs.getAxis("move_y");
|
||||||
if(Math.abs(xa) < 0.3) xa = 0;
|
if(Math.abs(xa) < 0.3) xa = 0;
|
||||||
if(Math.abs(ya) < 0.3) ya = 0;
|
if(Math.abs(ya) < 0.3) ya = 0;
|
||||||
|
|
||||||
vector.y += ya*speed;
|
movement.y += ya*speed;
|
||||||
vector.x += xa*speed;
|
movement.x += xa*speed;
|
||||||
|
|
||||||
boolean shooting = !Inputs.keyDown("dash") && Inputs.keyDown("shoot") && control.input().recipe == null
|
boolean shooting = !Inputs.keyDown("dash") && Inputs.keyDown("shoot") && control.input().recipe == null
|
||||||
&& !ui.hasMouse() && !control.input().onConfigurable();
|
&& !ui.hasMouse() && !control.input().onConfigurable();
|
||||||
@@ -190,23 +192,22 @@ public class Player extends SyncEntity{
|
|||||||
weaponRight.update(player, false);
|
weaponRight.update(player, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dashing && Timers.get(this, "dashfx", 3) && vector.len() > 0){
|
if(dashing && Timers.get(this, "dashfx", 3) && movement.len() > 0){
|
||||||
Angles.translation(angle + 180, 3f);
|
Effects.effect(Fx.dashsmoke, x + Angles.trnsx(angle + 180f, 3f), y + Angles.trnsy(angle + 180f, 3f));
|
||||||
Effects.effect(Fx.dashsmoke, x + Angles.x(), y + Angles.y());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vector.limit(speed);
|
movement.limit(speed);
|
||||||
|
|
||||||
if(!noclip){
|
if(!noclip){
|
||||||
move(vector.x*Timers.delta(), vector.y*Timers.delta());
|
move(movement.x*Timers.delta(), movement.y*Timers.delta());
|
||||||
}else{
|
}else{
|
||||||
x += vector.x*Timers.delta();
|
x += movement.x*Timers.delta();
|
||||||
y += vector.y*Timers.delta();
|
y += movement.y*Timers.delta();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!shooting){
|
if(!shooting){
|
||||||
if(!vector.isZero())
|
if(!movement.isZero())
|
||||||
angle = Mathf.lerpAngDelta(angle, vector.angle(), 0.13f);
|
angle = Mathf.lerpAngDelta(angle, movement.angle(), 0.13f);
|
||||||
}else{
|
}else{
|
||||||
float angle = Angles.mouseAngle(x, y);
|
float angle = Angles.mouseAngle(x, y);
|
||||||
this.angle = Mathf.lerpAngDelta(this.angle, angle, 0.1f);
|
this.angle = Mathf.lerpAngDelta(this.angle, angle, 0.1f);
|
||||||
@@ -273,40 +274,24 @@ public class Player extends SyncEntity{
|
|||||||
this.health = health;
|
this.health = health;
|
||||||
this.dashing = dashing == 1;
|
this.dashing = dashing == 1;
|
||||||
|
|
||||||
interpolator.targetrot = angle;
|
interpolator.read(this.x, this.y, x, y, angle, time);
|
||||||
interpolator.time = 0f;
|
|
||||||
interpolator.last.set(this.x, this.y);
|
|
||||||
interpolator.target.set(x, y);
|
|
||||||
interpolator.spacing = Math.min(Math.max(((TimeUtils.timeSinceMillis(time) / 1000f) * 60f), 4f), 10);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void interpolate() {
|
public void interpolate() {
|
||||||
|
super.interpolate();
|
||||||
|
|
||||||
Interpolator i = interpolator;
|
Interpolator i = interpolator;
|
||||||
|
|
||||||
i.time += 1f / i.spacing * Timers.delta();
|
float tx = x + Angles.trnsx(angle + 180f, 3f);
|
||||||
|
float ty = y + Angles.trnsy(angle + 180f, 3f);
|
||||||
Mathf.lerp2(Tmp.v2.set(i.last), i.target, i.time);
|
|
||||||
|
|
||||||
x = Tmp.v2.x;
|
|
||||||
y = Tmp.v2.y;
|
|
||||||
|
|
||||||
if(i.target.dst(x, y) > 128){
|
|
||||||
set(i.target.x, i.target.y);
|
|
||||||
i.time = 0f;
|
|
||||||
i.last.set(i.target);
|
|
||||||
}
|
|
||||||
|
|
||||||
angle = Mathf.lerpAngDelta(angle, i.targetrot, 0.6f);
|
|
||||||
|
|
||||||
if(isAndroid && i.target.dst(i.last) > 2f && Timers.get(this, "dashfx", 2)){
|
if(isAndroid && i.target.dst(i.last) > 2f && Timers.get(this, "dashfx", 2)){
|
||||||
Angles.translation(angle + 180, 3f);
|
Effects.effect(Fx.dashsmoke, tx, ty);
|
||||||
Effects.effect(Fx.dashsmoke, x + Angles.x(), y + Angles.y());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dashing && !dead && Timers.get(this, "dashfx", 3) && i.target.dst(i.last) > 1f){
|
if(dashing && !dead && Timers.get(this, "dashfx", 3) && i.target.dst(i.last) > 1f){
|
||||||
Angles.translation(angle + 180, 3f);
|
Effects.effect(Fx.dashsmoke, tx, ty);
|
||||||
Effects.effect(Fx.dashsmoke, x + Angles.x(), y + Angles.y());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,28 +1,79 @@
|
|||||||
package io.anuke.mindustry.entities;
|
package io.anuke.mindustry.entities;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Gdx;
|
||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
|
import com.badlogic.gdx.math.Vector3;
|
||||||
import com.badlogic.gdx.utils.ObjectIntMap;
|
import com.badlogic.gdx.utils.ObjectIntMap;
|
||||||
|
import com.badlogic.gdx.utils.TimeUtils;
|
||||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||||
|
import io.anuke.ucore.core.Timers;
|
||||||
import io.anuke.ucore.entities.DestructibleEntity;
|
import io.anuke.ucore.entities.DestructibleEntity;
|
||||||
|
import io.anuke.ucore.util.Mathf;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import static io.anuke.mindustry.Vars.threads;
|
||||||
|
|
||||||
public abstract class SyncEntity extends DestructibleEntity{
|
public abstract class SyncEntity extends DestructibleEntity{
|
||||||
private static ObjectIntMap<Class<? extends SyncEntity>> writeSizes = new ObjectIntMap<>();
|
private static ObjectIntMap<Class<? extends SyncEntity>> writeSizes = new ObjectIntMap<>();
|
||||||
|
|
||||||
protected transient Interpolator interpolator = new Interpolator();
|
protected transient Interpolator interpolator = new Interpolator();
|
||||||
|
|
||||||
|
//smoothed position/angle
|
||||||
|
private Vector3 spos = new Vector3();
|
||||||
|
|
||||||
|
public float angle;
|
||||||
|
|
||||||
static{
|
static{
|
||||||
setWriteSize(Enemy.class, 4 + 4 + 2 + 2);
|
setWriteSize(Enemy.class, 4 + 4 + 2 + 2);
|
||||||
setWriteSize(Player.class, 4 + 4 + 4 + 2 + 1);
|
setWriteSize(Player.class, 4 + 4 + 4 + 2 + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isSmoothing(){
|
||||||
|
return threads.isEnabled() && threads.getFPS() <= Gdx.graphics.getFramesPerSecond() / 2f;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract void writeSpawn(ByteBuffer data);
|
public abstract void writeSpawn(ByteBuffer data);
|
||||||
public abstract void readSpawn(ByteBuffer data);
|
public abstract void readSpawn(ByteBuffer data);
|
||||||
|
|
||||||
public abstract void write(ByteBuffer data);
|
public abstract void write(ByteBuffer data);
|
||||||
public abstract void read(ByteBuffer data, long time);
|
public abstract void read(ByteBuffer data, long time);
|
||||||
public abstract void interpolate();
|
|
||||||
|
public void interpolate(){
|
||||||
|
interpolator.update();
|
||||||
|
|
||||||
|
x = interpolator.pos.x;
|
||||||
|
y = interpolator.pos.y;
|
||||||
|
angle = interpolator.angle;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void draw(){
|
||||||
|
float x = this.x, y = this.y, angle = this.angle;
|
||||||
|
|
||||||
|
//interpolates data at low tick speeds.
|
||||||
|
if(isSmoothing()){
|
||||||
|
if(Vector2.dst(spos.x, spos.y, x, y) > 128){
|
||||||
|
spos.set(x, y, angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.x = spos.x = Mathf.lerpDelta(spos.x, x, 0.2f);
|
||||||
|
this.y = spos.y = Mathf.lerpDelta(spos.y, y, 0.2f);
|
||||||
|
this.angle = spos.z = Mathf.lerpAngDelta(spos.z, angle, 0.3f);
|
||||||
|
}
|
||||||
|
|
||||||
|
drawSmooth();
|
||||||
|
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.angle = angle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3 getDrawPosition(){
|
||||||
|
return isSmoothing() ? spos : spos.set(x, y, angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawSmooth(){}
|
||||||
|
|
||||||
public int getWriteSize(){
|
public int getWriteSize(){
|
||||||
return getWriteSize(getClass());
|
return getWriteSize(getClass());
|
||||||
@@ -47,11 +98,40 @@ public abstract class SyncEntity extends DestructibleEntity{
|
|||||||
return (T)this;
|
return (T)this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Interpolator {
|
public static class Interpolator {
|
||||||
|
//used for movement
|
||||||
public Vector2 target = new Vector2();
|
public Vector2 target = new Vector2();
|
||||||
public Vector2 last = new Vector2();
|
public Vector2 last = new Vector2();
|
||||||
public float targetrot;
|
public float targetrot;
|
||||||
public float spacing = 1f;
|
public float spacing = 1f;
|
||||||
public float time;
|
public float time;
|
||||||
|
|
||||||
|
//current state
|
||||||
|
public Vector2 pos = new Vector2();
|
||||||
|
public float angle;
|
||||||
|
|
||||||
|
public void read(float cx, float cy, float x, float y, float angle, long sent){
|
||||||
|
targetrot = angle;
|
||||||
|
time = 0f;
|
||||||
|
last.set(cx, cy);
|
||||||
|
target.set(x, y);
|
||||||
|
spacing = Math.min(Math.max(((TimeUtils.timeSinceMillis(sent) / 1000f) * 60f), 4f), 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(){
|
||||||
|
|
||||||
|
time += 1f / spacing * Timers.delta();
|
||||||
|
|
||||||
|
Mathf.lerp2(pos.set(last), target, time);
|
||||||
|
|
||||||
|
angle = Mathf.lerpAngDelta(angle, targetrot, 0.6f);
|
||||||
|
|
||||||
|
if(target.dst(pos) > 128){
|
||||||
|
pos.set(target);
|
||||||
|
last.set(target);
|
||||||
|
time = 0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,10 +108,10 @@ public class TileEntity extends Entity{
|
|||||||
public void update(){
|
public void update(){
|
||||||
if(health != 0 && health < tile.block().health && !(tile.block() instanceof Wall) &&
|
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*Timers.delta()*(1f-health/tile.block().health))){
|
||||||
|
|
||||||
Effects.effect(Fx.smoke, x+Mathf.range(4), y+Mathf.range(4));
|
Effects.effect(Fx.smoke, x+Mathf.range(4), y+Mathf.range(4));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(health <= 0){
|
if(health <= 0){
|
||||||
onDeath();
|
onDeath();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,20 +11,21 @@ import io.anuke.ucore.entities.Entities;
|
|||||||
import io.anuke.ucore.entities.Entity;
|
import io.anuke.ucore.entities.Entity;
|
||||||
import io.anuke.ucore.entities.SolidEntity;
|
import io.anuke.ucore.entities.SolidEntity;
|
||||||
import io.anuke.ucore.function.Consumer;
|
import io.anuke.ucore.function.Consumer;
|
||||||
import io.anuke.ucore.util.Angles;
|
|
||||||
import io.anuke.ucore.util.Mathf;
|
import io.anuke.ucore.util.Mathf;
|
||||||
import io.anuke.ucore.util.Physics;
|
import io.anuke.ucore.util.Physics;
|
||||||
|
import io.anuke.ucore.util.Translator;
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
|
|
||||||
public class DamageArea{
|
public class DamageArea{
|
||||||
private static Rectangle rect = new Rectangle();
|
private static Rectangle rect = new Rectangle();
|
||||||
|
private static Translator tr = new Translator();
|
||||||
|
|
||||||
//only for entities, not tiles (yet!)
|
//only for entities, not tiles (yet!)
|
||||||
public static void damageLine(Entity owner, Effect effect, float x, float y, float angle, float length, int damage){
|
public static void damageLine(Entity owner, Effect effect, float x, float y, float angle, float length, int damage){
|
||||||
Angles.translation(angle, length);
|
tr.trns(angle, length);
|
||||||
rect.setPosition(x, y).setSize(Angles.x(), Angles.y());
|
rect.setPosition(x, y).setSize(tr.x, tr.y);
|
||||||
float x2 = Angles.x() + x, y2 = Angles.y() + y;
|
float x2 = tr.x + x, y2 = tr.y + y;
|
||||||
|
|
||||||
if(rect.width < 0){
|
if(rect.width < 0){
|
||||||
rect.x += rect.width;
|
rect.x += rect.width;
|
||||||
|
|||||||
@@ -3,21 +3,23 @@ package io.anuke.mindustry.entities.effect;
|
|||||||
import com.badlogic.gdx.graphics.Color;
|
import com.badlogic.gdx.graphics.Color;
|
||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
|
||||||
import io.anuke.mindustry.graphics.Fx;
|
import io.anuke.mindustry.graphics.Fx;
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
import io.anuke.mindustry.world.blocks.types.PowerAcceptor;
|
import io.anuke.mindustry.world.blocks.types.PowerAcceptor;
|
||||||
import io.anuke.ucore.graphics.Draw;
|
|
||||||
import io.anuke.ucore.core.Effects;
|
import io.anuke.ucore.core.Effects;
|
||||||
import io.anuke.ucore.entities.TimedEntity;
|
import io.anuke.ucore.entities.TimedEntity;
|
||||||
|
import io.anuke.ucore.graphics.Draw;
|
||||||
import io.anuke.ucore.graphics.Lines;
|
import io.anuke.ucore.graphics.Lines;
|
||||||
import io.anuke.ucore.util.Angles;
|
|
||||||
import io.anuke.ucore.util.Mathf;
|
import io.anuke.ucore.util.Mathf;
|
||||||
|
import io.anuke.ucore.util.Translator;
|
||||||
|
|
||||||
|
import static io.anuke.mindustry.Vars.tilesize;
|
||||||
|
import static io.anuke.mindustry.Vars.world;
|
||||||
|
|
||||||
public class EMP extends TimedEntity{
|
public class EMP extends TimedEntity{
|
||||||
static final int maxTargets = 8;
|
static final int maxTargets = 8;
|
||||||
static Array<Tile> array = new Array<>();
|
static Array<Tile> array = new Array<>();
|
||||||
|
static Translator tr = new Translator();
|
||||||
|
|
||||||
int radius = 4;
|
int radius = 4;
|
||||||
int damage = 6;
|
int damage = 6;
|
||||||
@@ -80,8 +82,8 @@ public class EMP extends TimedEntity{
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0; i < 14 - targets.size; i ++){
|
for(int i = 0; i < 14 - targets.size; i ++){
|
||||||
Angles.translation(Mathf.randomSeed(i + id*77)*360f, radius * tilesize);
|
tr.trns(Mathf.randomSeed(i + id*77)*360f, radius * tilesize);
|
||||||
drawLine(x + Angles.x(), y + Angles.y());
|
drawLine(x + tr.x, y + tr.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
Lines.stroke(fract()*2f);
|
Lines.stroke(fract()*2f);
|
||||||
|
|||||||
@@ -4,19 +4,18 @@ import com.badlogic.gdx.graphics.Color;
|
|||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
import com.badlogic.gdx.utils.ObjectSet;
|
import com.badlogic.gdx.utils.ObjectSet;
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
|
||||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||||
import io.anuke.mindustry.graphics.Fx;
|
import io.anuke.mindustry.graphics.Fx;
|
||||||
import io.anuke.ucore.graphics.Draw;
|
|
||||||
import io.anuke.ucore.core.Effects;
|
import io.anuke.ucore.core.Effects;
|
||||||
import io.anuke.ucore.core.Timers;
|
import io.anuke.ucore.core.Timers;
|
||||||
import io.anuke.ucore.entities.Entities;
|
import io.anuke.ucore.entities.Entities;
|
||||||
import io.anuke.ucore.entities.Entity;
|
import io.anuke.ucore.entities.Entity;
|
||||||
import io.anuke.ucore.entities.SolidEntity;
|
import io.anuke.ucore.entities.SolidEntity;
|
||||||
|
import io.anuke.ucore.graphics.Draw;
|
||||||
import io.anuke.ucore.graphics.Lines;
|
import io.anuke.ucore.graphics.Lines;
|
||||||
import io.anuke.ucore.util.Mathf;
|
import io.anuke.ucore.util.Mathf;
|
||||||
import io.anuke.ucore.util.Tmp;
|
|
||||||
|
import static io.anuke.mindustry.Vars.enemyGroup;
|
||||||
|
|
||||||
public class TeslaOrb extends Entity{
|
public class TeslaOrb extends Entity{
|
||||||
private Array<Vector2> points = new Array<>();
|
private Array<Vector2> points = new Array<>();
|
||||||
@@ -25,6 +24,7 @@ public class TeslaOrb extends Entity{
|
|||||||
private float range = 0;
|
private float range = 0;
|
||||||
private float lifetime = 30f;
|
private float lifetime = 30f;
|
||||||
private float life = 0f;
|
private float life = 0f;
|
||||||
|
private Vector2 vector = new Vector2();
|
||||||
|
|
||||||
public TeslaOrb(float x, float y, float range, int damage){
|
public TeslaOrb(float x, float y, float range, int damage){
|
||||||
set(x, y);
|
set(x, y);
|
||||||
@@ -83,7 +83,7 @@ public class TeslaOrb extends Entity{
|
|||||||
|
|
||||||
float range = 1f;
|
float range = 1f;
|
||||||
|
|
||||||
Vector2 previous = Tmp.v1.set(x, y);
|
Vector2 previous = vector.set(x, y);
|
||||||
|
|
||||||
for(Vector2 enemy : points){
|
for(Vector2 enemy : points){
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,18 @@
|
|||||||
package io.anuke.mindustry.entities.enemies;
|
package io.anuke.mindustry.entities.enemies;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
import com.badlogic.gdx.utils.TimeUtils;
|
|
||||||
import io.anuke.mindustry.entities.Bullet;
|
import io.anuke.mindustry.entities.Bullet;
|
||||||
import io.anuke.mindustry.entities.BulletType;
|
import io.anuke.mindustry.entities.BulletType;
|
||||||
import io.anuke.mindustry.entities.SyncEntity;
|
import io.anuke.mindustry.entities.SyncEntity;
|
||||||
import io.anuke.mindustry.net.Net;
|
import io.anuke.mindustry.net.Net;
|
||||||
import io.anuke.mindustry.net.NetEvents;
|
import io.anuke.mindustry.net.NetEvents;
|
||||||
import io.anuke.ucore.core.Timers;
|
|
||||||
import io.anuke.ucore.entities.Entity;
|
import io.anuke.ucore.entities.Entity;
|
||||||
import io.anuke.ucore.entities.SolidEntity;
|
import io.anuke.ucore.entities.SolidEntity;
|
||||||
import io.anuke.ucore.util.Angles;
|
import io.anuke.ucore.graphics.Draw;
|
||||||
import io.anuke.ucore.util.Mathf;
|
import io.anuke.ucore.util.Mathf;
|
||||||
import io.anuke.ucore.util.Timer;
|
import io.anuke.ucore.util.Timer;
|
||||||
import io.anuke.ucore.util.Tmp;
|
import io.anuke.ucore.util.Translator;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
@@ -30,12 +29,15 @@ public class Enemy extends SyncEntity {
|
|||||||
public Enemy spawner;
|
public Enemy spawner;
|
||||||
public int spawned;
|
public int spawned;
|
||||||
|
|
||||||
public float angle;
|
|
||||||
public Vector2 velocity = new Vector2();
|
public Vector2 velocity = new Vector2();
|
||||||
|
public Vector2 totalMove = new Vector2();
|
||||||
|
public Vector2 tpos = new Vector2(-999, -999);
|
||||||
public Entity target;
|
public Entity target;
|
||||||
public float hitTime;
|
public float hitTime;
|
||||||
public int tier = 1;
|
public int tier = 1;
|
||||||
public Vector2 totalMove = new Vector2();
|
|
||||||
|
public TextureRegion region;
|
||||||
|
public Translator tr = new Translator();
|
||||||
|
|
||||||
public Enemy(EnemyType type){
|
public Enemy(EnemyType type){
|
||||||
this.type = type;
|
this.type = type;
|
||||||
@@ -50,7 +52,7 @@ public class Enemy extends SyncEntity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(){
|
public void drawSmooth(){
|
||||||
type.draw(this);
|
type.draw(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,6 +92,7 @@ public class Enemy extends SyncEntity {
|
|||||||
hitbox.setSize(type.hitsize);
|
hitbox.setSize(type.hitsize);
|
||||||
hitboxTile.setSize(type.hitsizeTile);
|
hitboxTile.setSize(type.hitsizeTile);
|
||||||
maxhealth = type.health * tier;
|
maxhealth = type.health * tier;
|
||||||
|
region = Draw.region(type.name + "-t" + Mathf.clamp(tier, 1, 3));
|
||||||
|
|
||||||
heal();
|
heal();
|
||||||
}
|
}
|
||||||
@@ -138,25 +141,7 @@ public class Enemy extends SyncEntity {
|
|||||||
|
|
||||||
this.health = health;
|
this.health = health;
|
||||||
|
|
||||||
interpolator.targetrot = angle / 2f;
|
interpolator.read(this.x, this.y, x, y, angle, time);
|
||||||
interpolator.time = 0f;
|
|
||||||
interpolator.last.set(this.x, this.y);
|
|
||||||
interpolator.target.set(x, y);
|
|
||||||
interpolator.spacing = Math.min(Math.max(((TimeUtils.timeSinceMillis(time) / 1000f) * 60f), 4f), 10f);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void interpolate() {
|
|
||||||
Interpolator i = interpolator;
|
|
||||||
|
|
||||||
i.time += 1f / i.spacing * Timers.delta();
|
|
||||||
|
|
||||||
Mathf.lerp2(Tmp.v2.set(i.last), i.target, i.time);
|
|
||||||
|
|
||||||
x = Tmp.v2.x;
|
|
||||||
y = Tmp.v2.y;
|
|
||||||
|
|
||||||
angle = Mathf.lerpAngDelta(angle, i.targetrot, 0.6f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void shoot(BulletType bullet){
|
public void shoot(BulletType bullet){
|
||||||
@@ -166,13 +151,13 @@ public class Enemy extends SyncEntity {
|
|||||||
public void shoot(BulletType bullet, float rotation){
|
public void shoot(BulletType bullet, float rotation){
|
||||||
|
|
||||||
if(!(Net.client())) {
|
if(!(Net.client())) {
|
||||||
Angles.translation(angle + rotation, type.length);
|
tr.trns(angle + rotation, type.length);
|
||||||
Bullet out = new Bullet(bullet, this, x + Angles.x(), y + Angles.y(), this.angle + rotation).add();
|
Bullet out = new Bullet(bullet, this, x + tr.x, y + tr.y, this.angle + rotation).add();
|
||||||
out.damage = (int) ((bullet.damage * (1 + (tier - 1) * 1f)));
|
out.damage = (int) ((bullet.damage * (1 + (tier - 1) * 1f)));
|
||||||
type.onShoot(this, bullet, rotation);
|
type.onShoot(this, bullet, rotation);
|
||||||
|
|
||||||
if(Net.server()){
|
if(Net.server()){
|
||||||
NetEvents.handleBullet(bullet, this, x + Angles.x(), y + Angles.y(), this.angle + rotation, (short)out.damage);
|
NetEvents.handleBullet(bullet, this, x + tr.x, y + tr.y, this.angle + rotation, (short)out.damage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import io.anuke.ucore.entities.Entities;
|
|||||||
import io.anuke.ucore.graphics.Draw;
|
import io.anuke.ucore.graphics.Draw;
|
||||||
import io.anuke.ucore.util.Mathf;
|
import io.anuke.ucore.util.Mathf;
|
||||||
import io.anuke.ucore.util.Strings;
|
import io.anuke.ucore.util.Strings;
|
||||||
import io.anuke.ucore.util.Tmp;
|
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
|
|
||||||
@@ -60,6 +59,10 @@ public class EnemyType {
|
|||||||
protected final int timerReload = timeid ++;
|
protected final int timerReload = timeid ++;
|
||||||
protected final int timerReset = timeid ++;
|
protected final int timerReset = timeid ++;
|
||||||
|
|
||||||
|
protected final Vector2 shift = new Vector2();
|
||||||
|
protected final Vector2 move = new Vector2();
|
||||||
|
protected final Vector2 calc = new Vector2();
|
||||||
|
|
||||||
public EnemyType(String name){
|
public EnemyType(String name){
|
||||||
this.id = lastid++;
|
this.id = lastid++;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
@@ -67,15 +70,13 @@ public class EnemyType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void draw(Enemy enemy){
|
public void draw(Enemy enemy){
|
||||||
String region = name + "-t" + Mathf.clamp(enemy.tier, 1, 3);
|
|
||||||
|
|
||||||
Shaders.outline.color.set(tierColors[enemy.tier - 1]);
|
Shaders.outline.color.set(tierColors[enemy.tier - 1]);
|
||||||
Shaders.outline.lighten = Mathf.clamp(enemy.hitTime/hitDuration);
|
Shaders.outline.lighten = Mathf.clamp(enemy.hitTime/hitDuration);
|
||||||
Shaders.outline.region = Draw.region(region);
|
Shaders.outline.region = enemy.region;
|
||||||
|
|
||||||
Shaders.outline.apply();
|
Shaders.outline.apply();
|
||||||
|
|
||||||
Draw.rect(region, enemy.x, enemy.y, enemy.angle - 90);
|
Draw.rect(enemy.region, enemy.x, enemy.y, enemy.angle - 90);
|
||||||
Draw.color();
|
Draw.color();
|
||||||
|
|
||||||
Graphics.flush();
|
Graphics.flush();
|
||||||
@@ -160,14 +161,14 @@ public class EnemyType {
|
|||||||
Vector2 vec;
|
Vector2 vec;
|
||||||
|
|
||||||
if(nearCore){
|
if(nearCore){
|
||||||
vec = Tmp.v1.setZero();
|
vec = move.setZero();
|
||||||
if(targetCore) enemy.target = core.entity;
|
if(targetCore) enemy.target = core.entity;
|
||||||
}else{
|
}else{
|
||||||
vec = world.pathfinder().find(enemy);
|
vec = world.pathfinder().find(enemy);
|
||||||
vec.sub(enemy.x, enemy.y).limit(speed);
|
vec.sub(enemy.x, enemy.y).limit(speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2 shift = Tmp.v3.setZero();
|
shift.setZero();
|
||||||
float shiftRange = enemy.hitbox.width + 2f;
|
float shiftRange = enemy.hitbox.width + 2f;
|
||||||
float avoidRange = shiftRange + 4f;
|
float avoidRange = shiftRange + 4f;
|
||||||
float attractRange = avoidRange + 7f;
|
float attractRange = avoidRange + 7f;
|
||||||
@@ -182,11 +183,11 @@ public class EnemyType {
|
|||||||
float scl = Mathf.clamp(1.4f - dst / shiftRange) * mass * 1f/mass;
|
float scl = Mathf.clamp(1.4f - dst / shiftRange) * mass * 1f/mass;
|
||||||
shift.add((enemy.x - other.x) * scl, (enemy.y - other.y) * scl);
|
shift.add((enemy.x - other.x) * scl, (enemy.y - other.y) * scl);
|
||||||
}else if(dst < avoidRange){
|
}else if(dst < avoidRange){
|
||||||
Tmp.v2.set((enemy.x - other.x), (enemy.y - other.y)).setLength(avoidSpeed);
|
calc.set((enemy.x - other.x), (enemy.y - other.y)).setLength(avoidSpeed);
|
||||||
shift.add(Tmp.v2.scl(1.1f));
|
shift.add(calc.scl(1.1f));
|
||||||
}else if(dst < attractRange && !nearCore){
|
}else if(dst < attractRange && !nearCore){
|
||||||
Tmp.v2.set((enemy.x - other.x), (enemy.y - other.y)).setLength(avoidSpeed);
|
calc.set((enemy.x - other.x), (enemy.y - other.y)).setLength(avoidSpeed);
|
||||||
shift.add(Tmp.v2.scl(-1));
|
shift.add(calc.scl(-1));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
package io.anuke.mindustry.entities.enemies.types;
|
package io.anuke.mindustry.entities.enemies.types;
|
||||||
|
|
||||||
import com.badlogic.gdx.math.Vector2;
|
|
||||||
import io.anuke.mindustry.entities.Bullet;
|
import io.anuke.mindustry.entities.Bullet;
|
||||||
import io.anuke.mindustry.entities.BulletType;
|
import io.anuke.mindustry.entities.BulletType;
|
||||||
import io.anuke.mindustry.entities.TileEntity;
|
import io.anuke.mindustry.entities.TileEntity;
|
||||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||||
import io.anuke.mindustry.entities.enemies.EnemyType;
|
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||||
import io.anuke.ucore.util.Tmp;
|
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.tilesize;
|
import static io.anuke.mindustry.Vars.tilesize;
|
||||||
|
|
||||||
@@ -26,15 +24,16 @@ public class BlastType extends EnemyType {
|
|||||||
public void behavior(Enemy enemy){
|
public void behavior(Enemy enemy){
|
||||||
|
|
||||||
float range = 10f;
|
float range = 10f;
|
||||||
Vector2 offset = Tmp.v3.setZero();
|
float ox = 0, oy = 0;
|
||||||
|
|
||||||
if(enemy.target instanceof TileEntity){
|
if(enemy.target instanceof TileEntity){
|
||||||
TileEntity e = (TileEntity)enemy.target;
|
TileEntity e = (TileEntity)enemy.target;
|
||||||
range = (e.tile.block().width * tilesize) /2f + 8f;
|
range = (e.tile.block().width * tilesize) /2f + 8f;
|
||||||
offset.set(e.tile.block().getPlaceOffset());
|
ox = e.tile.block().getPlaceOffset().x;
|
||||||
|
oy = e.tile.block().getPlaceOffset().y;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(enemy.target != null && enemy.target.distanceTo(enemy.x - offset.x, enemy.y - offset.y) < range){
|
if(enemy.target != null && enemy.target.distanceTo(enemy.x - ox, enemy.y - oy) < range){
|
||||||
explode(enemy);
|
explode(enemy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,13 +35,13 @@ public class FortressType extends EnemyType {
|
|||||||
world.getCore().worldy()) <= 90f){
|
world.getCore().worldy()) <= 90f){
|
||||||
|
|
||||||
if(Timers.get(this, "spawn", spawnTime) && enemy.spawned < maxSpawn){
|
if(Timers.get(this, "spawn", spawnTime) && enemy.spawned < maxSpawn){
|
||||||
Angles.translation(enemy.angle, 20f);
|
enemy.tr.trns(enemy.angle, 20f);
|
||||||
|
|
||||||
Enemy s = new Enemy(EnemyTypes.fast);
|
Enemy s = new Enemy(EnemyTypes.fast);
|
||||||
s.lane = enemy.lane;
|
s.lane = enemy.lane;
|
||||||
s.tier = enemy.tier;
|
s.tier = enemy.tier;
|
||||||
s.spawner = enemy;
|
s.spawner = enemy;
|
||||||
s.set(enemy.x + Angles.x(), enemy.y + Angles.y());
|
s.set(enemy.x + enemy.tr.x, enemy.y + enemy.tr.y);
|
||||||
s.add();
|
s.add();
|
||||||
|
|
||||||
Effects.effect(Fx.spawn, enemy);
|
Effects.effect(Fx.spawn, enemy);
|
||||||
@@ -53,7 +53,7 @@ public class FortressType extends EnemyType {
|
|||||||
|
|
||||||
|
|
||||||
public void onShoot(Enemy enemy, BulletType type, float rotation){
|
public void onShoot(Enemy enemy, BulletType type, float rotation){
|
||||||
Effects.effect(Fx.largeCannonShot, enemy.x + Angles.x(), enemy.y + Angles.y(), enemy.angle);
|
Effects.effect(Fx.largeCannonShot, enemy.x + enemy.tr.x, enemy.y + enemy.tr.y, enemy.angle);
|
||||||
Effects.shake(3f, 3f, enemy);
|
Effects.shake(3f, 3f, enemy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ public class HealerType extends EnemyType {
|
|||||||
|
|
||||||
if(target == null) return;
|
if(target == null) return;
|
||||||
|
|
||||||
Angles.translation(enemy.angleTo(target), 5f);
|
enemy.tr.trns(enemy.angleTo(target), 5f);
|
||||||
|
|
||||||
Shaders.outline.color.set(Color.CLEAR);
|
Shaders.outline.color.set(Color.CLEAR);
|
||||||
Shaders.outline.apply();
|
Shaders.outline.apply();
|
||||||
@@ -82,7 +82,7 @@ public class HealerType extends EnemyType {
|
|||||||
if(target.health < target.maxhealth){
|
if(target.health < target.maxhealth){
|
||||||
Draw.color(Hue.rgb(138, 244, 138, (MathUtils.sin(Timers.time()) + 1f) / 13f));
|
Draw.color(Hue.rgb(138, 244, 138, (MathUtils.sin(Timers.time()) + 1f) / 13f));
|
||||||
Draw.alpha(0.9f);
|
Draw.alpha(0.9f);
|
||||||
Shapes.laser("laser", "laserend", enemy.x + Angles.x(), enemy.y + Angles.y(), target.x - Angles.x()/1.5f, target.y - Angles.y()/1.5f);
|
Shapes.laser("laser", "laserend", enemy.x + enemy.tr.x, enemy.y + enemy.tr.y, target.x - enemy.tr.x/1.5f, target.y - enemy.tr.y/1.5f);
|
||||||
Draw.color();
|
Draw.color();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,17 +17,14 @@ public class TankType extends EnemyType {
|
|||||||
bullet = BulletType.small;
|
bullet = BulletType.small;
|
||||||
length = 3f;
|
length = 3f;
|
||||||
mass = 1.4f;
|
mass = 1.4f;
|
||||||
|
length = 8f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void shoot(Enemy enemy){
|
public void shoot(Enemy enemy){
|
||||||
super.shoot(enemy);
|
super.shoot(enemy);
|
||||||
|
|
||||||
Angles.translation(enemy.angle, 8f);
|
Angles.shotgun(3, 8f, enemy.angle, f -> enemy.shoot(bullet, f));
|
||||||
|
|
||||||
Angles.shotgun(3, 8f, enemy.angle, f -> {
|
|
||||||
enemy.shoot(bullet, f);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,16 +7,16 @@ public enum GameMode{
|
|||||||
sandbox{
|
sandbox{
|
||||||
{
|
{
|
||||||
infiniteResources = true;
|
infiniteResources = true;
|
||||||
toggleWaves = true;
|
disableWaveTimer = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
freebuild{
|
freebuild{
|
||||||
{
|
{
|
||||||
toggleWaves = true;
|
disableWaveTimer = true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
public boolean infiniteResources;
|
public boolean infiniteResources;
|
||||||
public boolean toggleWaves;
|
public boolean disableWaveTimer;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString(){
|
public String toString(){
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
package io.anuke.mindustry.graphics;
|
package io.anuke.mindustry.graphics;
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.Color;
|
import com.badlogic.gdx.graphics.Color;
|
||||||
|
import com.badlogic.gdx.math.Vector2;
|
||||||
import com.badlogic.gdx.utils.FloatArray;
|
import com.badlogic.gdx.utils.FloatArray;
|
||||||
|
|
||||||
import io.anuke.ucore.core.Core;
|
import io.anuke.ucore.core.Core;
|
||||||
import io.anuke.ucore.core.Settings;
|
import io.anuke.ucore.core.Settings;
|
||||||
import io.anuke.ucore.core.Timers;
|
import io.anuke.ucore.core.Timers;
|
||||||
import io.anuke.ucore.graphics.Shader;
|
import io.anuke.ucore.graphics.Shader;
|
||||||
import io.anuke.ucore.scene.ui.layout.Unit;
|
import io.anuke.ucore.scene.ui.layout.Unit;
|
||||||
import io.anuke.ucore.util.Tmp;
|
|
||||||
|
|
||||||
public class Shaders{
|
public class Shaders{
|
||||||
public static final Outline outline = new Outline();
|
public static final Outline outline = new Outline();
|
||||||
public static final Shield shield = new Shield();
|
public static final Shield shield = new Shield();
|
||||||
|
|
||||||
|
private static final Vector2 vec = new Vector2();
|
||||||
|
|
||||||
public static class Outline extends Shader{
|
public static class Outline extends Shader{
|
||||||
public Color color = new Color();
|
public Color color = new Color();
|
||||||
@@ -26,7 +27,7 @@ public class Shaders{
|
|||||||
public void apply(){
|
public void apply(){
|
||||||
shader.setUniformf("u_color", color);
|
shader.setUniformf("u_color", color);
|
||||||
shader.setUniformf("u_lighten", lighten);
|
shader.setUniformf("u_lighten", lighten);
|
||||||
shader.setUniformf("u_texsize", Tmp.v1.set(region.getTexture().getWidth(), region.getTexture().getHeight()));
|
shader.setUniformf("u_texsize", vec.set(region.getTexture().getWidth(), region.getTexture().getHeight()));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -52,8 +53,8 @@ public class Shaders{
|
|||||||
shader.setUniformf("u_color", color);
|
shader.setUniformf("u_color", color);
|
||||||
shader.setUniformf("u_time", Timers.time() / Unit.dp.scl(1f));
|
shader.setUniformf("u_time", Timers.time() / Unit.dp.scl(1f));
|
||||||
shader.setUniformf("u_scaling", scaling);
|
shader.setUniformf("u_scaling", scaling);
|
||||||
shader.setUniformf("u_offset", Tmp.v1.set(Core.camera.position.x, Core.camera.position.y));
|
shader.setUniformf("u_offset", vec.set(Core.camera.position.x, Core.camera.position.y));
|
||||||
shader.setUniformf("u_texsize", Tmp.v1.set(region.getTexture().getWidth() / scale,
|
shader.setUniformf("u_texsize", vec.set(region.getTexture().getWidth() / scale,
|
||||||
region.getTexture().getHeight() / scale));
|
region.getTexture().getHeight() / scale));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import io.anuke.ucore.core.Sounds;
|
|||||||
import io.anuke.ucore.entities.Entities;
|
import io.anuke.ucore.entities.Entities;
|
||||||
import io.anuke.ucore.entities.SolidEntity;
|
import io.anuke.ucore.entities.SolidEntity;
|
||||||
import io.anuke.ucore.util.Mathf;
|
import io.anuke.ucore.util.Mathf;
|
||||||
import io.anuke.ucore.util.Tmp;
|
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
|
|
||||||
@@ -36,6 +35,8 @@ public abstract class InputHandler extends InputAdapter{
|
|||||||
public PlaceMode lastPlaceMode = placeMode;
|
public PlaceMode lastPlaceMode = placeMode;
|
||||||
public PlaceMode lastBreakMode = breakMode;
|
public PlaceMode lastBreakMode = breakMode;
|
||||||
|
|
||||||
|
private Rectangle rect = new Rectangle();
|
||||||
|
|
||||||
public abstract void update();
|
public abstract void update();
|
||||||
public abstract float getCursorX();
|
public abstract float getCursorX();
|
||||||
public abstract float getCursorY();
|
public abstract float getCursorY();
|
||||||
@@ -93,21 +94,21 @@ public abstract class InputHandler extends InputAdapter{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Tmp.r2.setSize(type.width * tilesize, type.height * tilesize);
|
rect.setSize(type.width * tilesize, type.height * tilesize);
|
||||||
Vector2 offset = type.getPlaceOffset();
|
Vector2 offset = type.getPlaceOffset();
|
||||||
Tmp.r2.setCenter(offset.x + x * tilesize, offset.y + y * tilesize);
|
rect.setCenter(offset.x + x * tilesize, offset.y + y * tilesize);
|
||||||
|
|
||||||
for(SolidEntity e : Entities.getNearby(enemyGroup, x * tilesize, y * tilesize, tilesize * 2f)){
|
for(SolidEntity e : Entities.getNearby(enemyGroup, x * tilesize, y * tilesize, tilesize * 2f)){
|
||||||
Rectangle rect = e.hitbox.getRect(e.x, e.y);
|
Rectangle rect = e.hitbox.getRect(e.x, e.y);
|
||||||
|
|
||||||
if(Tmp.r2.overlaps(rect)){
|
if(this.rect.overlaps(rect)){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(type.solid || type.solidifes) {
|
if(type.solid || type.solidifes) {
|
||||||
for (Player player : playerGroup.all()) {
|
for (Player player : playerGroup.all()) {
|
||||||
if (!player.isAndroid && Tmp.r2.overlaps(player.hitbox.getRect(player.x, player.y))) {
|
if (!player.isAndroid && rect.overlaps(player.hitbox.getRect(player.x, player.y))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -138,14 +139,14 @@ public abstract class InputHandler extends InputAdapter{
|
|||||||
for(int dx = 0; dx < type.width; dx ++){
|
for(int dx = 0; dx < type.width; dx ++){
|
||||||
for(int dy = 0; dy < type.height; dy ++){
|
for(int dy = 0; dy < type.height; dy ++){
|
||||||
Tile other = world.tile(x + dx + offsetx, y + dy + offsety);
|
Tile other = world.tile(x + dx + offsetx, y + dy + offsety);
|
||||||
if(other == null || other.block() != Blocks.air || isSpawnPoint(other)){
|
if(other == null || (other.block() != Blocks.air && !other.block().alwaysReplace) || isSpawnPoint(other)){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}else{
|
}else{
|
||||||
if(tile.block() != type && type.canReplace(tile.block()) && tile.block().isMultiblock() == type.isMultiblock()){
|
if(tile.block() != type && (type.canReplace(tile.block()) || tile.block().alwaysReplace) && tile.block().isMultiblock() == type.isMultiblock()){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return tile.block() == Blocks.air;
|
return tile.block() == Blocks.air;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import io.anuke.ucore.graphics.Draw;
|
|||||||
import io.anuke.ucore.graphics.Lines;
|
import io.anuke.ucore.graphics.Lines;
|
||||||
import io.anuke.ucore.util.Bundles;
|
import io.anuke.ucore.util.Bundles;
|
||||||
import io.anuke.ucore.util.Mathf;
|
import io.anuke.ucore.util.Mathf;
|
||||||
import io.anuke.ucore.util.Tmp;
|
import io.anuke.ucore.util.Translator;
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
|
|
||||||
@@ -44,8 +44,8 @@ public enum PlaceMode{
|
|||||||
|
|
||||||
if(control.input().recipe.result.rotate){
|
if(control.input().recipe.result.rotate){
|
||||||
Draw.color(Colors.get("placeRotate"));
|
Draw.color(Colors.get("placeRotate"));
|
||||||
Tmp.v1.set(7, 0).rotate(control.input().rotation * 90);
|
tr.trns(control.input().rotation * 90, 7, 0);
|
||||||
Lines.line(x, y, x + Tmp.v1.x, y + Tmp.v1.y);
|
Lines.line(x, y, x + tr.x, y + tr.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,8 +293,8 @@ public enum PlaceMode{
|
|||||||
if(control.input().recipe.result.rotate){
|
if(control.input().recipe.result.rotate){
|
||||||
float cx = tx * t, cy = ty * t;
|
float cx = tx * t, cy = ty * t;
|
||||||
Draw.color(Colors.get("placeRotate"));
|
Draw.color(Colors.get("placeRotate"));
|
||||||
Tmp.v1.set(7, 0).rotate(rotation * 90);
|
tr.trns(rotation * 90, 7, 0);
|
||||||
Lines.line(cx, cy, cx + Tmp.v1.x, cy + Tmp.v1.y);
|
Lines.line(cx, cy, cx + tr.x, cy + tr.y);
|
||||||
}
|
}
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
}
|
}
|
||||||
@@ -368,6 +368,8 @@ public enum PlaceMode{
|
|||||||
public boolean showCancel;
|
public boolean showCancel;
|
||||||
public boolean delete = false;
|
public boolean delete = false;
|
||||||
public boolean both = false;
|
public boolean both = false;
|
||||||
|
|
||||||
|
private static final Translator tr = new Translator();
|
||||||
|
|
||||||
public void draw(int tilex, int tiley, int endx, int endy){
|
public void draw(int tilex, int tiley, int endx, int endy){
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package io.anuke.mindustry.io;
|
package io.anuke.mindustry.io;
|
||||||
|
|
||||||
|
import io.anuke.mindustry.core.ThreadHandler.ThreadProvider;
|
||||||
import io.anuke.ucore.scene.ui.TextField;
|
import io.anuke.ucore.scene.ui.TextField;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@@ -27,4 +28,27 @@ public abstract class Platform {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
public boolean isDebug(){return false;}
|
public boolean isDebug(){return false;}
|
||||||
|
public ThreadProvider getThreadProvider(){
|
||||||
|
return new ThreadProvider() {
|
||||||
|
@Override
|
||||||
|
public boolean isOnThread() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sleep(long ms) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start(Runnable run) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stop() {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import com.badlogic.gdx.input.GestureDetector;
|
|||||||
import com.badlogic.gdx.input.GestureDetector.GestureListener;
|
import com.badlogic.gdx.input.GestureDetector.GestureListener;
|
||||||
import com.badlogic.gdx.math.Bresenham2;
|
import com.badlogic.gdx.math.Bresenham2;
|
||||||
import com.badlogic.gdx.math.GridPoint2;
|
import com.badlogic.gdx.math.GridPoint2;
|
||||||
|
import com.badlogic.gdx.math.Rectangle;
|
||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
import com.badlogic.gdx.scenes.scene2d.utils.ScissorStack;
|
import com.badlogic.gdx.scenes.scene2d.utils.ScissorStack;
|
||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
@@ -43,6 +44,8 @@ public class MapView extends Element implements GestureListener{
|
|||||||
private float zoom = 1f;
|
private float zoom = 1f;
|
||||||
private boolean grid = false;
|
private boolean grid = false;
|
||||||
private GridImage image = new GridImage(0, 0);
|
private GridImage image = new GridImage(0, 0);
|
||||||
|
private Vector2 vec = new Vector2();
|
||||||
|
private Rectangle rect = new Rectangle();
|
||||||
|
|
||||||
private boolean drawing;
|
private boolean drawing;
|
||||||
private int lastx, lasty;
|
private int lastx, lasty;
|
||||||
@@ -214,7 +217,7 @@ public class MapView extends Element implements GestureListener{
|
|||||||
float px = ((float)x / editor.texture().getWidth()) * sclwidth + offsetx*zoom - sclwidth/2 + getWidth()/2;
|
float px = ((float)x / editor.texture().getWidth()) * sclwidth + offsetx*zoom - sclwidth/2 + getWidth()/2;
|
||||||
float py = (float)((float)(editor.texture().getHeight() - 1 - y) / editor.texture().getHeight()) * sclheight
|
float py = (float)((float)(editor.texture().getHeight() - 1 - y) / editor.texture().getHeight()) * sclheight
|
||||||
+ offsety*zoom - sclheight/2 + getHeight()/2;
|
+ offsety*zoom - sclheight/2 + getHeight()/2;
|
||||||
return Tmp.v1.set(px, py);
|
return vec.set(px, py);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -229,7 +232,7 @@ public class MapView extends Element implements GestureListener{
|
|||||||
image.setImageSize(editor.pixmap().getWidth(), editor.pixmap().getHeight());
|
image.setImageSize(editor.pixmap().getWidth(), editor.pixmap().getHeight());
|
||||||
|
|
||||||
batch.flush();
|
batch.flush();
|
||||||
boolean pop = ScissorStack.pushScissors(Tmp.r1.set(x + width/2 - size/2, y + height/2 - size/2, size, size));
|
boolean pop = ScissorStack.pushScissors(rect.set(x + width/2 - size/2, y + height/2 - size/2, size, size));
|
||||||
|
|
||||||
batch.draw(editor.texture(), centerx - sclwidth/2, centery - sclheight/2, sclwidth, sclheight);
|
batch.draw(editor.texture(), centerx - sclwidth/2, centery - sclheight/2, sclwidth, sclheight);
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import java.io.IOException;
|
|||||||
import static io.anuke.mindustry.Vars.*;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
|
|
||||||
public class Net{
|
public class Net{
|
||||||
public static final int version = 19;
|
public static final int version = 20;
|
||||||
|
|
||||||
private static boolean server;
|
private static boolean server;
|
||||||
private static boolean active;
|
private static boolean active;
|
||||||
|
|||||||
@@ -508,15 +508,15 @@ public class Packets {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(ByteBuffer buffer) {
|
public void write(ByteBuffer buffer) {
|
||||||
buffer.putInt(position);
|
buffer.putInt((rotation) | (position << 2));
|
||||||
buffer.put(rotation);
|
|
||||||
buffer.put(itemid);
|
buffer.put(itemid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void read(ByteBuffer buffer) {
|
public void read(ByteBuffer buffer) {
|
||||||
position = buffer.getInt();
|
int i = buffer.getInt();
|
||||||
rotation = buffer.get();
|
rotation = (byte)(i & 0x3);
|
||||||
|
position = i >> 2;
|
||||||
itemid = buffer.get();
|
itemid = buffer.get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import io.anuke.ucore.core.Timers;
|
|||||||
import io.anuke.ucore.entities.Entity;
|
import io.anuke.ucore.entities.Entity;
|
||||||
import io.anuke.ucore.util.Angles;
|
import io.anuke.ucore.util.Angles;
|
||||||
import io.anuke.ucore.util.Mathf;
|
import io.anuke.ucore.util.Mathf;
|
||||||
|
import io.anuke.ucore.util.Translator;
|
||||||
|
|
||||||
public class Weapon extends Upgrade{
|
public class Weapon extends Upgrade{
|
||||||
public static final Weapon
|
public static final Weapon
|
||||||
@@ -87,6 +88,8 @@ public class Weapon extends Upgrade{
|
|||||||
float length = 3f;
|
float length = 3f;
|
||||||
/**whether to shoot the weapons in different arms one after another, rather an all at once*/
|
/**whether to shoot the weapons in different arms one after another, rather an all at once*/
|
||||||
boolean roundrobin = false;
|
boolean roundrobin = false;
|
||||||
|
/**translator for vector calulations*/
|
||||||
|
Translator tr = new Translator();
|
||||||
|
|
||||||
private Weapon(String name, float reload, BulletType type){
|
private Weapon(String name, float reload, BulletType type){
|
||||||
super(name);
|
super(name);
|
||||||
@@ -100,15 +103,15 @@ public class Weapon extends Upgrade{
|
|||||||
Timers.reset(p, "reload" + !left, reload/2f);
|
Timers.reset(p, "reload" + !left, reload/2f);
|
||||||
}
|
}
|
||||||
float ang = Angles.mouseAngle(p.x, p.y);
|
float ang = Angles.mouseAngle(p.x, p.y);
|
||||||
Angles.vector.set(3f * Mathf.sign(left), length).rotate(ang - 90);
|
tr.trns(ang - 90, 3f * Mathf.sign(left), length);
|
||||||
shoot(p, p.x + Angles.x(), p.y + Angles.y(), Angles.mouseAngle(p.x + Angles.x(), p.y + Angles.y()));
|
shoot(p, p.x + tr.x, p.y + tr.y, Angles.mouseAngle(p.x + tr.x, p.y + tr.y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void shootInternal(Player p, float x, float y, float rotation){
|
void shootInternal(Player p, float x, float y, float rotation){
|
||||||
Angles.shotgun(shots, spacing, rotation, f -> bullet(p, x, y, f + Mathf.range(inaccuracy)));
|
Angles.shotgun(shots, spacing, rotation, f -> bullet(p, x, y, f + Mathf.range(inaccuracy)));
|
||||||
Angles.translation(rotation, 3f);
|
tr.trns(rotation, 3f);
|
||||||
if(effect != null) Effects.effect(effect, x + Angles.x(), y + Angles.y(), rotation);
|
if(effect != null) Effects.effect(effect, x + tr.x, y + tr.y, rotation);
|
||||||
Effects.shake(shake, shake, x, y);
|
Effects.shake(shake, shake, x, y);
|
||||||
Effects.sound(shootsound, x, y);
|
Effects.sound(shootsound, x, y);
|
||||||
}
|
}
|
||||||
@@ -122,7 +125,7 @@ public class Weapon extends Upgrade{
|
|||||||
}
|
}
|
||||||
|
|
||||||
void bullet(Entity owner, float x, float y, float angle){
|
void bullet(Entity owner, float x, float y, float angle){
|
||||||
Angles.translation(angle, 3f);
|
tr.trns(angle, 3f);
|
||||||
new Bullet(type, owner, x + Angles.x(), y + Angles.y(), angle).add();
|
new Bullet(type, owner, x + tr.x, y + tr.y, angle).add();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package io.anuke.mindustry.ui.dialogs;
|
package io.anuke.mindustry.ui.dialogs;
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||||
|
import com.badlogic.gdx.math.Vector2;
|
||||||
import io.anuke.mindustry.game.Difficulty;
|
import io.anuke.mindustry.game.Difficulty;
|
||||||
import io.anuke.mindustry.game.GameMode;
|
import io.anuke.mindustry.game.GameMode;
|
||||||
import io.anuke.mindustry.world.Map;
|
import io.anuke.mindustry.world.Map;
|
||||||
@@ -16,7 +17,6 @@ import io.anuke.ucore.scene.ui.layout.Table;
|
|||||||
import io.anuke.ucore.scene.utils.Elements;
|
import io.anuke.ucore.scene.utils.Elements;
|
||||||
import io.anuke.ucore.util.Bundles;
|
import io.anuke.ucore.util.Bundles;
|
||||||
import io.anuke.ucore.util.Mathf;
|
import io.anuke.ucore.util.Mathf;
|
||||||
import io.anuke.ucore.util.Tmp;
|
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
|
|
||||||
@@ -133,13 +133,15 @@ public class LevelDialog extends FloatingDialog{
|
|||||||
});
|
});
|
||||||
}).width(images+16).padBottom(-10f).grow().get();
|
}).width(images+16).padBottom(-10f).grow().get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vector2 hit = new Vector2();
|
||||||
|
|
||||||
image.addListener(new ClickListener(){
|
image.addListener(new ClickListener(){
|
||||||
public void clicked(InputEvent event, float x, float y){
|
public void clicked(InputEvent event, float x, float y){
|
||||||
image.localToStageCoordinates(Tmp.v1.set(x, y));
|
image.localToStageCoordinates(hit.set(x, y));
|
||||||
if(delete[0] != null && (delete[0].getClickListener().isOver() || delete[0].getClickListener().isPressed()
|
if(delete[0] != null && (delete[0].getClickListener().isOver() || delete[0].getClickListener().isPressed()
|
||||||
|| (Core.scene.hit(Tmp.v1.x, Tmp.v1.y, true) != null &&
|
|| (Core.scene.hit(hit.x, hit.y, true) != null &&
|
||||||
Core.scene.hit(Tmp.v1.x, Tmp.v1.y, true).isDescendantOf(delete[0])))){
|
Core.scene.hit(hit.x, hit.y, true).isDescendantOf(delete[0])))){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -113,6 +113,14 @@ public class SettingsMenuDialog extends SettingsDialog{
|
|||||||
game.sliderPref("sensitivity", 100, 10, 300, i -> i + "%");
|
game.sliderPref("sensitivity", 100, 10, 300, i -> i + "%");
|
||||||
game.sliderPref("saveinterval", 90, 10, 5*120, i -> Bundles.format("setting.seconds", i));
|
game.sliderPref("saveinterval", 90, 10, 5*120, i -> Bundles.format("setting.seconds", i));
|
||||||
|
|
||||||
|
if(!gwt){
|
||||||
|
graphics.checkPref("multithread", false, threads::setEnabled);
|
||||||
|
|
||||||
|
if(Settings.getBool("multithread")){
|
||||||
|
threads.setEnabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(!android && !gwt) {
|
if(!android && !gwt) {
|
||||||
graphics.checkPref("vsync", true, b -> Gdx.graphics.setVSync(b));
|
graphics.checkPref("vsync", true, b -> Gdx.graphics.setVSync(b));
|
||||||
graphics.checkPref("fullscreen", false, b -> {
|
graphics.checkPref("fullscreen", false, b -> {
|
||||||
@@ -128,6 +136,7 @@ public class SettingsMenuDialog extends SettingsDialog{
|
|||||||
Gdx.graphics.setFullscreenMode(Gdx.graphics.getDisplayMode());
|
Gdx.graphics.setFullscreenMode(Gdx.graphics.getDisplayMode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
graphics.checkPref("fps", false);
|
graphics.checkPref("fps", false);
|
||||||
graphics.checkPref("lasers", true);
|
graphics.checkPref("lasers", true);
|
||||||
graphics.checkPref("indicators", true);
|
graphics.checkPref("indicators", true);
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package io.anuke.mindustry.ui.fragments;
|
|||||||
|
|
||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
import com.badlogic.gdx.files.FileHandle;
|
import com.badlogic.gdx.files.FileHandle;
|
||||||
import io.anuke.mindustry.Vars;
|
|
||||||
import io.anuke.mindustry.entities.Player;
|
import io.anuke.mindustry.entities.Player;
|
||||||
import io.anuke.mindustry.net.Net;
|
import io.anuke.mindustry.net.Net;
|
||||||
import io.anuke.ucore.scene.builders.button;
|
import io.anuke.ucore.scene.builders.button;
|
||||||
@@ -50,7 +49,7 @@ public class DebugFragment implements Fragment {
|
|||||||
row();
|
row();
|
||||||
new button("infammo", "toggle", () -> infiniteAmmo = !infiniteAmmo);
|
new button("infammo", "toggle", () -> infiniteAmmo = !infiniteAmmo);
|
||||||
row();
|
row();
|
||||||
new button("wave", () -> logic.runWave());
|
new button("wave", () -> state.wavetime = 0f);
|
||||||
row();
|
row();
|
||||||
new button("clear", () -> {
|
new button("clear", () -> {
|
||||||
enemyGroup.clear();
|
enemyGroup.clear();
|
||||||
@@ -58,9 +57,7 @@ public class DebugFragment implements Fragment {
|
|||||||
netClient.clearRecieved();
|
netClient.clearRecieved();
|
||||||
});
|
});
|
||||||
row();
|
row();
|
||||||
new button("spawn", () -> {try{ Net.connect("localhost", Vars.port); }catch (Exception e){e.printStackTrace();}});
|
new button("spawn", () -> {});
|
||||||
row();
|
|
||||||
new button("stuff", () -> netClient.test());
|
|
||||||
row();
|
row();
|
||||||
}}.end();
|
}}.end();
|
||||||
|
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ public class HudFragment implements Fragment{
|
|||||||
visible(() -> !state.is(State.menu));
|
visible(() -> !state.is(State.menu));
|
||||||
|
|
||||||
Label fps = new Label(() -> (Settings.getBool("fps") ? (Gdx.graphics.getFramesPerSecond() + " FPS") +
|
Label fps = new Label(() -> (Settings.getBool("fps") ? (Gdx.graphics.getFramesPerSecond() + " FPS") +
|
||||||
(Net.client() && !gwt ? " / Ping: " + Net.getPing() : "") : ""));
|
(threads.isEnabled() ? " / " + threads.getFPS() + " TPS" : "") + (Net.client() && !gwt ? " / Ping: " + Net.getPing() : "") : ""));
|
||||||
row();
|
row();
|
||||||
add(fps).size(-1);
|
add(fps).size(-1);
|
||||||
|
|
||||||
@@ -179,7 +179,7 @@ public class HudFragment implements Fragment{
|
|||||||
|
|
||||||
new label(()-> state.enemies > 0 ?
|
new label(()-> state.enemies > 0 ?
|
||||||
getEnemiesRemaining() :
|
getEnemiesRemaining() :
|
||||||
(control.tutorial().active() || state.mode.toggleWaves) ? "$text.waiting"
|
(control.tutorial().active() || state.mode.disableWaveTimer) ? "$text.waiting"
|
||||||
: Bundles.format("text.wave.waiting", (int) (state.wavetime / 60f)))
|
: Bundles.format("text.wave.waiting", (int) (state.wavetime / 60f)))
|
||||||
.minWidth(126).padLeft(-6).padRight(-12).left();
|
.minWidth(126).padLeft(-6).padRight(-12).left();
|
||||||
|
|
||||||
@@ -194,7 +194,7 @@ public class HudFragment implements Fragment{
|
|||||||
|
|
||||||
private void playButton(float uheight){
|
private void playButton(float uheight){
|
||||||
new imagebutton("icon-play", 30f, () -> {
|
new imagebutton("icon-play", 30f, () -> {
|
||||||
logic.runWave();
|
state.wavetime = 0f;
|
||||||
}).height(uheight).fillX().right().padTop(-8f).padBottom(-12f).padRight(-36).width(40f).update(l->{
|
}).height(uheight).fillX().right().padTop(-8f).padBottom(-12f).padRight(-36).width(40f).update(l->{
|
||||||
boolean vis = state.enemies <= 0 && (Net.server() || !Net.active());
|
boolean vis = state.enemies <= 0 && (Net.server() || !Net.active());
|
||||||
boolean paused = state.is(State.paused) || !vis;
|
boolean paused = state.is(State.paused) || !vis;
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import io.anuke.ucore.graphics.Draw;
|
|||||||
import io.anuke.ucore.scene.ui.layout.Table;
|
import io.anuke.ucore.scene.ui.layout.Table;
|
||||||
import io.anuke.ucore.util.Bundles;
|
import io.anuke.ucore.util.Bundles;
|
||||||
import io.anuke.ucore.util.Mathf;
|
import io.anuke.ucore.util.Mathf;
|
||||||
import io.anuke.ucore.util.Tmp;
|
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.state;
|
import static io.anuke.mindustry.Vars.state;
|
||||||
import static io.anuke.mindustry.Vars.tilesize;
|
import static io.anuke.mindustry.Vars.tilesize;
|
||||||
@@ -30,8 +29,8 @@ public class Block{
|
|||||||
private static ObjectMap<String, Block> map = new ObjectMap<>();
|
private static ObjectMap<String, Block> map = new ObjectMap<>();
|
||||||
|
|
||||||
protected static TextureRegion temp = new TextureRegion();
|
protected static TextureRegion temp = new TextureRegion();
|
||||||
|
protected Vector2 offset = new Vector2();
|
||||||
|
|
||||||
public Tile[] temptiles = new Tile[4];
|
|
||||||
/**internal name*/
|
/**internal name*/
|
||||||
public final String name;
|
public final String name;
|
||||||
/**internal ID*/
|
/**internal ID*/
|
||||||
@@ -88,6 +87,8 @@ public class Block{
|
|||||||
public Layer layer2 = null;
|
public Layer layer2 = null;
|
||||||
/**list of displayed block status bars. Defaults to health bar.*/
|
/**list of displayed block status bars. Defaults to health bar.*/
|
||||||
public Array<BlockBar> bars = Array.with(new BlockBar(Color.RED, false, tile -> tile.entity.health / (float)tile.block().health));
|
public Array<BlockBar> bars = Array.with(new BlockBar(Color.RED, false, tile -> tile.entity.health / (float)tile.block().health));
|
||||||
|
/**whether this block can be replaced in all cases*/
|
||||||
|
public boolean alwaysReplace = false;
|
||||||
|
|
||||||
public Block(String name) {
|
public Block(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
@@ -273,7 +274,7 @@ public class Block{
|
|||||||
|
|
||||||
/**Offset for placing and drawing multiblocks.*/
|
/**Offset for placing and drawing multiblocks.*/
|
||||||
public Vector2 getPlaceOffset(){
|
public Vector2 getPlaceOffset(){
|
||||||
return Tmp.v3.set(((width + 1) % 2) * tilesize/2, ((height + 1) % 2) * tilesize/2);
|
return offset.set(((width + 1) % 2) * tilesize/2, ((height + 1) % 2) * tilesize/2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isMultiblock(){
|
public boolean isMultiblock(){
|
||||||
|
|||||||
@@ -237,13 +237,13 @@ public class Tile{
|
|||||||
if(rotation == 3) return world.tile(x, y - 1);
|
if(rotation == 3) return world.tile(x, y - 1);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Tile[] getNearby(){
|
|
||||||
return world.getNearby(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Tile[] getNearby(Tile[] copy){
|
public Tile[] getNearby(Tile[] temptiles){
|
||||||
return world.getNearby(x, y, copy);
|
temptiles[0] = world.tile(x+1, y);
|
||||||
|
temptiles[1] = world.tile(x, y+1);
|
||||||
|
temptiles[2] = world.tile(x-1, y);
|
||||||
|
temptiles[3] = world.tile(x, y-1);
|
||||||
|
return temptiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateOcclusion(){
|
public void updateOcclusion(){
|
||||||
|
|||||||
@@ -45,8 +45,6 @@ public class DistributionBlocks{
|
|||||||
}},
|
}},
|
||||||
liquidjunction = new LiquidJunction("liquidjunction"){{
|
liquidjunction = new LiquidJunction("liquidjunction"){{
|
||||||
|
|
||||||
}},
|
|
||||||
liquiditemjunction = new LiquidItemJunction("liquiditemjunction"){{
|
|
||||||
}},
|
}},
|
||||||
powerbooster = new PowerBooster("powerbooster"){{
|
powerbooster = new PowerBooster("powerbooster"){{
|
||||||
powerRange = 4;
|
powerRange = 4;
|
||||||
|
|||||||
@@ -40,12 +40,11 @@ public class WeaponBlocks{
|
|||||||
@Override
|
@Override
|
||||||
protected void shoot(Tile tile){
|
protected void shoot(Tile tile){
|
||||||
TurretEntity entity = tile.entity();
|
TurretEntity entity = tile.entity();
|
||||||
|
|
||||||
Angles.vector.set(4, -2).rotate(entity.rotation);
|
for(int i : Mathf.signs){
|
||||||
bullet(tile, entity.rotation);
|
tr.trns(entity.rotation, 4, -2 * i);
|
||||||
|
bullet(tile, entity.rotation);
|
||||||
Angles.vector.set(4, 2).rotate(entity.rotation);
|
}
|
||||||
bullet(tile, entity.rotation);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -136,9 +135,10 @@ public class WeaponBlocks{
|
|||||||
@Override
|
@Override
|
||||||
public void shoot(Tile tile){
|
public void shoot(Tile tile){
|
||||||
TurretEntity entity = tile.entity();
|
TurretEntity entity = tile.entity();
|
||||||
Angles.translation(entity.rotation, 4);
|
|
||||||
|
|
||||||
new TeslaOrb(tile.worldx() + Angles.x(), tile.worldy() + Angles.y(), range, 9).add();
|
float len = 4f;
|
||||||
|
|
||||||
|
new TeslaOrb(tile.drawx() + Angles.trnsx(entity.rotation, len), tile.drawy() + Angles.trnsy(entity.rotation, len), range, 9).add();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -179,10 +179,10 @@ public class WeaponBlocks{
|
|||||||
float space = 3.5f;
|
float space = 3.5f;
|
||||||
|
|
||||||
for(int i = -1; i < 1; i ++){
|
for(int i = -1; i < 1; i ++){
|
||||||
Angles.vector.set(len, Mathf.sign(i) * space).rotate(entity.rotation);
|
tr.trns(entity.rotation, len, Mathf.sign(i) * space);
|
||||||
bullet(tile, entity.rotation);
|
bullet(tile, entity.rotation);
|
||||||
Effects.effect(shootEffect, tile.drawx() + Angles.x(),
|
Effects.effect(shootEffect, tile.drawx() + tr.x,
|
||||||
tile.drawy()+ Angles.y(), entity.rotation);
|
tile.drawy() + tr.y, entity.rotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
Effects.shake(1f, 1f, tile.worldx(), tile.worldy());
|
Effects.shake(1f, 1f, tile.worldx(), tile.worldy());
|
||||||
|
|||||||
@@ -20,10 +20,9 @@ public class BlendBlock extends Block{
|
|||||||
Draw.rect(variants > 0 ? (name() + Mathf.randomSeed(tile.id(), 1, variants)) : name(),
|
Draw.rect(variants > 0 ? (name() + Mathf.randomSeed(tile.id(), 1, variants)) : name(),
|
||||||
tile.worldx(), tile.worldy());
|
tile.worldx(), tile.worldy());
|
||||||
|
|
||||||
Tile[] nearby = tile.getNearby();
|
|
||||||
|
|
||||||
for(int i = 0; i < 4; i ++){
|
for(int i = 0; i < 4; i ++){
|
||||||
if(nearby[i] != null && !blend.test(nearby[i].block())){
|
Tile near = tile.getNearby(i);
|
||||||
|
if(near != null && !blend.test(near.block())){
|
||||||
Draw.rect(edge + "-" + i, tile.worldx(), tile.worldy());
|
Draw.rect(edge + "-" + i, tile.worldx(), tile.worldy());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import io.anuke.mindustry.entities.TileEntity;
|
|||||||
import io.anuke.mindustry.resource.Liquid;
|
import io.anuke.mindustry.resource.Liquid;
|
||||||
import io.anuke.mindustry.world.Block;
|
import io.anuke.mindustry.world.Block;
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
|
import io.anuke.ucore.core.Timers;
|
||||||
import io.anuke.ucore.graphics.Draw;
|
import io.anuke.ucore.graphics.Draw;
|
||||||
import io.anuke.ucore.util.Mathf;
|
import io.anuke.ucore.util.Mathf;
|
||||||
|
|
||||||
@@ -80,7 +81,7 @@ public class LiquidBlock extends Block implements LiquidAcceptor{
|
|||||||
LiquidAcceptor other = (LiquidAcceptor)next.block();
|
LiquidAcceptor other = (LiquidAcceptor)next.block();
|
||||||
|
|
||||||
float flow = Math.min(other.getLiquidCapacity(next) - other.getLiquid(next) - 0.001f,
|
float flow = Math.min(other.getLiquidCapacity(next) - other.getLiquid(next) - 0.001f,
|
||||||
Math.min(entity.liquidAmount/flowfactor, entity.liquidAmount));
|
Math.min(entity.liquidAmount/flowfactor * Timers.delta(), entity.liquidAmount));
|
||||||
|
|
||||||
if(flow <= 0f || entity.liquidAmount < flow) return;
|
if(flow <= 0f || entity.liquidAmount < flow) return;
|
||||||
|
|
||||||
|
|||||||
@@ -9,5 +9,6 @@ public class Rock extends Block {
|
|||||||
shadow = name+"shadow";
|
shadow = name+"shadow";
|
||||||
breakable = true;
|
breakable = true;
|
||||||
breaktime = 10;
|
breaktime = 10;
|
||||||
|
alwaysReplace = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import io.anuke.ucore.core.Effects.Effect;
|
|||||||
import io.anuke.ucore.entities.Entities;
|
import io.anuke.ucore.entities.Entities;
|
||||||
import io.anuke.ucore.entities.SolidEntity;
|
import io.anuke.ucore.entities.SolidEntity;
|
||||||
import io.anuke.ucore.graphics.Draw;
|
import io.anuke.ucore.graphics.Draw;
|
||||||
import io.anuke.ucore.util.Tmp;
|
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
@@ -20,6 +19,8 @@ import java.io.IOException;
|
|||||||
import static io.anuke.mindustry.Vars.*;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
|
|
||||||
public class Door extends Wall{
|
public class Door extends Wall{
|
||||||
|
protected final Rectangle rect = new Rectangle();
|
||||||
|
|
||||||
protected Effect openfx = Fx.dooropen;
|
protected Effect openfx = Fx.dooropen;
|
||||||
protected Effect closefx = Fx.doorclose;
|
protected Effect closefx = Fx.doorclose;
|
||||||
|
|
||||||
@@ -65,13 +66,13 @@ public class Door extends Wall{
|
|||||||
boolean anyEntities(Tile tile){
|
boolean anyEntities(Tile tile){
|
||||||
int x = tile.x, y = tile.y;
|
int x = tile.x, y = tile.y;
|
||||||
Block type = tile.block();
|
Block type = tile.block();
|
||||||
Tmp.r2.setSize(type.width * tilesize, type.height * tilesize);
|
rect.setSize(type.width * tilesize, type.height * tilesize);
|
||||||
Tmp.r2.setCenter(tile.drawx(), tile.drawy());
|
rect.setCenter(tile.drawx(), tile.drawy());
|
||||||
|
|
||||||
for(SolidEntity e : Entities.getNearby(enemyGroup, x * tilesize, y * tilesize, tilesize * 2f)){
|
for(SolidEntity e : Entities.getNearby(enemyGroup, x * tilesize, y * tilesize, tilesize * 2f)){
|
||||||
Rectangle rect = e.hitbox.getRect(e.x, e.y);
|
Rectangle rect = e.hitbox.getRect(e.x, e.y);
|
||||||
|
|
||||||
if(Tmp.r2.overlaps(rect)){
|
if(rect.overlaps(rect)){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -79,7 +80,7 @@ public class Door extends Wall{
|
|||||||
for(SolidEntity e : Entities.getNearby(playerGroup, x * tilesize, y * tilesize, tilesize * 2f)){
|
for(SolidEntity e : Entities.getNearby(playerGroup, x * tilesize, y * tilesize, tilesize * 2f)){
|
||||||
Rectangle rect = e.hitbox.getRect(e.x, e.y);
|
Rectangle rect = e.hitbox.getRect(e.x, e.y);
|
||||||
|
|
||||||
if(Tmp.r2.overlaps(rect)){
|
if(rect.overlaps(rect)){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ public class LaserTurret extends PowerTurret{
|
|||||||
TurretEntity entity = tile.entity();
|
TurretEntity entity = tile.entity();
|
||||||
Enemy enemy = entity.target;
|
Enemy enemy = entity.target;
|
||||||
|
|
||||||
if(Angles.angleDist(entity.rotation, Angles.angle(tile.worldx(), tile.worldy(), enemy.x, enemy.y)) < cone){
|
if(Angles.angleDist(entity.rotation, Angles.angle(tile.drawx(), tile.drawy(), enemy.x, enemy.y)) < cone){
|
||||||
enemy.damage(damage);
|
enemy.damage(damage);
|
||||||
Effects.effect(hiteffect, enemy.x + Mathf.range(3), enemy.y + Mathf.range(3));
|
Effects.effect(hiteffect, enemy.x + Mathf.range(3), enemy.y + Mathf.range(3));
|
||||||
}
|
}
|
||||||
@@ -45,10 +45,10 @@ public class LaserTurret extends PowerTurret{
|
|||||||
TurretEntity entity = tile.entity();
|
TurretEntity entity = tile.entity();
|
||||||
|
|
||||||
if(entity.target != null &&
|
if(entity.target != null &&
|
||||||
Angles.angleDist(entity.rotation, Angles.angle(tile.worldx(), tile.worldy(), entity.target.x, entity.target.y)) <= cone){
|
Angles.angleDist(entity.rotation, Angles.angle(tile.drawx(), tile.drawy(), entity.target.x, entity.target.y)) <= cone){
|
||||||
Angles.translation(entity.rotation, 4f);
|
float len = 4f;
|
||||||
|
|
||||||
float x = tile.worldx() + Angles.x(), y = tile.worldy() + Angles.y();
|
float x = tile.drawx() + Angles.trnsx(entity.rotation, len), y = tile.drawy() + Angles.trnsy(entity.rotation, len);
|
||||||
float x2 = entity.target.x, y2 = entity.target.y;
|
float x2 = entity.target.x, y2 = entity.target.y;
|
||||||
|
|
||||||
float lighten = (MathUtils.sin(Timers.time()/1.2f) + 1f) / 10f;
|
float lighten = (MathUtils.sin(Timers.time()/1.2f) + 1f) / 10f;
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ public class RepairTurret extends PowerTurret{
|
|||||||
@Override
|
@Override
|
||||||
public void drawSelect(Tile tile){
|
public void drawSelect(Tile tile){
|
||||||
Draw.color(Color.GREEN);
|
Draw.color(Color.GREEN);
|
||||||
Lines.dashCircle(tile.worldx(), tile.worldy(), range);
|
Lines.dashCircle(tile.drawx(), tile.drawy(), range);
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,8 +83,9 @@ public class RepairTurret extends PowerTurret{
|
|||||||
|
|
||||||
if(entity.power >= powerUsed && entity.blockTarget != null && Angles.angleDist(entity.angleTo(entity.blockTarget), entity.rotation) < 10){
|
if(entity.power >= powerUsed && entity.blockTarget != null && Angles.angleDist(entity.angleTo(entity.blockTarget), entity.rotation) < 10){
|
||||||
Tile targetTile = entity.blockTarget.tile;
|
Tile targetTile = entity.blockTarget.tile;
|
||||||
Angles.translation(entity.rotation, 4f);
|
float len = 4f;
|
||||||
float x = tile.drawx() + Angles.x(), y = tile.drawy() + Angles.y();
|
|
||||||
|
float x = tile.drawx() + Angles.trnsx(entity.rotation, len), y = tile.drawy() + Angles.trnsy(entity.rotation, len);
|
||||||
float x2 = targetTile.drawx(), y2 = targetTile.drawy();
|
float x2 = targetTile.drawx(), y2 = targetTile.drawy();
|
||||||
|
|
||||||
Draw.color(Hue.rgb(138, 244, 138, (MathUtils.sin(Timers.time()) + 1f) / 14f));
|
Draw.color(Hue.rgb(138, 244, 138, (MathUtils.sin(Timers.time()) + 1f) / 14f));
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import io.anuke.ucore.graphics.Lines;
|
|||||||
import io.anuke.ucore.util.Angles;
|
import io.anuke.ucore.util.Angles;
|
||||||
import io.anuke.ucore.util.Mathf;
|
import io.anuke.ucore.util.Mathf;
|
||||||
import io.anuke.ucore.util.Strings;
|
import io.anuke.ucore.util.Strings;
|
||||||
|
import io.anuke.ucore.util.Translator;
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
@@ -51,6 +52,7 @@ public class Turret extends Block{
|
|||||||
protected Effect shootEffect = null;
|
protected Effect shootEffect = null;
|
||||||
protected float shootShake = 0f;
|
protected float shootShake = 0f;
|
||||||
protected int soundReload = 0;
|
protected int soundReload = 0;
|
||||||
|
protected Translator tr = new Translator();
|
||||||
|
|
||||||
public Turret(String name) {
|
public Turret(String name) {
|
||||||
super(name);
|
super(name);
|
||||||
@@ -210,14 +212,14 @@ public class Turret extends Block{
|
|||||||
protected void shoot(Tile tile){
|
protected void shoot(Tile tile){
|
||||||
TurretEntity entity = tile.entity();
|
TurretEntity entity = tile.entity();
|
||||||
|
|
||||||
Angles.translation(entity.rotation, width * tilesize / 2f);
|
tr.trns(entity.rotation, width * tilesize/2);
|
||||||
|
|
||||||
for(int i = 0; i < shots; i ++){
|
for(int i = 0; i < shots; i ++){
|
||||||
if(Mathf.zero(shotDelayScale)){
|
if(Mathf.zero(shotDelayScale)){
|
||||||
bullet(tile, entity.rotation + Mathf.range(inaccuracy));
|
bullet(tile, entity.rotation + Mathf.range(inaccuracy));
|
||||||
}else{
|
}else{
|
||||||
Timers.run(i * shotDelayScale, ()->{
|
Timers.run(i * shotDelayScale, () -> {
|
||||||
Angles.translation(entity.rotation, width * tilesize / 2f);
|
tr.trns(entity.rotation, width * tilesize/2f);
|
||||||
bullet(tile, entity.rotation + Mathf.range(inaccuracy));
|
bullet(tile, entity.rotation + Mathf.range(inaccuracy));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -225,8 +227,8 @@ public class Turret extends Block{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(shootEffect != null){
|
if(shootEffect != null){
|
||||||
Effects.effect(shootEffect, tile.drawx() + Angles.x(),
|
Effects.effect(shootEffect, tile.drawx() + tr.x,
|
||||||
tile.drawy()+ Angles.y(), entity.rotation);
|
tile.drawy() + tr.y, entity.rotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(shootShake > 0){
|
if(shootShake > 0){
|
||||||
@@ -235,7 +237,7 @@ public class Turret extends Block{
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void bullet(Tile tile, float angle){
|
protected void bullet(Tile tile, float angle){
|
||||||
Bullet out = new Bullet(bullet, tile.entity, tile.drawx() + Angles.x(), tile.drawy() + Angles.y(), angle).add();
|
new Bullet(bullet, tile.entity, tile.drawx() + tr.x, tile.drawy() + tr.y, angle).add();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TurretEntity extends TileEntity{
|
public static class TurretEntity extends TileEntity{
|
||||||
|
|||||||
@@ -9,10 +9,7 @@ import io.anuke.mindustry.world.Layer;
|
|||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
import io.anuke.ucore.core.Timers;
|
import io.anuke.ucore.core.Timers;
|
||||||
import io.anuke.ucore.graphics.Draw;
|
import io.anuke.ucore.graphics.Draw;
|
||||||
import io.anuke.ucore.util.Bits;
|
import io.anuke.ucore.util.*;
|
||||||
import io.anuke.ucore.util.Mathf;
|
|
||||||
import io.anuke.ucore.util.Strings;
|
|
||||||
import io.anuke.ucore.util.Tmp;
|
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
@@ -24,39 +21,43 @@ import java.util.List;
|
|||||||
import static io.anuke.mindustry.Vars.tilesize;
|
import static io.anuke.mindustry.Vars.tilesize;
|
||||||
|
|
||||||
public class Conveyor extends Block{
|
public class Conveyor extends Block{
|
||||||
|
private static ItemPos drawpos = new ItemPos();
|
||||||
private static ItemPos pos1 = new ItemPos();
|
private static ItemPos pos1 = new ItemPos();
|
||||||
private static ItemPos pos2 = new ItemPos();
|
private static ItemPos pos2 = new ItemPos();
|
||||||
private static LongArray removals = new LongArray();
|
|
||||||
private static final float itemSpace = 0.135f;
|
private static final float itemSpace = 0.135f;
|
||||||
private static final float offsetScl = 128f*3f;
|
private static final float offsetScl = 128f*3f;
|
||||||
private static final float itemSize = 4f;
|
private static final float itemSize = 4f;
|
||||||
|
private static final float minmove = 1f / (Short.MAX_VALUE - 2);
|
||||||
|
|
||||||
|
private final Translator tr1 = new Translator();
|
||||||
|
private final Translator tr2 = new Translator();
|
||||||
|
|
||||||
public float speed = 0.02f;
|
public float speed = 0.02f;
|
||||||
|
|
||||||
protected Conveyor(String name) {
|
protected Conveyor(String name) {
|
||||||
super(name);
|
super(name);
|
||||||
rotate = true;
|
rotate = true;
|
||||||
update = true;
|
update = true;
|
||||||
layer = Layer.overlay;
|
layer = Layer.overlay;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void getStats(Array<String> list){
|
public void getStats(Array<String> list){
|
||||||
super.getStats(list);
|
super.getStats(list);
|
||||||
list.add("[iteminfo]Item Speed/second: " + Strings.toFixed(speed * 60, 1));
|
list.add("[iteminfo]Item Speed/second: " + Strings.toFixed(speed * 60, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canReplace(Block other){
|
public boolean canReplace(Block other){
|
||||||
return other instanceof Conveyor || other instanceof Router || other instanceof Junction;
|
return other instanceof Conveyor || other instanceof Router || other instanceof Junction;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(Tile tile){
|
public void draw(Tile tile){
|
||||||
byte rotation = tile.getRotation();
|
byte rotation = tile.getRotation();
|
||||||
|
|
||||||
Draw.rect(name() +
|
Draw.rect(name() +
|
||||||
(Timers.time() % ((20 / 100f) / speed) < (10 / 100f) / speed && acceptItem(Item.stone, tile, null) ? "" : "move"),
|
(Timers.time() % ((20 / 100f) / speed) < (10 / 100f) / speed && acceptItem(Item.stone, tile, null) ? "" : "move"),
|
||||||
tile.worldx(), tile.worldy(), rotation * 90);
|
tile.worldx(), tile.worldy(), rotation * 90);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,78 +65,71 @@ public class Conveyor extends Block{
|
|||||||
public boolean isLayer(Tile tile){
|
public boolean isLayer(Tile tile){
|
||||||
return tile.<ConveyorEntity>entity().convey.size > 0;
|
return tile.<ConveyorEntity>entity().convey.size > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawLayer(Tile tile){
|
public void drawLayer(Tile tile){
|
||||||
ConveyorEntity entity = tile.entity();
|
ConveyorEntity entity = tile.entity();
|
||||||
|
|
||||||
byte rotation = tile.getRotation();
|
byte rotation = tile.getRotation();
|
||||||
|
|
||||||
for(int i = 0; i < entity.convey.size; i ++){
|
for(int i = 0; i < entity.convey.size; i ++){
|
||||||
ItemPos pos = pos1.set(entity.convey.get(i));
|
ItemPos pos = drawpos.set(entity.convey.get(i), ItemPos.drawShorts);
|
||||||
|
|
||||||
if(pos.item == null) continue;
|
if(pos.item == null) continue;
|
||||||
|
|
||||||
Tmp.v1.set(tilesize, 0).rotate(rotation * 90);
|
tr1.trns(rotation * 90, tilesize, 0);
|
||||||
Tmp.v2.set(-tilesize / 2, pos.x*tilesize/2).rotate(rotation * 90);
|
tr2.trns(rotation * 90, -tilesize / 2, pos.x*tilesize/2);
|
||||||
|
|
||||||
Draw.rect(pos.item.region,
|
Draw.rect(pos.item.region,
|
||||||
tile.x * tilesize + Tmp.v1.x * pos.y + Tmp.v2.x,
|
tile.x * tilesize + tr1.x * pos.y + tr2.x,
|
||||||
tile.y * tilesize + Tmp.v1.y * pos.y + Tmp.v2.y, itemSize, itemSize);
|
tile.y * tilesize + tr1.y * pos.y + tr2.y, itemSize, itemSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(Tile tile){
|
public void update(Tile tile){
|
||||||
|
|
||||||
ConveyorEntity entity = tile.entity();
|
ConveyorEntity entity = tile.entity();
|
||||||
entity.minitem = 1f;
|
entity.minitem = 1f;
|
||||||
|
|
||||||
removals.clear();
|
|
||||||
|
|
||||||
float shift = entity.elapsed * speed;
|
int minremove = Integer.MAX_VALUE;
|
||||||
|
|
||||||
for(int i = 0; i < entity.convey.size; i ++){
|
for(int i = 0; i < entity.convey.size; i ++){
|
||||||
long value = entity.convey.get(i);
|
long value = entity.convey.get(i);
|
||||||
ItemPos pos = pos1.set(value);
|
ItemPos pos = pos1.set(value, ItemPos.updateShorts);
|
||||||
|
|
||||||
pos.y += shift;
|
|
||||||
|
|
||||||
|
//..this should never happen, but in case it does, remove it and stop here
|
||||||
if(pos.item == null){
|
if(pos.item == null){
|
||||||
removals.add(value);
|
entity.convey.removeValue(value);
|
||||||
continue;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean canmove = i == entity.convey.size - 1 ||
|
|
||||||
!(pos2.set(entity.convey.get(i + 1)).y - pos.y < itemSpace * Math.max(Timers.delta(), 1f));
|
|
||||||
|
|
||||||
float minmove = 1f / (Short.MAX_VALUE - 2);
|
float nextpos = (i == entity.convey.size - 1 ? 100f : pos2.set(entity.convey.get(i + 1), ItemPos.updateShorts).y) - itemSpace;
|
||||||
|
float maxmove = Math.min(nextpos - pos.y, speed * Timers.delta());
|
||||||
|
|
||||||
if(canmove){
|
if(maxmove > minmove){
|
||||||
pos.y += Math.max(speed * Timers.delta(), minmove); //TODO fix precision issues when at high FPS?
|
pos.y += maxmove;
|
||||||
pos.x = Mathf.lerpDelta(pos.x, 0, 0.06f);
|
pos.x = Mathf.lerpDelta(pos.x, 0, 0.06f);
|
||||||
}else{
|
}else{
|
||||||
pos.x = Mathf.lerpDelta(pos.x, pos.seed/offsetScl, 0.1f);
|
pos.x = Mathf.lerpDelta(pos.x, pos.seed/offsetScl, 0.1f);
|
||||||
}
|
}
|
||||||
|
|
||||||
pos.y = Mathf.clamp(pos.y);
|
pos.y = Mathf.clamp(pos.y);
|
||||||
|
|
||||||
if(pos.y >= 0.9999f && offloadDir(tile, pos.item)){
|
if(pos.y >= 0.9999f && offloadDir(tile, pos.item)){
|
||||||
removals.add(value);
|
minremove = Math.min(i, minremove);
|
||||||
}else{
|
}else{
|
||||||
value = pos.pack();
|
value = pos.pack();
|
||||||
|
|
||||||
if(pos.y < entity.minitem)
|
if(pos.y < entity.minitem)
|
||||||
entity.minitem = pos.y;
|
entity.minitem = pos.y;
|
||||||
entity.convey.set(i, value);
|
entity.convey.set(i, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
entity.elapsed = 0f;
|
if(minremove != Integer.MAX_VALUE) entity.convey.truncate(minremove);
|
||||||
entity.convey.removeAll(removals);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TileEntity getEntity(){
|
public TileEntity getEntity(){
|
||||||
return new ConveyorEntity();
|
return new ConveyorEntity();
|
||||||
@@ -145,25 +139,24 @@ public class Conveyor extends Block{
|
|||||||
public boolean acceptItem(Item item, Tile tile, Tile source){
|
public boolean acceptItem(Item item, Tile tile, Tile source){
|
||||||
int direction = source == null ? 0 : Math.abs(source.relativeTo(tile.x, tile.y) - tile.getRotation());
|
int direction = source == null ? 0 : Math.abs(source.relativeTo(tile.x, tile.y) - tile.getRotation());
|
||||||
float minitem = tile.<ConveyorEntity>entity().minitem;
|
float minitem = tile.<ConveyorEntity>entity().minitem;
|
||||||
return (((direction == 0) && minitem > 0.05f) ||
|
return (((direction == 0) && minitem > 0.05f) ||
|
||||||
((direction %2 == 1) && minitem > 0.52f)) && (source == null || !(source.block().rotate && (source.getRotation() + 2) % 4 == tile.getRotation()));
|
((direction %2 == 1) && minitem > 0.52f)) && (source == null || !(source.block().rotate && (source.getRotation() + 2) % 4 == tile.getRotation()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleItem(Item item, Tile tile, Tile source){
|
public void handleItem(Item item, Tile tile, Tile source){
|
||||||
byte rotation = tile.getRotation();
|
byte rotation = tile.getRotation();
|
||||||
|
|
||||||
int ch = Math.abs(source.relativeTo(tile.x, tile.y) - rotation);
|
int ch = Math.abs(source.relativeTo(tile.x, tile.y) - rotation);
|
||||||
int ang = ((source.relativeTo(tile.x, tile.y) - rotation));
|
int ang = ((source.relativeTo(tile.x, tile.y) - rotation));
|
||||||
|
|
||||||
|
|
||||||
float pos = ch == 0 ? 0 : ch % 2 == 1 ? 0.5f : 1f;
|
float pos = ch == 0 ? 0 : ch % 2 == 1 ? 0.5f : 1f;
|
||||||
float y = (ang == -1 || ang == 3) ? 1 : (ang == 1 || ang == -3) ? -1 : 0;
|
float y = (ang == -1 || ang == 3) ? 1 : (ang == 1 || ang == -3) ? -1 : 0;
|
||||||
|
|
||||||
ConveyorEntity entity = tile.entity();
|
ConveyorEntity entity = tile.entity();
|
||||||
long result = ItemPos.packItem(item, y*0.9f, pos, (byte)Mathf.random(255));
|
long result = ItemPos.packItem(item, y*0.9f, pos, (byte)Mathf.random(255));
|
||||||
boolean inserted = false;
|
boolean inserted = false;
|
||||||
|
|
||||||
for(int i = 0; i < entity.convey.size; i ++){
|
for(int i = 0; i < entity.convey.size; i ++){
|
||||||
if(compareItems(result, entity.convey.get(i)) < 0){
|
if(compareItems(result, entity.convey.get(i)) < 0){
|
||||||
entity.convey.insert(i, result);
|
entity.convey.insert(i, result);
|
||||||
@@ -171,13 +164,13 @@ public class Conveyor extends Block{
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//this item must be greater than anything there...
|
//this item must be greater than anything there...
|
||||||
if(!inserted){
|
if(!inserted){
|
||||||
entity.convey.add(result);
|
entity.convey.add(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Conveyor data format:
|
* Conveyor data format:
|
||||||
* [0] item ordinal
|
* [0] item ordinal
|
||||||
@@ -189,80 +182,78 @@ public class Conveyor extends Block{
|
|||||||
public static class ConveyorEntity extends TileEntity{
|
public static class ConveyorEntity extends TileEntity{
|
||||||
|
|
||||||
LongArray convey = new LongArray();
|
LongArray convey = new LongArray();
|
||||||
float minitem = 1, elapsed;
|
float minitem = 1;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(DataOutputStream stream) throws IOException{
|
public void write(DataOutputStream stream) throws IOException{
|
||||||
stream.writeInt(convey.size);
|
stream.writeInt(convey.size);
|
||||||
|
|
||||||
for(int i = 0; i < convey.size; i ++){
|
for(int i = 0; i < convey.size; i ++){
|
||||||
stream.writeInt(ItemPos.toInt(convey.get(i)));
|
stream.writeInt(ItemPos.toInt(convey.get(i)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void read(DataInputStream stream) throws IOException{
|
public void read(DataInputStream stream) throws IOException{
|
||||||
convey.clear();
|
convey.clear();
|
||||||
int amount = stream.readInt();
|
int amount = stream.readInt();
|
||||||
convey.ensureCapacity(amount);
|
convey.ensureCapacity(amount);
|
||||||
|
|
||||||
for(int i = 0; i < amount; i ++){
|
for(int i = 0; i < amount; i ++){
|
||||||
convey.add(ItemPos.toLong(stream.readInt()));
|
convey.add(ItemPos.toLong(stream.readInt()));
|
||||||
}
|
}
|
||||||
|
|
||||||
sort(convey.items, convey.size);
|
sort(convey.items, convey.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void readNetwork(DataInputStream stream, float elapsed) throws IOException{
|
|
||||||
read(stream);
|
|
||||||
this.elapsed = elapsed;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void sort(long[] elements, int length){
|
private static void sort(long[] elements, int length){
|
||||||
List<Long> wrapper = new AbstractList<Long>() {
|
List<Long> wrapper = new AbstractList<Long>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long get(int index) {
|
public Long get(int index) {
|
||||||
return elements[index];
|
return elements[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int size() {
|
public int size() {
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long set(int index, Long element) {
|
public Long set(int index, Long element) {
|
||||||
long v = elements[index];
|
long v = elements[index];
|
||||||
elements[index] = element;
|
elements[index] = element;
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Collections.sort(wrapper, Conveyor::compareItems);
|
Collections.sort(wrapper, Conveyor::compareItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int compareItems(Long a, Long b){
|
private static int compareItems(Long a, Long b){
|
||||||
pos1.set(a);
|
pos1.set(a, ItemPos.packShorts);
|
||||||
pos2.set(b);
|
pos2.set(b, ItemPos.packShorts);
|
||||||
return Float.compare(pos1.y, pos2.y);
|
return Float.compare(pos1.y, pos2.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Container class. Do not instantiate.
|
//Container class. Do not instantiate.
|
||||||
static class ItemPos{
|
static class ItemPos{
|
||||||
private static short[] writeShort = new short[4];
|
private static short[] writeShort = new short[4];
|
||||||
private static byte[] writeByte = new byte[4];
|
private static byte[] writeByte = new byte[4];
|
||||||
|
|
||||||
|
private static short[] packShorts = new short[4];
|
||||||
|
private static short[] drawShorts = new short[4];
|
||||||
|
private static short[] updateShorts = new short[4];
|
||||||
|
|
||||||
Item item;
|
Item item;
|
||||||
float x, y;
|
float x, y;
|
||||||
byte seed;
|
byte seed;
|
||||||
|
|
||||||
private ItemPos(){}
|
private ItemPos(){}
|
||||||
|
|
||||||
ItemPos set(long lvalue){
|
ItemPos set(long lvalue, short[] values){
|
||||||
short[] values = Bits.getShorts(lvalue);
|
Bits.getShorts(lvalue, values);
|
||||||
|
|
||||||
if(values[0] >= Item.getAllItems().size || values[0] < 0)
|
if(values[0] >= Item.getAllItems().size || values[0] < 0)
|
||||||
item = null;
|
item = null;
|
||||||
@@ -274,13 +265,13 @@ public class Conveyor extends Block{
|
|||||||
seed = (byte)values[3];
|
seed = (byte)values[3];
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
long pack(){
|
long pack(){
|
||||||
return packItem(item, x, y, seed);
|
return packItem(item, x, y, seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
static long packItem(Item item, float x, float y, byte seed){
|
static long packItem(Item item, float x, float y, byte seed){
|
||||||
short[] shorts = Bits.getShorts();
|
short[] shorts = packShorts;
|
||||||
shorts[0] = (short)item.id;
|
shorts[0] = (short)item.id;
|
||||||
shorts[1] = (short)(x*Short.MAX_VALUE);
|
shorts[1] = (short)(x*Short.MAX_VALUE);
|
||||||
shorts[2] = (short)((y - 1f)*Short.MAX_VALUE);
|
shorts[2] = (short)((y - 1f)*Short.MAX_VALUE);
|
||||||
@@ -321,4 +312,4 @@ public class Conveyor extends Block{
|
|||||||
return Bits.packLong(shorts);
|
return Bits.packLong(shorts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -22,18 +22,6 @@ public class Junction extends Block{
|
|||||||
public boolean canReplace(Block other){
|
public boolean canReplace(Block other){
|
||||||
return other instanceof Conveyor || other instanceof Router;
|
return other instanceof Conveyor || other instanceof Router;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleItem(Item item, Tile tile, Tile source){
|
|
||||||
JunctionEntity entity = tile.entity();
|
|
||||||
boolean x = tile.x == source.x;
|
|
||||||
long value = Bits.packLong(NumberUtils.floatToIntBits(Timers.time()), Bits.packInt((short)item.id, source.relativeTo(tile.x, tile.y)));
|
|
||||||
if(x){
|
|
||||||
entity.bx.add(value);
|
|
||||||
}else {
|
|
||||||
entity.by.add(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(Tile tile){
|
public void update(Tile tile){
|
||||||
@@ -64,6 +52,18 @@ public class Junction extends Block{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleItem(Item item, Tile tile, Tile source){
|
||||||
|
JunctionEntity entity = tile.entity();
|
||||||
|
boolean x = tile.x == source.x;
|
||||||
|
long value = Bits.packLong(NumberUtils.floatToIntBits(Timers.time()), Bits.packInt((short)item.id, source.relativeTo(tile.x, tile.y)));
|
||||||
|
if(x){
|
||||||
|
entity.bx.add(value);
|
||||||
|
}else {
|
||||||
|
entity.by.add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean acceptItem(Item item, Tile tile, Tile source){
|
public boolean acceptItem(Item item, Tile tile, Tile source){
|
||||||
JunctionEntity entity = tile.entity();
|
JunctionEntity entity = tile.entity();
|
||||||
@@ -91,6 +91,7 @@ public class Junction extends Block{
|
|||||||
int index;
|
int index;
|
||||||
|
|
||||||
void add(long id){
|
void add(long id){
|
||||||
|
if(full()) return;
|
||||||
items[index++] = id;
|
items[index++] = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,64 +0,0 @@
|
|||||||
package io.anuke.mindustry.world.blocks.types.distribution;
|
|
||||||
|
|
||||||
import io.anuke.mindustry.resource.Item;
|
|
||||||
import io.anuke.mindustry.resource.Liquid;
|
|
||||||
import io.anuke.mindustry.world.Tile;
|
|
||||||
import io.anuke.mindustry.world.blocks.types.LiquidBlock;
|
|
||||||
import io.anuke.ucore.graphics.Draw;
|
|
||||||
import io.anuke.ucore.core.Timers;
|
|
||||||
|
|
||||||
public class LiquidItemJunction extends LiquidBlock{
|
|
||||||
|
|
||||||
public LiquidItemJunction(String name) {
|
|
||||||
super(name);
|
|
||||||
rotate = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void draw(Tile tile){
|
|
||||||
Draw.rect(name(), tile.worldx(), tile.worldy(), tile.getRotation() * 90);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleLiquid(Tile tile, Tile source, Liquid liquid, float amount){
|
|
||||||
int dir = source.relativeTo(tile.x, tile.y);
|
|
||||||
dir = (dir+4)%4;
|
|
||||||
Tile to = tile.getNearby()[dir];
|
|
||||||
|
|
||||||
((LiquidBlock)to.block()).handleLiquid(to, tile, liquid, amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean acceptLiquid(Tile dest, Tile source, Liquid liquid, float amount){
|
|
||||||
int dir = source.relativeTo(dest.x, dest.y);
|
|
||||||
dir = (dir+4)%4;
|
|
||||||
|
|
||||||
if(dir+dest.getRotation() % 2 == 1) return false;
|
|
||||||
|
|
||||||
Tile to = dest.getNearby()[dir];
|
|
||||||
return to != null && to.block() != this && to.block() instanceof LiquidBlock &&
|
|
||||||
((LiquidBlock)to.block()).acceptLiquid(to, dest, liquid, amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleItem(Item item, Tile tile, Tile source){
|
|
||||||
int dir = source.relativeTo(tile.x, tile.y);
|
|
||||||
Tile to = tile.getNearby()[dir];
|
|
||||||
|
|
||||||
Timers.run(15, ()->{
|
|
||||||
if(to == null || to.entity == null) return;
|
|
||||||
to.block().handleItem(item, to, tile);
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean acceptItem(Item item, Tile tile, Tile source){
|
|
||||||
int dir = source.relativeTo(tile.x, tile.y);
|
|
||||||
|
|
||||||
if((dir+ tile.getRotation()) % 2 == 0) return false;
|
|
||||||
|
|
||||||
Tile to = tile.getNearby()[dir];
|
|
||||||
return to != null && to.block().acceptItem(item, to, tile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -23,7 +23,7 @@ public class LiquidJunction extends Conduit{
|
|||||||
public void handleLiquid(Tile tile, Tile source, Liquid liquid, float amount){
|
public void handleLiquid(Tile tile, Tile source, Liquid liquid, float amount){
|
||||||
int dir = source.relativeTo(tile.x, tile.y);
|
int dir = source.relativeTo(tile.x, tile.y);
|
||||||
dir = (dir+4)%4;
|
dir = (dir+4)%4;
|
||||||
Tile to = tile.getNearby()[dir];
|
Tile to = tile.getNearby(dir);
|
||||||
|
|
||||||
((LiquidBlock)to.block()).handleLiquid(to, tile, liquid, amount);
|
((LiquidBlock)to.block()).handleLiquid(to, tile, liquid, amount);
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ public class LiquidJunction extends Conduit{
|
|||||||
public boolean acceptLiquid(Tile dest, Tile source, Liquid liquid, float amount){
|
public boolean acceptLiquid(Tile dest, Tile source, Liquid liquid, float amount){
|
||||||
int dir = source.relativeTo(dest.x, dest.y);
|
int dir = source.relativeTo(dest.x, dest.y);
|
||||||
dir = (dir+4)%4;
|
dir = (dir+4)%4;
|
||||||
Tile to = dest.getNearby()[dir];
|
Tile to = dest.getNearby(dir);
|
||||||
return to != null && to.block() != this && to.block() instanceof LiquidBlock &&
|
return to != null && to.block() != this && to.block() instanceof LiquidBlock &&
|
||||||
((LiquidBlock)to.block()).acceptLiquid(to, dest, liquid, amount);
|
((LiquidBlock)to.block()).acceptLiquid(to, dest, liquid, amount);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public class LiquidRouter extends Conduit{
|
|||||||
|
|
||||||
if(entity.liquidAmount > 0){
|
if(entity.liquidAmount > 0){
|
||||||
if(tile.getExtra() != tile.getRotation()){
|
if(tile.getExtra() != tile.getRotation()){
|
||||||
tryMoveLiquid(tile, tile.getNearby()[tile.getRotation()]);
|
tryMoveLiquid(tile, tile.getNearby(tile.getRotation()));
|
||||||
}
|
}
|
||||||
|
|
||||||
tile.setRotation((byte)((tile.getRotation() + 1) % 4));
|
tile.setRotation((byte)((tile.getRotation() + 1) % 4));
|
||||||
|
|||||||
@@ -66,10 +66,10 @@ public class Sorter extends Block{
|
|||||||
Tile to;
|
Tile to;
|
||||||
|
|
||||||
if(item == entity.sortItem){
|
if(item == entity.sortItem){
|
||||||
to = dest.getNearby()[dir];
|
to = dest.getNearby(dir);
|
||||||
}else{
|
}else{
|
||||||
Tile a = dest.getNearby()[Mathf.mod(dir - 1, 4)];
|
Tile a = dest.getNearby(Mathf.mod(dir - 1, 4));
|
||||||
Tile b = dest.getNearby()[Mathf.mod(dir + 1, 4)];
|
Tile b = dest.getNearby(Mathf.mod(dir + 1, 4));
|
||||||
boolean ac = a.block().acceptItem(item, a, dest);
|
boolean ac = a.block().acceptItem(item, a, dest);
|
||||||
boolean bc = b.block().acceptItem(item, b, dest);
|
boolean bc = b.block().acceptItem(item, b, dest);
|
||||||
|
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ public class Splitter extends Block{
|
|||||||
if(dir == -1) return null;
|
if(dir == -1) return null;
|
||||||
Tile to;
|
Tile to;
|
||||||
|
|
||||||
Tile a = dest.getNearby()[Mathf.mod(dir - 1, 4)];
|
Tile a = dest.getNearby(Mathf.mod(dir - 1, 4));
|
||||||
Tile b = dest.getNearby()[Mathf.mod(dir + 1, 4)];
|
Tile b = dest.getNearby(Mathf.mod(dir + 1, 4));
|
||||||
boolean ac = a.block().acceptItem(item, a, dest);
|
boolean ac = a.block().acceptItem(item, a, dest);
|
||||||
boolean bc = b.block().acceptItem(item, b, dest);
|
boolean bc = b.block().acceptItem(item, b, dest);
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public class TunnelConveyor extends Block{
|
|||||||
Tile to = tunnel.getNearby(tunnel.getRotation());
|
Tile to = tunnel.getNearby(tunnel.getRotation());
|
||||||
if(to == null) return;
|
if(to == null) return;
|
||||||
|
|
||||||
entity.buffer[entity.index ++] = item.id;
|
entity.buffer[entity.index ++] = Bits.packLong(NumberUtils.floatToIntBits(Timers.time()), item.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -48,9 +48,7 @@ public class TunnelConveyor extends Block{
|
|||||||
|
|
||||||
if(Timers.time() >= time + speed){
|
if(Timers.time() >= time + speed){
|
||||||
|
|
||||||
int val = Bits.getRightInt(l);
|
Item item = Item.getByID(Bits.getRightInt(l));
|
||||||
|
|
||||||
Item item = Item.getByID(Bits.getLeftShort(val));
|
|
||||||
|
|
||||||
Tile tunnel = getDestTunnel(tile, item);
|
Tile tunnel = getDestTunnel(tile, item);
|
||||||
if(tunnel == null) return;
|
if(tunnel == null) return;
|
||||||
|
|||||||
@@ -25,6 +25,9 @@ public class Generator extends PowerBlock{
|
|||||||
public static final int powerTime = 2;
|
public static final int powerTime = 2;
|
||||||
public static boolean drawRangeOverlay = false;
|
public static boolean drawRangeOverlay = false;
|
||||||
|
|
||||||
|
protected Translator t1 = new Translator();
|
||||||
|
protected Translator t2 = new Translator();
|
||||||
|
|
||||||
public int laserRange = 6;
|
public int laserRange = 6;
|
||||||
public int laserDirections = 4;
|
public int laserDirections = 4;
|
||||||
public float powerSpeed = 0.5f;
|
public float powerSpeed = 0.5f;
|
||||||
@@ -177,10 +180,10 @@ public class Generator extends PowerBlock{
|
|||||||
if(target != null){
|
if(target != null){
|
||||||
boolean interfering = isInterfering(target, rotation);
|
boolean interfering = isInterfering(target, rotation);
|
||||||
|
|
||||||
Tmp.v1.set(Angles.translation(rotation * 90, target.block().width * tilesize / 2 + 2f +
|
t1.trns(rotation * 90, target.block().width * tilesize / 2 + 2f +
|
||||||
(interfering ? Vector2.dst(tile.worldx(), tile.worldy(), target.worldx(), target.worldy()) / 2f - tilesize / 2f * target.block().width + 1 : 0)));
|
(interfering ? Vector2.dst(tile.worldx(), tile.worldy(), target.worldx(), target.worldy()) / 2f - tilesize / 2f * target.block().width + 1 : 0));
|
||||||
|
|
||||||
Angles.translation(rotation * 90, width * tilesize / 2 + 2f);
|
t2.trns(rotation * 90, width * tilesize / 2 + 2f);
|
||||||
|
|
||||||
if(!interfering){
|
if(!interfering){
|
||||||
Draw.tint(Hue.mix(Color.GRAY, Color.WHITE, 0.904f + Mathf.sin(Timers.time(), 1.7f, 0.06f)));
|
Draw.tint(Hue.mix(Color.GRAY, Color.WHITE, 0.904f + Mathf.sin(Timers.time(), 1.7f, 0.06f)));
|
||||||
@@ -188,7 +191,7 @@ public class Generator extends PowerBlock{
|
|||||||
Draw.tint(Hue.mix(Color.SCARLET, Color.WHITE, 0.902f + Mathf.sin(Timers.time(), 1.7f, 0.08f)));
|
Draw.tint(Hue.mix(Color.SCARLET, Color.WHITE, 0.902f + Mathf.sin(Timers.time(), 1.7f, 0.08f)));
|
||||||
|
|
||||||
if(state.is(State.playing) && Mathf.chance(Timers.delta() * 0.033)){
|
if(state.is(State.playing) && Mathf.chance(Timers.delta() * 0.033)){
|
||||||
Effects.effect(Fx.laserspark, target.worldx() - Tmp.v1.x, target.worldy() - Tmp.v1.y);
|
Effects.effect(Fx.laserspark, target.worldx() - t1.x, target.worldy() - t1.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,9 +200,9 @@ public class Generator extends PowerBlock{
|
|||||||
int relative = tile.relativeTo(target.x, target.y);
|
int relative = tile.relativeTo(target.x, target.y);
|
||||||
|
|
||||||
if(relative == -1){
|
if(relative == -1){
|
||||||
Shapes.laser("laser", "laserend", tile.worldx() + Angles.x(), tile.worldy() + Angles.y(),
|
Shapes.laser("laser", "laserend", tile.worldx() + t2.x, tile.worldy() + t2.y,
|
||||||
target.worldx() - Tmp.v1.x + Mathf.range(r),
|
target.worldx() - t1.x + Mathf.range(r),
|
||||||
target.worldy() - Tmp.v1.y + Mathf.range(r), 0.7f);
|
target.worldy() - t1.y + Mathf.range(r), 0.7f);
|
||||||
}else{
|
}else{
|
||||||
Draw.rect("laserfull",
|
Draw.rect("laserfull",
|
||||||
tile.worldx() + Geometry.d4[relative].x * width * tilesize / 2f,
|
tile.worldx() + Geometry.d4[relative].x * width * tilesize / 2f,
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import io.anuke.ucore.core.Timers;
|
|||||||
import io.anuke.ucore.graphics.Draw;
|
import io.anuke.ucore.graphics.Draw;
|
||||||
import io.anuke.ucore.util.Mathf;
|
import io.anuke.ucore.util.Mathf;
|
||||||
import io.anuke.ucore.util.Strings;
|
import io.anuke.ucore.util.Strings;
|
||||||
import io.anuke.ucore.util.Tmp;
|
import io.anuke.ucore.util.Translator;
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
@@ -25,6 +25,8 @@ import static io.anuke.mindustry.Vars.tilesize;
|
|||||||
public class NuclearReactor extends LiquidPowerGenerator{
|
public class NuclearReactor extends LiquidPowerGenerator{
|
||||||
protected final int timerFuel = timers++;
|
protected final int timerFuel = timers++;
|
||||||
|
|
||||||
|
protected final Translator tr = new Translator();
|
||||||
|
|
||||||
protected Item generateItem;
|
protected Item generateItem;
|
||||||
protected int itemCapacity = 30;
|
protected int itemCapacity = 30;
|
||||||
protected Color coolColor = new Color(1, 1, 1, 0f);
|
protected Color coolColor = new Color(1, 1, 1, 0f);
|
||||||
@@ -137,15 +139,15 @@ public class NuclearReactor extends LiquidPowerGenerator{
|
|||||||
|
|
||||||
for(int i = 0; i < 20; i ++){
|
for(int i = 0; i < 20; i ++){
|
||||||
Timers.run(Mathf.random(50), ()->{
|
Timers.run(Mathf.random(50), ()->{
|
||||||
Tmp.v1.setToRandomDirection().setLength(Mathf.random(40f));
|
tr.rnd(Mathf.random(40f));
|
||||||
Effects.effect(Fx.explosion, Tmp.v1.x + tile.worldx(), Tmp.v1.y + tile.worldy());
|
Effects.effect(Fx.explosion, tr.x + tile.worldx(), tr.y + tile.worldy());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0; i < 70; i ++){
|
for(int i = 0; i < 70; i ++){
|
||||||
Timers.run(Mathf.random(80), ()->{
|
Timers.run(Mathf.random(80), ()->{
|
||||||
Tmp.v1.setToRandomDirection().setLength(Mathf.random(120f));
|
tr.rnd(Mathf.random(120f));
|
||||||
Effects.effect(Fx.nuclearsmoke, Tmp.v1.x + tile.worldx(), Tmp.v1.y + tile.worldy());
|
Effects.effect(Fx.nuclearsmoke, tr.x + tile.worldx(), tr.y + tile.worldy());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,9 @@ package io.anuke.mindustry.desktop;
|
|||||||
import club.minnced.discord.rpc.DiscordEventHandlers;
|
import club.minnced.discord.rpc.DiscordEventHandlers;
|
||||||
import club.minnced.discord.rpc.DiscordRPC;
|
import club.minnced.discord.rpc.DiscordRPC;
|
||||||
import club.minnced.discord.rpc.DiscordRichPresence;
|
import club.minnced.discord.rpc.DiscordRichPresence;
|
||||||
|
import io.anuke.kryonet.DefaultThreadImpl;
|
||||||
import io.anuke.mindustry.core.GameState.State;
|
import io.anuke.mindustry.core.GameState.State;
|
||||||
|
import io.anuke.mindustry.core.ThreadHandler.ThreadProvider;
|
||||||
import io.anuke.mindustry.io.Platform;
|
import io.anuke.mindustry.io.Platform;
|
||||||
import io.anuke.mindustry.net.Net;
|
import io.anuke.mindustry.net.Net;
|
||||||
import io.anuke.ucore.util.Strings;
|
import io.anuke.ucore.util.Strings;
|
||||||
@@ -85,4 +87,9 @@ public class DesktopPlatform extends Platform {
|
|||||||
public boolean isDebug() {
|
public boolean isDebug() {
|
||||||
return args.length > 0 && args[0].equalsIgnoreCase("-debug");
|
return args.length > 0 && args[0].equalsIgnoreCase("-debug");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ThreadProvider getThreadProvider() {
|
||||||
|
return new DefaultThreadImpl();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
40
kryonet/src/io/anuke/kryonet/DefaultThreadImpl.java
Normal file
40
kryonet/src/io/anuke/kryonet/DefaultThreadImpl.java
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package io.anuke.kryonet;
|
||||||
|
|
||||||
|
import io.anuke.mindustry.core.ThreadHandler.ThreadProvider;
|
||||||
|
import io.anuke.ucore.util.Log;
|
||||||
|
|
||||||
|
public class DefaultThreadImpl implements ThreadProvider {
|
||||||
|
private Thread thread;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isOnThread() {
|
||||||
|
return Thread.currentThread() == thread;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sleep(long ms) throws InterruptedException{
|
||||||
|
Thread.sleep(ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start(Runnable run) {
|
||||||
|
if(thread != null){
|
||||||
|
thread.interrupt();
|
||||||
|
thread = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
thread = new Thread(run);
|
||||||
|
thread.setDaemon(true);
|
||||||
|
thread.setName("Update Thread");
|
||||||
|
thread.start();
|
||||||
|
Log.info("Starting logic thread.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stop() {
|
||||||
|
if(thread != null){
|
||||||
|
thread.interrupt();
|
||||||
|
thread = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user