Added new save file format system, wall balancing

This commit is contained in:
Anuken 2018-01-02 15:47:08 -05:00
parent 4b69f5b41c
commit 2796ab9801
25 changed files with 939 additions and 529 deletions

View file

@ -11,7 +11,6 @@ import io.anuke.kryonet.KryoClient;
import io.anuke.kryonet.KryoServer;
import io.anuke.mindustry.io.PlatformFunction;
import io.anuke.mindustry.net.Net;
import io.anuke.ucore.function.Callable;
import io.anuke.ucore.scene.ui.TextField;
import io.anuke.ucore.scene.ui.layout.Unit;
@ -56,17 +55,16 @@ public class AndroidLauncher extends AndroidApplication{
}
@Override
public void onSceneChange(String state, String details, String icon) {
}
public void onSceneChange(String state, String details, String icon) { }
@Override
public void onGameExit() {
public void onGameExit() { }
@Override
public void openDonations() {
showDonations();
}
};
Mindustry.donationsCallable = new Callable(){ @Override public void run(){ showDonations(); } };
if(doubleScaleTablets && isTablet(this.getContext())){
Unit.dp.addition = 0.5f;

View file

@ -4,17 +4,15 @@ import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.I18NBundle;
import com.badlogic.gdx.utils.OrderedMap;
import io.anuke.mindustry.core.*;
import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.io.PlatformFunction;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.blocks.*;
import io.anuke.ucore.UCore;
import io.anuke.mindustry.world.BlockLoader;
import io.anuke.ucore.core.Core;
import io.anuke.ucore.core.Inputs;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.function.Callable;
import io.anuke.ucore.modules.ModuleCore;
import io.anuke.ucore.scene.ui.TextField;
@ -22,7 +20,6 @@ import java.util.Date;
import java.util.Locale;
public class Mindustry extends ModuleCore {
public static Callable donationsCallable;
public static boolean hasDiscord = true;
public static Array<String> args = new Array<>();
public static PlatformFunction platforms = new PlatformFunction(){
@ -31,14 +28,17 @@ public class Mindustry extends ModuleCore {
@Override public void openLink(String link){ }
@Override public void addDialog(TextField field){}
@Override public void onSceneChange(String state, String details, String icon) {}
@Override public void onGameExit() { }
@Override public void onGameExit() {}
@Override public void openDonations() {}
};
public static OrderedMap<String, Integer> idMap = new OrderedMap<>();
public static boolean externalBundle = false;
@Override
public void init(){
loadBundle();
BlockLoader.load();
module(Vars.world = new World());
module(Vars.control = new Control());
@ -68,24 +68,12 @@ public class Mindustry extends ModuleCore {
Locale locale = Locale.getDefault();
Core.bundle = I18NBundle.createBundle(handle, locale);
}
//always initialize blocks in this order, otherwise there are ID errors
Block[] blockClasses = {
Blocks.air,
DefenseBlocks.compositewall,
DistributionBlocks.conduit,
ProductionBlocks.coaldrill,
WeaponBlocks.chainturret,
SpecialBlocks.enemySpawn
};
UCore.log("Block classes: " + blockClasses.length);
}
@Override
public void postInit(){
Vars.control.reset();
Vars.control.getSaves().convertSaves();
}
@Override

View file

@ -2,6 +2,7 @@ package io.anuke.mindustry.core;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.utils.TimeUtils;
import com.badlogic.gdx.utils.compression.Lzma;
import com.badlogic.gdx.utils.reflect.ClassReflection;
import com.badlogic.gdx.utils.reflect.ReflectionException;
import io.anuke.mindustry.Vars;
@ -27,6 +28,8 @@ import io.anuke.ucore.entities.BaseBulletType;
import io.anuke.ucore.entities.Entity;
import io.anuke.ucore.modules.Module;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.util.Arrays;
@ -76,8 +79,16 @@ public class NetClient extends Module {
Net.handle(WorldData.class, data -> {
Gdx.app.postRunnable(() -> {
ByteArrayOutputStream outc = new ByteArrayOutputStream();
try {
Lzma.decompress(data.stream, outc);
}catch (IOException e){
throw new RuntimeException(e);
}
UCore.log("Recieved world data: " + data.stream.available() + " bytes.");
NetworkIO.load(data.stream);
NetworkIO.load(new ByteArrayInputStream(outc.toByteArray()));
Vars.player.set(Vars.control.core.worldx(), Vars.control.core.worldy() - Vars.tilesize*2);
GameState.set(State.playing);

View file

@ -5,6 +5,7 @@ import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.utils.IntArray;
import com.badlogic.gdx.utils.IntMap;
import com.badlogic.gdx.utils.TimeUtils;
import com.badlogic.gdx.utils.compression.Lzma;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.BulletType;
@ -56,8 +57,19 @@ public class NetServer extends Module{
UCore.log("Packed " + stream.size() + " uncompressed bytes of data.");
ByteArrayInputStream inc = new ByteArrayInputStream(stream.toByteArray());
ByteArrayOutputStream outc = new ByteArrayOutputStream();
try {
Lzma.compress(inc, outc);
}catch (IOException e){
throw new RuntimeException(e);
}
UCore.log("Packed " + outc.size() + " COMPRESSED bytes of data.");
//TODO compress and uncompress when sending
data.stream = new ByteArrayInputStream(stream.toByteArray());
data.stream = new ByteArrayInputStream(outc.toByteArray());
Net.sendStream(id, data);

View file

@ -53,8 +53,6 @@ public class UI extends SceneModule{
Tooltip tooltip;
Tile configTile;
MapEditor editor;
String lastip = "localhost";
int lastport = Vars.port;
boolean wasPaused = false;
private Fragment menufrag = new MenuFragment(),

View file

@ -5,7 +5,8 @@ import io.anuke.ucore.core.Settings;
import io.anuke.ucore.util.Mathf;
public class EnemySpawn{
private static float[] scalings = {2f, 1.5f, 1f};
/**Scaling multiplier for each difficulty. Easy, normal, hard.*/
private static float[] scalings = {4f, 2.5f, 1.5f};
/**The enemy type spawned*/
public final Class<? extends Enemy> type;

View file

@ -16,9 +16,8 @@ import io.anuke.ucore.entities.Entities;
import java.io.*;
import static io.anuke.mindustry.Vars.android;
import static io.anuke.mindustry.io.SaveIO.enemyIDs;
import static io.anuke.mindustry.io.SaveIO.idEnemies;
import static io.anuke.mindustry.io.SaveFileVersion.enemyIDs;
import static io.anuke.mindustry.io.SaveFileVersion.idEnemies;
public class NetworkIO {
private static final int fileVersionID = 13;

View file

@ -1,9 +1,9 @@
package io.anuke.mindustry.io;
import java.util.Date;
import io.anuke.ucore.scene.ui.TextField;
import java.util.Date;
public interface PlatformFunction{
public String format(Date date);
public String format(int number);
@ -11,4 +11,5 @@ public interface PlatformFunction{
public void addDialog(TextField field);
public void onSceneChange(String state, String details, String icon);
public void onGameExit();
public void openDonations();
}

View file

@ -0,0 +1,49 @@
package io.anuke.mindustry.io;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.ObjectMap;
import io.anuke.mindustry.entities.enemies.*;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public abstract class SaveFileVersion {
public static final Array<Class<? extends Enemy>> enemyIDs = Array.with(
Enemy.class,
FastEnemy.class,
RapidEnemy.class,
FlamerEnemy.class,
TankEnemy.class,
BlastEnemy.class,
MortarEnemy.class,
TestEnemy.class,
HealerEnemy.class,
TitanEnemy.class,
EmpEnemy.class
);
public static final ObjectMap<Class<? extends Enemy>, Byte> idEnemies = new ObjectMap<Class<? extends Enemy>, Byte>(){{
for(int i = 0; i < enemyIDs.size; i ++){
put(enemyIDs.get(i), (byte)i);
}
}};
public final int version;
public SaveFileVersion(int version){
this.version = version;
}
public SaveMeta getData(DataInputStream stream) throws IOException{
int version = stream.readInt(); //read version
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
return new SaveMeta(version, time, mode, map, wave);
}
public abstract void read(DataInputStream stream) throws IOException;
public abstract void write(DataOutputStream stream) throws IOException;
}

View file

@ -1,112 +1,23 @@
package io.anuke.mindustry.io;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Base64Coder;
import com.badlogic.gdx.utils.ObjectMap;
import com.badlogic.gdx.utils.TimeUtils;
import com.badlogic.gdx.utils.reflect.ClassReflection;
import io.anuke.mindustry.Mindustry;
import com.badlogic.gdx.utils.OrderedMap;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.entities.enemies.*;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.Weapon;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.GameMode;
import io.anuke.mindustry.world.Map;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.Blocks;
import io.anuke.ucore.core.Core;
import io.anuke.mindustry.io.versions.Save12;
import io.anuke.mindustry.io.versions.Save13;
import io.anuke.ucore.UCore;
import io.anuke.ucore.core.Settings;
import io.anuke.ucore.entities.Entities;
import java.io.*;
import java.util.Arrays;
import java.util.Date;
import static io.anuke.mindustry.Vars.android;
/*
* Save format:
*
* --META--
*
* Save file version ID (int)
* Last saved timestamp (long)
*
* --STATE DATA--
* Wave (int)
* Wave countdown time (float)
*
* Gamemode Ordinal (byte)
* Map ordinal (byte)
*
* Player X (float)
* Player Y (float)
* Player health (int)
*
* Amount of weapons (byte)
* (weapon list)
* Weapon enum ordinal (byte)
*
* Amount of items (byte)
* (item list)
* Item ID (byte)
* Item amount (int)
*
* --ENEMY DATA--
* Amount of enemies (int)
* (enemy list)
* enemy type ID (byte)
* spawn lane (byte)
* x (float)
* y (float)
* tier (byte)
* health (int)
*
*
* --MAP DATA--
* Seed (int)
* Amount of tiles (int)
* (tile list)
* Tile position, as a single integer, in the format x+y*width
* Tile link - (byte)
* Tile type (boolean)- whether the block has a tile entity attached
* Block ID - the block ID (byte)
* (the following only applies to tile entity blocks)
* Block placerot (byte)
* Block health (int)
* Amount of items (byte)
* (item list)
* Item ID (byte)
* Item amount (int)
* Additional tile entity data (varies, check the TileEntity classes)
*/
public class SaveIO{
/**Save file version ID. Should be incremented every breaking release.*/
private static final int fileVersionID = 12;
//TODO automatic registration of types?
public static final Array<Class<? extends Enemy>> enemyIDs = Array.with(
Enemy.class,
FastEnemy.class,
RapidEnemy.class,
FlamerEnemy.class,
TankEnemy.class,
BlastEnemy.class,
MortarEnemy.class,
TestEnemy.class,
HealerEnemy.class,
TitanEnemy.class,
EmpEnemy.class
);
public static final ObjectMap<Class<? extends Enemy>, Byte> idEnemies = new ObjectMap<Class<? extends Enemy>, Byte>(){{
for(int i = 0; i < enemyIDs.size; i ++){
put(enemyIDs.get(i), (byte)i);
}
public static final OrderedMap<Integer, SaveFileVersion> versions = new OrderedMap(){{
put(12, new Save12());
put(13, new Save13());
}};
public static void saveToSlot(int slot){
if(Vars.gwt){
ByteArrayOutputStream stream = new ByteArrayOutputStream();
@ -146,6 +57,29 @@ public class SaveIO{
}
}
public static boolean checkConvert(int slot){
try{
DataInputStream stream = readSlotMeta(slot);
int version = stream.readInt();
stream.close();
if(version != getVersion().version){
UCore.log("Converting slot " + slot + ": " + version + " -> " + getVersion().version);
stream = readSlotMeta(slot);
SaveFileVersion target = versions.get(version);
target.read(stream);
stream.close();
saveToSlot(slot);
return true;
}
return false;
}catch (IOException e){
throw new RuntimeException(e);
}
}
public static boolean isSaveValid(FileHandle file){
return isSaveValid(new DataInputStream(file.read()));
}
@ -154,7 +88,7 @@ public class SaveIO{
try{
SaveMeta meta = getData(stream);
return meta.version == fileVersionID && meta.map != null;
return meta.map != null;
}catch (Exception e){
return false;
}
@ -167,12 +101,9 @@ public class SaveIO{
public static SaveMeta getData(DataInputStream stream){
try{
int version = stream.readInt(); //read version
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
return new SaveMeta(version, time, mode, map, wave);
SaveMeta meta = getVersion().getData(stream);
stream.close();
return meta;
}catch (IOException e){
throw new RuntimeException(e);
}
@ -187,132 +118,13 @@ public class SaveIO{
}
public static void write(OutputStream os){
try(DataOutputStream stream = new DataOutputStream(os)){
//--META--
stream.writeInt(fileVersionID); //version id
stream.writeLong(TimeUtils.millis()); //last saved
//--GENERAL STATE--
stream.writeByte(Vars.control.getMode().ordinal()); //gamemode
stream.writeByte(Vars.world.getMap().id); //map ID
stream.writeInt(Vars.control.getWave()); //wave
stream.writeFloat(Vars.control.getWaveCountdown()); //wave countdown
stream.writeFloat(Vars.player.x); //player x/y
stream.writeFloat(Vars.player.y);
stream.writeInt(Vars.player.health); //player health
stream.writeByte(Vars.control.getWeapons().size - 1); //amount of weapons
//start at 1, because the first weapon is always the starter - ignore that
for(int i = 1; i < Vars.control.getWeapons().size; i ++){
stream.writeByte(Vars.control.getWeapons().get(i).ordinal()); //weapon ordinal
}
//--INVENTORY--
int l = Vars.control.getItems().length;
int itemsize = 0;
for(int i = 0; i < l; i ++){
if(Vars.control.getItems()[i] > 0){
itemsize ++;
}
}
stream.writeByte(itemsize); //amount of items
for(int i = 0; i < l; i ++){
if(Vars.control.getItems()[i] > 0){
stream.writeByte(i); //item ID
stream.writeInt(Vars.control.getItems()[i]); //item amount
}
}
//--ENEMIES--
int totalEnemies = 0;
Array<Enemy> enemies = Vars.control.enemyGroup.all();
for(int i = 0; i < enemies.size; i ++){
Enemy enemy = enemies.get(i);
if(idEnemies.containsKey(enemy.getClass())){
totalEnemies ++;
}
}
stream.writeInt(totalEnemies); //enemy amount
for(int i = 0; i < enemies.size; i ++){
Enemy enemy = enemies.get(i);
if(idEnemies.containsKey(enemy.getClass())){
stream.writeByte(idEnemies.get(enemy.getClass())); //type
stream.writeByte(enemy.lane); //lane
stream.writeFloat(enemy.x); //x
stream.writeFloat(enemy.y); //y
stream.writeByte(enemy.tier); //tier
stream.writeInt(enemy.health); //health
}
}
//--MAP DATA--
//seed
stream.writeInt(Vars.world.getSeed());
int totalblocks = 0;
for(int x = 0; x < Vars.world.width(); x ++){
for(int y = 0; y < Vars.world.height(); y ++){
Tile tile = Vars.world.tile(x, y);
if(tile.breakable()){
totalblocks ++;
}
}
}
//tile amount
stream.writeInt(totalblocks);
for(int x = 0; x < Vars.world.width(); x ++){
for(int y = 0; y < Vars.world.height(); y ++){
Tile tile = Vars.world.tile(x, y);
if(tile.breakable()){
stream.writeInt(x + y*Vars.world.width()); //tile pos
stream.writeByte(tile.link);
stream.writeBoolean(tile.entity != null); //whether it has a tile entity
stream.writeInt(tile.block().id); //block ID
if(tile.entity != null){
stream.writeByte(tile.getRotation()); //placerot
stream.writeInt(tile.entity.health); //health
int amount = 0;
for(int i = 0; i < tile.entity.items.length; i ++){
if(tile.entity.items[i] > 0) amount ++;
}
stream.writeByte(amount); //amount of items
for(int i = 0; i < tile.entity.items.length; i ++){
if(tile.entity.items[i] > 0){
stream.writeByte(i); //item ID
stream.writeInt(tile.entity.items[i]); //item amount
}
}
tile.entity.write(stream);
}
}
}
}
DataOutputStream stream;
try{
stream = new DataOutputStream(os);
getVersion().write(stream);
stream.close();
}catch (IOException e){
throw new RuntimeException(e);
}
@ -324,150 +136,19 @@ public class SaveIO{
//TODO GWT support
public static void load(InputStream is){
DataInputStream stream;
try(DataInputStream stream = new DataInputStream(is)){
int version = stream.readInt();
/*long loadTime = */stream.readLong();
if(version != fileVersionID){
throw new RuntimeException("Save file version mismatch!");
}
//general state
byte mode = stream.readByte();
byte mapid = stream.readByte();
int wave = stream.readInt();
float wavetime = stream.readFloat();
float playerx = stream.readFloat();
float playery = stream.readFloat();
int playerhealth = stream.readInt();
Vars.player.x = playerx;
Vars.player.y = playery;
Vars.player.health = playerhealth;
Vars.control.setMode(GameMode.values()[mode]);
Core.camera.position.set(playerx, playery, 0);
//weapons
Vars.control.getWeapons().clear();
Vars.control.getWeapons().add(Weapon.blaster);
Vars.player.weapon = Weapon.blaster;
int weapons = stream.readByte();
for(int i = 0; i < weapons; i ++){
Vars.control.addWeapon(Weapon.values()[stream.readByte()]);
}
Vars.ui.updateWeapons();
//inventory
int totalItems = stream.readByte();
Arrays.fill(Vars.control.getItems(), 0);
for(int i = 0; i < totalItems; i ++){
Item item = Item.getByID(stream.readByte());
int amount = stream.readInt();
Vars.control.getItems()[item.id] = amount;
}
Vars.ui.updateItems();
//enemies
Entities.clear();
int enemies = stream.readInt();
Array<Enemy> enemiesToUpdate = new Array<>();
for(int i = 0; i < enemies; i ++){
byte type = stream.readByte();
int lane = stream.readByte();
float x = stream.readFloat();
float y = stream.readFloat();
byte tier = stream.readByte();
int health = stream.readInt();
try{
Enemy enemy = ClassReflection.newInstance(enemyIDs.get(type));
enemy.lane = lane;
enemy.health = health;
enemy.x = x;
enemy.y = y;
enemy.tier = tier;
enemy.add(Vars.control.enemyGroup);
enemiesToUpdate.add(enemy);
}catch (Exception e){
throw new RuntimeException(e);
}
}
Vars.control.setWaveData(enemies, wave, wavetime);
if(!android)
Vars.player.add();
//map
int seed = stream.readInt();
int tiles = stream.readInt();
Vars.world.loadMap(Vars.world.maps().getMap(mapid), seed);
Vars.renderer.clearTiles();
for(Enemy enemy : enemiesToUpdate){
enemy.node = -2;
}
for(int x = 0; x < Vars.world.width(); x ++){
for(int y = 0; y < Vars.world.height(); y ++){
Tile tile = Vars.world.tile(x, y);
//remove breakables like rocks
if(tile.breakable()){
Vars.world.tile(x, y).setBlock(Blocks.air);
}
}
}
for(int i = 0; i < tiles; i ++){
int pos = stream.readInt();
byte link = stream.readByte();
boolean hasEntity = stream.readBoolean();
int blockid = stream.readInt();
Tile tile = Vars.world.tile(pos % Vars.world.width(), pos / Vars.world.width());
tile.setBlock(Block.getByID(blockid));
tile.link = link;
if(hasEntity){
byte rotation = stream.readByte();
int health = stream.readInt();
int items = stream.readByte();
tile.entity.health = health;
tile.setRotation(rotation);
for(int j = 0; j < items; j ++){
int itemid = stream.readByte();
int itemamount = stream.readInt();
tile.entity.items[itemid] = itemamount;
}
tile.entity.read(stream);
}
}
try{
stream = new DataInputStream(is);
getVersion().read(stream);
stream.close();
}catch (IOException e){
throw new RuntimeException(e);
}
}
public static SaveFileVersion getVersion(){
return versions.get(versions.orderedKeys().peek());
}
}

View file

@ -34,6 +34,12 @@ public class Saves {
}
}
public void convertSaves(){
for(SaveSlot slot : saves){
SaveIO.checkConvert(slot.index);
}
}
public SaveSlot getCurrent() {
return current;
}

View file

@ -0,0 +1,300 @@
package io.anuke.mindustry.io.versions;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.TimeUtils;
import com.badlogic.gdx.utils.reflect.ClassReflection;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.entities.enemies.Enemy;
import io.anuke.mindustry.io.SaveFileVersion;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.Weapon;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.GameMode;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.Blocks;
import io.anuke.ucore.core.Core;
import io.anuke.ucore.entities.Entities;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Arrays;
import static io.anuke.mindustry.Vars.android;
public class Save12 extends SaveFileVersion {
public Save12(){
super(12);
}
@Override
public void read(DataInputStream stream) throws IOException {
int version = stream.readInt();
/*long loadTime = */stream.readLong();
if(version != this.version){
throw new RuntimeException("Save file version mismatch!");
}
//general state
byte mode = stream.readByte();
byte mapid = stream.readByte();
int wave = stream.readInt();
float wavetime = stream.readFloat();
float playerx = stream.readFloat();
float playery = stream.readFloat();
int playerhealth = stream.readInt();
Vars.player.x = playerx;
Vars.player.y = playery;
Vars.player.health = playerhealth;
Vars.control.setMode(GameMode.values()[mode]);
Core.camera.position.set(playerx, playery, 0);
//weapons
Vars.control.getWeapons().clear();
Vars.control.getWeapons().add(Weapon.blaster);
Vars.player.weapon = Weapon.blaster;
int weapons = stream.readByte();
for(int i = 0; i < weapons; i ++){
Vars.control.addWeapon(Weapon.values()[stream.readByte()]);
}
Vars.ui.updateWeapons();
//inventory
int totalItems = stream.readByte();
Arrays.fill(Vars.control.getItems(), 0);
for(int i = 0; i < totalItems; i ++){
Item item = Item.getByID(stream.readByte());
int amount = stream.readInt();
Vars.control.getItems()[item.id] = amount;
}
Vars.ui.updateItems();
//enemies
Entities.clear();
int enemies = stream.readInt();
Array<Enemy> enemiesToUpdate = new Array<>();
for(int i = 0; i < enemies; i ++){
byte type = stream.readByte();
int lane = stream.readByte();
float x = stream.readFloat();
float y = stream.readFloat();
byte tier = stream.readByte();
int health = stream.readInt();
try{
Enemy enemy = ClassReflection.newInstance(enemyIDs.get(type));
enemy.lane = lane;
enemy.health = health;
enemy.x = x;
enemy.y = y;
enemy.tier = tier;
enemy.add(Vars.control.enemyGroup);
enemiesToUpdate.add(enemy);
}catch (Exception e){
throw new RuntimeException(e);
}
}
Vars.control.setWaveData(enemies, wave, wavetime);
if(!android)
Vars.player.add();
//map
int seed = stream.readInt();
int tiles = stream.readInt();
Vars.world.loadMap(Vars.world.maps().getMap(mapid), seed);
Vars.renderer.clearTiles();
for(Enemy enemy : enemiesToUpdate){
enemy.node = -2;
}
for(int x = 0; x < Vars.world.width(); x ++){
for(int y = 0; y < Vars.world.height(); y ++){
Tile tile = Vars.world.tile(x, y);
//remove breakables like rocks
if(tile.breakable()){
Vars.world.tile(x, y).setBlock(Blocks.air);
}
}
}
for(int i = 0; i < tiles; i ++){
int pos = stream.readInt();
byte link = stream.readByte();
boolean hasEntity = stream.readBoolean();
int blockid = stream.readInt();
Tile tile = Vars.world.tile(pos % Vars.world.width(), pos / Vars.world.width());
tile.setBlock(Block.getByID(blockid));
tile.link = link;
if(hasEntity){
byte rotation = stream.readByte();
int health = stream.readInt();
int items = stream.readByte();
tile.entity.health = health;
tile.setRotation(rotation);
for(int j = 0; j < items; j ++){
int itemid = stream.readByte();
int itemamount = stream.readInt();
tile.entity.items[itemid] = itemamount;
}
tile.entity.read(stream);
}
}
}
@Override
public void write(DataOutputStream stream) throws IOException {
//--META--
stream.writeInt(version); //version id
stream.writeLong(TimeUtils.millis()); //last saved
//--GENERAL STATE--
stream.writeByte(Vars.control.getMode().ordinal()); //gamemode
stream.writeByte(Vars.world.getMap().id); //map ID
stream.writeInt(Vars.control.getWave()); //wave
stream.writeFloat(Vars.control.getWaveCountdown()); //wave countdown
stream.writeFloat(Vars.player.x); //player x/y
stream.writeFloat(Vars.player.y);
stream.writeInt(Vars.player.health); //player health
stream.writeByte(Vars.control.getWeapons().size - 1); //amount of weapons
//start at 1, because the first weapon is always the starter - ignore that
for(int i = 1; i < Vars.control.getWeapons().size; i ++){
stream.writeByte(Vars.control.getWeapons().get(i).ordinal()); //weapon ordinal
}
//--INVENTORY--
int l = Vars.control.getItems().length;
int itemsize = 0;
for(int i = 0; i < l; i ++){
if(Vars.control.getItems()[i] > 0){
itemsize ++;
}
}
stream.writeByte(itemsize); //amount of items
for(int i = 0; i < l; i ++){
if(Vars.control.getItems()[i] > 0){
stream.writeByte(i); //item ID
stream.writeInt(Vars.control.getItems()[i]); //item amount
}
}
//--ENEMIES--
int totalEnemies = 0;
Array<Enemy> enemies = Vars.control.enemyGroup.all();
for(int i = 0; i < enemies.size; i ++){
Enemy enemy = enemies.get(i);
if(idEnemies.containsKey(enemy.getClass())){
totalEnemies ++;
}
}
stream.writeInt(totalEnemies); //enemy amount
for(int i = 0; i < enemies.size; i ++){
Enemy enemy = enemies.get(i);
if(idEnemies.containsKey(enemy.getClass())){
stream.writeByte(idEnemies.get(enemy.getClass())); //type
stream.writeByte(enemy.lane); //lane
stream.writeFloat(enemy.x); //x
stream.writeFloat(enemy.y); //y
stream.writeByte(enemy.tier); //tier
stream.writeInt(enemy.health); //health
}
}
//--MAP DATA--
//seed
stream.writeInt(Vars.world.getSeed());
int totalblocks = 0;
for(int x = 0; x < Vars.world.width(); x ++){
for(int y = 0; y < Vars.world.height(); y ++){
Tile tile = Vars.world.tile(x, y);
if(tile.breakable()){
totalblocks ++;
}
}
}
//tile amount
stream.writeInt(totalblocks);
for(int x = 0; x < Vars.world.width(); x ++){
for(int y = 0; y < Vars.world.height(); y ++){
Tile tile = Vars.world.tile(x, y);
if(tile.breakable()){
stream.writeInt(x + y*Vars.world.width()); //tile pos
stream.writeByte(tile.link);
stream.writeBoolean(tile.entity != null); //whether it has a tile entity
stream.writeInt(tile.block().id); //block ID
if(tile.entity != null){
stream.writeByte(tile.getRotation()); //placerot
stream.writeInt(tile.entity.health); //health
int amount = 0;
for(int i = 0; i < tile.entity.items.length; i ++){
if(tile.entity.items[i] > 0) amount ++;
}
stream.writeByte(amount); //amount of items
for(int i = 0; i < tile.entity.items.length; i ++){
if(tile.entity.items[i] > 0){
stream.writeByte(i); //item ID
stream.writeInt(tile.entity.items[i]); //item amount
}
}
tile.entity.write(stream);
}
}
}
}
}
}

View file

@ -0,0 +1,333 @@
package io.anuke.mindustry.io.versions;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.TimeUtils;
import com.badlogic.gdx.utils.reflect.ClassReflection;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.entities.enemies.Enemy;
import io.anuke.mindustry.io.SaveFileVersion;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.Weapon;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.GameMode;
import io.anuke.mindustry.world.Generator;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.Blocks;
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.entities.Entities;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Arrays;
import static io.anuke.mindustry.Vars.android;
public class Save13 extends SaveFileVersion {
public Save13(){
super(13);
}
@Override
public void read(DataInputStream stream) throws IOException {
int version = stream.readInt();
/*long loadTime = */stream.readLong();
if(version != this.version){
throw new RuntimeException("Save file version mismatch!");
}
//general state
byte mode = stream.readByte();
byte mapid = stream.readByte();
int wave = stream.readInt();
float wavetime = stream.readFloat();
float playerx = stream.readFloat();
float playery = stream.readFloat();
int playerhealth = stream.readInt();
Vars.player.x = playerx;
Vars.player.y = playery;
Vars.player.health = playerhealth;
Vars.control.setMode(GameMode.values()[mode]);
Core.camera.position.set(playerx, playery, 0);
//weapons
Vars.control.getWeapons().clear();
Vars.control.getWeapons().add(Weapon.blaster);
Vars.player.weapon = Weapon.blaster;
int weapons = stream.readByte();
for(int i = 0; i < weapons; i ++){
Vars.control.addWeapon(Weapon.values()[stream.readByte()]);
}
Vars.ui.updateWeapons();
//inventory
int totalItems = stream.readByte();
Arrays.fill(Vars.control.getItems(), 0);
for(int i = 0; i < totalItems; i ++){
Item item = Item.getByID(stream.readByte());
int amount = stream.readInt();
Vars.control.getItems()[item.id] = amount;
}
Vars.ui.updateItems();
//enemies
Entities.clear();
int enemies = stream.readInt();
Array<Enemy> enemiesToUpdate = new Array<>();
for(int i = 0; i < enemies; i ++){
byte type = stream.readByte();
int lane = stream.readByte();
float x = stream.readFloat();
float y = stream.readFloat();
byte tier = stream.readByte();
int health = stream.readShort();
try{
Enemy enemy = ClassReflection.newInstance(enemyIDs.get(type));
enemy.lane = lane;
enemy.health = health;
enemy.x = x;
enemy.y = y;
enemy.tier = tier;
enemy.add(Vars.control.enemyGroup);
enemiesToUpdate.add(enemy);
}catch (Exception e){
throw new RuntimeException(e);
}
}
Vars.control.setWaveData(enemies, wave, wavetime);
if(!android)
Vars.player.add();
//map
int seed = stream.readInt();
Vars.world.loadMap(Vars.world.maps().getMap(mapid), seed);
Vars.renderer.clearTiles();
for(Enemy enemy : enemiesToUpdate){
enemy.node = -2;
}
int rocks = stream.readInt();
for(int x = 0; x < Vars.world.width(); x ++){
for(int y = 0; y < Vars.world.height(); y ++){
Tile tile = Vars.world.tile(x, y);
//remove breakables like rocks
if(tile.breakable()){
Vars.world.tile(x, y).setBlock(Blocks.air);
}
}
}
for(int i = 0; i < rocks; i ++){
int pos = stream.readInt();
Tile tile = Vars.world.tile(pos % Vars.world.width(), pos / Vars.world.width());
Block result = Generator.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 = Vars.world.tile(pos % Vars.world.width(), pos / Vars.world.width());
tile.setBlock(Block.getByID(blockid));
if(blockid == Blocks.blockpart.id){
tile.link = stream.readByte();
}
if(tile.entity != null){
byte rotation = stream.readByte();
short health = stream.readShort();
int items = stream.readByte();
tile.entity.health = health;
tile.setRotation(rotation);
for(int j = 0; j < items; j ++){
int itemid = stream.readByte();
int itemamount = stream.readInt();
tile.entity.items[itemid] = itemamount;
}
tile.entity.read(stream);
}
}
}
@Override
public void write(DataOutputStream stream) throws IOException {
//--META--
stream.writeInt(version); //version id
stream.writeLong(TimeUtils.millis()); //last saved
//--GENERAL STATE--
stream.writeByte(Vars.control.getMode().ordinal()); //gamemode
stream.writeByte(Vars.world.getMap().id); //map ID
stream.writeInt(Vars.control.getWave()); //wave
stream.writeFloat(Vars.control.getWaveCountdown()); //wave countdown
stream.writeFloat(Vars.player.x); //player x/y
stream.writeFloat(Vars.player.y);
stream.writeInt(Vars.player.health); //player health
stream.writeByte(Vars.control.getWeapons().size - 1); //amount of weapons
//start at 1, because the first weapon is always the starter - ignore that
for(int i = 1; i < Vars.control.getWeapons().size; i ++){
stream.writeByte(Vars.control.getWeapons().get(i).ordinal()); //weapon ordinal
}
//--INVENTORY--
int l = Vars.control.getItems().length;
int itemsize = 0;
for(int i = 0; i < l; i ++){
if(Vars.control.getItems()[i] > 0){
itemsize ++;
}
}
stream.writeByte(itemsize); //amount of items
for(int i = 0; i < l; i ++){
if(Vars.control.getItems()[i] > 0){
stream.writeByte(i); //item ID
stream.writeInt(Vars.control.getItems()[i]); //item amount
}
}
//--ENEMIES--
int totalEnemies = 0;
Array<Enemy> enemies = Vars.control.enemyGroup.all();
for(int i = 0; i < enemies.size; i ++){
Enemy enemy = enemies.get(i);
if(idEnemies.containsKey(enemy.getClass())){
totalEnemies ++;
}
}
stream.writeInt(totalEnemies); //enemy amount
for(int i = 0; i < enemies.size; i ++){
Enemy enemy = enemies.get(i);
if(idEnemies.containsKey(enemy.getClass())){
stream.writeByte(idEnemies.get(enemy.getClass())); //type
stream.writeByte(enemy.lane); //lane
stream.writeFloat(enemy.x); //x
stream.writeFloat(enemy.y); //y
stream.writeByte(enemy.tier); //tier
stream.writeShort(enemy.health); //health
}
}
//--MAP DATA--
//seed
stream.writeInt(Vars.world.getSeed());
int totalblocks = 0;
int totalrocks = 0;
for(int x = 0; x < Vars.world.width(); x ++){
for(int y = 0; y < Vars.world.height(); y ++){
Tile tile = Vars.world.tile(x, y);
if(tile.breakable()){
if(tile.block() instanceof Rock){
totalrocks ++;
}else{
totalblocks ++;
}
}
}
}
//amount of rocks
stream.writeInt(totalrocks);
//write all rocks
for(int x = 0; x < Vars.world.width(); x ++) {
for (int y = 0; y < Vars.world.height(); y++) {
Tile tile = Vars.world.tile(x, y);
if (tile.block() instanceof Rock) {
stream.writeInt(tile.packedPosition());
}
}
}
//write all blocks
stream.writeInt(totalblocks);
for(int x = 0; x < Vars.world.width(); x ++){
for(int y = 0; y < Vars.world.height(); y ++){
Tile tile = Vars.world.tile(x, y);
if(tile.breakable() && !(tile.block() instanceof Rock)){
stream.writeInt(x + y*Vars.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.getRotation()); //placerot
stream.writeShort(tile.entity.health); //health
byte amount = 0;
for(int i = 0; i < tile.entity.items.length; i ++){
if(tile.entity.items[i] > 0) amount ++;
}
stream.writeByte(amount); //amount of items
for(int i = 0; i < tile.entity.items.length; i ++){
if(tile.entity.items[i] > 0){
stream.writeByte(i); //item ID
stream.writeInt(tile.entity.items[i]); //item amount
}
}
tile.entity.write(stream);
}
}
}
}
}
}

View file

@ -7,18 +7,18 @@ import io.anuke.mindustry.world.blocks.*;
import static io.anuke.mindustry.resource.Section.*;
public enum Recipe{
stonewall(defense, DefenseBlocks.stonewall, stack(Item.stone, 2)),
ironwall(defense, DefenseBlocks.ironwall, stack(Item.iron, 2)),
steelwall(defense, DefenseBlocks.steelwall, stack(Item.steel, 2)),
titaniumwall(defense, DefenseBlocks.titaniumwall, stack(Item.titanium, 2)),
duriumwall(defense, DefenseBlocks.diriumwall, stack(Item.dirium, 2)),
stonewall(defense, DefenseBlocks.stonewall, stack(Item.stone, 12)),
ironwall(defense, DefenseBlocks.ironwall, stack(Item.iron, 12)),
steelwall(defense, DefenseBlocks.steelwall, stack(Item.steel, 11)),
titaniumwall(defense, DefenseBlocks.titaniumwall, stack(Item.titanium, 12)),
duriumwall(defense, DefenseBlocks.diriumwall, stack(Item.dirium, 12)),
//compositewall(defense, DefenseBlocks.compositewall, stack(Item.dirium, 2), stack(Item.titanium, 2), stack(Item.steel, 2), stack(Item.iron, 2)),
steelwalllarge(defense, DefenseBlocks.steelwalllarge, stack(Item.steel, 8)),
titaniumwalllarge(defense, DefenseBlocks.titaniumwalllarge, stack(Item.titanium, 8)),
duriumwalllarge(defense, DefenseBlocks.diriumwalllarge, stack(Item.dirium, 8)),
door(defense, DefenseBlocks.door, stack(Item.steel, 3), stack(Item.iron, 3)),
largedoor(defense, DefenseBlocks.largedoor, stack(Item.steel, 3*4), stack(Item.iron, 3*4)),
titaniumshieldwall(defense, DefenseBlocks.titaniumshieldwall, stack(Item.titanium, 3)),
steelwalllarge(defense, DefenseBlocks.steelwalllarge, stack(Item.steel, 12*4)),
titaniumwalllarge(defense, DefenseBlocks.titaniumwalllarge, stack(Item.titanium, 12*4)),
duriumwalllarge(defense, DefenseBlocks.diriumwalllarge, stack(Item.dirium, 12*4)),
door(defense, DefenseBlocks.door, stack(Item.steel, 3), stack(Item.iron, 3*4)),
largedoor(defense, DefenseBlocks.largedoor, stack(Item.steel, 3*4), stack(Item.iron, 3*4*4)),
titaniumshieldwall(defense, DefenseBlocks.titaniumshieldwall, stack(Item.titanium, 16)),
conveyor(distribution, DistributionBlocks.conveyor, stack(Item.stone, 1)),
steelconveyor(distribution, DistributionBlocks.steelconveyor, stack(Item.steel, 1)),

View file

@ -73,13 +73,11 @@ public class MenuFragment implements Fragment{
new imagebutton("icon-tools", isize, () -> ui.showPrefs()).text("$text.settings").padTop(4f);
new imagebutton("icon-add", isize, () -> ui.showJoinGame()).text("$text.joingame").padTop(4f);
if(Mindustry.donationsCallable != null){
new imagebutton("icon-donate", isize, () -> {
Mindustry.donationsCallable.run();
}).text("$text.donate").padTop(4f);
}
new imagebutton("icon-donate", isize, () -> {
Mindustry.platforms.openDonations();
}).text("$text.donate").padTop(4f);
visible(()->GameState.is(State.menu));
}}.end();
}}.end();

View file

@ -81,16 +81,15 @@ public class Block{
public Layer layer2 = null;
public Block(String name) {
blocks.add(this);
this.name = name;
this.formalName = Bundles.get("block." + name + ".name", name);
this.description = Bundles.getOrNull("block." + name + ".description");
this.fullDescription = Bundles.getOrNull("block." + name + ".fulldescription");
this.solid = false;
this.id = lastid++;
blocks.add(this);
}
public boolean isLayer(Tile tile){return true;}
public boolean isLayer2(Tile tile){return true;}

View file

@ -0,0 +1,19 @@
package io.anuke.mindustry.world;
import io.anuke.mindustry.world.blocks.*;
public class BlockLoader {
public static void load(){
Block[] blockClasses = {
Blocks.air,
DefenseBlocks.compositewall,
DistributionBlocks.conduit,
ProductionBlocks.coaldrill,
WeaponBlocks.chainturret,
SpecialBlocks.enemySpawn
//add any new block sections here
};
}
}

View file

@ -22,7 +22,9 @@ public class Blocks{
public void draw(Tile tile){}
},
blockpart = new BlockPart(),
blockpart = new BlockPart(){
},
deepwater = new Floor("deepwater"){{
variants = 0;
@ -99,15 +101,15 @@ public class Blocks{
drops = new ItemStack(Item.uranium, 1);
}},
dirt = new Floor("dirt"),
dirt = new Floor("dirt"){},
sand = new Floor("sand"),
sand = new Floor("sand"){},
ice = new Floor("ice"),
ice = new Floor("ice"){},
snow = new Floor("snow"),
snow = new Floor("snow"){},
grass = new Floor("grass"),
grass = new Floor("grass"){},
sandblock = new StaticBlock("sandblock"){{
solid = true;

View file

@ -6,44 +6,45 @@ import io.anuke.mindustry.world.blocks.types.Wall;
import io.anuke.mindustry.world.blocks.types.defense.*;
public class DefenseBlocks{
static final int wallHealthMultiplier = 4;
public static final Block
stonewall = new Wall("stonewall"){{
health = 50;
health = 50*wallHealthMultiplier;
}},
ironwall = new Wall("ironwall"){{
health = 80;
health = 80*wallHealthMultiplier;
}},
steelwall = new Wall("steelwall"){{
health = 110;
health = 110*wallHealthMultiplier;
}},
titaniumwall = new Wall("titaniumwall"){{
health = 150;
health = 150*wallHealthMultiplier;
}},
diriumwall = new Wall("duriumwall"){{
health = 190;
health = 190*wallHealthMultiplier;
}},
compositewall = new Wall("compositewall"){{
health = 270;
health = 270*wallHealthMultiplier;
}},
steelwalllarge = new Wall("steelwall-large"){{
health = 110*4;
health = 110*4*wallHealthMultiplier;
width = height = 2;
}},
titaniumwalllarge = new Wall("titaniumwall-large"){{
health = 150*4;
health = 150*4*wallHealthMultiplier;
width = height = 2;
}},
diriumwalllarge = new Wall("duriumwall-large"){{
health = 190*4;
health = 190*4*wallHealthMultiplier;
width = height = 2;
}},
titaniumshieldwall = new ShieldedWallBlock("titaniumshieldwall"){{
health = 150;
health = 150*wallHealthMultiplier;
}},
repairturret = new RepairTurret("repairturret"){
@ -65,16 +66,16 @@ public class DefenseBlocks{
shieldgenerator = new ShieldBlock("shieldgenerator"){
{
health = 100*wallHealthMultiplier;
}
},
door = new Door("door"){{
health = 90;
health = 90*wallHealthMultiplier;
}},
largedoor = new Door("door-large"){{
openfx = Fx.dooropenlarge;
closefx = Fx.doorcloselarge;
health = 90*4;
health = 90*4*wallHealthMultiplier;
width = height = 2;
}};
}

View file

@ -1,6 +1,5 @@
package io.anuke.mindustry.world.blocks;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.graphics.Fx;
import io.anuke.mindustry.resource.Item;
@ -14,14 +13,15 @@ import io.anuke.ucore.core.Effects;
public class ProductionBlocks{
public static final Block
core = new CoreBlock("core"),
core = new CoreBlock("core"){},
pump = new Pump("pump"){{
}},
pump = new Pump("pump"){},
fluxpump = new Pump("fluxpump"){{
pumpAmount = 3f;
}},
fluxpump = new Pump("fluxpump"){
{
pumpAmount = 3f;
}
},
smelter = new Crafter("smelter"){
{
@ -63,19 +63,6 @@ public class ProductionBlocks{
health = 70;
}
},
//TODO
/*siliconextractor = new LiquidCrafter("siliconextractor"){
{
input = Item.sand;
inputAmount = 5;
inputLiquid = Liquid.water;
liquidAmount = 18.99f;
output = Item.silicon;
health = 50;
purifyTime = 50;
}
},*/
oilrefinery = new LiquidCrafter("oilrefinery"){
{
@ -116,32 +103,42 @@ public class ProductionBlocks{
}
},
stonedrill = new Drill("stonedrill"){{
resource = Blocks.stone;
result = Item.stone;
time = 4;
}},
stonedrill = new Drill("stonedrill"){
{
resource = Blocks.stone;
result = Item.stone;
time = 4;
}
},
irondrill = new Drill("irondrill"){{
resource = Blocks.iron;
result = Item.iron;
}},
irondrill = new Drill("irondrill"){
{
resource = Blocks.iron;
result = Item.iron;
}
},
coaldrill = new Drill("coaldrill"){{
resource = Blocks.coal;
result = Item.coal;
}},
coaldrill = new Drill("coaldrill"){
{
resource = Blocks.coal;
result = Item.coal;
}
},
uraniumdrill = new Drill("uraniumdrill"){{
resource = Blocks.uranium;
result = Item.uranium;
time = 7;
}},
uraniumdrill = new Drill("uraniumdrill"){
{
resource = Blocks.uranium;
result = Item.uranium;
time = 7;
}
},
titaniumdrill = new Drill("titaniumdrill"){{
resource = Blocks.titanium;
result = Item.titanium;
}},
titaniumdrill = new Drill("titaniumdrill"){
{
resource = Blocks.titanium;
result = Item.titanium;
}
},
omnidrill = new Drill("omnidrill"){
{
@ -210,4 +207,16 @@ public class ProductionBlocks{
breaktime *= 2.3f;
}
};
/*
siliconextractor = new LiquidCrafter("siliconextractor"){
{
input = Item.sand;
inputAmount = 5;
inputLiquid = Liquid.water;
liquidAmount = 18.99f;
output = Item.sand;
health = 50;
purifyTime = 50;
}
}*/;
}

View file

@ -4,6 +4,6 @@ import io.anuke.mindustry.world.Block;
public class SpecialBlocks{
public static final Block
playerSpawn = new Block("playerspawn"),
enemySpawn = new Block("enemyspawn");
playerSpawn = new Block("playerspawn"){},
enemySpawn = new Block("enemyspawn"){};
}

View file

@ -17,15 +17,14 @@ import io.anuke.ucore.util.Strings;
public class ShieldBlock extends PowerBlock{
public float shieldRadius = 40f;
public float powerDrain = 0.005f;
public float powerPerDamage = 0.13f;
public float powerPerDamage = 0.1f;
public float maxRadius = 40f;
public float radiusScale = 200f;
public float radiusScale = 240f;
public ShieldBlock(String name) {
super(name);
voltage = powerDrain;
powerCapacity = 40f;
health = 100;
}
@Override

View file

@ -1,19 +1,19 @@
package io.anuke.mindustry.world.blocks.types.defense;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.PowerBlock;
import io.anuke.ucore.core.Draw;
import io.anuke.ucore.core.Graphics;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.util.Strings;
public class ShieldedWallBlock extends PowerBlock{
static final float hitTime = 18f;
static final Color hitColor = Color.SKY.cpy().mul(1.2f);
public float powerToDamage = 0.1f;
public float powerPerDamage = 0.08f;
public ShieldedWallBlock(String name) {
super(name);
@ -24,7 +24,7 @@ public class ShieldedWallBlock extends PowerBlock{
@Override
public int handleDamage(Tile tile, int amount){
float drain = amount * powerToDamage;
float drain = amount * powerPerDamage;
ShieldedWallEntity entity = tile.entity();
if(entity.power > drain){
@ -32,7 +32,7 @@ public class ShieldedWallBlock extends PowerBlock{
entity.hit = hitTime;
return 0;
}else if(entity.power > 0){
int reduction = (int)(entity.power / powerToDamage);
int reduction = (int)(entity.power / powerPerDamage);
entity.power = 0;
return amount - reduction;
@ -40,6 +40,12 @@ public class ShieldedWallBlock extends PowerBlock{
return amount;
}
@Override
public void getStats(Array<String> list){
super.getStats(list);
list.add("[powerinfo]Power Drain/damage: " + Strings.toFixed(powerPerDamage, 2));
}
@Override
public void draw(Tile tile){
@ -47,7 +53,7 @@ public class ShieldedWallBlock extends PowerBlock{
ShieldedWallEntity entity = tile.entity();
if(entity.power > powerToDamage){
if(entity.power > powerPerDamage){
Vars.renderer.addShield(() -> Draw.rect("blank", tile.worldx(), tile.worldy(), Vars.tilesize, Vars.tilesize));
}

View file

@ -61,31 +61,32 @@ public class DesktopLauncher {
}
@Override
public void addDialog(TextField field){
}
public void addDialog(TextField field){}
@Override
public void openDonations(){}
@Override
public void onSceneChange(String state, String details, String icon) {
DiscordRPC lib = DiscordRPC.INSTANCE;
DiscordRPC lib = DiscordRPC.INSTANCE;
String applicationId = "397335883319083018";
String applicationId = "397335883319083018";
DiscordEventHandlers handlers = new DiscordEventHandlers();
DiscordEventHandlers handlers = new DiscordEventHandlers();
lib.Discord_Initialize(applicationId, handlers, true, "");
lib.Discord_Initialize(applicationId, handlers, true, "");
DiscordRichPresence presence = new DiscordRichPresence();
presence.startTimestamp = System.currentTimeMillis() / 1000; // epoch second
presence.state = state;
//presence.details = details;
presence.largeImageKey = "logo";
presence.largeImageText = details;
lib.Discord_UpdatePresence(presence);
}
DiscordRichPresence presence = new DiscordRichPresence();
presence.startTimestamp = System.currentTimeMillis() / 1000; // epoch second
presence.state = state;
//presence.details = details;
presence.largeImageKey = "logo";
presence.largeImageText = details;
lib.Discord_UpdatePresence(presence);
}
@Override
public void onGameExit() {
@Override
public void onGameExit() {
DiscordRPC.INSTANCE.Discord_Shutdown();
}
};

View file

@ -1,24 +1,26 @@
package io.anuke.mindustry.client;
import java.util.Date;
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.backends.gwt.GwtApplication;
import com.badlogic.gdx.backends.gwt.GwtApplicationConfiguration;
import com.badlogic.gdx.backends.gwt.preloader.Preloader.PreloaderCallback;
import com.badlogic.gdx.backends.gwt.preloader.Preloader.PreloaderState;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.*;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NodeList;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.i18n.shared.DateTimeFormat;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.*;
import io.anuke.mindustry.Mindustry;
import io.anuke.mindustry.io.PlatformFunction;
import io.anuke.ucore.scene.ui.TextField;
import java.util.Date;
public class HtmlLauncher extends GwtApplication {
static final int WIDTH = 800;
static final int HEIGHT = 600;
@ -109,19 +111,16 @@ public class HtmlLauncher extends GwtApplication {
}
@Override
public void addDialog(TextField field){
}
public void addDialog(TextField field){}
@Override
public void onSceneChange(String state, String details, String icon) {
}
public void onSceneChange(String state, String details, String icon) {}
@Override
public void onGameExit() {
public void onGameExit() {}
}
@Override
public void openDonations() {}
};
return new Mindustry();