Large-scale bugfix: fixed #76, as well as many other timer bugs

This commit is contained in:
Anuken 2018-02-11 16:10:23 -05:00
parent ef4a7a8fea
commit a248891a94
15 changed files with 325 additions and 30 deletions

View File

@ -24,7 +24,7 @@ allprojects {
appName = 'Mindustry'
gdxVersion = '1.9.8'
aiVersion = '1.8.1'
uCoreVersion = 'b42c54e'
uCoreVersion = '91b310b'
getVersionString = {
String buildVersion = getBuildVersion()

View File

@ -1,7 +1,7 @@
#Autogenerated file. Do not modify.
#Sat Feb 10 12:55:55 EST 2018
#Sun Feb 11 16:07:52 EST 2018
version=beta
androidBuildCode=155
androidBuildCode=168
name=Mindustry
code=3.3
build=custom build

View File

@ -26,6 +26,7 @@ import io.anuke.ucore.entities.Entity;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.modules.Module;
import io.anuke.ucore.util.Log;
import io.anuke.ucore.util.Timer;
import java.io.DataInputStream;
import java.io.IOException;
@ -37,6 +38,7 @@ public class NetClient extends Module {
private final static float dataTimeout = 60*18; //18 seconds timeout
private final static float playerSyncTime = 2;
private Timer timer = new Timer(5);
private boolean connecting = false;
private boolean gotData = false;
private boolean kicked = false;
@ -75,7 +77,7 @@ public class NetClient extends Module {
Net.handleClient(Disconnect.class, packet -> {
if (kicked) return;
Timers.runFor(3f, ui.loadfrag::hide);
Timers.runTask(3f, ui.loadfrag::hide);
state.set(State.menu);
@ -153,7 +155,8 @@ public class NetClient extends Module {
state.wavetime = packet.countdown;
state.wave = packet.wave;
Timers.resetTime(packet.time + (float) (TimeUtils.timeSinceMillis(packet.timestamp) / 1000.0 * 60.0));
//removed: messing with time isn't necessary anymore
//Timers.resetTime(packet.time + (float) (TimeUtils.timeSinceMillis(packet.timestamp) / 1000.0 * 60.0));
ui.hudfrag.updateItems();
});
@ -334,7 +337,9 @@ public class NetClient extends Module {
}
void sync(){
if(Timers.get("syncPlayer", playerSyncTime)){
if(timer.get(0, playerSyncTime)){
byte[] bytes = new byte[player.getWriteSize() + 8];
ByteBuffer buffer = ByteBuffer.wrap(bytes);
buffer.putLong(TimeUtils.millis());
@ -345,7 +350,7 @@ public class NetClient extends Module {
Net.send(packet, SendMode.udp);
}
if(Timers.get("updatePing", 60)){
if(timer.get(1, playerSyncTime)){
Net.updatePing();
}
}

View File

@ -24,6 +24,7 @@ import io.anuke.ucore.entities.Entities;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.modules.Module;
import io.anuke.ucore.util.Log;
import io.anuke.ucore.util.Timer;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@ -34,11 +35,16 @@ import java.nio.ByteBuffer;
import static io.anuke.mindustry.Vars.*;
public class NetServer extends Module{
private final static float serverSyncTime = 4, itemSyncTime = 10, blockSyncTime = 120;
private final static int timerEntitySync = 0;
private final static int timerStateSync = 1;
/**Maps connection IDs to players.*/
IntMap<Player> connections = new IntMap<>();
ObjectMap<String, ByteArray> weapons = new ObjectMap<>();
float serverSyncTime = 4, itemSyncTime = 10, blockSyncTime = 120;
boolean closing = false;
private IntMap<Player> connections = new IntMap<>();
private ObjectMap<String, ByteArray> weapons = new ObjectMap<>();
private boolean closing = false;
private Timer timer = new Timer(5);
public NetServer(){
@ -218,7 +224,7 @@ public class NetServer extends Module{
void sync(){
if(Timers.get("serverSync", serverSyncTime)){
if(timer.get(timerEntitySync, serverSyncTime)){
//scan through all groups with syncable entities
for(EntityGroup<?> group : Entities.getAllGroups()) {
if(group.size() == 0 || !(group.all().first() instanceof SyncEntity)) continue;
@ -283,7 +289,7 @@ public class NetServer extends Module{
}
}
if(Timers.get("serverItemSync", itemSyncTime)){
if(timer.get(timerStateSync, itemSyncTime)){
StateSyncPacket packet = new StateSyncPacket();
packet.items = state.inventory.getItems();
packet.countdown = state.wavetime;
@ -294,6 +300,7 @@ public class NetServer extends Module{
Net.send(packet, SendMode.udp);
}
/*
if(Timers.get("serverBlockSync", blockSyncTime)){

View File

@ -5,10 +5,12 @@ import io.anuke.ucore.entities.BulletEntity;
import io.anuke.ucore.entities.Entity;
import io.anuke.ucore.entities.SolidEntity;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Timer;
import static io.anuke.mindustry.Vars.*;
public class Bullet extends BulletEntity{
public Timer timer = new Timer(3);
public Bullet(BulletType type, Entity owner, float x, float y, float angle){
super(type, owner, angle);

View File

@ -52,7 +52,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
}
public void update(Bullet b){
if(Timers.get(b, "smoke", 4)){
if(b.timer.get(0, 4)){
Effects.effect(Fx.railsmoke, b.x, b.y);
}
}
@ -73,7 +73,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
}
public void update(Bullet b){
if(Timers.get(b, "smoke", 2)){
if(b.timer.get(0, 2)){
Effects.effect(Fx.empspark, b.x + Mathf.range(2), b.y + Mathf.range(2));
}
}
@ -107,7 +107,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
}
public void update(Bullet b){
if(Timers.get(b, "smoke", 7)){
if(b.timer.get(0, 7)){
Effects.effect(Fx.smoke, b.x + Mathf.range(2), b.y + Mathf.range(2));
}
}
@ -132,7 +132,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
}
public void update(Bullet b){
if(Timers.get(b, "smoke", 7)){
if(b.timer.get(0, 7)){
Effects.effect(Fx.smoke, b.x + Mathf.range(2), b.y + Mathf.range(2));
}
}
@ -187,7 +187,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
}
public void update(Bullet b){
if(Timers.get(b, "smoke", 4)){
if(b.timer.get(0, 4)){
Effects.effect(Fx.smoke, b.x + Mathf.range(2), b.y + Mathf.range(2));
}
}
@ -218,7 +218,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
}
public void update(Bullet b){
if(Timers.get(b, "smoke", 4)){
if(b.timer.get(0, 4)){
Effects.effect(Fx.smoke, b.x + Mathf.range(2), b.y + Mathf.range(2));
}
}
@ -391,7 +391,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
}
public void update(Bullet b){
if(Timers.get(b, "smoke", 4)){
if(b.timer.get(0, 4)){
Effects.effect(Fx.chainsmoke, b.x, b.y);
}
}

View File

@ -16,6 +16,7 @@ import io.anuke.ucore.entities.SolidEntity;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Timer;
import io.anuke.ucore.util.Translator;
import java.nio.ByteBuffer;
@ -26,6 +27,11 @@ public class Player extends SyncEntity{
static final float speed = 1.1f;
static final float dashSpeed = 1.8f;
static final int timerDash = 0;
static final int timerShootLeft = 1;
static final int timerShootRight = 2;
static final int timerRegen = 20;
public String name = "name";
public boolean isAndroid;
public Color color = new Color();
@ -40,6 +46,7 @@ public class Player extends SyncEntity{
public int clientid;
public boolean isLocal = false;
public Timer timer = new Timer(4);
private Vector2 movement = new Vector2();
private Translator tr = new Translator();
@ -168,7 +175,7 @@ public class Player extends SyncEntity{
float speed = dashing ? (debug ? Player.dashSpeed * 5f : Player.dashSpeed) : Player.speed;
if(health < maxhealth && Timers.get(this, "regen", 20))
if(health < maxhealth && timer.get(timerRegen, 20 ))
health ++;
health = Mathf.clamp(health, -1, maxhealth);
@ -191,7 +198,7 @@ public class Player extends SyncEntity{
weaponRight.update(player, false);
}
if(dashing && Timers.get(this, "dashfx", 3) && movement.len() > 0){
if(dashing && timer.get(timerDash, 3) && movement.len() > 0){
Effects.effect(Fx.dashsmoke, x + Angles.trnsx(angle + 180f, 3f), y + Angles.trnsy(angle + 180f, 3f));
}
@ -255,7 +262,7 @@ public class Player extends SyncEntity{
@Override
public void write(ByteBuffer data) {
if(Net.client()) {
if(Net.client() || isLocal) {
data.putFloat(x);
data.putFloat(y);
}else{
@ -290,11 +297,11 @@ public class Player extends SyncEntity{
float tx = x + Angles.trnsx(angle + 180f, 3f);
float ty = y + Angles.trnsy(angle + 180f, 3f);
if(isAndroid && i.target.dst(i.last) > 2f && Timers.get(this, "dashfx", 2)){
if(isAndroid && i.target.dst(i.last) > 2f && timer.get(timerDash, 1)){
Effects.effect(Fx.dashsmoke, tx, ty);
}
if(dashing && !dead && Timers.get(this, "dashfx", 3) && i.target.dst(i.last) > 1f){
if(dashing && !dead && timer.get(timerDash, 3) && i.target.dst(i.last) > 1f){
Effects.effect(Fx.dashsmoke, tx, ty);
}
}

View File

@ -227,6 +227,7 @@ public class NetworkIO {
float timerTime = stream.readFloat();
long timestamp = stream.readLong();
Timers.clear();
Timers.resetTime(timerTime + (TimeUtils.timeSinceMillis(timestamp) / 1000f) * 60f);
//general state

View File

@ -9,7 +9,6 @@ import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.NetEvents;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.Entity;
import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf;
@ -98,9 +97,11 @@ public class Weapon extends Upgrade{
}
public void update(Player p, boolean left){
if(Timers.get(p, "reload"+left, reload)){
int t = left ? 1 : 2;
int t2 = !left ? 1 : 2;
if(p.timer.get(t, reload)){
if(roundrobin){
Timers.reset(p, "reload" + !left, reload/2f);
p.timer.reset(t2, reload/2f);
}
float ang = Angles.mouseAngle(p.x, p.y);
tr.trns(ang - 90, 3f * Mathf.sign(left), length);

View File

@ -3,7 +3,10 @@ package io.anuke.mindustry.ui.fragments;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.enemies.Enemy;
import io.anuke.mindustry.entities.enemies.EnemyTypes;
import io.anuke.mindustry.net.Net;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.scene.builders.button;
import io.anuke.ucore.scene.builders.label;
import io.anuke.ucore.scene.builders.table;
@ -12,6 +15,7 @@ import io.anuke.ucore.scene.ui.ScrollPane;
import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.util.Log;
import io.anuke.ucore.util.Log.LogHandler;
import io.anuke.ucore.util.Mathf;
import static io.anuke.mindustry.Vars.*;
@ -57,8 +61,19 @@ public class DebugFragment implements Fragment {
netClient.clearRecieved();
});
row();
new button("spawn", () -> {});
new button("spawn", () -> {
for(int i = 0; i < 30; i ++){
new Enemy(EnemyTypes.blast).set(player.x + Mathf.range(50f), player.y + Mathf.range(50f)).add();
}
});
row();
new button("time", () -> {
Timers.resetTime(10368000);
});
row();
new button("time2", () -> {
Timers.resetTime(0);
});
}}.end();
row();
@ -114,6 +129,8 @@ public class DebugFragment implements Fragment {
StringBuilder result = join(
"net.active: " + Net.active(),
"net.server: " + Net.server(),
"net.client: " + Net.client(),
"state: " + state.getState(),
Net.client() ?
"chat.open: " + ui.chatfrag.chatOpen() + "\n" +
"chat.messages: " + ui.chatfrag.getMessagesSize() + "\n" +
@ -122,6 +139,7 @@ public class DebugFragment implements Fragment {
"players: " + playerGroup.size(),
"enemies: " + enemyGroup.size(),
"tiles: " + tileGroup.size(),
"time: " + Timers.time(),
world.getCore() != null && world.getCore().entity != null ? "core.health: " + world.getCore().entity.health : "",
"core: " + world.getCore(),
"state.gameover: " + state.gameOver,

View File

@ -34,7 +34,7 @@ import static io.anuke.ucore.util.Log.*;
public class ServerControl extends Module {
private final CommandHandler handler = new CommandHandler("");
private ShuffleMode mode = ShuffleMode.both;
private ShuffleMode mode;
public ServerControl(){
Settings.defaults("shufflemode", "normal");

View File

@ -0,0 +1,95 @@
package io.anuke.mindustry.server.mapgen;
public class GenProperties {
public long seed;
public SpawnStyle spawns;
public MapStyle maps;
public OreStyle ores;
public RiverType riverType;
public RiverStyle rivers;
public TerrainStyle terrains;
public FoliageStyle foliage;
public EnvironmentStyle environment;
enum SpawnStyle{
/**spawn in a wide arc with branching paths*/
arc,
/**spawn in one big group*/
grouped,
/**surround player spawn*/
surround
}
enum MapStyle{
/**256x512*/
longY,
/**128x256*/
smallY,
/**128x128*/
small,
/**256x256*/
normal
}
enum OreStyle{
/**'vanilla' noise-distributed ores*/
normal,
/**ores hug the walls*/
nearWalls,
/**ores hug all liquid rivers*/
nearRivers,
/**large veins*/
largeVeins
}
enum RiverType{
lava,
water,
oil,
none
}
enum RiverStyle{
/**long thin river spanning entire map*/
longThin,
/**long river branching into many others*/
longBranch,
/**one long, thick river*/
longThick,
/**short, thick river that ends in a lake*/
shortLake
}
enum TerrainStyle{
/**bordered around by the normal material*/
normal,
/**everything is islands*/
waterIslands,
/**everything is islands: lava edition*/
lavaIslands
}
enum FoliageStyle{
patches,
veins,
blobs,
ridges
}
enum FoilageType{
grass,
sand,
darkStone,
ice,
}
enum EnvironmentStyle{
desert,
stoneDesert,
grassy,
dark,
darkStone,
stone,
icy,
}
}

View File

@ -0,0 +1,55 @@
package io.anuke.mindustry.server.mapgen;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Pixmap.Format;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.ColorMapper;
import io.anuke.mindustry.world.ColorMapper.BlockPair;
import io.anuke.ucore.util.Mathf;
public class MapImage {
public final Pixmap pixmap;
public final int width, height;
public MapImage(Pixmap pixmap){
this.pixmap = pixmap;
this.width = pixmap.getWidth();
this.height = pixmap.getHeight();
}
public MapImage(int width, int height){
this(new Pixmap(width, height, Format.RGBA8888));
}
public Block wall(int x, int y){
BlockPair pair = ColorMapper.get(pixmap.getPixel(x, y));
return pair.wall;
}
public Block floor(int x, int y){
BlockPair pair = ColorMapper.get(pixmap.getPixel(x, y));
return pair.floor;
}
public void set(int x, int y, Block block){
pixmap.drawPixel(x, y, ColorMapper.getColor(block));
}
public Block get(int x, int y){
BlockPair pair = ColorMapper.get(pixmap.getPixel(x, y));
return pair.dominant();
}
public boolean solid(int x, int y){
BlockPair pair = ColorMapper.get(pixmap.getPixel(x, y));
return pair.dominant().solid;
}
public boolean has(int x, int y){
return Mathf.inBounds(x, y, width, height);
}
public int pack(int x, int y){
return x + y*width;
}
}

View File

@ -0,0 +1,90 @@
package io.anuke.mindustry.server.mapgen;
import com.badlogic.gdx.ai.pfa.Connection;
import com.badlogic.gdx.ai.pfa.DefaultGraphPath;
import com.badlogic.gdx.ai.pfa.Heuristic;
import com.badlogic.gdx.ai.pfa.indexed.IndexedAStarPathFinder;
import com.badlogic.gdx.ai.pfa.indexed.IndexedGraph;
import com.badlogic.gdx.math.GridPoint2;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.world.Block;
import io.anuke.ucore.util.Geometry;
public class MapPathfinder {
private IndexedGraph<Integer> graph = new MapGraph();
private DefaultGraphPath<Integer> path = new DefaultGraphPath<>();
private IndexedAStarPathFinder<Integer> finder = new IndexedAStarPathFinder<>(graph);
private Heuristic<Integer> heuristic;
private MapImage image;
public Array<GridPoint2> find(int startx, int starty, int endx, int endy, Evaluator eval){
finder.searchNodePath(image.pack(startx, starty), image.pack(endx, endy),
(heuristic = (node, endNode) ->
eval.cost(image.get(node % image.width, node / image.width),
node % image.width,
node / image.width)), path);
Array<GridPoint2> arr = new Array<>();
for(int i : path.nodes){
arr.add(new GridPoint2(i % image.width, i / image.width));
}
return arr;
}
private class MapGraph extends DefaultGraphPath<Integer> implements IndexedGraph<Integer>{
private Array<Connection<Integer>> cons = new Array<>();
@Override
public int getIndex(Integer node) {
return node;
}
@Override
public int getNodeCount() {
return image.width * image.height;
}
@Override
public Array<Connection<Integer>> getConnections(Integer fromNode) {
int x = fromNode % image.width;
int y = fromNode / image.width;
cons.clear();
for(GridPoint2 p : Geometry.d4){
if(image.has(x + p.x, y + p.y)){
cons.add(new MapConnection(fromNode, image.pack(x + p.x, y + p.y)));
}
}
return cons;
}
}
private class MapConnection implements Connection<Integer>{
int from, to;
MapConnection(int from, int to){
this.from = from;
this.to = to;
}
@Override
public float getCost() {
return heuristic.estimate(from, to);
}
@Override
public Integer getFromNode() {
return from;
}
@Override
public Integer getToNode() {
return to;
}
}
interface Evaluator{
int cost(Block block, int x, int y);
}
}

View File

@ -0,0 +1,14 @@
package io.anuke.mindustry.server.mapgen;
import io.anuke.mindustry.world.Map;
import io.anuke.ucore.noise.RidgedPerlin;
import io.anuke.ucore.noise.Simplex;
public class ProcGen {
public RidgedPerlin rid = new RidgedPerlin(1, 1, 1);
public Simplex sim = new Simplex();
public Map generate(GenProperties props){
return null;
}
}