Removed shadow/world padding
This commit is contained in:
@@ -1,23 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module>
|
||||
<source path="io/anuke/mindustry"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.world.Tile"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.game.Content"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.type.ItemStack"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.maps.Maps"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.world.Map"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.game.SpawnGroup"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.core.GameState"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.io.SaveFileVersion"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.ucore.entities.impl.EffectEntity"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.entities.effect"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.entities.bullet.Bullet"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.game.Team"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.maps.missions.Mission"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.type.Item"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.world.meta.BlockBar"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.maps.generation.WorldGenerator"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.entities.StatusController"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.maps.Sector"/>
|
||||
<extend-configuration-property name="gdx.reflect.include" value="com.badlogic.gdx.utils.Predicate"/>
|
||||
</module>
|
||||
@@ -94,6 +94,7 @@ public class Vars{
|
||||
public static float controllerMin = 0.25f;
|
||||
public static float baseControllerSpeed = 11f;
|
||||
public static boolean snapCamera = true;
|
||||
|
||||
public static ContentLoader content;
|
||||
public static GameState state;
|
||||
public static ThreadHandler threads;
|
||||
@@ -162,6 +163,7 @@ public class Vars{
|
||||
});
|
||||
}
|
||||
|
||||
state = new GameState();
|
||||
threads = new ThreadHandler();
|
||||
|
||||
mobile = Gdx.app.getType() == ApplicationType.Android || Gdx.app.getType() == ApplicationType.iOS || testMobile;
|
||||
|
||||
@@ -71,6 +71,7 @@ public class BlockIndexer{
|
||||
flagMap[i][j] = new ObjectSet<>();
|
||||
}
|
||||
}
|
||||
|
||||
typeMap.clear();
|
||||
ores = null;
|
||||
|
||||
@@ -246,7 +247,7 @@ public class BlockIndexer{
|
||||
for(int x = quadrantX * structQuadrantSize; x < world.width() && x < (quadrantX + 1) * structQuadrantSize; x++){
|
||||
for(int y = quadrantY * structQuadrantSize; y < world.height() && y < (quadrantY + 1) * structQuadrantSize; y++){
|
||||
Tile result = world.tile(x, y);
|
||||
if(result.block().drops == null || !scanOres.contains(result.block().drops.item)) continue;
|
||||
if( result == null || result.block().drops == null || !scanOres.contains(result.block().drops.item)) continue;
|
||||
|
||||
itemSet.add(result.block().drops.item);
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public class Mechs implements ContentList{
|
||||
|
||||
alpha = new Mech("alpha-mech", false){
|
||||
int maxDrones = 3;
|
||||
float buildTime = 200f;
|
||||
float buildTime = 20f;
|
||||
|
||||
{
|
||||
drillPower = 1;
|
||||
@@ -53,14 +53,19 @@ public class Mechs implements ContentList{
|
||||
@Override
|
||||
public void updateAlt(Player player){
|
||||
|
||||
if(getDrones(player) < maxDrones && !TutorialSector.supressDrone() && player.timer.get(Player.timerAbility, buildTime)){
|
||||
if(!Net.client()) {
|
||||
AlphaDrone drone = (AlphaDrone) UnitTypes.alphaDrone.create(player.getTeam());
|
||||
drone.leader = player;
|
||||
drone.set(player.x, player.y);
|
||||
drone.add();
|
||||
if(player.isShooting && getDrones(player) < maxDrones && !TutorialSector.supressDrone()){
|
||||
player.timer.get(Player.timerAbility, buildTime);
|
||||
|
||||
if(player.timer.getTime(Player.timerAbility) > buildTime/2f){
|
||||
if(!Net.client()){
|
||||
AlphaDrone drone = (AlphaDrone) UnitTypes.alphaDrone.create(player.getTeam());
|
||||
drone.leader = player;
|
||||
drone.set(player.x, player.y);
|
||||
drone.add();
|
||||
|
||||
Effects.effect(UnitFx.unitLand, player);
|
||||
}
|
||||
}
|
||||
Effects.effect(UnitFx.unitLand, player);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -139,7 +139,7 @@ public class Blocks extends BlockList implements ContentList{
|
||||
}};
|
||||
|
||||
ice = new Floor("ice"){{
|
||||
dragMultiplier = 0.3f;
|
||||
dragMultiplier = 0.2f;
|
||||
speedMultiplier = 0.4f;
|
||||
minimapColor = Color.valueOf("b8eef8");
|
||||
hasOres = true;
|
||||
|
||||
@@ -30,7 +30,7 @@ public class LiquidBlocks extends BlockList implements ContentList{
|
||||
|
||||
thermalPump = new Pump("thermal-pump"){{
|
||||
shadow = "shadow-rounded-2";
|
||||
pumpAmount = 0.3f;
|
||||
pumpAmount = 0.275f;
|
||||
consumes.power(0.03f);
|
||||
liquidCapacity = 40f;
|
||||
hasPower = true;
|
||||
|
||||
@@ -20,9 +20,9 @@ public class PowerBlocks extends BlockList implements ContentList{
|
||||
}};
|
||||
|
||||
thermalGenerator = new LiquidHeatGenerator("thermal-generator"){{
|
||||
maxLiquidGenerate = 0.5f;
|
||||
maxLiquidGenerate = 4f;
|
||||
powerCapacity = 40f;
|
||||
powerPerLiquid = 1f;
|
||||
powerPerLiquid = 0.1f;
|
||||
generateEffect = BlockFx.redgeneratespark;
|
||||
size = 2;
|
||||
}};
|
||||
|
||||
@@ -179,12 +179,6 @@ public class Control extends Module{
|
||||
});
|
||||
|
||||
Events.on(WorldLoadEvent.class, event -> threads.runGraphics(() -> Events.fire(new WorldLoadGraphicsEvent())));
|
||||
|
||||
Events.on(TileChangeEvent.class, event -> {
|
||||
if(event.tile.getTeam() == players[0].getTeam() && Recipe.getByResult(event.tile.block()) != null){
|
||||
unlocks.handleContentUsed(Recipe.getByResult(event.tile.block()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void addPlayer(int index){
|
||||
@@ -278,7 +272,7 @@ public class Control extends Module{
|
||||
outer:
|
||||
for(int i = 0; i < content.recipes().size; i ++){
|
||||
Recipe recipe = content.recipes().get(i);
|
||||
if(!recipe.hidden && recipe.requirements != null){
|
||||
if(!recipe.isHidden() && recipe.requirements != null){
|
||||
for(ItemStack stack : recipe.requirements){
|
||||
if(!entity.items.has(stack.item, Math.min((int) (stack.amount * unlockResourceScaling), 2000))) continue outer;
|
||||
}
|
||||
|
||||
@@ -10,9 +10,11 @@ import io.anuke.mindustry.game.EventType.*;
|
||||
import io.anuke.mindustry.game.GameMode;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.game.Teams;
|
||||
import io.anuke.mindustry.game.UnlockableContent;
|
||||
import io.anuke.mindustry.gen.Call;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.mindustry.type.ItemStack;
|
||||
import io.anuke.mindustry.type.Recipe;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.ucore.core.Events;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
@@ -35,13 +37,31 @@ public class Logic extends Module{
|
||||
public boolean doUpdate = true;
|
||||
|
||||
public Logic(){
|
||||
state = new GameState();
|
||||
Events.on(TileChangeEvent.class, event -> {
|
||||
if(event.tile.getTeam() == defaultTeam && Recipe.getByResult(event.tile.block()) != null){
|
||||
handleContent(Recipe.getByResult(event.tile.block()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(){
|
||||
EntityQuery.init();
|
||||
EntityQuery.collisions().setCollider(tilesize, world::solid);
|
||||
EntityQuery.collisions().setCollider(tilesize, (x, y) -> {
|
||||
Tile tile = world.tile(x, y);
|
||||
return tile != null && tile.solid();
|
||||
});
|
||||
}
|
||||
|
||||
/**Handles the event of content being used by either the player or some block.*/
|
||||
public void handleContent(UnlockableContent content){
|
||||
if(world.getSector() != null){
|
||||
world.getSector().currentMission().onContentUsed(content);
|
||||
}
|
||||
|
||||
if(!headless){
|
||||
control.unlocks.unlockContent(content);
|
||||
}
|
||||
}
|
||||
|
||||
public void play(){
|
||||
@@ -142,7 +162,8 @@ public class Logic extends Module{
|
||||
|
||||
world.sectors.completeSector(world.getSector().x, world.getSector().y);
|
||||
world.sectors.save();
|
||||
if(!headless){
|
||||
|
||||
if(!headless && !Net.client()){
|
||||
ui.missions.show(world.getSector());
|
||||
}
|
||||
|
||||
@@ -151,7 +172,6 @@ public class Logic extends Module{
|
||||
|
||||
@Override
|
||||
public void update(){
|
||||
if(threads.isEnabled() && !threads.isOnThread()) return;
|
||||
|
||||
if(Vars.control != null){
|
||||
control.runUpdateLogic();
|
||||
@@ -159,15 +179,10 @@ public class Logic extends Module{
|
||||
|
||||
if(!state.is(State.menu)){
|
||||
|
||||
if(!Net.client() && !world.isInvalidMap()){
|
||||
updateSectors();
|
||||
checkGameOver();
|
||||
}
|
||||
|
||||
if(!state.isPaused()){
|
||||
Timers.update();
|
||||
|
||||
if(!state.mode.disableWaveTimer && !state.mode.disableWaves){
|
||||
if(!state.mode.disableWaveTimer && !state.mode.disableWaves && !state.gameOver){
|
||||
state.wavetime -= Timers.delta();
|
||||
}
|
||||
|
||||
@@ -216,10 +231,11 @@ public class Logic extends Module{
|
||||
|
||||
world.pathfinder.update();
|
||||
}
|
||||
}
|
||||
|
||||
if(threads.isEnabled()){
|
||||
netServer.update();
|
||||
if(!Net.client() && !world.isInvalidMap()){
|
||||
updateSectors();
|
||||
checkGameOver();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,14 +165,17 @@ public class NetClient extends Module{
|
||||
public static void onKick(KickReason reason){
|
||||
netClient.disconnectQuietly();
|
||||
state.set(State.menu);
|
||||
if(!reason.quiet){
|
||||
if(reason.extraText() != null){
|
||||
ui.showText(reason.toString(), reason.extraText());
|
||||
}else{
|
||||
ui.showText("$text.disconnect", reason.toString());
|
||||
|
||||
threads.runGraphics(() -> {
|
||||
if(!reason.quiet){
|
||||
if(reason.extraText() != null){
|
||||
ui.showText(reason.toString(), reason.extraText());
|
||||
}else{
|
||||
ui.showText("$text.disconnect", reason.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
ui.loadfrag.hide();
|
||||
ui.loadfrag.hide();
|
||||
});
|
||||
}
|
||||
|
||||
@Remote(variants = Variant.both)
|
||||
@@ -396,11 +399,11 @@ public class NetClient extends Module{
|
||||
quiet = true;
|
||||
}
|
||||
|
||||
public synchronized void addRemovedEntity(int id){
|
||||
public void addRemovedEntity(int id){
|
||||
removed.add(id);
|
||||
}
|
||||
|
||||
public synchronized boolean isEntityUsed(int id){
|
||||
public boolean isEntityUsed(int id){
|
||||
return removed.contains(id);
|
||||
}
|
||||
|
||||
@@ -411,11 +414,9 @@ public class NetClient extends Module{
|
||||
|
||||
BuildRequest[] requests;
|
||||
|
||||
synchronized(player.getPlaceQueue()){
|
||||
requests = new BuildRequest[player.getPlaceQueue().size];
|
||||
for(int i = 0; i < requests.length; i++){
|
||||
requests[i] = player.getPlaceQueue().get(i);
|
||||
}
|
||||
requests = new BuildRequest[player.getPlaceQueue().size];
|
||||
for(int i = 0; i < requests.length; i++){
|
||||
requests[i] = player.getPlaceQueue().get(i);
|
||||
}
|
||||
|
||||
Call.onClientShapshot(lastSent++, TimeUtils.millis(), player.x, player.y,
|
||||
|
||||
@@ -416,7 +416,6 @@ public class NetServer extends Module{
|
||||
}
|
||||
|
||||
public void update(){
|
||||
if(threads.isEnabled() && !threads.isOnThread()) return;
|
||||
|
||||
if(!headless && !closing && Net.server() && state.is(State.menu)){
|
||||
closing = true;
|
||||
|
||||
@@ -248,11 +248,12 @@ public class Renderer extends RendererModule{
|
||||
overlays.drawBottom();
|
||||
drawAndInterpolate(playerGroup, p -> true, Player::drawBuildRequests);
|
||||
|
||||
Shaders.shield.color.set(Palette.accent);
|
||||
Graphics.beginShaders(Shaders.shield);
|
||||
EntityDraw.draw(shieldGroup);
|
||||
EntityDraw.drawWith(shieldGroup, shield -> true, shield -> ((ShieldEntity)shield).drawOver());
|
||||
Draw.color(Palette.accent);
|
||||
Graphics.endShaders();
|
||||
Draw.color();
|
||||
|
||||
overlays.drawTop();
|
||||
|
||||
|
||||
@@ -1,80 +1,35 @@
|
||||
package io.anuke.mindustry.core;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.utils.Queue;
|
||||
import com.badlogic.gdx.utils.TimeUtils;
|
||||
import io.anuke.ucore.core.Settings;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.util.Log;
|
||||
import io.anuke.ucore.util.Threads;
|
||||
import io.anuke.ucore.util.Threads.ThreadInfoProvider;
|
||||
|
||||
import static io.anuke.mindustry.Vars.control;
|
||||
import static io.anuke.mindustry.Vars.logic;
|
||||
|
||||
public class ThreadHandler implements ThreadInfoProvider{
|
||||
private final Queue<Runnable> toRun = new Queue<>();
|
||||
private Thread thread, graphicsThread;
|
||||
private final Object updateLock = new Object();
|
||||
private float delta = 1f;
|
||||
private float smoothDelta = 1f;
|
||||
private long frame = 0, lastDeltaUpdate;
|
||||
private float framesSinceUpdate;
|
||||
private boolean enabled;
|
||||
private boolean rendered = true;
|
||||
private long lastFrameTime;
|
||||
|
||||
public ThreadHandler(){
|
||||
Threads.setThreadInfoProvider(this);
|
||||
graphicsThread = Thread.currentThread();
|
||||
|
||||
Timers.setDeltaProvider(() -> {
|
||||
float result = isOnThread() ? delta : Gdx.graphics.getDeltaTime() * 60f;
|
||||
return Math.min(Float.isNaN(result) ? 1f : result, 15f);
|
||||
float result = Gdx.graphics.getDeltaTime() * 60f;
|
||||
return Math.min(Float.isNaN(result) || Float.isInfinite(result) ? 1f : result, 15f);
|
||||
});
|
||||
}
|
||||
|
||||
public void run(Runnable r){
|
||||
if(enabled){
|
||||
synchronized(toRun){
|
||||
toRun.addLast(r);
|
||||
}
|
||||
}else{
|
||||
r.run();
|
||||
}
|
||||
r.run();
|
||||
}
|
||||
|
||||
public void runGraphics(Runnable r){
|
||||
if(enabled){
|
||||
Gdx.app.postRunnable(r);
|
||||
}else{
|
||||
r.run();
|
||||
}
|
||||
r.run();
|
||||
}
|
||||
|
||||
public void runDelay(Runnable r){
|
||||
if(enabled){
|
||||
synchronized(toRun){
|
||||
toRun.addLast(r);
|
||||
}
|
||||
}else{
|
||||
Gdx.app.postRunnable(r);
|
||||
}
|
||||
}
|
||||
|
||||
public int getTPS(){
|
||||
if(smoothDelta == 0f){
|
||||
return 60;
|
||||
}
|
||||
return (int) (60 / smoothDelta);
|
||||
Gdx.app.postRunnable(r);
|
||||
}
|
||||
|
||||
public long getFrameID(){
|
||||
return enabled ? frame : Gdx.graphics.getFrameId();
|
||||
}
|
||||
|
||||
public float getFramesSinceUpdate(){
|
||||
return framesSinceUpdate;
|
||||
return Gdx.graphics.getFrameId();
|
||||
}
|
||||
|
||||
public void handleBeginRender(){
|
||||
@@ -95,119 +50,16 @@ public class ThreadHandler implements ThreadInfoProvider{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!enabled) return;
|
||||
|
||||
framesSinceUpdate += Timers.delta();
|
||||
|
||||
synchronized(updateLock){
|
||||
rendered = true;
|
||||
updateLock.notify();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEnabled(){
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled){
|
||||
if(enabled){
|
||||
logic.doUpdate = false;
|
||||
Timers.runTask(2f, () -> {
|
||||
if(thread != null){
|
||||
thread.interrupt();
|
||||
thread = null;
|
||||
}
|
||||
|
||||
thread = new Thread(this::runLogic);
|
||||
thread.setDaemon(true);
|
||||
thread.setName("Update Thread");
|
||||
thread.start();
|
||||
Log.info("Starting logic thread.");
|
||||
|
||||
this.enabled = true;
|
||||
});
|
||||
}else{
|
||||
this.enabled = false;
|
||||
if(thread != null){
|
||||
thread.interrupt();
|
||||
thread = null;
|
||||
}
|
||||
Timers.runTask(2f, () -> {
|
||||
logic.doUpdate = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public boolean doInterpolate(){
|
||||
return enabled && Gdx.graphics.getFramesPerSecond() - getTPS() > 20 && getTPS() < 30;
|
||||
}
|
||||
|
||||
public boolean isOnThread(){
|
||||
return Thread.currentThread() == thread;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOnLogicThread() {
|
||||
return !enabled || Thread.currentThread() == thread;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOnGraphicsThread() {
|
||||
return !enabled || Thread.currentThread() == graphicsThread;
|
||||
return true;
|
||||
}
|
||||
|
||||
private void runLogic(){
|
||||
try{
|
||||
while(true){
|
||||
long time = TimeUtils.nanoTime();
|
||||
|
||||
while(true){
|
||||
Runnable r;
|
||||
synchronized(toRun){
|
||||
if(toRun.size > 0){
|
||||
r = toRun.removeFirst();
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
r.run();
|
||||
}
|
||||
|
||||
logic.doUpdate = true;
|
||||
logic.update();
|
||||
logic.doUpdate = false;
|
||||
|
||||
long elapsed = TimeUtils.nanosToMillis(TimeUtils.timeSinceNanos(time));
|
||||
long target = (long) ((1000) / 60f);
|
||||
|
||||
if(elapsed < target){
|
||||
Thread.sleep(target - elapsed);
|
||||
}
|
||||
|
||||
synchronized(updateLock){
|
||||
while(!rendered){
|
||||
updateLock.wait();
|
||||
}
|
||||
rendered = false;
|
||||
}
|
||||
|
||||
long actuallyElapsed = TimeUtils.nanosToMillis(TimeUtils.timeSinceNanos(time));
|
||||
delta = Math.max(actuallyElapsed, target) / 1000f * 60f;
|
||||
|
||||
if(TimeUtils.timeSinceMillis(lastDeltaUpdate) > 1000){
|
||||
lastDeltaUpdate = TimeUtils.millis();
|
||||
smoothDelta = delta;
|
||||
}
|
||||
|
||||
frame++;
|
||||
framesSinceUpdate = 0;
|
||||
}
|
||||
}catch(InterruptedException ex){
|
||||
Log.info("Stopping logic thread.");
|
||||
}catch(Throwable ex){
|
||||
control.setError(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import io.anuke.ucore.scene.ui.TextField.TextFieldFilter;
|
||||
import io.anuke.ucore.scene.ui.TooltipManager;
|
||||
import io.anuke.ucore.scene.ui.layout.Table;
|
||||
import io.anuke.ucore.scene.ui.layout.Unit;
|
||||
import io.anuke.ucore.util.Threads;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
import static io.anuke.ucore.scene.actions.Actions.*;
|
||||
@@ -154,6 +155,7 @@ public class UI extends SceneModule{
|
||||
load = new LoadDialog();
|
||||
levels = new CustomGameDialog();
|
||||
language = new LanguageDialog();
|
||||
unlocks = new UnlocksDialog();
|
||||
settings = new SettingsMenuDialog();
|
||||
host = new HostDialog();
|
||||
paused = new PausedDialog();
|
||||
@@ -164,7 +166,6 @@ public class UI extends SceneModule{
|
||||
traces = new TraceDialog();
|
||||
maps = new MapsDialog();
|
||||
localplayers = new LocalPlayerDialog();
|
||||
unlocks = new UnlocksDialog();
|
||||
content = new ContentInfoDialog();
|
||||
sectors = new SectorsDialog();
|
||||
missions = new MissionDialog();
|
||||
@@ -239,6 +240,8 @@ public class UI extends SceneModule{
|
||||
}
|
||||
|
||||
public void showInfoFade(String info){
|
||||
Threads.assertGraphics();
|
||||
|
||||
Table table = new Table();
|
||||
table.setFillParent(true);
|
||||
table.actions(Actions.fadeOut(7f, Interpolation.fade), Actions.removeActor());
|
||||
@@ -247,6 +250,8 @@ public class UI extends SceneModule{
|
||||
}
|
||||
|
||||
public void showInfo(String info){
|
||||
Threads.assertGraphics();
|
||||
|
||||
new Dialog("$text.info.title", "dialog"){{
|
||||
getCell(content()).growX();
|
||||
content().margin(15).add(info).width(400f).wrap().get().setAlignment(Align.center, Align.center);
|
||||
@@ -255,6 +260,8 @@ public class UI extends SceneModule{
|
||||
}
|
||||
|
||||
public void showInfo(String info, Runnable clicked){
|
||||
Threads.assertGraphics();
|
||||
|
||||
new Dialog("$text.info.title", "dialog"){{
|
||||
getCell(content()).growX();
|
||||
content().margin(15).add(info).width(400f).wrap().get().setAlignment(Align.center, Align.center);
|
||||
|
||||
@@ -70,7 +70,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
||||
public TargetTrait moveTarget;
|
||||
|
||||
private float walktime;
|
||||
private Queue<BuildRequest> placeQueue = new ThreadQueue<>();
|
||||
private Queue<BuildRequest> placeQueue = new Queue<>();
|
||||
private Tile mining;
|
||||
private CarriableTrait carrying;
|
||||
private Trail trail = new Trail(12);
|
||||
@@ -323,7 +323,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
||||
}
|
||||
|
||||
if(floor.isLiquid){
|
||||
Draw.tint(Color.WHITE, floor.liquidColor, Mathf.clamp(drownTime));
|
||||
Draw.tint(Color.WHITE, floor.liquidColor, drownTime);
|
||||
}else{
|
||||
Draw.tint(Color.WHITE);
|
||||
}
|
||||
@@ -421,55 +421,53 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
||||
|
||||
/**Draw all current build requests. Does not draw the beam effect, only the positions.*/
|
||||
public void drawBuildRequests(){
|
||||
synchronized(getPlaceQueue()){
|
||||
for(BuildRequest request : getPlaceQueue()){
|
||||
if(getCurrentRequest() == request) continue;
|
||||
for(BuildRequest request : getPlaceQueue()){
|
||||
if(getCurrentRequest() == request) continue;
|
||||
|
||||
if(request.breaking){
|
||||
Block block = world.tile(request.x, request.y).target().block();
|
||||
if(request.breaking){
|
||||
Block block = world.tile(request.x, request.y).target().block();
|
||||
|
||||
//draw removal request
|
||||
Lines.stroke(2f);
|
||||
//draw removal request
|
||||
Lines.stroke(2f);
|
||||
|
||||
Draw.color(Palette.removeBack);
|
||||
Draw.color(Palette.removeBack);
|
||||
|
||||
float rad = Mathf.absin(Timers.time(), 7f, 1f) + block.size * tilesize / 2f - 1;
|
||||
float rad = Mathf.absin(Timers.time(), 7f, 1f) + block.size * tilesize / 2f - 1;
|
||||
|
||||
Lines.square(
|
||||
request.x * tilesize + block.offset(),
|
||||
request.y * tilesize + block.offset() - 1,
|
||||
rad);
|
||||
Lines.square(
|
||||
request.x * tilesize + block.offset(),
|
||||
request.y * tilesize + block.offset() - 1,
|
||||
rad);
|
||||
|
||||
Draw.color(Palette.remove);
|
||||
Draw.color(Palette.remove);
|
||||
|
||||
Lines.square(
|
||||
request.x * tilesize + block.offset(),
|
||||
request.y * tilesize + block.offset(),
|
||||
rad);
|
||||
}else{
|
||||
//draw place request
|
||||
Lines.stroke(2f);
|
||||
Lines.square(
|
||||
request.x * tilesize + block.offset(),
|
||||
request.y * tilesize + block.offset(),
|
||||
rad);
|
||||
}else{
|
||||
//draw place request
|
||||
Lines.stroke(2f);
|
||||
|
||||
Draw.color(Palette.accentBack);
|
||||
Draw.color(Palette.accentBack);
|
||||
|
||||
float rad = Mathf.absin(Timers.time(), 7f, 1f) - 2f + request.recipe.result.size * tilesize / 2f;
|
||||
float rad = Mathf.absin(Timers.time(), 7f, 1f) - 2f + request.recipe.result.size * tilesize / 2f;
|
||||
|
||||
Lines.square(
|
||||
request.x * tilesize + request.recipe.result.offset(),
|
||||
request.y * tilesize + request.recipe.result.offset() - 1,
|
||||
rad);
|
||||
Lines.square(
|
||||
request.x * tilesize + request.recipe.result.offset(),
|
||||
request.y * tilesize + request.recipe.result.offset() - 1,
|
||||
rad);
|
||||
|
||||
Draw.color(Palette.accent);
|
||||
Draw.color(Palette.accent);
|
||||
|
||||
Lines.square(
|
||||
request.x * tilesize + request.recipe.result.offset(),
|
||||
request.y * tilesize + request.recipe.result.offset(),
|
||||
rad);
|
||||
}
|
||||
Lines.square(
|
||||
request.x * tilesize + request.recipe.result.offset(),
|
||||
request.y * tilesize + request.recipe.result.offset(),
|
||||
rad);
|
||||
}
|
||||
|
||||
Draw.reset();
|
||||
}
|
||||
|
||||
Draw.reset();
|
||||
}
|
||||
|
||||
//endregion
|
||||
@@ -512,14 +510,14 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
||||
achievedFlight = true;
|
||||
}
|
||||
|
||||
if(boostHeat <= liftoffBoost + 0.05f && achievedFlight){
|
||||
if(boostHeat <= liftoffBoost + 0.05f && achievedFlight && !mech.flying){
|
||||
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);
|
||||
}
|
||||
if(!mech.flying) mech.onLand(this);
|
||||
mech.onLand(this);
|
||||
achievedFlight = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -259,27 +259,25 @@ public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{
|
||||
|
||||
@Override
|
||||
public void update(){
|
||||
synchronized(Tile.tileSetLock){
|
||||
//TODO better smoke effect, this one is awful
|
||||
if(health != 0 && health < tile.block().health && !(tile.block() instanceof Wall) &&
|
||||
Mathf.chance(0.009f * Timers.delta() * (1f - health / tile.block().health))){
|
||||
//TODO better smoke effect, this one is awful
|
||||
if(health != 0 && health < tile.block().health && !(tile.block() instanceof Wall) &&
|
||||
Mathf.chance(0.009f * Timers.delta() * (1f - health / tile.block().health))){
|
||||
|
||||
Effects.effect(Fx.smoke, x + Mathf.range(4), y + Mathf.range(4));
|
||||
}
|
||||
Effects.effect(Fx.smoke, x + Mathf.range(4), y + Mathf.range(4));
|
||||
}
|
||||
|
||||
timeScaleDuration -= Timers.delta();
|
||||
if(timeScaleDuration <= 0f || !tile.block().canOverdrive){
|
||||
timeScale = 1f;
|
||||
}
|
||||
timeScaleDuration -= Timers.delta();
|
||||
if(timeScaleDuration <= 0f || !tile.block().canOverdrive){
|
||||
timeScale = 1f;
|
||||
}
|
||||
|
||||
if(health <= 0){
|
||||
onDeath();
|
||||
}
|
||||
Block previous = tile.block();
|
||||
tile.block().update(tile);
|
||||
if(tile.block() == previous && cons != null){
|
||||
cons.update(this);
|
||||
}
|
||||
if(health <= 0){
|
||||
onDeath();
|
||||
}
|
||||
Block previous = tile.block();
|
||||
tile.block().update(tile);
|
||||
if(tile.block() == previous && cons != null){
|
||||
cons.update(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -278,7 +278,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
||||
|
||||
drownTime = Mathf.clamp(drownTime);
|
||||
|
||||
if(drownTime >= 0.999f){
|
||||
if(drownTime >= 0.999f && !Net.client()){
|
||||
damage(health + 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -88,14 +88,13 @@ public interface BuilderTrait extends Entity{
|
||||
}
|
||||
|
||||
default void readBuilding(DataInput input, boolean applyChanges) throws IOException{
|
||||
synchronized(getPlaceQueue()){
|
||||
if(applyChanges) getPlaceQueue().clear();
|
||||
if(applyChanges) getPlaceQueue().clear();
|
||||
|
||||
byte type = input.readByte();
|
||||
if(type != -1){
|
||||
int position = input.readInt();
|
||||
float progress = input.readFloat();
|
||||
BuildRequest request;
|
||||
byte type = input.readByte();
|
||||
if(type != -1){
|
||||
int position = input.readInt();
|
||||
float progress = input.readFloat();
|
||||
BuildRequest request;
|
||||
|
||||
if(type == 1){ //remove
|
||||
request = new BuildRequest(Pos.x(position), Pos.y(position));
|
||||
@@ -105,13 +104,12 @@ public interface BuilderTrait extends Entity{
|
||||
request = new BuildRequest(Pos.x(position), Pos.y(position), rotation, content.recipe(recipe));
|
||||
}
|
||||
|
||||
request.progress = progress;
|
||||
request.progress = progress;
|
||||
|
||||
if(applyChanges){
|
||||
getPlaceQueue().addLast(request);
|
||||
}else if(isBuilding()){
|
||||
getCurrentRequest().progress = progress;
|
||||
}
|
||||
if(applyChanges){
|
||||
getPlaceQueue().addLast(request);
|
||||
}else if(isBuilding()){
|
||||
getCurrentRequest().progress = progress;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -126,13 +124,11 @@ public interface BuilderTrait extends Entity{
|
||||
* Otherwise, a new place request is added to the queue.
|
||||
*/
|
||||
default void replaceBuilding(int x, int y, int rotation, Recipe recipe){
|
||||
synchronized(getPlaceQueue()){
|
||||
for(BuildRequest request : getPlaceQueue()){
|
||||
if(request.x == x && request.y == y){
|
||||
clearBuilding();
|
||||
addBuildRequest(request);
|
||||
return;
|
||||
}
|
||||
for(BuildRequest request : getPlaceQueue()){
|
||||
if(request.x == x && request.y == y){
|
||||
clearBuilding();
|
||||
addBuildRequest(request);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,18 +142,16 @@ public interface BuilderTrait extends Entity{
|
||||
|
||||
/**Add another build requests to the tail of the queue, if it doesn't exist there yet.*/
|
||||
default void addBuildRequest(BuildRequest place){
|
||||
synchronized(getPlaceQueue()){
|
||||
for(BuildRequest request : getPlaceQueue()){
|
||||
if(request.x == place.x && request.y == place.y){
|
||||
return;
|
||||
}
|
||||
for(BuildRequest request : getPlaceQueue()){
|
||||
if(request.x == place.x && request.y == place.y){
|
||||
return;
|
||||
}
|
||||
Tile tile = world.tile(place.x, place.y);
|
||||
if(tile != null && tile.entity instanceof BuildEntity){
|
||||
place.progress = tile.<BuildEntity>entity().progress;
|
||||
}
|
||||
getPlaceQueue().addLast(place);
|
||||
}
|
||||
Tile tile = world.tile(place.x, place.y);
|
||||
if(tile != null && tile.entity instanceof BuildEntity){
|
||||
place.progress = tile.<BuildEntity>entity().progress;
|
||||
}
|
||||
getPlaceQueue().addLast(place);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -165,9 +159,7 @@ public interface BuilderTrait extends Entity{
|
||||
* May return null.
|
||||
*/
|
||||
default BuildRequest getCurrentRequest(){
|
||||
synchronized(getPlaceQueue()){
|
||||
return getPlaceQueue().size == 0 ? null : getPlaceQueue().first();
|
||||
}
|
||||
return getPlaceQueue().size == 0 ? null : getPlaceQueue().first();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -279,18 +271,15 @@ public interface BuilderTrait extends Entity{
|
||||
/**Draw placement effects for an entity. This includes mining*/
|
||||
default void drawBuilding(Unit unit){
|
||||
BuildRequest request;
|
||||
|
||||
synchronized(getPlaceQueue()){
|
||||
if(!isBuilding()){
|
||||
if(getMineTile() != null){
|
||||
drawMining(unit);
|
||||
}
|
||||
return;
|
||||
if(!isBuilding()){
|
||||
if(getMineTile() != null){
|
||||
drawMining(unit);
|
||||
}
|
||||
|
||||
request = getCurrentRequest();
|
||||
return;
|
||||
}
|
||||
|
||||
request = getCurrentRequest();
|
||||
|
||||
Tile tile = world.tile(request.x, request.y);
|
||||
|
||||
if(unit.distanceTo(tile) > placeDistance){
|
||||
|
||||
@@ -28,10 +28,7 @@ import io.anuke.ucore.core.Effects;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.entities.EntityGroup;
|
||||
import io.anuke.ucore.graphics.Draw;
|
||||
import io.anuke.ucore.util.Angles;
|
||||
import io.anuke.ucore.util.Geometry;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
import io.anuke.ucore.util.Timer;
|
||||
import io.anuke.ucore.util.*;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
@@ -316,8 +313,8 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
|
||||
if(target != null) behavior();
|
||||
|
||||
if(!isWave && !isFlying()){
|
||||
x = Mathf.clamp(x, 0, world.width() * tilesize);
|
||||
y = Mathf.clamp(y, 0, world.height() * tilesize);
|
||||
x = Mathf.clamp(x, tilesize/2f, world.width() * tilesize - tilesize/2f);
|
||||
y = Mathf.clamp(y, tilesize/2f, world.height() * tilesize - tilesize/2f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,21 @@
|
||||
package io.anuke.mindustry.entities.units.types;
|
||||
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import io.anuke.annotations.Annotations.Loc;
|
||||
import io.anuke.annotations.Annotations.Remote;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.content.fx.UnitFx;
|
||||
import io.anuke.mindustry.entities.Player;
|
||||
import io.anuke.mindustry.entities.Predict;
|
||||
import io.anuke.mindustry.entities.Unit;
|
||||
import io.anuke.mindustry.entities.traits.TargetTrait;
|
||||
import io.anuke.mindustry.entities.units.BaseUnit;
|
||||
import io.anuke.mindustry.entities.units.FlyingUnit;
|
||||
import io.anuke.mindustry.entities.units.UnitCommand;
|
||||
import io.anuke.mindustry.entities.units.UnitState;
|
||||
import io.anuke.mindustry.gen.Call;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.mindustry.type.AmmoType;
|
||||
import io.anuke.ucore.core.Effects;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
|
||||
import java.io.DataInput;
|
||||
@@ -22,7 +28,8 @@ import static io.anuke.mindustry.Vars.players;
|
||||
public class AlphaDrone extends FlyingUnit {
|
||||
static final float followDistance = 80f;
|
||||
|
||||
public Unit leader;
|
||||
public Player leader;
|
||||
|
||||
public final UnitState attack = new UnitState() {
|
||||
@Override
|
||||
public void update() {
|
||||
@@ -32,15 +39,18 @@ public class AlphaDrone extends FlyingUnit {
|
||||
}
|
||||
TargetTrait last = target;
|
||||
target = leader;
|
||||
|
||||
if(last == null){
|
||||
circle(50f);
|
||||
circle(leader.isShooting ? 60f : 0f);
|
||||
}
|
||||
|
||||
target = last;
|
||||
if(distanceTo(leader) < followDistance){
|
||||
targetClosest();
|
||||
}else{
|
||||
target = null;
|
||||
}
|
||||
|
||||
if(target != null){
|
||||
attack(50f);
|
||||
|
||||
@@ -51,9 +61,20 @@ public class AlphaDrone extends FlyingUnit {
|
||||
getWeapon().update(AlphaDrone.this, to.x, to.y);
|
||||
}
|
||||
}
|
||||
|
||||
if(!leader.isShooting && distanceTo(leader) < 8f){
|
||||
Call.onAlphaDroneFade(AlphaDrone.this);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Remote(called = Loc.server)
|
||||
public static void onAlphaDroneFade(BaseUnit drone){
|
||||
if(drone == null) return;
|
||||
drone.remove();
|
||||
Effects.effect(UnitFx.pickup, drone);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(UnitCommand command){
|
||||
//nuh
|
||||
|
||||
@@ -40,12 +40,11 @@ import static io.anuke.mindustry.Vars.unitGroups;
|
||||
import static io.anuke.mindustry.Vars.world;
|
||||
|
||||
public class Drone extends FlyingUnit implements BuilderTrait{
|
||||
protected static float discoverRange = 120f;
|
||||
protected static int timerRepairEffect = timerIndex++;
|
||||
|
||||
protected Item targetItem;
|
||||
protected Tile mineTile;
|
||||
protected Queue<BuildRequest> placeQueue = new ThreadQueue<>();
|
||||
protected Queue<BuildRequest> placeQueue = new Queue<>();
|
||||
protected boolean isBreaking;
|
||||
|
||||
public final UnitState
|
||||
@@ -250,14 +249,12 @@ public class Drone extends FlyingUnit implements BuilderTrait{
|
||||
for(BaseUnit unit : group.all()){
|
||||
if(unit instanceof Drone){
|
||||
Drone drone = (Drone)unit;
|
||||
synchronized(drone.getPlaceQueue()){
|
||||
if(drone.isBuilding()){
|
||||
//stop building if opposite building begins.
|
||||
BuildRequest req = drone.getCurrentRequest();
|
||||
if(req.breaking != event.breaking && req.x == event.tile.x && req.y == event.tile.y){
|
||||
drone.clearBuilding();
|
||||
drone.setState(drone.repair);
|
||||
}
|
||||
if(drone.isBuilding()){
|
||||
//stop building if opposite building begins.
|
||||
BuildRequest req = drone.getCurrentRequest();
|
||||
if(req.breaking != event.breaking && req.x == event.tile.x && req.y == event.tile.y){
|
||||
drone.clearBuilding();
|
||||
drone.setState(drone.repair);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -319,6 +316,10 @@ public class Drone extends FlyingUnit implements BuilderTrait{
|
||||
TileEntity entity = (TileEntity) target;
|
||||
entity.health += type.healSpeed * Timers.delta();
|
||||
entity.health = Mathf.clamp(entity.health, 0, entity.tile.block().health);
|
||||
|
||||
if(timer.get(timerRepairEffect, 30)){
|
||||
Effects.effect(BlockFx.healBlockFull, Palette.heal, entity.x, entity.y, entity.tile.block().size);
|
||||
}
|
||||
}
|
||||
|
||||
updateBuilding(this);
|
||||
|
||||
@@ -19,14 +19,6 @@ public class Unlocks{
|
||||
Settings.setSerializer(ContentType.class, (stream, t) -> stream.writeInt(t.ordinal()), stream -> ContentType.values()[stream.readInt()]);
|
||||
}
|
||||
|
||||
/**Handles the event of content being used by either the player or some block.*/
|
||||
public void handleContentUsed(UnlockableContent content){
|
||||
if(world.getSector() != null){
|
||||
world.getSector().currentMission().onContentUsed(content);
|
||||
}
|
||||
unlockContent(content);
|
||||
}
|
||||
|
||||
/** Returns whether or not this piece of content is unlocked yet.*/
|
||||
public boolean isUnlocked(UnlockableContent content){
|
||||
return rootSet().isUnlocked(content) || currentSet().isUnlocked(content);
|
||||
|
||||
@@ -106,32 +106,29 @@ public class BlockRenderer{
|
||||
for(int x = minx; x <= maxx; x++){
|
||||
for(int y = miny; y <= maxy; y++){
|
||||
boolean expanded = (Math.abs(x - avgx) > rangex || Math.abs(y - avgy) > rangey);
|
||||
Tile tile = world.rawTile(x, y);
|
||||
|
||||
synchronized(Tile.tileSetLock){
|
||||
Tile tile = world.rawTile(x, y);
|
||||
if(tile != null){
|
||||
Block block = tile.block();
|
||||
Team team = tile.getTeam();
|
||||
|
||||
if(tile != null){
|
||||
Block block = tile.block();
|
||||
Team team = tile.getTeam();
|
||||
if(!expanded && block != Blocks.air && world.isAccessible(x, y)){
|
||||
tile.block().drawShadow(tile);
|
||||
}
|
||||
|
||||
if(!expanded && block != Blocks.air && world.isAccessible(x, y)){
|
||||
tile.block().drawShadow(tile);
|
||||
if(block != Blocks.air){
|
||||
if(!expanded){
|
||||
addRequest(tile, Layer.block);
|
||||
teamChecks.add(team.ordinal());
|
||||
}
|
||||
|
||||
if(block != Blocks.air){
|
||||
if(!expanded){
|
||||
addRequest(tile, Layer.block);
|
||||
teamChecks.add(team.ordinal());
|
||||
if(block.expanded || !expanded){
|
||||
if(block.layer != null && block.isLayer(tile)){
|
||||
addRequest(tile, block.layer);
|
||||
}
|
||||
|
||||
if(block.expanded || !expanded){
|
||||
if(block.layer != null && block.isLayer(tile)){
|
||||
addRequest(tile, block.layer);
|
||||
}
|
||||
|
||||
if(block.layer2 != null && block.isLayer2(tile)){
|
||||
addRequest(tile, block.layer2);
|
||||
}
|
||||
if(block.layer2 != null && block.isLayer2(tile)){
|
||||
addRequest(tile, block.layer2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -171,16 +168,14 @@ public class BlockRenderer{
|
||||
layerBegins(req.layer);
|
||||
}
|
||||
|
||||
synchronized(Tile.tileSetLock){
|
||||
Block block = req.tile.block();
|
||||
Block block = req.tile.block();
|
||||
|
||||
if(req.layer == Layer.block){
|
||||
block.draw(req.tile);
|
||||
}else if(req.layer == block.layer){
|
||||
block.drawLayer(req.tile);
|
||||
}else if(req.layer == block.layer2){
|
||||
block.drawLayer2(req.tile);
|
||||
}
|
||||
if(req.layer == Layer.block){
|
||||
block.draw(req.tile);
|
||||
}else if(req.layer == block.layer){
|
||||
block.drawLayer(req.tile);
|
||||
}else if(req.layer == block.layer2){
|
||||
block.drawLayer2(req.tile);
|
||||
}
|
||||
|
||||
lastLayer = req.layer;
|
||||
@@ -199,17 +194,16 @@ public class BlockRenderer{
|
||||
BlockRequest req = requests.get(index);
|
||||
if(req.tile.getTeam() != team) continue;
|
||||
|
||||
synchronized(Tile.tileSetLock){
|
||||
Block block = req.tile.block();
|
||||
Block block = req.tile.block();
|
||||
|
||||
if(req.layer == Layer.block){
|
||||
block.draw(req.tile);
|
||||
}else if(req.layer == block.layer){
|
||||
block.drawLayer(req.tile);
|
||||
}else if(req.layer == block.layer2){
|
||||
block.drawLayer2(req.tile);
|
||||
}
|
||||
if(req.layer == Layer.block){
|
||||
block.draw(req.tile);
|
||||
}else if(req.layer == block.layer){
|
||||
block.drawLayer(req.tile);
|
||||
}else if(req.layer == block.layer2){
|
||||
block.drawLayer2(req.tile);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -74,20 +74,18 @@ public class MinimapRenderer implements Disposable{
|
||||
dx = Mathf.clamp(dx, sz, world.width() - sz);
|
||||
dy = Mathf.clamp(dy, sz, world.height() - sz);
|
||||
|
||||
synchronized(units){
|
||||
rect.set((dx - sz) * tilesize, (dy - sz) * tilesize, sz * 2 * tilesize, sz * 2 * tilesize);
|
||||
Graphics.beginClip(x, y, w, h);
|
||||
rect.set((dx - sz) * tilesize, (dy - sz) * tilesize, sz * 2 * tilesize, sz * 2 * tilesize);
|
||||
Graphics.beginClip(x, y, w, h);
|
||||
|
||||
for(Unit unit : units){
|
||||
float rx = (unit.x - rect.x) / rect.width * w, ry = (unit.y - rect.y) / rect.width * h;
|
||||
Draw.color(unit.getTeam().color);
|
||||
Draw.rect("white", x + rx, y + ry, w / (sz * 2), h / (sz * 2));
|
||||
}
|
||||
|
||||
Draw.color();
|
||||
|
||||
Graphics.endClip();
|
||||
for(Unit unit : units){
|
||||
float rx = (unit.x - rect.x) / rect.width * w, ry = (unit.y - rect.y) / rect.width * h;
|
||||
Draw.color(unit.getTeam().color);
|
||||
Draw.rect("white", x + rx, y + ry, w / (sz * 2), h / (sz * 2));
|
||||
}
|
||||
|
||||
Draw.color();
|
||||
|
||||
Graphics.endClip();
|
||||
}
|
||||
|
||||
public TextureRegion getRegion(){
|
||||
@@ -128,11 +126,9 @@ public class MinimapRenderer implements Disposable{
|
||||
dx = Mathf.clamp(dx, sz, world.width() - sz);
|
||||
dy = Mathf.clamp(dy, sz, world.height() - sz);
|
||||
|
||||
synchronized(units){
|
||||
rect.set((dx - sz) * tilesize, (dy - sz) * tilesize, sz * 2 * tilesize, sz * 2 * tilesize);
|
||||
units.clear();
|
||||
Units.getNearby(rect, units::add);
|
||||
}
|
||||
rect.set((dx - sz) * tilesize, (dy - sz) * tilesize, sz * 2 * tilesize, sz * 2 * tilesize);
|
||||
units.clear();
|
||||
Units.getNearby(rect, units::add);
|
||||
}
|
||||
|
||||
private int colorFor(Tile tile){
|
||||
|
||||
@@ -53,10 +53,7 @@ public class OverlayRenderer{
|
||||
//draw config selected block
|
||||
if(input.frag.config.isShown()){
|
||||
Tile tile = input.frag.config.getSelectedTile();
|
||||
|
||||
synchronized(Tile.tileSetLock){
|
||||
tile.block().drawConfigure(tile);
|
||||
}
|
||||
tile.block().drawConfigure(tile);
|
||||
}
|
||||
|
||||
input.drawTop();
|
||||
@@ -113,53 +110,52 @@ public class OverlayRenderer{
|
||||
Draw.reset();
|
||||
}
|
||||
|
||||
synchronized(Tile.tileSetLock){
|
||||
Block block = target.block();
|
||||
TileEntity entity = target.entity;
|
||||
Block block = target.block();
|
||||
TileEntity entity = target.entity;
|
||||
|
||||
if(entity != null){
|
||||
int[] values = {0, 0};
|
||||
boolean[] doDraw = {false};
|
||||
if(entity != null){
|
||||
int[] values = {0, 0};
|
||||
boolean[] doDraw = {false};
|
||||
|
||||
Runnable drawbars = () -> {
|
||||
for(BlockBar bar : block.bars.list()){
|
||||
float offset = Mathf.sign(bar.top) * (block.size / 2f * tilesize + 2f + (bar.top ? values[0] : values[1]));
|
||||
Runnable drawbars = () -> {
|
||||
for(BlockBar bar : block.bars.list()){
|
||||
float offset = Mathf.sign(bar.top) * (block.size / 2f * tilesize + 2f + (bar.top ? values[0] : values[1]));
|
||||
|
||||
float value = bar.value.get(target);
|
||||
float value = bar.value.get(target);
|
||||
|
||||
if(MathUtils.isEqual(value, -1f)) continue;
|
||||
if(MathUtils.isEqual(value, -1f)) continue;
|
||||
|
||||
if(doDraw[0]){
|
||||
drawBar(bar.type.color, target.drawx(), target.drawy() + offset, value);
|
||||
}
|
||||
|
||||
if(bar.top)
|
||||
values[0]++;
|
||||
else
|
||||
values[1]++;
|
||||
if(doDraw[0]){
|
||||
drawBar(bar.type.color, target.drawx(), target.drawy() + offset, value);
|
||||
}
|
||||
};
|
||||
|
||||
drawbars.run();
|
||||
|
||||
if(values[0] > 0){
|
||||
drawEncloser(target.drawx(), target.drawy() + block.size * tilesize / 2f + 2f, values[0]);
|
||||
if(bar.top)
|
||||
values[0]++;
|
||||
else
|
||||
values[1]++;
|
||||
}
|
||||
};
|
||||
|
||||
if(values[1] > 0){
|
||||
drawEncloser(target.drawx(), target.drawy() - block.size * tilesize / 2f - 2f - values[1], values[1]);
|
||||
}
|
||||
drawbars.run();
|
||||
|
||||
doDraw[0] = true;
|
||||
values[0] = 0;
|
||||
values[1] = 1;
|
||||
|
||||
drawbars.run();
|
||||
if(values[0] > 0){
|
||||
drawEncloser(target.drawx(), target.drawy() + block.size * tilesize / 2f + 2f, values[0]);
|
||||
}
|
||||
|
||||
if(values[1] > 0){
|
||||
drawEncloser(target.drawx(), target.drawy() - block.size * tilesize / 2f - 2f - values[1], values[1]);
|
||||
}
|
||||
|
||||
target.block().drawSelect(target);
|
||||
doDraw[0] = true;
|
||||
values[0] = 0;
|
||||
values[1] = 1;
|
||||
|
||||
drawbars.run();
|
||||
}
|
||||
|
||||
|
||||
target.block().drawSelect(target);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ package io.anuke.mindustry.graphics;
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||
import com.badlogic.gdx.utils.FloatArray;
|
||||
import io.anuke.ucore.core.Core;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.graphics.Draw;
|
||||
@@ -168,9 +167,7 @@ public class Shaders{
|
||||
}
|
||||
|
||||
public static class Shield extends Shader{
|
||||
public static final int MAX_HITS = 3 * 64;
|
||||
public Color color = new Color();
|
||||
public FloatArray hits = new FloatArray();
|
||||
//public Color color = new Color();
|
||||
|
||||
public Shield(){
|
||||
super("shield", "default");
|
||||
@@ -179,12 +176,9 @@ public class Shaders{
|
||||
@Override
|
||||
public void apply(){
|
||||
float scaling = Core.cameraScale / 4f / Core.camera.zoom;
|
||||
if(hits.size > 0){
|
||||
shader.setUniform3fv("u_hits[0]", hits.items, 0, Math.min(hits.size, MAX_HITS));
|
||||
shader.setUniformi("u_hitamount", Math.min(hits.size, MAX_HITS) / 3);
|
||||
}
|
||||
|
||||
shader.setUniformf("u_dp", Unit.dp.scl(1f));
|
||||
shader.setUniformf("u_color", color);
|
||||
//shader.setUniformf("u_color", color);
|
||||
shader.setUniformf("u_time", Timers.time() / Unit.dp.scl(1f));
|
||||
shader.setUniformf("u_scaling", scaling);
|
||||
shader.setUniformf("u_offset",
|
||||
|
||||
@@ -22,7 +22,7 @@ public class Trail{
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public synchronized void update(float curx, float cury){
|
||||
public void update(float curx, float cury){
|
||||
if(Vector2.dst(curx, cury, lastX, lastY) >= maxJump){
|
||||
points.clear();
|
||||
}
|
||||
@@ -39,11 +39,11 @@ public class Trail{
|
||||
lastY = cury;
|
||||
}
|
||||
|
||||
public synchronized void clear(){
|
||||
public void clear(){
|
||||
points.clear();
|
||||
}
|
||||
|
||||
public synchronized void draw(Color color, float stroke){
|
||||
public void draw(Color color, float stroke){
|
||||
Draw.color(color);
|
||||
|
||||
for(int i = 0; i < points.size - 2; i += 2){
|
||||
|
||||
@@ -430,7 +430,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
|
||||
@Override
|
||||
public boolean touchDown(int screenX, int screenY, int pointer, int button){
|
||||
if(state.is(State.menu)) return false;
|
||||
if(state.is(State.menu) || player.isDead()) return false;
|
||||
|
||||
//get tile on cursor
|
||||
Tile cursor = tileAt(screenX, screenY);
|
||||
@@ -519,7 +519,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
|
||||
@Override
|
||||
public boolean longPress(float x, float y){
|
||||
if(state.is(State.menu) || mode == none) return false;
|
||||
if(state.is(State.menu) || mode == none || player.isDead()) return false;
|
||||
|
||||
//get tile on cursor
|
||||
Tile cursor = tileAt(x, y);
|
||||
@@ -535,7 +535,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
|
||||
if(mode == breaking){
|
||||
Effects.effect(Fx.tapBlock, cursor.worldx(), cursor.worldy(), 1f);
|
||||
}else{
|
||||
}else if(recipe != null){
|
||||
Effects.effect(Fx.tapBlock, cursor.worldx() + recipe.result.offset(), cursor.worldy() + recipe.result.offset(), recipe.result.size);
|
||||
}
|
||||
|
||||
@@ -595,7 +595,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
|
||||
@Override
|
||||
public void update(){
|
||||
if(state.is(State.menu)){
|
||||
if(state.is(State.menu) || player.isDead()){
|
||||
selection.clear();
|
||||
removals.clear();
|
||||
mode = none;
|
||||
|
||||
@@ -47,23 +47,15 @@ public class MapIO{
|
||||
data.position(0, 0);
|
||||
|
||||
TileDataMarker marker = data.newDataMarker();
|
||||
Color color = new Color();
|
||||
|
||||
for(int y = 0; y < data.height(); y++){
|
||||
for(int x = 0; x < data.width(); x++){
|
||||
data.read(marker);
|
||||
byte elev = y >= data.height() - 1 ? 0 : data.read(x, y + 1, DataPosition.elevation);
|
||||
Block floor = content.block(marker.floor);
|
||||
Block wall = content.block(marker.wall);
|
||||
int wallc = ColorMapper.getBlockColor(wall);
|
||||
if(wallc == 0 && (wall.update || wall.solid || wall.breakable)) wallc = Team.all[marker.team].intColor;
|
||||
wallc = wallc == 0 ? ColorMapper.getBlockColor(floor) : wallc;
|
||||
if(marker.elevation > 0){
|
||||
float scaling = 1f + marker.elevation / 8f;
|
||||
color.set(wallc);
|
||||
color.mul(scaling, scaling, scaling, 1f);
|
||||
wallc = Color.rgba8888(color);
|
||||
}
|
||||
pixmap.drawPixel(x, pixmap.getHeight() - 1 - y, wallc);
|
||||
int color = ColorMapper.colorFor(floor, wall, Team.all[marker.team], marker.elevation + 1, elev > marker.elevation ? (byte)(1 << 6) : (byte)0);
|
||||
pixmap.drawPixel(x, pixmap.getHeight() - 1 - y, color);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package io.anuke.mindustry.maps;
|
||||
|
||||
import com.badlogic.gdx.utils.IntIntMap;
|
||||
import com.badlogic.gdx.utils.ObjectMap;
|
||||
import io.anuke.ucore.util.Bundles;
|
||||
|
||||
public class MapMeta{
|
||||
public final int version;
|
||||
@@ -18,15 +19,19 @@ public class MapMeta{
|
||||
}
|
||||
|
||||
public String author(){
|
||||
return tags.get("author", "unknown");
|
||||
return tag("author");
|
||||
}
|
||||
|
||||
public String description(){
|
||||
return tags.get("description", "unknown");
|
||||
return tag("description");
|
||||
}
|
||||
|
||||
public String name(){
|
||||
return tags.get("name", "unknown");
|
||||
return tag("name");
|
||||
}
|
||||
|
||||
public String tag(String name){
|
||||
return tags.containsKey(name) && !tags.get(name).trim().isEmpty() ? tags.get(name): Bundles.get("text.unknown");
|
||||
}
|
||||
|
||||
public boolean hasOreGen(){
|
||||
|
||||
@@ -23,10 +23,10 @@ public class SectorPresets{
|
||||
|
||||
public SectorPresets(){
|
||||
|
||||
//base tutorial mission (disabled)
|
||||
/*add(new SectorPreset(0, 0,
|
||||
//base tutorial mission
|
||||
add(new SectorPreset(0, 0,
|
||||
TutorialSector.getMissions(),
|
||||
Array.with(Items.copper, Items.coal, Items.lead)));*/
|
||||
Array.with(Items.copper, Items.coal, Items.lead)));
|
||||
|
||||
//command center mission
|
||||
add(new SectorPreset(0, 1,
|
||||
@@ -56,7 +56,8 @@ public class SectorPresets{
|
||||
Missions.blockRecipe(ProductionBlocks.waterExtractor),
|
||||
new ContentMission(Items.biomatter),
|
||||
Missions.blockRecipe(CraftingBlocks.biomatterCompressor),
|
||||
new ContentMission(Liquids.oil)
|
||||
new ContentMission(Liquids.oil),
|
||||
new BattleMission()
|
||||
),
|
||||
Array.with(Items.copper, Items.lead, Items.coal, Items.titanium)));
|
||||
}
|
||||
@@ -69,6 +70,8 @@ public class SectorPresets{
|
||||
return presets.get(x, y);
|
||||
}
|
||||
|
||||
public GridMap<SectorPreset> getPresets() { return presets; }
|
||||
|
||||
private void add(SectorPreset preset){
|
||||
presets.put(preset.x, preset.y, preset);
|
||||
orePresets.put(preset.x, preset.y, preset.ores);
|
||||
|
||||
@@ -41,7 +41,7 @@ public class Sectors{
|
||||
private final AsyncExecutor executor = new AsyncExecutor(6);
|
||||
|
||||
public void playSector(Sector sector){
|
||||
if(sector.hasSave() && SaveIO.breakingVersions.contains(sector.getSave().getBuild())){
|
||||
if(!headless && sector.hasSave() && SaveIO.breakingVersions.contains(sector.getSave().getBuild())){
|
||||
sector.getSave().delete();
|
||||
ui.showInfo("$text.save.old");
|
||||
}
|
||||
@@ -88,8 +88,6 @@ public class Sectors{
|
||||
|
||||
public Difficulty getDifficulty(Sector sector){
|
||||
if(sector.difficulty == 0){
|
||||
//yes, this means hard tutorial difficulty
|
||||
//(((have fun)))
|
||||
return Difficulty.hard;
|
||||
}else if(sector.difficulty < 4){
|
||||
return Difficulty.normal;
|
||||
@@ -158,7 +156,7 @@ public class Sectors{
|
||||
}
|
||||
grid.clear();
|
||||
|
||||
Array<Sector> out = Settings.getObject("sectors", Array.class, Array::new);
|
||||
Array<Sector> out = Settings.getObject("sector-data-2", Array.class, Array::new);
|
||||
|
||||
for(Sector sector : out){
|
||||
|
||||
@@ -187,7 +185,7 @@ public class Sectors{
|
||||
}
|
||||
}
|
||||
|
||||
Settings.putObject("sectors", out);
|
||||
Settings.putObject("sector-data-2", out);
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
@@ -229,7 +227,7 @@ public class Sectors{
|
||||
private void generate(Sector sector){
|
||||
|
||||
//50% chance to get a wave mission
|
||||
if(Mathf.randomSeed(sector.getSeed() + 6) < 0.5){
|
||||
if(Mathf.randomSeed(sector.getSeed() + 7) < 0.5){
|
||||
//recipe mission (maybe)
|
||||
addRecipeMission(sector, 3);
|
||||
sector.missions.add(new WaveMission(sector.difficulty*5 + Mathf.randomSeed(sector.getSeed(), 1, 4)*5));
|
||||
|
||||
@@ -2,12 +2,15 @@ package io.anuke.mindustry.maps;
|
||||
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import io.anuke.mindustry.content.Items;
|
||||
import io.anuke.mindustry.content.UnitTypes;
|
||||
import io.anuke.mindustry.content.blocks.*;
|
||||
import io.anuke.mindustry.maps.generation.Generation;
|
||||
import io.anuke.mindustry.maps.missions.*;
|
||||
import io.anuke.mindustry.content.blocks.CraftingBlocks;
|
||||
import io.anuke.mindustry.content.blocks.ProductionBlocks;
|
||||
import io.anuke.mindustry.content.blocks.StorageBlocks;
|
||||
import io.anuke.mindustry.content.blocks.UnitBlocks;
|
||||
import io.anuke.mindustry.maps.missions.BlockMission;
|
||||
import io.anuke.mindustry.maps.missions.ItemMission;
|
||||
import io.anuke.mindustry.maps.missions.Mission;
|
||||
import io.anuke.mindustry.maps.missions.WaveMission;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.ucore.util.Bundles;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
@@ -16,7 +19,7 @@ public class TutorialSector{
|
||||
private static int droneIndex;
|
||||
|
||||
public static Array<Mission> getMissions(){
|
||||
|
||||
/*
|
||||
Array<Mission> missions = Array.with(
|
||||
new ItemMission(Items.copper, 60).setMessage("$tutorial.begin"),
|
||||
|
||||
@@ -30,7 +33,8 @@ public class TutorialSector{
|
||||
//TODO fill turret with items mission
|
||||
//new BlockMission(ProductionBlocks.mechanicalDrill).setMessage("$tutorial.drillturret"),
|
||||
|
||||
new WaveMission(2).setMessage("$tutorial.waves"),
|
||||
// Create a wave mission which spawns the core at 60, 60 rather than in the center of the map
|
||||
new WaveMission(2, 60, 60).setMessage("$tutorial.waves"),
|
||||
|
||||
new ItemMission(Items.lead, 150).setMessage("$tutorial.lead"),
|
||||
new ItemMission(Items.copper, 250).setMessage("$tutorial.morecopper"),
|
||||
@@ -82,9 +86,21 @@ public class TutorialSector{
|
||||
droneIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
return missions;
|
||||
return Array.with(
|
||||
//intentionally unlocalized
|
||||
new ItemMission(Items.copper, 50).setMessage("An updated tutorial will return next build.\nFor now, you'll have to deal with... this."),
|
||||
|
||||
new BlockMission(ProductionBlocks.mechanicalDrill),
|
||||
|
||||
new ItemMission(Items.copper, 100),
|
||||
new ItemMission(Items.lead, 50),
|
||||
|
||||
new BlockMission(CraftingBlocks.smelter),
|
||||
new ItemMission(Items.densealloy, 10),
|
||||
new WaveMission(5)
|
||||
);
|
||||
}
|
||||
|
||||
public static boolean supressDrone(){
|
||||
|
||||
@@ -57,6 +57,7 @@ public class FortressGenerator{
|
||||
|
||||
void gen(){
|
||||
gen.setBlock(enemyX, enemyY, StorageBlocks.core, team);
|
||||
gen.random.nextBoolean();
|
||||
|
||||
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);
|
||||
|
||||
@@ -312,7 +312,7 @@ public class WorldGenerator{
|
||||
+ sim3.octaveNoise2D(detailed ? 12 : 9, 0.6, 1f / 1100f, x - 120, y);
|
||||
double lake = sim2.octaveNoise2D(1, 1, 1f / 110f, x, y);
|
||||
|
||||
elevation -= lake/3f;
|
||||
elevation -= Math.pow(lake + 0.15, 5);
|
||||
|
||||
int lerpDst = 20;
|
||||
lerpDst *= lerpDst;
|
||||
@@ -330,9 +330,9 @@ public class WorldGenerator{
|
||||
}
|
||||
}
|
||||
|
||||
if(elevation < 0.7 || lake > 0.96){
|
||||
if(elevation < 0.7){
|
||||
floor = Blocks.deepwater;
|
||||
}else if(elevation < 0.79 || lake > 0.948){
|
||||
}else if(elevation < 0.79){
|
||||
floor = Blocks.water;
|
||||
}else if(elevation < 0.85){
|
||||
floor = Blocks.sand;
|
||||
|
||||
@@ -12,8 +12,24 @@ import io.anuke.ucore.util.Bundles;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class BattleMission extends Mission{
|
||||
public class BattleMission extends MissionWithStartingCore{
|
||||
final int spacing = 30;
|
||||
public static final int defaultXCorePos = 50;
|
||||
public static final int defaultYCorePos = 50;
|
||||
|
||||
/** Creates a battle mission with the player core being at (@defaultXCorePos, @defaultYCorePos) */
|
||||
public BattleMission(){
|
||||
this(defaultXCorePos, defaultYCorePos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a wave survival with the player core being at a custom location.
|
||||
* @param xCorePos The X coordinate of the custom core position.
|
||||
* @param yCorePos The Y coordinate of the custom core position.
|
||||
*/
|
||||
public BattleMission(int xCorePos, int yCorePos){
|
||||
super(xCorePos, yCorePos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIcon(){
|
||||
@@ -37,7 +53,7 @@ public class BattleMission extends Mission{
|
||||
|
||||
@Override
|
||||
public void generate(Generation gen){
|
||||
generateCoreAt(gen, 50, 50, defaultTeam);
|
||||
generateCoreAtFirstSpawnPoint(gen, defaultTeam);
|
||||
|
||||
if(state.teams.get(defaultTeam).cores.size == 0){
|
||||
return;
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
package io.anuke.mindustry.maps.missions;
|
||||
|
||||
import io.anuke.mindustry.Vars;
|
||||
|
||||
/**A mission that just displays some text.*/
|
||||
public class MessageMission extends ActionMission{
|
||||
|
||||
public MessageMission(String text){
|
||||
super(() -> {
|
||||
if(!Vars.headless){
|
||||
Vars.ui.showInfo(text);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -100,10 +100,4 @@ public abstract class Mission{
|
||||
}
|
||||
|
||||
public void generate(Generation gen){}
|
||||
|
||||
public void generateCoreAt(Generation gen, int coreX, int coreY, Team team){
|
||||
gen.tiles[coreX][coreY].setBlock(StorageBlocks.core);
|
||||
gen.tiles[coreX][coreY].setTeam(team);
|
||||
state.teams.get(team).cores.add(gen.tiles[coreX][coreY]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
package io.anuke.mindustry.maps.missions;
|
||||
|
||||
import com.badlogic.gdx.math.GridPoint2;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import io.anuke.mindustry.content.blocks.StorageBlocks;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.maps.generation.Generation;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
|
||||
import static io.anuke.mindustry.Vars.state;
|
||||
|
||||
public abstract class MissionWithStartingCore extends Mission{
|
||||
/** Stores a custom starting location for the core, or null if the default calculation (map center) shall be used. */
|
||||
private final GridPoint2 customStartingPoint;
|
||||
|
||||
/** Default constructor. Missions created this way will have a player starting core in the center of the map. */
|
||||
MissionWithStartingCore(){
|
||||
this.customStartingPoint = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a mission with a core on a non-default location.
|
||||
* @param xCorePos The x coordinate of the custom core position.
|
||||
* @param yCorePos The y coordinate of the custom core position.
|
||||
*/
|
||||
MissionWithStartingCore(int xCorePos, int yCorePos){
|
||||
this.customStartingPoint = new GridPoint2(xCorePos, yCorePos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a player core based on generation parameters.
|
||||
* @param gen The generation parameters which provide the map size.
|
||||
* @param team The team to generate the core for.
|
||||
*/
|
||||
public void generateCoreAtFirstSpawnPoint(Generation gen, Team team){
|
||||
Array<GridPoint2> spawnPoints = getSpawnPoints(gen);
|
||||
if(spawnPoints == null || spawnPoints.size == 0){
|
||||
throw new IllegalArgumentException("A MissionWithStartingCore subclass did not provide a spawn point in getSpawnPoints(). However, at least one point must always be provided.");
|
||||
}
|
||||
|
||||
Tile startingCoreTile = gen.tiles[spawnPoints.first().x][spawnPoints.first().y];
|
||||
startingCoreTile.setBlock(StorageBlocks.core);
|
||||
startingCoreTile.setTeam(team);
|
||||
state.teams.get(team).cores.add(startingCoreTile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the spawn point in the center of the map or at a custom location which was provided through the constructor.
|
||||
* @param gen The generation parameters which provide the map size.
|
||||
* @return The center of the map or a custom location.
|
||||
* @implNote Must return an array with at least one entry.
|
||||
*/
|
||||
@Override
|
||||
public Array<GridPoint2> getSpawnPoints(Generation gen){
|
||||
if(this.customStartingPoint == null){
|
||||
return Array.with(new GridPoint2(gen.width / 2, gen.height / 2));
|
||||
}else{
|
||||
return Array.with(this.customStartingPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package io.anuke.mindustry.maps.missions;
|
||||
|
||||
import com.badlogic.gdx.math.GridPoint2;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.game.GameMode;
|
||||
@@ -9,16 +8,31 @@ import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.game.Waves;
|
||||
import io.anuke.mindustry.maps.Sector;
|
||||
import io.anuke.mindustry.maps.generation.Generation;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.ucore.util.Bundles;
|
||||
|
||||
import static io.anuke.mindustry.Vars.state;
|
||||
import static io.anuke.mindustry.Vars.waveTeam;
|
||||
import static io.anuke.mindustry.Vars.world;
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class WaveMission extends Mission{
|
||||
public class WaveMission extends MissionWithStartingCore{
|
||||
private final int target;
|
||||
|
||||
/**
|
||||
* Creates a wave survival mission with the player core being in the center of the map.
|
||||
* @param target The number of waves to be survived.
|
||||
*/
|
||||
public WaveMission(int target){
|
||||
super();
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a wave survival with the player core being at a custom location.
|
||||
* @param target The number of waves to be survived.
|
||||
* @param xCorePos The X coordinate of the custom core position.
|
||||
* @param yCorePos The Y coordinate of the custom core position.
|
||||
*/
|
||||
public WaveMission(int target, int xCorePos, int yCorePos){
|
||||
super(xCorePos, yCorePos);
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
@@ -29,8 +43,7 @@ public class WaveMission extends Mission{
|
||||
|
||||
@Override
|
||||
public void generate(Generation gen){
|
||||
int coreX = gen.width/2, coreY = gen.height/2;
|
||||
generateCoreAt(gen, coreX, coreY, Team.blue);
|
||||
generateCoreAtFirstSpawnPoint(gen, Team.blue);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -49,7 +62,7 @@ public class WaveMission extends Mission{
|
||||
public String displayString(){
|
||||
return state.wave > target ?
|
||||
Bundles.format(
|
||||
Vars.unitGroups[Vars.waveTeam.ordinal()].size() > 1 ?
|
||||
Vars.unitGroups[Vars.waveTeam.ordinal()].size() > 1 && !Net.client() ?
|
||||
"text.mission.wave.enemies" :
|
||||
"text.mission.wave.enemy", target, target, Vars.unitGroups[Vars.waveTeam.ordinal()].size()) :
|
||||
Bundles.format("text.mission.wave", state.wave, target, (int)(state.wavetime/60));
|
||||
@@ -71,9 +84,4 @@ public class WaveMission extends Mission{
|
||||
public boolean isComplete(){
|
||||
return state.wave > target && Vars.unitGroups[Vars.waveTeam.ordinal()].size() == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Array<GridPoint2> getSpawnPoints(Generation gen){
|
||||
return Array.with(new GridPoint2(gen.width/2, gen.height/2));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ public class Net{
|
||||
}
|
||||
|
||||
String error = t.getMessage() == null ? "" : t.getMessage().toLowerCase();
|
||||
String type = error.getClass().toString().toLowerCase();
|
||||
String type = t.getClass().toString().toLowerCase();
|
||||
|
||||
if(error.equals("mismatch")){
|
||||
error = Bundles.get("text.error.mismatch");
|
||||
|
||||
@@ -1,21 +1,17 @@
|
||||
package io.anuke.mindustry.ui;
|
||||
|
||||
import com.badlogic.gdx.graphics.Texture.TextureFilter;
|
||||
import com.badlogic.gdx.graphics.g2d.Batch;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||
import io.anuke.mindustry.graphics.Shaders;
|
||||
import io.anuke.ucore.core.Core;
|
||||
import io.anuke.ucore.core.Graphics;
|
||||
import io.anuke.ucore.graphics.Draw;
|
||||
import io.anuke.ucore.scene.Element;
|
||||
import io.anuke.ucore.scene.event.InputEvent;
|
||||
import io.anuke.ucore.scene.event.InputListener;
|
||||
import io.anuke.ucore.scene.style.TextureRegionDrawable;
|
||||
import io.anuke.ucore.scene.ui.Image;
|
||||
import io.anuke.ucore.scene.ui.layout.Table;
|
||||
|
||||
import static io.anuke.mindustry.Vars.renderer;
|
||||
import static io.anuke.mindustry.Vars.showFog;
|
||||
import static io.anuke.mindustry.Vars.world;
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class Minimap extends Table{
|
||||
|
||||
@@ -25,14 +21,15 @@ public class Minimap extends Table{
|
||||
margin(5);
|
||||
marginBottom(10);
|
||||
|
||||
Image image = new Image(new TextureRegionDrawable(new TextureRegion())){
|
||||
TextureRegion r = new TextureRegion();
|
||||
|
||||
Element elem = new Element(){
|
||||
@Override
|
||||
public void draw(Batch batch, float parentAlpha){
|
||||
public void draw(){
|
||||
if(renderer.minimap.getRegion() == null) return;
|
||||
|
||||
TextureRegionDrawable draw = (TextureRegionDrawable) getDrawable();
|
||||
draw.getRegion().setRegion(renderer.minimap.getRegion());
|
||||
super.draw(batch, parentAlpha);
|
||||
Draw.crect(renderer.minimap.getRegion(), x, y, width, height);
|
||||
|
||||
if(renderer.minimap.getTexture() != null){
|
||||
renderer.minimap.drawEntities(x, y, width, height);
|
||||
}
|
||||
@@ -40,7 +37,7 @@ public class Minimap extends Table{
|
||||
if(showFog){
|
||||
renderer.fog.getTexture().setFilter(TextureFilter.Nearest, TextureFilter.Nearest);
|
||||
|
||||
TextureRegion r = draw.getRegion();
|
||||
r.setRegion(renderer.minimap.getRegion());
|
||||
float pad = renderer.fog.getPadding();
|
||||
|
||||
float px = r.getU() * world.width() + pad;
|
||||
@@ -55,7 +52,7 @@ public class Minimap extends Table{
|
||||
r.setV2(1f - py2 / (world.height() + pad*2f));
|
||||
|
||||
Graphics.shader(Shaders.fog);
|
||||
super.draw(batch, parentAlpha);
|
||||
Draw.crect(r, x, y, width, height);
|
||||
Graphics.shader();
|
||||
|
||||
renderer.fog.getTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear);
|
||||
@@ -70,7 +67,7 @@ public class Minimap extends Table{
|
||||
}
|
||||
});
|
||||
|
||||
image.update(() -> {
|
||||
elem.update(() -> {
|
||||
|
||||
Element e = Core.scene.hit(Graphics.mouse().x, Graphics.mouse().y, true);
|
||||
if(e != null && e.isDescendantOf(this)){
|
||||
@@ -79,6 +76,7 @@ public class Minimap extends Table{
|
||||
Core.scene.setScrollFocus(null);
|
||||
}
|
||||
});
|
||||
add(image).size(140f, 140f);
|
||||
|
||||
add(elem).size(140f, 140f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,6 +57,9 @@ public class PausedDialog extends FloatingDialog{
|
||||
hide();
|
||||
});
|
||||
|
||||
content().row();
|
||||
content().addButton("$text.unlocks", ui.unlocks::show);
|
||||
|
||||
content().row();
|
||||
content().addButton("$text.settings", ui.settings::show);
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ public class SectorsDialog extends FloatingDialog{
|
||||
margin(0);
|
||||
getTitleTable().clear();
|
||||
clear();
|
||||
stack(content(), buttons(), container).grow();
|
||||
stack(content(), container, buttons()).grow();
|
||||
|
||||
shown(this::setup);
|
||||
}
|
||||
@@ -128,7 +128,7 @@ public class SectorsDialog extends FloatingDialog{
|
||||
class SectorView extends Element{
|
||||
float lastX, lastY;
|
||||
boolean clicked = false;
|
||||
float panX = 0, panY = -sectorSize/2f;
|
||||
float panX = sectorSize/2f, panY = sectorSize/2f;
|
||||
|
||||
SectorView(){
|
||||
addListener(new InputListener(){
|
||||
|
||||
@@ -130,13 +130,16 @@ public class SettingsMenuDialog extends SettingsDialog{
|
||||
sound.volumePrefs();
|
||||
|
||||
game.screenshakePref();
|
||||
//game.checkPref("smoothcam", true);
|
||||
game.checkPref("effects", true);
|
||||
if(mobile){
|
||||
game.checkPref("autotarget", true);
|
||||
}
|
||||
//game.sliderPref("sensitivity", 100, 10, 300, i -> i + "%");
|
||||
game.sliderPref("saveinterval", 60, 10, 5 * 120, i -> Bundles.format("setting.seconds", i));
|
||||
game.sliderPref("saveinterval", 120, 10, 5 * 120, i -> Bundles.format("setting.seconds", i));
|
||||
|
||||
if(!mobile){
|
||||
game.checkPref("crashreport", true);
|
||||
}
|
||||
|
||||
game.pref(new Setting(){
|
||||
@Override
|
||||
public void add(SettingsTable table){
|
||||
@@ -187,12 +190,6 @@ public class SettingsMenuDialog extends SettingsDialog{
|
||||
});
|
||||
|
||||
graphics.sliderPref("fpscap", 125, 5, 125, 5, s -> (s > 120 ? Bundles.get("setting.fpscap.none") : Bundles.format("setting.fpscap.text", s)));
|
||||
graphics.checkPref("multithread", mobile, threads::setEnabled);
|
||||
|
||||
if(Settings.getBool("multithread")){
|
||||
threads.setEnabled(true);
|
||||
}
|
||||
|
||||
|
||||
if(!mobile){
|
||||
graphics.checkPref("vsync", true, b -> Gdx.graphics.setVSync(b));
|
||||
|
||||
@@ -107,7 +107,7 @@ public class HudFragment extends Fragment{
|
||||
|
||||
Stack stack = new Stack();
|
||||
TextButton waves = new TextButton("");
|
||||
Table btable = new Table().margin(14);
|
||||
Table btable = new Table().margin(0);
|
||||
|
||||
stack.add(waves);
|
||||
stack.add(btable);
|
||||
@@ -126,7 +126,6 @@ public class HudFragment extends Fragment{
|
||||
IntFormat tps = new IntFormat("text.tps");
|
||||
IntFormat ping = new IntFormat("text.ping");
|
||||
t.label(() -> fps.get(Gdx.graphics.getFramesPerSecond())).padRight(10);
|
||||
t.label(() -> tps.get(threads.getTPS())).visible(() -> threads.isEnabled());
|
||||
t.row();
|
||||
if(Net.hasClient()){
|
||||
t.label(() -> ping.get(Net.getPing())).visible(Net::client).colspan(2);
|
||||
@@ -375,7 +374,7 @@ public class HudFragment extends Fragment{
|
||||
(!state.mode.disableWaveTimer ?
|
||||
Bundles.format("text.wave.waiting", (int)(state.wavetime/60)) :
|
||||
Bundles.get("text.waiting"))) :
|
||||
Bundles.format("text.mission.display", world.getSector().currentMission().displayString())).growX();
|
||||
Bundles.format("text.mission.display", world.getSector().currentMission().displayString())).growX().pad(8f);
|
||||
|
||||
table.clicked(() -> {
|
||||
if(world.getSector() != null && world.getSector().currentMission().hasMessage()){
|
||||
|
||||
@@ -230,7 +230,7 @@ public class Block extends BaseBlock {
|
||||
/**Call when some content is produced. This unlocks the content if it is applicable.*/
|
||||
public void useContent(Tile tile, UnlockableContent content){
|
||||
if(!headless && tile.getTeam() == players[0].getTeam()){
|
||||
control.unlocks.handleContentUsed(content);
|
||||
logic.handleContent(content);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,11 +14,7 @@ public class ColorMapper implements ContentList{
|
||||
private static ObjectIntMap<Block> colorMap = new ObjectIntMap<>();
|
||||
private static ThreadLocal<Color> tmpColors = new ThreadLocal<>();
|
||||
|
||||
public static Block getByColor(int color){
|
||||
return blockMap.get(color);
|
||||
}
|
||||
|
||||
public static int getBlockColor(Block block){
|
||||
private static int getBlockColor(Block block){
|
||||
return colorMap.get(block, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
|
||||
public class Tile implements PosTrait, TargetTrait{
|
||||
public static final Object tileSetLock = new Object();
|
||||
/**
|
||||
* The coordinates of the core tile this is linked to, in the form of two bytes packed into one.
|
||||
* This is relative to the block it is linked to; negate coords to find the link.
|
||||
@@ -130,8 +129,9 @@ public class Tile implements PosTrait, TargetTrait{
|
||||
return wall;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Team getTeam(){
|
||||
return Team.all[team];
|
||||
return Team.all[target().team];
|
||||
}
|
||||
|
||||
public void setTeam(Team team){
|
||||
@@ -143,33 +143,27 @@ public class Tile implements PosTrait, TargetTrait{
|
||||
}
|
||||
|
||||
public void setBlock(Block type, int rotation){
|
||||
synchronized(tileSetLock){
|
||||
preChanged();
|
||||
if(rotation < 0) rotation = (-rotation + 2);
|
||||
this.wall = type;
|
||||
this.link = 0;
|
||||
setRotation((byte) (rotation % 4));
|
||||
changed();
|
||||
}
|
||||
preChanged();
|
||||
if(rotation < 0) rotation = (-rotation + 2);
|
||||
this.wall = type;
|
||||
this.link = 0;
|
||||
setRotation((byte) (rotation % 4));
|
||||
changed();
|
||||
}
|
||||
|
||||
public void setBlock(Block type, Team team){
|
||||
synchronized(tileSetLock){
|
||||
preChanged();
|
||||
this.wall = type;
|
||||
this.team = (byte)team.ordinal();
|
||||
this.link = 0;
|
||||
changed();
|
||||
}
|
||||
preChanged();
|
||||
this.wall = type;
|
||||
this.team = (byte)team.ordinal();
|
||||
this.link = 0;
|
||||
changed();
|
||||
}
|
||||
|
||||
public void setBlock(Block type){
|
||||
synchronized(tileSetLock){
|
||||
preChanged();
|
||||
this.wall = type;
|
||||
this.link = 0;
|
||||
changed();
|
||||
}
|
||||
preChanged();
|
||||
this.wall = type;
|
||||
this.link = 0;
|
||||
changed();
|
||||
}
|
||||
|
||||
public void setFloor(Floor type){
|
||||
@@ -266,7 +260,7 @@ public class Tile implements PosTrait, TargetTrait{
|
||||
* Returns the list of all tiles linked to this multiblock, or an empty array if it's not a multiblock.
|
||||
* This array contains all linked tiles, including this tile itself.
|
||||
*/
|
||||
public synchronized Array<Tile> getLinkedTiles(Array<Tile> tmpArray){
|
||||
public Array<Tile> getLinkedTiles(Array<Tile> tmpArray){
|
||||
Block block = block();
|
||||
tmpArray.clear();
|
||||
if(block.isMultiblock()){
|
||||
@@ -288,7 +282,7 @@ public class Tile implements PosTrait, TargetTrait{
|
||||
* Returns the list of all tiles linked to this multiblock if it were this block, or an empty array if it's not a multiblock.
|
||||
* This array contains all linked tiles, including this tile itself.
|
||||
*/
|
||||
public synchronized Array<Tile> getLinkedTilesAs(Block block, Array<Tile> tmpArray){
|
||||
public Array<Tile> getLinkedTilesAs(Block block, Array<Tile> tmpArray){
|
||||
tmpArray.clear();
|
||||
if(block.isMultiblock()){
|
||||
int offsetx = -(block.size - 1) / 2;
|
||||
@@ -390,52 +384,47 @@ public class Tile implements PosTrait, TargetTrait{
|
||||
}
|
||||
|
||||
private void preChanged(){
|
||||
synchronized(tileSetLock){
|
||||
block().removed(this);
|
||||
if(entity != null){
|
||||
entity.removeFromProximity();
|
||||
}
|
||||
team = 0;
|
||||
block().removed(this);
|
||||
if(entity != null){
|
||||
entity.removeFromProximity();
|
||||
}
|
||||
team = 0;
|
||||
}
|
||||
|
||||
private void changed(){
|
||||
|
||||
synchronized(tileSetLock){
|
||||
if(entity != null){
|
||||
entity.remove();
|
||||
entity = null;
|
||||
}
|
||||
|
||||
Block block = block();
|
||||
|
||||
if(block.hasEntity()){
|
||||
entity = block.newEntity().init(this, block.update);
|
||||
entity.cons = new ConsumeModule();
|
||||
if(block.hasItems) entity.items = new ItemModule();
|
||||
if(block.hasLiquids) entity.liquids = new LiquidModule();
|
||||
if(block.hasPower){
|
||||
entity.power = new PowerModule();
|
||||
entity.power.graph.add(this);
|
||||
}
|
||||
|
||||
if(!world.isGenerating()){
|
||||
entity.updateProximity();
|
||||
}
|
||||
}else if(!(block instanceof BlockPart) && !world.isGenerating()){
|
||||
//since the entity won't update proximity for us, update proximity for all nearby tiles manually
|
||||
for(GridPoint2 p : Geometry.d4){
|
||||
Tile tile = world.tile(x + p.x, y + p.y);
|
||||
if(tile != null){
|
||||
tile = tile.target();
|
||||
tile.block().onProximityUpdate(tile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateOcclusion();
|
||||
if(entity != null){
|
||||
entity.remove();
|
||||
entity = null;
|
||||
}
|
||||
|
||||
Block block = block();
|
||||
|
||||
if(block.hasEntity()){
|
||||
entity = block.newEntity().init(this, block.update);
|
||||
entity.cons = new ConsumeModule();
|
||||
if(block.hasItems) entity.items = new ItemModule();
|
||||
if(block.hasLiquids) entity.liquids = new LiquidModule();
|
||||
if(block.hasPower){
|
||||
entity.power = new PowerModule();
|
||||
entity.power.graph.add(this);
|
||||
}
|
||||
|
||||
if(!world.isGenerating()){
|
||||
entity.updateProximity();
|
||||
}
|
||||
}else if(!(block instanceof BlockPart) && !world.isGenerating()){
|
||||
//since the entity won't update proximity for us, update proximity for all nearby tiles manually
|
||||
for(GridPoint2 p : Geometry.d4){
|
||||
Tile tile = world.tile(x + p.x, y + p.y);
|
||||
if(tile != null){
|
||||
tile = tile.target();
|
||||
tile.block().onProximityUpdate(tile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateOcclusion();
|
||||
|
||||
world.notifyChanged(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.mindustry.type.Liquid;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.mindustry.world.consumers.ConsumeLiquidFilter;
|
||||
import io.anuke.mindustry.world.meta.BlockStat;
|
||||
import io.anuke.ucore.core.Effects;
|
||||
import io.anuke.ucore.graphics.Draw;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
@@ -15,9 +16,7 @@ import static io.anuke.mindustry.Vars.tilesize;
|
||||
public abstract class ItemLiquidGenerator extends ItemGenerator{
|
||||
protected float minLiquidEfficiency = 0.2f;
|
||||
protected float powerPerLiquid = 0.13f;
|
||||
/**
|
||||
* Maximum liquid used per frame.
|
||||
*/
|
||||
/**Maximum liquid used per frame.*/
|
||||
protected float maxLiquidGenerate = 0.4f;
|
||||
|
||||
public ItemLiquidGenerator(String name){
|
||||
@@ -28,6 +27,12 @@ public abstract class ItemLiquidGenerator extends ItemGenerator{
|
||||
consumes.add(new ConsumeLiquidFilter(liquid -> getLiquidEfficiency(liquid) >= minLiquidEfficiency, 0.001f, true)).update(false).optional(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(){
|
||||
super.init();
|
||||
stats.remove(BlockStat.liquidFuelUse);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Tile tile){
|
||||
ItemGeneratorEntity entity = tile.entity();
|
||||
|
||||
@@ -13,19 +13,21 @@ import io.anuke.ucore.util.Mathf;
|
||||
|
||||
public abstract class LiquidGenerator extends PowerGenerator{
|
||||
protected float minEfficiency = 0.2f;
|
||||
protected float powerPerLiquid = 0.13f;
|
||||
/**
|
||||
* Maximum liquid used per frame.
|
||||
*/
|
||||
protected float maxLiquidGenerate = 0.4f;
|
||||
protected float powerPerLiquid;
|
||||
/**Maximum liquid used per frame.*/
|
||||
protected float maxLiquidGenerate;
|
||||
protected Effect generateEffect = BlockFx.generatespark;
|
||||
|
||||
public LiquidGenerator(String name){
|
||||
super(name);
|
||||
liquidCapacity = 30f;
|
||||
hasLiquids = true;
|
||||
}
|
||||
|
||||
consumes.add(new ConsumeLiquidFilter(liquid -> getEfficiency(liquid) >= minEfficiency, 0.001f)).update(false);
|
||||
@Override
|
||||
public void setStats(){
|
||||
consumes.add(new ConsumeLiquidFilter(liquid -> getEfficiency(liquid) >= minEfficiency, maxLiquidGenerate)).update(false);
|
||||
super.setStats();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -14,7 +14,7 @@ public class LiquidHeatGenerator extends LiquidGenerator{
|
||||
public void setStats(){
|
||||
super.setStats();
|
||||
|
||||
stats.add(BlockStat.basePowerGeneration, maxLiquidGenerate * powerPerLiquid * 60f * 0.4f, StatUnit.powerSecond);
|
||||
stats.add(BlockStat.basePowerGeneration, maxLiquidGenerate * powerPerLiquid * 60f, StatUnit.powerSecond);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.badlogic.gdx.utils.IntSet;
|
||||
import com.badlogic.gdx.utils.ObjectSet;
|
||||
import com.badlogic.gdx.utils.Queue;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
|
||||
import static io.anuke.mindustry.Vars.threads;
|
||||
|
||||
@@ -37,63 +38,38 @@ public class PowerGraph{
|
||||
|
||||
lastFrameUpdated = threads.getFrameID();
|
||||
|
||||
boolean charge = false;
|
||||
|
||||
float totalInput = 0f;
|
||||
float bufferInput = 0f;
|
||||
|
||||
for(Tile producer : producers){
|
||||
if (producer.block().consumesPower) {
|
||||
bufferInput += producer.entity.power.amount;
|
||||
} else {
|
||||
totalInput += producer.entity.power.amount;
|
||||
}
|
||||
totalInput += producer.entity.power.amount;
|
||||
}
|
||||
|
||||
float maxOutput = 0f;
|
||||
float bufferOutput = 0f;
|
||||
for(Tile consumer : consumers){
|
||||
if (consumer.block().outputsPower) {
|
||||
bufferOutput += consumer.block().powerCapacity - consumer.entity.power.amount;
|
||||
} else {
|
||||
maxOutput += consumer.block().powerCapacity - consumer.entity.power.amount;
|
||||
}
|
||||
}
|
||||
|
||||
if (maxOutput < totalInput) {
|
||||
charge = true;
|
||||
}
|
||||
|
||||
if (totalInput + bufferInput <= 0.0001f || maxOutput + bufferOutput <= 0.0001f) {
|
||||
return;
|
||||
}
|
||||
|
||||
float bufferUsed = 0;
|
||||
if (charge) {
|
||||
bufferUsed = Math.min((totalInput - maxOutput) / bufferOutput, 1f);
|
||||
} else {
|
||||
bufferUsed = Math.min((maxOutput - totalInput) / bufferInput, 1f);
|
||||
}
|
||||
|
||||
float inputUsed = charge ? Math.min((maxOutput + bufferOutput) / totalInput, 1f) : 1f;
|
||||
for(Tile producer : producers){
|
||||
if (producer.block().consumesPower) {
|
||||
if (!charge) {
|
||||
producer.entity.power.amount -= producer.entity.power.amount * bufferUsed;
|
||||
}
|
||||
float accumulator = producer.entity.power.amount;
|
||||
|
||||
if(accumulator <= 0.0001f) continue;
|
||||
|
||||
float toEach = accumulator / consumers.size;
|
||||
float outputs = 0f;
|
||||
|
||||
for(Tile tile : consumers){
|
||||
outputs += Math.min(tile.block().powerCapacity - tile.entity.power.amount, toEach) / toEach;
|
||||
}
|
||||
|
||||
float finalEach = toEach / outputs * Timers.delta();
|
||||
float buffer = 0f;
|
||||
|
||||
if(Float.isNaN(finalEach) || Float.isInfinite(finalEach)){
|
||||
continue;
|
||||
}
|
||||
producer.entity.power.amount -= producer.entity.power.amount * inputUsed;
|
||||
}
|
||||
|
||||
float outputSatisfied = charge ? 1f : Math.min((totalInput + bufferInput) / maxOutput, 1f);
|
||||
for(Tile consumer : consumers){
|
||||
if (consumer.block().outputsPower) {
|
||||
if (charge) {
|
||||
consumer.entity.power.amount += (consumer.block().powerCapacity - consumer.entity.power.amount) * bufferUsed;
|
||||
}
|
||||
continue;
|
||||
for(Tile tile : consumers){
|
||||
float used = Math.min(tile.block().powerCapacity - tile.entity.power.amount, finalEach) * accumulator / totalInput;
|
||||
buffer += used;
|
||||
tile.entity.power.amount += used;
|
||||
}
|
||||
consumer.entity.power.amount += (consumer.block().powerCapacity - consumer.entity.power.amount) * outputSatisfied;
|
||||
|
||||
producer.entity.power.amount -= buffer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -127,7 +127,7 @@ public class MechPad extends Block{
|
||||
|
||||
if(checkValidTap(tile, player)){
|
||||
Call.onMechFactoryTap(player, tile);
|
||||
}else if(player.isLocal && mobile){
|
||||
}else if(player.isLocal && mobile && !player.isDead()){
|
||||
player.moveTarget = tile.entity;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user