Added freebuild / Power system fix / Net packet pool fix / Crash fixes
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
text.about=Created by [ROYAL]Anuken[] - [SKY]anukendev@gmail.com[]
|
text.about=Created by [ROYAL]Anuken[] - [SKY]anukendev@gmail.com[]
|
||||||
text.credits=Credits
|
text.credits=Credits
|
||||||
text.discord=Join the mindustry discord!
|
text.discord=Join the mindustry discord!
|
||||||
text.changes=[SCARLET]Attention!\n[]Some important game mechanics have been changed.\n\n- [accent]Teleporters[] now use power.\n- [accent]Smelteries[] and [accent]crucibles[] now have a maximum item capacity.\n- [accent]Crucibles[] now require coal as fuel.
|
|
||||||
text.link.discord.description=the official Mindustry discord chatroom
|
text.link.discord.description=the official Mindustry discord chatroom
|
||||||
text.link.github.description=Game source code
|
text.link.github.description=Game source code
|
||||||
text.link.dev-builds.description=Unstable development builds
|
text.link.dev-builds.description=Unstable development builds
|
||||||
@@ -271,15 +270,6 @@ text.info.title=[accent]Info
|
|||||||
text.error.title=[crimson]An error has occured
|
text.error.title=[crimson]An error has occured
|
||||||
text.error.crashmessage=[SCARLET]An unexpected error has occured, which would have caused a crash.\n[]Please report the exact circumstances under which this error occured to the developer: \n[ORANGE]anukendev@gmail.com[]
|
text.error.crashmessage=[SCARLET]An unexpected error has occured, which would have caused a crash.\n[]Please report the exact circumstances under which this error occured to the developer: \n[ORANGE]anukendev@gmail.com[]
|
||||||
text.error.crashtitle=An error has occured
|
text.error.crashtitle=An error has occured
|
||||||
text.mode.break=Break mode: {0}
|
|
||||||
text.mode.place=Place mode: {0}
|
|
||||||
placemode.hold.name=line
|
|
||||||
placemode.areadelete.name=area
|
|
||||||
placemode.touchdelete.name=touch
|
|
||||||
placemode.holddelete.name=hold
|
|
||||||
placemode.none.name=none
|
|
||||||
placemode.touch.name=touch
|
|
||||||
placemode.cursor.name=cursor
|
|
||||||
text.blocks.blockinfo=Block Info
|
text.blocks.blockinfo=Block Info
|
||||||
text.blocks.powercapacity=Power Capacity
|
text.blocks.powercapacity=Power Capacity
|
||||||
text.blocks.powershot=Power/Shot
|
text.blocks.powershot=Power/Shot
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ public class PowerBlocks extends BlockList implements ContentList {
|
|||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load() {
|
||||||
combustionGenerator = new BurnerGenerator("combustion-generator") {{
|
combustionGenerator = new BurnerGenerator("combustion-generator") {{
|
||||||
powerOutput = 0.06f;
|
powerOutput = 0.09f;
|
||||||
powerCapacity = 40f;
|
powerCapacity = 40f;
|
||||||
itemDuration = 40f;
|
itemDuration = 40f;
|
||||||
}};
|
}};
|
||||||
@@ -27,7 +27,7 @@ public class PowerBlocks extends BlockList implements ContentList {
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
turbineGenerator = new TurbineGenerator("turbine-generator") {{
|
turbineGenerator = new TurbineGenerator("turbine-generator") {{
|
||||||
powerOutput = 0.15f;
|
powerOutput = 0.25f;
|
||||||
powerCapacity = 40f;
|
powerCapacity = 40f;
|
||||||
itemDuration = 30f;
|
itemDuration = 30f;
|
||||||
size = 2;
|
size = 2;
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
package io.anuke.mindustry.core;
|
package io.anuke.mindustry.core;
|
||||||
|
|
||||||
import com.badlogic.gdx.utils.*;
|
import com.badlogic.gdx.utils.Array;
|
||||||
|
import com.badlogic.gdx.utils.ObjectSet;
|
||||||
|
import com.badlogic.gdx.utils.OrderedMap;
|
||||||
|
import com.badlogic.gdx.utils.OrderedSet;
|
||||||
import io.anuke.mindustry.content.*;
|
import io.anuke.mindustry.content.*;
|
||||||
import io.anuke.mindustry.content.blocks.*;
|
import io.anuke.mindustry.content.blocks.*;
|
||||||
import io.anuke.mindustry.content.bullets.*;
|
import io.anuke.mindustry.content.bullets.*;
|
||||||
@@ -28,6 +31,7 @@ public class ContentLoader {
|
|||||||
private static boolean loaded = false;
|
private static boolean loaded = false;
|
||||||
private static ObjectSet<Array<? extends Content>> contentSet = new OrderedSet<>();
|
private static ObjectSet<Array<? extends Content>> contentSet = new OrderedSet<>();
|
||||||
private static OrderedMap<String, Array<Content>> contentMap = new OrderedMap<>();
|
private static OrderedMap<String, Array<Content>> contentMap = new OrderedMap<>();
|
||||||
|
private static ObjectSet<Consumer<Content>> initialization = new ObjectSet<>();
|
||||||
private static ContentList[] content = {
|
private static ContentList[] content = {
|
||||||
//effects
|
//effects
|
||||||
new BlockFx(),
|
new BlockFx(),
|
||||||
@@ -132,11 +136,15 @@ public class ContentLoader {
|
|||||||
|
|
||||||
/**Initializes all content with the specified function.*/
|
/**Initializes all content with the specified function.*/
|
||||||
public static void initialize(Consumer<Content> callable){
|
public static void initialize(Consumer<Content> callable){
|
||||||
|
if(initialization.contains(callable)) return;
|
||||||
|
|
||||||
for(Array<? extends Content> arr : contentSet){
|
for(Array<? extends Content> arr : contentSet){
|
||||||
for(Content content : arr){
|
for(Content content : arr){
|
||||||
callable.accept(content);
|
callable.accept(content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initialization.add(callable);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void dispose(){
|
public static void dispose(){
|
||||||
|
|||||||
@@ -13,10 +13,10 @@ import io.anuke.mindustry.entities.TileEntity;
|
|||||||
import io.anuke.mindustry.game.Content;
|
import io.anuke.mindustry.game.Content;
|
||||||
import io.anuke.mindustry.game.ContentDatabase;
|
import io.anuke.mindustry.game.ContentDatabase;
|
||||||
import io.anuke.mindustry.game.EventType.*;
|
import io.anuke.mindustry.game.EventType.*;
|
||||||
import io.anuke.mindustry.input.MobileInput;
|
|
||||||
import io.anuke.mindustry.input.DefaultKeybinds;
|
import io.anuke.mindustry.input.DefaultKeybinds;
|
||||||
import io.anuke.mindustry.input.DesktopInput;
|
import io.anuke.mindustry.input.DesktopInput;
|
||||||
import io.anuke.mindustry.input.InputHandler;
|
import io.anuke.mindustry.input.InputHandler;
|
||||||
|
import io.anuke.mindustry.input.MobileInput;
|
||||||
import io.anuke.mindustry.io.Map;
|
import io.anuke.mindustry.io.Map;
|
||||||
import io.anuke.mindustry.io.Saves;
|
import io.anuke.mindustry.io.Saves;
|
||||||
import io.anuke.mindustry.net.Net;
|
import io.anuke.mindustry.net.Net;
|
||||||
@@ -285,6 +285,7 @@ public class Control extends Module{
|
|||||||
@Override
|
@Override
|
||||||
public void dispose(){
|
public void dispose(){
|
||||||
Platform.instance.onGameExit();
|
Platform.instance.onGameExit();
|
||||||
|
ContentLoader.dispose();
|
||||||
Net.dispose();
|
Net.dispose();
|
||||||
ui.editor.dispose();
|
ui.editor.dispose();
|
||||||
}
|
}
|
||||||
@@ -321,6 +322,18 @@ public class Control extends Module{
|
|||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!Settings.has("4.0-no-sound")){
|
||||||
|
Settings.putBool("4.0-no-sound", true);
|
||||||
|
|
||||||
|
Timers.runTask(4f, () -> {
|
||||||
|
FloatingDialog dialog = new FloatingDialog("[orange]Attention![]");
|
||||||
|
dialog.buttons().addButton("$text.ok", dialog::hide).size(100f, 60f);
|
||||||
|
dialog.content().add("You might have noticed that 4.0 does not have any sound.\nThis is [orange]intentional![] Sound will be added in a later update.\n\n[LIGHT_GRAY](now stop reporting this as a bug)").wrap().width(500f);
|
||||||
|
dialog.show();
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Called from main logic thread.*/
|
/**Called from main logic thread.*/
|
||||||
@@ -355,7 +368,7 @@ public class Control extends Module{
|
|||||||
}
|
}
|
||||||
|
|
||||||
//check unlocks every 2 seconds
|
//check unlocks every 2 seconds
|
||||||
if(!state.mode.infiniteResources && !state.mode.disableWaveTimer && Timers.get("timerCheckUnlock", 120)){
|
if(!state.mode.infiniteResources && Timers.get("timerCheckUnlock", 120)){
|
||||||
checkUnlockableBlocks();
|
checkUnlockableBlocks();
|
||||||
|
|
||||||
//save if the db changed, but don't save unlocks
|
//save if the db changed, but don't save unlocks
|
||||||
|
|||||||
@@ -12,8 +12,6 @@ public class GameState{
|
|||||||
|
|
||||||
public int wave = 1;
|
public int wave = 1;
|
||||||
public float wavetime;
|
public float wavetime;
|
||||||
public float extrawavetime;
|
|
||||||
public int enemies = 0;
|
|
||||||
public boolean gameOver = false;
|
public boolean gameOver = false;
|
||||||
public GameMode mode = GameMode.waves;
|
public GameMode mode = GameMode.waves;
|
||||||
public Difficulty difficulty = Difficulty.normal;
|
public Difficulty difficulty = Difficulty.normal;
|
||||||
|
|||||||
@@ -70,9 +70,7 @@ public class Logic extends Module {
|
|||||||
|
|
||||||
public void reset(){
|
public void reset(){
|
||||||
state.wave = 1;
|
state.wave = 1;
|
||||||
state.extrawavetime = maxwavespace * state.difficulty.maxTimeScaling;
|
|
||||||
state.wavetime = wavespace * state.difficulty.timeScaling;
|
state.wavetime = wavespace * state.difficulty.timeScaling;
|
||||||
state.enemies = 0;
|
|
||||||
state.gameOver = false;
|
state.gameOver = false;
|
||||||
state.teams = new TeamInfo();
|
state.teams = new TeamInfo();
|
||||||
state.teams.add(Team.blue, true);
|
state.teams.add(Team.blue, true);
|
||||||
@@ -89,7 +87,6 @@ public class Logic extends Module {
|
|||||||
state.spawner.spawnEnemies();
|
state.spawner.spawnEnemies();
|
||||||
state.wave ++;
|
state.wave ++;
|
||||||
state.wavetime = wavespace * state.difficulty.timeScaling;
|
state.wavetime = wavespace * state.difficulty.timeScaling;
|
||||||
state.extrawavetime = maxwavespace * state.difficulty.maxTimeScaling;
|
|
||||||
|
|
||||||
Events.fire(WaveEvent.class);
|
Events.fire(WaveEvent.class);
|
||||||
}
|
}
|
||||||
@@ -133,15 +130,10 @@ public class Logic extends Module {
|
|||||||
if(!state.is(State.paused) || Net.active()){
|
if(!state.is(State.paused) || Net.active()){
|
||||||
|
|
||||||
if(!state.mode.disableWaveTimer){
|
if(!state.mode.disableWaveTimer){
|
||||||
|
state.wavetime -= Timers.delta();
|
||||||
if(state.enemies <= 0){
|
|
||||||
if(!world.getMap().name.equals("tutorial")) state.wavetime -= Timers.delta();
|
|
||||||
}else{
|
|
||||||
state.extrawavetime -= Timers.delta();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!Net.client() && (state.wavetime <= 0 || state.extrawavetime <= 0)){
|
if(!Net.client() && state.wavetime <= 0){
|
||||||
runWave();
|
runWave();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -92,8 +92,6 @@ public class UI extends SceneModule{
|
|||||||
|
|
||||||
Settings.setErrorHandler(()-> Timers.run(1f, ()-> showError("[crimson]Failed to access local storage.\nSettings will not be saved.")));
|
Settings.setErrorHandler(()-> Timers.run(1f, ()-> showError("[crimson]Failed to access local storage.\nSettings will not be saved.")));
|
||||||
|
|
||||||
Settings.defaults("pixelate", true);
|
|
||||||
|
|
||||||
Dialog.closePadR = -1;
|
Dialog.closePadR = -1;
|
||||||
Dialog.closePadT = 5;
|
Dialog.closePadT = 5;
|
||||||
|
|
||||||
|
|||||||
@@ -268,6 +268,11 @@ public class MapEditor{
|
|||||||
|
|
||||||
public void resize(int width, int height){
|
public void resize(int width, int height){
|
||||||
map = new MapTileData(width, height);
|
map = new MapTileData(width, height);
|
||||||
|
for (int x = 0; x < map.width(); x++) {
|
||||||
|
for (int y = 0; y < map.height(); y++) {
|
||||||
|
map.write(x, y, DataPosition.floor, (byte)Blocks.stone.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
renderer.resize(width, height);
|
renderer.resize(width, height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -369,8 +369,8 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
public void updateSelectedBlock(){
|
public void updateSelectedBlock(){
|
||||||
Block block = editor.getDrawBlock();
|
Block block = editor.getDrawBlock();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for(Block test : Block.all()){
|
for(int j = 0; j < Block.all().size; j ++){
|
||||||
if(block == test){
|
if(block.id == j){
|
||||||
blockgroup.getButtons().get(i).setChecked(true);
|
blockgroup.getButtons().get(i).setChecked(true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ public class MapRenderer implements Disposable{
|
|||||||
while(it.hasNext){
|
while(it.hasNext){
|
||||||
int i = it.next();
|
int i = it.next();
|
||||||
int x = i % width;
|
int x = i % width;
|
||||||
int y = i / height;
|
int y = i / width;
|
||||||
render(x, y);
|
render(x, y);
|
||||||
}
|
}
|
||||||
updates.clear();
|
updates.clear();
|
||||||
|
|||||||
@@ -610,7 +610,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
|||||||
if (target == null) {
|
if (target == null) {
|
||||||
isShooting = false;
|
isShooting = false;
|
||||||
target = Units.getClosestTarget(team, x, y, inventory.getAmmoRange());
|
target = Units.getClosestTarget(team, x, y, inventory.getAmmoRange());
|
||||||
} else {
|
} else if(target.isValid()){
|
||||||
//rotate toward and shoot the target
|
//rotate toward and shoot the target
|
||||||
rotation = Mathf.slerpDelta(rotation, angleTo(target), 0.2f);
|
rotation = Mathf.slerpDelta(rotation, angleTo(target), 0.2f);
|
||||||
|
|
||||||
@@ -697,12 +697,18 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
|||||||
public void readSave(DataInput stream) throws IOException {
|
public void readSave(DataInput stream) throws IOException {
|
||||||
boolean local = stream.readBoolean();
|
boolean local = stream.readBoolean();
|
||||||
|
|
||||||
if(local){
|
if(local && !headless){
|
||||||
byte mechid = stream.readByte();
|
byte mechid = stream.readByte();
|
||||||
int index = stream.readByte();
|
int index = stream.readByte();
|
||||||
players[index].readSaveSuper(stream);
|
players[index].readSaveSuper(stream);
|
||||||
players[index].mech = Upgrade.getByID(mechid);
|
players[index].mech = Upgrade.getByID(mechid);
|
||||||
players[index].dead = false;
|
players[index].dead = false;
|
||||||
|
}else if(local){
|
||||||
|
byte mechid = stream.readByte();
|
||||||
|
stream.readByte();
|
||||||
|
readSaveSuper(stream);
|
||||||
|
mech = Upgrade.getByID(mechid);
|
||||||
|
dead = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable
|
|||||||
|
|
||||||
/**Start a fire on the tile. If there already is a file there, refreshes its lifetime.*/
|
/**Start a fire on the tile. If there already is a file there, refreshes its lifetime.*/
|
||||||
public static void create(Tile tile){
|
public static void create(Tile tile){
|
||||||
if(Net.client()) return; //not clientside.
|
if(Net.client() || tile == null) return; //not clientside.
|
||||||
|
|
||||||
Fire fire = map.get(tile.packedPosition());
|
Fire fire = map.get(tile.packedPosition());
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable
|
|||||||
|
|
||||||
/**Attempts to extinguish a fire by shortening its life. If there is no fire here, does nothing.*/
|
/**Attempts to extinguish a fire by shortening its life. If there is no fire here, does nothing.*/
|
||||||
public static void extinguish(Tile tile, float intensity) {
|
public static void extinguish(Tile tile, float intensity) {
|
||||||
if (map.containsKey(tile.packedPosition())) {
|
if (tile != null && map.containsKey(tile.packedPosition())) {
|
||||||
map.get(tile.packedPosition()).time += intensity * Timers.delta();
|
map.get(tile.packedPosition()).time += intensity * Timers.delta();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ public class ItemDrop extends SolidEntity implements SaveTrait, SyncTrait, DrawT
|
|||||||
Effects.effect(UnitFx.pickup, drop);
|
Effects.effect(UnitFx.pickup, drop);
|
||||||
}
|
}
|
||||||
itemGroup.removeByID(itemid);
|
itemGroup.removeByID(itemid);
|
||||||
|
netClient.addRemovedEntity(itemid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Internal use only!*/
|
/**Internal use only!*/
|
||||||
|
|||||||
@@ -4,12 +4,13 @@ import io.anuke.ucore.util.Bundles;
|
|||||||
|
|
||||||
public enum GameMode{
|
public enum GameMode{
|
||||||
waves,
|
waves,
|
||||||
sandbox{
|
//disabled for technical reasons
|
||||||
|
/*sandbox{
|
||||||
{
|
{
|
||||||
infiniteResources = true;
|
infiniteResources = true;
|
||||||
disableWaveTimer = true;
|
disableWaveTimer = true;
|
||||||
}
|
}
|
||||||
},
|
},*/
|
||||||
freebuild{
|
freebuild{
|
||||||
{
|
{
|
||||||
disableWaveTimer = true;
|
disableWaveTimer = true;
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ public class OverlayRenderer {
|
|||||||
drawbars.run();
|
drawbars.run();
|
||||||
|
|
||||||
if(values[0] > 0){
|
if(values[0] > 0){
|
||||||
drawEncloser(target.drawx(), target.drawy() + block.size * tilesize/2f + 2f + values[0]/2f - 0.5f + (values[0] > 2 ? 0.5f : 0), values[0]);
|
drawEncloser(target.drawx(), target.drawy() + block.size * tilesize/2f + 2f + values[0]/2f - 0.5f + (values[0] > 1 ? 0.75f : 0), values[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(values[1] > 0){
|
if(values[1] > 0){
|
||||||
|
|||||||
@@ -353,7 +353,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
if(tile != null){
|
if(tile != null){
|
||||||
|
|
||||||
//draw placing
|
//draw placing
|
||||||
if(mode == placing) {
|
if(mode == placing && recipe != null) {
|
||||||
NormalizeDrawResult dresult = PlaceUtils.normalizeDrawArea(recipe.result, lineStartX, lineStartY, tile.x, tile.y, true, maxLength, lineScale);
|
NormalizeDrawResult dresult = PlaceUtils.normalizeDrawArea(recipe.result, lineStartX, lineStartY, tile.x, tile.y, true, maxLength, lineScale);
|
||||||
|
|
||||||
Lines.rect(dresult.x, dresult.y, dresult.x2 - dresult.x, dresult.y2 - dresult.y);
|
Lines.rect(dresult.x, dresult.y, dresult.x2 - dresult.x, dresult.y2 - dresult.y);
|
||||||
@@ -465,7 +465,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
|
|
||||||
if (tile == null) return false;
|
if (tile == null) return false;
|
||||||
|
|
||||||
if(mode == placing) {
|
if(mode == placing && recipe != null) {
|
||||||
|
|
||||||
//normalize area
|
//normalize area
|
||||||
NormalizeResult result = PlaceUtils.normalizeArea(lineStartX, lineStartY, tile.x, tile.y, rotation, true, 100);
|
NormalizeResult result = PlaceUtils.normalizeArea(lineStartX, lineStartY, tile.x, tile.y, rotation, true, 100);
|
||||||
@@ -599,6 +599,10 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
selection.clear();
|
selection.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(lineMode && mode == placing && recipe == null){
|
||||||
|
lineMode = false;
|
||||||
|
}
|
||||||
|
|
||||||
//if there is no mode and there's a recipe, switch to placing
|
//if there is no mode and there's a recipe, switch to placing
|
||||||
if(recipe != null && mode == none){
|
if(recipe != null && mode == none){
|
||||||
mode = placing;
|
mode = placing;
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import io.anuke.ucore.entities.Entities;
|
|||||||
import io.anuke.ucore.entities.EntityGroup;
|
import io.anuke.ucore.entities.EntityGroup;
|
||||||
import io.anuke.ucore.entities.trait.Entity;
|
import io.anuke.ucore.entities.trait.Entity;
|
||||||
import io.anuke.ucore.util.Bits;
|
import io.anuke.ucore.util.Bits;
|
||||||
import io.anuke.ucore.util.Log;
|
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
@@ -51,7 +50,6 @@ public class Save16 extends SaveFileVersion {
|
|||||||
|
|
||||||
state.difficulty = Difficulty.values()[difficulty];
|
state.difficulty = Difficulty.values()[difficulty];
|
||||||
state.mode = GameMode.values()[mode];
|
state.mode = GameMode.values()[mode];
|
||||||
state.enemies = 0; //TODO display enemies correctly!
|
|
||||||
state.wave = wave;
|
state.wave = wave;
|
||||||
state.wavetime = wavetime;
|
state.wavetime = wavetime;
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ public class Net{
|
|||||||
private static boolean active;
|
private static boolean active;
|
||||||
private static boolean clientLoaded;
|
private static boolean clientLoaded;
|
||||||
private static Array<Object> packetQueue = new Array<>();
|
private static Array<Object> packetQueue = new Array<>();
|
||||||
private static ObjectMap<Class<?>, Consumer> listeners = new ObjectMap<>();
|
|
||||||
private static ObjectMap<Class<?>, Consumer> clientListeners = new ObjectMap<>();
|
private static ObjectMap<Class<?>, Consumer> clientListeners = new ObjectMap<>();
|
||||||
private static ObjectMap<Class<?>, BiConsumer<Integer, Object>> serverListeners = new ObjectMap<>();
|
private static ObjectMap<Class<?>, BiConsumer<Integer, Object>> serverListeners = new ObjectMap<>();
|
||||||
private static ClientProvider clientProvider;
|
private static ClientProvider clientProvider;
|
||||||
@@ -146,11 +145,6 @@ public class Net{
|
|||||||
Net.serverProvider = provider;
|
Net.serverProvider = provider;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Registers a common listener for when an object is recieved. Fired on both client and serve.r*/
|
|
||||||
public static <T> void handle(Class<T> type, Consumer<T> listener){
|
|
||||||
listeners.put(type, listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**Registers a client listener for when an object is recieved.*/
|
/**Registers a client listener for when an object is recieved.*/
|
||||||
public static <T> void handleClient(Class<T> type, Consumer<T> listener){
|
public static <T> void handleClient(Class<T> type, Consumer<T> listener){
|
||||||
clientListeners.put(type, listener);
|
clientListeners.put(type, listener);
|
||||||
@@ -178,12 +172,10 @@ public class Net{
|
|||||||
streams.remove(builder.id);
|
streams.remove(builder.id);
|
||||||
handleClientReceived(builder.build());
|
handleClientReceived(builder.build());
|
||||||
}
|
}
|
||||||
}else if(clientListeners.get(object.getClass()) != null ||
|
}else if(clientListeners.get(object.getClass()) != null){
|
||||||
listeners.get(object.getClass()) != null){
|
|
||||||
|
|
||||||
if(clientLoaded || ((object instanceof Packet) && ((Packet) object).isImportant())){
|
if(clientLoaded || ((object instanceof Packet) && ((Packet) object).isImportant())){
|
||||||
if(clientListeners.get(object.getClass()) != null) clientListeners.get(object.getClass()).accept(object);
|
if(clientListeners.get(object.getClass()) != null) clientListeners.get(object.getClass()).accept(object);
|
||||||
if(listeners.get(object.getClass()) != null) listeners.get(object.getClass()).accept(object);
|
|
||||||
synchronized (packetPoolLock) {
|
synchronized (packetPoolLock) {
|
||||||
Pooling.free(object);
|
Pooling.free(object);
|
||||||
}
|
}
|
||||||
@@ -203,9 +195,8 @@ public class Net{
|
|||||||
/**Call to handle a packet being recieved for the server.*/
|
/**Call to handle a packet being recieved for the server.*/
|
||||||
public static void handleServerReceived(int connection, Object object){
|
public static void handleServerReceived(int connection, Object object){
|
||||||
|
|
||||||
if(serverListeners.get(object.getClass()) != null || listeners.get(object.getClass()) != null){
|
if(serverListeners.get(object.getClass()) != null){
|
||||||
if(serverListeners.get(object.getClass()) != null) serverListeners.get(object.getClass()).accept(connection, object);
|
if(serverListeners.get(object.getClass()) != null) serverListeners.get(object.getClass()).accept(connection, object);
|
||||||
if(listeners.get(object.getClass()) != null) listeners.get(object.getClass()).accept(object);
|
|
||||||
synchronized (packetPoolLock) {
|
synchronized (packetPoolLock) {
|
||||||
Pooling.free(object);
|
Pooling.free(object);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,19 +4,20 @@ import com.badlogic.gdx.Gdx;
|
|||||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||||
import com.badlogic.gdx.utils.Align;
|
import com.badlogic.gdx.utils.Align;
|
||||||
import io.anuke.mindustry.game.Difficulty;
|
import io.anuke.mindustry.game.Difficulty;
|
||||||
import io.anuke.mindustry.game.EventType.ResizeEvent;
|
|
||||||
import io.anuke.mindustry.game.GameMode;
|
import io.anuke.mindustry.game.GameMode;
|
||||||
import io.anuke.mindustry.io.Map;
|
import io.anuke.mindustry.io.Map;
|
||||||
import io.anuke.mindustry.ui.BorderImage;
|
import io.anuke.mindustry.ui.BorderImage;
|
||||||
import io.anuke.ucore.core.Events;
|
|
||||||
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.Draw;
|
import io.anuke.ucore.graphics.Draw;
|
||||||
import io.anuke.ucore.scene.event.Touchable;
|
import io.anuke.ucore.scene.event.Touchable;
|
||||||
|
import io.anuke.ucore.scene.ui.ButtonGroup;
|
||||||
import io.anuke.ucore.scene.ui.ImageButton;
|
import io.anuke.ucore.scene.ui.ImageButton;
|
||||||
import io.anuke.ucore.scene.ui.ScrollPane;
|
import io.anuke.ucore.scene.ui.ScrollPane;
|
||||||
|
import io.anuke.ucore.scene.ui.TextButton;
|
||||||
import io.anuke.ucore.scene.ui.layout.Table;
|
import io.anuke.ucore.scene.ui.layout.Table;
|
||||||
import io.anuke.ucore.scene.utils.Cursors;
|
import io.anuke.ucore.scene.utils.Cursors;
|
||||||
|
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;
|
||||||
|
|
||||||
@@ -42,7 +43,7 @@ public class LevelDialog extends FloatingDialog{
|
|||||||
|
|
||||||
int maxwidth = (Gdx.graphics.getHeight() > Gdx.graphics.getHeight() ? 2 : 4);
|
int maxwidth = (Gdx.graphics.getHeight() > Gdx.graphics.getHeight() ? 2 : 4);
|
||||||
|
|
||||||
/*Table selmode = new Table();
|
Table selmode = new Table();
|
||||||
ButtonGroup<TextButton> group = new ButtonGroup<>();
|
ButtonGroup<TextButton> group = new ButtonGroup<>();
|
||||||
selmode.add("$text.level.mode").padRight(15f);
|
selmode.add("$text.level.mode").padRight(15f);
|
||||||
|
|
||||||
@@ -50,14 +51,13 @@ public class LevelDialog extends FloatingDialog{
|
|||||||
TextButton[] b = {null};
|
TextButton[] b = {null};
|
||||||
b[0] = Elements.newButton("$mode." + mode.name() + ".name", "toggle", () -> state.mode = mode);
|
b[0] = Elements.newButton("$mode." + mode.name() + ".name", "toggle", () -> state.mode = mode);
|
||||||
b[0].update(() -> b[0].setChecked(state.mode == mode));
|
b[0].update(() -> b[0].setChecked(state.mode == mode));
|
||||||
b[0].setDisabled(true);
|
|
||||||
group.add(b[0]);
|
group.add(b[0]);
|
||||||
selmode.add(b[0]).size(130f, 54f);
|
selmode.add(b[0]).size(130f, 54f);
|
||||||
}
|
}
|
||||||
selmode.addButton("?", this::displayGameModeHelp).size(50f, 54f).padLeft(18f);
|
selmode.addButton("?", this::displayGameModeHelp).size(50f, 54f).padLeft(18f);
|
||||||
|
|
||||||
content().add(selmode);
|
content().add(selmode);
|
||||||
content().row();*/
|
content().row();
|
||||||
|
|
||||||
Difficulty[] ds = Difficulty.values();
|
Difficulty[] ds = Difficulty.values();
|
||||||
|
|
||||||
|
|||||||
@@ -181,6 +181,8 @@ public class BlockInventoryFragment extends Fragment {
|
|||||||
|
|
||||||
@Remote(called = Loc.server, targets = Loc.both, in = In.blocks, forward = true)
|
@Remote(called = Loc.server, targets = Loc.both, in = In.blocks, forward = true)
|
||||||
public static void requestItem(Player player, Tile tile, Item item, int amount){
|
public static void requestItem(Player player, Tile tile, Item item, int amount){
|
||||||
|
if(player == null) return;
|
||||||
|
|
||||||
int removed = tile.block().removeStack(tile, item, amount);
|
int removed = tile.block().removeStack(tile, item, amount);
|
||||||
|
|
||||||
player.inventory.addItem(item, removed);
|
player.inventory.addItem(item, removed);
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ public class DebugFragment extends Fragment {
|
|||||||
result.append(player.id);
|
result.append(player.id);
|
||||||
result.append("\n");
|
result.append("\n");
|
||||||
result.append(" cid: ");
|
result.append(" cid: ");
|
||||||
result.append(player.con.id);
|
result.append(player.con == null ? -1 : player.con.id);
|
||||||
result.append("\n");
|
result.append("\n");
|
||||||
result.append(" dead: ");
|
result.append(" dead: ");
|
||||||
result.append(player.isDead());
|
result.append(player.isDead());
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import com.badlogic.gdx.math.Interpolation;
|
|||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
import com.badlogic.gdx.utils.Scaling;
|
import com.badlogic.gdx.utils.Scaling;
|
||||||
import io.anuke.mindustry.core.GameState.State;
|
import io.anuke.mindustry.core.GameState.State;
|
||||||
|
import io.anuke.mindustry.game.Team;
|
||||||
import io.anuke.mindustry.net.Net;
|
import io.anuke.mindustry.net.Net;
|
||||||
import io.anuke.mindustry.type.Recipe;
|
import io.anuke.mindustry.type.Recipe;
|
||||||
import io.anuke.mindustry.ui.IntFormat;
|
import io.anuke.mindustry.ui.IntFormat;
|
||||||
@@ -288,10 +289,11 @@ public class HudFragment extends Fragment{
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String getEnemiesRemaining() {
|
private String getEnemiesRemaining() {
|
||||||
if(state.enemies == 1) {
|
int enemies = unitGroups[Team.red.ordinal()].size();
|
||||||
return Bundles.format("text.enemies.single", state.enemies);
|
if(enemies == 1) {
|
||||||
|
return Bundles.format("text.enemies.single", enemies);
|
||||||
} else {
|
} else {
|
||||||
return Bundles.format("text.enemies", state.enemies);
|
return Bundles.format("text.enemies", enemies);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,7 +312,7 @@ public class HudFragment extends Fragment{
|
|||||||
|
|
||||||
row();
|
row();
|
||||||
|
|
||||||
new label(() -> state.enemies > 0 ?
|
new label(() -> unitGroups[Team.red.ordinal()].size() > 0 && state.mode.disableWaveTimer ?
|
||||||
getEnemiesRemaining() :
|
getEnemiesRemaining() :
|
||||||
(state.mode.disableWaveTimer) ? "$text.waiting"
|
(state.mode.disableWaveTimer) ? "$text.waiting"
|
||||||
: timef.get((int) (state.wavetime / 60f)))
|
: timef.get((int) (state.wavetime / 60f)))
|
||||||
@@ -333,10 +335,9 @@ public class HudFragment extends Fragment{
|
|||||||
}).height(uheight).fillX().right().padTop(-8f).padBottom(-12f).padLeft(-15).padRight(-10).width(40f).update(l->{
|
}).height(uheight).fillX().right().padTop(-8f).padBottom(-12f).padLeft(-15).padRight(-10).width(40f).update(l->{
|
||||||
boolean vis = state.mode.disableWaveTimer && (Net.server() || !Net.active());
|
boolean vis = state.mode.disableWaveTimer && (Net.server() || !Net.active());
|
||||||
boolean paused = state.is(State.paused) || !vis;
|
boolean paused = state.is(State.paused) || !vis;
|
||||||
|
|
||||||
l.setVisible(vis);
|
|
||||||
l.getStyle().imageUp = Core.skin.getDrawable(vis ? "icon-play" : "clear");
|
l.getStyle().imageUp = Core.skin.getDrawable(vis ? "icon-play" : "clear");
|
||||||
l.setTouchable(!paused ? Touchable.enabled : Touchable.disabled);
|
l.setTouchable(!paused ? Touchable.enabled : Touchable.disabled);
|
||||||
});
|
}).visible(() -> state.mode.disableWaveTimer && (Net.server() || !Net.active()) && unitGroups[Team.red.ordinal()].size() == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -432,7 +432,7 @@ public class Block extends BaseBlock implements Content{
|
|||||||
|
|
||||||
if(shadowRegions != null) {
|
if(shadowRegions != null) {
|
||||||
Draw.rect(shadowRegions[(Mathf.randomSeed(tile.id(), 0, variants - 1))], tile.worldx(), tile.worldy());
|
Draw.rect(shadowRegions[(Mathf.randomSeed(tile.id(), 0, variants - 1))], tile.worldx(), tile.worldy());
|
||||||
}else{
|
}else if(shadowRegion != null){
|
||||||
Draw.rect(shadowRegion, tile.drawx(), tile.drawy());
|
Draw.rect(shadowRegion, tile.drawx(), tile.drawy());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ public class BreakBlock extends Block {
|
|||||||
public void afterDestroyed(Tile tile, TileEntity e){
|
public void afterDestroyed(Tile tile, TileEntity e){
|
||||||
BreakEntity entity = (BreakEntity)e;
|
BreakEntity entity = (BreakEntity)e;
|
||||||
|
|
||||||
if(entity.previous.synthetic()){
|
if(entity != null && entity.previous != null && entity.previous.synthetic()){
|
||||||
tile.setBlock(entity.previous);
|
tile.setBlock(entity.previous);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -145,7 +145,9 @@ public class BreakBlock extends Block {
|
|||||||
|
|
||||||
if(tile.entity instanceof BreakEntity){
|
if(tile.entity instanceof BreakEntity){
|
||||||
BreakEntity entity = tile.entity();
|
BreakEntity entity = tile.entity();
|
||||||
Effects.effect(Fx.breakBlock, tile.drawx(), tile.drawy(), entity.previous.size);
|
if(entity.previous != null){
|
||||||
|
Effects.effect(Fx.breakBlock, tile.drawx(), tile.drawy(), entity.previous.size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
world.removeBlock(tile);
|
world.removeBlock(tile);
|
||||||
@@ -186,6 +188,10 @@ public class BreakBlock extends Block {
|
|||||||
}
|
}
|
||||||
|
|
||||||
progress += add;
|
progress += add;
|
||||||
|
|
||||||
|
if(progress > 1.0001f){
|
||||||
|
progress = 1.0001f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float progress(){
|
public float progress(){
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ public class BuildBlock extends Block {
|
|||||||
@Override
|
@Override
|
||||||
public boolean isSolidFor(Tile tile) {
|
public boolean isSolidFor(Tile tile) {
|
||||||
BuildEntity entity = tile.entity();
|
BuildEntity entity = tile.entity();
|
||||||
return entity.recipe.result.solid || entity.previous.solid;
|
return entity == null || entity.recipe ==null || entity.recipe.result.solid || entity.previous.solid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -88,7 +88,7 @@ public class BuildBlock extends Block {
|
|||||||
public void draw(Tile tile){
|
public void draw(Tile tile){
|
||||||
BuildEntity entity = tile.entity();
|
BuildEntity entity = tile.entity();
|
||||||
|
|
||||||
if(entity.previous.synthetic()) {
|
if(entity.previous != null && entity.previous.synthetic()) {
|
||||||
for (TextureRegion region : entity.previous.getBlockIcon()) {
|
for (TextureRegion region : entity.previous.getBlockIcon()) {
|
||||||
Draw.rect(region, tile.drawx(), tile.drawy(), entity.recipe.result.rotate ? tile.getRotation() * 90 : 0);
|
Draw.rect(region, tile.drawx(), tile.drawy(), entity.recipe.result.rotate ? tile.getRotation() * 90 : 0);
|
||||||
}
|
}
|
||||||
@@ -131,7 +131,7 @@ public class BuildBlock extends Block {
|
|||||||
CallBlocks.onBuildDeath(tile);
|
CallBlocks.onBuildDeath(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!entity.updated){
|
if(!entity.updated && entity.recipe != null){
|
||||||
entity.progress -= 1f/entity.recipe.cost/decaySpeedScl;
|
entity.progress -= 1f/entity.recipe.cost/decaySpeedScl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,6 +208,10 @@ public class BuildBlock extends Block {
|
|||||||
|
|
||||||
lastProgress = maxProgress;
|
lastProgress = maxProgress;
|
||||||
updated = true;
|
updated = true;
|
||||||
|
|
||||||
|
if(progress > 1.0001f){
|
||||||
|
progress = 1.0001f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public double checkRequired(InventoryModule inventory, double amount){
|
public double checkRequired(InventoryModule inventory, double amount){
|
||||||
|
|||||||
@@ -40,6 +40,13 @@ public class ItemTurret extends CooledTurret {
|
|||||||
|
|
||||||
return Math.min((int)((maxAmmo - entity.totalAmmo) / ammoMap.get(item).quantityMultiplier), amount);
|
return Math.min((int)((maxAmmo - entity.totalAmmo) / ammoMap.get(item).quantityMultiplier), amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleStack(Item item, int amount, Tile tile, Unit source){
|
||||||
|
for (int i = 0; i < amount; i++) {
|
||||||
|
handleItem(item, tile, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//currently can't remove items from turrets.
|
//currently can't remove items from turrets.
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -51,7 +51,9 @@ public class PowerDistributor extends PowerBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected boolean shouldDistribute(Tile tile, Tile other) {
|
protected boolean shouldDistribute(Tile tile, Tile other) {
|
||||||
return !(other.block() instanceof PowerGenerator) || other.entity.power.amount / other.block().powerCapacity < tile.entity.power.amount / powerCapacity;
|
//only generators can distribute to other generators
|
||||||
|
return (!(other.block() instanceof PowerGenerator) || tile.block() instanceof PowerGenerator)
|
||||||
|
&& other.entity.power.amount / other.block().powerCapacity < tile.entity.power.amount / powerCapacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -129,14 +129,14 @@ public class PowerNode extends PowerBlock{
|
|||||||
Tile link = world.tile(x, y);
|
Tile link = world.tile(x, y);
|
||||||
if(link != null) link = link.target();
|
if(link != null) link = link.target();
|
||||||
|
|
||||||
if(link != tile && linkValid(tile, link)){
|
if(link != tile && linkValid(tile, link, false)){
|
||||||
boolean linked = linked(tile, link);
|
boolean linked = linked(tile, link);
|
||||||
Draw.color(linked ? Palette.place : Palette.breakInvalid);
|
Draw.color(linked ? Palette.place : Palette.breakInvalid);
|
||||||
|
|
||||||
Lines.square(link.drawx(), link.drawy(),
|
Lines.square(link.drawx(), link.drawy(),
|
||||||
link.block().size * tilesize / 2f + 1f + (linked ? 0f : Mathf.absin(Timers.time(), 4f, 1f)));
|
link.block().size * tilesize / 2f + 1f + (linked ? 0f : Mathf.absin(Timers.time(), 4f, 1f)));
|
||||||
|
|
||||||
if(entity.links.size >= maxNodes && !linked){
|
if((entity.links.size >= maxNodes || (link.block() instanceof PowerNode && ((DistributorEntity)link.entity).links.size >= ((PowerNode)link.block()).maxNodes)) && !linked){
|
||||||
Draw.color();
|
Draw.color();
|
||||||
Draw.rect("cross-" + link.block().size, link.drawx(), link.drawy());
|
Draw.rect("cross-" + link.block().size, link.drawx(), link.drawy());
|
||||||
}
|
}
|
||||||
@@ -190,11 +190,13 @@ public class PowerNode extends PowerBlock{
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected boolean shouldDistribute(Tile tile, Tile other) {
|
protected boolean shouldDistribute(Tile tile, Tile other) {
|
||||||
return other.entity.power.amount / other.block().powerCapacity <= tile.entity.power.amount / powerCapacity;
|
return other.entity.power.amount / other.block().powerCapacity <= tile.entity.power.amount / powerCapacity &&
|
||||||
|
!(other.block() instanceof PowerGenerator); //do not distribute to power generators
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean shouldLeechPower(Tile tile, Tile other){
|
protected boolean shouldLeechPower(Tile tile, Tile other){
|
||||||
return !(other.block() instanceof PowerNode)
|
return !(other.block() instanceof PowerNode)
|
||||||
|
&& other.block() instanceof PowerDistributor //only suck power from batteries and power generators
|
||||||
&& other.entity.power.amount / other.block().powerCapacity > tile.entity.power.amount / powerCapacity;
|
&& other.entity.power.amount / other.block().powerCapacity > tile.entity.power.amount / powerCapacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,6 +244,10 @@ public class PowerNode extends PowerBlock{
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected boolean linkValid(Tile tile, Tile link){
|
protected boolean linkValid(Tile tile, Tile link){
|
||||||
|
return linkValid(tile, link, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean linkValid(Tile tile, Tile link, boolean checkMaxNodes){
|
||||||
if(!(tile != link && link != null && link.block().hasPower)) return false;
|
if(!(tile != link && link != null && link.block().hasPower)) return false;
|
||||||
|
|
||||||
if(link.block() instanceof PowerNode){
|
if(link.block() instanceof PowerNode){
|
||||||
@@ -250,7 +256,7 @@ public class PowerNode extends PowerBlock{
|
|||||||
return Vector2.dst(tile.drawx(), tile.drawy(), link.drawx(), link.drawy()) <= Math.max(laserRange * tilesize,
|
return Vector2.dst(tile.drawx(), tile.drawy(), link.drawx(), link.drawy()) <= Math.max(laserRange * tilesize,
|
||||||
((PowerNode)link.block()).laserRange * tilesize) - tilesize/2f
|
((PowerNode)link.block()).laserRange * tilesize) - tilesize/2f
|
||||||
+ (link.block().size-1)*tilesize/2f + (tile.block().size-1)*tilesize/2f &&
|
+ (link.block().size-1)*tilesize/2f + (tile.block().size-1)*tilesize/2f &&
|
||||||
(oe.links.size < ((PowerNode)link.block()).maxNodes || oe.links.contains(tile.packedPosition()));
|
(!checkMaxNodes || (oe.links.size < ((PowerNode)link.block()).maxNodes || oe.links.contains(tile.packedPosition())));
|
||||||
}else{
|
}else{
|
||||||
return Vector2.dst(tile.drawx(), tile.drawy(), link.drawx(), link.drawy())
|
return Vector2.dst(tile.drawx(), tile.drawy(), link.drawx(), link.drawy())
|
||||||
<= laserRange * tilesize - tilesize/2f + (link.block().size-1)*tilesize;
|
<= laserRange * tilesize - tilesize/2f + (link.block().size-1)*tilesize;
|
||||||
@@ -276,8 +282,9 @@ public class PowerNode extends PowerBlock{
|
|||||||
return new DistributorEntity();
|
return new DistributorEntity();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Remote(targets = Loc.both, called = Loc.both, in = In.blocks, forward = true)
|
@Remote(targets = Loc.both, called = Loc.server, in = In.blocks, forward = true)
|
||||||
public static void linkPowerDistributors(Player player, Tile tile, Tile other){
|
public static void linkPowerDistributors(Player player, Tile tile, Tile other){
|
||||||
|
|
||||||
DistributorEntity entity = tile.entity();
|
DistributorEntity entity = tile.entity();
|
||||||
|
|
||||||
if(!entity.links.contains(other.packedPosition())){
|
if(!entity.links.contains(other.packedPosition())){
|
||||||
|
|||||||
@@ -154,6 +154,9 @@ public class MechFactory extends Block{
|
|||||||
MechFactoryEntity entity = tile.entity();
|
MechFactoryEntity entity = tile.entity();
|
||||||
|
|
||||||
Effects.effect(Fx.spawn, entity);
|
Effects.effect(Fx.spawn, entity);
|
||||||
|
|
||||||
|
if(entity.player == null) return;
|
||||||
|
|
||||||
Mech result = ((MechFactory)tile.block()).mech;
|
Mech result = ((MechFactory)tile.block()).mech;
|
||||||
|
|
||||||
if(entity.player.mech == result){
|
if(entity.player.mech == result){
|
||||||
|
|||||||
@@ -26,9 +26,6 @@ public class ByteSerializer implements Serialization {
|
|||||||
throw new RuntimeException("Unregistered class: " + ClassReflection.getSimpleName(o.getClass()));
|
throw new RuntimeException("Unregistered class: " + ClassReflection.getSimpleName(o.getClass()));
|
||||||
byteBuffer.put(id);
|
byteBuffer.put(id);
|
||||||
((Packet) o).write(byteBuffer);
|
((Packet) o).write(byteBuffer);
|
||||||
synchronized (packetPoolLock) {
|
|
||||||
Pooling.free(o);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import io.anuke.mindustry.net.NetworkIO;
|
|||||||
import io.anuke.mindustry.net.Packets.Connect;
|
import io.anuke.mindustry.net.Packets.Connect;
|
||||||
import io.anuke.mindustry.net.Packets.Disconnect;
|
import io.anuke.mindustry.net.Packets.Disconnect;
|
||||||
import io.anuke.ucore.function.Consumer;
|
import io.anuke.ucore.function.Consumer;
|
||||||
|
import io.anuke.ucore.util.Pooling;
|
||||||
import io.anuke.ucore.util.Strings;
|
import io.anuke.ucore.util.Strings;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -26,6 +27,7 @@ import java.nio.channels.ClosedSelectorException;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
|
import static io.anuke.mindustry.net.Net.packetPoolLock;
|
||||||
|
|
||||||
public class KryoClient implements ClientProvider{
|
public class KryoClient implements ClientProvider{
|
||||||
Client client;
|
Client client;
|
||||||
@@ -134,6 +136,10 @@ public class KryoClient implements ClientProvider{
|
|||||||
}else{
|
}else{
|
||||||
client.sendUDP(object);
|
client.sendUDP(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
synchronized (packetPoolLock) {
|
||||||
|
Pooling.free(object);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -6,9 +6,7 @@ import io.anuke.ucore.util.ColorCodes;
|
|||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.headless;
|
import static io.anuke.mindustry.Vars.headless;
|
||||||
|
|
||||||
@@ -65,25 +63,4 @@ public class KryoCore {
|
|||||||
private static int calculateLag() {
|
private static int calculateLag() {
|
||||||
return fakeLagMin + (int)(Math.random() * (fakeLagMax - fakeLagMin));
|
return fakeLagMin + (int)(Math.random() * (fakeLagMax - fakeLagMin));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Executes something in a potentially unreliable way. Used to simulate lag and packet errors with UDP.*/
|
|
||||||
public static void recieveUnreliable(Runnable run){
|
|
||||||
if(fakeLag && threadPool == null){
|
|
||||||
threadPool = Executors.newScheduledThreadPool(1, r -> {
|
|
||||||
Thread t = Executors.defaultThreadFactory().newThread(r);
|
|
||||||
t.setDaemon(true);
|
|
||||||
return t;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if(fakeLag){
|
|
||||||
do {
|
|
||||||
if (Math.random() >= fakeLagDrop) {
|
|
||||||
threadPool.schedule(run, calculateLag(), TimeUnit.MILLISECONDS);
|
|
||||||
}
|
|
||||||
} while (Math.random() < fakeLagDuplicate);
|
|
||||||
}else{
|
|
||||||
run.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,10 +15,7 @@ import io.anuke.mindustry.net.Net.SendMode;
|
|||||||
import io.anuke.mindustry.net.Net.ServerProvider;
|
import io.anuke.mindustry.net.Net.ServerProvider;
|
||||||
import io.anuke.mindustry.net.NetConnection;
|
import io.anuke.mindustry.net.NetConnection;
|
||||||
import io.anuke.mindustry.net.NetworkIO;
|
import io.anuke.mindustry.net.NetworkIO;
|
||||||
import io.anuke.mindustry.net.Packets.Connect;
|
import io.anuke.mindustry.net.Packets.*;
|
||||||
import io.anuke.mindustry.net.Packets.Disconnect;
|
|
||||||
import io.anuke.mindustry.net.Packets.StreamBegin;
|
|
||||||
import io.anuke.mindustry.net.Packets.StreamChunk;
|
|
||||||
import io.anuke.mindustry.net.Streamable;
|
import io.anuke.mindustry.net.Streamable;
|
||||||
import io.anuke.ucore.UCore;
|
import io.anuke.ucore.UCore;
|
||||||
import io.anuke.ucore.core.Timers;
|
import io.anuke.ucore.core.Timers;
|
||||||
|
|||||||
@@ -221,7 +221,7 @@ public class ServerControl extends Module {
|
|||||||
if(playerGroup.size() > 0) {
|
if(playerGroup.size() > 0) {
|
||||||
info("&lyPlayers: {0}", playerGroup.size());
|
info("&lyPlayers: {0}", playerGroup.size());
|
||||||
for (Player p : playerGroup.all()) {
|
for (Player p : playerGroup.all()) {
|
||||||
print(" &y{0} / Connection {1} / IP: {2}", p.name, p.con, p.con.address);
|
print(" &y{0} / Connection {1} / IP: {2}", p.name, p.con.id, p.con.address);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
info("&lyNo players connected.");
|
info("&lyNo players connected.");
|
||||||
|
|||||||
Reference in New Issue
Block a user