Fixed: missing spawns / incorrect ranks / jittery movement / tests

This commit is contained in:
Anuken
2019-02-23 15:08:07 -05:00
parent d74887eaa1
commit 976b39414f
15 changed files with 65 additions and 40 deletions

View File

@@ -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 -> {

View File

@@ -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();

View File

@@ -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();

View File

@@ -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));

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;
} }
} }

View File

@@ -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();
} }

View File

@@ -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;

View File

@@ -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();

View 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;
}
}

View File

@@ -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();

View File

@@ -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;

View File

@@ -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();
}
} }
}; };

View File

@@ -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