PvP game over condition and message
This commit is contained in:
BIN
core/assets-raw/sprites/blocks/mechs/alpha-mech-pad.png
Normal file
BIN
core/assets-raw/sprites/blocks/mechs/alpha-mech-pad.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 351 B |
@@ -114,7 +114,7 @@ text.hosting=[accent]Opening server...
|
|||||||
text.hosts.refresh=Refresh
|
text.hosts.refresh=Refresh
|
||||||
text.hosts.discovering=Discovering LAN games
|
text.hosts.discovering=Discovering LAN games
|
||||||
text.server.refreshing=Refreshing server
|
text.server.refreshing=Refreshing server
|
||||||
text.hosts.none=[lightgray]No LAN games found!
|
text.hosts.none=[lightgray]No local games found!
|
||||||
text.host.invalid=[scarlet]Can't connect to host.
|
text.host.invalid=[scarlet]Can't connect to host.
|
||||||
text.trace=Trace Player
|
text.trace=Trace Player
|
||||||
text.trace.playername=Player name: [accent]{0}
|
text.trace.playername=Player name: [accent]{0}
|
||||||
@@ -586,6 +586,7 @@ block.pneumatic-drill.name=Pneumatic Drill
|
|||||||
block.laser-drill.name=Laser Drill
|
block.laser-drill.name=Laser Drill
|
||||||
block.water-extractor.name=Water Extractor
|
block.water-extractor.name=Water Extractor
|
||||||
block.cultivator.name=Cultivator
|
block.cultivator.name=Cultivator
|
||||||
|
block.alpha-mech-pad.name=Alpha Mech Pad
|
||||||
block.dart-ship-pad.name=Dart Ship Pad
|
block.dart-ship-pad.name=Dart Ship Pad
|
||||||
block.delta-mech-pad.name=Delta Mech Pad
|
block.delta-mech-pad.name=Delta Mech Pad
|
||||||
block.javelin-ship-pad.name=Javelin Ship Pad
|
block.javelin-ship-pad.name=Javelin Ship Pad
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
Before Width: | Height: | Size: 344 KiB After Width: | Height: | Size: 602 KiB |
@@ -6,6 +6,7 @@ import io.anuke.mindustry.game.GameMode;
|
|||||||
import io.anuke.mindustry.type.ContentType;
|
import io.anuke.mindustry.type.ContentType;
|
||||||
import io.anuke.mindustry.type.ItemStack;
|
import io.anuke.mindustry.type.ItemStack;
|
||||||
import io.anuke.mindustry.type.Recipe;
|
import io.anuke.mindustry.type.Recipe;
|
||||||
|
import io.anuke.mindustry.type.Recipe.RecipeVisibility;
|
||||||
|
|
||||||
import static io.anuke.mindustry.type.Category.*;
|
import static io.anuke.mindustry.type.Category.*;
|
||||||
|
|
||||||
@@ -152,14 +153,15 @@ public class Recipes implements ContentList{
|
|||||||
//UNITS
|
//UNITS
|
||||||
|
|
||||||
//bodies
|
//bodies
|
||||||
new Recipe(units, UpgradeBlocks.dartPad, new ItemStack(Items.lead, 150), new ItemStack(Items.copper, 150), new ItemStack(Items.silicon, 200), new ItemStack(Items.titanium, 240)).setDesktop(); //dart is desktop only, because it's the starter mobile ship
|
new Recipe(units, UpgradeBlocks.dartPad, new ItemStack(Items.lead, 150), new ItemStack(Items.copper, 150), new ItemStack(Items.silicon, 200), new ItemStack(Items.titanium, 240)).setVisible(RecipeVisibility.desktopOnly);
|
||||||
new Recipe(units, UpgradeBlocks.tridentPad, new ItemStack(Items.lead, 250), new ItemStack(Items.copper, 250), new ItemStack(Items.silicon, 250), new ItemStack(Items.titanium, 300), new ItemStack(Items.plastanium, 200));
|
new Recipe(units, UpgradeBlocks.tridentPad, new ItemStack(Items.lead, 250), new ItemStack(Items.copper, 250), new ItemStack(Items.silicon, 250), new ItemStack(Items.titanium, 300), new ItemStack(Items.plastanium, 200));
|
||||||
new Recipe(units, UpgradeBlocks.javelinPad, new ItemStack(Items.lead, 350), new ItemStack(Items.silicon, 450), new ItemStack(Items.titanium, 500), new ItemStack(Items.plastanium, 400), new ItemStack(Items.phasematter, 200));
|
new Recipe(units, UpgradeBlocks.javelinPad, new ItemStack(Items.lead, 350), new ItemStack(Items.silicon, 450), new ItemStack(Items.titanium, 500), new ItemStack(Items.plastanium, 400), new ItemStack(Items.phasematter, 200));
|
||||||
new Recipe(units, UpgradeBlocks.glaivePad, new ItemStack(Items.lead, 450), new ItemStack(Items.silicon, 650), new ItemStack(Items.titanium, 700), new ItemStack(Items.plastanium, 600), new ItemStack(Items.surgealloy, 200));
|
new Recipe(units, UpgradeBlocks.glaivePad, new ItemStack(Items.lead, 450), new ItemStack(Items.silicon, 650), new ItemStack(Items.titanium, 700), new ItemStack(Items.plastanium, 600), new ItemStack(Items.surgealloy, 200));
|
||||||
|
|
||||||
new Recipe(units, UpgradeBlocks.tauPad, new ItemStack(Items.lead, 250), new ItemStack(Items.densealloy, 250), new ItemStack(Items.copper, 250), new ItemStack(Items.silicon, 250)).setDesktop();
|
new Recipe(units, UpgradeBlocks.alphaPad, new ItemStack(Items.lead, 200), new ItemStack(Items.densealloy, 100), new ItemStack(Items.copper, 150)).setVisible(RecipeVisibility.mobileOnly);
|
||||||
new Recipe(units, UpgradeBlocks.deltaPad, new ItemStack(Items.lead, 350), new ItemStack(Items.densealloy, 350), new ItemStack(Items.copper, 400), new ItemStack(Items.silicon, 450), new ItemStack(Items.thorium, 300)).setDesktop();
|
new Recipe(units, UpgradeBlocks.tauPad, new ItemStack(Items.lead, 250), new ItemStack(Items.densealloy, 250), new ItemStack(Items.copper, 250), new ItemStack(Items.silicon, 250));
|
||||||
new Recipe(units, UpgradeBlocks.omegaPad, new ItemStack(Items.lead, 450), new ItemStack(Items.densealloy, 550), new ItemStack(Items.silicon, 650), new ItemStack(Items.thorium, 600), new ItemStack(Items.surgealloy, 240)).setDesktop();
|
new Recipe(units, UpgradeBlocks.deltaPad, new ItemStack(Items.lead, 350), new ItemStack(Items.densealloy, 350), new ItemStack(Items.copper, 400), new ItemStack(Items.silicon, 450), new ItemStack(Items.thorium, 300));
|
||||||
|
new Recipe(units, UpgradeBlocks.omegaPad, new ItemStack(Items.lead, 450), new ItemStack(Items.densealloy, 550), new ItemStack(Items.silicon, 650), new ItemStack(Items.thorium, 600), new ItemStack(Items.surgealloy, 240));
|
||||||
|
|
||||||
//actual unit related stuff
|
//actual unit related stuff
|
||||||
new Recipe(units, UnitBlocks.spiritFactory, new ItemStack(Items.copper, 70), new ItemStack(Items.lead, 110), new ItemStack(Items.silicon, 130));
|
new Recipe(units, UnitBlocks.spiritFactory, new ItemStack(Items.copper, 70), new ItemStack(Items.lead, 110), new ItemStack(Items.silicon, 130));
|
||||||
|
|||||||
@@ -5,10 +5,16 @@ import io.anuke.mindustry.world.Block;
|
|||||||
import io.anuke.mindustry.world.blocks.units.MechPad;
|
import io.anuke.mindustry.world.blocks.units.MechPad;
|
||||||
|
|
||||||
public class UpgradeBlocks extends BlockList{
|
public class UpgradeBlocks extends BlockList{
|
||||||
public static Block deltaPad, tauPad, omegaPad, dartPad, javelinPad, tridentPad, glaivePad;
|
public static Block alphaPad, deltaPad, tauPad, omegaPad, dartPad, javelinPad, tridentPad, glaivePad;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load(){
|
public void load(){
|
||||||
|
alphaPad = new MechPad("alpha-mech-pad"){{
|
||||||
|
mech = Mechs.alpha;
|
||||||
|
size = 2;
|
||||||
|
powerCapacity = 50f;
|
||||||
|
}};
|
||||||
|
|
||||||
deltaPad = new MechPad("delta-mech-pad"){{
|
deltaPad = new MechPad("delta-mech-pad"){{
|
||||||
mech = Mechs.delta;
|
mech = Mechs.delta;
|
||||||
size = 2;
|
size = 2;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import com.badlogic.gdx.math.Vector2;
|
|||||||
import io.anuke.mindustry.content.fx.Fx;
|
import io.anuke.mindustry.content.fx.Fx;
|
||||||
import io.anuke.mindustry.core.GameState.State;
|
import io.anuke.mindustry.core.GameState.State;
|
||||||
import io.anuke.mindustry.entities.Player;
|
import io.anuke.mindustry.entities.Player;
|
||||||
|
import io.anuke.mindustry.entities.TileEntity;
|
||||||
import io.anuke.mindustry.entities.Unit;
|
import io.anuke.mindustry.entities.Unit;
|
||||||
import io.anuke.mindustry.entities.effect.GroundEffectEntity;
|
import io.anuke.mindustry.entities.effect.GroundEffectEntity;
|
||||||
import io.anuke.mindustry.entities.effect.GroundEffectEntity.GroundEffect;
|
import io.anuke.mindustry.entities.effect.GroundEffectEntity.GroundEffect;
|
||||||
@@ -143,7 +144,12 @@ public class Renderer extends RendererModule{
|
|||||||
Vector2 position = averagePosition();
|
Vector2 position = averagePosition();
|
||||||
|
|
||||||
if(players[0].isDead()){
|
if(players[0].isDead()){
|
||||||
smoothCamera(position.x + 0.0001f, position.y + 0.0001f, 0.08f);
|
TileEntity core = players[0].getClosestCore();
|
||||||
|
if(core != null){
|
||||||
|
smoothCamera(core.x, core.y, 0.08f);
|
||||||
|
}else{
|
||||||
|
smoothCamera(position.x + 0.0001f, position.y + 0.0001f, 0.08f);
|
||||||
|
}
|
||||||
}else if(!mobile){
|
}else if(!mobile){
|
||||||
setCamera(position.x + 0.0001f, position.y + 0.0001f);
|
setCamera(position.x + 0.0001f, position.y + 0.0001f);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -209,6 +209,7 @@ public class World extends Module{
|
|||||||
public void loadSector(Sector sector){
|
public void loadSector(Sector sector){
|
||||||
currentSector = sector;
|
currentSector = sector;
|
||||||
state.difficulty = sectors.getDifficulty(sector);
|
state.difficulty = sectors.getDifficulty(sector);
|
||||||
|
state.mode = sector.currentMission().getMode();
|
||||||
Timers.mark();
|
Timers.mark();
|
||||||
Timers.mark();
|
Timers.mark();
|
||||||
|
|
||||||
@@ -254,6 +255,8 @@ public class World extends Module{
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
endMapLoad();
|
||||||
|
|
||||||
if(!headless){
|
if(!headless){
|
||||||
if(state.teams.get(players[0].getTeam()).cores.size == 0){
|
if(state.teams.get(players[0].getTeam()).cores.size == 0){
|
||||||
ui.showError("$text.map.nospawn");
|
ui.showError("$text.map.nospawn");
|
||||||
@@ -275,7 +278,6 @@ public class World extends Module{
|
|||||||
|
|
||||||
if(invalidMap) threads.runDelay(() -> state.set(State.menu));
|
if(invalidMap) threads.runDelay(() -> state.set(State.menu));
|
||||||
|
|
||||||
endMapLoad();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void notifyChanged(Tile tile){
|
public void notifyChanged(Tile tile){
|
||||||
|
|||||||
@@ -573,7 +573,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Recipe.getByResult(block) != null && Recipe.getByResult(block).desktopOnly && mobile){
|
if(Recipe.getByResult(block) != null && !Recipe.getByResult(block).visibility.shown()){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import io.anuke.mindustry.world.blocks.Floor;
|
|||||||
import io.anuke.mindustry.world.blocks.storage.CoreBlock.CoreEntity;
|
import io.anuke.mindustry.world.blocks.storage.CoreBlock.CoreEntity;
|
||||||
import io.anuke.ucore.core.*;
|
import io.anuke.ucore.core.*;
|
||||||
import io.anuke.ucore.entities.EntityGroup;
|
import io.anuke.ucore.entities.EntityGroup;
|
||||||
|
import io.anuke.ucore.entities.EntityQuery;
|
||||||
import io.anuke.ucore.graphics.Draw;
|
import io.anuke.ucore.graphics.Draw;
|
||||||
import io.anuke.ucore.graphics.Hue;
|
import io.anuke.ucore.graphics.Hue;
|
||||||
import io.anuke.ucore.graphics.Lines;
|
import io.anuke.ucore.graphics.Lines;
|
||||||
@@ -47,6 +48,8 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
|||||||
private static final int timerShootRight = 1;
|
private static final int timerShootRight = 1;
|
||||||
private static final float liftoffBoost = 0.2f;
|
private static final float liftoffBoost = 0.2f;
|
||||||
|
|
||||||
|
private static final Rectangle rect = new Rectangle();
|
||||||
|
|
||||||
//region instance variables
|
//region instance variables
|
||||||
|
|
||||||
public float baseRotation;
|
public float baseRotation;
|
||||||
@@ -474,6 +477,21 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
|||||||
shootHeat = Mathf.lerpDelta(shootHeat, isShooting() ? 1f : 0f, 0.06f);
|
shootHeat = Mathf.lerpDelta(shootHeat, isShooting() ? 1f : 0f, 0.06f);
|
||||||
mech.updateAlt(this); //updated regardless
|
mech.updateAlt(this); //updated regardless
|
||||||
|
|
||||||
|
if(boostHeat > liftoffBoost + 0.1f){
|
||||||
|
achievedFlight = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(boostHeat <= liftoffBoost + 0.05f && achievedFlight){
|
||||||
|
if(tile != null){
|
||||||
|
if(mech.shake > 1f){
|
||||||
|
Effects.shake(mech.shake, mech.shake, this);
|
||||||
|
}
|
||||||
|
Effects.effect(UnitFx.unitLand, tile.floor().minimapColor, x, y, tile.floor().isLiquid ? 1f : 0.5f);
|
||||||
|
}
|
||||||
|
mech.onLand(this);
|
||||||
|
achievedFlight = false;
|
||||||
|
}
|
||||||
|
|
||||||
if(!isLocal){
|
if(!isLocal){
|
||||||
interpolate();
|
interpolate();
|
||||||
updateBuilding(this); //building happens even with non-locals
|
updateBuilding(this); //building happens even with non-locals
|
||||||
@@ -509,21 +527,6 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
|||||||
protected void updateMech(){
|
protected void updateMech(){
|
||||||
Tile tile = world.tileWorld(x, y);
|
Tile tile = world.tileWorld(x, y);
|
||||||
|
|
||||||
if(boostHeat > liftoffBoost + 0.1f){
|
|
||||||
achievedFlight = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(boostHeat <= liftoffBoost + 0.05f && achievedFlight){
|
|
||||||
if(tile != null){
|
|
||||||
if(mech.shake > 1f){
|
|
||||||
Effects.shake(mech.shake, mech.shake, this);
|
|
||||||
}
|
|
||||||
Effects.effect(UnitFx.unitLand, tile.floor().minimapColor, x, y, tile.floor().isLiquid ? 1f : 0.5f);
|
|
||||||
}
|
|
||||||
mech.onLand(this);
|
|
||||||
achievedFlight = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
isBoosting = Inputs.keyDown("dash") && !mech.flying;
|
isBoosting = Inputs.keyDown("dash") && !mech.flying;
|
||||||
|
|
||||||
//if player is in solid block
|
//if player is in solid block
|
||||||
@@ -583,7 +586,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
|||||||
}
|
}
|
||||||
float prex = x, prey = y;
|
float prex = x, prey = y;
|
||||||
updateVelocityStatus();
|
updateVelocityStatus();
|
||||||
moved = distanceTo(prex, prey) > 0.01f;
|
moved = distanceTo(prex, prey) > 0.001f;
|
||||||
}else{
|
}else{
|
||||||
velocity.setZero();
|
velocity.setZero();
|
||||||
x = Mathf.lerpDelta(x, getCarrier().getX(), 0.1f);
|
x = Mathf.lerpDelta(x, getCarrier().getX(), 0.1f);
|
||||||
@@ -641,26 +644,46 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
|||||||
moveTarget = null;
|
moveTarget = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
movement.set(targetX - x, targetY - y).limit(mech.speed);
|
if(getCarrier() != null){
|
||||||
|
velocity.setZero();
|
||||||
|
x = Mathf.lerpDelta(x, getCarrier().getX(), 0.1f);
|
||||||
|
y = Mathf.lerpDelta(y, getCarrier().getY(), 0.1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
movement.set(targetX - x, targetY - y).limit(isBoosting && !mech.flying ? mech.boostSpeed : mech.speed);
|
||||||
movement.setAngle(Mathf.slerp(movement.angle(), velocity.angle(), 0.05f));
|
movement.setAngle(Mathf.slerp(movement.angle(), velocity.angle(), 0.05f));
|
||||||
|
|
||||||
if(distanceTo(targetX, targetY) < attractDst){
|
if(distanceTo(targetX, targetY) < attractDst){
|
||||||
movement.setZero();
|
movement.setZero();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float expansion = 3f;
|
||||||
|
|
||||||
|
getHitbox(rect);
|
||||||
|
rect.x -= expansion;
|
||||||
|
rect.y -= expansion;
|
||||||
|
rect.width += expansion*2f;
|
||||||
|
rect.height += expansion*2f;
|
||||||
|
|
||||||
|
isBoosting = EntityQuery.collisions().overlapsTile(rect) || distanceTo(targetX, targetY) > 85f;
|
||||||
|
|
||||||
velocity.add(movement.scl(Timers.delta()));
|
velocity.add(movement.scl(Timers.delta()));
|
||||||
|
|
||||||
if(velocity.len() <= 0.2f){
|
if(velocity.len() <= 0.2f && mech.flying){
|
||||||
rotation += Mathf.sin(Timers.time() + id * 99, 10f, 1f);
|
rotation += Mathf.sin(Timers.time() + id * 99, 10f, 1f);
|
||||||
}else if(target == null){
|
}else if(target == null){
|
||||||
rotation = Mathf.slerpDelta(rotation, velocity.angle(), velocity.len() / 10f);
|
rotation = Mathf.slerpDelta(rotation, velocity.angle(), velocity.len() / 10f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float lx = x, ly = y;
|
||||||
updateVelocityStatus();
|
updateVelocityStatus();
|
||||||
|
moved = distanceTo(lx, ly) > 0.001f && !isCarried();
|
||||||
|
|
||||||
//hovering effect
|
if(mech.flying){
|
||||||
x += Mathf.sin(Timers.time() + id * 999, 25f, 0.08f);
|
//hovering effect
|
||||||
y += Mathf.cos(Timers.time() + id * 999, 25f, 0.08f);
|
x += Mathf.sin(Timers.time() + id * 999, 25f, 0.08f);
|
||||||
|
y += Mathf.cos(Timers.time() + id * 999, 25f, 0.08f);
|
||||||
|
}
|
||||||
|
|
||||||
//update shooting if not building, not mining and there's ammo left
|
//update shooting if not building, not mining and there's ammo left
|
||||||
if(!isBuilding() && getMineTile() == null){
|
if(!isBuilding() && getMineTile() == null){
|
||||||
|
|||||||
@@ -15,24 +15,21 @@ public enum GameMode{
|
|||||||
disableWaves = true;
|
disableWaves = true;
|
||||||
hidden = true;
|
hidden = true;
|
||||||
enemyCheat = true;
|
enemyCheat = true;
|
||||||
showPads = true;
|
|
||||||
}},
|
}},
|
||||||
victory{{
|
victory{{
|
||||||
disableWaves = true;
|
disableWaves = true;
|
||||||
hidden = true;
|
hidden = true;
|
||||||
enemyCheat = false;
|
enemyCheat = false;
|
||||||
showPads = true;
|
|
||||||
showMission = false;
|
showMission = false;
|
||||||
}},
|
}},
|
||||||
pvp{{
|
pvp{{
|
||||||
showPads = true;
|
|
||||||
disableWaves = true;
|
disableWaves = true;
|
||||||
isPvp = true;
|
isPvp = true;
|
||||||
enemyCoreBuildRadius = 600f;
|
enemyCoreBuildRadius = 600f;
|
||||||
respawnTime = 60 * 10;
|
respawnTime = 60 * 10;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
public boolean infiniteResources, disableWaveTimer, disableWaves, showMission = true, hidden, enemyCheat, isPvp, showPads;
|
public boolean infiniteResources, disableWaveTimer, disableWaves, showMission = true, hidden, enemyCheat, isPvp;
|
||||||
public float enemyCoreBuildRadius = 400f;
|
public float enemyCoreBuildRadius = 400f;
|
||||||
public float respawnTime = 60 * 4;
|
public float respawnTime = 60 * 4;
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ public class SectorPresets{
|
|||||||
//pad mission
|
//pad mission
|
||||||
add(new SectorPreset(0, -2,
|
add(new SectorPreset(0, -2,
|
||||||
Structs.array(
|
Structs.array(
|
||||||
Missions.blockRecipe(mobile ? UpgradeBlocks.tridentPad : UpgradeBlocks.deltaPad),
|
Missions.blockRecipe(mobile ? UpgradeBlocks.alphaPad : UpgradeBlocks.dartPad),
|
||||||
new MechMission(Mechs.delta),
|
new MechMission(Mechs.delta),
|
||||||
new WaveMission(15)
|
new WaveMission(15)
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -377,7 +377,7 @@ public class Sectors{
|
|||||||
|
|
||||||
//50% chance to get a wave mission
|
//50% chance to get a wave mission
|
||||||
if(Mathf.randomSeed(sector.getSeed() + 6) < 0.5 || (sector.width + sector.height) <= 3){
|
if(Mathf.randomSeed(sector.getSeed() + 6) < 0.5 || (sector.width + sector.height) <= 3){
|
||||||
sector.missions.add(new WaveMission(sector.difficulty*5 + Mathf.randomSeed(sector.getSeed(), 0, 3)*5));
|
sector.missions.add(new WaveMission(sector.difficulty*5 + Mathf.randomSeed(sector.getSeed(), 1, 4)*5));
|
||||||
}else{
|
}else{
|
||||||
sector.missions.add(new BattleMission());
|
sector.missions.add(new BattleMission());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,11 +26,9 @@ import io.anuke.mindustry.world.blocks.defense.turrets.Turret;
|
|||||||
import io.anuke.mindustry.world.blocks.power.NuclearReactor;
|
import io.anuke.mindustry.world.blocks.power.NuclearReactor;
|
||||||
import io.anuke.mindustry.world.blocks.power.PowerGenerator;
|
import io.anuke.mindustry.world.blocks.power.PowerGenerator;
|
||||||
import io.anuke.mindustry.world.blocks.power.SolarGenerator;
|
import io.anuke.mindustry.world.blocks.power.SolarGenerator;
|
||||||
import io.anuke.mindustry.world.blocks.production.Drill;
|
|
||||||
import io.anuke.mindustry.world.blocks.storage.CoreBlock;
|
import io.anuke.mindustry.world.blocks.storage.CoreBlock;
|
||||||
import io.anuke.mindustry.world.blocks.storage.StorageBlock;
|
import io.anuke.mindustry.world.blocks.storage.StorageBlock;
|
||||||
import io.anuke.mindustry.world.blocks.units.UnitFactory;
|
import io.anuke.mindustry.world.blocks.units.UnitFactory;
|
||||||
import io.anuke.mindustry.world.consumers.ConsumePower;
|
|
||||||
import io.anuke.ucore.function.BiFunction;
|
import io.anuke.ucore.function.BiFunction;
|
||||||
import io.anuke.ucore.function.IntPositionConsumer;
|
import io.anuke.ucore.function.IntPositionConsumer;
|
||||||
import io.anuke.ucore.function.TriFunction;
|
import io.anuke.ucore.function.TriFunction;
|
||||||
@@ -60,15 +58,13 @@ public class FortressGenerator{
|
|||||||
void gen(){
|
void gen(){
|
||||||
gen.setBlock(enemyX, enemyY, StorageBlocks.core, team);
|
gen.setBlock(enemyX, enemyY, StorageBlocks.core, team);
|
||||||
|
|
||||||
float difficultyScl = Mathf.clamp(gen.sector.difficulty / 20f + gen.random.range(1f/2f), 0f, 0.9999f);
|
float difficultyScl = Mathf.clamp(gen.sector.difficulty / 20f + gen.random.range(0.25f), 0f, 0.9999f);
|
||||||
|
float dscl2 = Mathf.clamp(0.5f + gen.sector.difficulty / 20f + gen.random.range(0.1f), 0f, 1.5f);
|
||||||
int coreDst = FortressGenerator.coreDst*Math.min(gen.sector.width, gen.sector.height);
|
int coreDst = FortressGenerator.coreDst*Math.min(gen.sector.width, gen.sector.height);
|
||||||
|
|
||||||
Array<Block> turrets = find(b -> b instanceof ItemTurret);
|
Array<Block> turrets = find(b -> b instanceof ItemTurret);
|
||||||
Array<Block> powerTurrets = find(b -> b instanceof PowerTurret);
|
Array<Block> powerTurrets = find(b -> b instanceof PowerTurret);
|
||||||
Array<Block> drills = find(b -> b instanceof Drill && !b.consumes.has(ConsumePower.class));
|
|
||||||
Array<Block> powerDrills = find(b -> b instanceof Drill && b.consumes.has(ConsumePower.class));
|
|
||||||
Array<Block> walls = find(b -> b instanceof Wall && !(b instanceof Door) && b.size == 1);
|
Array<Block> walls = find(b -> b instanceof Wall && !(b instanceof Door) && b.size == 1);
|
||||||
Array<Block> wallsLarge = find(b -> b instanceof Wall && !(b instanceof Door) && b.size == 2);
|
|
||||||
|
|
||||||
Block wall = walls.get((int)(difficultyScl * walls.size));
|
Block wall = walls.get((int)(difficultyScl * walls.size));
|
||||||
|
|
||||||
@@ -140,19 +136,19 @@ public class FortressGenerator{
|
|||||||
seeder.get(turret2, tile -> tile.block() instanceof PowerBlock && gen.random.chance(0.12 - turret2.size*0.02)),
|
seeder.get(turret2, tile -> tile.block() instanceof PowerBlock && gen.random.chance(0.12 - turret2.size*0.02)),
|
||||||
|
|
||||||
//shields
|
//shields
|
||||||
seeder.get(DefenseBlocks.forceProjector, tile -> tile.block() instanceof CoreBlock || tile.block() instanceof UnitFactory && gen.random.chance(0.08)),
|
seeder.get(DefenseBlocks.forceProjector, tile -> (tile.block() instanceof CoreBlock || tile.block() instanceof UnitFactory) && gen.random.chance(0.2 * dscl2)),
|
||||||
|
|
||||||
//unit pads (assorted)
|
//unit pads (assorted)
|
||||||
seeder.get(UnitBlocks.daggerFactory, tile -> tile.block() instanceof MendProjector || tile.block() instanceof ForceProjector && gen.random.chance(0.3)),
|
seeder.get(UnitBlocks.daggerFactory, tile -> (tile.block() instanceof MendProjector || tile.block() instanceof ForceProjector) && gen.random.chance(0.3 * dscl2)),
|
||||||
|
|
||||||
//unit pads (assorted)
|
//unit pads (assorted)
|
||||||
seeder.get(UnitBlocks.wraithFactory, tile -> tile.block() instanceof MendProjector || tile.block() instanceof ForceProjector && gen.random.chance(0.3)),
|
seeder.get(UnitBlocks.wraithFactory, tile -> (tile.block() instanceof MendProjector || tile.block() instanceof ForceProjector) && gen.random.chance(0.3 * dscl2)),
|
||||||
|
|
||||||
//unit pads (assorted)
|
//unit pads (assorted)
|
||||||
seeder.get(UnitBlocks.titanFactory, tile -> tile.block() instanceof MendProjector || tile.block() instanceof ForceProjector && gen.random.chance(0.23)),
|
seeder.get(UnitBlocks.titanFactory, tile -> (tile.block() instanceof MendProjector || tile.block() instanceof ForceProjector) && gen.random.chance(0.23 * dscl2)),
|
||||||
|
|
||||||
//unit pads (assorted)
|
//unit pads (assorted)
|
||||||
seeder.get(UnitBlocks.ghoulFactory, tile -> tile.block() instanceof MendProjector || tile.block() instanceof ForceProjector && gen.random.chance(0.23)),
|
seeder.get(UnitBlocks.ghoulFactory, tile -> (tile.block() instanceof MendProjector || tile.block() instanceof ForceProjector) && gen.random.chance(0.23 * dscl2)),
|
||||||
|
|
||||||
//vaults
|
//vaults
|
||||||
seeder.get(StorageBlocks.vault, tile -> (tile.block() instanceof CoreBlock || tile.block() instanceof ForceProjector) && gen.random.chance(0.4)),
|
seeder.get(StorageBlocks.vault, tile -> (tile.block() instanceof CoreBlock || tile.block() instanceof ForceProjector) && gen.random.chance(0.4)),
|
||||||
|
|||||||
@@ -137,8 +137,8 @@ public class Net{
|
|||||||
* Starts discovering servers on a different thread. Does not work with GWT.
|
* Starts discovering servers on a different thread. Does not work with GWT.
|
||||||
* Callback is run on the main libGDX thread.
|
* Callback is run on the main libGDX thread.
|
||||||
*/
|
*/
|
||||||
public static void discoverServers(Consumer<Array<Host>> cons){
|
public static void discoverServers(Consumer<Host> cons, Runnable done){
|
||||||
clientProvider.discover(cons);
|
clientProvider.discover(cons, done);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -374,8 +374,9 @@ public class Net{
|
|||||||
/**
|
/**
|
||||||
* Discover servers. This should run the callback regardless of whether any servers are found. Should not block.
|
* Discover servers. This should run the callback regardless of whether any servers are found. Should not block.
|
||||||
* Callback should be run on libGDX main thread.
|
* Callback should be run on libGDX main thread.
|
||||||
|
* @param done is the callback that should run after discovery.
|
||||||
*/
|
*/
|
||||||
void discover(Consumer<Array<Host>> callback);
|
void discover(Consumer<Host> callback, Runnable done);
|
||||||
|
|
||||||
/**Ping a host. If an error occured, failed() should be called with the exception.*/
|
/**Ping a host. If an error occured, failed() should be called with the exception.*/
|
||||||
void pingHost(String address, int port, Consumer<Host> valid, Consumer<Exception> failed);
|
void pingHost(String address, int port, Consumer<Host> valid, Consumer<Exception> failed);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
|||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
import com.badlogic.gdx.utils.ObjectMap;
|
import com.badlogic.gdx.utils.ObjectMap;
|
||||||
import com.badlogic.gdx.utils.OrderedMap;
|
import com.badlogic.gdx.utils.OrderedMap;
|
||||||
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.game.GameMode;
|
import io.anuke.mindustry.game.GameMode;
|
||||||
import io.anuke.mindustry.game.UnlockableContent;
|
import io.anuke.mindustry.game.UnlockableContent;
|
||||||
import io.anuke.mindustry.ui.ContentDisplay;
|
import io.anuke.mindustry.ui.ContentDisplay;
|
||||||
@@ -28,10 +29,9 @@ public class Recipe extends UnlockableContent{
|
|||||||
public final Category category;
|
public final Category category;
|
||||||
public final float cost;
|
public final float cost;
|
||||||
|
|
||||||
public boolean desktopOnly = false;
|
public RecipeVisibility visibility = RecipeVisibility.all;
|
||||||
//the only gamemode in which the recipe shows up
|
//the only gamemode in which the recipe shows up
|
||||||
public GameMode mode;
|
public GameMode mode;
|
||||||
public boolean isPad;
|
|
||||||
public boolean hidden;
|
public boolean hidden;
|
||||||
public boolean alwaysUnlocked;
|
public boolean alwaysUnlocked;
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ public class Recipe extends UnlockableContent{
|
|||||||
arr.clear();
|
arr.clear();
|
||||||
for(Recipe r : content.recipes()){
|
for(Recipe r : content.recipes()){
|
||||||
if(r.category == category && (control.unlocks.isUnlocked(r)) &&
|
if(r.category == category && (control.unlocks.isUnlocked(r)) &&
|
||||||
!((r.mode != null && r.mode != state.mode) || (r.desktopOnly && mobile) || (r.isPad && !state.mode.showPads))){
|
!((r.mode != null && r.mode != state.mode) || !r.visibility.shown())){
|
||||||
arr.add(r);
|
arr.add(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -89,13 +89,8 @@ public class Recipe extends UnlockableContent{
|
|||||||
return recipeMap.get(block);
|
return recipeMap.get(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Recipe setPad(){
|
public Recipe setVisible(RecipeVisibility visibility){
|
||||||
this.isPad = true;
|
this.visibility = visibility;
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Recipe setDesktop(){
|
|
||||||
desktopOnly = true;
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,7 +117,7 @@ public class Recipe extends UnlockableContent{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isHidden(){
|
public boolean isHidden(){
|
||||||
return (desktopOnly && mobile) || hidden;
|
return !visibility.shown() || hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -196,4 +191,21 @@ public class Recipe extends UnlockableContent{
|
|||||||
this.blockDependencies = dependencies;
|
this.blockDependencies = dependencies;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum RecipeVisibility{
|
||||||
|
mobileOnly(true, false),
|
||||||
|
desktopOnly(false, true),
|
||||||
|
all(true, true);
|
||||||
|
|
||||||
|
public final boolean mobile, desktop;
|
||||||
|
|
||||||
|
RecipeVisibility(boolean mobile, boolean desktop){
|
||||||
|
this.mobile = mobile;
|
||||||
|
this.desktop = desktop;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean shown(){
|
||||||
|
return (Vars.mobile && mobile) || (!Vars.mobile && desktop);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ public class JoinDialog extends FloatingDialog{
|
|||||||
Table local = new Table();
|
Table local = new Table();
|
||||||
Table remote = new Table();
|
Table remote = new Table();
|
||||||
Table hosts = new Table();
|
Table hosts = new Table();
|
||||||
|
int totalHosts;
|
||||||
|
|
||||||
public JoinDialog(){
|
public JoinDialog(){
|
||||||
super("$text.joingame");
|
super("$text.joingame");
|
||||||
@@ -185,15 +186,6 @@ public class JoinDialog extends FloatingDialog{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void refreshLocal(){
|
|
||||||
if(!Vars.gwt){
|
|
||||||
local.clear();
|
|
||||||
local.background("button");
|
|
||||||
local.label(() -> "[accent]" + Bundles.get("text.hosts.discovering") + Strings.animated(4, 10f, ".")).pad(10f);
|
|
||||||
Net.discoverServers(this::addLocalHosts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void setup(){
|
void setup(){
|
||||||
float w = targetWidth();
|
float w = targetWidth();
|
||||||
|
|
||||||
@@ -255,32 +247,50 @@ public class JoinDialog extends FloatingDialog{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void addLocalHosts(Array<Host> array){
|
void refreshLocal(){
|
||||||
float w = targetWidth();
|
if(!Vars.gwt){
|
||||||
|
totalHosts = 0;
|
||||||
|
|
||||||
local.clear();
|
local.clear();
|
||||||
|
local.background((Drawable)null);
|
||||||
|
local.table("button", t -> {
|
||||||
|
t.label(() -> "[accent]" + Bundles.get("text.hosts.discovering") + Strings.animated(4, 10f, ".")).pad(10f);
|
||||||
|
}).growX();
|
||||||
|
Net.discoverServers(this::addLocalHost, this::finishLocalHosts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(array.size == 0){
|
void finishLocalHosts(){
|
||||||
|
if(totalHosts == 0){
|
||||||
|
local.clear();
|
||||||
|
local.background("button");
|
||||||
local.add("$text.hosts.none").pad(10f);
|
local.add("$text.hosts.none").pad(10f);
|
||||||
local.add().growX();
|
local.add().growX();
|
||||||
local.addImageButton("icon-loading", 16 * 2f, this::refreshLocal).pad(-10f).padLeft(0).padTop(-6).size(70f, 74f);
|
local.addImageButton("icon-loading", 16 * 2f, this::refreshLocal).pad(-10f).padLeft(0).padTop(-6).size(70f, 74f);
|
||||||
}else{
|
}else{
|
||||||
for(Host a : array){
|
local.background((Drawable) null);
|
||||||
TextButton button = local.addButton("[accent]" + a.name, "clear", () -> connect(a.address, port))
|
|
||||||
.width(w).height(80f).pad(4f).get();
|
|
||||||
button.left();
|
|
||||||
button.row();
|
|
||||||
button.add("[lightgray]" + (a.players != 1 ? Bundles.format("text.players", a.players) :
|
|
||||||
Bundles.format("text.players.single", a.players)));
|
|
||||||
button.row();
|
|
||||||
button.add("[lightgray]" + a.address).pad(4).left();
|
|
||||||
|
|
||||||
local.row();
|
|
||||||
local.background((Drawable) null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addLocalHost(Host host){
|
||||||
|
if(totalHosts == 0){
|
||||||
|
local.clear();
|
||||||
|
}
|
||||||
|
totalHosts ++;
|
||||||
|
float w = targetWidth();
|
||||||
|
|
||||||
|
local.row();
|
||||||
|
|
||||||
|
TextButton button = local.addButton("[accent]" + host.name, "clear", () -> connect(host.address, port))
|
||||||
|
.width(w).height(80f).pad(4f).get();
|
||||||
|
button.left();
|
||||||
|
button.row();
|
||||||
|
button.add("[lightgray]" + (host.players != 1 ? Bundles.format("text.players", host.players) :
|
||||||
|
Bundles.format("text.players.single", host.players)));
|
||||||
|
button.row();
|
||||||
|
button.add("[lightgray]" + host.address).pad(4).left();
|
||||||
|
}
|
||||||
|
|
||||||
void connect(String ip, int port){
|
void connect(String ip, int port){
|
||||||
ui.loadfrag.show("$text.connecting");
|
ui.loadfrag.show("$text.connecting");
|
||||||
|
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ public class BlocksFragment extends Fragment{
|
|||||||
|
|
||||||
//add actual recipes
|
//add actual recipes
|
||||||
for(Recipe r : recipes){
|
for(Recipe r : recipes){
|
||||||
if((r.mode != null && r.mode != state.mode) || (r.desktopOnly && mobile) || (r.isPad && !state.mode.showPads)) continue;
|
if((r.mode != null && r.mode != state.mode) || !r.visibility.shown()) continue;
|
||||||
|
|
||||||
ImageButton image = new ImageButton(new TextureRegion(), "select");
|
ImageButton image = new ImageButton(new TextureRegion(), "select");
|
||||||
|
|
||||||
|
|||||||
@@ -429,10 +429,11 @@ public class Tile implements PosTrait, TargetTrait{
|
|||||||
entity.power = new PowerModule();
|
entity.power = new PowerModule();
|
||||||
entity.power.graph.add(this);
|
entity.power.graph.add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!world.isGenerating()){
|
if(!world.isGenerating()){
|
||||||
entity.updateProximity();
|
entity.updateProximity();
|
||||||
}
|
}
|
||||||
}else if(!(block instanceof BlockPart)){
|
}else if(!(block instanceof BlockPart) && !world.isGenerating()){
|
||||||
//since the entity won't update proximity for us, update proximity for all nearby tiles manually
|
//since the entity won't update proximity for us, update proximity for all nearby tiles manually
|
||||||
for(GridPoint2 p : Geometry.d4){
|
for(GridPoint2 p : Geometry.d4){
|
||||||
Tile tile = world.tile(x + p.x, y + p.y);
|
Tile tile = world.tile(x + p.x, y + p.y);
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import io.anuke.ucore.core.Timers;
|
|||||||
import io.anuke.ucore.graphics.Draw;
|
import io.anuke.ucore.graphics.Draw;
|
||||||
import io.anuke.ucore.graphics.Lines;
|
import io.anuke.ucore.graphics.Lines;
|
||||||
import io.anuke.ucore.util.EnumSet;
|
import io.anuke.ucore.util.EnumSet;
|
||||||
|
import io.anuke.ucore.util.Log;
|
||||||
import io.anuke.ucore.util.Mathf;
|
import io.anuke.ucore.util.Mathf;
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
@@ -83,7 +84,6 @@ public class CoreBlock extends StorageBlock{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onProximityUpdate(Tile tile) {
|
public void onProximityUpdate(Tile tile) {
|
||||||
//add cores
|
|
||||||
state.teams.get(tile.getTeam()).cores.add(tile);
|
state.teams.get(tile.getTeam()).cores.add(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -123,7 +123,6 @@ public class MechPad extends Block{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tapped(Tile tile, Player player){
|
public void tapped(Tile tile, Player player){
|
||||||
if(mobile && !mech.flying) return;
|
|
||||||
|
|
||||||
if(checkValidTap(tile, player)){
|
if(checkValidTap(tile, player)){
|
||||||
Call.onMechFactoryTap(player, tile);
|
Call.onMechFactoryTap(player, tile);
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ import java.io.DataOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public class UnitFactory extends Block{
|
public class UnitFactory extends Block{
|
||||||
protected float gracePeriodMultiplier = 2f;
|
protected float gracePeriodMultiplier = 15f;
|
||||||
protected float speedupTime = 60f * 60f * 20;
|
protected float speedupTime = 60f * 60f * 20;
|
||||||
protected float maxSpeedup = 2f;
|
protected float maxSpeedup = 2f;
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ package io.anuke.kryonet;
|
|||||||
|
|
||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
import com.badlogic.gdx.utils.ObjectMap;
|
|
||||||
import com.badlogic.gdx.utils.ObjectSet;
|
|
||||||
import com.esotericsoftware.kryonet.*;
|
import com.esotericsoftware.kryonet.*;
|
||||||
import com.esotericsoftware.minlog.Log;
|
import com.esotericsoftware.minlog.Log;
|
||||||
import io.anuke.mindustry.net.Host;
|
import io.anuke.mindustry.net.Host;
|
||||||
@@ -20,19 +18,17 @@ import net.jpountz.lz4.LZ4Factory;
|
|||||||
import net.jpountz.lz4.LZ4FastDecompressor;
|
import net.jpountz.lz4.LZ4FastDecompressor;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.DatagramPacket;
|
import java.net.*;
|
||||||
import java.net.DatagramSocket;
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.ClosedSelectorException;
|
import java.nio.channels.ClosedSelectorException;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
import static io.anuke.mindustry.net.Net.packetPoolLock;
|
import static io.anuke.mindustry.net.Net.packetPoolLock;
|
||||||
|
|
||||||
public class KryoClient implements ClientProvider{
|
public class KryoClient implements ClientProvider{
|
||||||
Client client;
|
Client client;
|
||||||
ObjectMap<InetAddress, Host> addresses = new ObjectMap<>();
|
Consumer<Host> lastCallback;
|
||||||
|
Array<InetAddress> foundAddresses = new Array<>();
|
||||||
ClientDiscoveryHandler handler;
|
ClientDiscoveryHandler handler;
|
||||||
LZ4FastDecompressor decompressor = LZ4Factory.fastestInstance().fastDecompressor();
|
LZ4FastDecompressor decompressor = LZ4Factory.fastestInstance().fastDecompressor();
|
||||||
|
|
||||||
@@ -48,8 +44,14 @@ public class KryoClient implements ClientProvider{
|
|||||||
@Override
|
@Override
|
||||||
public void onDiscoveredHost(DatagramPacket datagramPacket) {
|
public void onDiscoveredHost(DatagramPacket datagramPacket) {
|
||||||
ByteBuffer buffer = ByteBuffer.wrap(datagramPacket.getData());
|
ByteBuffer buffer = ByteBuffer.wrap(datagramPacket.getData());
|
||||||
Host address = NetworkIO.readServerData(datagramPacket.getAddress().getHostAddress(), buffer);
|
Host host = NetworkIO.readServerData(datagramPacket.getAddress().getHostAddress(), buffer);
|
||||||
addresses.put(datagramPacket.getAddress(), address);
|
for(InetAddress address : foundAddresses){
|
||||||
|
if(address.equals(datagramPacket.getAddress()) || (isLocal(address) && isLocal(datagramPacket.getAddress()))){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Gdx.app.postRunnable(() -> lastCallback.accept(host));
|
||||||
|
foundAddresses.add(datagramPacket.getAddress());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -108,6 +110,17 @@ public class KryoClient implements ClientProvider{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isLocal(InetAddress addr) {
|
||||||
|
if (addr.isAnyLocalAddress() || addr.isLoopbackAddress()) return true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
return NetworkInterface.getByInetAddress(addr) != null;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] decompressSnapshot(byte[] input, int size){
|
public byte[] decompressSnapshot(byte[] input, int size){
|
||||||
byte[] result = new byte[size];
|
byte[] result = new byte[size];
|
||||||
@@ -170,7 +183,7 @@ public class KryoClient implements ClientProvider{
|
|||||||
|
|
||||||
socket.setSoTimeout(2000);
|
socket.setSoTimeout(2000);
|
||||||
|
|
||||||
addresses.clear();
|
lastCallback = valid;
|
||||||
|
|
||||||
DatagramPacket packet = handler.onRequestNewDatagramPacket();
|
DatagramPacket packet = handler.onRequestNewDatagramPacket();
|
||||||
|
|
||||||
@@ -187,23 +200,12 @@ public class KryoClient implements ClientProvider{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void discover(Consumer<Array<Host>> callback){
|
public void discover(Consumer<Host> callback, Runnable done){
|
||||||
runAsync(() -> {
|
runAsync(() -> {
|
||||||
addresses.clear();
|
foundAddresses.clear();
|
||||||
List<InetAddress> list = client.discoverHosts(port, 3000);
|
lastCallback = callback;
|
||||||
ObjectSet<String> hostnames = new ObjectSet<>();
|
client.discoverHosts(port, 3000);
|
||||||
Array<Host> result = new Array<>();
|
Gdx.app.postRunnable(done);
|
||||||
|
|
||||||
for(InetAddress a : list){
|
|
||||||
if(!hostnames.contains(a.getHostName())) {
|
|
||||||
Host address = addresses.get(a);
|
|
||||||
if(address != null) result.add(address);
|
|
||||||
|
|
||||||
}
|
|
||||||
hostnames.add(a.getHostName());
|
|
||||||
}
|
|
||||||
|
|
||||||
Gdx.app.postRunnable(() -> callback.accept(result));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user