New map format, completely broke loading or playing
This commit is contained in:
+1
-1
@@ -25,7 +25,7 @@ allprojects {
|
|||||||
appName = 'Mindustry'
|
appName = 'Mindustry'
|
||||||
gdxVersion = '1.9.8'
|
gdxVersion = '1.9.8'
|
||||||
aiVersion = '1.8.1'
|
aiVersion = '1.8.1'
|
||||||
uCoreVersion = '872bce6'
|
uCoreVersion = '9503bcb'
|
||||||
|
|
||||||
getVersionString = {
|
getVersionString = {
|
||||||
String buildVersion = getBuildVersion()
|
String buildVersion = getBuildVersion()
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 369 B |
Binary file not shown.
|
Before Width: | Height: | Size: 317 B |
@@ -1,7 +1,7 @@
|
|||||||
#Autogenerated file. Do not modify.
|
#Autogenerated file. Do not modify.
|
||||||
#Sat Mar 17 11:51:42 EDT 2018
|
#Sat Mar 17 21:20:30 EDT 2018
|
||||||
version=release
|
version=release
|
||||||
androidBuildCode=535
|
androidBuildCode=538
|
||||||
name=Mindustry
|
name=Mindustry
|
||||||
code=3.4
|
code=3.4
|
||||||
build=custom build
|
build=custom build
|
||||||
|
|||||||
@@ -53,6 +53,9 @@ public class Vars{
|
|||||||
//save file directory
|
//save file directory
|
||||||
public static final FileHandle saveDirectory = gwt ? null : UCore.isAssets() ?
|
public static final FileHandle saveDirectory = gwt ? null : UCore.isAssets() ?
|
||||||
Gdx.files.local("../../desktop/mindustry-saves") : Gdx.files.local("mindustry-saves/");
|
Gdx.files.local("../../desktop/mindustry-saves") : Gdx.files.local("mindustry-saves/");
|
||||||
|
|
||||||
|
public static final String mapExtension = "mmap";
|
||||||
|
public static final String saveExtension = "msav";
|
||||||
//scale of the font
|
//scale of the font
|
||||||
public static float fontscale = Math.max(Unit.dp.scl(1f)/2f, 0.5f);
|
public static float fontscale = Math.max(Unit.dp.scl(1f)/2f, 0.5f);
|
||||||
//camera zoom displayed on startup
|
//camera zoom displayed on startup
|
||||||
|
|||||||
@@ -1,17 +1,11 @@
|
|||||||
package io.anuke.mindustry.ai;
|
package io.anuke.mindustry.ai;
|
||||||
|
|
||||||
import com.badlogic.gdx.ai.pfa.PathFinderRequest;
|
|
||||||
import com.badlogic.gdx.ai.pfa.PathSmoother;
|
import com.badlogic.gdx.ai.pfa.PathSmoother;
|
||||||
import com.badlogic.gdx.math.MathUtils;
|
import com.badlogic.gdx.math.MathUtils;
|
||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
import io.anuke.mindustry.entities.units.BaseUnit;
|
import io.anuke.mindustry.entities.units.BaseUnit;
|
||||||
import io.anuke.mindustry.game.SpawnPoint;
|
import io.anuke.mindustry.game.SpawnPoint;
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
import io.anuke.ucore.core.Timers;
|
|
||||||
import io.anuke.ucore.util.Log;
|
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.state;
|
|
||||||
import static io.anuke.mindustry.Vars.world;
|
|
||||||
|
|
||||||
public class Pathfind{
|
public class Pathfind{
|
||||||
/**Maximum time taken per frame on pathfinding for a single path.*/
|
/**Maximum time taken per frame on pathfinding for a single path.*/
|
||||||
@@ -40,6 +34,7 @@ public class Pathfind{
|
|||||||
/**Update the pathfinders and continue calculating the path if it hasn't been calculated yet.
|
/**Update the pathfinders and continue calculating the path if it hasn't been calculated yet.
|
||||||
* This method is run each frame.*/
|
* This method is run each frame.*/
|
||||||
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(int i = 0; i < world.getSpawns().size; i ++){
|
for(int i = 0; i < world.getSpawns().size; i ++){
|
||||||
@@ -60,46 +55,20 @@ public class Pathfind{
|
|||||||
point.request.pathFound = true;
|
point.request.pathFound = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//1300-1500ms, usually 1400 unoptimized on Caldera
|
|
||||||
/**Benchmark pathfinding speed. Debugging stuff.*/
|
|
||||||
public void benchmark(){
|
|
||||||
SpawnPoint point = world.getSpawns().first();
|
|
||||||
int amount = 100;
|
|
||||||
|
|
||||||
//warmup
|
|
||||||
for(int i = 0; i < 100; i ++){
|
|
||||||
point.finder.searchNodePath(point.start, world.getCore(), state.difficulty.heuristic, point.path);
|
|
||||||
point.path.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
Timers.mark();
|
|
||||||
for(int i = 0; i < amount; i ++){
|
|
||||||
point.finder.searchNodePath(point.start, world.getCore(), state.difficulty.heuristic, point.path);
|
|
||||||
point.path.clear();
|
|
||||||
}
|
|
||||||
Log.info("Time elapsed: {0}ms\nAverage MS per path: {1}", Timers.elapsed(), Timers.elapsed()/amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**Reset and clear the paths.*/
|
|
||||||
public void resetPaths(){
|
|
||||||
for(int i = 0; i < world.getSpawns().size; i ++){
|
|
||||||
resetPathFor(world.getSpawns().get(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void resetPathFor(SpawnPoint point){
|
private void resetPathFor(SpawnPoint point){
|
||||||
|
/*
|
||||||
point.finder = new OptimizedPathFinder<>(graph);
|
point.finder = new OptimizedPathFinder<>(graph);
|
||||||
|
|
||||||
point.path.clear();
|
point.path.clear();
|
||||||
|
|
||||||
point.pathTiles = null;
|
point.pathTiles = null;
|
||||||
|
//TODO
|
||||||
point.request = new PathFinderRequest<>(point.start, world.getCore(), state.difficulty.heuristic, point.path);
|
point.request = new PathFinderRequest<>(point.start, world.getCore(), state.difficulty.heuristic, point.path);
|
||||||
point.request.statusChanged = true; //IMPORTANT!
|
point.request.statusChanged = true; //IMPORTANT!*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Finds the closest tile to a position, in an array of tiles.*/
|
/**Finds the closest tile to a position, in an array of tiles.*/
|
||||||
|
|||||||
@@ -9,25 +9,26 @@ import io.anuke.mindustry.game.EventType.*;
|
|||||||
import io.anuke.mindustry.game.Team;
|
import io.anuke.mindustry.game.Team;
|
||||||
import io.anuke.mindustry.game.Tutorial;
|
import io.anuke.mindustry.game.Tutorial;
|
||||||
import io.anuke.mindustry.game.UpgradeInventory;
|
import io.anuke.mindustry.game.UpgradeInventory;
|
||||||
import io.anuke.mindustry.graphics.Fx;
|
|
||||||
import io.anuke.mindustry.input.AndroidInput;
|
import io.anuke.mindustry.input.AndroidInput;
|
||||||
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.io.Map;
|
||||||
import io.anuke.mindustry.io.Platform;
|
import io.anuke.mindustry.io.Platform;
|
||||||
import io.anuke.mindustry.io.Saves;
|
import io.anuke.mindustry.io.Saves;
|
||||||
import io.anuke.mindustry.net.Net;
|
import io.anuke.mindustry.net.Net;
|
||||||
import io.anuke.mindustry.resource.Item;
|
import io.anuke.mindustry.resource.Item;
|
||||||
import io.anuke.mindustry.resource.Mech;
|
import io.anuke.mindustry.resource.Mech;
|
||||||
import io.anuke.mindustry.resource.Weapon;
|
import io.anuke.mindustry.resource.Weapon;
|
||||||
import io.anuke.mindustry.world.Map;
|
|
||||||
import io.anuke.ucore.UCore;
|
import io.anuke.ucore.UCore;
|
||||||
import io.anuke.ucore.core.*;
|
import io.anuke.ucore.core.*;
|
||||||
import io.anuke.ucore.core.Inputs.DeviceType;
|
import io.anuke.ucore.core.Inputs.DeviceType;
|
||||||
import io.anuke.ucore.entities.Entities;
|
import io.anuke.ucore.entities.Entities;
|
||||||
import io.anuke.ucore.modules.Module;
|
import io.anuke.ucore.modules.Module;
|
||||||
import io.anuke.ucore.scene.ui.layout.Unit;
|
import io.anuke.ucore.scene.ui.layout.Unit;
|
||||||
import io.anuke.ucore.util.*;
|
import io.anuke.ucore.util.Atlas;
|
||||||
|
import io.anuke.ucore.util.InputProxy;
|
||||||
|
import io.anuke.ucore.util.Mathf;
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
|
|
||||||
@@ -126,10 +127,6 @@ public class Control extends Module{
|
|||||||
|
|
||||||
KeyBinds.load();
|
KeyBinds.load();
|
||||||
|
|
||||||
for(Map map : world.maps().list()){
|
|
||||||
Settings.defaults("hiscore" + map.name, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
player = new Player();
|
player = new Player();
|
||||||
player.name = Settings.getString("name");
|
player.name = Settings.getString("name");
|
||||||
player.mech = android ? Mech.standardShip : Mech.standard;
|
player.mech = android ? Mech.standardShip : Mech.standard;
|
||||||
@@ -188,11 +185,15 @@ public class Control extends Module{
|
|||||||
|
|
||||||
Events.on(GameOverEvent.class, () -> {
|
Events.on(GameOverEvent.class, () -> {
|
||||||
Effects.shake(5, 6, Core.camera.position.x, Core.camera.position.y);
|
Effects.shake(5, 6, Core.camera.position.x, Core.camera.position.y);
|
||||||
Sounds.play("corexplode");
|
|
||||||
|
|
||||||
|
//TODO effects???
|
||||||
|
//Sounds.play("corexplode");
|
||||||
|
/*
|
||||||
for(int i = 0; i < 16; i ++){
|
for(int i = 0; i < 16; i ++){
|
||||||
Timers.run(i*2, ()-> Effects.effect(Fx.explosion, world.getCore().worldx()+Mathf.range(40), world.getCore().worldy()+Mathf.range(40)));
|
Timers.run(i*2, ()-> Effects.effect(Fx.explosion, world.getCore().worldx()+Mathf.range(40), world.getCore().worldy()+Mathf.range(40)));
|
||||||
}
|
}
|
||||||
Effects.effect(Fx.coreexplosion, world.getCore().worldx(), world.getCore().worldy());
|
Effects.effect(Fx.coreexplosion, world.getCore().worldx(), world.getCore().worldy());*/
|
||||||
|
|
||||||
ui.restart.show();
|
ui.restart.show();
|
||||||
|
|
||||||
@@ -249,23 +250,6 @@ public class Control extends Module{
|
|||||||
return tutorial;
|
return tutorial;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkOldUser(){
|
|
||||||
boolean hasPlayed = false;
|
|
||||||
|
|
||||||
for(Map map : world.maps().getAllMaps()){
|
|
||||||
if(Settings.getInt("hiscore" + map.name) != 0){
|
|
||||||
hasPlayed = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(hasPlayed && Settings.getString("lastVersion").equals("3.2")){
|
|
||||||
Timers.runTask(1f, () -> ui.showInfo("$text.changes"));
|
|
||||||
Settings.putString("lastVersion", "3.3");
|
|
||||||
Settings.save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose(){
|
public void dispose(){
|
||||||
Platform.instance.onGameExit();
|
Platform.instance.onGameExit();
|
||||||
@@ -292,8 +276,6 @@ public class Control extends Module{
|
|||||||
Entities.initPhysics();
|
Entities.initPhysics();
|
||||||
|
|
||||||
Platform.instance.updateRPC();
|
Platform.instance.updateRPC();
|
||||||
|
|
||||||
checkOldUser();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ public class GameState{
|
|||||||
public final Inventory inventory = new Inventory();
|
public final Inventory inventory = new Inventory();
|
||||||
|
|
||||||
public int wave = 1;
|
public int wave = 1;
|
||||||
public int lastUpdated = -1;
|
|
||||||
public float wavetime;
|
public float wavetime;
|
||||||
public float extrawavetime;
|
public float extrawavetime;
|
||||||
public int enemies = 0;
|
public int enemies = 0;
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import io.anuke.mindustry.game.Team;
|
|||||||
import io.anuke.mindustry.game.WaveCreator;
|
import io.anuke.mindustry.game.WaveCreator;
|
||||||
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.mindustry.world.blocks.ProductionBlocks;
|
|
||||||
import io.anuke.ucore.core.Events;
|
import io.anuke.ucore.core.Events;
|
||||||
import io.anuke.ucore.core.Timers;
|
import io.anuke.ucore.core.Timers;
|
||||||
import io.anuke.ucore.entities.Entities;
|
import io.anuke.ucore.entities.Entities;
|
||||||
@@ -51,7 +50,6 @@ public class Logic extends Module {
|
|||||||
state.extrawavetime = maxwavespace * state.difficulty.maxTimeScaling;
|
state.extrawavetime = maxwavespace * state.difficulty.maxTimeScaling;
|
||||||
state.wavetime = wavespace * state.difficulty.timeScaling;
|
state.wavetime = wavespace * state.difficulty.timeScaling;
|
||||||
state.enemies = 0;
|
state.enemies = 0;
|
||||||
state.lastUpdated = -1;
|
|
||||||
state.gameOver = false;
|
state.gameOver = false;
|
||||||
state.inventory.clearItems();
|
state.inventory.clearItems();
|
||||||
state.allyTeams.clear();
|
state.allyTeams.clear();
|
||||||
@@ -67,11 +65,6 @@ public class Logic extends Module {
|
|||||||
|
|
||||||
public void runWave(){
|
public void runWave(){
|
||||||
|
|
||||||
if(state.lastUpdated < state.wave + 1){
|
|
||||||
world.pathfinder().resetPaths();
|
|
||||||
state.lastUpdated = state.wave + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO spawn enemies
|
//TODO spawn enemies
|
||||||
|
|
||||||
state.wave ++;
|
state.wave ++;
|
||||||
@@ -93,7 +86,7 @@ public class Logic extends Module {
|
|||||||
if(!Net.client())
|
if(!Net.client())
|
||||||
world.pathfinder().update();
|
world.pathfinder().update();
|
||||||
|
|
||||||
if(world.getCore() != null && world.getCore().block() != ProductionBlocks.core && !state.gameOver){
|
if(world.getAllyCores().size == 0 && !state.gameOver){
|
||||||
state.gameOver = true;
|
state.gameOver = true;
|
||||||
if(Net.server()) NetEvents.handleGameOver();
|
if(Net.server()) NetEvents.handleGameOver();
|
||||||
Events.fire(GameOverEvent.class);
|
Events.fire(GameOverEvent.class);
|
||||||
@@ -105,11 +98,6 @@ public class Logic extends Module {
|
|||||||
|
|
||||||
if(state.enemies <= 0){
|
if(state.enemies <= 0){
|
||||||
if(!world.getMap().name.equals("tutorial")) state.wavetime -= delta();
|
if(!world.getMap().name.equals("tutorial")) state.wavetime -= delta();
|
||||||
|
|
||||||
if(state.lastUpdated < state.wave + 1 && state.wavetime < aheadPathfinding){ //start updating beforehand
|
|
||||||
world.pathfinder().resetPaths();
|
|
||||||
state.lastUpdated = state.wave + 1;
|
|
||||||
}
|
|
||||||
}else{
|
}else{
|
||||||
state.extrawavetime -= delta();
|
state.extrawavetime -= delta();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,10 +14,8 @@ import io.anuke.mindustry.net.Net.SendMode;
|
|||||||
import io.anuke.mindustry.net.NetworkIO;
|
import io.anuke.mindustry.net.NetworkIO;
|
||||||
import io.anuke.mindustry.net.Packets.*;
|
import io.anuke.mindustry.net.Packets.*;
|
||||||
import io.anuke.mindustry.world.Block;
|
import io.anuke.mindustry.world.Block;
|
||||||
import io.anuke.mindustry.world.Map;
|
|
||||||
import io.anuke.mindustry.world.Placement;
|
import io.anuke.mindustry.world.Placement;
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
import io.anuke.mindustry.world.blocks.ProductionBlocks;
|
|
||||||
import io.anuke.ucore.core.Timers;
|
import io.anuke.ucore.core.Timers;
|
||||||
import io.anuke.ucore.entities.BaseBulletType;
|
import io.anuke.ucore.entities.BaseBulletType;
|
||||||
import io.anuke.ucore.entities.Entities;
|
import io.anuke.ucore.entities.Entities;
|
||||||
@@ -101,18 +99,6 @@ public class NetClient extends Module {
|
|||||||
finishConnecting();
|
finishConnecting();
|
||||||
});
|
});
|
||||||
|
|
||||||
Net.handleClient(CustomMapPacket.class, packet -> {
|
|
||||||
Log.info("Recieved custom map: {0} bytes.", packet.stream.available());
|
|
||||||
|
|
||||||
//custom map is always sent before world data
|
|
||||||
Map map = NetworkIO.loadMap(packet.stream);
|
|
||||||
|
|
||||||
world.maps().setNetworkMap(map);
|
|
||||||
|
|
||||||
MapAckPacket ack = new MapAckPacket();
|
|
||||||
Net.send(ack, SendMode.tcp);
|
|
||||||
});
|
|
||||||
|
|
||||||
Net.handleClient(SyncPacket.class, packet -> {
|
Net.handleClient(SyncPacket.class, packet -> {
|
||||||
if (connecting) return;
|
if (connecting) return;
|
||||||
int players = 0;
|
int players = 0;
|
||||||
@@ -253,10 +239,7 @@ public class NetClient extends Module {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Net.handleClient(GameOverPacket.class, packet -> {
|
Net.handleClient(GameOverPacket.class, packet -> {
|
||||||
if(world.getCore().block() != ProductionBlocks.core &&
|
//TODO core death effects
|
||||||
world.getCore().entity != null){
|
|
||||||
world.getCore().entity.onDeath(true);
|
|
||||||
}
|
|
||||||
quiet = true;
|
quiet = true;
|
||||||
ui.restart.show();
|
ui.restart.show();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -97,25 +97,7 @@ public class NetServer extends Module{
|
|||||||
|
|
||||||
admins.getTrace(ip).playerid = player.id;
|
admins.getTrace(ip).playerid = player.id;
|
||||||
|
|
||||||
if(world.getMap().custom){
|
//TODO try DeflaterOutputStream
|
||||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
|
||||||
NetworkIO.writeMap(world.getMap(), stream);
|
|
||||||
CustomMapPacket data = new CustomMapPacket();
|
|
||||||
data.stream = new ByteArrayInputStream(stream.toByteArray());
|
|
||||||
Net.sendStream(id, data);
|
|
||||||
|
|
||||||
Log.info("Sending custom map: Packed {0} uncompressed bytes of MAP data.", stream.size());
|
|
||||||
}else{
|
|
||||||
//hack-- simulate the map ack packet recieved to send the world data to the client.
|
|
||||||
Net.handleServerReceived(id, new MapAckPacket());
|
|
||||||
}
|
|
||||||
|
|
||||||
Platform.instance.updateRPC();
|
|
||||||
});
|
|
||||||
|
|
||||||
Net.handleServer(MapAckPacket.class, (id, packet) -> {
|
|
||||||
Player player = connections.get(id);
|
|
||||||
|
|
||||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||||
NetworkIO.writeWorld(player, weapons.get(player.name, new ByteArray()), stream);
|
NetworkIO.writeWorld(player, weapons.get(player.name, new ByteArray()), stream);
|
||||||
WorldData data = new WorldData();
|
WorldData data = new WorldData();
|
||||||
@@ -123,6 +105,8 @@ public class NetServer extends Module{
|
|||||||
Net.sendStream(id, data);
|
Net.sendStream(id, data);
|
||||||
|
|
||||||
Log.info("Packed {0} uncompressed bytes of WORLD data.", stream.size());
|
Log.info("Packed {0} uncompressed bytes of WORLD data.", stream.size());
|
||||||
|
|
||||||
|
Platform.instance.updateRPC();
|
||||||
});
|
});
|
||||||
|
|
||||||
Net.handleServer(ConnectConfirmPacket.class, (id, packet) -> {
|
Net.handleServer(ConnectConfirmPacket.class, (id, packet) -> {
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ 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.SyncEntity;
|
||||||
import io.anuke.mindustry.entities.units.BaseUnit;
|
import io.anuke.mindustry.entities.units.BaseUnit;
|
||||||
import io.anuke.mindustry.game.SpawnPoint;
|
|
||||||
import io.anuke.mindustry.game.Team;
|
import io.anuke.mindustry.game.Team;
|
||||||
import io.anuke.mindustry.graphics.BlockRenderer;
|
import io.anuke.mindustry.graphics.BlockRenderer;
|
||||||
import io.anuke.mindustry.graphics.Shaders;
|
import io.anuke.mindustry.graphics.Shaders;
|
||||||
@@ -26,7 +25,6 @@ import io.anuke.mindustry.ui.fragments.ToolFragment;
|
|||||||
import io.anuke.mindustry.world.BlockBar;
|
import io.anuke.mindustry.world.BlockBar;
|
||||||
import io.anuke.mindustry.world.Tile;
|
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.ucore.core.*;
|
import io.anuke.ucore.core.*;
|
||||||
import io.anuke.ucore.entities.EffectEntity;
|
import io.anuke.ucore.entities.EffectEntity;
|
||||||
import io.anuke.ucore.entities.Entities;
|
import io.anuke.ucore.entities.Entities;
|
||||||
@@ -119,14 +117,11 @@ public class Renderer extends RendererModule{
|
|||||||
}else{
|
}else{
|
||||||
boolean smoothcam = Settings.getBool("smoothcam");
|
boolean smoothcam = Settings.getBool("smoothcam");
|
||||||
|
|
||||||
if(world.getCore() == null || world.getCore().block() == ProductionBlocks.core){
|
|
||||||
if(!smoothcam){
|
if(!smoothcam){
|
||||||
setCamera(player.x, player.y);
|
setCamera(player.x, player.y);
|
||||||
}else{
|
|
||||||
smoothCamera(player.x, player.y, android ? 0.3f : 0.14f);
|
|
||||||
}
|
|
||||||
}else{
|
}else{
|
||||||
smoothCamera(world.getCore().worldx(), world.getCore().worldy(), 0.4f);
|
smoothCamera(player.x, player.y, android ? 0.3f : 0.14f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Settings.getBool("pixelate"))
|
if(Settings.getBool("pixelate"))
|
||||||
@@ -392,6 +387,8 @@ public class Renderer extends RendererModule{
|
|||||||
|
|
||||||
//draw tutorial placement point
|
//draw tutorial placement point
|
||||||
if(world.getMap().name.equals("tutorial") && control.tutorial().showBlock()){
|
if(world.getMap().name.equals("tutorial") && control.tutorial().showBlock()){
|
||||||
|
//TODO draw placement point for tutorial
|
||||||
|
/*
|
||||||
int x = world.getCore().x + control.tutorial().getPlacePoint().x;
|
int x = world.getCore().x + control.tutorial().getPlacePoint().x;
|
||||||
int y = world.getCore().y + control.tutorial().getPlacePoint().y;
|
int y = world.getCore().y + control.tutorial().getPlacePoint().y;
|
||||||
int rot = control.tutorial().getPlaceRotation();
|
int rot = control.tutorial().getPlaceRotation();
|
||||||
@@ -405,7 +402,7 @@ public class Renderer extends RendererModule{
|
|||||||
if(rot != -1){
|
if(rot != -1){
|
||||||
Lines.lineAngle(x * tilesize, y * tilesize, rot * 90, 6);
|
Lines.lineAngle(x * tilesize, y * tilesize, rot * 90, 6);
|
||||||
}
|
}
|
||||||
Draw.reset();
|
Draw.reset();*/
|
||||||
}
|
}
|
||||||
|
|
||||||
//draw config selected block
|
//draw config selected block
|
||||||
@@ -435,17 +432,6 @@ public class Renderer extends RendererModule{
|
|||||||
|
|
||||||
input.placeMode.draw(control.input().getBlockX(), control.input().getBlockY(),
|
input.placeMode.draw(control.input().getBlockX(), control.input().getBlockY(),
|
||||||
control.input().getBlockEndX(), control.input().getBlockEndY());
|
control.input().getBlockEndX(), control.input().getBlockEndY());
|
||||||
|
|
||||||
Lines.stroke(1f);
|
|
||||||
Draw.color(Color.SCARLET);
|
|
||||||
for(SpawnPoint spawn : world.getSpawns()){
|
|
||||||
Lines.dashCircle(spawn.start.worldx(), spawn.start.worldy(), enemyspawnspace);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(world.getCore() != null) {
|
|
||||||
Draw.color(Color.LIME);
|
|
||||||
Lines.poly(world.getSpawnX(), world.getSpawnY(), 4, 6f, Timers.time() * 2f);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(input.breakMode == PlaceMode.holdDelete)
|
if(input.breakMode == PlaceMode.holdDelete)
|
||||||
input.breakMode.draw(tilex, tiley, 0, 0);
|
input.breakMode.draw(tilex, tiley, 0, 0);
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import com.badlogic.gdx.math.Interpolation;
|
|||||||
import com.badlogic.gdx.utils.Align;
|
import com.badlogic.gdx.utils.Align;
|
||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.io.Platform;
|
import io.anuke.mindustry.io.Platform;
|
||||||
import io.anuke.mindustry.mapeditor.MapEditorDialog;
|
|
||||||
import io.anuke.mindustry.ui.dialogs.*;
|
import io.anuke.mindustry.ui.dialogs.*;
|
||||||
import io.anuke.mindustry.ui.fragments.*;
|
import io.anuke.mindustry.ui.fragments.*;
|
||||||
import io.anuke.ucore.core.Core;
|
import io.anuke.ucore.core.Core;
|
||||||
@@ -44,7 +43,7 @@ public class UI extends SceneModule{
|
|||||||
public PausedDialog paused;
|
public PausedDialog paused;
|
||||||
public SettingsMenuDialog settings;
|
public SettingsMenuDialog settings;
|
||||||
public ControlsDialog controls;
|
public ControlsDialog controls;
|
||||||
public MapEditorDialog editor;
|
public FloatingDialog editor; //TODO change back to map editor dialog
|
||||||
public LanguageDialog language;
|
public LanguageDialog language;
|
||||||
public BansDialog bans;
|
public BansDialog bans;
|
||||||
public AdminsDialog admins;
|
public AdminsDialog admins;
|
||||||
@@ -144,7 +143,7 @@ public class UI extends SceneModule{
|
|||||||
@Override
|
@Override
|
||||||
public void init(){
|
public void init(){
|
||||||
|
|
||||||
editor = new MapEditorDialog();
|
(editor = new FloatingDialog("The editor is currently broken.")).addCloseButton();
|
||||||
controls = new ControlsDialog();
|
controls = new ControlsDialog();
|
||||||
restart = new RestartDialog();
|
restart = new RestartDialog();
|
||||||
join = new JoinDialog();
|
join = new JoinDialog();
|
||||||
|
|||||||
@@ -6,20 +6,19 @@ import com.badlogic.gdx.math.Vector2;
|
|||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
import io.anuke.mindustry.ai.Pathfind;
|
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.io.Map;
|
||||||
import io.anuke.mindustry.io.Maps;
|
import io.anuke.mindustry.io.Maps;
|
||||||
import io.anuke.mindustry.world.*;
|
import io.anuke.mindustry.world.Block;
|
||||||
|
import io.anuke.mindustry.world.Tile;
|
||||||
|
import io.anuke.mindustry.world.WorldGenerator;
|
||||||
import io.anuke.mindustry.world.blocks.Blocks;
|
import io.anuke.mindustry.world.blocks.Blocks;
|
||||||
import io.anuke.mindustry.world.blocks.DistributionBlocks;
|
|
||||||
import io.anuke.mindustry.world.blocks.ProductionBlocks;
|
import io.anuke.mindustry.world.blocks.ProductionBlocks;
|
||||||
import io.anuke.mindustry.world.blocks.WeaponBlocks;
|
|
||||||
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.modules.Module;
|
import io.anuke.ucore.modules.Module;
|
||||||
import io.anuke.ucore.util.Mathf;
|
import io.anuke.ucore.util.Mathf;
|
||||||
import io.anuke.ucore.util.Tmp;
|
import io.anuke.ucore.util.Tmp;
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.control;
|
|
||||||
import static io.anuke.mindustry.Vars.tilesize;
|
import static io.anuke.mindustry.Vars.tilesize;
|
||||||
|
|
||||||
public class World extends Module{
|
public class World extends Module{
|
||||||
@@ -31,42 +30,41 @@ public class World extends Module{
|
|||||||
private Maps maps = new Maps();
|
private Maps maps = new Maps();
|
||||||
private Array<Tile> allyCores = new Array<>();
|
private Array<Tile> allyCores = new Array<>();
|
||||||
private Array<Tile> enemyCores = new Array<>();
|
private Array<Tile> enemyCores = new Array<>();
|
||||||
private Array<SpawnPoint> spawns = new Array<>();
|
|
||||||
|
|
||||||
private Array<Tile> tempTiles = new Array<>();
|
private Array<Tile> tempTiles = new Array<>();
|
||||||
|
|
||||||
public World(){
|
public World(){
|
||||||
maps.loadMaps();
|
maps.load();
|
||||||
currentMap = maps.getMap(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose(){
|
public void dispose(){
|
||||||
maps.dispose();
|
maps.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Array<SpawnPoint> getSpawns(){
|
|
||||||
return spawns;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Tile getCore(){
|
|
||||||
return core;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Maps maps(){
|
public Maps maps(){
|
||||||
return maps;
|
return maps;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Pathfind pathfinder(){
|
public Pathfind pathfinder(){
|
||||||
return pathfind;
|
return pathfind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Array<Tile> getAllyCores() {
|
||||||
|
return allyCores;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Array<Tile> getEnemyCores() {
|
||||||
|
return enemyCores;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO proper spawnpoints!
|
||||||
public float getSpawnX(){
|
public float getSpawnX(){
|
||||||
return core.worldx();
|
return width() * tilesize/2f;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getSpawnY(){
|
public float getSpawnY(){
|
||||||
return core.worldy() - tilesize*2;
|
return height() * tilesize/2f;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean solid(int x, int y){
|
public boolean solid(int x, int y){
|
||||||
@@ -105,11 +103,11 @@ public class World extends Module{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int width(){
|
public int width(){
|
||||||
return currentMap.getWidth();
|
return currentMap.meta.width;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int height(){
|
public int height(){
|
||||||
return currentMap.getHeight();
|
return currentMap.meta.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Tile tile(int packed){
|
public Tile tile(int packed){
|
||||||
@@ -136,16 +134,6 @@ public class World extends Module{
|
|||||||
return tiles;
|
return tiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createTiles(){
|
|
||||||
for(int x = 0; x < tiles.length; x ++){
|
|
||||||
for(int y = 0; y < tiles[0].length; y ++){
|
|
||||||
if(tiles[x][y] == null){
|
|
||||||
tiles[x][y] = new Tile(x, y, Blocks.stone);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void clearTileEntities(){
|
private void clearTileEntities(){
|
||||||
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 ++){
|
||||||
@@ -155,43 +143,40 @@ public class World extends Module{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**Resizes the tile array to the specified size and returns the resulting tile array.
|
||||||
|
* Only use for loading saves!*/
|
||||||
|
public Tile[][] createTiles(int width, int height){
|
||||||
|
if(tiles != null){
|
||||||
|
clearTileEntities();
|
||||||
|
|
||||||
|
if(tiles.length != width || tiles[0].length != height){
|
||||||
|
tiles = new Tile[width][height];
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
tiles = new Tile[width][height];
|
||||||
|
}
|
||||||
|
|
||||||
|
return tiles;
|
||||||
|
}
|
||||||
|
|
||||||
public void loadMap(Map map){
|
public void loadMap(Map map){
|
||||||
loadMap(map, MathUtils.random(0, 99999));
|
loadMap(map, MathUtils.random(0, 999999));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadMap(Map map, int seed){
|
public void loadMap(Map map, int seed){
|
||||||
currentMap = map;
|
this.currentMap = map;
|
||||||
|
|
||||||
if(tiles != null){
|
|
||||||
clearTileEntities();
|
|
||||||
|
|
||||||
if(tiles.length != map.getWidth() || tiles[0].length != map.getHeight()){
|
|
||||||
tiles = new Tile[map.getWidth()][map.getHeight()];
|
|
||||||
}
|
|
||||||
|
|
||||||
createTiles();
|
|
||||||
}else{
|
|
||||||
tiles = new Tile[map.getWidth()][map.getHeight()];
|
|
||||||
|
|
||||||
createTiles();
|
|
||||||
}
|
|
||||||
|
|
||||||
spawns.clear();
|
|
||||||
|
|
||||||
Entities.resizeTree(0, 0, map.getWidth() * tilesize, map.getHeight() * tilesize);
|
|
||||||
|
|
||||||
this.seed = seed;
|
this.seed = seed;
|
||||||
|
|
||||||
core = WorldGenerator.generate(map.pixmap, tiles, spawns);
|
|
||||||
|
|
||||||
Placement.placeBlock(core.x, core.y, ProductionBlocks.core, 0, false, false);
|
int width = map.meta.width, height = map.meta.height;
|
||||||
|
|
||||||
control.tutorial().setDefaultBlocks(core.x, core.y);
|
|
||||||
|
|
||||||
pathfind.resetPaths();
|
createTiles(width, height);
|
||||||
|
|
||||||
|
Entities.resizeTree(0, 0, width * tilesize, height * tilesize);
|
||||||
|
|
||||||
|
WorldGenerator.generate(tiles, maps.readTileData(map));
|
||||||
}
|
}
|
||||||
|
|
||||||
void set(int x, int y, Block type, int rot){
|
void set(int x, int y, Block type, int rot){
|
||||||
if(!Mathf.inBounds(x, y, tiles)){
|
if(!Mathf.inBounds(x, y, tiles)){
|
||||||
return;
|
return;
|
||||||
@@ -201,7 +186,7 @@ public class World extends Module{
|
|||||||
}
|
}
|
||||||
tiles[x][y].setBlock(type, rot);
|
tiles[x][y].setBlock(type, rot);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSeed(){
|
public int getSeed(){
|
||||||
return seed;
|
return seed;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,17 +3,31 @@ package io.anuke.mindustry.entities;
|
|||||||
import io.anuke.mindustry.game.Team;
|
import io.anuke.mindustry.game.Team;
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
import io.anuke.ucore.entities.BulletEntity;
|
import io.anuke.ucore.entities.BulletEntity;
|
||||||
|
import io.anuke.ucore.entities.Entity;
|
||||||
import io.anuke.ucore.util.Timer;
|
import io.anuke.ucore.util.Timer;
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
|
|
||||||
public class Bullet extends BulletEntity{
|
public class Bullet extends BulletEntity{
|
||||||
public Timer timer = new Timer(3);
|
public Timer timer = new Timer(3);
|
||||||
|
public Team team;
|
||||||
|
|
||||||
public Bullet(BulletType type, Unit owner, float x, float y, float angle){
|
public Bullet(BulletType type, Unit owner, float x, float y, float angle){
|
||||||
super(type, owner, angle);
|
super(type, owner, angle);
|
||||||
set(x, y);
|
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
this.team = owner.team;
|
||||||
|
set(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Bullet(BulletType type, Entity owner, Team team, float x, float y, float angle){
|
||||||
|
super(type, owner, angle);
|
||||||
|
this.team = team;
|
||||||
|
this.type = type;
|
||||||
|
set(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Bullet(BulletType type, Bullet parent, float x, float y, float angle){
|
||||||
|
this(type, parent.owner, parent.team, x, y, angle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void draw(){
|
public void draw(){
|
||||||
@@ -39,14 +53,6 @@ public class Bullet extends BulletEntity{
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Unit owner(){
|
|
||||||
return (Unit)owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Team team(){
|
|
||||||
return ((Unit)owner).team;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(){
|
public void update(){
|
||||||
super.update();
|
super.update();
|
||||||
@@ -58,7 +64,7 @@ public class Bullet extends BulletEntity{
|
|||||||
if (tile == null) return false;
|
if (tile == null) return false;
|
||||||
tile = tile.target();
|
tile = tile.target();
|
||||||
|
|
||||||
if (tile.entity != null && tile.entity.collide(this) && !tile.entity.dead && tile.entity.tile.getTeam() != team()) {
|
if (tile.entity != null && tile.entity.collide(this) && !tile.entity.dead && tile.entity.tile.getTeam() != team) {
|
||||||
tile.entity.collision(this);
|
tile.entity.collision(this);
|
||||||
remove();
|
remove();
|
||||||
type.hit(this);
|
type.hit(this);
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
|
|||||||
Effects.effect(Fx.shellsmoke, b);
|
Effects.effect(Fx.shellsmoke, b);
|
||||||
Effects.effect(Fx.shellexplosion, b);
|
Effects.effect(Fx.shellexplosion, b);
|
||||||
|
|
||||||
DamageArea.damage(b.team(), b.x, b.y, 25f, (int)(damage * 2f/3f));
|
DamageArea.damage(b.team, b.x, b.y, 25f, (int)(damage * 2f/3f));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
flak = new BulletType(2.9f, 8) {
|
flak = new BulletType(2.9f, 8) {
|
||||||
@@ -148,7 +148,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
|
|||||||
public void hit(Bullet b, float hitx, float hity) {
|
public void hit(Bullet b, float hitx, float hity) {
|
||||||
Effects.effect(shellsmoke, b);
|
Effects.effect(shellsmoke, b);
|
||||||
for(int i = 0; i < 3; i ++){
|
for(int i = 0; i < 3; i ++){
|
||||||
Bullet bullet = new Bullet(flakspark, b.owner(), hitx, hity, b.angle() + Mathf.range(120f));
|
Bullet bullet = new Bullet(flakspark, b, hitx, hity, b.angle() + Mathf.range(120f));
|
||||||
bullet.add();
|
bullet.add();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -201,7 +201,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
|
|||||||
Effects.effect(Fx.shellsmoke, b);
|
Effects.effect(Fx.shellsmoke, b);
|
||||||
Effects.effect(Fx.shockwaveSmall, b);
|
Effects.effect(Fx.shockwaveSmall, b);
|
||||||
|
|
||||||
DamageArea.damage(b.team(), b.x, b.y, 50f, (int)(damage * 2f/3f));
|
DamageArea.damage(b.team, b.x, b.y, 50f, (int)(damage * 2f/3f));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
yellowshell = new BulletType(1.2f, 20){
|
yellowshell = new BulletType(1.2f, 20){
|
||||||
@@ -232,7 +232,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
|
|||||||
Effects.effect(Fx.shellsmoke, b);
|
Effects.effect(Fx.shellsmoke, b);
|
||||||
Effects.effect(Fx.shockwaveSmall, b);
|
Effects.effect(Fx.shockwaveSmall, b);
|
||||||
|
|
||||||
DamageArea.damage(b.team(), b.x, b.y, 25f, (int)(damage * 2f/3f));
|
DamageArea.damage(b.team, b.x, b.y, 25f, (int)(damage * 2f/3f));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
blast = new BulletType(1.1f, 90){
|
blast = new BulletType(1.1f, 90){
|
||||||
@@ -255,7 +255,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
|
|||||||
//TODO remove translation() usage
|
//TODO remove translation() usage
|
||||||
Angles.circleVectors(30, 6f, (nx, ny) -> {
|
Angles.circleVectors(30, 6f, (nx, ny) -> {
|
||||||
float ang = Mathf.atan2(nx, ny);
|
float ang = Mathf.atan2(nx, ny);
|
||||||
Bullet o = new Bullet(blastshot, b.owner(), b.x + nx, b.y + ny, ang).add();
|
Bullet o = new Bullet(blastshot, b, b.x + nx, b.y + ny, ang).add();
|
||||||
o.damage = b.damage/9;
|
o.damage = b.damage/9;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -370,7 +370,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
|
|||||||
|
|
||||||
Effects.effect(Fx.clusterbomb, b);
|
Effects.effect(Fx.clusterbomb, b);
|
||||||
|
|
||||||
DamageArea.damage(b.team(), b.x, b.y, 35f, damage);
|
DamageArea.damage(b.team, b.x, b.y, 35f, damage);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
vulcan = new BulletType(4.5f, 12) {
|
vulcan = new BulletType(4.5f, 12) {
|
||||||
@@ -419,7 +419,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
|
|||||||
|
|
||||||
public void hit(Bullet b, float hitx, float hity) {
|
public void hit(Bullet b, float hitx, float hity) {
|
||||||
for(int i = 0; i < 4; i ++){
|
for(int i = 0; i < 4; i ++){
|
||||||
Bullet bullet = new Bullet(scrap, b.owner(), b.x, b.y, b.angle() + Mathf.range(80f));
|
Bullet bullet = new Bullet(scrap, b, b.x, b.y, b.angle() + Mathf.range(80f));
|
||||||
bullet.add();
|
bullet.add();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -449,7 +449,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void init(Bullet b) {
|
public void init(Bullet b) {
|
||||||
DamageArea.damageLine(b.team(), Fx.beamhit, b.x, b.y, b.angle(), length, damage);
|
DamageArea.damageLine(b.team, Fx.beamhit, b.x, b.y, b.angle(), length, damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void draw(Bullet b) {
|
public void draw(Bullet b) {
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import com.badlogic.gdx.math.GridPoint2;
|
|||||||
import io.anuke.mindustry.core.GameState.State;
|
import io.anuke.mindustry.core.GameState.State;
|
||||||
import io.anuke.mindustry.resource.Item;
|
import io.anuke.mindustry.resource.Item;
|
||||||
import io.anuke.mindustry.world.Block;
|
import io.anuke.mindustry.world.Block;
|
||||||
import io.anuke.mindustry.world.Tile;
|
|
||||||
import io.anuke.mindustry.world.blocks.*;
|
import io.anuke.mindustry.world.blocks.*;
|
||||||
import io.anuke.ucore.core.Timers;
|
import io.anuke.ucore.core.Timers;
|
||||||
import io.anuke.ucore.scene.builders.button;
|
import io.anuke.ucore.scene.builders.button;
|
||||||
@@ -70,11 +69,12 @@ public class Tutorial{
|
|||||||
//info.setText(stage.text);
|
//info.setText(stage.text);
|
||||||
|
|
||||||
if(stage.showBlock){
|
if(stage.showBlock){
|
||||||
|
/*
|
||||||
Tile tile = world.tile(world.getCore().x + stage.blockPlaceX, world.getCore().y + stage.blockPlaceY);
|
Tile tile = world.tile(world.getCore().x + stage.blockPlaceX, world.getCore().y + stage.blockPlaceY);
|
||||||
|
|
||||||
if(tile.block() == stage.targetBlock && (tile.getRotation() == stage.blockRotation || stage.blockRotation == -1)){
|
if(tile.block() == stage.targetBlock && (tile.getRotation() == stage.blockRotation || stage.blockRotation == -1)){
|
||||||
move(true);
|
move(true);
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,6 +287,7 @@ public class Tutorial{
|
|||||||
}
|
}
|
||||||
|
|
||||||
void onSwitch(){
|
void onSwitch(){
|
||||||
|
/*
|
||||||
for(int flip : new int[]{1, -1}){
|
for(int flip : new int[]{1, -1}){
|
||||||
world.tile(world.getCore().x + flip, world.getCore().y - 2).setBlock(DistributionBlocks.conveyor, 2 * flip);
|
world.tile(world.getCore().x + flip, world.getCore().y - 2).setBlock(DistributionBlocks.conveyor, 2 * flip);
|
||||||
world.tile(world.getCore().x + flip*2, world.getCore().y - 2).setBlock(DistributionBlocks.conveyor, 2 * flip);
|
world.tile(world.getCore().x + flip*2, world.getCore().y - 2).setBlock(DistributionBlocks.conveyor, 2 * flip);
|
||||||
@@ -295,7 +296,7 @@ public class Tutorial{
|
|||||||
world.tile(world.getCore().x + flip*2, world.getCore().y - 4).setFloor(Blocks.stone);
|
world.tile(world.getCore().x + flip*2, world.getCore().y - 4).setFloor(Blocks.stone);
|
||||||
world.tile(world.getCore().x + flip*2, world.getCore().y - 4).setBlock(ProductionBlocks.stonedrill);
|
world.tile(world.getCore().x + flip*2, world.getCore().y - 4).setBlock(ProductionBlocks.stonedrill);
|
||||||
|
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
deleteBlock{
|
deleteBlock{
|
||||||
@@ -342,7 +343,7 @@ public class Tutorial{
|
|||||||
|
|
||||||
void onSwitch(){
|
void onSwitch(){
|
||||||
for(int i = 0; i < 4; i ++){
|
for(int i = 0; i < 4; i ++){
|
||||||
world.tile(world.getCore().x + 2, world.getCore().y - 2 + i).setBlock(DistributionBlocks.conveyor, 1);
|
//world.tile(world.getCore().x + 2, world.getCore().y - 2 + i).setBlock(DistributionBlocks.conveyor, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
control.input().recipe = null;
|
control.input().recipe = null;
|
||||||
@@ -428,7 +429,7 @@ public class Tutorial{
|
|||||||
|
|
||||||
void onSwitch(){
|
void onSwitch(){
|
||||||
ui.<ImageButton>find("sectionbuttondistribution").fireClick();
|
ui.<ImageButton>find("sectionbuttondistribution").fireClick();
|
||||||
world.tile(blockPlaceX + world.getCore().x, blockPlaceY + world.getCore().y).setBlock(Blocks.air);
|
//world.tile(blockPlaceX + world.getCore().x, blockPlaceY + world.getCore().y).setBlock(Blocks.air);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
conduitUse2{
|
conduitUse2{
|
||||||
@@ -444,7 +445,7 @@ public class Tutorial{
|
|||||||
}
|
}
|
||||||
|
|
||||||
void onSwitch(){
|
void onSwitch(){
|
||||||
world.tile(blockPlaceX + world.getCore().x, blockPlaceY + world.getCore().y).setBlock(Blocks.air);
|
//world.tile(blockPlaceX + world.getCore().x, blockPlaceY + world.getCore().y).setBlock(Blocks.air);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
conduitUse3{
|
conduitUse3{
|
||||||
@@ -460,7 +461,7 @@ public class Tutorial{
|
|||||||
}
|
}
|
||||||
|
|
||||||
void onSwitch(){
|
void onSwitch(){
|
||||||
world.tile(blockPlaceX + world.getCore().x, blockPlaceY + world.getCore().y).setBlock(Blocks.air);
|
//world.tile(blockPlaceX + world.getCore().x, blockPlaceY + world.getCore().y).setBlock(Blocks.air);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
generator{
|
generator{
|
||||||
@@ -475,7 +476,7 @@ public class Tutorial{
|
|||||||
}
|
}
|
||||||
|
|
||||||
void onSwitch(){
|
void onSwitch(){
|
||||||
world.tile(blockPlaceX + world.getCore().x, blockPlaceY + world.getCore().y).setBlock(Blocks.air);
|
//world.tile(blockPlaceX + world.getCore().x, blockPlaceY + world.getCore().y).setBlock(Blocks.air);
|
||||||
ui.<ImageButton>find("sectionbuttonpower").fireClick();
|
ui.<ImageButton>find("sectionbuttonpower").fireClick();
|
||||||
state.inventory.addItem(Item.steel, 60);
|
state.inventory.addItem(Item.steel, 60);
|
||||||
state.inventory.addItem(Item.iron, 60);
|
state.inventory.addItem(Item.iron, 60);
|
||||||
@@ -558,6 +559,7 @@ public class Tutorial{
|
|||||||
}
|
}
|
||||||
|
|
||||||
void onSwitch(){
|
void onSwitch(){
|
||||||
|
/*
|
||||||
for(int i = 0; i < 5; i ++){
|
for(int i = 0; i < 5; i ++){
|
||||||
world.tile(world.getCore().x, world.getCore().y - 6 + i).setBlock(DistributionBlocks.conveyor, 1);
|
world.tile(world.getCore().x, world.getCore().y - 6 + i).setBlock(DistributionBlocks.conveyor, 1);
|
||||||
}
|
}
|
||||||
@@ -570,7 +572,7 @@ public class Tutorial{
|
|||||||
world.tile(world.getCore().x-1, world.getCore().y - 8).setBlock(ProductionBlocks.coaldrill);
|
world.tile(world.getCore().x-1, world.getCore().y - 8).setBlock(ProductionBlocks.coaldrill);
|
||||||
|
|
||||||
world.tile(world.getCore().x+1, world.getCore().y - 7).setBlock(DistributionBlocks.conveyor, 2);
|
world.tile(world.getCore().x+1, world.getCore().y - 7).setBlock(DistributionBlocks.conveyor, 2);
|
||||||
world.tile(world.getCore().x-1, world.getCore().y - 7).setBlock(DistributionBlocks.conveyor, 0);
|
world.tile(world.getCore().x-1, world.getCore().y - 7).setBlock(DistributionBlocks.conveyor, 0);*/
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
tunnelExplain{
|
tunnelExplain{
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import com.badlogic.gdx.graphics.Color;
|
|||||||
import com.badlogic.gdx.graphics.GL20;
|
import com.badlogic.gdx.graphics.GL20;
|
||||||
import com.badlogic.gdx.graphics.OrthographicCamera;
|
import com.badlogic.gdx.graphics.OrthographicCamera;
|
||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
import io.anuke.mindustry.game.SpawnPoint;
|
|
||||||
import io.anuke.mindustry.world.Block;
|
import io.anuke.mindustry.world.Block;
|
||||||
import io.anuke.mindustry.world.Layer;
|
import io.anuke.mindustry.world.Layer;
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
@@ -188,10 +187,6 @@ public class BlockRenderer{
|
|||||||
Graphics.begin();
|
Graphics.begin();
|
||||||
|
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
|
|
||||||
if(showPaths && debug){
|
|
||||||
drawPaths();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(debug && debugChunks){
|
if(debug && debugChunks){
|
||||||
Draw.color(Color.YELLOW);
|
Draw.color(Color.YELLOW);
|
||||||
@@ -209,21 +204,6 @@ public class BlockRenderer{
|
|||||||
Draw.reset();
|
Draw.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawPaths(){
|
|
||||||
Draw.color(Color.RED);
|
|
||||||
for(SpawnPoint point : world.getSpawns()){
|
|
||||||
if(point.pathTiles != null){
|
|
||||||
for(int i = 1; i < point.pathTiles.length; i ++){
|
|
||||||
Lines.line(point.pathTiles[i-1].worldx(), point.pathTiles[i-1].worldy(),
|
|
||||||
point.pathTiles[i].worldx(), point.pathTiles[i].worldy());
|
|
||||||
Lines.circle(point.pathTiles[i-1].worldx(), point.pathTiles[i-1].worldy(), 6f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Draw.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void drawCache(DrawLayer layer, int crangex, int crangey){
|
void drawCache(DrawLayer layer, int crangex, int crangey){
|
||||||
Gdx.gl.glEnable(GL20.GL_BLEND);
|
Gdx.gl.glEnable(GL20.GL_BLEND);
|
||||||
|
|||||||
@@ -78,13 +78,13 @@ public abstract class InputHandler extends InputAdapter{
|
|||||||
|
|
||||||
if(!type.isMultiblock() && control.tutorial().active() &&
|
if(!type.isMultiblock() && control.tutorial().active() &&
|
||||||
control.tutorial().showBlock()){
|
control.tutorial().showBlock()){
|
||||||
|
|
||||||
|
//TODO placepoint control, make sure it's correct.
|
||||||
GridPoint2 point = control.tutorial().getPlacePoint();
|
GridPoint2 point = control.tutorial().getPlacePoint();
|
||||||
int rotation = control.tutorial().getPlaceRotation();
|
int rotation = control.tutorial().getPlaceRotation();
|
||||||
Block block = control.tutorial().getPlaceBlock();
|
Block block = control.tutorial().getPlaceBlock();
|
||||||
|
|
||||||
if(type != block || point.x != x - world.getCore().x || point.y != y - world.getCore().y
|
if(type != block || (rotation != -1 && rotation != this.rotation)){
|
||||||
|| (rotation != -1 && rotation != this.rotation)){
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}else if(control.tutorial().active()){
|
}else if(control.tutorial().active()){
|
||||||
@@ -98,11 +98,12 @@ public abstract class InputHandler extends InputAdapter{
|
|||||||
if(control.tutorial().active()){
|
if(control.tutorial().active()){
|
||||||
|
|
||||||
if(control.tutorial().showBlock()){
|
if(control.tutorial().showBlock()){
|
||||||
|
//TODO placepoint control, make sure it's correct
|
||||||
GridPoint2 point = control.tutorial().getPlacePoint();
|
GridPoint2 point = control.tutorial().getPlacePoint();
|
||||||
int rotation = control.tutorial().getPlaceRotation();
|
int rotation = control.tutorial().getPlaceRotation();
|
||||||
Block block = control.tutorial().getPlaceBlock();
|
Block block = control.tutorial().getPlaceBlock();
|
||||||
|
|
||||||
if(block != Blocks.air || point.x != x - world.getCore().x || point.y != y - world.getCore().y
|
if(block != Blocks.air
|
||||||
|| (rotation != -1 && rotation != this.rotation)){
|
|| (rotation != -1 && rotation != this.rotation)){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package io.anuke.mindustry.io;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.graphics.Texture;
|
||||||
|
|
||||||
|
public class Map {
|
||||||
|
/**Internal map name. This is the filename, without any extensions.*/
|
||||||
|
public final String name;
|
||||||
|
/**Whether this is a custom map.*/
|
||||||
|
public final boolean custom;
|
||||||
|
/**Metadata. Author description, display name, etc.*/
|
||||||
|
public final MapMeta meta;
|
||||||
|
/**Preview texture.*/
|
||||||
|
public Texture texture;
|
||||||
|
|
||||||
|
public Map(String name, MapMeta meta, boolean custom){
|
||||||
|
this.name = name;
|
||||||
|
this.custom = custom;
|
||||||
|
this.meta = meta;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,4 +3,6 @@ package io.anuke.mindustry.io;
|
|||||||
/**Reads and writes map files.*/
|
/**Reads and writes map files.*/
|
||||||
public class MapIO {
|
public class MapIO {
|
||||||
//TODO implementation
|
//TODO implementation
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package io.anuke.mindustry.io;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.utils.ObjectMap;
|
||||||
|
|
||||||
|
public class MapMeta {
|
||||||
|
public final int version;
|
||||||
|
public final ObjectMap<String, String> tags;
|
||||||
|
public final int width, height;
|
||||||
|
|
||||||
|
public MapMeta(int version, ObjectMap<String, String> tags, int width, int height) {
|
||||||
|
this.version = version;
|
||||||
|
this.tags = tags;
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String author(){
|
||||||
|
return tags.get("author", "unknown");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String description(){
|
||||||
|
return tags.get("description", "unknown");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String name(){
|
||||||
|
return tags.get("name", "unknown");
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasOreGen(){
|
||||||
|
return tags.get("oregen", "1").equals("1");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
package io.anuke.mindustry.io;
|
||||||
|
|
||||||
|
import io.anuke.ucore.util.Bits;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
public class MapTileData {
|
||||||
|
/**Tile size: 3 bytes.
|
||||||
|
* 0: ground tile
|
||||||
|
* 1: wall tile
|
||||||
|
* 2: rotation + team*/
|
||||||
|
private final static int TILE_SIZE = 3;
|
||||||
|
|
||||||
|
private final ByteBuffer buffer;
|
||||||
|
private final TileData tile = new TileData();
|
||||||
|
private final int width, height;
|
||||||
|
|
||||||
|
public MapTileData(int width, int height){
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
buffer = ByteBuffer.allocate(width * height * TILE_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MapTileData(byte[] bytes, int width, int height){
|
||||||
|
buffer = ByteBuffer.wrap(bytes);
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int width(){
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int height(){
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Reads and returns the next tile data.*/
|
||||||
|
public TileData read(){
|
||||||
|
tile.read();
|
||||||
|
return tile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Writes tile data at a specified position. Uses the tile data returned by read().*/
|
||||||
|
public void write(int x, int y){
|
||||||
|
position(x, y);
|
||||||
|
tile.write();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Sets read position to the specified coordinates*/
|
||||||
|
public void position(int x, int y){
|
||||||
|
buffer.position((x + width * y) * TILE_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TileData{
|
||||||
|
public byte floor, wall;
|
||||||
|
public byte rotation;
|
||||||
|
public byte team;
|
||||||
|
|
||||||
|
private void read(){
|
||||||
|
floor = buffer.get();
|
||||||
|
wall = buffer.get();
|
||||||
|
byte rt = buffer.get();
|
||||||
|
rotation = Bits.getLeftByte(rt);
|
||||||
|
team = Bits.getRightByte(rt);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void write(){
|
||||||
|
buffer.put(floor);
|
||||||
|
buffer.put(wall);
|
||||||
|
byte rt = Bits.packByte(rotation, team);
|
||||||
|
buffer.put(rt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,224 +1,89 @@
|
|||||||
package io.anuke.mindustry.io;
|
package io.anuke.mindustry.io;
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
import com.badlogic.gdx.files.FileHandle;
|
import com.badlogic.gdx.utils.Array;
|
||||||
import com.badlogic.gdx.graphics.Color;
|
import com.badlogic.gdx.utils.Disposable;
|
||||||
import com.badlogic.gdx.graphics.Pixmap;
|
import com.badlogic.gdx.utils.ObjectMap;
|
||||||
import com.badlogic.gdx.graphics.Texture;
|
|
||||||
import com.badlogic.gdx.utils.*;
|
|
||||||
import com.badlogic.gdx.utils.Json.Serializer;
|
|
||||||
import com.badlogic.gdx.utils.JsonWriter.OutputType;
|
|
||||||
import io.anuke.mindustry.world.Map;
|
|
||||||
import io.anuke.ucore.core.Settings;
|
|
||||||
import io.anuke.ucore.graphics.Pixmaps;
|
|
||||||
import io.anuke.ucore.util.Log;
|
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
import java.io.DataInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import static io.anuke.mindustry.Vars.customMapDirectory;
|
||||||
|
import static io.anuke.mindustry.Vars.mapExtension;
|
||||||
|
|
||||||
public class Maps implements Disposable{
|
public class Maps implements Disposable{
|
||||||
private IntMap<Map> maps = new IntMap<>();
|
private ObjectMap<String, Map> maps = new ObjectMap<>();
|
||||||
private ObjectMap<String, Map> mapNames = new ObjectMap<>();
|
private Array<Map> allMaps = new Array<>();
|
||||||
|
private Array<Map> customMaps = new Array<>();
|
||||||
private Array<Map> defaultMaps = new Array<>();
|
private Array<Map> defaultMaps = new Array<>();
|
||||||
private Map networkMap;
|
|
||||||
private int lastID;
|
|
||||||
private Json json = new Json();
|
|
||||||
private Array<Map> array = new Array<>();
|
|
||||||
|
|
||||||
public Maps() {
|
public void load(){
|
||||||
json.setOutputType(OutputType.json);
|
//TODO
|
||||||
json.setElementType(ArrayContainer.class, "maps", Map.class);
|
|
||||||
json.setSerializer(Color.class, new ColorSerializer());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Iterable<Map> list(){
|
public void save(){
|
||||||
return maps.values();
|
//TODO?
|
||||||
}
|
}
|
||||||
|
|
||||||
public Array<Map> getDefaultMaps(){
|
/**Returns a list of all maps, including custom ones.*/
|
||||||
return defaultMaps;
|
public Array<Map> all(){
|
||||||
|
return allMaps;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Array<Map> getCustomMaps(){
|
/**Returns map by internal name.*/
|
||||||
array.clear();
|
public Map getByName(String name){
|
||||||
for(Map map : list()){
|
return maps.get(name);
|
||||||
if(map.custom) array.add(map);
|
|
||||||
}
|
|
||||||
return array;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Array<Map> getAllMaps(){
|
//TODO GWT support: read from prefs string if custom
|
||||||
array.clear();
|
public MapTileData readTileData(Map map){
|
||||||
for(Map map : list()){
|
|
||||||
array.add(map);
|
|
||||||
}
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setNetworkMap(Map map){
|
|
||||||
if(networkMap != null){
|
|
||||||
networkMap.pixmap.dispose();
|
|
||||||
networkMap = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
networkMap = map;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map getMap(int id){
|
|
||||||
if(id == -1){
|
|
||||||
return networkMap;
|
|
||||||
}
|
|
||||||
return maps.get(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map getMap(String name){
|
|
||||||
return mapNames.get(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void loadMaps(){
|
|
||||||
if(!loadMapFile(Gdx.files.internal("maps/maps.json"), true)){
|
|
||||||
throw new RuntimeException("Failed to load maps!");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!gwt) {
|
|
||||||
if (!loadMapFile(customMapDirectory.child("maps.json"), false)) {
|
|
||||||
try {
|
|
||||||
Log.info("Failed to find custom map directory.");
|
|
||||||
customMapDirectory.child("maps.json").writeString("{}", false);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Failed to create custom map directory!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeMap(Map map){
|
|
||||||
maps.remove(map.id);
|
|
||||||
mapNames.remove(map.name);
|
|
||||||
Array<Map> out = new Array<>();
|
|
||||||
for(Map m : maps.values()){
|
|
||||||
if(m.custom){
|
|
||||||
out.add(m);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
saveMaps(out, customMapDirectory.child("maps.json"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void saveAndReload(Map map, Pixmap out){
|
|
||||||
if(map.pixmap != null && out != map.pixmap && map.texture != null){
|
|
||||||
map.texture.dispose();
|
|
||||||
map.texture = new Texture(out);
|
|
||||||
}else if (out == map.pixmap){
|
|
||||||
map.texture.draw(out, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
map.pixmap = out;
|
|
||||||
if(map.texture == null) map.texture = new Texture(map.pixmap);
|
|
||||||
|
|
||||||
if(map.id == -1){
|
|
||||||
if(mapNames.containsKey(map.name)){
|
|
||||||
map.id = mapNames.get(map.name).id;
|
|
||||||
}else{
|
|
||||||
map.id = ++lastID;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!Settings.has("hiscore" + map.name)){
|
|
||||||
Settings.defaults("hiscore" + map.name, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
saveCustomMap(map);
|
|
||||||
ui.levels.reload();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void saveMaps(Array<Map> array, FileHandle file){
|
|
||||||
json.toJson(new ArrayContainer(array), file);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void saveCustomMap(Map toSave){
|
|
||||||
toSave.custom = true;
|
|
||||||
Array<Map> out = new Array<>();
|
|
||||||
boolean added = false;
|
|
||||||
for(Map map : maps.values()){
|
|
||||||
if(map.custom){
|
|
||||||
if(map.name.equals(toSave.name)){
|
|
||||||
out.add(toSave);
|
|
||||||
toSave.id = map.id;
|
|
||||||
added = true;
|
|
||||||
}else{
|
|
||||||
out.add(map);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!added){
|
|
||||||
out.add(toSave);
|
|
||||||
}
|
|
||||||
maps.remove(toSave.id);
|
|
||||||
mapNames.remove(toSave.name);
|
|
||||||
maps.put(toSave.id, toSave);
|
|
||||||
mapNames.put(toSave.name, toSave);
|
|
||||||
Pixmaps.write(toSave.pixmap, customMapDirectory.child(toSave.name + ".png"));
|
|
||||||
saveMaps(out, customMapDirectory.child("maps.json"));
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean loadMapFile(FileHandle file, boolean logException){
|
|
||||||
try {
|
try {
|
||||||
Array<Map> arr = json.fromJson(ArrayContainer.class, file).maps;
|
InputStream stream;
|
||||||
if (arr != null) { //can be an empty map file
|
|
||||||
for (Map map : arr) {
|
if (map.custom) {
|
||||||
map.pixmap = new Pixmap(file.sibling(map.name + ".png"));
|
stream = Gdx.files.local("maps/" + map.name + "." + mapExtension).read();
|
||||||
if (!headless) map.texture = new Texture(map.pixmap);
|
} else {
|
||||||
maps.put(map.id, map);
|
stream = customMapDirectory.child(map.name + "." + mapExtension).read();
|
||||||
mapNames.put(map.name, map);
|
|
||||||
lastID = Math.max(lastID, map.id);
|
|
||||||
if (!map.custom) {
|
|
||||||
defaultMaps.add(map);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}catch (GdxRuntimeException e){
|
DataInputStream ds = new DataInputStream(stream);
|
||||||
Log.err(e);
|
MapTileData data = readTileData(ds);
|
||||||
return true;
|
ds.close();
|
||||||
}catch(Exception e){
|
return data;
|
||||||
if(logException) {
|
}catch (IOException e){
|
||||||
Log.err(e);
|
throw new RuntimeException(e);
|
||||||
Log.err("Failed loading map file: {0}", file);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private MapTileData readTileData(DataInputStream stream) throws IOException{
|
||||||
|
MapMeta meta = readMapMeta(stream);
|
||||||
|
byte[] bytes = new byte[stream.available()];
|
||||||
|
stream.read(bytes);
|
||||||
|
return new MapTileData(bytes, meta.width, meta.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
private MapMeta readMapMeta(DataInputStream stream) throws IOException{
|
||||||
|
ObjectMap<String, String> tags = new ObjectMap<>();
|
||||||
|
|
||||||
|
int version = stream.readInt();
|
||||||
|
|
||||||
|
byte tagAmount = stream.readByte();
|
||||||
|
|
||||||
|
for(int i = 0; i < tagAmount; i ++){
|
||||||
|
String name = stream.readUTF();
|
||||||
|
String value = stream.readUTF();
|
||||||
|
tags.put(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
int width = stream.readShort();
|
||||||
|
int height = stream.readShort();
|
||||||
|
|
||||||
|
return new MapMeta(version, tags, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose(){
|
public void dispose() {
|
||||||
for(Map map : maps.values()){
|
|
||||||
if(map.texture != null) map.texture.dispose();
|
|
||||||
map.pixmap.dispose();
|
|
||||||
}
|
|
||||||
maps.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class ArrayContainer{
|
|
||||||
Array<Map> maps;
|
|
||||||
|
|
||||||
public ArrayContainer() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public ArrayContainer(Array<Map> maps) {
|
|
||||||
this.maps = maps;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ColorSerializer implements Serializer<Color>{
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void write(Json json, Color object, Class knownType){
|
|
||||||
json.writeValue(object.toString().substring(0, 6));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Color read(Json json, JsonValue jsonData, Class type){
|
|
||||||
return Color.valueOf(jsonData.asString());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,10 @@ public abstract class SaveFileVersion {
|
|||||||
public SaveMeta getData(DataInputStream stream) throws IOException{
|
public SaveMeta getData(DataInputStream stream) throws IOException{
|
||||||
long time = stream.readLong(); //read last saved time
|
long time = stream.readLong(); //read last saved time
|
||||||
byte mode = stream.readByte(); //read the gamemode
|
byte mode = stream.readByte(); //read the gamemode
|
||||||
byte map = stream.readByte(); //read the map
|
String map = stream.readUTF(); //read the map
|
||||||
int wave = stream.readInt(); //read the wave
|
int wave = stream.readInt(); //read the wave
|
||||||
return new SaveMeta(version, time, mode, map, wave, Difficulty.normal);
|
byte difficulty = stream.readByte(); //read the difficulty
|
||||||
|
return new SaveMeta(version, time, mode, map, wave, Difficulty.values()[difficulty]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void read(DataInputStream stream) throws IOException;
|
public abstract void read(DataInputStream stream) throws IOException;
|
||||||
|
|||||||
@@ -79,8 +79,8 @@ public class SaveIO{
|
|||||||
try{
|
try{
|
||||||
int version = stream.readInt();
|
int version = stream.readInt();
|
||||||
SaveFileVersion ver = versions.get(version);
|
SaveFileVersion ver = versions.get(version);
|
||||||
SaveMeta meta = ver.getData(stream);
|
ver.getData(stream);
|
||||||
return meta.map != null;
|
return true;
|
||||||
}catch (Exception e){
|
}catch (Exception e){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package io.anuke.mindustry.io;
|
|||||||
|
|
||||||
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 java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
@@ -16,11 +15,11 @@ public class SaveMeta {
|
|||||||
public int wave;
|
public int wave;
|
||||||
public Difficulty difficulty;
|
public Difficulty difficulty;
|
||||||
|
|
||||||
public SaveMeta(int version, long date, int mode, int map, int wave, Difficulty difficulty){
|
public SaveMeta(int version, long date, int mode, String map, int wave, Difficulty difficulty){
|
||||||
this.version = version;
|
this.version = version;
|
||||||
this.date = Platform.instance.format(new Date(date));
|
this.date = Platform.instance.format(new Date(date));
|
||||||
this.mode = GameMode.values()[mode];
|
this.mode = GameMode.values()[mode];
|
||||||
this.map = world.maps().getMap(map);
|
this.map = world.maps().getByName(map);
|
||||||
this.wave = wave;
|
this.wave = wave;
|
||||||
this.difficulty = difficulty;
|
this.difficulty = difficulty;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import com.badlogic.gdx.utils.async.AsyncExecutor;
|
|||||||
import io.anuke.mindustry.core.GameState.State;
|
import io.anuke.mindustry.core.GameState.State;
|
||||||
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.ucore.core.Settings;
|
import io.anuke.ucore.core.Settings;
|
||||||
import io.anuke.ucore.core.Timers;
|
import io.anuke.ucore.core.Timers;
|
||||||
|
|
||||||
|
|||||||
@@ -8,18 +8,16 @@ import io.anuke.mindustry.game.Difficulty;
|
|||||||
import io.anuke.mindustry.game.GameMode;
|
import io.anuke.mindustry.game.GameMode;
|
||||||
import io.anuke.mindustry.game.Team;
|
import io.anuke.mindustry.game.Team;
|
||||||
import io.anuke.mindustry.io.SaveFileVersion;
|
import io.anuke.mindustry.io.SaveFileVersion;
|
||||||
import io.anuke.mindustry.io.SaveMeta;
|
|
||||||
import io.anuke.mindustry.resource.Item;
|
import io.anuke.mindustry.resource.Item;
|
||||||
import io.anuke.mindustry.resource.Upgrade;
|
import io.anuke.mindustry.resource.Upgrade;
|
||||||
import io.anuke.mindustry.resource.Weapon;
|
import io.anuke.mindustry.resource.Weapon;
|
||||||
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.mindustry.world.WorldGenerator;
|
|
||||||
import io.anuke.mindustry.world.blocks.Blocks;
|
import io.anuke.mindustry.world.blocks.Blocks;
|
||||||
import io.anuke.mindustry.world.blocks.types.BlockPart;
|
import io.anuke.mindustry.world.blocks.types.BlockPart;
|
||||||
import io.anuke.mindustry.world.blocks.types.Rock;
|
|
||||||
import io.anuke.ucore.core.Core;
|
import io.anuke.ucore.core.Core;
|
||||||
import io.anuke.ucore.entities.EntityGroup;
|
import io.anuke.ucore.entities.EntityGroup;
|
||||||
|
import io.anuke.ucore.util.Bits;
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
@@ -34,16 +32,6 @@ public class Save16 extends SaveFileVersion {
|
|||||||
super(16);
|
super(16);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SaveMeta getData(DataInputStream stream) throws IOException{
|
|
||||||
long time = stream.readLong(); //read last saved time
|
|
||||||
byte mode = stream.readByte(); //read the gamemode
|
|
||||||
byte map = stream.readByte(); //read the map
|
|
||||||
int wave = stream.readInt(); //read the wave
|
|
||||||
stream.readFloat(); //wave time
|
|
||||||
byte difficulty = stream.readByte();
|
|
||||||
return new SaveMeta(version, time, mode, map, wave, Difficulty.values()[difficulty]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void read(DataInputStream stream) throws IOException {
|
public void read(DataInputStream stream) throws IOException {
|
||||||
/*long loadTime = */
|
/*long loadTime = */
|
||||||
@@ -51,11 +39,11 @@ public class Save16 extends SaveFileVersion {
|
|||||||
|
|
||||||
//general state
|
//general state
|
||||||
byte mode = stream.readByte();
|
byte mode = stream.readByte();
|
||||||
byte mapid = stream.readByte();
|
String mapname = stream.readUTF();
|
||||||
|
|
||||||
int wave = stream.readInt();
|
int wave = stream.readInt();
|
||||||
float wavetime = stream.readFloat();
|
|
||||||
byte difficulty = stream.readByte();
|
byte difficulty = stream.readByte();
|
||||||
|
float wavetime = stream.readFloat();
|
||||||
|
|
||||||
state.difficulty = Difficulty.values()[difficulty];
|
state.difficulty = Difficulty.values()[difficulty];
|
||||||
|
|
||||||
@@ -148,62 +136,44 @@ public class Save16 extends SaveFileVersion {
|
|||||||
|
|
||||||
//map
|
//map
|
||||||
|
|
||||||
int seed = stream.readInt();
|
short width = stream.readShort();
|
||||||
|
short height = stream.readShort();
|
||||||
|
|
||||||
world.loadMap(world.maps().getMap(mapid), seed);
|
Tile[][] tiles = world.createTiles(width, height);
|
||||||
if(!headless) renderer.clearTiles();
|
|
||||||
|
|
||||||
int rocks = stream.readInt();
|
|
||||||
|
|
||||||
for(int x = 0; x < world.width(); x ++){
|
for(int x = 0; x < world.width(); x ++){
|
||||||
for(int y = 0; y < world.height(); y ++){
|
for(int y = 0; y < world.height(); y ++) {
|
||||||
Tile tile = world.tile(x, y);
|
byte floorid = stream.readByte();
|
||||||
|
byte wallid = stream.readByte();
|
||||||
|
|
||||||
//remove breakables like rocks
|
Tile tile = new Tile(x, y, floorid, wallid);
|
||||||
if(tile.breakable()){
|
|
||||||
world.tile(x, y).setBlock(Blocks.air);
|
if (wallid == Blocks.blockpart.id) {
|
||||||
|
tile.link = stream.readByte();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tile.entity != null) {
|
||||||
|
byte tr = stream.readByte();
|
||||||
|
byte team = Bits.getLeftByte(tr);
|
||||||
|
byte rotation = Bits.getRightByte(tr);
|
||||||
|
short health = stream.readShort();
|
||||||
|
|
||||||
|
tile.setTeam(Team.values()[team]);
|
||||||
|
tile.entity.health = health;
|
||||||
|
tile.setRotation(rotation);
|
||||||
|
|
||||||
|
if (tile.entity.inventory != null) tile.entity.inventory.read(stream);
|
||||||
|
if (tile.entity.power != null) tile.entity.power.read(stream);
|
||||||
|
if (tile.entity.liquid != null) tile.entity.liquid.read(stream);
|
||||||
|
|
||||||
|
tile.entity.read(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
tiles[x][y] = tile;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0; i < rocks; i ++){
|
if(!headless) renderer.clearTiles();
|
||||||
int pos = stream.readInt();
|
|
||||||
Tile tile = world.tile(pos % world.width(), pos / world.width());
|
|
||||||
if(tile == null) continue;
|
|
||||||
Block result = WorldGenerator.rocks.get(tile.floor());
|
|
||||||
if(result != null) tile.setBlock(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
int tiles = stream.readInt();
|
|
||||||
|
|
||||||
for(int i = 0; i < tiles; i ++){
|
|
||||||
int pos = stream.readInt();
|
|
||||||
int blockid = stream.readInt();
|
|
||||||
|
|
||||||
Tile tile = world.tile(pos % world.width(), pos / world.width());
|
|
||||||
|
|
||||||
tile.setBlock(map.get(blockid));
|
|
||||||
|
|
||||||
if(blockid == Blocks.blockpart.id){
|
|
||||||
tile.link = stream.readByte();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(tile.entity != null){
|
|
||||||
byte team = stream.readByte();
|
|
||||||
byte rotation = stream.readByte();
|
|
||||||
short health = stream.readShort();
|
|
||||||
|
|
||||||
tile.setTeam(Team.values()[team]);
|
|
||||||
tile.entity.health = health;
|
|
||||||
tile.setRotation(rotation);
|
|
||||||
|
|
||||||
if(tile.entity.inventory != null) tile.entity.inventory.read(stream);
|
|
||||||
if(tile.entity.power != null) tile.entity.power.read(stream);
|
|
||||||
if(tile.entity.liquid != null) tile.entity.liquid.read(stream);
|
|
||||||
|
|
||||||
tile.entity.read(stream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -214,11 +184,11 @@ public class Save16 extends SaveFileVersion {
|
|||||||
|
|
||||||
//--GENERAL STATE--
|
//--GENERAL STATE--
|
||||||
stream.writeByte(state.mode.ordinal()); //gamemode
|
stream.writeByte(state.mode.ordinal()); //gamemode
|
||||||
stream.writeByte(world.getMap().id); //map ID
|
stream.writeUTF(world.getMap().name); //map ID
|
||||||
|
|
||||||
stream.writeInt(state.wave); //wave
|
stream.writeInt(state.wave); //wave
|
||||||
|
stream.writeByte(state.difficulty.ordinal()); //difficulty ordinal
|
||||||
stream.writeFloat(state.wavetime); //wave countdown
|
stream.writeFloat(state.wavetime); //wave countdown
|
||||||
stream.writeByte(state.difficulty.ordinal());
|
|
||||||
|
|
||||||
//--BLOCK HEADER--
|
//--BLOCK HEADER--
|
||||||
|
|
||||||
@@ -286,65 +256,31 @@ public class Save16 extends SaveFileVersion {
|
|||||||
|
|
||||||
//--MAP DATA--
|
//--MAP DATA--
|
||||||
|
|
||||||
//seed
|
//write world size
|
||||||
stream.writeInt(world.getSeed());
|
stream.writeShort(world.width());
|
||||||
|
stream.writeShort(world.height());
|
||||||
int totalblocks = 0;
|
|
||||||
int totalrocks = 0;
|
|
||||||
|
|
||||||
|
//now write all blocks
|
||||||
for(int x = 0; x < world.width(); x ++){
|
for(int x = 0; x < world.width(); x ++){
|
||||||
for(int y = 0; y < world.height(); y ++){
|
for(int y = 0; y < world.height(); y ++){
|
||||||
Tile tile = world.tile(x, y);
|
Tile tile = world.tile(x, y);
|
||||||
|
|
||||||
if(tile != null && tile.breakable()){
|
stream.writeByte(tile.floor().id); //floor ID
|
||||||
if(tile.block() instanceof Rock){
|
stream.writeByte(tile.block().id); //wall ID
|
||||||
totalrocks ++;
|
|
||||||
}else{
|
if(tile.block() instanceof BlockPart){
|
||||||
totalblocks ++;
|
stream.writeByte(tile.link);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//amount of rocks
|
if(tile.entity != null){
|
||||||
stream.writeInt(totalrocks);
|
stream.writeByte(Bits.packByte((byte)tile.getTeam().ordinal(), tile.getRotation())); //team + rotation
|
||||||
|
stream.writeShort((short)tile.entity.health); //health
|
||||||
|
|
||||||
//write all rocks
|
if(tile.entity.inventory != null) tile.entity.inventory.write(stream);
|
||||||
for(int x = 0; x < world.width(); x ++) {
|
if(tile.entity.power != null) tile.entity.power.write(stream);
|
||||||
for (int y = 0; y < world.height(); y++) {
|
if(tile.entity.liquid != null) tile.entity.liquid.write(stream);
|
||||||
Tile tile = world.tile(x, y);
|
|
||||||
|
|
||||||
if (tile != null && tile.block() instanceof Rock) {
|
tile.entity.write(stream);
|
||||||
stream.writeInt(tile.packedPosition());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//write all blocks
|
|
||||||
stream.writeInt(totalblocks);
|
|
||||||
|
|
||||||
for(int x = 0; x < world.width(); x ++){
|
|
||||||
for(int y = 0; y < world.height(); y ++){
|
|
||||||
Tile tile = world.tile(x, y);
|
|
||||||
|
|
||||||
if(tile != null && tile.breakable() && !(tile.block() instanceof Rock)){
|
|
||||||
|
|
||||||
stream.writeInt(x + y*world.width()); //tile pos
|
|
||||||
stream.writeInt(tile.block().id); //block ID
|
|
||||||
|
|
||||||
if(tile.block() instanceof BlockPart) stream.writeByte(tile.link);
|
|
||||||
|
|
||||||
if(tile.entity != null){
|
|
||||||
stream.writeByte(tile.getTeam().ordinal());
|
|
||||||
stream.writeByte(tile.getRotation()); //rotation
|
|
||||||
stream.writeShort((short)tile.entity.health); //health
|
|
||||||
|
|
||||||
if(tile.entity.inventory != null) tile.entity.inventory.write(stream);
|
|
||||||
if(tile.entity.power != null) tile.entity.power.write(stream);
|
|
||||||
if(tile.entity.liquid != null) tile.entity.liquid.write(stream);
|
|
||||||
|
|
||||||
tile.entity.write(stream);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
package io.anuke.mindustry.mapeditor;
|
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.Pixmap;
|
|
||||||
import com.badlogic.gdx.utils.Disposable;
|
|
||||||
import io.anuke.ucore.graphics.Pixmaps;
|
|
||||||
|
|
||||||
public class DrawOperation implements Disposable{
|
|
||||||
Pixmap from, to, pixmap;
|
|
||||||
|
|
||||||
public DrawOperation(Pixmap pixmap){
|
|
||||||
this.pixmap = pixmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void add(Pixmap from, Pixmap to) {
|
|
||||||
this.from = from;
|
|
||||||
this.to = to;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void undo() {
|
|
||||||
if(from != null) pixmap.drawPixmap(from, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void redo() {
|
|
||||||
if(to != null) pixmap.drawPixmap(to, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void dispose() {
|
|
||||||
if(!Pixmaps.isDisposed(from))
|
|
||||||
from.dispose();
|
|
||||||
|
|
||||||
if(!Pixmaps.isDisposed(to))
|
|
||||||
to.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void disposeFrom(){
|
|
||||||
if(from != null) from.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
package io.anuke.mindustry.mapeditor;
|
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.Pixmap;
|
|
||||||
import com.badlogic.gdx.math.GridPoint2;
|
|
||||||
import com.badlogic.gdx.utils.IntSet;
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
|
||||||
import io.anuke.mindustry.world.Block;
|
|
||||||
import io.anuke.mindustry.world.ColorMapper;
|
|
||||||
import io.anuke.mindustry.world.ColorMapper.BlockPair;
|
|
||||||
|
|
||||||
import java.util.Stack;
|
|
||||||
|
|
||||||
public enum EditorTool{
|
|
||||||
pick{
|
|
||||||
public void touched(MapEditor editor, int x, int y){
|
|
||||||
BlockPair pair = ColorMapper.get(editor.pixmap().getPixel(x, y));
|
|
||||||
if(pair == null) return;
|
|
||||||
Block block = pair.dominant();
|
|
||||||
editor.setDrawBlock(block);
|
|
||||||
ui.editor.updateSelectedBlock();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
pencil{
|
|
||||||
{
|
|
||||||
edit = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void touched(MapEditor editor, int x, int y){
|
|
||||||
editor.draw(x, y);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
line{
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
fill{
|
|
||||||
{
|
|
||||||
edit = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void touched(MapEditor editor, int x, int y){
|
|
||||||
Pixmap pix = editor.pixmap();
|
|
||||||
|
|
||||||
int dest = pix.getPixel(x, y);
|
|
||||||
|
|
||||||
int width = pix.getWidth();
|
|
||||||
|
|
||||||
IntSet set = new IntSet();
|
|
||||||
Stack<GridPoint2> points = new Stack<GridPoint2>();
|
|
||||||
points.add(new GridPoint2(x, y));
|
|
||||||
|
|
||||||
while( !points.isEmpty()){
|
|
||||||
GridPoint2 pos = points.pop();
|
|
||||||
set.add(asInt(pos.x, pos.y, width));
|
|
||||||
|
|
||||||
int pcolor = pix.getPixel(pos.x, pos.y);
|
|
||||||
if(colorEquals(pcolor, dest)){
|
|
||||||
|
|
||||||
pix.drawPixel(pos.x, pos.y);
|
|
||||||
|
|
||||||
if(pos.x > 0 && !set.contains(asInt(pos.x - 1, pos.y, width))) points.add(new GridPoint2(pos).cpy().add( -1, 0));
|
|
||||||
if(pos.y > 0 && !set.contains(asInt(pos.x, pos.y - 1, width))) points.add(new GridPoint2(pos).cpy().add(0, -1));
|
|
||||||
if(pos.x < pix.getWidth() - 1 && !set.contains(asInt(pos.x + 1, pos.y, width))) points.add(new GridPoint2(pos).cpy().add(1, 0));
|
|
||||||
if(pos.y < pix.getHeight() - 1 && !set.contains(asInt(pos.x, pos.y + 1, width))) points.add(new GridPoint2(pos).cpy().add(0, 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
editor.updateTexture();
|
|
||||||
}
|
|
||||||
|
|
||||||
int asInt(int x, int y, int width){
|
|
||||||
return x+y*width;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean colorEquals(int a, int b){
|
|
||||||
return a == b;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
zoom;
|
|
||||||
boolean edit;
|
|
||||||
|
|
||||||
public void touched(MapEditor editor, int x, int y){
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,201 +0,0 @@
|
|||||||
package io.anuke.mindustry.mapeditor;
|
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx;
|
|
||||||
import com.badlogic.gdx.graphics.GL20;
|
|
||||||
import com.badlogic.gdx.graphics.Pixmap;
|
|
||||||
import com.badlogic.gdx.graphics.Pixmap.Format;
|
|
||||||
import com.badlogic.gdx.graphics.Texture;
|
|
||||||
import io.anuke.mindustry.world.Block;
|
|
||||||
import io.anuke.mindustry.world.ColorMapper;
|
|
||||||
import io.anuke.mindustry.world.Map;
|
|
||||||
import io.anuke.mindustry.world.blocks.Blocks;
|
|
||||||
import io.anuke.ucore.graphics.Pixmaps;
|
|
||||||
|
|
||||||
public class MapEditor{
|
|
||||||
public static final int[] validMapSizes = {128, 256, 512};
|
|
||||||
public static final int[] brushSizes = {1, 2, 3, 4, 5, 9, 15};
|
|
||||||
public static final int maxSpawnpoints = 15;
|
|
||||||
public static final Format format = Format.RGBA8888;
|
|
||||||
|
|
||||||
private Pixmap[] brushPixmaps = new Pixmap[brushSizes.length];
|
|
||||||
|
|
||||||
private Map map;
|
|
||||||
|
|
||||||
private MapFilter filter = new MapFilter();
|
|
||||||
private Pixmap filterPixmap;
|
|
||||||
private Texture filterTexture;
|
|
||||||
|
|
||||||
private Pixmap pixmap;
|
|
||||||
private Texture texture;
|
|
||||||
private int brushSize = 1;
|
|
||||||
private Block drawBlock = Blocks.stone;
|
|
||||||
|
|
||||||
public MapEditor(){
|
|
||||||
for(int i = 0; i < brushSizes.length; i ++){
|
|
||||||
int s = brushSizes[i];
|
|
||||||
brushPixmaps[i] = new Pixmap(s*2-1, s*2-1, format);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map getMap(){
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateTexture(){
|
|
||||||
texture.draw(pixmap, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public MapFilter getFilter(){
|
|
||||||
return filter;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void applyFilterPreview(){
|
|
||||||
if(filterPixmap != null && (filterPixmap.getWidth() != pixmap.getWidth()
|
|
||||||
|| filterPixmap.getHeight() != pixmap.getHeight())){
|
|
||||||
filterPixmap.dispose();
|
|
||||||
filterTexture.dispose();
|
|
||||||
filterPixmap = null;
|
|
||||||
filterTexture = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(filterPixmap == null){
|
|
||||||
filterPixmap = Pixmaps.copy(pixmap);
|
|
||||||
|
|
||||||
filter.process(filterPixmap);
|
|
||||||
filterTexture = new Texture(filterPixmap);
|
|
||||||
}else{
|
|
||||||
filterPixmap.drawPixmap(pixmap, 0, 0);
|
|
||||||
filter.process(filterPixmap);
|
|
||||||
filterTexture.draw(filterPixmap, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public Texture getFilterTexture(){
|
|
||||||
return filterTexture;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void applyFilter(){
|
|
||||||
filter.process(pixmap);
|
|
||||||
texture.draw(pixmap, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void beginEdit(Map map){
|
|
||||||
drawBlock = Blocks.stone;
|
|
||||||
this.map = map;
|
|
||||||
this.brushSize = 1;
|
|
||||||
if(map.pixmap == null){
|
|
||||||
pixmap = new Pixmap(256, 256, format);
|
|
||||||
pixmap.setColor(ColorMapper.getColor(drawBlock));
|
|
||||||
pixmap.fill();
|
|
||||||
texture = new Texture(pixmap);
|
|
||||||
}else{
|
|
||||||
pixmap = map.pixmap;
|
|
||||||
texture = map.texture;
|
|
||||||
pixmap.setColor(ColorMapper.getColor(drawBlock));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public Block getDrawBlock(){
|
|
||||||
return drawBlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDrawBlock(Block block){
|
|
||||||
this.drawBlock = block;
|
|
||||||
pixmap.setColor(ColorMapper.getColor(block));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBrushSize(int size){
|
|
||||||
this.brushSize = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getBrushSize() {
|
|
||||||
return brushSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void draw(int dx, int dy){
|
|
||||||
if(dx < 0 || dy < 0 || dx >= pixmap.getWidth() || dy >= pixmap.getHeight()){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, texture.getTextureObjectHandle());
|
|
||||||
|
|
||||||
int dstWidth = brushSize*2-1;
|
|
||||||
int dstHeight = brushSize*2-1;
|
|
||||||
int width = pixmap.getWidth(), height = pixmap.getHeight();
|
|
||||||
|
|
||||||
int x = dx - dstWidth/2;
|
|
||||||
int y = dy - dstHeight/2;
|
|
||||||
|
|
||||||
if (x + dstWidth > width){
|
|
||||||
x = width - dstWidth;
|
|
||||||
}else if (x < 0){
|
|
||||||
x = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (y + dstHeight > height){
|
|
||||||
dstHeight = height - y;
|
|
||||||
}else if (y < 0){
|
|
||||||
dstHeight += y;
|
|
||||||
y = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pixmap.fillCircle(dx, dy, brushSize-1);
|
|
||||||
|
|
||||||
Pixmap dst = brush(brushSize);
|
|
||||||
dst.drawPixmap(pixmap, x, y, dstWidth, dstHeight, 0, 0, dstWidth, dstHeight);
|
|
||||||
|
|
||||||
Gdx.gl.glTexSubImage2D(GL20.GL_TEXTURE_2D, 0, x, y, dstWidth, dstHeight,
|
|
||||||
dst.getGLFormat(), dst.getGLType(), dst.getPixels());
|
|
||||||
}
|
|
||||||
|
|
||||||
private Pixmap brush(int size){
|
|
||||||
for(int i = 0; i < brushSizes.length; i ++){
|
|
||||||
if(brushSizes[i] == size){
|
|
||||||
return brushPixmaps[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Texture texture(){
|
|
||||||
return texture;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Pixmap pixmap(){
|
|
||||||
return pixmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPixmap(Pixmap out){
|
|
||||||
if(pixmap.getWidth() == out.getWidth() && pixmap.getHeight() == out.getHeight()){
|
|
||||||
pixmap.dispose();
|
|
||||||
pixmap = out;
|
|
||||||
texture.draw(out, 0, 0);
|
|
||||||
}else{
|
|
||||||
pixmap.dispose();
|
|
||||||
texture.dispose();
|
|
||||||
pixmap = out;
|
|
||||||
texture = new Texture(out);
|
|
||||||
}
|
|
||||||
pixmap.setColor(ColorMapper.getColor(drawBlock));
|
|
||||||
map.pixmap = pixmap;
|
|
||||||
map.texture = texture;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void resize(int width, int height){
|
|
||||||
Pixmap out = Pixmaps.resize(pixmap, width, height, ColorMapper.getColor(Blocks.stone));
|
|
||||||
pixmap.dispose();
|
|
||||||
pixmap = out;
|
|
||||||
texture.dispose();
|
|
||||||
texture = new Texture(out);
|
|
||||||
|
|
||||||
if(filterPixmap != null){
|
|
||||||
filterPixmap.dispose();
|
|
||||||
filterTexture.dispose();
|
|
||||||
filterPixmap = null;
|
|
||||||
filterTexture = null;
|
|
||||||
}
|
|
||||||
pixmap.setColor(ColorMapper.getColor(drawBlock));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,439 +0,0 @@
|
|||||||
package io.anuke.mindustry.mapeditor;
|
|
||||||
|
|
||||||
import com.badlogic.gdx.Input.Keys;
|
|
||||||
import com.badlogic.gdx.files.FileHandle;
|
|
||||||
import com.badlogic.gdx.graphics.Color;
|
|
||||||
import com.badlogic.gdx.graphics.Pixmap;
|
|
||||||
import com.badlogic.gdx.graphics.Texture;
|
|
||||||
import io.anuke.mindustry.io.Platform;
|
|
||||||
import io.anuke.mindustry.ui.dialogs.FileChooser;
|
|
||||||
import io.anuke.mindustry.world.Block;
|
|
||||||
import io.anuke.mindustry.world.ColorMapper;
|
|
||||||
import io.anuke.mindustry.world.ColorMapper.BlockPair;
|
|
||||||
import io.anuke.mindustry.world.Map;
|
|
||||||
import io.anuke.mindustry.world.blocks.Blocks;
|
|
||||||
import io.anuke.mindustry.world.blocks.SpecialBlocks;
|
|
||||||
import io.anuke.ucore.core.Core;
|
|
||||||
import io.anuke.ucore.core.Graphics;
|
|
||||||
import io.anuke.ucore.core.Inputs;
|
|
||||||
import io.anuke.ucore.core.Timers;
|
|
||||||
import io.anuke.ucore.graphics.Draw;
|
|
||||||
import io.anuke.ucore.graphics.Pixmaps;
|
|
||||||
import io.anuke.ucore.scene.Element;
|
|
||||||
import io.anuke.ucore.scene.builders.build;
|
|
||||||
import io.anuke.ucore.scene.builders.imagebutton;
|
|
||||||
import io.anuke.ucore.scene.builders.label;
|
|
||||||
import io.anuke.ucore.scene.builders.table;
|
|
||||||
import io.anuke.ucore.scene.ui.*;
|
|
||||||
import io.anuke.ucore.scene.ui.layout.Table;
|
|
||||||
import io.anuke.ucore.util.Bundles;
|
|
||||||
import io.anuke.ucore.util.Log;
|
|
||||||
import io.anuke.ucore.util.Strings;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
|
||||||
|
|
||||||
public class MapEditorDialog extends Dialog{
|
|
||||||
private MapEditor editor;
|
|
||||||
private MapView view;
|
|
||||||
private MapGenerateDialog dialog;
|
|
||||||
private MapLoadDialog loadDialog;
|
|
||||||
private MapSaveDialog saveDialog;
|
|
||||||
private MapResizeDialog resizeDialog;
|
|
||||||
private ScrollPane pane;
|
|
||||||
private FileChooser openFile, saveFile;
|
|
||||||
private boolean saved = false;
|
|
||||||
|
|
||||||
private ButtonGroup<ImageButton> blockgroup;
|
|
||||||
|
|
||||||
public MapEditorDialog(){
|
|
||||||
super("$text.mapeditor", "dialog");
|
|
||||||
if(gwt) return;
|
|
||||||
|
|
||||||
editor = new MapEditor();
|
|
||||||
dialog = new MapGenerateDialog(editor);
|
|
||||||
view = new MapView(editor);
|
|
||||||
|
|
||||||
openFile = new FileChooser("$text.loadimage", FileChooser.pngFilter, true, file -> {
|
|
||||||
ui.loadfrag.show();
|
|
||||||
Timers.run(3f, () -> {
|
|
||||||
try{
|
|
||||||
Pixmap pixmap = new Pixmap(file);
|
|
||||||
if(verifySize(pixmap)){
|
|
||||||
editor.setPixmap(pixmap);
|
|
||||||
view.clearStack();
|
|
||||||
}else{
|
|
||||||
ui.showError(Bundles.format("text.editor.badsize", Arrays.toString(MapEditor.validMapSizes)));
|
|
||||||
}
|
|
||||||
}catch (Exception e){
|
|
||||||
ui.showError(Bundles.format("text.editor.errorimageload", Strings.parseException(e, false)));
|
|
||||||
Log.err(e);
|
|
||||||
}
|
|
||||||
ui.loadfrag.hide();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
saveFile = new FileChooser("$saveimage", false, file -> {
|
|
||||||
if(!file.extension().toLowerCase().equals(".png")){
|
|
||||||
file = file.parent().child(file.nameWithoutExtension() + ".png");
|
|
||||||
}
|
|
||||||
FileHandle result = file;
|
|
||||||
ui.loadfrag.show();
|
|
||||||
Timers.run(3f, () -> {
|
|
||||||
try{
|
|
||||||
Pixmaps.write(editor.pixmap(), result);
|
|
||||||
}catch (Exception e){
|
|
||||||
ui.showError(Bundles.format("text.editor.errorimagesave", Strings.parseException(e, false)));
|
|
||||||
if(!android) Log.err(e);
|
|
||||||
}
|
|
||||||
ui.loadfrag.hide();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
loadDialog = new MapLoadDialog(map -> {
|
|
||||||
saveDialog.setFieldText(map.name);
|
|
||||||
ui.loadfrag.show();
|
|
||||||
|
|
||||||
Timers.run(3f, () -> {
|
|
||||||
Map copy = new Map();
|
|
||||||
copy.name = map.name;
|
|
||||||
copy.id = -1;
|
|
||||||
copy.pixmap = Pixmaps.copy(map.pixmap);
|
|
||||||
copy.texture = new Texture(copy.pixmap);
|
|
||||||
copy.oreGen = map.oreGen;
|
|
||||||
editor.beginEdit(copy);
|
|
||||||
ui.loadfrag.hide();
|
|
||||||
view.clearStack();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
resizeDialog = new MapResizeDialog(editor, (x, y) -> {
|
|
||||||
Pixmap pix = editor.pixmap();
|
|
||||||
if(!(pix.getWidth() == x && pix.getHeight() == y)){
|
|
||||||
ui.loadfrag.show();
|
|
||||||
Timers.run(10f, ()->{
|
|
||||||
editor.resize(x, y);
|
|
||||||
view.clearStack();
|
|
||||||
ui.loadfrag.hide();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
saveDialog = new MapSaveDialog(name -> {
|
|
||||||
ui.loadfrag.show();
|
|
||||||
if(verifyMap()){
|
|
||||||
saved = true;
|
|
||||||
String before = editor.getMap().name;
|
|
||||||
editor.getMap().name = name;
|
|
||||||
Timers.run(10f, () -> {
|
|
||||||
world.maps().saveAndReload(editor.getMap(), editor.pixmap());
|
|
||||||
loadDialog.rebuild();
|
|
||||||
ui.loadfrag.hide();
|
|
||||||
view.clearStack();
|
|
||||||
|
|
||||||
if(!name.equals(before)) {
|
|
||||||
Map map = new Map();
|
|
||||||
map.name = editor.getMap().name;
|
|
||||||
map.oreGen = editor.getMap().oreGen;
|
|
||||||
map.pixmap = Pixmaps.copy(editor.getMap().pixmap);
|
|
||||||
map.texture = new Texture(map.pixmap);
|
|
||||||
map.custom = true;
|
|
||||||
editor.beginEdit(map);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}else{
|
|
||||||
ui.loadfrag.hide();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
setFillParent(true);
|
|
||||||
|
|
||||||
clearChildren();
|
|
||||||
margin(0);
|
|
||||||
build.begin(this);
|
|
||||||
build();
|
|
||||||
build.end();
|
|
||||||
|
|
||||||
tapped(() -> {
|
|
||||||
Element e = Core.scene.hit(Graphics.mouse().x, Graphics.mouse().y, true);
|
|
||||||
if(e == null || !e.isDescendantOf(pane)) Core.scene.setScrollFocus(null);
|
|
||||||
});
|
|
||||||
|
|
||||||
update(() -> {
|
|
||||||
if(Core.scene != null && Core.scene.getKeyboardFocus() == this){
|
|
||||||
doInput();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
shown(() -> {
|
|
||||||
saved = true;
|
|
||||||
editor.beginEdit(new Map());
|
|
||||||
blockgroup.getButtons().get(2).setChecked(true);
|
|
||||||
Core.scene.setScrollFocus(view);
|
|
||||||
view.clearStack();
|
|
||||||
|
|
||||||
Timers.runTask(10f, Platform.instance::updateRPC);
|
|
||||||
});
|
|
||||||
|
|
||||||
hidden(() -> Platform.instance.updateRPC());
|
|
||||||
}
|
|
||||||
|
|
||||||
public MapView getView() {
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void resetSaved(){
|
|
||||||
saved = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateSelectedBlock(){
|
|
||||||
Block block = editor.getDrawBlock();
|
|
||||||
int i = 0;
|
|
||||||
for(BlockPair pair : ColorMapper.getPairs()){
|
|
||||||
if(pair.wall == block || (pair.wall == Blocks.air && pair.floor == block)){
|
|
||||||
blockgroup.getButtons().get(i).setChecked(true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasPane(){
|
|
||||||
return Core.scene.getScrollFocus() == pane;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void build(){
|
|
||||||
|
|
||||||
new table(){{
|
|
||||||
float isize = 16*2f;
|
|
||||||
aleft();
|
|
||||||
|
|
||||||
new table(){{
|
|
||||||
|
|
||||||
defaults().growY().width(130f).padBottom(-6);
|
|
||||||
|
|
||||||
new imagebutton("icon-terrain", isize, () ->
|
|
||||||
dialog.show()
|
|
||||||
).text("$text.editor.generate");
|
|
||||||
|
|
||||||
row();
|
|
||||||
|
|
||||||
new imagebutton("icon-resize", isize, () ->
|
|
||||||
resizeDialog.show()
|
|
||||||
).text("$text.editor.resize").padTop(4f);
|
|
||||||
|
|
||||||
row();
|
|
||||||
|
|
||||||
new imagebutton("icon-load-map", isize, () ->
|
|
||||||
loadDialog.show()
|
|
||||||
).text("$text.editor.loadmap");
|
|
||||||
|
|
||||||
row();
|
|
||||||
|
|
||||||
new imagebutton("icon-save-map", isize, ()->
|
|
||||||
saveDialog.show()
|
|
||||||
).text("$text.editor.savemap");
|
|
||||||
|
|
||||||
row();
|
|
||||||
|
|
||||||
new imagebutton("icon-load-image", isize, () ->
|
|
||||||
openFile.show()
|
|
||||||
).text("$text.editor.loadimage");
|
|
||||||
|
|
||||||
row();
|
|
||||||
|
|
||||||
new imagebutton("icon-save-image", isize, () ->
|
|
||||||
saveFile.show()
|
|
||||||
).text("$text.editor.saveimage");
|
|
||||||
|
|
||||||
row();
|
|
||||||
|
|
||||||
new imagebutton("icon-back", isize, () -> {
|
|
||||||
if(!saved){
|
|
||||||
ui.showConfirm("$text.confirm", "$text.editor.unsaved",
|
|
||||||
MapEditorDialog.this::hide);
|
|
||||||
}else{
|
|
||||||
hide();
|
|
||||||
}
|
|
||||||
}).padBottom(0).text("$text.back");
|
|
||||||
|
|
||||||
}}.left().growY().end();
|
|
||||||
|
|
||||||
new table("button"){{
|
|
||||||
add(view).grow();
|
|
||||||
}}.grow().end();
|
|
||||||
|
|
||||||
new table(){{
|
|
||||||
Table tools = new Table("button");
|
|
||||||
tools.top();
|
|
||||||
tools.marginTop(0).marginBottom(6);
|
|
||||||
|
|
||||||
ButtonGroup<ImageButton> group = new ButtonGroup<>();
|
|
||||||
int i = 1;
|
|
||||||
|
|
||||||
tools.defaults().size(53f, 58f).padBottom(-6);
|
|
||||||
|
|
||||||
ImageButton undo = tools.addImageButton("icon-undo", 16*2f, () -> view.undo()).get();
|
|
||||||
ImageButton redo = tools.addImageButton("icon-redo", 16*2f, () -> view.redo()).get();
|
|
||||||
ImageButton grid = tools.addImageButton("icon-grid", "toggle", 16*2f, () -> view.setGrid(!view.isGrid())).get();
|
|
||||||
|
|
||||||
undo.setDisabled(() -> !view.getStack().canUndo());
|
|
||||||
redo.setDisabled(() -> !view.getStack().canRedo());
|
|
||||||
|
|
||||||
undo.update(() -> undo.getImage().setColor(undo.isDisabled() ? Color.GRAY : Color.WHITE));
|
|
||||||
redo.update(() -> redo.getImage().setColor(redo.isDisabled() ? Color.GRAY : Color.WHITE));
|
|
||||||
grid.update(() -> grid.setChecked(view.isGrid()));
|
|
||||||
|
|
||||||
for(EditorTool tool : EditorTool.values()){
|
|
||||||
ImageButton button = new ImageButton("icon-" + tool.name(), "toggle");
|
|
||||||
button.clicked(() -> view.setTool(tool));
|
|
||||||
button.resizeImage(16*2f);
|
|
||||||
button.update(() -> button.setChecked(view.getTool() == tool));
|
|
||||||
group.add(button);
|
|
||||||
if (tool == EditorTool.pencil)
|
|
||||||
button.setChecked(true);
|
|
||||||
|
|
||||||
tools.add(button).padBottom(-6f);
|
|
||||||
if(i++ % 4 == 1) tools.row();
|
|
||||||
}
|
|
||||||
|
|
||||||
add(tools).width(53*4).padBottom(-6);
|
|
||||||
|
|
||||||
row();
|
|
||||||
|
|
||||||
new table("button"){{
|
|
||||||
margin(10f);
|
|
||||||
Slider slider = new Slider(0, MapEditor.brushSizes.length-1, 1, false);
|
|
||||||
slider.moved(f -> editor.setBrushSize(MapEditor.brushSizes[(int)(float)f]));
|
|
||||||
new label(() -> Bundles.format("text.editor.brushsize", MapEditor.brushSizes[(int)slider.getValue()])).left();
|
|
||||||
row();
|
|
||||||
add(slider).growX().padTop(4f);
|
|
||||||
}}.growX().padBottom(-6).end();
|
|
||||||
|
|
||||||
row();
|
|
||||||
|
|
||||||
new table("button"){{
|
|
||||||
get().addCheck("$text.oregen", b -> editor.getMap().oreGen = b)
|
|
||||||
.update(c -> c.setChecked(editor.getMap().oreGen)).padTop(3).padBottom(3);
|
|
||||||
}}.growX().padBottom(-6).end();
|
|
||||||
|
|
||||||
row();
|
|
||||||
|
|
||||||
addBlockSelection(get());
|
|
||||||
|
|
||||||
row();
|
|
||||||
|
|
||||||
}}.right().growY().end();
|
|
||||||
}}.grow().end();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void doInput(){
|
|
||||||
//tool select
|
|
||||||
for(int i = 0; i < EditorTool.values().length; i ++){
|
|
||||||
int code = i == 0 ? 5 : i;
|
|
||||||
if(Inputs.keyTap("weapon_" + code)){
|
|
||||||
view.setTool(EditorTool.values()[i]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//ctrl keys (undo, redo, save)
|
|
||||||
if(Inputs.keyDown(Keys.CONTROL_LEFT)){
|
|
||||||
if(Inputs.keyTap(Keys.Z)){
|
|
||||||
view.undo();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Inputs.keyTap(Keys.Y)){
|
|
||||||
view.redo();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Inputs.keyTap(Keys.S)){
|
|
||||||
saveDialog.save();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Inputs.keyTap(Keys.G)){
|
|
||||||
view.setGrid(!view.isGrid());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean verifySize(Pixmap pix){
|
|
||||||
boolean w = false, h = false;
|
|
||||||
for(int i : MapEditor.validMapSizes){
|
|
||||||
if(pix.getWidth() == i)
|
|
||||||
w = true;
|
|
||||||
if(pix.getHeight() == i)
|
|
||||||
h = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return w && h;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean verifyMap(){
|
|
||||||
int psc = ColorMapper.getColor(SpecialBlocks.playerSpawn);
|
|
||||||
int esc = ColorMapper.getColor(SpecialBlocks.enemySpawn);
|
|
||||||
|
|
||||||
int playerSpawns = 0;
|
|
||||||
int enemySpawns = 0;
|
|
||||||
Pixmap pix = editor.pixmap();
|
|
||||||
|
|
||||||
for(int x = 0; x < pix.getWidth(); x ++){
|
|
||||||
for(int y = 0; y < pix.getHeight(); y ++){
|
|
||||||
int i = pix.getPixel(x, y);
|
|
||||||
if(i == psc) playerSpawns ++;
|
|
||||||
if(i == esc) enemySpawns ++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(playerSpawns == 0){
|
|
||||||
ui.showError("$text.editor.noplayerspawn");
|
|
||||||
return false;
|
|
||||||
}else if(playerSpawns > 1){
|
|
||||||
ui.showError("$text.editor.manyplayerspawns");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(enemySpawns > MapEditor.maxSpawnpoints){
|
|
||||||
ui.showError(Bundles.format("text.editor.manyenemyspawns", MapEditor.maxSpawnpoints));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addBlockSelection(Table table){
|
|
||||||
Table content = new Table();
|
|
||||||
pane = new ScrollPane(content, "volume");
|
|
||||||
pane.setScrollingDisabled(true, false);
|
|
||||||
pane.setFadeScrollBars(false);
|
|
||||||
pane.setOverscroll(true, false);
|
|
||||||
ButtonGroup<ImageButton> group = new ButtonGroup<>();
|
|
||||||
blockgroup = group;
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
for(BlockPair pair : ColorMapper.getPairs()){
|
|
||||||
Block block = pair.wall == Blocks.air ? pair.floor : pair.wall;
|
|
||||||
|
|
||||||
ImageButton button = new ImageButton(Draw.hasRegion(block.name) ? Draw.region(block.name) : Draw.region(block.name + "1"), "toggle");
|
|
||||||
button.clicked(() -> editor.setDrawBlock(block));
|
|
||||||
button.resizeImage(8*4f);
|
|
||||||
group.add(button);
|
|
||||||
content.add(button).pad(4f).size(53f, 58f);
|
|
||||||
|
|
||||||
if(i++ % 2 == 1){
|
|
||||||
content.row();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
group.getButtons().get(2).setChecked(true);
|
|
||||||
|
|
||||||
Table extra = new Table("button");
|
|
||||||
extra.labelWrap(() -> editor.getDrawBlock().formalName).width(180f).center();
|
|
||||||
table.add(extra).padBottom(-6).growX();
|
|
||||||
table.row();
|
|
||||||
table.add(pane).growY().fillX();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,244 +0,0 @@
|
|||||||
package io.anuke.mindustry.mapeditor;
|
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.Pixmap;
|
|
||||||
import com.badlogic.gdx.math.Vector2;
|
|
||||||
import com.badlogic.gdx.utils.ObjectMap;
|
|
||||||
import com.badlogic.gdx.utils.OrderedMap;
|
|
||||||
|
|
||||||
import io.anuke.mindustry.world.Block;
|
|
||||||
import io.anuke.mindustry.world.ColorMapper;
|
|
||||||
import io.anuke.mindustry.world.ColorMapper.BlockPair;
|
|
||||||
import io.anuke.mindustry.world.blocks.Blocks;
|
|
||||||
import io.anuke.mindustry.world.blocks.types.Floor;
|
|
||||||
import io.anuke.ucore.graphics.Pixmaps;
|
|
||||||
import io.anuke.ucore.noise.RidgedPerlin;
|
|
||||||
import io.anuke.ucore.noise.Simplex;
|
|
||||||
import io.anuke.ucore.util.Mathf;
|
|
||||||
|
|
||||||
public class MapFilter{
|
|
||||||
private ObjectMap<String, GenPref> prefs = map(
|
|
||||||
pref("replace", "whether to replace blocks"),
|
|
||||||
pref("terrain", "generate new terrain"),
|
|
||||||
pref("circle", "generate terrain in a circle"),
|
|
||||||
pref("distort", "distort the map image"),
|
|
||||||
pref("sand", "add patches of sand"),
|
|
||||||
pref("grass", "add patches of grass"),
|
|
||||||
pref("stone", "add patches of stone"),
|
|
||||||
pref("blackstone", "add patches of black stone"),
|
|
||||||
pref("allgrass", "fill map with grass"),
|
|
||||||
pref("allsnow", "fill map with snow"),
|
|
||||||
pref("allsand", "fill map with sand"),
|
|
||||||
pref("water", "add lakes"),
|
|
||||||
pref("oil", "add oil lakes"),
|
|
||||||
pref("lavariver", "add lava rivers"),
|
|
||||||
pref("slavariver", "ad small lava rivers"),
|
|
||||||
pref("river", "add rivers"),
|
|
||||||
pref("iceriver", "add frozen rivers"),
|
|
||||||
pref("oilriver", "add oil rivers")
|
|
||||||
);
|
|
||||||
|
|
||||||
private Simplex sim = new Simplex();
|
|
||||||
private RidgedPerlin rid = new RidgedPerlin(1, 10, 20f);
|
|
||||||
private RidgedPerlin rid2 = new RidgedPerlin(1, 6, 1f);
|
|
||||||
private RidgedPerlin rid3 = new RidgedPerlin(1, 6, 1f);
|
|
||||||
|
|
||||||
public MapFilter(){
|
|
||||||
prefs.get("replace").enabled = true;
|
|
||||||
prefs.get("terrain").enabled = true;
|
|
||||||
randomize();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void randomize(){
|
|
||||||
sim.setSeed(Mathf.random(999999));
|
|
||||||
rid.setSeed(Mathf.random(999999));
|
|
||||||
rid2.setSeed(Mathf.random(999999));
|
|
||||||
rid3.setSeed(Mathf.random(999999));
|
|
||||||
}
|
|
||||||
|
|
||||||
public ObjectMap<String, GenPref> getPrefs(){
|
|
||||||
return prefs;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Pixmap process(Pixmap pixmap){
|
|
||||||
if(prefs.get("terrain").enabled){
|
|
||||||
for(int x = 0; x < pixmap.getWidth(); x++){
|
|
||||||
for(int y = 0; y < pixmap.getHeight(); y++){
|
|
||||||
float dist = Vector2.dst((float) x / pixmap.getWidth(), (float) y / pixmap.getHeight(), 0.5f, 0.5f) * 2f;
|
|
||||||
double noise = sim.octaveNoise2D(6, 0.6, 1 / 180.0, x, y + 9999) / (prefs.get("circle").enabled ? 1.7 : 1f) + dist / 10f;
|
|
||||||
|
|
||||||
if(dist > 0.8){
|
|
||||||
noise += 2 * (dist - 0.8);
|
|
||||||
}
|
|
||||||
|
|
||||||
Block block = noise > 0.6 ? Blocks.stoneblock : Blocks.stone;
|
|
||||||
|
|
||||||
pixmap.drawPixel(x, y, ColorMapper.getColor(block));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Pixmap src = Pixmaps.copy(pixmap);
|
|
||||||
|
|
||||||
for(int x = 0; x < pixmap.getWidth(); x++){
|
|
||||||
for(int y = 0; y < pixmap.getHeight(); y++){
|
|
||||||
int dx = 0, dy = 0;
|
|
||||||
|
|
||||||
if(prefs.get("distort").enabled){
|
|
||||||
double intensity = 12;
|
|
||||||
double scale = 80;
|
|
||||||
double octaves = 4;
|
|
||||||
double falloff = 0.6;
|
|
||||||
double nx = (sim.octaveNoise2D(octaves, falloff, 1 / scale, x, y) - 0.5f) * intensity;
|
|
||||||
double ny = (sim.octaveNoise2D(octaves, falloff, 1 / scale, x, y + 99999) - 0.5f) * intensity;
|
|
||||||
dx = (int) nx;
|
|
||||||
dy = (int) ny;
|
|
||||||
}
|
|
||||||
|
|
||||||
int pix = src.getPixel(x + dx, y + dy);
|
|
||||||
|
|
||||||
BlockPair pair = ColorMapper.get(pix);
|
|
||||||
Block block = pair == null ? null : pair.wall == Blocks.air ? pair.floor : pair.wall;
|
|
||||||
|
|
||||||
if(block == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
boolean floor = block instanceof Floor;
|
|
||||||
|
|
||||||
double noise = sim.octaveNoise2D(4, 0.6, 1 / 170.0, x, y) + sim.octaveNoise2D(1, 1.0, 1 / 5.0, x, y) / 18.0;
|
|
||||||
double nwater = sim.octaveNoise2D(1, 1.0, 1 / 130.0, x, y);
|
|
||||||
noise += nwater / 5.0;
|
|
||||||
|
|
||||||
double noil = sim.octaveNoise2D(1, 1.0, 1 / 150.0, x + 9999, y) + sim.octaveNoise2D(1, 1.0, 1 / 2.0, x, y) / 290.0;
|
|
||||||
|
|
||||||
if(!floor || prefs.get("replace").enabled){
|
|
||||||
|
|
||||||
if(prefs.get("allgrass").enabled){
|
|
||||||
block = floor ? Blocks.grass : Blocks.grassblock;
|
|
||||||
}else if(prefs.get("allsnow").enabled){
|
|
||||||
block = floor ? Blocks.snow : Blocks.snowblock;
|
|
||||||
}else if(prefs.get("allsand").enabled){
|
|
||||||
block = floor ? Blocks.sand : Blocks.sandblock;
|
|
||||||
}else if(prefs.get("replace").enabled){
|
|
||||||
block = floor ? Blocks.stone : Blocks.stoneblock;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(noise > 0.7 && prefs.get("grass").enabled){
|
|
||||||
block = floor ? Blocks.grass : Blocks.grassblock;
|
|
||||||
}
|
|
||||||
if(noise > 0.7 && prefs.get("blackstone").enabled){
|
|
||||||
block = floor ? Blocks.blackstone : Blocks.blackstoneblock;
|
|
||||||
}
|
|
||||||
if(noise > 0.7 && prefs.get("sand").enabled){
|
|
||||||
block = floor ? Blocks.sand : Blocks.sandblock;
|
|
||||||
}
|
|
||||||
if(noise > 0.8 && prefs.get("stone").enabled){
|
|
||||||
block = floor ? Blocks.stone : Blocks.stoneblock;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(floor){
|
|
||||||
if(nwater > 0.93 && prefs.get("water").enabled){
|
|
||||||
block = Blocks.water;
|
|
||||||
if(nwater > 0.943){
|
|
||||||
block = Blocks.deepwater;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(noil > 0.95 && prefs.get("oil").enabled){
|
|
||||||
block = Blocks.dirt;
|
|
||||||
if(noil > 0.955){
|
|
||||||
block = Blocks.oil;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(floor && prefs.get("lavariver").enabled){
|
|
||||||
double lava = rid.getValue(x, y, 1 / 100f);
|
|
||||||
double t = 0.6;
|
|
||||||
if(lava > t){
|
|
||||||
block = Blocks.lava;
|
|
||||||
}else if(lava > t - 0.2){
|
|
||||||
block = Blocks.blackstone;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(floor && prefs.get("slavariver").enabled){
|
|
||||||
double lava = rid.getValue(x, y, 1 / 40f);
|
|
||||||
double t = 0.7;
|
|
||||||
if(lava > t){
|
|
||||||
block = Blocks.lava;
|
|
||||||
}else if(lava > t - 0.3){
|
|
||||||
block = Blocks.blackstone;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(floor && prefs.get("oilriver").enabled){
|
|
||||||
double lava = rid3.getValue(x, y, 1 / 100f);
|
|
||||||
double t = 0.9;
|
|
||||||
if(lava > t){
|
|
||||||
block = Blocks.oil;
|
|
||||||
}else if(lava > t - 0.2){
|
|
||||||
block = Blocks.dirt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(floor && prefs.get("river").enabled){
|
|
||||||
double riv = rid2.getValue(x, y, 1 / 140f);
|
|
||||||
double t = 0.4;
|
|
||||||
|
|
||||||
if(riv > t + 0.1){
|
|
||||||
block = Blocks.deepwater;
|
|
||||||
}else if(riv > t){
|
|
||||||
block = Blocks.water;
|
|
||||||
}else if(riv > t - 0.2){
|
|
||||||
block = Blocks.grass;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(floor && prefs.get("iceriver").enabled){
|
|
||||||
double riv = rid2.getValue(x, y, 1 / 140f);
|
|
||||||
double t = 0.4;
|
|
||||||
|
|
||||||
if(riv > t + 0.1){
|
|
||||||
block = Blocks.ice;
|
|
||||||
}else if(riv > t){
|
|
||||||
block = Blocks.ice;
|
|
||||||
}else if(riv > t - 0.2){
|
|
||||||
block = Blocks.snow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pixmap.drawPixel(x, y, ColorMapper.getColor(block));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
src.dispose();
|
|
||||||
|
|
||||||
return pixmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static OrderedMap<String, GenPref> map(GenPref...objects){
|
|
||||||
OrderedMap<String, GenPref> prefs = new OrderedMap<>();
|
|
||||||
|
|
||||||
for(int i = 0; i < objects.length; i ++){
|
|
||||||
GenPref pref = (GenPref)objects[i];
|
|
||||||
prefs.put(pref.name, pref);
|
|
||||||
}
|
|
||||||
return prefs;
|
|
||||||
}
|
|
||||||
|
|
||||||
private GenPref pref(String name, String desc){
|
|
||||||
return new GenPref(name, desc);
|
|
||||||
}
|
|
||||||
|
|
||||||
class GenPref{
|
|
||||||
public final String name;
|
|
||||||
public final String description;
|
|
||||||
public boolean enabled;
|
|
||||||
|
|
||||||
GenPref(String name, String description){
|
|
||||||
this.name = name;
|
|
||||||
this.description = description;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,105 +0,0 @@
|
|||||||
package io.anuke.mindustry.mapeditor;
|
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.Pixmap;
|
|
||||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
|
||||||
import com.badlogic.gdx.utils.Align;
|
|
||||||
import com.badlogic.gdx.utils.Scaling;
|
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
|
||||||
import io.anuke.mindustry.mapeditor.MapFilter.GenPref;
|
|
||||||
import io.anuke.mindustry.ui.BorderImage;
|
|
||||||
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
|
|
||||||
import io.anuke.ucore.core.Timers;
|
|
||||||
import io.anuke.ucore.graphics.Pixmaps;
|
|
||||||
import io.anuke.ucore.scene.style.TextureRegionDrawable;
|
|
||||||
import io.anuke.ucore.scene.ui.CheckBox;
|
|
||||||
import io.anuke.ucore.scene.ui.Image;
|
|
||||||
import io.anuke.ucore.scene.ui.ScrollPane;
|
|
||||||
import io.anuke.ucore.scene.ui.layout.Stack;
|
|
||||||
import io.anuke.ucore.scene.ui.layout.Table;
|
|
||||||
|
|
||||||
public class MapGenerateDialog extends FloatingDialog{
|
|
||||||
private MapEditor editor;
|
|
||||||
private Image image;
|
|
||||||
private boolean loading;
|
|
||||||
|
|
||||||
public MapGenerateDialog(MapEditor editor) {
|
|
||||||
super("$text.editor.generate");
|
|
||||||
this.editor = editor;
|
|
||||||
|
|
||||||
Stack stack = new Stack();
|
|
||||||
stack.add(image = new BorderImage());
|
|
||||||
|
|
||||||
Image loadImage = new Image("icon-loading");
|
|
||||||
loadImage.setScaling(Scaling.none);
|
|
||||||
loadImage.setScale(3f);
|
|
||||||
loadImage.update(() -> loadImage.setOrigin(Align.center));
|
|
||||||
loadImage.setVisible(() -> loading);
|
|
||||||
Image next = new Image("white");
|
|
||||||
next.setScaling(Scaling.fit);
|
|
||||||
next.setColor(0, 0, 0, 0.6f);
|
|
||||||
next.setVisible(() -> loading);
|
|
||||||
|
|
||||||
stack.add(next);
|
|
||||||
stack.add(loadImage);
|
|
||||||
|
|
||||||
content().add(stack).grow();
|
|
||||||
image.setScaling(Scaling.fit);
|
|
||||||
Table preft = new Table();
|
|
||||||
preft.left();
|
|
||||||
preft.margin(4f).marginRight(25f);
|
|
||||||
|
|
||||||
for(GenPref pref : editor.getFilter().getPrefs().values()){
|
|
||||||
CheckBox box = new CheckBox(pref.name);
|
|
||||||
box.setChecked(pref.enabled);
|
|
||||||
box.changed(() -> pref.enabled = box.isChecked());
|
|
||||||
preft.add(box).pad(4f).left();
|
|
||||||
preft.row();
|
|
||||||
}
|
|
||||||
|
|
||||||
ScrollPane pane = new ScrollPane(preft, "volume");
|
|
||||||
pane.setFadeScrollBars(false);
|
|
||||||
pane.setScrollingDisabled(true, false);
|
|
||||||
|
|
||||||
content().add(pane).fillY();
|
|
||||||
|
|
||||||
buttons().defaults().size(170f, 50f).pad(4f);
|
|
||||||
buttons().addButton("$text.back", this::hide);
|
|
||||||
buttons().addButton("$text.randomize", () ->{
|
|
||||||
editor.getFilter().randomize();
|
|
||||||
apply();
|
|
||||||
});
|
|
||||||
buttons().addButton("$text.update", this::apply);
|
|
||||||
buttons().addButton("$text.apply", () ->{
|
|
||||||
ui.loadfrag.show();
|
|
||||||
|
|
||||||
Timers.run(3f, () ->{
|
|
||||||
Pixmap copy = Pixmaps.copy(editor.pixmap());
|
|
||||||
editor.applyFilter();
|
|
||||||
ui.editor.getView().push(copy, Pixmaps.copy(editor.pixmap()));
|
|
||||||
ui.loadfrag.hide();
|
|
||||||
ui.editor.resetSaved();
|
|
||||||
hide();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
shown(() ->{
|
|
||||||
loading = true;
|
|
||||||
Timers.run(30f, () -> {
|
|
||||||
editor.applyFilterPreview();
|
|
||||||
image.setDrawable(new TextureRegionDrawable(new TextureRegion(editor.getFilterTexture())));
|
|
||||||
loading = false;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void apply(){
|
|
||||||
loading = true;
|
|
||||||
Timers.run(3f, () -> {
|
|
||||||
editor.applyFilterPreview();
|
|
||||||
loading = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
package io.anuke.mindustry.mapeditor;
|
|
||||||
|
|
||||||
import io.anuke.mindustry.ui.BorderImage;
|
|
||||||
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
|
|
||||||
import io.anuke.mindustry.world.Map;
|
|
||||||
import io.anuke.ucore.function.Consumer;
|
|
||||||
import io.anuke.ucore.scene.ui.ButtonGroup;
|
|
||||||
import io.anuke.ucore.scene.ui.ScrollPane;
|
|
||||||
import io.anuke.ucore.scene.ui.TextButton;
|
|
||||||
import io.anuke.ucore.scene.ui.layout.Table;
|
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.world;
|
|
||||||
|
|
||||||
public class MapLoadDialog extends FloatingDialog{
|
|
||||||
private Map selected = world.maps().getMap(0);
|
|
||||||
|
|
||||||
public MapLoadDialog(Consumer<Map> loader) {
|
|
||||||
super("$text.editor.loadmap");
|
|
||||||
|
|
||||||
shown(this::rebuild);
|
|
||||||
rebuild();
|
|
||||||
|
|
||||||
TextButton button = new TextButton("$text.load");
|
|
||||||
button.setDisabled(() -> selected == null);
|
|
||||||
button.clicked(() -> {
|
|
||||||
if (selected != null) {
|
|
||||||
loader.accept(selected);
|
|
||||||
hide();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
buttons().defaults().size(200f, 50f);
|
|
||||||
buttons().addButton("$text.cancel", this::hide);
|
|
||||||
buttons().add(button);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void rebuild(){
|
|
||||||
content().clear();
|
|
||||||
|
|
||||||
selected = world.maps().getMap(0);
|
|
||||||
|
|
||||||
ButtonGroup<TextButton> group = new ButtonGroup<>();
|
|
||||||
|
|
||||||
int maxcol = 3;
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
Table table = new Table();
|
|
||||||
table.defaults().size(200f, 90f).pad(4f);
|
|
||||||
table.margin(10f);
|
|
||||||
|
|
||||||
ScrollPane pane = new ScrollPane(table, "horizontal");
|
|
||||||
pane.setFadeScrollBars(false);
|
|
||||||
|
|
||||||
for (Map map : world.maps().list()) {
|
|
||||||
if (!map.visible) continue;
|
|
||||||
|
|
||||||
TextButton button = new TextButton(map.localized(), "toggle");
|
|
||||||
button.add(new BorderImage(map.texture, 2f)).size(16 * 4f);
|
|
||||||
button.getCells().reverse();
|
|
||||||
button.clicked(() -> selected = map);
|
|
||||||
button.getLabelCell().grow().left().padLeft(5f);
|
|
||||||
group.add(button);
|
|
||||||
table.add(button);
|
|
||||||
if (++i % maxcol == 0) table.row();
|
|
||||||
}
|
|
||||||
|
|
||||||
content().add("$text.editor.loadmap");
|
|
||||||
content().row();
|
|
||||||
content().add(pane);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
package io.anuke.mindustry.mapeditor;
|
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.Pixmap;
|
|
||||||
import com.badlogic.gdx.utils.Align;
|
|
||||||
|
|
||||||
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
|
|
||||||
import io.anuke.ucore.function.BiConsumer;
|
|
||||||
import io.anuke.ucore.scene.ui.ButtonGroup;
|
|
||||||
import io.anuke.ucore.scene.ui.TextButton;
|
|
||||||
import io.anuke.ucore.scene.ui.layout.Table;
|
|
||||||
|
|
||||||
public class MapResizeDialog extends FloatingDialog{
|
|
||||||
int width, height;
|
|
||||||
|
|
||||||
public MapResizeDialog(MapEditor editor, BiConsumer<Integer, Integer> cons){
|
|
||||||
super("$text.editor.resizemap");
|
|
||||||
shown(() -> {
|
|
||||||
content().clear();
|
|
||||||
Pixmap pix = editor.pixmap();
|
|
||||||
width = pix.getWidth();
|
|
||||||
height = pix.getHeight();
|
|
||||||
|
|
||||||
Table table = new Table();
|
|
||||||
|
|
||||||
for(int d = 0; d < 2; d ++){
|
|
||||||
boolean w = d == 0;
|
|
||||||
int curr = d == 0 ? pix.getWidth() : pix.getHeight();
|
|
||||||
int idx = 0;
|
|
||||||
for(int i = 0; i < MapEditor.validMapSizes.length; i ++)
|
|
||||||
if(MapEditor.validMapSizes[i] == curr) idx = i;
|
|
||||||
|
|
||||||
table.add(d == 0 ? "$text.width": "$text.height").padRight(8f);
|
|
||||||
ButtonGroup<TextButton> group = new ButtonGroup<>();
|
|
||||||
for(int i = 0; i < MapEditor.validMapSizes.length; i ++){
|
|
||||||
int size = MapEditor.validMapSizes[i];
|
|
||||||
TextButton button = new TextButton(size + "", "toggle");
|
|
||||||
button.clicked(() -> {
|
|
||||||
if(w)
|
|
||||||
width = size;
|
|
||||||
else
|
|
||||||
height = size;
|
|
||||||
});
|
|
||||||
group.add(button);
|
|
||||||
if(i == idx) button.setChecked(true);
|
|
||||||
table.add(button).size(100f, 54f).pad(2f);
|
|
||||||
}
|
|
||||||
|
|
||||||
table.row();
|
|
||||||
}
|
|
||||||
|
|
||||||
content().label(() ->
|
|
||||||
width + height > 512 ? "$text.editor.resizebig" : ""
|
|
||||||
).get().setAlignment(Align.center, Align.center);
|
|
||||||
content().row();
|
|
||||||
content().add(table);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
buttons().defaults().size(200f, 50f);
|
|
||||||
buttons().addButton("$text.cancel", this::hide);
|
|
||||||
buttons().addButton("$text.editor.resize", () -> {
|
|
||||||
cons.accept(width, height);
|
|
||||||
hide();
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
package io.anuke.mindustry.mapeditor;
|
|
||||||
|
|
||||||
import io.anuke.mindustry.io.Platform;
|
|
||||||
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
|
|
||||||
import io.anuke.mindustry.world.Map;
|
|
||||||
import io.anuke.ucore.function.Consumer;
|
|
||||||
import io.anuke.ucore.scene.ui.TextButton;
|
|
||||||
import io.anuke.ucore.scene.ui.TextField;
|
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
|
||||||
|
|
||||||
public class MapSaveDialog extends FloatingDialog{
|
|
||||||
private TextField field;
|
|
||||||
private Consumer<String> listener;
|
|
||||||
|
|
||||||
public MapSaveDialog(Consumer<String> cons){
|
|
||||||
super("$text.editor.savemap");
|
|
||||||
field = new TextField();
|
|
||||||
listener = cons;
|
|
||||||
|
|
||||||
Platform.instance.addDialog(field);
|
|
||||||
|
|
||||||
shown(() -> {
|
|
||||||
content().clear();
|
|
||||||
content().label(() ->{
|
|
||||||
Map map = world.maps().getMap(field.getText());
|
|
||||||
if(map != null){
|
|
||||||
if(map.custom){
|
|
||||||
return "$text.editor.overwrite";
|
|
||||||
}else{
|
|
||||||
return "$text.editor.failoverwrite";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}).colspan(2);
|
|
||||||
content().row();
|
|
||||||
content().add("$text.editor.mapname").padRight(14f);
|
|
||||||
content().add(field).size(220f, 48f);
|
|
||||||
});
|
|
||||||
|
|
||||||
buttons().defaults().size(200f, 50f).pad(2f);
|
|
||||||
buttons().addButton("$text.cancel", this::hide);
|
|
||||||
|
|
||||||
TextButton button = new TextButton("$text.save");
|
|
||||||
button.clicked(() -> {
|
|
||||||
if(!invalid()){
|
|
||||||
cons.accept(field.getText());
|
|
||||||
hide();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
button.setDisabled(this::invalid);
|
|
||||||
buttons().add(button);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void save(){
|
|
||||||
if(!invalid()){
|
|
||||||
listener.accept(field.getText());
|
|
||||||
}else{
|
|
||||||
ui.showError("$text.editor.failoverwrite");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFieldText(String text){
|
|
||||||
field.setText(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean invalid(){
|
|
||||||
if(field.getText().isEmpty()){
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
Map map = world.maps().getMap(field.getText());
|
|
||||||
return map != null && !map.custom;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,328 +0,0 @@
|
|||||||
package io.anuke.mindustry.mapeditor;
|
|
||||||
|
|
||||||
import com.badlogic.gdx.Input.Keys;
|
|
||||||
import com.badlogic.gdx.graphics.Color;
|
|
||||||
import com.badlogic.gdx.graphics.Colors;
|
|
||||||
import com.badlogic.gdx.graphics.Pixmap;
|
|
||||||
import com.badlogic.gdx.graphics.g2d.Batch;
|
|
||||||
import com.badlogic.gdx.input.GestureDetector;
|
|
||||||
import com.badlogic.gdx.input.GestureDetector.GestureListener;
|
|
||||||
import com.badlogic.gdx.math.Bresenham2;
|
|
||||||
import com.badlogic.gdx.math.GridPoint2;
|
|
||||||
import com.badlogic.gdx.math.Rectangle;
|
|
||||||
import com.badlogic.gdx.math.Vector2;
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.utils.ScissorStack;
|
|
||||||
import com.badlogic.gdx.utils.Array;
|
|
||||||
import io.anuke.mindustry.ui.GridImage;
|
|
||||||
import io.anuke.mindustry.world.ColorMapper;
|
|
||||||
import io.anuke.ucore.core.Core;
|
|
||||||
import io.anuke.ucore.core.Graphics;
|
|
||||||
import io.anuke.ucore.core.Inputs;
|
|
||||||
import io.anuke.ucore.graphics.Draw;
|
|
||||||
import io.anuke.ucore.graphics.Lines;
|
|
||||||
import io.anuke.ucore.graphics.Pixmaps;
|
|
||||||
import io.anuke.ucore.scene.Element;
|
|
||||||
import io.anuke.ucore.scene.event.InputEvent;
|
|
||||||
import io.anuke.ucore.scene.event.InputListener;
|
|
||||||
import io.anuke.ucore.scene.event.Touchable;
|
|
||||||
import io.anuke.ucore.scene.ui.TextField;
|
|
||||||
import io.anuke.ucore.scene.ui.layout.Unit;
|
|
||||||
import io.anuke.ucore.util.Mathf;
|
|
||||||
import io.anuke.ucore.util.Tmp;
|
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.ui;
|
|
||||||
|
|
||||||
public class MapView extends Element implements GestureListener{
|
|
||||||
private MapEditor editor;
|
|
||||||
private EditorTool tool = EditorTool.pencil;
|
|
||||||
private OperationStack stack = new OperationStack();
|
|
||||||
private DrawOperation op;
|
|
||||||
private Pixmap current;
|
|
||||||
private Bresenham2 br = new Bresenham2();
|
|
||||||
private boolean updated = false;
|
|
||||||
private float offsetx, offsety;
|
|
||||||
private float zoom = 1f;
|
|
||||||
private boolean grid = false;
|
|
||||||
private GridImage image = new GridImage(0, 0);
|
|
||||||
private Vector2 vec = new Vector2();
|
|
||||||
private Rectangle rect = new Rectangle();
|
|
||||||
|
|
||||||
private boolean drawing;
|
|
||||||
private int lastx, lasty;
|
|
||||||
private int startx, starty;
|
|
||||||
|
|
||||||
public void setTool(EditorTool tool){
|
|
||||||
this.tool = tool;
|
|
||||||
}
|
|
||||||
|
|
||||||
public EditorTool getTool() {
|
|
||||||
return tool;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clearStack(){
|
|
||||||
stack.clear();
|
|
||||||
current = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OperationStack getStack() {
|
|
||||||
return stack;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setGrid(boolean grid) {
|
|
||||||
this.grid = grid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isGrid() {
|
|
||||||
return grid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void push(Pixmap previous, Pixmap add){
|
|
||||||
DrawOperation op = new DrawOperation(editor.pixmap());
|
|
||||||
op.add(previous, add);
|
|
||||||
stack.add(op);
|
|
||||||
this.current = add;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void undo(){
|
|
||||||
if(stack.canUndo()){
|
|
||||||
stack.undo();
|
|
||||||
editor.updateTexture();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void redo(){
|
|
||||||
if(stack.canRedo()){
|
|
||||||
stack.redo();
|
|
||||||
editor.updateTexture();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public MapView(MapEditor editor){
|
|
||||||
this.editor = editor;
|
|
||||||
|
|
||||||
Inputs.addProcessor(0, new GestureDetector(20, 0.5f, 2, 0.15f, this));
|
|
||||||
setTouchable(Touchable.enabled);
|
|
||||||
|
|
||||||
addListener(new InputListener(){
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
|
|
||||||
if(pointer != 0){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(current == null){
|
|
||||||
current = Pixmaps.copy(editor.pixmap());
|
|
||||||
}
|
|
||||||
updated = false;
|
|
||||||
|
|
||||||
GridPoint2 p = project(x, y);
|
|
||||||
lastx = p.x;
|
|
||||||
lasty = p.y;
|
|
||||||
startx = p.x;
|
|
||||||
starty = p.y;
|
|
||||||
tool.touched(editor, p.x, p.y);
|
|
||||||
|
|
||||||
if(tool.edit){
|
|
||||||
updated = true;
|
|
||||||
ui.editor.resetSaved();
|
|
||||||
}
|
|
||||||
|
|
||||||
op = new DrawOperation(editor.pixmap());
|
|
||||||
|
|
||||||
drawing = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void touchUp (InputEvent event, float x, float y, int pointer, int button) {
|
|
||||||
drawing = false;
|
|
||||||
|
|
||||||
GridPoint2 p = project(x, y);
|
|
||||||
|
|
||||||
if(tool == EditorTool.line){
|
|
||||||
ui.editor.resetSaved();
|
|
||||||
Array<GridPoint2> points = br.line(startx, starty, p.x, p.y);
|
|
||||||
for(GridPoint2 point : points){
|
|
||||||
editor.draw(point.x, point.y);
|
|
||||||
}
|
|
||||||
updated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(updated){
|
|
||||||
if(op == null) op = new DrawOperation(editor.pixmap());
|
|
||||||
Pixmap next = Pixmaps.copy(editor.pixmap());
|
|
||||||
op.add(current, next);
|
|
||||||
current = null;
|
|
||||||
stack.add(op);
|
|
||||||
op = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void touchDragged (InputEvent event, float x, float y, int pointer) {
|
|
||||||
GridPoint2 p = project(x, y);
|
|
||||||
|
|
||||||
if(drawing && tool == EditorTool.pencil){
|
|
||||||
ui.editor.resetSaved();
|
|
||||||
Array<GridPoint2> points = br.line(lastx, lasty, p.x, p.y);
|
|
||||||
for(GridPoint2 point : points){
|
|
||||||
editor.draw(point.x, point.y);
|
|
||||||
}
|
|
||||||
updated = true;
|
|
||||||
}
|
|
||||||
lastx = p.x;
|
|
||||||
lasty = p.y;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void act(float delta){
|
|
||||||
super.act(delta);
|
|
||||||
|
|
||||||
if(Core.scene.getKeyboardFocus() == null || !(Core.scene.getKeyboardFocus() instanceof TextField) &&
|
|
||||||
!Inputs.keyDown(Keys.CONTROL_LEFT)) {
|
|
||||||
float ax = Inputs.getAxis("move_x");
|
|
||||||
float ay = Inputs.getAxis("move_y");
|
|
||||||
offsetx -= ax * 15f / zoom;
|
|
||||||
offsety -= ay * 15f / zoom;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ui.editor.hasPane()) return;
|
|
||||||
|
|
||||||
zoom += Inputs.scroll()/10f * zoom;
|
|
||||||
clampZoom();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void clampZoom(){
|
|
||||||
zoom = Mathf.clamp(zoom, 0.2f, 12f);
|
|
||||||
}
|
|
||||||
|
|
||||||
private GridPoint2 project(float x, float y){
|
|
||||||
float ratio = 1f / ((float)editor.pixmap().getWidth() / editor.pixmap().getHeight());
|
|
||||||
float size = Math.min(width, height);
|
|
||||||
float sclwidth = size * zoom;
|
|
||||||
float sclheight = size * zoom * ratio;
|
|
||||||
x = (x - getWidth()/2 + sclwidth/2 - offsetx*zoom) / sclwidth * editor.texture().getWidth();
|
|
||||||
y = (y - getHeight()/2 + sclheight/2 - offsety*zoom) / sclheight * editor.texture().getHeight();
|
|
||||||
return Tmp.g1.set((int)x, editor.texture().getHeight() - 1 - (int)y);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Vector2 unproject(int x, int y){
|
|
||||||
float ratio = 1f / ((float)editor.pixmap().getWidth() / editor.pixmap().getHeight());
|
|
||||||
float size = Math.min(width, height);
|
|
||||||
float sclwidth = size * zoom;
|
|
||||||
float sclheight = size * zoom * ratio;
|
|
||||||
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
|
|
||||||
+ offsety*zoom - sclheight/2 + getHeight()/2;
|
|
||||||
return vec.set(px, py);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void draw(Batch batch, float alpha){
|
|
||||||
float ratio = 1f / ((float)editor.pixmap().getWidth() / editor.pixmap().getHeight());
|
|
||||||
float size = Math.min(width, height);
|
|
||||||
float sclwidth = size * zoom;
|
|
||||||
float sclheight = size * zoom * ratio;
|
|
||||||
float centerx = x + width/2 + offsetx * zoom;
|
|
||||||
float centery = y + height/2 + offsety * zoom;
|
|
||||||
|
|
||||||
image.setImageSize(editor.pixmap().getWidth(), editor.pixmap().getHeight());
|
|
||||||
|
|
||||||
batch.flush();
|
|
||||||
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);
|
|
||||||
|
|
||||||
if(grid){
|
|
||||||
Draw.color(Color.GRAY);
|
|
||||||
image.setBounds(centerx - sclwidth/2, centery - sclheight/2, sclwidth, sclheight);
|
|
||||||
image.draw(batch, alpha);
|
|
||||||
Draw.color();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(tool == EditorTool.line && drawing){
|
|
||||||
Vector2 v1 = unproject(startx, starty).add(x, y);
|
|
||||||
float sx = v1.x, sy = v1.y;
|
|
||||||
Vector2 v2 = unproject(lastx, lasty).add(x, y);
|
|
||||||
|
|
||||||
Draw.color(Tmp.c1.set(ColorMapper.getColor(editor.getDrawBlock())));
|
|
||||||
Lines.stroke(Unit.dp.scl(3f * zoom));
|
|
||||||
Lines.line(sx, sy, v2.x, v2.y);
|
|
||||||
|
|
||||||
Lines.poly(sx, sy, 40, editor.getBrushSize() * zoom * 3);
|
|
||||||
|
|
||||||
Lines.poly(v2.x, v2.y, 40, editor.getBrushSize() * zoom * 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
batch.flush();
|
|
||||||
|
|
||||||
if(pop) ScissorStack.popScissors();
|
|
||||||
|
|
||||||
Draw.color(Colors.get("accent"));
|
|
||||||
Lines.stroke(Unit.dp.scl(3f));
|
|
||||||
Lines.rect(x + width/2 - size/2, y + height/2 - size/2, size, size);
|
|
||||||
Draw.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean active(){
|
|
||||||
return Core.scene.getKeyboardFocus() != null
|
|
||||||
&& Core.scene.getKeyboardFocus().isDescendantOf(ui.editor)
|
|
||||||
&& ui.editor.isShown() && tool == EditorTool.zoom &&
|
|
||||||
Core.scene.hit(Graphics.mouse().x, Graphics.mouse().y, true) == this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean touchDown(float x, float y, int pointer, int button){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean tap(float x, float y, int count, int button){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean longPress(float x, float y){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean fling(float velocityX, float velocityY, int button){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean pan(float x, float y, float deltaX, float deltaY){
|
|
||||||
if(!active()) return false;
|
|
||||||
offsetx += deltaX / zoom;
|
|
||||||
offsety -= deltaY / zoom;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean panStop(float x, float y, int pointer, int button){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean zoom(float initialDistance, float distance){
|
|
||||||
if(!active()) return false;
|
|
||||||
float nzoom = distance - initialDistance;
|
|
||||||
zoom += nzoom / 10000f / Unit.dp.scl(1f) * zoom;
|
|
||||||
clampZoom();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean pinch(Vector2 initialPointer1, Vector2 initialPointer2, Vector2 pointer1, Vector2 pointer2){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void pinchStop(){
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
package io.anuke.mindustry.mapeditor;
|
|
||||||
|
|
||||||
import com.badlogic.gdx.utils.Array;
|
|
||||||
|
|
||||||
public class OperationStack{
|
|
||||||
private final static int maxSize = 10;
|
|
||||||
private Array<DrawOperation> stack = new Array<>();
|
|
||||||
private int index = 0;
|
|
||||||
|
|
||||||
public OperationStack(){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clear(){
|
|
||||||
for(DrawOperation op : stack){
|
|
||||||
op.dispose();
|
|
||||||
}
|
|
||||||
stack.clear();
|
|
||||||
index = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void add(DrawOperation action){
|
|
||||||
stack.truncate(stack.size + index);
|
|
||||||
index = 0;
|
|
||||||
stack.add(action);
|
|
||||||
|
|
||||||
if(stack.size > maxSize){
|
|
||||||
stack.get(0).disposeFrom();
|
|
||||||
stack.removeIndex(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean canUndo(){
|
|
||||||
return !(stack.size - 1 + index < 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean canRedo(){
|
|
||||||
return !(index > -1 || stack.size + index < 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void undo(){
|
|
||||||
if(!canUndo()) return;
|
|
||||||
|
|
||||||
stack.get(stack.size - 1 + index).undo();
|
|
||||||
index --;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void redo(){
|
|
||||||
if(!canRedo()) return;
|
|
||||||
|
|
||||||
index ++;
|
|
||||||
stack.get(stack.size - 1 + index).redo();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +1,19 @@
|
|||||||
package io.anuke.mindustry.net;
|
package io.anuke.mindustry.net;
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.Pixmap;
|
|
||||||
import com.badlogic.gdx.graphics.Pixmap.Format;
|
|
||||||
import com.badlogic.gdx.utils.ByteArray;
|
import com.badlogic.gdx.utils.ByteArray;
|
||||||
import com.badlogic.gdx.utils.TimeUtils;
|
import com.badlogic.gdx.utils.TimeUtils;
|
||||||
import io.anuke.mindustry.entities.Player;
|
import io.anuke.mindustry.entities.Player;
|
||||||
import io.anuke.mindustry.game.GameMode;
|
import io.anuke.mindustry.game.GameMode;
|
||||||
|
import io.anuke.mindustry.game.Team;
|
||||||
import io.anuke.mindustry.io.Version;
|
import io.anuke.mindustry.io.Version;
|
||||||
import io.anuke.mindustry.resource.Upgrade;
|
import io.anuke.mindustry.resource.Upgrade;
|
||||||
import io.anuke.mindustry.resource.Weapon;
|
import io.anuke.mindustry.resource.Weapon;
|
||||||
import io.anuke.mindustry.world.*;
|
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.types.BlockPart;
|
import io.anuke.mindustry.world.blocks.types.BlockPart;
|
||||||
import io.anuke.mindustry.world.blocks.types.Rock;
|
|
||||||
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.util.Bits;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
@@ -23,86 +22,6 @@ import static io.anuke.mindustry.Vars.*;
|
|||||||
|
|
||||||
public class NetworkIO {
|
public class NetworkIO {
|
||||||
|
|
||||||
public static void writeMap(Map map, OutputStream os){
|
|
||||||
try(DataOutputStream stream = new DataOutputStream(os)){
|
|
||||||
stream.writeUTF(map.name);
|
|
||||||
stream.writeBoolean(map.oreGen);
|
|
||||||
|
|
||||||
stream.writeShort(map.getWidth());
|
|
||||||
stream.writeShort(map.getHeight());
|
|
||||||
|
|
||||||
int width = map.getWidth();
|
|
||||||
int cap = map.getWidth() * map.getHeight();
|
|
||||||
int pos = 0;
|
|
||||||
|
|
||||||
while(pos < cap){
|
|
||||||
int color = map.pixmap.getPixel(pos % width, pos / width);
|
|
||||||
byte id = ColorMapper.getColorID(color);
|
|
||||||
|
|
||||||
int length = 1;
|
|
||||||
while(true){
|
|
||||||
if(pos >= cap || length > 254){
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
pos ++;
|
|
||||||
|
|
||||||
int next = map.pixmap.getPixel(pos % width, pos / width);
|
|
||||||
if(next != color){
|
|
||||||
pos --;
|
|
||||||
break;
|
|
||||||
}else{
|
|
||||||
length ++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(id == -1) id = 2;
|
|
||||||
stream.writeByte((byte)(length > 127 ? length - 256 : length));
|
|
||||||
stream.writeByte(id);
|
|
||||||
|
|
||||||
pos ++;
|
|
||||||
}
|
|
||||||
}catch (IOException e){
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Map loadMap(InputStream is){
|
|
||||||
try(DataInputStream stream = new DataInputStream(is)){
|
|
||||||
String name = stream.readUTF();
|
|
||||||
boolean ores = stream.readBoolean();
|
|
||||||
|
|
||||||
short width = stream.readShort();
|
|
||||||
short height = stream.readShort();
|
|
||||||
Pixmap pixmap = new Pixmap(width, height, Format.RGBA8888);
|
|
||||||
|
|
||||||
int pos = 0;
|
|
||||||
while(stream.available() > 0){
|
|
||||||
int length = stream.readByte();
|
|
||||||
byte id = stream.readByte();
|
|
||||||
if(length < 0) length += 256;
|
|
||||||
int color = ColorMapper.getColorByID(id);
|
|
||||||
|
|
||||||
for(int p = 0; p < length; p ++){
|
|
||||||
pixmap.drawPixel(pos % width, pos / width,color);
|
|
||||||
pos ++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Map map = new Map();
|
|
||||||
map.name = name;
|
|
||||||
map.oreGen = ores;
|
|
||||||
map.custom = true;
|
|
||||||
map.pixmap = pixmap;
|
|
||||||
map.visible = false;
|
|
||||||
map.id = -1;
|
|
||||||
|
|
||||||
return map;
|
|
||||||
}catch (IOException e){
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void writeWorld(Player player, ByteArray upgrades, OutputStream os){
|
public static void writeWorld(Player player, ByteArray upgrades, OutputStream os){
|
||||||
|
|
||||||
try(DataOutputStream stream = new DataOutputStream(os)){
|
try(DataOutputStream stream = new DataOutputStream(os)){
|
||||||
@@ -112,7 +31,7 @@ public class NetworkIO {
|
|||||||
|
|
||||||
//--GENERAL STATE--
|
//--GENERAL STATE--
|
||||||
stream.writeByte(state.mode.ordinal()); //gamemode
|
stream.writeByte(state.mode.ordinal()); //gamemode
|
||||||
stream.writeByte(world.getMap().custom ? -1 : world.getMap().id); //map ID
|
stream.writeUTF(world.getMap().name); //map ID
|
||||||
|
|
||||||
stream.writeInt(state.wave); //wave
|
stream.writeInt(state.wave); //wave
|
||||||
stream.writeFloat(state.wavetime); //wave countdown
|
stream.writeFloat(state.wavetime); //wave countdown
|
||||||
@@ -136,87 +55,33 @@ public class NetworkIO {
|
|||||||
|
|
||||||
//--MAP DATA--
|
//--MAP DATA--
|
||||||
|
|
||||||
//seed
|
//map size
|
||||||
stream.writeInt(world.getSeed());
|
stream.writeShort(world.width());
|
||||||
|
stream.writeShort(world.height());
|
||||||
int totalblocks = 0;
|
|
||||||
int totalrocks = 0;
|
|
||||||
|
|
||||||
for(int x = 0; x < world.width(); x ++){
|
for(int x = 0; x < world.width(); x ++){
|
||||||
for(int y = 0; y < world.height(); y ++){
|
for(int y = 0; y < world.height(); y ++){
|
||||||
Tile tile = world.tile(x, y);
|
Tile tile = world.tile(x, y);
|
||||||
|
|
||||||
if(tile.breakable()){
|
//TODO will break if block number gets over BYTE_MAX
|
||||||
if(tile.block() instanceof Rock){
|
stream.writeByte(tile.floor().id); //floor ID
|
||||||
totalrocks ++;
|
stream.writeByte(tile.block().id); //block ID
|
||||||
}else{
|
|
||||||
totalblocks ++;
|
if(tile.block() instanceof BlockPart){
|
||||||
}
|
stream.writeByte(tile.link);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//amount of rocks
|
if(tile.entity != null){
|
||||||
stream.writeInt(totalrocks);
|
stream.writeByte(Bits.packByte((byte)tile.getTeam().ordinal(), tile.getRotation()));
|
||||||
|
stream.writeShort((short)tile.entity.health); //health
|
||||||
|
|
||||||
//write all rocks
|
if(tile.entity.inventory != null) tile.entity.inventory.write(stream);
|
||||||
for(int x = 0; x < world.width(); x ++) {
|
if(tile.entity.power != null) tile.entity.power.write(stream);
|
||||||
for (int y = 0; y < world.height(); y++) {
|
if(tile.entity.liquid != null) tile.entity.liquid.write(stream);
|
||||||
Tile tile = world.tile(x, y);
|
|
||||||
|
|
||||||
if (tile.block() instanceof Rock) {
|
tile.entity.write(stream);
|
||||||
stream.writeInt(tile.packedPosition());
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//tile amount
|
|
||||||
stream.writeInt(totalblocks);
|
|
||||||
|
|
||||||
for(int x = 0; x < world.width(); x ++){
|
|
||||||
for(int y = 0; y < world.height(); y ++){
|
|
||||||
Tile tile = world.tile(x, y);
|
|
||||||
|
|
||||||
if(tile.breakable() && !(tile.block() instanceof Rock)){
|
|
||||||
|
|
||||||
stream.writeInt(x + y*world.width()); //tile pos
|
|
||||||
//TODO will break if block number gets over BYTE_MAX
|
|
||||||
stream.writeByte(tile.block().id); //block ID
|
|
||||||
|
|
||||||
if(tile.block() instanceof BlockPart){
|
|
||||||
stream.writeByte(tile.link);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(tile.entity != null){
|
|
||||||
stream.writeByte(tile.getRotation());
|
|
||||||
stream.writeByte(tile.getDump());
|
|
||||||
stream.writeByte(tile.getExtra());
|
|
||||||
stream.writeShort((short)tile.entity.health); //health
|
|
||||||
|
|
||||||
if(tile.entity.inventory != null) tile.entity.inventory.write(stream);
|
|
||||||
if(tile.entity.power != null) tile.entity.power.write(stream);
|
|
||||||
if(tile.entity.liquid != null) tile.entity.liquid.write(stream);
|
|
||||||
|
|
||||||
//timer data
|
|
||||||
|
|
||||||
//amount of active timers
|
|
||||||
byte times = 0;
|
|
||||||
|
|
||||||
for(; times < tile.entity.timer.getTimes().length; times ++){
|
|
||||||
if(tile.entity.timer.getTimes()[times] <= 1){
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stream.writeByte(times);
|
|
||||||
|
|
||||||
for(int i = 0; i < times; i ++){
|
|
||||||
stream.writeFloat(tile.entity.timer.getTimes()[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
tile.entity.write(stream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,6 +93,8 @@ public class NetworkIO {
|
|||||||
/**Return whether a custom map is expected, and thus whether the client should wait for additional data.*/
|
/**Return whether a custom map is expected, and thus whether the client should wait for additional data.*/
|
||||||
public static void loadWorld(InputStream is){
|
public static void loadWorld(InputStream is){
|
||||||
|
|
||||||
|
//TODO !! use map name as the network map in Maps, so getMap() isn't null.
|
||||||
|
|
||||||
try(DataInputStream stream = new DataInputStream(is)){
|
try(DataInputStream stream = new DataInputStream(is)){
|
||||||
float timerTime = stream.readFloat();
|
float timerTime = stream.readFloat();
|
||||||
long timestamp = stream.readLong();
|
long timestamp = stream.readLong();
|
||||||
@@ -237,7 +104,7 @@ public class NetworkIO {
|
|||||||
|
|
||||||
//general state
|
//general state
|
||||||
byte mode = stream.readByte();
|
byte mode = stream.readByte();
|
||||||
byte mapid = stream.readByte();
|
String map = stream.readUTF();
|
||||||
|
|
||||||
int wave = stream.readInt();
|
int wave = stream.readInt();
|
||||||
float wavetime = stream.readFloat();
|
float wavetime = stream.readFloat();
|
||||||
@@ -266,7 +133,7 @@ public class NetworkIO {
|
|||||||
byte weapons = stream.readByte();
|
byte weapons = stream.readByte();
|
||||||
|
|
||||||
for(int i = 0; i < weapons; i ++){
|
for(int i = 0; i < weapons; i ++){
|
||||||
control.upgrades().getWeapons().add((Weapon) Upgrade.getByID(stream.readByte()));
|
control.upgrades().getWeapons().add(Upgrade.getByID(stream.readByte()));
|
||||||
}
|
}
|
||||||
|
|
||||||
player.weaponLeft = player.weaponRight = control.upgrades().getWeapons().peek();
|
player.weaponLeft = player.weaponRight = control.upgrades().getWeapons().peek();
|
||||||
@@ -278,68 +145,44 @@ public class NetworkIO {
|
|||||||
player.add();
|
player.add();
|
||||||
|
|
||||||
//map
|
//map
|
||||||
|
int width = stream.readShort();
|
||||||
|
int height = stream.readShort();
|
||||||
|
|
||||||
int seed = stream.readInt();
|
Tile[][] tiles = world.createTiles(width, height);
|
||||||
|
|
||||||
world.loadMap(world.maps().getMap(mapid), seed);
|
|
||||||
renderer.clearTiles();
|
|
||||||
|
|
||||||
player.set(world.getSpawnX(), world.getSpawnY());
|
|
||||||
|
|
||||||
for(int x = 0; x < world.width(); x ++){
|
for(int x = 0; x < world.width(); x ++){
|
||||||
for(int y = 0; y < world.height(); y ++){
|
for(int y = 0; y < world.height(); y ++){
|
||||||
Tile tile = world.tile(x, y);
|
byte floorid = stream.readByte();
|
||||||
|
byte blockid = stream.readByte();
|
||||||
|
|
||||||
//remove breakables like rocks
|
Tile tile = new Tile(x, y, floorid, blockid);
|
||||||
if(tile.breakable()){
|
|
||||||
world.tile(x, y).setBlock(Blocks.air);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int rocks = stream.readInt();
|
if(tile.block() == Blocks.blockpart){
|
||||||
|
tile.link = stream.readByte();
|
||||||
for(int i = 0; i < rocks; i ++){
|
|
||||||
int pos = stream.readInt();
|
|
||||||
Tile tile = world.tile(pos % world.width(), pos / world.width());
|
|
||||||
Block result = WorldGenerator.rocks.get(tile.floor());
|
|
||||||
if(result != null) tile.setBlock(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
int tiles = stream.readInt();
|
|
||||||
|
|
||||||
for(int i = 0; i < tiles; i ++){
|
|
||||||
int pos = stream.readInt();
|
|
||||||
byte blockid = stream.readByte();
|
|
||||||
|
|
||||||
Tile tile = world.tile(pos % world.width(), pos / world.width());
|
|
||||||
tile.setBlock(Block.getByID(blockid));
|
|
||||||
|
|
||||||
if(tile.block() == Blocks.blockpart){
|
|
||||||
tile.link = stream.readByte();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(tile.entity != null){
|
|
||||||
tile.setRotation(stream.readByte());
|
|
||||||
tile.setDump(stream.readByte());
|
|
||||||
tile.setExtra(stream.readByte());
|
|
||||||
short health = stream.readShort();
|
|
||||||
|
|
||||||
tile.entity.health = health;
|
|
||||||
|
|
||||||
if(tile.entity.inventory != null) tile.entity.inventory.read(stream);
|
|
||||||
if(tile.entity.power != null) tile.entity.power.read(stream);
|
|
||||||
if(tile.entity.liquid != null) tile.entity.liquid.read(stream);
|
|
||||||
|
|
||||||
byte timers = stream.readByte();
|
|
||||||
for(int time = 0; time < timers; time ++){
|
|
||||||
tile.entity.timer.getTimes()[time] = stream.readFloat();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tile.entity.read(stream);
|
if(tile.entity != null) {
|
||||||
|
byte tr = stream.readByte();
|
||||||
|
short health = stream.readShort();
|
||||||
|
|
||||||
|
tile.setTeam(Team.values()[Bits.getLeftByte(tr)]);
|
||||||
|
tile.setRotation(Bits.getRightByte(tr));
|
||||||
|
|
||||||
|
tile.entity.health = health;
|
||||||
|
|
||||||
|
if (tile.entity.inventory != null) tile.entity.inventory.read(stream);
|
||||||
|
if (tile.entity.power != null) tile.entity.power.read(stream);
|
||||||
|
if (tile.entity.liquid != null) tile.entity.liquid.read(stream);
|
||||||
|
|
||||||
|
tile.entity.read(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
tiles[x][y] = tile;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
player.set(world.getSpawnX(), world.getSpawnY());
|
||||||
|
|
||||||
}catch (IOException e){
|
}catch (IOException e){
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import io.anuke.mindustry.resource.Item;
|
|||||||
import io.anuke.mindustry.world.Block;
|
import io.anuke.mindustry.world.Block;
|
||||||
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.util.IOUtils;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
@@ -64,8 +65,7 @@ public class Packets {
|
|||||||
@Override
|
@Override
|
||||||
public void write(ByteBuffer buffer) {
|
public void write(ByteBuffer buffer) {
|
||||||
buffer.putInt(Version.build);
|
buffer.putInt(Version.build);
|
||||||
buffer.put((byte)name.getBytes().length);
|
IOUtils.writeString(buffer, name);
|
||||||
buffer.put(name.getBytes());
|
|
||||||
buffer.put(android ? (byte)1 : 0);
|
buffer.put(android ? (byte)1 : 0);
|
||||||
buffer.putInt(color);
|
buffer.putInt(color);
|
||||||
buffer.put(uuid);
|
buffer.put(uuid);
|
||||||
@@ -74,10 +74,7 @@ public class Packets {
|
|||||||
@Override
|
@Override
|
||||||
public void read(ByteBuffer buffer) {
|
public void read(ByteBuffer buffer) {
|
||||||
version = buffer.getInt();
|
version = buffer.getInt();
|
||||||
byte length = buffer.get();
|
name = IOUtils.readString(buffer);
|
||||||
byte[] bytes = new byte[length];
|
|
||||||
buffer.get(bytes);
|
|
||||||
name = new String(bytes);
|
|
||||||
android = buffer.get() == 1;
|
android = buffer.get() == 1;
|
||||||
color = buffer.getInt();
|
color = buffer.getInt();
|
||||||
uuid = new byte[8];
|
uuid = new byte[8];
|
||||||
@@ -320,8 +317,7 @@ public class Packets {
|
|||||||
}else{
|
}else{
|
||||||
buffer.putShort((short)-1);
|
buffer.putShort((short)-1);
|
||||||
}
|
}
|
||||||
buffer.putShort((short)text.getBytes().length);
|
IOUtils.writeString(buffer, text);
|
||||||
buffer.put(text.getBytes());
|
|
||||||
buffer.putInt(id);
|
buffer.putInt(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,12 +329,9 @@ public class Packets {
|
|||||||
buffer.get(n);
|
buffer.get(n);
|
||||||
name = new String(n);
|
name = new String(n);
|
||||||
}
|
}
|
||||||
short tlength = buffer.getShort();
|
|
||||||
byte[] t = new byte[tlength];
|
|
||||||
buffer.get(t);
|
|
||||||
|
|
||||||
|
text = IOUtils.readString(buffer);
|
||||||
id = buffer.getInt();
|
id = buffer.getInt();
|
||||||
text = new String(t);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -487,16 +480,12 @@ public class Packets {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(ByteBuffer buffer) {
|
public void write(ByteBuffer buffer) {
|
||||||
buffer.putShort((short)message.getBytes().length);
|
IOUtils.writeString(buffer, message);
|
||||||
buffer.put(message.getBytes());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void read(ByteBuffer buffer) {
|
public void read(ByteBuffer buffer) {
|
||||||
short length = buffer.getShort();
|
message = IOUtils.readString(buffer);
|
||||||
byte[] bytes = new byte[length];
|
|
||||||
buffer.get(bytes);
|
|
||||||
message = new String(bytes);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ import io.anuke.mindustry.Vars;
|
|||||||
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.Player;
|
import io.anuke.mindustry.entities.Player;
|
||||||
|
import io.anuke.mindustry.entities.Unit;
|
||||||
import io.anuke.mindustry.graphics.Fx;
|
import io.anuke.mindustry.graphics.Fx;
|
||||||
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.Effects;
|
import io.anuke.ucore.core.Effects;
|
||||||
import io.anuke.ucore.core.Effects.Effect;
|
import io.anuke.ucore.core.Effects.Effect;
|
||||||
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;
|
import io.anuke.ucore.util.Translator;
|
||||||
@@ -125,7 +125,7 @@ public class Weapon extends Upgrade{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void bullet(Entity owner, float x, float y, float angle){
|
void bullet(Unit owner, float x, float y, float angle){
|
||||||
tr.trns(angle, 3f);
|
tr.trns(angle, 3f);
|
||||||
new Bullet(type, owner, x + tr.x, y + tr.y, angle).add();
|
new Bullet(type, owner, x + tr.x, y + tr.y, angle).add();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
package io.anuke.mindustry.ui.dialogs;
|
package io.anuke.mindustry.ui.dialogs;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.graphics.Color;
|
||||||
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.io.Map;
|
||||||
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.scene.event.ClickListener;
|
|
||||||
import io.anuke.ucore.scene.event.InputEvent;
|
|
||||||
import io.anuke.ucore.scene.event.Touchable;
|
import io.anuke.ucore.scene.event.Touchable;
|
||||||
import io.anuke.ucore.scene.ui.*;
|
import io.anuke.ucore.scene.ui.*;
|
||||||
import io.anuke.ucore.scene.ui.layout.Stack;
|
import io.anuke.ucore.scene.ui.layout.Stack;
|
||||||
@@ -21,7 +19,6 @@ import io.anuke.ucore.util.Mathf;
|
|||||||
import static io.anuke.mindustry.Vars.*;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
|
|
||||||
public class LevelDialog extends FloatingDialog{
|
public class LevelDialog extends FloatingDialog{
|
||||||
private Map selectedMap = world.maps().getMap(0);
|
|
||||||
private ScrollPane pane;
|
private ScrollPane pane;
|
||||||
|
|
||||||
public LevelDialog(){
|
public LevelDialog(){
|
||||||
@@ -88,10 +85,8 @@ public class LevelDialog extends FloatingDialog{
|
|||||||
content().row();
|
content().row();
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for(Map map : world.maps().list()){
|
for(Map map : world.maps().all()){
|
||||||
|
|
||||||
if(!map.visible && !debug) continue;
|
|
||||||
|
|
||||||
if(i % maxwidth == 0){
|
if(i % maxwidth == 0){
|
||||||
maps.row();
|
maps.row();
|
||||||
}
|
}
|
||||||
@@ -115,40 +110,16 @@ public class LevelDialog extends FloatingDialog{
|
|||||||
Stack stack = new Stack();
|
Stack stack = new Stack();
|
||||||
|
|
||||||
Image back = new Image("white");
|
Image back = new Image("white");
|
||||||
back.setColor(map.backgroundColor);
|
back.setColor(Color.valueOf("646464"));
|
||||||
|
|
||||||
ImageButton image = new ImageButton(new TextureRegion(map.texture), "togglemap");
|
ImageButton image = new ImageButton(new TextureRegion(map.texture), "togglemap");
|
||||||
image.row();
|
image.row();
|
||||||
image.add(inset).width(images+6);
|
image.add(inset).width(images+6);
|
||||||
TextButton[] delete = new TextButton[1];
|
//TODO custom map delete button
|
||||||
if(map.custom){
|
|
||||||
image.row();
|
|
||||||
delete[0] = image.addButton("Delete", () -> {
|
|
||||||
Timers.run(1f, () -> {
|
|
||||||
ui.showConfirm("$text.level.delete.title", Bundles.format("text.level.delete", Bundles.get("map."+map.name+".name", map.name)), () -> {
|
|
||||||
world.maps().removeMap(map);
|
|
||||||
reload();
|
|
||||||
Core.scene.setScrollFocus(pane);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}).width(images+16).padBottom(-10f).grow().get();
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 hit = new Vector2();
|
image.clicked(() -> {
|
||||||
|
hide();
|
||||||
image.addListener(new ClickListener(){
|
control.playMap(map);
|
||||||
public void clicked(InputEvent event, float x, float y){
|
|
||||||
image.localToStageCoordinates(hit.set(x, y));
|
|
||||||
if(delete[0] != null && (delete[0].getClickListener().isOver() || delete[0].getClickListener().isPressed()
|
|
||||||
|| (Core.scene.hit(hit.x, hit.y, true) != null &&
|
|
||||||
Core.scene.hit(hit.x, hit.y, true).isDescendantOf(delete[0])))){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
selectedMap = map;
|
|
||||||
hide();
|
|
||||||
control.playMap(selectedMap);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
image.getImageCell().size(images);
|
image.getImageCell().size(images);
|
||||||
|
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ public class LoadDialog extends FloatingDialog{
|
|||||||
|
|
||||||
button.defaults().padBottom(3);
|
button.defaults().padBottom(3);
|
||||||
button.row();
|
button.row();
|
||||||
button.add(Bundles.format("text.save.map", color+slot.getMap().localized()));
|
button.add(Bundles.format("text.save.map", color+slot.getMap().meta.name()));
|
||||||
button.row();
|
button.row();
|
||||||
button.add(Bundles.get("text.level.mode") + " " +color+ slot.getMode());
|
button.add(Bundles.get("text.level.mode") + " " +color+ slot.getMode());
|
||||||
button.row();
|
button.row();
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ public class PausedDialog extends FloatingDialog{
|
|||||||
content().row();
|
content().row();
|
||||||
content().addButton("$text.savegame", () -> {
|
content().addButton("$text.savegame", () -> {
|
||||||
save.show();
|
save.show();
|
||||||
}).disabled(b -> world.getMap().id == -1);
|
});
|
||||||
|
|
||||||
content().row();
|
content().row();
|
||||||
content().addButton("$text.loadgame", () -> {
|
content().addButton("$text.loadgame", () -> {
|
||||||
@@ -93,7 +93,6 @@ public class PausedDialog extends FloatingDialog{
|
|||||||
|
|
||||||
imagebutton sa = new imagebutton("icon-save", isize, save::show);
|
imagebutton sa = new imagebutton("icon-save", isize, save::show);
|
||||||
sa.text("$text.save").padTop(4f);
|
sa.text("$text.save").padTop(4f);
|
||||||
sa.cell.disabled(b -> world.getMap().id == -1);
|
|
||||||
|
|
||||||
content().row();
|
content().row();
|
||||||
|
|
||||||
|
|||||||
@@ -121,8 +121,6 @@ public class DebugFragment implements Fragment {
|
|||||||
"players: " + playerGroup.size(),
|
"players: " + playerGroup.size(),
|
||||||
"tiles: " + tileGroup.size(),
|
"tiles: " + tileGroup.size(),
|
||||||
"time: " + Timers.time(),
|
"time: " + Timers.time(),
|
||||||
world.getCore() != null && world.getCore().entity != null ? "core.health: " + world.getCore().entity.health : "",
|
|
||||||
"core: " + world.getCore(),
|
|
||||||
"state.gameover: " + state.gameOver,
|
"state.gameover: " + state.gameOver,
|
||||||
"state: " + state.getState(),
|
"state: " + state.getState(),
|
||||||
!Net.server() ? clientDebug.getOut() : serverDebug.getOut()
|
!Net.server() ? clientDebug.getOut() : serverDebug.getOut()
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ public class MenuFragment implements Fragment{
|
|||||||
|
|
||||||
new imagebutton("icon-play-2", isize, ui.levels::show).text("$text.play").padTop(4f);
|
new imagebutton("icon-play-2", isize, ui.levels::show).text("$text.play").padTop(4f);
|
||||||
|
|
||||||
new imagebutton("icon-tutorial", isize, () -> control.playMap(world.maps().getMap("tutorial"))).text("$text.tutorial").padTop(4f);
|
new imagebutton("icon-tutorial", isize, () -> control.playMap(world.maps().getByName("tutorial"))).text("$text.tutorial").padTop(4f);
|
||||||
|
|
||||||
new imagebutton("icon-load", isize, ui.load::show).text("$text.load").padTop(4f);
|
new imagebutton("icon-load", isize, ui.load::show).text("$text.load").padTop(4f);
|
||||||
|
|
||||||
@@ -120,7 +120,7 @@ public class MenuFragment implements Fragment{
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
dialog.content().add(new MenuButton("icon-tutorial", "$text.tutorial", ()-> {
|
dialog.content().add(new MenuButton("icon-tutorial", "$text.tutorial", ()-> {
|
||||||
control.playMap(world.maps().getMap("tutorial"));
|
control.playMap(world.maps().getByName("tutorial"));
|
||||||
dialog.hide();
|
dialog.hide();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|||||||
@@ -6,9 +6,7 @@ import com.badlogic.gdx.utils.IntIntMap;
|
|||||||
import com.badlogic.gdx.utils.IntMap;
|
import com.badlogic.gdx.utils.IntMap;
|
||||||
import com.badlogic.gdx.utils.IntMap.Entry;
|
import com.badlogic.gdx.utils.IntMap.Entry;
|
||||||
import com.badlogic.gdx.utils.ObjectIntMap;
|
import com.badlogic.gdx.utils.ObjectIntMap;
|
||||||
|
|
||||||
import io.anuke.mindustry.world.blocks.Blocks;
|
import io.anuke.mindustry.world.blocks.Blocks;
|
||||||
import io.anuke.mindustry.world.blocks.SpecialBlocks;
|
|
||||||
|
|
||||||
public class ColorMapper{
|
public class ColorMapper{
|
||||||
/**maps color IDs to their actual RGBA8888 colors*/
|
/**maps color IDs to their actual RGBA8888 colors*/
|
||||||
@@ -19,8 +17,6 @@ public class ColorMapper{
|
|||||||
private static ObjectIntMap<Block> reverseColors = new ObjectIntMap<>();
|
private static ObjectIntMap<Block> reverseColors = new ObjectIntMap<>();
|
||||||
private static Array<BlockPair> pairs = new Array<>();
|
private static Array<BlockPair> pairs = new Array<>();
|
||||||
private static IntMap<BlockPair> colors = map(
|
private static IntMap<BlockPair> colors = map(
|
||||||
"ff0000", pair(Blocks.dirt, SpecialBlocks.enemySpawn),
|
|
||||||
"00ff00", pair(Blocks.stone, SpecialBlocks.playerSpawn),
|
|
||||||
"323232", pair(Blocks.stone),
|
"323232", pair(Blocks.stone),
|
||||||
"646464", pair(Blocks.stone, Blocks.stoneblock),
|
"646464", pair(Blocks.stone, Blocks.stoneblock),
|
||||||
"50965a", pair(Blocks.grass),
|
"50965a", pair(Blocks.grass),
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
package io.anuke.mindustry.world;
|
|
||||||
|
|
||||||
public class Map{
|
|
||||||
public String name;
|
|
||||||
public String author;
|
|
||||||
public String description;
|
|
||||||
public boolean visible = true;
|
|
||||||
public boolean custom = false;
|
|
||||||
public boolean oreGen = true;
|
|
||||||
}
|
|
||||||
@@ -5,7 +5,6 @@ import com.badlogic.gdx.math.Vector2;
|
|||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
import io.anuke.mindustry.entities.Player;
|
import io.anuke.mindustry.entities.Player;
|
||||||
import io.anuke.mindustry.entities.Units;
|
import io.anuke.mindustry.entities.Units;
|
||||||
import io.anuke.mindustry.game.SpawnPoint;
|
|
||||||
import io.anuke.mindustry.game.Team;
|
import io.anuke.mindustry.game.Team;
|
||||||
import io.anuke.mindustry.graphics.Fx;
|
import io.anuke.mindustry.graphics.Fx;
|
||||||
import io.anuke.mindustry.resource.ItemStack;
|
import io.anuke.mindustry.resource.ItemStack;
|
||||||
@@ -93,13 +92,6 @@ public class Placement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean validPlace(Team team, int x, int y, Block type){
|
public static boolean validPlace(Team team, int x, int y, Block type){
|
||||||
for(int i = 0; i < world.getSpawns().size; i ++){
|
|
||||||
SpawnPoint spawn = world.getSpawns().get(i);
|
|
||||||
if(Vector2.dst(x * tilesize, y * tilesize, spawn.start.worldx(), spawn.start.worldy()) < enemyspawnspace){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Recipe recipe = Recipes.getByResult(type);
|
Recipe recipe = Recipes.getByResult(type);
|
||||||
|
|
||||||
if(recipe == null || !state.inventory.hasItems(recipe.requirements)){
|
if(recipe == null || !state.inventory.hasItems(recipe.requirements)){
|
||||||
@@ -157,8 +149,9 @@ public class Placement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO make this work!
|
||||||
public static boolean isSpawnPoint(Tile tile){
|
public static boolean isSpawnPoint(Tile tile){
|
||||||
return tile != null && tile.x == world.getCore().x && tile.y == world.getCore().y - 2;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean validBreak(Team team, int x, int y){
|
public static boolean validBreak(Team team, int x, int y){
|
||||||
|
|||||||
@@ -37,24 +37,25 @@ public class Tile{
|
|||||||
this.x = (short)x;
|
this.x = (short)x;
|
||||||
this.y = (short)y;
|
this.y = (short)y;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Tile(int x, int y, Block floor){
|
public Tile(int x, int y, byte floor, byte wall){
|
||||||
this(x, y);
|
this(x, y);
|
||||||
iSetFloor(floor);
|
this.floor = floor;
|
||||||
|
this.wall = wall;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Tile(int x, int y, byte floor, byte wall, byte rotation, byte team){
|
||||||
|
this(x, y);
|
||||||
|
this.floor = floor;
|
||||||
|
this.wall = wall;
|
||||||
|
this.rotation = rotation;
|
||||||
|
this.team = team;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int packedPosition(){
|
public int packedPosition(){
|
||||||
return x + y * world.width();
|
return x + y * world.width();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void iSetFloor(Block floor){
|
|
||||||
this.floor = (byte)floor.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void iSetBlock(Block wall){
|
|
||||||
this.wall = (byte)wall.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte getWallID(){
|
public byte getWallID(){
|
||||||
return wall;
|
return wall;
|
||||||
}
|
}
|
||||||
@@ -130,23 +131,23 @@ public class Tile{
|
|||||||
public void setBlock(Block type, int rotation){
|
public void setBlock(Block type, int rotation){
|
||||||
synchronized (tileSetLock) {
|
synchronized (tileSetLock) {
|
||||||
if(rotation < 0) rotation = (-rotation + 2);
|
if(rotation < 0) rotation = (-rotation + 2);
|
||||||
iSetBlock(type);
|
this.wall = (byte)type.id;
|
||||||
setRotation((byte) (rotation % 4));
|
|
||||||
this.link = 0;
|
this.link = 0;
|
||||||
|
setRotation((byte) (rotation % 4));
|
||||||
changed();
|
changed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBlock(Block type){
|
public void setBlock(Block type){
|
||||||
synchronized (tileSetLock) {
|
synchronized (tileSetLock) {
|
||||||
iSetBlock(type);
|
this.wall = (byte)type.id;
|
||||||
this.link = 0;
|
this.link = 0;
|
||||||
changed();
|
changed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFloor(Block type){
|
public void setFloor(Block type){
|
||||||
iSetFloor(type);
|
this.floor = (byte)type.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRotation(byte rotation){
|
public void setRotation(byte rotation){
|
||||||
|
|||||||
@@ -1,19 +1,14 @@
|
|||||||
package io.anuke.mindustry.world;
|
package io.anuke.mindustry.world;
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.Color;
|
|
||||||
import com.badlogic.gdx.graphics.Pixmap;
|
|
||||||
import com.badlogic.gdx.utils.Array;
|
|
||||||
import com.badlogic.gdx.utils.ObjectMap;
|
import com.badlogic.gdx.utils.ObjectMap;
|
||||||
import io.anuke.mindustry.game.SpawnPoint;
|
import io.anuke.mindustry.io.MapTileData;
|
||||||
import io.anuke.mindustry.world.ColorMapper.BlockPair;
|
import io.anuke.mindustry.io.MapTileData.TileData;
|
||||||
import io.anuke.mindustry.world.blocks.Blocks;
|
import io.anuke.mindustry.world.blocks.Blocks;
|
||||||
import io.anuke.mindustry.world.blocks.SpecialBlocks;
|
|
||||||
import io.anuke.ucore.graphics.Hue;
|
|
||||||
import io.anuke.ucore.noise.Noise;
|
import io.anuke.ucore.noise.Noise;
|
||||||
import io.anuke.ucore.util.Mathf;
|
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.world;
|
import static io.anuke.mindustry.Vars.world;
|
||||||
|
|
||||||
|
|
||||||
public class WorldGenerator {
|
public class WorldGenerator {
|
||||||
public static final ObjectMap<Block, Block> rocks = new ObjectMap<Block, Block>(){{
|
public static final ObjectMap<Block, Block> rocks = new ObjectMap<Block, Block>(){{
|
||||||
put(Blocks.stone, Blocks.rock);
|
put(Blocks.stone, Blocks.rock);
|
||||||
@@ -22,67 +17,21 @@ public class WorldGenerator {
|
|||||||
put(Blocks.blackstone, Blocks.blackrock);
|
put(Blocks.blackstone, Blocks.blackrock);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
/**Returns the core (starting) block. Should fill spawns with the correct spawnpoints.*/
|
/**Should fill spawns with the correct spawnpoints.*/
|
||||||
public static void generate(Tile[][] tiles, Map map){
|
public static void generate(Tile[][] tiles, MapTileData data){
|
||||||
Noise.setSeed(world.getSeed());
|
Noise.setSeed(world.getSeed());
|
||||||
|
|
||||||
for(int x = 0; x < pixmap.getWidth(); x ++){
|
for(int x = 0; x < data.width(); x ++){
|
||||||
for(int y = 0; y < pixmap.getHeight(); y ++){
|
for(int y = 0; y < data.height(); y ++){
|
||||||
Block floor = Blocks.stone;
|
TileData tile = data.read();
|
||||||
Block block = Blocks.air;
|
tiles[x][y] = new Tile(x, y, tile.floor, tile.wall, tile.rotation, tile.team);
|
||||||
|
|
||||||
int color = pixmap.getPixel(x, pixmap.getHeight()-1-y);
|
//TODO ores, plants, extra decoration?
|
||||||
BlockPair pair = ColorMapper.get(color);
|
|
||||||
|
|
||||||
if(pair != null){
|
|
||||||
block = pair.wall;
|
|
||||||
floor = pair.floor;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(block == SpecialBlocks.playerSpawn){
|
|
||||||
block = Blocks.air;
|
|
||||||
core = world.tile(x, y);
|
|
||||||
}else if(block == SpecialBlocks.enemySpawn){
|
|
||||||
block = Blocks.air;
|
|
||||||
spawns.add(new SpawnPoint(tiles[x][y]));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(block == Blocks.air && Mathf.chance(0.025) && rocks.containsKey(floor)){
|
|
||||||
block = rocks.get(floor);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(world.getMap().oreGen && (floor == Blocks.stone || floor == Blocks.grass || floor == Blocks.blackstone ||
|
|
||||||
floor == Blocks.snow || floor == Blocks.sand)){
|
|
||||||
if(Noise.nnoise(x, y, 8, 1) > 0.21){
|
|
||||||
floor = Blocks.iron;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Noise.nnoise(x, y, 6, 1) > 0.237){
|
|
||||||
floor = Blocks.coal;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Noise.nnoise(x + 9999, y + 9999, 8, 1) > 0.27){
|
|
||||||
floor = Blocks.titanium;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Noise.nnoise(x + 99999, y + 99999, 7, 1) > 0.259){
|
|
||||||
floor = Blocks.uranium;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(color == Hue.rgb(Color.PURPLE)){
|
|
||||||
//TODO place unit here
|
|
||||||
//if(!Vars.android) new BaseUnit(UnitTypes.target).set(x * tilesize, y * tilesize).add();
|
|
||||||
floor = Blocks.stone;
|
|
||||||
}
|
|
||||||
|
|
||||||
tiles[x][y].setBlock(block, 0);
|
|
||||||
tiles[x][y].setFloor(floor);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int x = 0; x < pixmap.getWidth(); x ++){
|
for(int x = 0; x < data.width(); x ++){
|
||||||
for(int y = 0; y < pixmap.getHeight(); y ++) {
|
for(int y = 0; y < data.height(); y ++) {
|
||||||
tiles[x][y].updateOcclusion();
|
tiles[x][y].updateOcclusion();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -229,7 +229,7 @@ public class Turret extends Block{
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void bullet(Tile tile, float angle){
|
protected void bullet(Tile tile, float angle){
|
||||||
new Bullet(bullet, tile.entity, tile.drawx() + tr.x, tile.drawy() + tr.y, angle).add();
|
new Bullet(bullet, tile.entity, tile.getTeam(), tile.drawx() + tr.x, tile.drawy() + tr.y, angle).add();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TurretEntity extends TileEntity{
|
public static class TurretEntity extends TileEntity{
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import io.anuke.mindustry.world.Tile;
|
|||||||
|
|
||||||
import static io.anuke.mindustry.Vars.debug;
|
import static io.anuke.mindustry.Vars.debug;
|
||||||
import static io.anuke.mindustry.Vars.state;
|
import static io.anuke.mindustry.Vars.state;
|
||||||
|
import static io.anuke.mindustry.Vars.world;
|
||||||
|
|
||||||
public class CoreBlock extends StorageBlock {
|
public class CoreBlock extends StorageBlock {
|
||||||
protected int capacity = 1000;
|
protected int capacity = 1000;
|
||||||
@@ -25,6 +26,12 @@ public class CoreBlock extends StorageBlock {
|
|||||||
return debug ? 0 : amount;
|
return debug ? 0 : amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onDestroyed(Tile tile){
|
||||||
|
//TODO more dramatic effects
|
||||||
|
super.onDestroyed(tile);
|
||||||
|
world.getAllyCores().removeValue(tile, true);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleItem(Item item, Tile tile, Tile source){
|
public void handleItem(Item item, Tile tile, Tile source){
|
||||||
if(Net.server() || !Net.active()) state.inventory.addItem(item, 1);
|
if(Net.server() || !Net.active()) state.inventory.addItem(item, 1);
|
||||||
|
|||||||
Reference in New Issue
Block a user