Many bugfixes for multiplayer, QoL, balancing, new difficulties
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="io.anuke.mindustry"
|
package="io.anuke.mindustry"
|
||||||
android:versionCode="50"
|
android:versionCode="51"
|
||||||
android:versionName="3.3b2" >
|
android:versionName="3.3b3" >
|
||||||
|
|
||||||
<uses-permission android:name="com.android.vending.BILLING" />
|
<uses-permission android:name="com.android.vending.BILLING" />
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
|
|||||||
@@ -189,6 +189,8 @@ text.health=health
|
|||||||
setting.difficulty.easy=easy
|
setting.difficulty.easy=easy
|
||||||
setting.difficulty.normal=normal
|
setting.difficulty.normal=normal
|
||||||
setting.difficulty.hard=hard
|
setting.difficulty.hard=hard
|
||||||
|
setting.difficulty.insane=insane
|
||||||
|
setting.difficulty.purge=purge
|
||||||
setting.difficulty.name=Difficulty
|
setting.difficulty.name=Difficulty
|
||||||
setting.screenshake.name=Screen Shake
|
setting.screenshake.name=Screen Shake
|
||||||
setting.smoothcam.name=Smooth Camera
|
setting.smoothcam.name=Smooth Camera
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import com.badlogic.gdx.math.Vector2;
|
|||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||||
import io.anuke.mindustry.entities.enemies.EnemyType;
|
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||||
import io.anuke.mindustry.world.SpawnPoint;
|
import io.anuke.mindustry.game.SpawnPoint;
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
import io.anuke.ucore.UCore;
|
import io.anuke.ucore.UCore;
|
||||||
import io.anuke.ucore.core.Timers;
|
import io.anuke.ucore.core.Timers;
|
||||||
|
|||||||
@@ -12,6 +12,10 @@ import io.anuke.mindustry.entities.*;
|
|||||||
import io.anuke.mindustry.entities.effect.Shield;
|
import io.anuke.mindustry.entities.effect.Shield;
|
||||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||||
import io.anuke.mindustry.entities.enemies.EnemyTypes;
|
import io.anuke.mindustry.entities.enemies.EnemyTypes;
|
||||||
|
import io.anuke.mindustry.game.Difficulty;
|
||||||
|
import io.anuke.mindustry.game.EnemySpawn;
|
||||||
|
import io.anuke.mindustry.game.SpawnPoint;
|
||||||
|
import io.anuke.mindustry.game.WaveCreator;
|
||||||
import io.anuke.mindustry.graphics.Fx;
|
import io.anuke.mindustry.graphics.Fx;
|
||||||
import io.anuke.mindustry.input.AndroidInput;
|
import io.anuke.mindustry.input.AndroidInput;
|
||||||
import io.anuke.mindustry.input.DesktopInput;
|
import io.anuke.mindustry.input.DesktopInput;
|
||||||
@@ -53,16 +57,16 @@ public class Control extends Module{
|
|||||||
public final EntityGroup<Bullet> bulletGroup = Entities.addGroup(Bullet.class);
|
public final EntityGroup<Bullet> bulletGroup = Entities.addGroup(Bullet.class);
|
||||||
public final EntityGroup<Shield> shieldGroup = Entities.addGroup(Shield.class);
|
public final EntityGroup<Shield> shieldGroup = Entities.addGroup(Shield.class);
|
||||||
|
|
||||||
Array<EnemySpawn> spawns;
|
Array<io.anuke.mindustry.game.EnemySpawn> spawns;
|
||||||
int wave = 1;
|
int wave = 1;
|
||||||
int lastUpdated = -1;
|
int lastUpdated = -1;
|
||||||
float wavetime;
|
float wavetime;
|
||||||
float extrawavetime;
|
float extrawavetime;
|
||||||
int enemies = 0;
|
int enemies = 0;
|
||||||
GameMode mode = GameMode.waves;
|
io.anuke.mindustry.game.GameMode mode = io.anuke.mindustry.game.GameMode.waves;
|
||||||
|
|
||||||
Tile core;
|
Tile core;
|
||||||
Array<SpawnPoint> spawnpoints = new Array<>();
|
Array<io.anuke.mindustry.game.SpawnPoint> spawnpoints = new Array<>();
|
||||||
boolean shouldUpdateItems = false;
|
boolean shouldUpdateItems = false;
|
||||||
boolean wasPaused = false;
|
boolean wasPaused = false;
|
||||||
|
|
||||||
@@ -275,7 +279,7 @@ public class Control extends Module{
|
|||||||
return core;
|
return core;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Array<SpawnPoint> getSpawnPoints(){
|
public Array<io.anuke.mindustry.game.SpawnPoint> getSpawnPoints(){
|
||||||
return spawnpoints;
|
return spawnpoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,7 +292,7 @@ public class Control extends Module{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void addSpawnPoint(Tile tile){
|
public void addSpawnPoint(Tile tile){
|
||||||
SpawnPoint point = new SpawnPoint();
|
io.anuke.mindustry.game.SpawnPoint point = new SpawnPoint();
|
||||||
point.start = tile;
|
point.start = tile;
|
||||||
spawnpoints.add(point);
|
spawnpoints.add(point);
|
||||||
}
|
}
|
||||||
@@ -306,11 +310,11 @@ public class Control extends Module{
|
|||||||
Timers.run(18, ()-> ui.loadfrag.hide());
|
Timers.run(18, ()-> ui.loadfrag.hide());
|
||||||
}
|
}
|
||||||
|
|
||||||
public GameMode getMode(){
|
public io.anuke.mindustry.game.GameMode getMode(){
|
||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMode(GameMode mode){
|
public void setMode(io.anuke.mindustry.game.GameMode mode){
|
||||||
this.mode = mode;
|
this.mode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -411,9 +415,11 @@ public class Control extends Module{
|
|||||||
}
|
}
|
||||||
|
|
||||||
float waveSpacing(){
|
float waveSpacing(){
|
||||||
int scale = Settings.getInt("difficulty");
|
return wavespace*getDifficulty().timeScaling;
|
||||||
float out = (scale == 0 ? 2f : scale == 1f ? 1f : 0.5f);
|
}
|
||||||
return wavespace*out;
|
|
||||||
|
public Difficulty getDifficulty(){
|
||||||
|
return Difficulty.values()[Settings.getInt("difficulty")];
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isHighScore(){
|
public boolean isHighScore(){
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package io.anuke.mindustry.core;
|
|||||||
|
|
||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
import com.badlogic.gdx.graphics.Color;
|
import com.badlogic.gdx.graphics.Color;
|
||||||
|
import com.badlogic.gdx.utils.IntSet;
|
||||||
import com.badlogic.gdx.utils.TimeUtils;
|
import com.badlogic.gdx.utils.TimeUtils;
|
||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.core.GameState.State;
|
import io.anuke.mindustry.core.GameState.State;
|
||||||
@@ -39,12 +40,14 @@ public class NetClient extends Module {
|
|||||||
boolean connecting = false;
|
boolean connecting = false;
|
||||||
boolean gotEntities = false, gotData = false;
|
boolean gotEntities = false, gotData = false;
|
||||||
boolean kicked = false;
|
boolean kicked = false;
|
||||||
|
IntSet requests = new IntSet();
|
||||||
float playerSyncTime = 2;
|
float playerSyncTime = 2;
|
||||||
float dataTimeout = 60*10;
|
float dataTimeout = 60*10;
|
||||||
|
|
||||||
public NetClient(){
|
public NetClient(){
|
||||||
|
|
||||||
Net.handle(Connect.class, packet -> {
|
Net.handle(Connect.class, packet -> {
|
||||||
|
requests.clear();
|
||||||
connecting = true;
|
connecting = true;
|
||||||
gotEntities = false;
|
gotEntities = false;
|
||||||
gotData = false;
|
gotData = false;
|
||||||
@@ -110,6 +113,10 @@ public class NetClient extends Module {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < data.enemies.length; i ++){
|
||||||
|
Net.handleClientReceived(data.enemies[i]);
|
||||||
|
}
|
||||||
|
|
||||||
for(int i = 0; i < data.weapons.length; i ++){
|
for(int i = 0; i < data.weapons.length; i ++){
|
||||||
Vars.control.addWeapon((Weapon) Upgrade.getByID(data.weapons[i]));
|
Vars.control.addWeapon((Weapon) Upgrade.getByID(data.weapons[i]));
|
||||||
}
|
}
|
||||||
@@ -129,7 +136,7 @@ public class NetClient extends Module {
|
|||||||
for(int i = 0; i < packet.ids.length; i ++){
|
for(int i = 0; i < packet.ids.length; i ++){
|
||||||
int id = packet.ids[i];
|
int id = packet.ids[i];
|
||||||
if(id != Vars.player.id){
|
if(id != Vars.player.id){
|
||||||
Entity entity = null;
|
Entity entity;
|
||||||
if(i >= packet.enemyStart){
|
if(i >= packet.enemyStart){
|
||||||
entity = Vars.control.enemyGroup.getByID(id);
|
entity = Vars.control.enemyGroup.getByID(id);
|
||||||
}else {
|
}else {
|
||||||
@@ -140,6 +147,13 @@ public class NetClient extends Module {
|
|||||||
|
|
||||||
if(sync == null){
|
if(sync == null){
|
||||||
Gdx.app.error("Mindustry", "Unknown entity ID: " + id + " " + (i >= packet.enemyStart ? "(enemy)" : "(player)"));
|
Gdx.app.error("Mindustry", "Unknown entity ID: " + id + " " + (i >= packet.enemyStart ? "(enemy)" : "(player)"));
|
||||||
|
if(!requests.contains(id)){
|
||||||
|
Gdx.app.error("Mindustry", "Sending entity request: " + id);
|
||||||
|
requests.add(id);
|
||||||
|
EntityRequestPacket req = new EntityRequestPacket();
|
||||||
|
req.id = id;
|
||||||
|
Net.send(req, SendMode.tcp);
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,6 +189,7 @@ public class NetClient extends Module {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Net.handle(EnemySpawnPacket.class, spawn -> {
|
Net.handle(EnemySpawnPacket.class, spawn -> {
|
||||||
|
requests.remove(spawn.id);
|
||||||
Gdx.app.postRunnable(() -> {
|
Gdx.app.postRunnable(() -> {
|
||||||
Enemy enemy = new Enemy(EnemyType.getByID(spawn.type));
|
Enemy enemy = new Enemy(EnemyType.getByID(spawn.type));
|
||||||
enemy.set(spawn.x, spawn.y);
|
enemy.set(spawn.x, spawn.y);
|
||||||
@@ -259,7 +274,12 @@ public class NetClient extends Module {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Net.handle(Player.class, Player::add);
|
Net.handle(Player.class, player -> {
|
||||||
|
requests.remove(player.id);
|
||||||
|
player.getInterpolator().last.set(player.x, player.y);
|
||||||
|
player.getInterpolator().target.set(player.x, player.y);
|
||||||
|
player.add();
|
||||||
|
});
|
||||||
|
|
||||||
Net.handle(ChatPacket.class, packet -> Gdx.app.postRunnable(() -> Vars.ui.chatfrag.addMessage(packet.text, Vars.netClient.colorizeName(packet.id, packet.name))));
|
Net.handle(ChatPacket.class, packet -> Gdx.app.postRunnable(() -> Vars.ui.chatfrag.addMessage(packet.text, Vars.netClient.colorizeName(packet.id, packet.name))));
|
||||||
|
|
||||||
@@ -303,6 +323,11 @@ public class NetClient extends Module {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void disconnectQuietly(){
|
||||||
|
kicked = true;
|
||||||
|
Net.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
public String colorizeName(int id, String name){
|
public String colorizeName(int id, String name){
|
||||||
return name == null ? null : "[#" + colorArray[id % colorArray.length].toString().toUpperCase() + "]" + name;
|
return name == null ? null : "[#" + colorArray[id % colorArray.length].toString().toUpperCase() + "]" + name;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,6 +61,8 @@ public class NetServer extends Module{
|
|||||||
player.name = packet.name;
|
player.name = packet.name;
|
||||||
player.isAndroid = packet.android;
|
player.isAndroid = packet.android;
|
||||||
player.set(Vars.control.core.worldx(), Vars.control.core.worldy() - Vars.tilesize*2);
|
player.set(Vars.control.core.worldx(), Vars.control.core.worldy() - Vars.tilesize*2);
|
||||||
|
player.getInterpolator().last.set(player.x, player.y);
|
||||||
|
player.getInterpolator().target.set(player.x, player.y);
|
||||||
player.add();
|
player.add();
|
||||||
connections.put(id, player);
|
connections.put(id, player);
|
||||||
|
|
||||||
@@ -73,6 +75,20 @@ public class NetServer extends Module{
|
|||||||
dp.playerWeapons[i] = dp.players[i].weaponLeft.id;
|
dp.playerWeapons[i] = dp.players[i].weaponLeft.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dp.enemies = new EnemySpawnPacket[Vars.control.enemyGroup.amount()];
|
||||||
|
|
||||||
|
for(int i = 0; i < Vars.control.enemyGroup.amount(); i ++){
|
||||||
|
Enemy enemy = Vars.control.enemyGroup.all().get(i);
|
||||||
|
EnemySpawnPacket e = new EnemySpawnPacket();
|
||||||
|
e.x = enemy.x;
|
||||||
|
e.y = enemy.y;
|
||||||
|
e.id = enemy.id;
|
||||||
|
e.tier = (byte)enemy.tier;
|
||||||
|
e.lane = (byte)enemy.lane;
|
||||||
|
e.type = enemy.type.id;
|
||||||
|
dp.enemies[i] = e;
|
||||||
|
}
|
||||||
|
|
||||||
UCore.log("Sending entities: " + Arrays.toString(dp.players));
|
UCore.log("Sending entities: " + Arrays.toString(dp.players));
|
||||||
|
|
||||||
Net.sendExcept(id, player, SendMode.tcp);
|
Net.sendExcept(id, player, SendMode.tcp);
|
||||||
@@ -102,6 +118,7 @@ public class NetServer extends Module{
|
|||||||
|
|
||||||
Net.handleServer(PositionPacket.class, pos -> {
|
Net.handleServer(PositionPacket.class, pos -> {
|
||||||
Player player = connections.get(Net.getLastConnection());
|
Player player = connections.get(Net.getLastConnection());
|
||||||
|
UCore.log("Recieving data: " + Arrays.toString(pos.data), "Player pos: " +player.x, player.y);
|
||||||
player.getInterpolator().type.read(player, pos.data);
|
player.getInterpolator().type.read(player, pos.data);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -187,6 +204,30 @@ public class NetServer extends Module{
|
|||||||
|
|
||||||
Net.sendExcept(Net.getLastConnection(), packet, SendMode.tcp);
|
Net.sendExcept(Net.getLastConnection(), packet, SendMode.tcp);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Net.handleServer(EntityRequestPacket.class, packet -> {
|
||||||
|
int id = packet.id;
|
||||||
|
int dest = Net.getLastConnection();
|
||||||
|
Gdx.app.postRunnable(() -> {
|
||||||
|
if(Vars.control.playerGroup.getByID(id) != null){
|
||||||
|
Net.sendTo(dest, Vars.control.playerGroup.getByID(id), SendMode.tcp);
|
||||||
|
Gdx.app.error("Mindustry", "Replying to entity request: player, " + id);
|
||||||
|
}else if (Vars.control.enemyGroup.getByID(id) != null){
|
||||||
|
Enemy enemy = Vars.control.enemyGroup.getByID(id);
|
||||||
|
EnemySpawnPacket e = new EnemySpawnPacket();
|
||||||
|
e.x = enemy.x;
|
||||||
|
e.y = enemy.y;
|
||||||
|
e.id = enemy.id;
|
||||||
|
e.tier = (byte)enemy.tier;
|
||||||
|
e.lane = (byte)enemy.lane;
|
||||||
|
e.type = enemy.type.id;
|
||||||
|
Net.sendTo(dest, e, SendMode.tcp);
|
||||||
|
Gdx.app.error("Mindustry", "Replying to entity request: enemy, " + id);
|
||||||
|
}else{
|
||||||
|
Gdx.app.error("Mindustry", "Entity request target not found!");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendMessage(String message){
|
public void sendMessage(String message){
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import io.anuke.mindustry.graphics.Shaders;
|
|||||||
import io.anuke.mindustry.input.InputHandler;
|
import io.anuke.mindustry.input.InputHandler;
|
||||||
import io.anuke.mindustry.input.PlaceMode;
|
import io.anuke.mindustry.input.PlaceMode;
|
||||||
import io.anuke.mindustry.ui.fragments.ToolFragment;
|
import io.anuke.mindustry.ui.fragments.ToolFragment;
|
||||||
import io.anuke.mindustry.world.SpawnPoint;
|
import io.anuke.mindustry.game.SpawnPoint;
|
||||||
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.mindustry.world.blocks.ProductionBlocks;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package io.anuke.mindustry.core;
|
package io.anuke.mindustry.core;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Gdx;
|
||||||
import com.badlogic.gdx.math.GridPoint2;
|
import com.badlogic.gdx.math.GridPoint2;
|
||||||
import com.badlogic.gdx.math.MathUtils;
|
import com.badlogic.gdx.math.MathUtils;
|
||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
@@ -24,7 +25,8 @@ 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.*;
|
import static io.anuke.mindustry.Vars.control;
|
||||||
|
import static io.anuke.mindustry.Vars.tilesize;
|
||||||
|
|
||||||
public class World extends Module{
|
public class World extends Module{
|
||||||
private int seed;
|
private int seed;
|
||||||
@@ -108,7 +110,7 @@ public class World extends Module{
|
|||||||
|
|
||||||
public Tile tile(int x, int y){
|
public Tile tile(int x, int y){
|
||||||
if(tiles == null){
|
if(tiles == null){
|
||||||
ui.showError("$text.error.crashmessage");
|
Gdx.app.postRunnable(() -> Vars.ui.showError("$text.error.crashmessage"));
|
||||||
GameState.set(State.menu);
|
GameState.set(State.menu);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -125,10 +125,13 @@ public class Player extends DestructibleEntity implements Syncable{
|
|||||||
|
|
||||||
float speed = dashing ? Player.dashSpeed : Player.speed;
|
float speed = dashing ? Player.dashSpeed : Player.speed;
|
||||||
|
|
||||||
if(health < maxhealth && Timers.get(this, "regen", 50))
|
if(health < maxhealth && Timers.get(this, "regen", 20))
|
||||||
health ++;
|
health ++;
|
||||||
|
|
||||||
|
health = Mathf.clamp(health, -1, maxhealth);
|
||||||
|
|
||||||
Tile tile = world.tileWorld(x, y);
|
Tile tile = world.tileWorld(x, y);
|
||||||
|
|
||||||
if(tile != null && tile.floor().liquid && tile.block() == Blocks.air){
|
if(tile != null && tile.floor().liquid && tile.block() == Blocks.air){
|
||||||
damage(health+1); //drown
|
damage(health+1); //drown
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package io.anuke.mindustry.game;
|
||||||
|
|
||||||
|
import io.anuke.ucore.util.Bundles;
|
||||||
|
|
||||||
|
public enum Difficulty {
|
||||||
|
easy(4f, 2f),
|
||||||
|
normal(2f, 1f),
|
||||||
|
hard(1.5f, 0.5f),
|
||||||
|
insane(0.5f, 0.25f),
|
||||||
|
purge(0.4f, 0.01f);
|
||||||
|
|
||||||
|
/**The scaling of how many waves it takes for one more enemy of a type to appear.
|
||||||
|
* For example: with enemeyScaling = 2 and the default scaling being 2, it would take 4 waves for
|
||||||
|
* an enemy spawn to go from 1->2 enemies.*/
|
||||||
|
public final float enemyScaling;
|
||||||
|
/**Multiplier of the time between waves.*/
|
||||||
|
public final float timeScaling;
|
||||||
|
|
||||||
|
Difficulty(float enemyScaling, float timeScaling){
|
||||||
|
this.enemyScaling = enemyScaling;
|
||||||
|
this.timeScaling = timeScaling;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return Bundles.get("setting.difficulty." + name());
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
-6
@@ -1,13 +1,10 @@
|
|||||||
package io.anuke.mindustry.entities;
|
package io.anuke.mindustry.game;
|
||||||
|
|
||||||
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.entities.enemies.EnemyType;
|
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||||
import io.anuke.ucore.core.Settings;
|
|
||||||
import io.anuke.ucore.util.Mathf;
|
import io.anuke.ucore.util.Mathf;
|
||||||
|
|
||||||
public class EnemySpawn{
|
public class EnemySpawn{
|
||||||
/**Scaling multiplier for each difficulty. Easy, normal, hard.*/
|
|
||||||
private static float[] scalings = {4f, 2.5f, 1.5f};
|
|
||||||
|
|
||||||
/**The enemy type spawned*/
|
/**The enemy type spawned*/
|
||||||
public final EnemyType type;
|
public final EnemyType type;
|
||||||
/**When this spawns should end*/
|
/**When this spawns should end*/
|
||||||
@@ -37,7 +34,7 @@ public class EnemySpawn{
|
|||||||
if(wave < after || wave > before || (wave - after) % spacing != 0){
|
if(wave < after || wave > before || (wave - after) % spacing != 0){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
float scaling = this.scaling * scalings[(Settings.getInt("difficulty"))];
|
float scaling = this.scaling * Vars.control.getDifficulty().enemyScaling;
|
||||||
|
|
||||||
return Math.min(amount-1 + Math.max((int)((wave / spacing) / scaling), 1) - (tier(wave, lane)-1) * tierscaleback, max);
|
return Math.min(amount-1 + Math.max((int)((wave / spacing) / scaling), 1) - (tier(wave, lane)-1) * tierscaleback, max);
|
||||||
}
|
}
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package io.anuke.mindustry.world;
|
package io.anuke.mindustry.game;
|
||||||
|
|
||||||
import io.anuke.ucore.util.Bundles;
|
import io.anuke.ucore.util.Bundles;
|
||||||
|
|
||||||
+2
-1
@@ -1,9 +1,10 @@
|
|||||||
package io.anuke.mindustry.world;
|
package io.anuke.mindustry.game;
|
||||||
|
|
||||||
import com.badlogic.gdx.ai.pfa.PathFinder;
|
import com.badlogic.gdx.ai.pfa.PathFinder;
|
||||||
import com.badlogic.gdx.ai.pfa.PathFinderRequest;
|
import com.badlogic.gdx.ai.pfa.PathFinderRequest;
|
||||||
|
|
||||||
import io.anuke.mindustry.ai.SmoothGraphPath;
|
import io.anuke.mindustry.ai.SmoothGraphPath;
|
||||||
|
import io.anuke.mindustry.world.Tile;
|
||||||
|
|
||||||
public class SpawnPoint{
|
public class SpawnPoint{
|
||||||
public Tile start;
|
public Tile start;
|
||||||
+2
-1
@@ -1,4 +1,4 @@
|
|||||||
package io.anuke.mindustry.entities;
|
package io.anuke.mindustry.game;
|
||||||
|
|
||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
import io.anuke.mindustry.entities.enemies.EnemyTypes;
|
import io.anuke.mindustry.entities.enemies.EnemyTypes;
|
||||||
@@ -6,6 +6,7 @@ import io.anuke.mindustry.entities.enemies.EnemyTypes;
|
|||||||
public class WaveCreator{
|
public class WaveCreator{
|
||||||
|
|
||||||
public static Array<EnemySpawn> getSpawns(){
|
public static Array<EnemySpawn> getSpawns(){
|
||||||
|
|
||||||
return Array.with(
|
return Array.with(
|
||||||
new EnemySpawn(EnemyTypes.standard){{
|
new EnemySpawn(EnemyTypes.standard){{
|
||||||
scaling = 1;
|
scaling = 1;
|
||||||
@@ -14,10 +14,10 @@ import com.badlogic.gdx.utils.Array;
|
|||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.core.GameState;
|
import io.anuke.mindustry.core.GameState;
|
||||||
import io.anuke.mindustry.core.GameState.State;
|
import io.anuke.mindustry.core.GameState.State;
|
||||||
|
import io.anuke.mindustry.game.SpawnPoint;
|
||||||
import io.anuke.mindustry.world.*;
|
import io.anuke.mindustry.world.*;
|
||||||
import io.anuke.mindustry.world.blocks.Blocks;
|
import io.anuke.mindustry.world.blocks.Blocks;
|
||||||
import io.anuke.mindustry.world.blocks.types.StaticBlock;
|
import io.anuke.mindustry.world.blocks.types.StaticBlock;
|
||||||
import io.anuke.ucore.UCore;
|
|
||||||
import io.anuke.ucore.core.Core;
|
import io.anuke.ucore.core.Core;
|
||||||
import io.anuke.ucore.core.Draw;
|
import io.anuke.ucore.core.Draw;
|
||||||
import io.anuke.ucore.core.Graphics;
|
import io.anuke.ucore.core.Graphics;
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import io.anuke.mindustry.resource.ItemStack;
|
|||||||
import io.anuke.mindustry.resource.Recipe;
|
import io.anuke.mindustry.resource.Recipe;
|
||||||
import io.anuke.mindustry.resource.Recipes;
|
import io.anuke.mindustry.resource.Recipes;
|
||||||
import io.anuke.mindustry.world.Block;
|
import io.anuke.mindustry.world.Block;
|
||||||
import io.anuke.mindustry.world.SpawnPoint;
|
import io.anuke.mindustry.game.SpawnPoint;
|
||||||
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.mindustry.world.blocks.ProductionBlocks;
|
||||||
@@ -109,9 +109,11 @@ public abstract class InputHandler extends InputAdapter{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(Player player : Vars.control.playerGroup.all()){
|
if(type.solid || type.solidifes) {
|
||||||
if(!player.isAndroid && Tmp.r2.overlaps(player.hitbox.getRect(player.x, player.y))){
|
for (Player player : Vars.control.playerGroup.all()) {
|
||||||
return false;
|
if (!player.isAndroid && Tmp.r2.overlaps(player.hitbox.getRect(player.x, player.y))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import io.anuke.mindustry.core.Tutorial.Stage;
|
|||||||
import io.anuke.mindustry.resource.Item;
|
import io.anuke.mindustry.resource.Item;
|
||||||
import io.anuke.mindustry.resource.Liquid;
|
import io.anuke.mindustry.resource.Liquid;
|
||||||
import io.anuke.mindustry.world.Block;
|
import io.anuke.mindustry.world.Block;
|
||||||
import io.anuke.mindustry.world.GameMode;
|
import io.anuke.mindustry.game.GameMode;
|
||||||
import io.anuke.mindustry.world.Map;
|
import io.anuke.mindustry.world.Map;
|
||||||
import io.anuke.ucore.core.Inputs.DeviceType;
|
import io.anuke.ucore.core.Inputs.DeviceType;
|
||||||
import io.anuke.ucore.core.KeyBinds;
|
import io.anuke.ucore.core.KeyBinds;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import io.anuke.mindustry.entities.enemies.Enemy;
|
|||||||
import io.anuke.mindustry.entities.enemies.EnemyType;
|
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||||
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.GameMode;
|
import io.anuke.mindustry.game.GameMode;
|
||||||
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.types.BlockPart;
|
import io.anuke.mindustry.world.blocks.types.BlockPart;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package io.anuke.mindustry.io;
|
|||||||
|
|
||||||
import io.anuke.mindustry.Mindustry;
|
import io.anuke.mindustry.Mindustry;
|
||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.world.GameMode;
|
import io.anuke.mindustry.game.GameMode;
|
||||||
import io.anuke.mindustry.world.Map;
|
import io.anuke.mindustry.world.Map;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import com.badlogic.gdx.utils.async.AsyncExecutor;
|
|||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.core.GameState;
|
import io.anuke.mindustry.core.GameState;
|
||||||
import io.anuke.mindustry.core.GameState.State;
|
import io.anuke.mindustry.core.GameState.State;
|
||||||
import io.anuke.mindustry.world.GameMode;
|
import io.anuke.mindustry.game.GameMode;
|
||||||
import io.anuke.mindustry.world.Map;
|
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;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ 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.BlockLoader;
|
import io.anuke.mindustry.world.BlockLoader;
|
||||||
import io.anuke.mindustry.world.GameMode;
|
import io.anuke.mindustry.game.GameMode;
|
||||||
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.ucore.core.Core;
|
import io.anuke.ucore.core.Core;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import com.badlogic.gdx.utils.TimeUtils;
|
|||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||||
import io.anuke.mindustry.entities.enemies.EnemyType;
|
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||||
|
import io.anuke.mindustry.game.GameMode;
|
||||||
import io.anuke.mindustry.io.SaveFileVersion;
|
import io.anuke.mindustry.io.SaveFileVersion;
|
||||||
import io.anuke.mindustry.resource.Item;
|
import io.anuke.mindustry.resource.Item;
|
||||||
import io.anuke.mindustry.resource.Upgrade;
|
import io.anuke.mindustry.resource.Upgrade;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ 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.GameMode;
|
import io.anuke.mindustry.game.GameMode;
|
||||||
import io.anuke.mindustry.world.Generator;
|
import io.anuke.mindustry.world.Generator;
|
||||||
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;
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ public class Packets {
|
|||||||
|
|
||||||
public static class EntityDataPacket{
|
public static class EntityDataPacket{
|
||||||
public Player[] players;
|
public Player[] players;
|
||||||
|
public EnemySpawnPacket[] enemies;
|
||||||
public byte[] playerWeapons;
|
public byte[] playerWeapons;
|
||||||
public int playerid;
|
public int playerid;
|
||||||
public byte[] weapons;
|
public byte[] weapons;
|
||||||
@@ -135,4 +136,8 @@ public class Packets {
|
|||||||
public int position;
|
public int position;
|
||||||
public byte data;
|
public byte data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class EntityRequestPacket{
|
||||||
|
public int id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ public class Registrator {
|
|||||||
WeaponSwitchPacket.class,
|
WeaponSwitchPacket.class,
|
||||||
BlockTapPacket.class,
|
BlockTapPacket.class,
|
||||||
BlockConfigPacket.class,
|
BlockConfigPacket.class,
|
||||||
|
EntityRequestPacket.class,
|
||||||
|
|
||||||
Class.class,
|
Class.class,
|
||||||
byte[].class,
|
byte[].class,
|
||||||
@@ -49,6 +50,7 @@ public class Registrator {
|
|||||||
Player[].class,
|
Player[].class,
|
||||||
Array.class,
|
Array.class,
|
||||||
Vector2.class,
|
Vector2.class,
|
||||||
|
EnemySpawnPacket[].class,
|
||||||
|
|
||||||
Entity.class,
|
Entity.class,
|
||||||
Player.class,
|
Player.class,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package io.anuke.mindustry.ui.dialogs;
|
|||||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||||
|
|
||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.world.GameMode;
|
import io.anuke.mindustry.game.GameMode;
|
||||||
import io.anuke.mindustry.world.Map;
|
import io.anuke.mindustry.world.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;
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ public class PausedDialog extends FloatingDialog{
|
|||||||
|
|
||||||
content().addButton("$text.quit", () -> {
|
content().addButton("$text.quit", () -> {
|
||||||
ui.showConfirm("$text.confirm", "$text.quit.confirm", () -> {
|
ui.showConfirm("$text.confirm", "$text.quit.confirm", () -> {
|
||||||
if(Net.active() && Net.client()) Net.disconnect();
|
if(Net.active() && Net.client()) Vars.netClient.disconnectQuietly();
|
||||||
runSave();
|
runSave();
|
||||||
hide();
|
hide();
|
||||||
GameState.set(State.menu);
|
GameState.set(State.menu);
|
||||||
@@ -110,7 +110,7 @@ public class PausedDialog extends FloatingDialog{
|
|||||||
|
|
||||||
new imagebutton("icon-quit", isize, () -> {
|
new imagebutton("icon-quit", isize, () -> {
|
||||||
Vars.ui.showConfirm("$text.confirm", "$text.quit.confirm", () -> {
|
Vars.ui.showConfirm("$text.confirm", "$text.quit.confirm", () -> {
|
||||||
if(Net.active() && Net.client()) Net.disconnect();
|
if(Net.active() && Net.client()) Vars.netClient.disconnectQuietly();
|
||||||
runSave();
|
runSave();
|
||||||
hide();
|
hide();
|
||||||
GameState.set(State.menu);
|
GameState.set(State.menu);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import com.badlogic.gdx.utils.Align;
|
|||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.core.GameState;
|
import io.anuke.mindustry.core.GameState;
|
||||||
import io.anuke.mindustry.core.GameState.State;
|
import io.anuke.mindustry.core.GameState.State;
|
||||||
|
import io.anuke.mindustry.game.Difficulty;
|
||||||
import io.anuke.mindustry.net.Net;
|
import io.anuke.mindustry.net.Net;
|
||||||
import io.anuke.ucore.core.Core;
|
import io.anuke.ucore.core.Core;
|
||||||
import io.anuke.ucore.core.Settings;
|
import io.anuke.ucore.core.Settings;
|
||||||
@@ -106,7 +107,7 @@ public class SettingsMenuDialog extends SettingsDialog{
|
|||||||
void addSettings(){
|
void addSettings(){
|
||||||
sound.volumePrefs();
|
sound.volumePrefs();
|
||||||
|
|
||||||
game.sliderPref("difficulty", 1, 0, 2, i -> Bundles.get("setting.difficulty." + (i == 0 ? "easy" : i == 1 ? "normal" : "hard")));
|
game.sliderPref("difficulty", 1, 0, Difficulty.values().length-1, i -> Difficulty.values()[i].toString());
|
||||||
game.screenshakePref();
|
game.screenshakePref();
|
||||||
game.checkPref("smoothcam", true);
|
game.checkPref("smoothcam", true);
|
||||||
game.checkPref("effects", true);
|
game.checkPref("effects", true);
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ public class ChatFragment extends Table implements Fragment{
|
|||||||
private final static int messagesShown = 10;
|
private final static int messagesShown = 10;
|
||||||
private final static int maxLength = 150;
|
private final static int maxLength = 150;
|
||||||
private Array<ChatMessage> messages = new Array<>();
|
private Array<ChatMessage> messages = new Array<>();
|
||||||
private float fadetime;
|
private float fadetime, lastfade;
|
||||||
private boolean chatOpen = false;
|
private boolean chatOpen = false;
|
||||||
private TextField chatfield;
|
private TextField chatfield;
|
||||||
private Label fieldlabel = new Label(">");
|
private Label fieldlabel = new Label(">");
|
||||||
@@ -157,12 +157,13 @@ public class ChatFragment extends Table implements Fragment{
|
|||||||
scene.setKeyboardFocus(chatfield);
|
scene.setKeyboardFocus(chatfield);
|
||||||
chatfield.fireClick();
|
chatfield.fireClick();
|
||||||
chatOpen = !chatOpen;
|
chatOpen = !chatOpen;
|
||||||
|
lastfade = fadetime;
|
||||||
fadetime = messagesShown + 1;
|
fadetime = messagesShown + 1;
|
||||||
}else if(chatOpen){
|
}else if(chatOpen){
|
||||||
scene.setKeyboardFocus(null);
|
scene.setKeyboardFocus(null);
|
||||||
chatOpen = !chatOpen;
|
chatOpen = !chatOpen;
|
||||||
|
fadetime = lastfade;
|
||||||
sendMessage();
|
sendMessage();
|
||||||
fadetime = messagesShown + 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,7 +181,7 @@ public class ChatFragment extends Table implements Fragment{
|
|||||||
messages.insert(0, new ChatMessage(message, sender));
|
messages.insert(0, new ChatMessage(message, sender));
|
||||||
|
|
||||||
fadetime += 1f;
|
fadetime += 1f;
|
||||||
fadetime = Math.min(fadetime, messagesShown) + 2f;
|
fadetime = Math.min(fadetime, messagesShown) + 1f;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ChatMessage{
|
private static class ChatMessage{
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ public class ProductionBlocks{
|
|||||||
inputs = new Item[]{Item.titanium, Item.steel};
|
inputs = new Item[]{Item.titanium, Item.steel};
|
||||||
fuel = Item.coal;
|
fuel = Item.coal;
|
||||||
result = Item.dirium;
|
result = Item.dirium;
|
||||||
burnDuration = 80f;
|
burnDuration = 40f;
|
||||||
craftTime = 40f;
|
craftTime = 20f;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,8 @@ public class BlockPart extends Block implements PowerAcceptor, LiquidAcceptor{
|
|||||||
@Override
|
@Override
|
||||||
public boolean isSolidFor(Tile tile){
|
public boolean isSolidFor(Tile tile){
|
||||||
return tile.getLinked() == null
|
return tile.getLinked() == null
|
||||||
|| (tile.getLinked().solid() || tile.getLinked().block().isSolidFor(tile.getLinked()));
|
|| (tile.getLinked().block() instanceof BlockPart || tile.getLinked().solid()
|
||||||
|
|| tile.getLinked().block().isSolidFor(tile.getLinked()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -17,14 +17,14 @@ import io.anuke.ucore.util.Strings;
|
|||||||
public class ShieldBlock extends PowerBlock{
|
public class ShieldBlock extends PowerBlock{
|
||||||
public float shieldRadius = 40f;
|
public float shieldRadius = 40f;
|
||||||
public float powerDrain = 0.005f;
|
public float powerDrain = 0.005f;
|
||||||
public float powerPerDamage = 0.07f;
|
public float powerPerDamage = 0.06f;
|
||||||
public float maxRadius = 40f;
|
public float maxRadius = 40f;
|
||||||
public float radiusScale = 300f;
|
public float radiusScale = 300f;
|
||||||
|
|
||||||
public ShieldBlock(String name) {
|
public ShieldBlock(String name) {
|
||||||
super(name);
|
super(name);
|
||||||
voltage = powerDrain;
|
voltage = powerDrain;
|
||||||
powerCapacity = 40f;
|
powerCapacity = 80f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ public class Smelter extends Block{
|
|||||||
protected Item fuel;
|
protected Item fuel;
|
||||||
protected Item result;
|
protected Item result;
|
||||||
|
|
||||||
protected float craftTime = 30f; //time to craft one item, so max 2 items per second by default
|
protected float craftTime = 15f; //time to craft one item, so max 4 items per second by default
|
||||||
protected float burnDuration = 60f; //by default, the fuel will burn 60 frames, so that's 2 items/fuel at most
|
protected float burnDuration = 45f; //by default, the fuel will burn 45 frames, so that's 4 items/fuel at most
|
||||||
protected Effect craftEffect = Fx.smelt, burnEffect = Fx.fuelburn;
|
protected Effect craftEffect = Fx.smelt, burnEffect = Fx.fuelburn;
|
||||||
|
|
||||||
protected int capacity = 20;
|
protected int capacity = 20;
|
||||||
|
|||||||
Reference in New Issue
Block a user