Fixed: missing spawns / incorrect ranks / jittery movement / tests
This commit is contained in:
@@ -101,9 +101,7 @@ public class Control implements ApplicationListener{
|
|||||||
});
|
});
|
||||||
|
|
||||||
Events.on(WorldLoadEvent.class, event -> {
|
Events.on(WorldLoadEvent.class, event -> {
|
||||||
if(mobile){
|
Core.app.post(() -> Core.camera.position.set(players[0]));
|
||||||
Core.app.post(() -> Core.camera.position.set(players[0]));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Events.on(ResetEvent.class, event -> {
|
Events.on(ResetEvent.class, event -> {
|
||||||
|
|||||||
@@ -68,7 +68,6 @@ public class Logic implements ApplicationListener{
|
|||||||
state.gameOver = state.launched = false;
|
state.gameOver = state.launched = false;
|
||||||
state.teams = new Teams();
|
state.teams = new Teams();
|
||||||
state.rules = new Rules();
|
state.rules = new Rules();
|
||||||
state.rules.spawns = DefaultWaves.getDefaultSpawns();
|
|
||||||
state.stats = new Stats();
|
state.stats = new Stats();
|
||||||
|
|
||||||
Time.clear();
|
Time.clear();
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import io.anuke.arc.math.geom.Rectangle;
|
|||||||
import io.anuke.arc.math.geom.Vector2;
|
import io.anuke.arc.math.geom.Vector2;
|
||||||
import io.anuke.arc.util.ScreenRecorder;
|
import io.anuke.arc.util.ScreenRecorder;
|
||||||
import io.anuke.arc.util.Time;
|
import io.anuke.arc.util.Time;
|
||||||
|
import io.anuke.arc.util.Tmp;
|
||||||
import io.anuke.arc.util.pooling.Pools;
|
import io.anuke.arc.util.pooling.Pools;
|
||||||
import io.anuke.mindustry.content.Fx;
|
import io.anuke.mindustry.content.Fx;
|
||||||
import io.anuke.mindustry.core.GameState.State;
|
import io.anuke.mindustry.core.GameState.State;
|
||||||
@@ -48,7 +49,6 @@ public class Renderer implements ApplicationListener{
|
|||||||
private float targetscale = io.anuke.arc.scene.ui.layout.Unit.dp.scl(4);
|
private float targetscale = io.anuke.arc.scene.ui.layout.Unit.dp.scl(4);
|
||||||
private float camerascale = targetscale;
|
private float camerascale = targetscale;
|
||||||
private Rectangle rect = new Rectangle(), rect2 = new Rectangle();
|
private Rectangle rect = new Rectangle(), rect2 = new Rectangle();
|
||||||
private Vector2 avgPosition = new Vector2();
|
|
||||||
private float shakeIntensity, shaketime;
|
private float shakeIntensity, shaketime;
|
||||||
|
|
||||||
public Renderer(){
|
public Renderer(){
|
||||||
@@ -115,7 +115,7 @@ public class Renderer implements ApplicationListener{
|
|||||||
if(state.is(State.menu)){
|
if(state.is(State.menu)){
|
||||||
graphics.clear(Color.BLACK);
|
graphics.clear(Color.BLACK);
|
||||||
}else{
|
}else{
|
||||||
Vector2 position = averagePosition();
|
Vector2 position = Tmp.v3.set(players[0]);
|
||||||
|
|
||||||
if(players[0].isDead()){
|
if(players[0].isDead()){
|
||||||
TileEntity core = players[0].getClosestCore();
|
TileEntity core = players[0].getClosestCore();
|
||||||
@@ -288,15 +288,6 @@ public class Renderer implements ApplicationListener{
|
|||||||
return camerascale;
|
return camerascale;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector2 averagePosition(){
|
|
||||||
avgPosition.setZero();
|
|
||||||
|
|
||||||
drawAndInterpolate(playerGroup, p -> p.isLocal, p -> avgPosition.add(p.x, p.y));
|
|
||||||
|
|
||||||
avgPosition.scl(1f / players.length);
|
|
||||||
return avgPosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void scaleCamera(float amount){
|
public void scaleCamera(float amount){
|
||||||
targetscale += amount;
|
targetscale += amount;
|
||||||
clampScale();
|
clampScale();
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import io.anuke.arc.Core;
|
|||||||
import io.anuke.arc.Events;
|
import io.anuke.arc.Events;
|
||||||
import io.anuke.arc.collection.Array;
|
import io.anuke.arc.collection.Array;
|
||||||
import io.anuke.arc.collection.IntArray;
|
import io.anuke.arc.collection.IntArray;
|
||||||
import io.anuke.mindustry.entities.EntityQuery;
|
|
||||||
import io.anuke.arc.math.Mathf;
|
import io.anuke.arc.math.Mathf;
|
||||||
import io.anuke.arc.math.geom.Geometry;
|
import io.anuke.arc.math.geom.Geometry;
|
||||||
import io.anuke.arc.math.geom.Point2;
|
import io.anuke.arc.math.geom.Point2;
|
||||||
@@ -17,11 +16,13 @@ import io.anuke.mindustry.ai.Pathfinder;
|
|||||||
import io.anuke.mindustry.ai.WaveSpawner;
|
import io.anuke.mindustry.ai.WaveSpawner;
|
||||||
import io.anuke.mindustry.content.Blocks;
|
import io.anuke.mindustry.content.Blocks;
|
||||||
import io.anuke.mindustry.core.GameState.State;
|
import io.anuke.mindustry.core.GameState.State;
|
||||||
|
import io.anuke.mindustry.entities.EntityQuery;
|
||||||
import io.anuke.mindustry.game.EventType.TileChangeEvent;
|
import io.anuke.mindustry.game.EventType.TileChangeEvent;
|
||||||
import io.anuke.mindustry.game.EventType.WorldLoadEvent;
|
import io.anuke.mindustry.game.EventType.WorldLoadEvent;
|
||||||
import io.anuke.mindustry.game.Team;
|
import io.anuke.mindustry.game.Team;
|
||||||
import io.anuke.mindustry.io.MapIO;
|
import io.anuke.mindustry.io.MapIO;
|
||||||
import io.anuke.mindustry.maps.Map;
|
import io.anuke.mindustry.maps.Map;
|
||||||
|
import io.anuke.mindustry.maps.MapException;
|
||||||
import io.anuke.mindustry.maps.MapTileData;
|
import io.anuke.mindustry.maps.MapTileData;
|
||||||
import io.anuke.mindustry.maps.MapTileData.TileDataMarker;
|
import io.anuke.mindustry.maps.MapTileData.TileDataMarker;
|
||||||
import io.anuke.mindustry.maps.Maps;
|
import io.anuke.mindustry.maps.Maps;
|
||||||
@@ -270,6 +271,17 @@ public class World implements ApplicationListener{
|
|||||||
ui.showError("$map.nospawn.pvp");
|
ui.showError("$map.nospawn.pvp");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}else{
|
||||||
|
invalidMap = true;
|
||||||
|
for(Team team : Team.all){
|
||||||
|
if(state.teams.get(team).cores.size != 0){
|
||||||
|
invalidMap = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(invalidMap){
|
||||||
|
throw new MapException(map, "Map has no cores!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(invalidMap) Core.app.post(() -> state.set(State.menu));
|
if(invalidMap) Core.app.post(() -> state.set(State.menu));
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
package io.anuke.mindustry.entities.traits;
|
package io.anuke.mindustry.entities.traits;
|
||||||
|
|
||||||
|
import io.anuke.arc.math.geom.Position;
|
||||||
import io.anuke.mindustry.entities.type.Player;
|
import io.anuke.mindustry.entities.type.Player;
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
|
|
||||||
public interface SpawnerTrait extends TargetTrait{
|
public interface SpawnerTrait extends TargetTrait, Position{
|
||||||
Tile getTile();
|
Tile getTile();
|
||||||
|
|
||||||
void updateSpawning(Player unit);
|
void updateSpawning(Player unit);
|
||||||
|
|||||||
@@ -464,8 +464,12 @@ public class Player extends Unit implements BuilderTrait, ShooterTrait{
|
|||||||
|
|
||||||
//region update methods
|
//region update methods
|
||||||
|
|
||||||
|
Vector2 last = new Vector2();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(){
|
public void update(){
|
||||||
|
last.set(this);
|
||||||
|
|
||||||
hitTime -= Time.delta();
|
hitTime -= Time.delta();
|
||||||
|
|
||||||
if(Float.isNaN(x) || Float.isNaN(y)){
|
if(Float.isNaN(x) || Float.isNaN(y)){
|
||||||
@@ -766,6 +770,8 @@ public class Player extends Unit implements BuilderTrait, ShooterTrait{
|
|||||||
}else if(getClosestCore() != null){
|
}else if(getClosestCore() != null){
|
||||||
this.spawner = (SpawnerTrait)getClosestCore();
|
this.spawner = (SpawnerTrait)getClosestCore();
|
||||||
}
|
}
|
||||||
|
}else if(getClosestCore() != null){
|
||||||
|
set(getClosestCore().getX(), getClosestCore().getY());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -841,7 +847,7 @@ public class Player extends Unit implements BuilderTrait, ShooterTrait{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void read(DataInput buffer) throws IOException{
|
public void read(DataInput buffer) throws IOException{
|
||||||
float lastx = x, lasty = y, lastrot = rotation;
|
float lastx = x, lasty = y, lastrot = rotation, lastvx = velocity.x, lastvy = velocity.y;
|
||||||
super.readSave(buffer);
|
super.readSave(buffer);
|
||||||
name = TypeIO.readStringData(buffer);
|
name = TypeIO.readStringData(buffer);
|
||||||
byte bools = buffer.readByte();
|
byte bools = buffer.readByte();
|
||||||
@@ -862,6 +868,8 @@ public class Player extends Unit implements BuilderTrait, ShooterTrait{
|
|||||||
if(isLocal){
|
if(isLocal){
|
||||||
x = lastx;
|
x = lastx;
|
||||||
y = lasty;
|
y = lasty;
|
||||||
|
velocity.x = lastvx;
|
||||||
|
velocity.y = lastvy;
|
||||||
}else{
|
}else{
|
||||||
mining = world.tile(mine);
|
mining = world.tile(mine);
|
||||||
isBoosting = boosting;
|
isBoosting = boosting;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ public class DefaultWaves{
|
|||||||
private static Array<SpawnGroup> spawns;
|
private static Array<SpawnGroup> spawns;
|
||||||
|
|
||||||
public static Array<SpawnGroup> getDefaultSpawns(){
|
public static Array<SpawnGroup> getDefaultSpawns(){
|
||||||
if(spawns == null){
|
if(spawns == null && UnitTypes.dagger != null){
|
||||||
spawns = Array.with(
|
spawns = Array.with(
|
||||||
new SpawnGroup(UnitTypes.dagger){{
|
new SpawnGroup(UnitTypes.dagger){{
|
||||||
end = 8;
|
end = 8;
|
||||||
@@ -164,6 +164,6 @@ public class DefaultWaves{
|
|||||||
}}
|
}}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return spawns;
|
return spawns == null ? new Array<>() : spawns;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,5 +28,5 @@ public class Rules{
|
|||||||
/**Zone ID, -1 for invalid zone.*/
|
/**Zone ID, -1 for invalid zone.*/
|
||||||
public byte zone = -1;
|
public byte zone = -1;
|
||||||
/**Spawn layout. Since only zones modify this, it should be assigned on save load.*/
|
/**Spawn layout. Since only zones modify this, it should be assigned on save load.*/
|
||||||
public transient Array<SpawnGroup> spawns = new Array<>();
|
public transient Array<SpawnGroup> spawns = DefaultWaves.getDefaultSpawns();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public class Stats{
|
|||||||
|
|
||||||
//each new launch period adds onto the rank 1.5 'points'
|
//each new launch period adds onto the rank 1.5 'points'
|
||||||
if(wavesLasted >= zone.conditionWave){
|
if(wavesLasted >= zone.conditionWave){
|
||||||
score += (float)((zone.conditionWave - wavesLasted) / zone.launchPeriod + 1) * 1.5f;
|
score += (float)((wavesLasted - zone.conditionWave) / zone.launchPeriod + 1) * 1.5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
int capacity = zone.generator.coreBlock.itemCapacity;
|
int capacity = zone.generator.coreBlock.itemCapacity;
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package io.anuke.mindustry.io;
|
package io.anuke.mindustry.io;
|
||||||
|
|
||||||
import io.anuke.arc.collection.Array;
|
import io.anuke.arc.collection.Array;
|
||||||
|
import io.anuke.arc.util.Pack;
|
||||||
|
import io.anuke.mindustry.content.Blocks;
|
||||||
import io.anuke.mindustry.entities.Entities;
|
import io.anuke.mindustry.entities.Entities;
|
||||||
import io.anuke.mindustry.entities.EntityGroup;
|
import io.anuke.mindustry.entities.EntityGroup;
|
||||||
import io.anuke.mindustry.entities.traits.Entity;
|
import io.anuke.mindustry.entities.traits.Entity;
|
||||||
import io.anuke.arc.util.Pack;
|
|
||||||
import io.anuke.mindustry.content.Blocks;
|
|
||||||
import io.anuke.mindustry.entities.traits.SaveTrait;
|
import io.anuke.mindustry.entities.traits.SaveTrait;
|
||||||
import io.anuke.mindustry.entities.traits.TypeTrait;
|
import io.anuke.mindustry.entities.traits.TypeTrait;
|
||||||
import io.anuke.mindustry.game.Content;
|
import io.anuke.mindustry.game.Content;
|
||||||
@@ -16,13 +16,13 @@ import io.anuke.mindustry.gen.Serialization;
|
|||||||
import io.anuke.mindustry.type.ContentType;
|
import io.anuke.mindustry.type.ContentType;
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
import io.anuke.mindustry.world.blocks.BlockPart;
|
import io.anuke.mindustry.world.blocks.BlockPart;
|
||||||
import io.anuke.mindustry.world.blocks.storage.CoreBlock;
|
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
import static io.anuke.mindustry.Vars.content;
|
||||||
|
import static io.anuke.mindustry.Vars.world;
|
||||||
|
|
||||||
public abstract class SaveFileVersion{
|
public abstract class SaveFileVersion{
|
||||||
public final int version;
|
public final int version;
|
||||||
@@ -110,8 +110,6 @@ public abstract class SaveFileVersion{
|
|||||||
byte team = Pack.leftByte(tr);
|
byte team = Pack.leftByte(tr);
|
||||||
byte rotation = Pack.rightByte(tr);
|
byte rotation = Pack.rightByte(tr);
|
||||||
|
|
||||||
Team t = Team.all[team];
|
|
||||||
|
|
||||||
tile.setTeam(Team.all[team]);
|
tile.setTeam(Team.all[team]);
|
||||||
tile.entity.health = health;
|
tile.entity.health = health;
|
||||||
tile.setRotation(rotation);
|
tile.setRotation(rotation);
|
||||||
@@ -123,10 +121,6 @@ public abstract class SaveFileVersion{
|
|||||||
|
|
||||||
tile.entity.readConfig(stream);
|
tile.entity.readConfig(stream);
|
||||||
tile.entity.read(stream);
|
tile.entity.read(stream);
|
||||||
|
|
||||||
if(tile.block() instanceof CoreBlock){
|
|
||||||
state.teams.get(t).cores.add(tile);
|
|
||||||
}
|
|
||||||
}else if(wallid == 0){
|
}else if(wallid == 0){
|
||||||
int consecutives = stream.readUnsignedByte();
|
int consecutives = stream.readUnsignedByte();
|
||||||
|
|
||||||
|
|||||||
10
core/src/io/anuke/mindustry/maps/MapException.java
Normal file
10
core/src/io/anuke/mindustry/maps/MapException.java
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package io.anuke.mindustry.maps;
|
||||||
|
|
||||||
|
public class MapException extends RuntimeException{
|
||||||
|
public final Map map;
|
||||||
|
|
||||||
|
public MapException(Map map, String s){
|
||||||
|
super(s);
|
||||||
|
this.map = map;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -144,7 +144,7 @@ public class HudFragment extends Fragment{
|
|||||||
}
|
}
|
||||||
infolabel.visible(() -> Core.settings.getBool("fps")).update(() ->
|
infolabel.visible(() -> Core.settings.getBool("fps")).update(() ->
|
||||||
infolabel.setPosition(0,
|
infolabel.setPosition(0,
|
||||||
healthTable.isVisible() ? healthTable.getY() + healthTable.getTranslation().y : wavetable.isVisible() ? wavetable.getY() : 0f,
|
healthTable.isVisible() ? healthTable.getY() + healthTable.getTranslation().y : waves.isVisible() ? wavetable.getY() : Core.graphics.getHeight(),
|
||||||
Align.topLeft));
|
Align.topLeft));
|
||||||
|
|
||||||
infolabel.pack();
|
infolabel.pack();
|
||||||
|
|||||||
@@ -4,17 +4,17 @@ import io.anuke.annotations.Annotations.Loc;
|
|||||||
import io.anuke.annotations.Annotations.Remote;
|
import io.anuke.annotations.Annotations.Remote;
|
||||||
import io.anuke.arc.Core;
|
import io.anuke.arc.Core;
|
||||||
import io.anuke.arc.collection.EnumSet;
|
import io.anuke.arc.collection.EnumSet;
|
||||||
import io.anuke.mindustry.entities.Effects;
|
|
||||||
import io.anuke.arc.graphics.g2d.Draw;
|
import io.anuke.arc.graphics.g2d.Draw;
|
||||||
import io.anuke.arc.graphics.g2d.Lines;
|
import io.anuke.arc.graphics.g2d.Lines;
|
||||||
import io.anuke.arc.graphics.g2d.TextureRegion;
|
import io.anuke.arc.graphics.g2d.TextureRegion;
|
||||||
import io.anuke.arc.math.Mathf;
|
import io.anuke.arc.math.Mathf;
|
||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.content.Fx;
|
import io.anuke.mindustry.content.Fx;
|
||||||
|
import io.anuke.mindustry.entities.Effects;
|
||||||
|
import io.anuke.mindustry.entities.traits.SpawnerTrait;
|
||||||
import io.anuke.mindustry.entities.type.Player;
|
import io.anuke.mindustry.entities.type.Player;
|
||||||
import io.anuke.mindustry.entities.type.TileEntity;
|
import io.anuke.mindustry.entities.type.TileEntity;
|
||||||
import io.anuke.mindustry.entities.type.Unit;
|
import io.anuke.mindustry.entities.type.Unit;
|
||||||
import io.anuke.mindustry.entities.traits.SpawnerTrait;
|
|
||||||
import io.anuke.mindustry.gen.Call;
|
import io.anuke.mindustry.gen.Call;
|
||||||
import io.anuke.mindustry.graphics.Pal;
|
import io.anuke.mindustry.graphics.Pal;
|
||||||
import io.anuke.mindustry.graphics.Shaders;
|
import io.anuke.mindustry.graphics.Shaders;
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import io.anuke.mindustry.game.EventType.GameOverEvent;
|
|||||||
import io.anuke.mindustry.gen.Call;
|
import io.anuke.mindustry.gen.Call;
|
||||||
import io.anuke.mindustry.io.SaveIO;
|
import io.anuke.mindustry.io.SaveIO;
|
||||||
import io.anuke.mindustry.maps.Map;
|
import io.anuke.mindustry.maps.Map;
|
||||||
|
import io.anuke.mindustry.maps.MapException;
|
||||||
import io.anuke.mindustry.net.Administration.PlayerInfo;
|
import io.anuke.mindustry.net.Administration.PlayerInfo;
|
||||||
import io.anuke.mindustry.net.Net;
|
import io.anuke.mindustry.net.Net;
|
||||||
import io.anuke.mindustry.net.Packets.KickReason;
|
import io.anuke.mindustry.net.Packets.KickReason;
|
||||||
@@ -220,12 +221,16 @@ public class ServerControl implements ApplicationListener{
|
|||||||
|
|
||||||
logic.reset();
|
logic.reset();
|
||||||
state.rules = preset.get();
|
state.rules = preset.get();
|
||||||
world.loadMap(result);
|
try{
|
||||||
logic.play();
|
world.loadMap(result);
|
||||||
|
logic.play();
|
||||||
|
|
||||||
info("Map loaded.");
|
info("Map loaded.");
|
||||||
|
|
||||||
host();
|
host();
|
||||||
|
}catch(MapException e){
|
||||||
|
Log.err(e.map.getDisplayName() + ": " + e.getMessage());
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
handler.register("port", "[port]", "Sets or displays the port for hosting the server.", arg -> {
|
handler.register("port", "[port]", "Sets or displays the port for hosting the server.", arg -> {
|
||||||
@@ -657,7 +662,12 @@ public class ServerControl implements ApplicationListener{
|
|||||||
lastTask = new Task(){
|
lastTask = new Task(){
|
||||||
@Override
|
@Override
|
||||||
public void run(){
|
public void run(){
|
||||||
r.run();
|
try{
|
||||||
|
r.run();
|
||||||
|
}catch(MapException e){
|
||||||
|
Log.err(e.map.getDisplayName() + ": " + e.getMessage());
|
||||||
|
Net.closeServer();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -181,6 +181,7 @@ public class ApplicationTests{
|
|||||||
@Test
|
@Test
|
||||||
void save(){
|
void save(){
|
||||||
world.loadMap(testMap);
|
world.loadMap(testMap);
|
||||||
|
assertTrue(state.teams.get(defaultTeam).cores.size > 0);
|
||||||
SaveIO.saveToSlot(0);
|
SaveIO.saveToSlot(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,6 +196,7 @@ public class ApplicationTests{
|
|||||||
|
|
||||||
assertEquals(world.width(), map.meta.width);
|
assertEquals(world.width(), map.meta.width);
|
||||||
assertEquals(world.height(), map.meta.height);
|
assertEquals(world.height(), map.meta.height);
|
||||||
|
assertTrue(state.teams.get(defaultTeam).cores.size > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
Reference in New Issue
Block a user