mirror of
https://github.com/Anuken/Mindustry.git
synced 2024-11-13 07:15:28 +03:00
Major refactoring of building, sound, inventory
This commit is contained in:
parent
de40df7f7b
commit
c1a5482ad2
Binary file not shown.
@ -4,6 +4,7 @@ import com.squareup.javapoet.*;
|
||||
import io.anuke.annotations.Annotations.Local;
|
||||
import io.anuke.annotations.Annotations.RemoteClient;
|
||||
import io.anuke.annotations.Annotations.RemoteServer;
|
||||
import io.anuke.annotations.Annotations.Unreliable;
|
||||
|
||||
import javax.annotation.processing.*;
|
||||
import javax.lang.model.SourceVersion;
|
||||
@ -22,7 +23,8 @@ import java.util.Set;
|
||||
@SupportedAnnotationTypes({
|
||||
"io.anuke.annotations.Annotations.RemoteClient",
|
||||
"io.anuke.annotations.Annotations.RemoteServer",
|
||||
"io.anuke.annotations.Annotations.Local"
|
||||
"io.anuke.annotations.Annotations.Local",
|
||||
"io.anuke.annotations.Annotations.Unreliable"
|
||||
})
|
||||
public class AnnotationProcessor extends AbstractProcessor {
|
||||
private static final int maxPacketSize = 128;
|
||||
@ -39,6 +41,19 @@ public class AnnotationProcessor extends AbstractProcessor {
|
||||
"rtype rvalue = io.anuke.mindustry.Vars.playerGroup.getByID(rbuffer.getInt())"
|
||||
}
|
||||
});
|
||||
|
||||
put("String", new String[][]{
|
||||
{
|
||||
"rbuffer.putShort((short)rvalue.getBytes().length)",
|
||||
"rbuffer.put(rvalue.getBytes())"
|
||||
},
|
||||
{
|
||||
"short __rvalue_length = rbuffer.getShort()",
|
||||
"byte[] __rvalue_bytes = new byte[__rvalue_length]",
|
||||
"rbuffer.get(__rvalue_bytes)",
|
||||
"rtype rvalue = new rtype(__rvalue_bytes)"
|
||||
}
|
||||
});
|
||||
}};
|
||||
|
||||
private Types typeUtils;
|
||||
@ -109,6 +124,7 @@ public class AnnotationProcessor extends AbstractProcessor {
|
||||
|
||||
if(e.getAnnotation(annotation) == null) continue;
|
||||
boolean local = e.getAnnotation(Local.class) != null;
|
||||
boolean unreliable = e.getAnnotation(Unreliable.class) != null;
|
||||
|
||||
ExecutableElement exec = (ExecutableElement)e;
|
||||
|
||||
@ -211,7 +227,8 @@ public class AnnotationProcessor extends AbstractProcessor {
|
||||
}
|
||||
}
|
||||
method.addStatement("packet.writeLength = TEMP_BUFFER.position()");
|
||||
method.addStatement("io.anuke.mindustry.net.Net.send(packet, io.anuke.mindustry.net.Net.SendMode.tcp)");
|
||||
method.addStatement("io.anuke.mindustry.net.Net.send(packet, "+
|
||||
(unreliable ? "io.anuke.mindustry.net.Net.SendMode.udp" : "io.anuke.mindustry.net.Net.SendMode.tcp")+")");
|
||||
|
||||
classBuilder.addMethod(method.build());
|
||||
|
||||
|
@ -14,7 +14,8 @@ import java.lang.annotation.Target;
|
||||
* {@link RemoteServer}: Marks a method as able to be invoked remotely on a server from a client.<br>
|
||||
* {@link Local}: Makes this method get invoked locally as well as remotely.<br>
|
||||
*<br>
|
||||
* All RemoteClient methods are put in the class CallClient, and all RemoteServer methods are put in the class CallServer.<br>
|
||||
* All RemoteClient methods are put in the class io.anuke.mindustry.gen.CallClient.<br>
|
||||
* All RemoteServer methods are put in the class io.anuke.mindustry.gen.CallServer.<br>
|
||||
*/
|
||||
public class Annotations {
|
||||
|
||||
@ -35,4 +36,10 @@ public class Annotations {
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.CLASS)
|
||||
public @interface Local{}
|
||||
|
||||
/**Marks a method to be invoked unreliably, e.g. with UDP instead of TCP.
|
||||
* This is faster, but is prone to packet loss and duplication.*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.CLASS)
|
||||
public @interface Unreliable{}
|
||||
}
|
||||
|
@ -46,13 +46,11 @@ public class PowerBlocks {
|
||||
nuclearReactor = new NuclearReactor("nuclearreactor") {{
|
||||
size = 3;
|
||||
health = 600;
|
||||
breaktime *= 2.3f;
|
||||
}},
|
||||
|
||||
fusionReactor = new FusionReactor("fusionreactor") {{
|
||||
size = 4;
|
||||
health = 600;
|
||||
breaktime *= 4f;
|
||||
}},
|
||||
|
||||
repairturret = new RepairTurret("repairturret") {{
|
||||
|
@ -60,7 +60,7 @@ public class ContentLoader {
|
||||
Log.info("--- CONTENT INFO ---");
|
||||
Log.info("Blocks loaded: {0}\nItems loaded: {1}\nLiquids loaded: {2}\nUpgrades loaded: {3}\nUnits loaded: {4}\nAmmo types loaded: {5}\nStatus effects loaded: {6}\nRecipes loaded: {7}\nTotal content classes: {8}",
|
||||
Block.getAllBlocks().size, Item.getAllItems().size, Liquid.getAllLiquids().size,
|
||||
Mech.getAllUpgrades().size, UnitType.getAllTypes().size, AmmoType.getAllTypes().size, StatusEffect.getAllEffects().size, Recipe.all().size, content.length);
|
||||
Mech.getAllUpgrades().size, UnitType.getAllTypes().size, AmmoType.getAllTypes().size, StatusEffect.getAllEffects().size, Recipe.getAllRecipes().size, content.length);
|
||||
|
||||
Log.info("-------------------");
|
||||
}
|
||||
|
@ -2,7 +2,10 @@ package io.anuke.mindustry.core;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.Input;
|
||||
import com.badlogic.gdx.audio.Sound;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.utils.ObjectMap;
|
||||
import com.badlogic.gdx.utils.TimeUtils;
|
||||
import io.anuke.mindustry.content.Mechs;
|
||||
import io.anuke.mindustry.core.GameState.State;
|
||||
import io.anuke.mindustry.entities.Player;
|
||||
@ -20,7 +23,7 @@ import io.anuke.ucore.core.*;
|
||||
import io.anuke.ucore.entities.Entities;
|
||||
import io.anuke.ucore.input.InputProxy;
|
||||
import io.anuke.ucore.modules.Module;
|
||||
import io.anuke.ucore.util.*;
|
||||
import io.anuke.ucore.util.Atlas;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
@ -29,10 +32,14 @@ import static io.anuke.mindustry.Vars.*;
|
||||
* Should <i>not</i> handle any logic-critical state.
|
||||
* This class is not created in the headless server.*/
|
||||
public class Control extends Module{
|
||||
/**Minimum period of time between the same sound being played.*/
|
||||
private static final long minSoundPeriod = 30;
|
||||
|
||||
private boolean hiscore = false;
|
||||
private boolean wasPaused = false;
|
||||
private Saves saves;
|
||||
private InputHandler[] inputs = {};
|
||||
private ObjectMap<Sound, Long> soundMap = new ObjectMap<>();
|
||||
|
||||
private Throwable error;
|
||||
private InputProxy proxy;
|
||||
@ -85,6 +92,15 @@ public class Control extends Module{
|
||||
"ping.mp3", "tesla.mp3", "waveend.mp3", "railgun.mp3", "blast.mp3", "bang2.mp3");
|
||||
|
||||
Sounds.setFalloff(9000f);
|
||||
Sounds.setPlayer(((sound, volume) -> {
|
||||
long time = TimeUtils.millis();
|
||||
long value = soundMap.get(sound, 0L);
|
||||
|
||||
if(TimeUtils.timeSinceMillis(value) >= minSoundPeriod){
|
||||
threads.run(() -> sound.play(volume));
|
||||
soundMap.put(sound, time);
|
||||
}
|
||||
}));
|
||||
|
||||
Musics.load("1.mp3", "2.mp3", "3.mp3", "4.mp3");
|
||||
|
||||
|
@ -3,15 +3,12 @@ package io.anuke.mindustry.core;
|
||||
import io.anuke.mindustry.game.Difficulty;
|
||||
import io.anuke.mindustry.game.EventType.StateChangeEvent;
|
||||
import io.anuke.mindustry.game.GameMode;
|
||||
import io.anuke.mindustry.game.Inventory;
|
||||
import io.anuke.mindustry.game.TeamInfo;
|
||||
import io.anuke.ucore.core.Events;
|
||||
|
||||
public class GameState{
|
||||
private State state = State.menu;
|
||||
|
||||
public final Inventory inventory = new Inventory();
|
||||
|
||||
public int wave = 1;
|
||||
public float wavetime;
|
||||
public float extrawavetime;
|
||||
|
@ -17,8 +17,6 @@ import io.anuke.ucore.entities.Entities;
|
||||
import io.anuke.ucore.entities.EntityGroup;
|
||||
import io.anuke.ucore.modules.Module;
|
||||
|
||||
import java.sql.Time;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
/**Logic module.
|
||||
@ -44,12 +42,6 @@ public class Logic extends Module {
|
||||
public void play(){
|
||||
state.wavetime = wavespace * state.difficulty.timeScaling * 2;
|
||||
|
||||
if(state.mode.infiniteResources){
|
||||
state.inventory.fill();
|
||||
}else{
|
||||
state.inventory.clearItems();
|
||||
}
|
||||
|
||||
Events.fire(PlayEvent.class);
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,6 @@ package io.anuke.mindustry.core;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.utils.IntMap;
|
||||
import com.badlogic.gdx.utils.IntSet;
|
||||
import io.anuke.mindustry.content.UpgradeRecipes;
|
||||
import io.anuke.mindustry.core.GameState.State;
|
||||
import io.anuke.mindustry.entities.BulletType;
|
||||
import io.anuke.mindustry.entities.Player;
|
||||
@ -17,7 +16,7 @@ import io.anuke.mindustry.net.Packets.*;
|
||||
import io.anuke.mindustry.resource.Recipe;
|
||||
import io.anuke.mindustry.resource.Upgrade;
|
||||
import io.anuke.mindustry.resource.Weapon;
|
||||
import io.anuke.mindustry.world.Placement;
|
||||
import io.anuke.mindustry.world.Build;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.ucore.core.Effects;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
@ -153,8 +152,6 @@ public class NetClient extends Module {
|
||||
});
|
||||
|
||||
Net.handleClient(StateSyncPacket.class, packet -> {
|
||||
System.arraycopy(packet.items, 0, state.inventory.writeItems(), 0, packet.items.length);
|
||||
|
||||
state.enemies = packet.enemies;
|
||||
state.wavetime = packet.countdown;
|
||||
state.wave = packet.wave;
|
||||
@ -178,7 +175,7 @@ public class NetClient extends Module {
|
||||
Net.handleClient(BreakPacket.class, (packet) -> {
|
||||
Player placer = playerGroup.getByID(packet.playerid);
|
||||
|
||||
Placement.breakBlock(placer.team, packet.x, packet.y, true, Timers.get("breakblocksound", 10));
|
||||
Build.breakBlock(placer.team, packet.x, packet.y, true, Timers.get("breakblocksound", 10));
|
||||
});
|
||||
|
||||
Net.handleClient(EntitySpawnPacket.class, packet -> {
|
||||
@ -271,7 +268,6 @@ public class NetClient extends Module {
|
||||
Net.handleClient(UpgradePacket.class, packet -> {
|
||||
Weapon weapon = Upgrade.getByID(packet.upgradeid);
|
||||
|
||||
state.inventory.removeItems(UpgradeRecipes.get(weapon));
|
||||
for(Player player : players) {
|
||||
player.upgrades.add(weapon);
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import com.badlogic.gdx.utils.IntMap;
|
||||
import com.badlogic.gdx.utils.TimeUtils;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.content.Mechs;
|
||||
import io.anuke.mindustry.content.UpgradeRecipes;
|
||||
import io.anuke.mindustry.core.GameState.State;
|
||||
import io.anuke.mindustry.entities.BulletType;
|
||||
import io.anuke.mindustry.entities.Player;
|
||||
@ -21,7 +20,7 @@ import io.anuke.mindustry.resource.Recipe;
|
||||
import io.anuke.mindustry.resource.Upgrade;
|
||||
import io.anuke.mindustry.resource.Weapon;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.Placement;
|
||||
import io.anuke.mindustry.world.Build;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.entities.BaseBulletType;
|
||||
@ -203,7 +202,7 @@ public class NetServer extends Module{
|
||||
Recipe recipe = Recipe.getByID(packet.recipe);
|
||||
Block block = recipe.result;
|
||||
|
||||
if(!Placement.validPlace(placer.team, packet.x, packet.y, block, packet.rotation)) return;
|
||||
if(!Build.validPlace(placer.team, packet.x, packet.y, block, packet.rotation)) return;
|
||||
|
||||
if(recipe == null || recipe.debugOnly != debug) return;
|
||||
|
||||
@ -215,8 +214,6 @@ public class NetServer extends Module{
|
||||
return;
|
||||
}
|
||||
|
||||
state.inventory.removeItems(recipe.requirements);
|
||||
|
||||
//todo implement placing
|
||||
//Placement.placeBlock(placer, packet.x, packet.y, recipe, packet.rotation, true, false);
|
||||
|
||||
@ -233,7 +230,7 @@ public class NetServer extends Module{
|
||||
Player placer = connections.get(id);
|
||||
packet.playerid = placer.id;
|
||||
|
||||
if(!Placement.validBreak(placer.team, packet.x, packet.y)) return;
|
||||
if(!Build.validBreak(placer.team, packet.x, packet.y)) return;
|
||||
|
||||
Tile tile = world.tile(packet.x, packet.y);
|
||||
|
||||
@ -244,7 +241,7 @@ public class NetServer extends Module{
|
||||
return;
|
||||
}
|
||||
|
||||
Block block = Placement.breakBlock(placer.team, packet.x, packet.y, true, false);
|
||||
Block block = Build.breakBlock(placer.team, packet.x, packet.y, true, false);
|
||||
|
||||
if(block != null) {
|
||||
TraceInfo trace = admins.getTraceByID(getUUID(id));
|
||||
@ -283,9 +280,7 @@ public class NetServer extends Module{
|
||||
|
||||
Weapon weapon = Upgrade.getByID(packet.upgradeid);
|
||||
|
||||
if(!state.inventory.hasItems(UpgradeRecipes.get(weapon))){
|
||||
return;
|
||||
}
|
||||
//todo verify upgrades with item requirements
|
||||
|
||||
if (!player.upgrades.contains(weapon, true)){
|
||||
player.upgrades.add(weapon);
|
||||
@ -293,7 +288,6 @@ public class NetServer extends Module{
|
||||
return;
|
||||
}
|
||||
|
||||
state.inventory.removeItems(UpgradeRecipes.get(weapon));
|
||||
Net.send(packet, SendMode.tcp);
|
||||
});
|
||||
|
||||
@ -493,7 +487,6 @@ public class NetServer extends Module{
|
||||
|
||||
if(timer.get(timerStateSync, itemSyncTime)){
|
||||
StateSyncPacket packet = new StateSyncPacket();
|
||||
packet.items = state.inventory.readItems();
|
||||
packet.countdown = state.wavetime;
|
||||
packet.enemies = state.enemies;
|
||||
packet.wave = state.wave;
|
||||
|
@ -4,7 +4,6 @@ import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.graphics.Texture.TextureWrap;
|
||||
import com.badlogic.gdx.graphics.g2d.GlyphLayout;
|
||||
import com.badlogic.gdx.math.Rectangle;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
@ -12,7 +11,6 @@ import com.badlogic.gdx.utils.FloatArray;
|
||||
import com.badlogic.gdx.utils.Pools;
|
||||
import io.anuke.mindustry.content.fx.Fx;
|
||||
import io.anuke.mindustry.core.GameState.State;
|
||||
import io.anuke.mindustry.entities.BlockPlacer.PlaceRequest;
|
||||
import io.anuke.mindustry.entities.Player;
|
||||
import io.anuke.mindustry.entities.Unit;
|
||||
import io.anuke.mindustry.entities.effect.BelowLiquidEffect;
|
||||
@ -22,14 +20,16 @@ import io.anuke.mindustry.entities.units.BaseUnit;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.graphics.*;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.Placement;
|
||||
import io.anuke.ucore.core.*;
|
||||
import io.anuke.ucore.entities.EffectEntity;
|
||||
import io.anuke.ucore.entities.Entities;
|
||||
import io.anuke.ucore.entities.Entity;
|
||||
import io.anuke.ucore.entities.EntityGroup;
|
||||
import io.anuke.ucore.function.Callable;
|
||||
import io.anuke.ucore.graphics.*;
|
||||
import io.anuke.ucore.graphics.Draw;
|
||||
import io.anuke.ucore.graphics.Hue;
|
||||
import io.anuke.ucore.graphics.Lines;
|
||||
import io.anuke.ucore.graphics.Surface;
|
||||
import io.anuke.ucore.modules.RendererModule;
|
||||
import io.anuke.ucore.scene.utils.Cursors;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
@ -206,13 +206,11 @@ public class Renderer extends RendererModule{
|
||||
blocks.processBlocks();
|
||||
blocks.drawBlocks(Layer.block);
|
||||
|
||||
//Graphics.surface(effectSurface, true);
|
||||
Graphics.shader(Shaders.blockbuild, false);
|
||||
blocks.drawBlocks(Layer.placement);
|
||||
Graphics.shader();
|
||||
//Graphics.flushSurface();
|
||||
|
||||
drawPlaceRequests();
|
||||
Entities.drawWith(playerGroup, p -> true, Player::drawBuildRequests);
|
||||
|
||||
blocks.drawBlocks(Layer.overlay);
|
||||
|
||||
@ -227,35 +225,18 @@ public class Renderer extends RendererModule{
|
||||
Entities.draw(airItemGroup);
|
||||
Entities.draw(effectGroup);
|
||||
|
||||
//drawShield();
|
||||
|
||||
overlays.draw();
|
||||
|
||||
if(pixelate)
|
||||
Graphics.flushSurface();
|
||||
|
||||
if(showPaths) drawDebug();
|
||||
drawPlayerNames();
|
||||
|
||||
Entities.drawWith(playerGroup, p -> !p.isLocal && !p.isDead(), Player::drawName);
|
||||
|
||||
batch.end();
|
||||
}
|
||||
|
||||
private void drawPlaceRequests(){
|
||||
Draw.color("accent");
|
||||
|
||||
for(Player player : playerGroup.all()) {
|
||||
for (PlaceRequest request : player.getPlaceQueue()) {
|
||||
if(Placement.validPlace(player.team, request.x, request.y, request.recipe.result, request.rotation)){
|
||||
Lines.poly(request.x * tilesize + request.recipe.result.getPlaceOffset().x,
|
||||
request.y * tilesize + request.recipe.result.getPlaceOffset().y,
|
||||
4, request.recipe.result.size * tilesize /2f + Mathf.absin(Timers.time(), 3f, 1f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Draw.color();
|
||||
}
|
||||
|
||||
private void drawAllTeams(boolean flying){
|
||||
for(Team team : Team.values()){
|
||||
EntityGroup<BaseUnit> group = unitGroups[team.ordinal()];
|
||||
@ -351,31 +332,6 @@ public class Renderer extends RendererModule{
|
||||
Draw.color();
|
||||
}
|
||||
|
||||
void drawPlayerNames(){
|
||||
GlyphLayout layout = Pools.obtain(GlyphLayout.class);
|
||||
|
||||
Draw.tscl(0.25f/2);
|
||||
for(Player player : playerGroup.all()){
|
||||
if(!player.isLocal && !player.isDead()){
|
||||
layout.setText(Core.font, player.name);
|
||||
Draw.color(0f, 0f, 0f, 0.3f);
|
||||
Draw.rect("blank", player.getDrawPosition().x, player.getDrawPosition().y + 8 - layout.height/2, layout.width + 2, layout.height + 2);
|
||||
Draw.color();
|
||||
Draw.tcolor(player.getColor());
|
||||
Draw.text(player.name, player.getDrawPosition().x, player.getDrawPosition().y + 8);
|
||||
|
||||
if(player.isAdmin){
|
||||
Draw.color(player.getColor());
|
||||
float s = 3f;
|
||||
Draw.rect("icon-admin-small", player.getDrawPosition().x + layout.width/2f + 2 + 1, player.getDrawPosition().y + 7f, s, s);
|
||||
}
|
||||
Draw.reset();
|
||||
}
|
||||
}
|
||||
Pools.free(layout);
|
||||
Draw.tscl(fontscale);
|
||||
}
|
||||
|
||||
void drawShield(){
|
||||
if(shieldGroup.size() == 0 && shieldDraws.size == 0) return;
|
||||
|
||||
|
154
core/src/io/anuke/mindustry/entities/BlockBuilder.java
Normal file
154
core/src/io/anuke/mindustry/entities/BlockBuilder.java
Normal file
@ -0,0 +1,154 @@
|
||||
package io.anuke.mindustry.entities;
|
||||
|
||||
import com.badlogic.gdx.utils.Queue;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.resource.Recipe;
|
||||
import io.anuke.mindustry.world.Build;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.mindustry.world.blocks.types.BuildBlock;
|
||||
import io.anuke.mindustry.world.blocks.types.BuildBlock.BuildEntity;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.graphics.Draw;
|
||||
import io.anuke.ucore.graphics.Fill;
|
||||
import io.anuke.ucore.graphics.Lines;
|
||||
import io.anuke.ucore.util.Angles;
|
||||
import io.anuke.ucore.util.Geometry;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
import io.anuke.ucore.util.Translator;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import static io.anuke.mindustry.Vars.world;
|
||||
|
||||
/**Interface for units that build thing.*/
|
||||
public interface BlockBuilder {
|
||||
//temporary static final values
|
||||
Translator[] tmptr = {new Translator(), new Translator(), new Translator(), new Translator()};
|
||||
float placeDistance = 80f;
|
||||
|
||||
/**Returns the queue for storing build requests.*/
|
||||
Queue<BuildRequest> getPlaceQueue();
|
||||
|
||||
/**Clears the placement queue.*/
|
||||
default void clearBuilding(){
|
||||
getPlaceQueue().clear();
|
||||
}
|
||||
|
||||
/**Add another build requests to the tail of the queue.*/
|
||||
default void addBuildRequest(BuildRequest place){
|
||||
getPlaceQueue().addLast(place);
|
||||
}
|
||||
|
||||
/**Return the build requests currently active, or the one at the top of the queue.
|
||||
* May return null.*/
|
||||
default BuildRequest getCurrentRequest(){
|
||||
return getPlaceQueue().size == 0 ? null : getPlaceQueue().first();
|
||||
}
|
||||
|
||||
/**Update building mechanism for this unit.*/
|
||||
default void updateBuilding(Unit unit){
|
||||
BuildRequest current = getCurrentRequest();
|
||||
|
||||
if(current == null) return; //nothing to do here
|
||||
|
||||
Tile tile = world.tile(current.x, current.y);
|
||||
|
||||
if(unit.distanceTo(tile) > placeDistance) { //out of range, skip it.
|
||||
getPlaceQueue().removeFirst();
|
||||
}else if(current.remove){
|
||||
if(Build.validBreak(unit.team, current.x, current.y)){ //if it's valid, break it
|
||||
current.removeProgress += 1f / tile.getBreakTime();
|
||||
|
||||
if(current.removeProgress >= 1f){
|
||||
Build.breakBlock(unit.team, current.x, current.y, true, true);
|
||||
}
|
||||
}else{
|
||||
//otherwise, skip it
|
||||
getPlaceQueue().removeFirst();
|
||||
}
|
||||
}else{
|
||||
if (!(tile.block() instanceof BuildBlock)) { //check if haven't started placing
|
||||
if(Build.validPlace(unit.team, current.x, current.y, current.recipe.result, current.rotation)){
|
||||
//if it's valid, place it
|
||||
Build.placeBlock(unit.team, current.x, current.y, current.recipe, current.rotation);
|
||||
}else{
|
||||
//otherwise, skip it
|
||||
getPlaceQueue().removeFirst();
|
||||
}
|
||||
}else{
|
||||
//otherwise, update it.
|
||||
BuildEntity entity = tile.entity();
|
||||
|
||||
entity.progress += 1f / entity.recipe.cost;
|
||||
unit.rotation = Mathf.slerpDelta(unit.rotation, unit.angleTo(entity), 0.4f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**Draw placement effects for an entity.*/
|
||||
default void drawBuilding(Unit unit){
|
||||
Tile tile = world.tile(getCurrentRequest().x, getCurrentRequest().y);
|
||||
|
||||
Draw.color(unit.distanceTo(tile) > placeDistance ? "placeInvalid" : "accent");
|
||||
float focusLen = 3.8f + Mathf.absin(Timers.time(), 1.1f, 0.6f);
|
||||
float px = unit.x + Angles.trnsx(unit.rotation, focusLen);
|
||||
float py = unit.y + Angles.trnsy(unit.rotation, focusLen);
|
||||
|
||||
float sz = Vars.tilesize*tile.block().size/2f;
|
||||
float ang = unit.angleTo(tile);
|
||||
|
||||
tmptr[0].set(tile.drawx() - sz, tile.drawy() - sz);
|
||||
tmptr[1].set(tile.drawx() + sz, tile.drawy() - sz);
|
||||
tmptr[2].set(tile.drawx() - sz, tile.drawy() + sz);
|
||||
tmptr[3].set(tile.drawx() + sz, tile.drawy() + sz);
|
||||
|
||||
Arrays.sort(tmptr, (a, b) -> -Float.compare(Angles.angleDist(Angles.angle(unit.x, unit.y, a.x, a.y), ang),
|
||||
Angles.angleDist(Angles.angle(unit.x, unit.y, b.x, b.y), ang)));
|
||||
|
||||
float x1 = tmptr[0].x, y1 = tmptr[0].y,
|
||||
x3 = tmptr[1].x, y3 = tmptr[1].y;
|
||||
Translator close = Geometry.findClosest(unit.x, unit.y, tmptr);
|
||||
float x2 = close.x, y2 = close.y;
|
||||
|
||||
Draw.alpha(0.3f + Mathf.absin(Timers.time(), 0.9f, 0.2f));
|
||||
|
||||
Fill.tri(px, py, x2, y2, x1, y1);
|
||||
Fill.tri(px, py, x2, y2, x3, y3);
|
||||
|
||||
Draw.alpha(1f);
|
||||
|
||||
Lines.line(px, py, x1, y1);
|
||||
Lines.line(px, py, x3, y3);
|
||||
|
||||
Fill.circle(px, py, 1.5f + Mathf.absin(Timers.time(), 1f, 1.8f));
|
||||
|
||||
Draw.color();
|
||||
}
|
||||
|
||||
/**Class for storing build requests. Can be either a place or remove request.*/
|
||||
class BuildRequest {
|
||||
public final int x, y, rotation;
|
||||
public final Recipe recipe;
|
||||
public final boolean remove;
|
||||
|
||||
float removeProgress;
|
||||
|
||||
/**This creates a build request.*/
|
||||
public BuildRequest(int x, int y, int rotation, Recipe recipe) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.rotation = rotation;
|
||||
this.recipe = recipe;
|
||||
this.remove = false;
|
||||
}
|
||||
|
||||
/**This creates a remove request.*/
|
||||
public BuildRequest(int x, int y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.rotation = -1;
|
||||
this.recipe = null;
|
||||
this.remove = true;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
package io.anuke.mindustry.entities;
|
||||
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.resource.Recipe;
|
||||
|
||||
public interface BlockPlacer {
|
||||
void addPlaceBlock(PlaceRequest place);
|
||||
Team getTeam();
|
||||
|
||||
class PlaceRequest{
|
||||
public final int x, y, rotation;
|
||||
public final Recipe recipe;
|
||||
|
||||
public PlaceRequest(int x, int y, int rotation, Recipe recipe) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.rotation = rotation;
|
||||
this.recipe = recipe;
|
||||
}
|
||||
}
|
||||
}
|
@ -10,6 +10,8 @@ import io.anuke.ucore.function.Callable;
|
||||
import io.anuke.ucore.graphics.Draw;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
|
||||
/**This class should not be used anymore, as the animation does not fit the style well.*/
|
||||
@Deprecated
|
||||
public class ItemAnimationEffect extends TimedEntity {
|
||||
private static final float size = 5f;
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
package io.anuke.mindustry.entities;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.g2d.GlyphLayout;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.Pools;
|
||||
import com.badlogic.gdx.utils.Queue;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.content.Mechs;
|
||||
import io.anuke.mindustry.content.Weapons;
|
||||
import io.anuke.mindustry.content.fx.ExplosionFx;
|
||||
@ -14,18 +15,11 @@ import io.anuke.mindustry.graphics.Palette;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.mindustry.net.NetEvents;
|
||||
import io.anuke.mindustry.resource.*;
|
||||
import io.anuke.mindustry.world.Placement;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.mindustry.world.blocks.types.BuildBlock;
|
||||
import io.anuke.mindustry.world.blocks.types.BuildBlock.BuildEntity;
|
||||
import io.anuke.mindustry.world.blocks.types.Floor;
|
||||
import io.anuke.ucore.core.Effects;
|
||||
import io.anuke.ucore.core.Inputs;
|
||||
import io.anuke.ucore.core.Settings;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.core.*;
|
||||
import io.anuke.ucore.entities.SolidEntity;
|
||||
import io.anuke.ucore.graphics.Draw;
|
||||
import io.anuke.ucore.graphics.Fill;
|
||||
import io.anuke.ucore.graphics.Lines;
|
||||
import io.anuke.ucore.util.*;
|
||||
|
||||
@ -33,17 +27,13 @@ import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class Player extends Unit implements BlockPlacer{
|
||||
static final float speed = 1.1f;
|
||||
static final float dashSpeed = 1.8f;
|
||||
public static final float placeDistance = 80f;
|
||||
|
||||
static final int timerRegen = 3;
|
||||
static final Translator[] tmptr = {new Translator(), new Translator(), new Translator(), new Translator()};
|
||||
public class Player extends Unit implements BlockBuilder {
|
||||
private static final float speed = 1.1f;
|
||||
private static final float dashSpeed = 1.8f;
|
||||
private static final Vector2 movement = new Vector2();
|
||||
|
||||
public String name = "name";
|
||||
public String uuid;
|
||||
@ -61,12 +51,10 @@ public class Player extends Unit implements BlockPlacer{
|
||||
public int playerIndex = 0;
|
||||
public boolean isLocal = false;
|
||||
public Timer timer = new Timer(4);
|
||||
public float walktime;
|
||||
public float respawntime;
|
||||
|
||||
private Queue<PlaceRequest> placeQueue = new Queue<>();
|
||||
private Tile currentPlace;
|
||||
private Vector2 movement = new Vector2();
|
||||
private float walktime;
|
||||
private float respawntime;
|
||||
private Queue<BuildRequest> placeQueue = new Queue<>();
|
||||
|
||||
public Player(){
|
||||
hitbox.setSize(5);
|
||||
@ -110,11 +98,6 @@ public class Player extends Unit implements BlockPlacer{
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPlaceBlock(PlaceRequest req){
|
||||
placeQueue.addFirst(req);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean collides(SolidEntity other){
|
||||
return !isDead() && super.collides(other) && !mech.flying;
|
||||
@ -227,45 +210,49 @@ public class Player extends Unit implements BlockPlacer{
|
||||
|
||||
@Override
|
||||
public void drawOver(){
|
||||
if(!isShooting() && currentPlace != null) {
|
||||
Draw.color(distanceTo(currentPlace) > placeDistance ? "placeInvalid" : "accent");
|
||||
float focusLen = 3.8f + Mathf.absin(Timers.time(), 1.1f, 0.6f);
|
||||
float px = x + Angles.trnsx(rotation, focusLen);
|
||||
float py = y + Angles.trnsy(rotation, focusLen);
|
||||
|
||||
Tile tile = currentPlace;
|
||||
|
||||
float sz = Vars.tilesize*tile.block().size/2f;
|
||||
float ang = angleTo(tile);
|
||||
|
||||
tmptr[0].set(tile.drawx() - sz, tile.drawy() - sz);
|
||||
tmptr[1].set(tile.drawx() + sz, tile.drawy() - sz);
|
||||
tmptr[2].set(tile.drawx() - sz, tile.drawy() + sz);
|
||||
tmptr[3].set(tile.drawx() + sz, tile.drawy() + sz);
|
||||
|
||||
Arrays.sort(tmptr, (a, b) -> -Float.compare(Angles.angleDist(Angles.angle(x, y, a.x, a.y), ang),
|
||||
Angles.angleDist(Angles.angle(x, y, b.x, b.y), ang)));
|
||||
|
||||
float x1 = tmptr[0].x, y1 = tmptr[0].y,
|
||||
x3 = tmptr[1].x, y3 = tmptr[1].y;
|
||||
Translator close = Geometry.findClosest(x, y, tmptr);
|
||||
float x2 = close.x, y2 = close.y;
|
||||
|
||||
Draw.alpha(0.3f + Mathf.absin(Timers.time(), 0.9f, 0.2f));
|
||||
|
||||
Fill.tri(px, py, x2, y2, x1, y1);
|
||||
Fill.tri(px, py, x2, y2, x3, y3);
|
||||
|
||||
Draw.alpha(1f);
|
||||
|
||||
Lines.line(px, py, x1, y1);
|
||||
Lines.line(px, py, x3, y3);
|
||||
|
||||
Fill.circle(px, py, 1.5f + Mathf.absin(Timers.time(), 1f, 1.8f));
|
||||
|
||||
Draw.color();
|
||||
if(!isShooting() && getCurrentRequest() != null) {
|
||||
drawBuilding(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void drawName(){
|
||||
GlyphLayout layout = Pools.obtain(GlyphLayout.class);
|
||||
|
||||
Draw.tscl(0.25f/2);
|
||||
layout.setText(Core.font, name);
|
||||
Draw.color(0f, 0f, 0f, 0.3f);
|
||||
Draw.rect("blank", getDrawPosition().x, getDrawPosition().y + 8 - layout.height/2, layout.width + 2, layout.height + 2);
|
||||
Draw.color();
|
||||
Draw.tcolor(color);
|
||||
Draw.text(name, getDrawPosition().x, getDrawPosition().y + 8);
|
||||
|
||||
if(isAdmin){
|
||||
Draw.color(color);
|
||||
float s = 3f;
|
||||
Draw.rect("icon-admin-small", getDrawPosition().x + layout.width/2f + 2 + 1, getDrawPosition().y + 7f, s, s);
|
||||
}
|
||||
|
||||
Draw.reset();
|
||||
Pools.free(layout);
|
||||
Draw.tscl(fontscale);
|
||||
}
|
||||
|
||||
public void drawBuildRequests(){
|
||||
for (BuildRequest request : getPlaceQueue()) {
|
||||
if(request.remove){
|
||||
Draw.color("placeInvalid");
|
||||
Tile tile = world.tile(request.x, request.y);
|
||||
|
||||
Lines.poly(tile.drawx(), tile.drawy(),
|
||||
4, tile.block().size * tilesize /2f + Mathf.absin(Timers.time(), 3f, 1f));
|
||||
}else{
|
||||
Draw.color("accent");
|
||||
Lines.poly(request.x * tilesize + request.recipe.result.getPlaceOffset().x,
|
||||
request.y * tilesize + request.recipe.result.getPlaceOffset().y,
|
||||
4, request.recipe.result.size * tilesize /2f + Mathf.absin(Timers.time(), 3f, 1f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(){
|
||||
@ -300,6 +287,7 @@ public class Player extends Unit implements BlockPlacer{
|
||||
y = Mathf.clamp(y, 0, world.height() * tilesize);
|
||||
}
|
||||
|
||||
/**Resets all values of the player.*/
|
||||
public void reset(){
|
||||
weapon = Weapons.blaster;
|
||||
team = Team.blue;
|
||||
@ -316,12 +304,11 @@ public class Player extends Unit implements BlockPlacer{
|
||||
return control.input(playerIndex).canShoot() && control.input(playerIndex).isShooting() && inventory.hasAmmo();
|
||||
}
|
||||
|
||||
public Queue<PlaceRequest> getPlaceQueue(){
|
||||
public Queue<BuildRequest> getPlaceQueue(){
|
||||
return placeQueue;
|
||||
}
|
||||
|
||||
protected void updateMech(){
|
||||
|
||||
Tile tile = world.tileWorld(x, y);
|
||||
|
||||
//if player is in solid block
|
||||
@ -330,29 +317,7 @@ public class Player extends Unit implements BlockPlacer{
|
||||
}
|
||||
|
||||
if(!isShooting()) {
|
||||
//update placing queue
|
||||
|
||||
if(currentPlace != null) {
|
||||
Tile check = currentPlace;
|
||||
|
||||
if (!(check.block() instanceof BuildBlock)) {
|
||||
currentPlace = null;
|
||||
}else if(distanceTo(check) <= placeDistance){
|
||||
BuildEntity entity = check.entity();
|
||||
|
||||
entity.progress += 1f / entity.recipe.cost;
|
||||
rotation = Mathf.slerpDelta(rotation, angleTo(entity), 0.4f);
|
||||
}
|
||||
|
||||
}else if(placeQueue.size > 0){
|
||||
PlaceRequest check = placeQueue.last();
|
||||
if(distanceTo(world.tile(check.x, check.y)) <= placeDistance &&
|
||||
Placement.validPlace(team, check.x, check.y, check.recipe.result, check.rotation)){
|
||||
placeQueue.removeLast();
|
||||
Placement.placeBlock(team, check.x, check.y, check.recipe, check.rotation, true, true);
|
||||
currentPlace = world.tile(check.x, check.y);
|
||||
}
|
||||
}
|
||||
updateBuilding(this);
|
||||
}
|
||||
|
||||
if(ui.chatfrag.chatOpen()) return;
|
||||
@ -365,11 +330,6 @@ public class Player extends Unit implements BlockPlacer{
|
||||
|
||||
speed *= ((1f-carrySlowdown) + (inventory.hasItem() ? (float)inventory.getItem().amount/inventory.capacity(): 1f) * carrySlowdown);
|
||||
|
||||
if(health < maxhealth && timer.get(timerRegen, 20))
|
||||
health ++;
|
||||
|
||||
health = Mathf.clamp(health, -1, maxhealth);
|
||||
|
||||
movement.set(0, 0);
|
||||
|
||||
String section = "player_" + (playerIndex + 1);
|
||||
@ -524,18 +484,4 @@ public class Player extends Unit implements BlockPlacer{
|
||||
|
||||
interpolator.read(this.x, this.y, x, y, rot, baseRot, time);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void interpolate() {
|
||||
super.interpolate();
|
||||
|
||||
Interpolator i = interpolator;
|
||||
|
||||
float tx = x + Angles.trnsx(rotation + 180f, 4f);
|
||||
float ty = y + Angles.trnsy(rotation + 180f, 4f);
|
||||
}
|
||||
|
||||
public Color getColor(){
|
||||
return color;
|
||||
}
|
||||
}
|
||||
|
@ -3,12 +3,13 @@ package io.anuke.mindustry.entities;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
|
||||
/**Class for predicting shoot angles based on velocities of targets.*/
|
||||
public class Predict {
|
||||
private static Vector2 vec = new Vector2();
|
||||
private static Vector2 vresult = new Vector2();
|
||||
|
||||
/**Returns resulting predicted vector.
|
||||
* Don't call from multiple threads, ever.*/
|
||||
* Don't call from multiple threads.*/
|
||||
public static Vector2 intercept(float srcx, float srcy, float dstx, float dsty, float dstvx, float dstvy, float v) {
|
||||
float tx = dstx - srcx,
|
||||
ty = dsty - srcy,
|
||||
@ -37,7 +38,6 @@ public class Predict {
|
||||
return sol;
|
||||
}
|
||||
|
||||
|
||||
private static Vector2 quad(float a, float b, float c) {
|
||||
Vector2 sol = null;
|
||||
if (Math.abs(a) < 1e-6) {
|
||||
|
@ -3,6 +3,7 @@ package io.anuke.mindustry.entities;
|
||||
import io.anuke.mindustry.content.StatusEffects;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
|
||||
/**Class for controlling status effects on an entity.*/
|
||||
public class StatusController {
|
||||
private static final TransitionResult globalResult = new TransitionResult();
|
||||
|
||||
|
@ -1,578 +0,0 @@
|
||||
package io.anuke.mindustry.game;
|
||||
|
||||
import com.badlogic.gdx.math.GridPoint2;
|
||||
import io.anuke.mindustry.content.Items;
|
||||
import io.anuke.mindustry.content.blocks.Blocks;
|
||||
import io.anuke.mindustry.content.blocks.DistributionBlocks;
|
||||
import io.anuke.mindustry.content.blocks.WeaponBlocks;
|
||||
import io.anuke.mindustry.core.GameState.State;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.scene.builders.button;
|
||||
import io.anuke.ucore.scene.builders.label;
|
||||
import io.anuke.ucore.scene.builders.table;
|
||||
import io.anuke.ucore.scene.ui.ImageButton;
|
||||
import io.anuke.ucore.scene.ui.Label;
|
||||
import io.anuke.ucore.scene.ui.TextButton;
|
||||
import io.anuke.ucore.util.Bundles;
|
||||
import io.anuke.ucore.util.Tmp;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class Tutorial{
|
||||
private Stage stage;
|
||||
private Label info;
|
||||
private TextButton next, prev;
|
||||
|
||||
public Tutorial(){
|
||||
reset();
|
||||
}
|
||||
|
||||
public boolean active(){
|
||||
return world.getMap() != null && world.getMap().name.equals("tutorial") && !state.is(State.menu);
|
||||
}
|
||||
|
||||
public void buildUI(table table){
|
||||
|
||||
table.atop();
|
||||
|
||||
new table("pane"){{
|
||||
atop();
|
||||
margin(12);
|
||||
|
||||
info = new label(()->stage.text).pad(10f).padBottom(5f).width(340f).colspan(2).get();
|
||||
info.setWrap(true);
|
||||
|
||||
row();
|
||||
|
||||
prev = new button("$text.tutorial.back", ()->{
|
||||
if(!prev.isDisabled())
|
||||
move(false);
|
||||
}).left().get();
|
||||
|
||||
next = new button("$text.tutorial.next", ()->{
|
||||
if(!next.isDisabled())
|
||||
move(true);
|
||||
}).right().get();
|
||||
|
||||
|
||||
}}.end();
|
||||
|
||||
prev.margin(16);
|
||||
next.margin(16);
|
||||
|
||||
prev.setDisabled(()->!canMove(false) || !stage.canBack);
|
||||
next.setDisabled(()->!stage.canForward);
|
||||
}
|
||||
|
||||
public void update(){
|
||||
stage.update(this);
|
||||
//info.setText(stage.text);
|
||||
|
||||
if(stage.showBlock){
|
||||
/*
|
||||
Tile tile = world.tile(world.getCore().x + stage.blockPlaceX, world.getCore().y + stage.blockPlaceY);
|
||||
|
||||
if(tile.block() == stage.targetBlock && (tile.getRotation() == stage.blockRotation || stage.blockRotation == -1)){
|
||||
move(true);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
public void reset(){
|
||||
stage = Stage.values()[0];
|
||||
stage.onSwitch();
|
||||
}
|
||||
|
||||
public void complete(){
|
||||
//new TextDialog("Congratulations!", "You have completed the tutorial!").padText(Unit.dp.inPixels(10f)).show();
|
||||
state.set(State.menu);
|
||||
reset();
|
||||
}
|
||||
|
||||
void move(boolean forward){
|
||||
//TODO
|
||||
}
|
||||
|
||||
boolean canMove(boolean forward){
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
public boolean showTarget(){
|
||||
return stage == Stage.shoot;
|
||||
}
|
||||
|
||||
public boolean canPlace(){
|
||||
return stage.canPlace;
|
||||
}
|
||||
|
||||
public boolean showBlock(){
|
||||
return stage.showBlock;
|
||||
}
|
||||
|
||||
public Block getPlaceBlock(){
|
||||
return stage.targetBlock;
|
||||
}
|
||||
|
||||
public GridPoint2 getPlacePoint(){
|
||||
return Tmp.g1.set(stage.blockPlaceX, stage.blockPlaceY);
|
||||
}
|
||||
|
||||
public int getPlaceRotation(){
|
||||
return stage.blockRotation;
|
||||
}
|
||||
|
||||
public void setDefaultBlocks(int corex, int corey){
|
||||
world.tile(corex, corey - 2).setBlock(Blocks.air);
|
||||
world.tile(corex, corey - 3).setBlock(Blocks.air);
|
||||
world.tile(corex, corey - 3).setFloor(Blocks.stone);
|
||||
|
||||
world.tile(corex + 1, corey - 8).setFloor(Blocks.iron);
|
||||
world.tile(corex - 1, corey - 8).setFloor(Blocks.coal);
|
||||
|
||||
int r = 10;
|
||||
|
||||
for(int x = -r; x <= r; x ++){
|
||||
for(int y = -r; y <= r; y ++){
|
||||
if(world.tile(corex + x, corey + y).block() == Blocks.rock){
|
||||
world.tile(corex + x, corey + y).setBlock(Blocks.air);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum Stage{
|
||||
intro{
|
||||
{
|
||||
}
|
||||
},
|
||||
moveDesktop{
|
||||
{
|
||||
desktopOnly = true;
|
||||
}
|
||||
},
|
||||
shoot{
|
||||
{
|
||||
desktopOnly = true;
|
||||
}
|
||||
},
|
||||
moveAndroid{
|
||||
{
|
||||
androidOnly = true;
|
||||
}
|
||||
},
|
||||
placeSelect{
|
||||
{
|
||||
canBack = false;
|
||||
canPlace = true;
|
||||
}
|
||||
|
||||
void onSwitch(){
|
||||
ui.<ImageButton>find("sectionbuttondistribution").fireClick();
|
||||
}
|
||||
},
|
||||
placeConveyorDesktop{
|
||||
{
|
||||
desktopOnly = true;
|
||||
canPlace = true;
|
||||
showBlock = true;
|
||||
canForward = false;
|
||||
blockRotation = 1;
|
||||
blockPlaceX = 0;
|
||||
blockPlaceY = -2;
|
||||
targetBlock = DistributionBlocks.conveyor;
|
||||
}
|
||||
},
|
||||
placeConveyorAndroid{
|
||||
{
|
||||
androidOnly = true;
|
||||
canPlace = true;
|
||||
showBlock = true;
|
||||
canForward = false;
|
||||
blockRotation = 1;
|
||||
blockPlaceX = 0;
|
||||
blockPlaceY = -2;
|
||||
targetBlock = DistributionBlocks.conveyor;
|
||||
}
|
||||
},
|
||||
placeConveyorAndroidInfo{
|
||||
{
|
||||
androidOnly = true;
|
||||
canBack = false;
|
||||
}
|
||||
|
||||
void onSwitch(){
|
||||
//player.recipe = null;
|
||||
}
|
||||
},
|
||||
placeDrill{
|
||||
{
|
||||
canPlace = true;
|
||||
canBack = false;
|
||||
showBlock = true;
|
||||
canForward = false;
|
||||
blockPlaceX = 0;
|
||||
blockPlaceY = -3;
|
||||
//targetBlock = ProductionBlocks.stonedrill;
|
||||
}
|
||||
|
||||
void onSwitch(){
|
||||
ui.<ImageButton>find("sectionbuttonproduction").fireClick();
|
||||
}
|
||||
},
|
||||
blockInfo{
|
||||
{
|
||||
canBack = true;
|
||||
}
|
||||
},
|
||||
deselectDesktop{
|
||||
{
|
||||
desktopOnly = true;
|
||||
canBack = false;
|
||||
}
|
||||
},
|
||||
deselectAndroid{
|
||||
{
|
||||
androidOnly = true;
|
||||
canBack = false;
|
||||
}
|
||||
},
|
||||
drillPlaced{
|
||||
{
|
||||
canBack = false;
|
||||
}
|
||||
|
||||
void onSwitch(){
|
||||
}
|
||||
},
|
||||
drillInfo{
|
||||
{
|
||||
}
|
||||
},
|
||||
drillPlaced2{
|
||||
{
|
||||
}
|
||||
},
|
||||
moreDrills{
|
||||
{
|
||||
canBack = false;
|
||||
}
|
||||
|
||||
void onSwitch(){
|
||||
/*
|
||||
for(int flip : new int[]{1, -1}){
|
||||
world.tile(world.getCore().x + flip, world.getCore().y - 2).setBlock(DistributionBlocks.conveyor, 2 * flip);
|
||||
world.tile(world.getCore().x + flip*2, world.getCore().y - 2).setBlock(DistributionBlocks.conveyor, 2 * flip);
|
||||
world.tile(world.getCore().x + flip*2, world.getCore().y - 3).setBlock(DistributionBlocks.conveyor, 2 * flip);
|
||||
world.tile(world.getCore().x + flip*2, world.getCore().y - 3).setBlock(DistributionBlocks.conveyor, 1);
|
||||
world.tile(world.getCore().x + flip*2, world.getCore().y - 4).setFloor(Blocks.stone);
|
||||
world.tile(world.getCore().x + flip*2, world.getCore().y - 4).setBlock(ProductionBlocks.stonedrill);
|
||||
|
||||
}*/
|
||||
}
|
||||
},
|
||||
deleteBlock{
|
||||
{
|
||||
canBack = false;
|
||||
canForward = false;
|
||||
showBlock = true;
|
||||
targetBlock = Blocks.air;
|
||||
blockPlaceX = 2;
|
||||
blockPlaceY = -2;
|
||||
desktopOnly = true;
|
||||
}
|
||||
},
|
||||
deleteBlockAndroid{
|
||||
{
|
||||
canBack = false;
|
||||
canForward = false;
|
||||
showBlock = true;
|
||||
targetBlock = Blocks.air;
|
||||
blockPlaceX = 2;
|
||||
blockPlaceY = -2;
|
||||
androidOnly = true;
|
||||
}
|
||||
},
|
||||
placeTurret{
|
||||
{
|
||||
canBack = false;
|
||||
canForward = false;
|
||||
showBlock = true;
|
||||
canPlace = true;
|
||||
targetBlock = WeaponBlocks.doubleturret;
|
||||
blockPlaceX = 2;
|
||||
blockPlaceY = 2;
|
||||
}
|
||||
|
||||
void onSwitch(){
|
||||
ui.<ImageButton>find("sectionbuttonweapon").fireClick();
|
||||
}
|
||||
},
|
||||
placedTurretAmmo{
|
||||
{
|
||||
canBack = false;
|
||||
}
|
||||
|
||||
void onSwitch(){
|
||||
for(int i = 0; i < 4; i ++){
|
||||
//world.tile(world.getCore().x + 2, world.getCore().y - 2 + i).setBlock(DistributionBlocks.conveyor, 1);
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
turretExplanation{
|
||||
{
|
||||
canBack = false;
|
||||
}
|
||||
},
|
||||
waves{
|
||||
{
|
||||
}
|
||||
},
|
||||
coreDestruction{
|
||||
{
|
||||
}
|
||||
},
|
||||
pausingDesktop{
|
||||
{
|
||||
desktopOnly = true;
|
||||
}
|
||||
},
|
||||
pausingAndroid{
|
||||
{
|
||||
androidOnly = true;
|
||||
}
|
||||
},
|
||||
//TODO re-add tutorial on weapons
|
||||
|
||||
spawnWave{
|
||||
float warmup = 0f;
|
||||
{
|
||||
canBack = false;
|
||||
canForward = false;
|
||||
}
|
||||
|
||||
void update(Tutorial t){
|
||||
warmup += Timers.delta();
|
||||
if(state.enemies == 0 && warmup > 60f){
|
||||
t.move(true);
|
||||
}
|
||||
}
|
||||
|
||||
void onSwitch(){
|
||||
warmup = 0f;
|
||||
logic.runWave();
|
||||
}
|
||||
},
|
||||
pumpDesc{
|
||||
{
|
||||
canBack = false;
|
||||
}
|
||||
},
|
||||
pumpPlace{
|
||||
{
|
||||
canBack = false;
|
||||
canForward = false;
|
||||
showBlock = true;
|
||||
canPlace = true;
|
||||
//targetBlock = ProductionBlocks.pump;
|
||||
blockPlaceX = 6;
|
||||
blockPlaceY = -2;
|
||||
}
|
||||
|
||||
void onSwitch(){
|
||||
ui.<ImageButton>find("sectionbuttonproduction").fireClick();
|
||||
state.inventory.addItem(Items.steel, 60);
|
||||
state.inventory.addItem(Items.iron, 60);
|
||||
}
|
||||
},
|
||||
conduitUse{
|
||||
{
|
||||
canBack = false;
|
||||
canForward = false;
|
||||
showBlock = true;
|
||||
canPlace = true;
|
||||
//targetBlock = DistributionBlocks.conduit;
|
||||
blockPlaceX = 5;
|
||||
blockPlaceY = -2;
|
||||
blockRotation = 2;
|
||||
}
|
||||
|
||||
void onSwitch(){
|
||||
ui.<ImageButton>find("sectionbuttondistribution").fireClick();
|
||||
//world.tile(blockPlaceX + world.getCore().x, blockPlaceY + world.getCore().y).setBlock(Blocks.air);
|
||||
}
|
||||
},
|
||||
conduitUse2{
|
||||
{
|
||||
canBack = false;
|
||||
canForward = false;
|
||||
showBlock = true;
|
||||
canPlace = true;
|
||||
//targetBlock = DistributionBlocks.conduit;
|
||||
//blockPlaceX = 4;
|
||||
blockPlaceY = -2;
|
||||
blockRotation = 1;
|
||||
}
|
||||
|
||||
void onSwitch(){
|
||||
//world.tile(blockPlaceX + world.getCore().x, blockPlaceY + world.getCore().y).setBlock(Blocks.air);
|
||||
}
|
||||
},
|
||||
conduitUse3{
|
||||
{
|
||||
canBack = false;
|
||||
canForward = false;
|
||||
showBlock = true;
|
||||
canPlace = true;
|
||||
//targetBlock = DistributionBlocks.conduit;
|
||||
blockPlaceX = 4;
|
||||
blockPlaceY = -1;
|
||||
blockRotation = 1;
|
||||
}
|
||||
|
||||
void onSwitch(){
|
||||
//world.tile(blockPlaceX + world.getCore().x, blockPlaceY + world.getCore().y).setBlock(Blocks.air);
|
||||
}
|
||||
},
|
||||
generator{
|
||||
{
|
||||
canBack = false;
|
||||
canForward = false;
|
||||
showBlock = true;
|
||||
canPlace = true;
|
||||
//targetBlock = ProductionBlocks.combustiongenerator;
|
||||
blockPlaceX = 4;
|
||||
blockPlaceY = 0;
|
||||
}
|
||||
|
||||
void onSwitch(){
|
||||
//world.tile(blockPlaceX + world.getCore().x, blockPlaceY + world.getCore().y).setBlock(Blocks.air);
|
||||
ui.<ImageButton>find("sectionbuttonpower").fireClick();
|
||||
state.inventory.addItem(Items.steel, 60);
|
||||
state.inventory.addItem(Items.iron, 60);
|
||||
}
|
||||
},
|
||||
generatorExplain{
|
||||
{
|
||||
canBack = false;
|
||||
}
|
||||
},
|
||||
lasers{
|
||||
{
|
||||
canBack = false;
|
||||
canForward = false;
|
||||
showBlock = true;
|
||||
canPlace = true;
|
||||
blockPlaceX = 4;
|
||||
blockPlaceY = 4;
|
||||
blockRotation = 2;
|
||||
//targetBlock = DistributionBlocks.powerlaser;
|
||||
}
|
||||
|
||||
void onSwitch(){
|
||||
ui.<ImageButton>find("sectionbuttonpower").fireClick();
|
||||
}
|
||||
},
|
||||
laserExplain{
|
||||
{
|
||||
canBack = false;
|
||||
}
|
||||
},
|
||||
laserMore{
|
||||
{
|
||||
canBack = false;
|
||||
}
|
||||
},
|
||||
healingTurret{
|
||||
{
|
||||
canBack = false;
|
||||
canForward = false;
|
||||
showBlock = true;
|
||||
canPlace = true;
|
||||
canBack = false;
|
||||
blockPlaceX = 1;
|
||||
blockPlaceY = 4;
|
||||
//targetBlock = DefenseBlocks.repairturret;
|
||||
}
|
||||
|
||||
void onSwitch(){
|
||||
ui.<ImageButton>find("sectionbuttonpower").fireClick();
|
||||
}
|
||||
},
|
||||
healingTurretExplain{
|
||||
{
|
||||
canBack = false;
|
||||
}
|
||||
},
|
||||
smeltery{
|
||||
{
|
||||
canBack = false;
|
||||
canForward = false;
|
||||
showBlock = true;
|
||||
canPlace = true;
|
||||
canBack = false;
|
||||
blockPlaceX = 0;
|
||||
blockPlaceY = -7;
|
||||
//targetBlock = ProductionBlocks.smelter;
|
||||
}
|
||||
|
||||
void onSwitch(){
|
||||
state.inventory.addItem(Items.stone, 40);
|
||||
state.inventory.addItem(Items.iron, 40);
|
||||
ui.<ImageButton>find("sectionbuttoncrafting").fireClick();
|
||||
|
||||
}
|
||||
},
|
||||
smelterySetup{
|
||||
{
|
||||
canBack = false;
|
||||
}
|
||||
|
||||
void onSwitch(){
|
||||
/*
|
||||
for(int i = 0; i < 5; i ++){
|
||||
world.tile(world.getCore().x, world.getCore().y - 6 + i).setBlock(DistributionBlocks.conveyor, 1);
|
||||
}
|
||||
|
||||
world.tile(world.getCore().x, world.getCore().y - 6 + 1).setBlock(DistributionBlocks.tunnel, 3);
|
||||
world.tile(world.getCore().x, world.getCore().y - 6 + 2).setBlock(DefenseBlocks.stonewall, 0);
|
||||
world.tile(world.getCore().x, world.getCore().y - 6 + 3).setBlock(DistributionBlocks.tunnel, 1);
|
||||
|
||||
world.tile(world.getCore().x+1, world.getCore().y - 8).setBlock(ProductionBlocks.irondrill);
|
||||
world.tile(world.getCore().x-1, world.getCore().y - 8).setBlock(ProductionBlocks.coaldrill);
|
||||
|
||||
world.tile(world.getCore().x+1, world.getCore().y - 7).setBlock(DistributionBlocks.conveyor, 2);
|
||||
world.tile(world.getCore().x-1, world.getCore().y - 7).setBlock(DistributionBlocks.conveyor, 0);*/
|
||||
}
|
||||
},
|
||||
tunnelExplain{
|
||||
{
|
||||
canBack = false;
|
||||
}
|
||||
},
|
||||
end{
|
||||
{
|
||||
canBack = false;
|
||||
}
|
||||
};
|
||||
public final String text = Bundles.getNotNull("tutorial."+name()+".text");
|
||||
|
||||
boolean androidOnly;
|
||||
boolean desktopOnly;
|
||||
|
||||
boolean canBack = true;
|
||||
boolean canForward = true;
|
||||
boolean canPlace = false;
|
||||
boolean showBlock = false;
|
||||
|
||||
int blockPlaceX = 0;
|
||||
int blockPlaceY = 0;
|
||||
int blockRotation = -1;
|
||||
Block targetBlock = null;
|
||||
|
||||
void update(Tutorial t){};
|
||||
void onSwitch(){}
|
||||
}
|
||||
}
|
@ -45,7 +45,7 @@ public class OverlayRenderer {
|
||||
int tiley = input.getBlockY();
|
||||
|
||||
//draw placement box
|
||||
if ((input.recipe != null && state.inventory.hasItems(input.recipe.requirements) && (!ui.hasMouse() || mobile)
|
||||
if ((input.recipe != null && (!ui.hasMouse() || mobile)
|
||||
&& input.drawPlace())) {
|
||||
|
||||
input.placeMode.draw(input, input.getBlockX(),
|
||||
@ -55,7 +55,7 @@ public class OverlayRenderer {
|
||||
input.breakMode.draw(input, tilex, tiley, 0, 0);
|
||||
|
||||
} else if (input.breakMode.delete && input.drawPlace()
|
||||
&& (input.recipe == null || !state.inventory.hasItems(input.recipe.requirements))
|
||||
&& (input.recipe == null)
|
||||
&& (input.placeMode.delete || input.breakMode.both || !mobile)) {
|
||||
|
||||
if (input.breakMode == PlaceMode.holdDelete)
|
||||
|
@ -7,7 +7,6 @@ import io.anuke.mindustry.core.GameState.State;
|
||||
import io.anuke.mindustry.entities.Player;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.mindustry.net.NetEvents;
|
||||
import io.anuke.mindustry.resource.ItemStack;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.ucore.core.Graphics;
|
||||
import io.anuke.ucore.core.Inputs;
|
||||
@ -98,28 +97,12 @@ public class AndroidInput extends InputHandler{
|
||||
mousex = Gdx.graphics.getWidth()/2;
|
||||
mousey = Gdx.graphics.getHeight()/2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cursorNear(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public Tile selected(){
|
||||
Vector2 vec = Graphics.world(mousex, mousey);
|
||||
return world.tile(Mathf.scl2(vec.x, tilesize), Mathf.scl2(vec.y, tilesize));
|
||||
}
|
||||
|
||||
public void breakBlock(){
|
||||
Tile tile = selected();
|
||||
breaktime += Timers.delta();
|
||||
|
||||
if(breaktime >= tile.block().breaktime){
|
||||
brokeBlock = true;
|
||||
breakBlock(tile.x, tile.y, true);
|
||||
breaktime = 0f;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(){
|
||||
enableHold = breakMode == PlaceMode.holdDelete;
|
||||
@ -150,15 +133,6 @@ public class AndroidInput extends InputHandler{
|
||||
if(sel == null)
|
||||
return;
|
||||
|
||||
if(warmup > warmupDelay && validBreak(sel.x, sel.y)){
|
||||
breaktime += Timers.delta();
|
||||
|
||||
if(breaktime > selected().block().breaktime){
|
||||
breakBlock();
|
||||
breaktime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
mousex = lx;
|
||||
mousey = ly;
|
||||
}else{
|
||||
@ -169,23 +143,6 @@ public class AndroidInput extends InputHandler{
|
||||
mousey = Mathf.clamp(mousey, 0, Gdx.graphics.getHeight());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryPlaceBlock(int x, int y, boolean sound){
|
||||
if(recipe != null &&
|
||||
validPlace(x, y, recipe.result) && cursorNear() &&
|
||||
state.inventory.hasItems(recipe.requirements)){
|
||||
|
||||
placeBlock(x, y, recipe, rotation, true, sound);
|
||||
|
||||
for(ItemStack stack : recipe.requirements){
|
||||
state.inventory.removeItem(stack);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean breaking(){
|
||||
return recipe == null;
|
||||
|
@ -21,7 +21,6 @@ public class DesktopInput extends InputHandler{
|
||||
float mousex, mousey;
|
||||
float endx, endy;
|
||||
private float controlx, controly;
|
||||
private boolean enableHold = false;
|
||||
private boolean beganBreak;
|
||||
private boolean controlling;
|
||||
private final int index;
|
||||
@ -178,17 +177,6 @@ public class DesktopInput extends InputHandler{
|
||||
recipe = null;
|
||||
}
|
||||
|
||||
//block breaking
|
||||
if(enableHold && Inputs.keyDown(section,"break") && cursor != null && validBreak(tilex(), tiley())){
|
||||
breaktime += Timers.delta();
|
||||
if(breaktime >= cursor.getBreakTime()){
|
||||
breakBlock(cursor.x, cursor.y, true);
|
||||
breaktime = 0f;
|
||||
}
|
||||
}else{
|
||||
breaktime = 0f;
|
||||
}
|
||||
|
||||
if(recipe != null){
|
||||
showCursor = validPlace(tilex(), tiley(), recipe.result) && cursorNear();
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ public class GestureHandler extends GestureAdapter{
|
||||
if(input.isCursorVisible() && !Inputs.keyDown("select")) return false;
|
||||
|
||||
if(!input.isCursorVisible() && !(input.recipe != null
|
||||
&& input.placeMode.lockCamera && state.inventory.hasItems(input.recipe.requirements)) &&
|
||||
&& input.placeMode.lockCamera) &&
|
||||
!(input.recipe == null && input.breakMode.lockCamera)){
|
||||
float dx = deltaX*Core.camera.zoom/Core.cameraScale, dy = deltaY*Core.camera.zoom/Core.cameraScale;
|
||||
input.player.x -= dx;
|
||||
|
@ -4,16 +4,14 @@ import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.InputAdapter;
|
||||
import com.badlogic.gdx.math.Interpolation;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import io.anuke.mindustry.entities.BlockPlacer.PlaceRequest;
|
||||
import io.anuke.mindustry.entities.BlockBuilder.BuildRequest;
|
||||
import io.anuke.mindustry.entities.ItemAnimationEffect;
|
||||
import io.anuke.mindustry.entities.Player;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.mindustry.net.NetEvents;
|
||||
import io.anuke.mindustry.resource.ItemStack;
|
||||
import io.anuke.mindustry.resource.Recipe;
|
||||
import io.anuke.mindustry.ui.fragments.OverlayFragment;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.Placement;
|
||||
import io.anuke.mindustry.world.Build;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.ucore.core.Core;
|
||||
import io.anuke.ucore.core.Graphics;
|
||||
@ -158,25 +156,20 @@ public abstract class InputHandler extends InputAdapter{
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean tryPlaceBlock(int x, int y, boolean sound){
|
||||
public boolean tryPlaceBlock(int x, int y){
|
||||
if(recipe != null &&
|
||||
validPlace(x, y, recipe.result) && !ui.hasMouse() && cursorNear() &&
|
||||
state.inventory.hasItems(recipe.requirements)){
|
||||
validPlace(x, y, recipe.result) && !ui.hasMouse() && cursorNear()){
|
||||
|
||||
placeBlock(x, y, recipe, rotation, true, sound);
|
||||
|
||||
for(ItemStack stack : recipe.requirements){
|
||||
state.inventory.removeItem(stack);
|
||||
}
|
||||
placeBlock(x, y, recipe, rotation);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean tryDeleteBlock(int x, int y, boolean sound){
|
||||
public boolean tryDeleteBlock(int x, int y){
|
||||
if(cursorNear() && validBreak(x, y)){
|
||||
breakBlock(x, y, sound);
|
||||
breakBlock(x, y);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -189,7 +182,7 @@ public abstract class InputHandler extends InputAdapter{
|
||||
public boolean validPlace(int x, int y, Block type){
|
||||
for(Tile tile : state.teams.get(player.team).cores){
|
||||
if(tile.distanceTo(x * tilesize, y * tilesize) < coreBuildRange){
|
||||
return Placement.validPlace(player.team, x, y, type, rotation) &&
|
||||
return Build.validPlace(player.team, x, y, type, rotation) &&
|
||||
Vector2.dst(player.x, player.y, x * tilesize, y * tilesize) < Player.placeDistance;
|
||||
}
|
||||
}
|
||||
@ -198,35 +191,16 @@ public abstract class InputHandler extends InputAdapter{
|
||||
}
|
||||
|
||||
public boolean validBreak(int x, int y){
|
||||
return Placement.validBreak(player.team, x, y);
|
||||
return Build.validBreak(player.team, x, y);
|
||||
}
|
||||
|
||||
public void placeBlock(int x, int y, Recipe recipe, int rotation, boolean effects, boolean sound){
|
||||
public void placeBlock(int x, int y, Recipe recipe, int rotation){
|
||||
//todo multiplayer support
|
||||
player.addPlaceBlock(new PlaceRequest(x, y, rotation, recipe));
|
||||
/*
|
||||
if(!Net.client()){ //is server or singleplayer
|
||||
threads.run(() -> Placement.placeBlock(player.team, x, y, recipe, rotation, effects, sound));
|
||||
}
|
||||
|
||||
if(Net.active()){
|
||||
NetEvents.handlePlace(player, x, y, recipe, rotation);
|
||||
}
|
||||
|
||||
//todo fix this, call placed()
|
||||
if(!Net.client()){
|
||||
//Tile tile = world.tile(x, y);
|
||||
//if(tile != null) threads.run(() -> result.placed(tile));
|
||||
}*/
|
||||
player.addBuildRequest(new BuildRequest(x, y, rotation, recipe));
|
||||
}
|
||||
|
||||
public void breakBlock(int x, int y, boolean sound){
|
||||
if(!Net.client()){
|
||||
threads.run(() -> Placement.breakBlock(player.team, x, y, true, sound));
|
||||
}
|
||||
|
||||
if(Net.active()){
|
||||
NetEvents.handleBreak(x, y);
|
||||
}
|
||||
public void breakBlock(int x, int y){
|
||||
//todo multiplayer support
|
||||
player.addBuildRequest(new BuildRequest(x, y));
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import com.badlogic.gdx.math.Vector2;
|
||||
import io.anuke.mindustry.graphics.Shaders;
|
||||
import io.anuke.mindustry.ui.fragments.ToolFragment;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.Placement;
|
||||
import io.anuke.mindustry.world.Build;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.ucore.core.Graphics;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
@ -55,7 +55,7 @@ public enum PlaceMode{
|
||||
}
|
||||
|
||||
public void tapped(InputHandler input, int tilex, int tiley){
|
||||
input.tryPlaceBlock(tilex, tiley, true);
|
||||
input.tryPlaceBlock(tilex, tiley);
|
||||
}
|
||||
},
|
||||
touch{
|
||||
@ -67,7 +67,7 @@ public enum PlaceMode{
|
||||
}
|
||||
|
||||
public void tapped(InputHandler input, int x, int y){
|
||||
input.tryPlaceBlock(x, y, true);
|
||||
input.tryPlaceBlock(x, y);
|
||||
}
|
||||
},
|
||||
none{
|
||||
@ -110,7 +110,7 @@ public enum PlaceMode{
|
||||
}
|
||||
|
||||
public void tapped(InputHandler input, int x, int y){
|
||||
input.tryDeleteBlock(x, y, true);
|
||||
input.tryDeleteBlock(x, y);
|
||||
}
|
||||
},
|
||||
areaDelete{
|
||||
@ -172,7 +172,7 @@ public enum PlaceMode{
|
||||
tilex = this.rtilex; tiley = this.rtiley;
|
||||
endx = this.rendx; endy = this.rendy;
|
||||
|
||||
input.player.getPlaceQueue().clear();
|
||||
input.player.clearBuilding();
|
||||
|
||||
if(mobile){
|
||||
ToolFragment t = input.frag.tool;
|
||||
@ -186,13 +186,10 @@ public enum PlaceMode{
|
||||
}
|
||||
}
|
||||
|
||||
boolean first = true;
|
||||
|
||||
for(int cx = tilex; cx <= endx; cx ++){
|
||||
for(int cy = tiley; cy <= endy; cy ++){
|
||||
if(input.tryDeleteBlock(cx, cy, first)){
|
||||
first = false;
|
||||
}
|
||||
input.tryDeleteBlock(cx, cy);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -283,7 +280,7 @@ public enum PlaceMode{
|
||||
|
||||
int wx = tilex + px * Mathf.sign(endx - tilex),
|
||||
wy = tiley + py * Mathf.sign(endy - tiley);
|
||||
if(!Placement.validPlace(input.player.team, wx, wy, block, rotation)){
|
||||
if(!Build.validPlace(input.player.team, wx, wy, block, rotation)){
|
||||
Draw.color("placeInvalid");
|
||||
}else{
|
||||
Draw.color("accent");
|
||||
@ -315,22 +312,21 @@ public enum PlaceMode{
|
||||
process(input, tilex, tiley, endx, endy);
|
||||
|
||||
input.rotation = this.rotation;
|
||||
input.player.getPlaceQueue().clear();
|
||||
input.player.clearBuilding();
|
||||
|
||||
boolean first = true;
|
||||
for(int x = 0; x <= Math.abs(this.rendx - this.rtilex); x += input.recipe.result.size){
|
||||
for(int y = 0; y <= Math.abs(this.rendy - this.rtiley); y += input.recipe.result.size){
|
||||
if(input.tryPlaceBlock(
|
||||
input.tryPlaceBlock(
|
||||
tilex + x * Mathf.sign(endx - tilex),
|
||||
tiley + y * Mathf.sign(endy - tiley), first)){
|
||||
first = false;
|
||||
}
|
||||
|
||||
tiley + y * Mathf.sign(endy - tiley));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void process(InputHandler input, int tilex, int tiley, int endx, int endy){
|
||||
|
||||
//todo hold shift to snap
|
||||
/*
|
||||
if(Math.abs(tilex - endx) > Math.abs(tiley - endy)){
|
||||
endy = tiley;
|
||||
|
@ -27,7 +27,7 @@ public class NetEvents {
|
||||
}
|
||||
|
||||
@RemoteServer
|
||||
public static void notifySomethingFromClient(Player player, int x, float y){
|
||||
public static void notifySomethingFromClient(Player player, int x, float y, String asdsad, long l){
|
||||
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,6 @@ import io.anuke.mindustry.gen.CallClient;
|
||||
import io.anuke.mindustry.io.Version;
|
||||
import io.anuke.mindustry.net.Packet.ImportantPacket;
|
||||
import io.anuke.mindustry.net.Packet.UnimportantPacket;
|
||||
import io.anuke.mindustry.resource.Item;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.ucore.entities.Entities;
|
||||
import io.anuke.ucore.entities.EntityGroup;
|
||||
@ -136,17 +135,13 @@ public class Packets {
|
||||
}
|
||||
|
||||
public static class StateSyncPacket implements Packet, UnimportantPacket{
|
||||
public int[] items;
|
||||
//todo fix item syncing
|
||||
public float countdown, time;
|
||||
public int enemies, wave;
|
||||
public long timestamp;
|
||||
|
||||
@Override
|
||||
public void write(ByteBuffer buffer) {
|
||||
for(int i = 0; i < items.length; i ++){
|
||||
buffer.putInt(items[i]);
|
||||
}
|
||||
|
||||
buffer.putFloat(countdown);
|
||||
buffer.putFloat(time);
|
||||
buffer.putShort((short)enemies);
|
||||
@ -156,12 +151,6 @@ public class Packets {
|
||||
|
||||
@Override
|
||||
public void read(ByteBuffer buffer) {
|
||||
items = new int[Item.getAllItems().size];
|
||||
|
||||
for(int i = 0; i < items.length; i ++){
|
||||
items[i] = buffer.getInt();
|
||||
}
|
||||
|
||||
countdown = buffer.getFloat();
|
||||
time = buffer.getFloat();
|
||||
enemies = buffer.getShort();
|
||||
|
@ -1,4 +0,0 @@
|
||||
package io.anuke.mindustry.resource;
|
||||
|
||||
public interface CarryItem {
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
package io.anuke.mindustry.resource;
|
||||
|
||||
public class ItemStack implements CarryItem{
|
||||
public class ItemStack{
|
||||
public Item item;
|
||||
public int amount;
|
||||
|
||||
|
@ -1,15 +0,0 @@
|
||||
package io.anuke.mindustry.resource;
|
||||
|
||||
public class LiquidStack implements CarryItem{
|
||||
public Liquid liquid;
|
||||
public float amount;
|
||||
|
||||
public LiquidStack(Liquid liquid, float amount){
|
||||
this.liquid = liquid;
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public boolean equals(LiquidStack other){
|
||||
return other != null && other.liquid == liquid && other.amount == amount;
|
||||
}
|
||||
}
|
@ -54,7 +54,7 @@ public class Recipe {
|
||||
return r;
|
||||
}
|
||||
|
||||
public static Array<Recipe> all(){
|
||||
public static Array<Recipe> getAllRecipes(){
|
||||
return allRecipes;
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ public class ColorPickDialog extends Dialog{
|
||||
cons.accept(color);
|
||||
hide();
|
||||
}).size(44, 48).pad(0).padBottom(-5.1f).get();
|
||||
button.setChecked(players[0].getColor().equals(color));
|
||||
button.setChecked(players[0].color.equals(color));
|
||||
button.getStyle().imageUpColor = color;
|
||||
|
||||
if(i%4 == 3){
|
||||
|
@ -42,7 +42,7 @@ public class HostDialog extends FloatingDialog{
|
||||
Settings.save();
|
||||
});
|
||||
}).size(50f, 54f).get();
|
||||
button.update(() -> button.getStyle().imageUpColor = player.getColor());
|
||||
button.update(() -> button.getStyle().imageUpColor = player.color);
|
||||
}).width(w).height(70f).pad(4).colspan(3);
|
||||
|
||||
content().row();
|
||||
|
@ -222,7 +222,7 @@ public class JoinDialog extends FloatingDialog {
|
||||
Settings.save();
|
||||
});
|
||||
}).size(50f, 54f).get();
|
||||
button.update(() -> button.getStyle().imageUpColor = player.getColor());
|
||||
button.update(() -> button.getStyle().imageUpColor = player.color);
|
||||
}).width(w).height(70f).pad(4);
|
||||
content().row();
|
||||
content().add(pane).width(w + 34).pad(0);
|
||||
|
@ -17,7 +17,6 @@ import io.anuke.mindustry.ui.dialogs.FloatingDialog;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.BlockStats;
|
||||
import io.anuke.ucore.graphics.Draw;
|
||||
import io.anuke.ucore.graphics.Hue;
|
||||
import io.anuke.ucore.scene.Element;
|
||||
import io.anuke.ucore.scene.Group;
|
||||
import io.anuke.ucore.scene.actions.Actions;
|
||||
@ -40,6 +39,16 @@ public class BlocksFragment implements Fragment{
|
||||
private boolean shown = true;
|
||||
private Recipe hoveredDescriptionRecipe;
|
||||
private IntSet itemset = new IntSet();
|
||||
private int[] tmpItems;
|
||||
|
||||
{
|
||||
int size = 0;
|
||||
for(Item ignored : Item.getAllItems()){
|
||||
size ++;
|
||||
}
|
||||
|
||||
tmpItems = new int[size];
|
||||
}
|
||||
|
||||
public void build(Group parent){
|
||||
InputHandler input = control.input(0);
|
||||
@ -55,7 +64,7 @@ public class BlocksFragment implements Fragment{
|
||||
itemtable = new Table("button");
|
||||
itemtable.setVisible(() -> input.recipe == null && !state.mode.infiniteResources);
|
||||
itemtable.update(() -> {
|
||||
int[] items = state.inventory.readItems();
|
||||
int[] items = tmpItems;
|
||||
for(int i = 0; i < items.length; i ++){
|
||||
if(itemset.contains(items[i]) != (items[i] > 0)){
|
||||
updateItems();
|
||||
@ -186,10 +195,9 @@ public class BlocksFragment implements Fragment{
|
||||
table.add(image).size(size + 8);
|
||||
|
||||
image.update(() -> {
|
||||
boolean has = (state.inventory.hasItems(r.requirements));
|
||||
image.setTouchable(Touchable.enabled);
|
||||
for(Element e : istack.getChildren()){
|
||||
e.setColor(has ? Color.WHITE : Hue.lightness(0.33f));
|
||||
e.setColor(Color.WHITE);
|
||||
}
|
||||
|
||||
for(Player player : players){
|
||||
@ -287,7 +295,7 @@ public class BlocksFragment implements Fragment{
|
||||
Label reqlabel = new Label("");
|
||||
|
||||
reqlabel.update(()->{
|
||||
int current = state.inventory.getAmount(stack.item);
|
||||
int current = stack.amount;
|
||||
String text = Mathf.clamp(current, 0, stack.amount) + "/" + stack.amount;
|
||||
|
||||
reqlabel.setColor(current < stack.amount ? Colors.get("missingitems") : Color.WHITE);
|
||||
@ -364,7 +372,7 @@ public class BlocksFragment implements Fragment{
|
||||
};
|
||||
|
||||
int index = 0;
|
||||
int[] items = state.inventory.readItems();
|
||||
int[] items = tmpItems;
|
||||
|
||||
for(int i = 0; i < items.length; i ++){
|
||||
int amount = items[i];
|
||||
|
@ -118,7 +118,7 @@ public class PlayerListFragment implements Fragment{
|
||||
});
|
||||
|
||||
button.add(stack).size(h);
|
||||
button.labelWrap("[#" + player.getColor().toString().toUpperCase() + "]" + player.name).width(170f).pad(10);
|
||||
button.labelWrap("[#" + player.color.toString().toUpperCase() + "]" + player.name).width(170f).pad(10);
|
||||
button.add().grow();
|
||||
|
||||
button.addImage("icon-admin").size(14*2).visible(() -> player.isAdmin && !(!player.isLocal && Net.server())).padRight(5);
|
||||
|
@ -3,7 +3,6 @@ package io.anuke.mindustry.ui.fragments;
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.utils.Align;
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
import io.anuke.mindustry.core.GameState.State;
|
||||
import io.anuke.mindustry.input.InputHandler;
|
||||
import io.anuke.mindustry.input.PlaceMode;
|
||||
@ -12,6 +11,8 @@ import io.anuke.ucore.core.Graphics;
|
||||
import io.anuke.ucore.scene.Group;
|
||||
import io.anuke.ucore.scene.ui.layout.Table;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class ToolFragment implements Fragment{
|
||||
private Table tools;
|
||||
private InputHandler input;
|
||||
@ -52,7 +53,7 @@ public class ToolFragment implements Fragment{
|
||||
});
|
||||
|
||||
tools.setVisible(() ->
|
||||
!state.is(State.menu) && mobile && ((input.recipe != null && state.inventory.hasItems(input.recipe.requirements) &&
|
||||
!state.is(State.menu) && mobile && ((input.recipe != null &&
|
||||
input.placeMode == PlaceMode.cursor) || confirming)
|
||||
);
|
||||
|
||||
|
@ -68,8 +68,6 @@ public class Block extends BaseBlock {
|
||||
public boolean liquid;
|
||||
/**whether this floor can be placed on.*/
|
||||
public boolean placeableOn = true;
|
||||
/**time it takes to break*/
|
||||
public float breaktime = 18;
|
||||
/**tile entity health*/
|
||||
public int health = 40;
|
||||
/**base block explosiveness*/
|
||||
|
@ -7,15 +7,15 @@ import io.anuke.mindustry.content.blocks.Blocks;
|
||||
import io.anuke.mindustry.content.fx.Fx;
|
||||
import io.anuke.mindustry.entities.Units;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.resource.ItemStack;
|
||||
import io.anuke.mindustry.resource.Recipe;
|
||||
import io.anuke.mindustry.world.blocks.types.BuildBlock.BuildEntity;
|
||||
import io.anuke.ucore.core.Effects;
|
||||
import io.anuke.ucore.entities.Entities;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
import static io.anuke.mindustry.Vars.tilesize;
|
||||
import static io.anuke.mindustry.Vars.world;
|
||||
|
||||
public class Placement {
|
||||
public class Build {
|
||||
private static final Rectangle rect = new Rectangle();
|
||||
private static Array<Tile> tempTiles = new Array<>();
|
||||
|
||||
@ -28,17 +28,9 @@ public class Placement {
|
||||
Block block = tile.isLinked() ? tile.getLinked().block() : tile.block();
|
||||
Recipe result = Recipe.getByResult(block);
|
||||
|
||||
if(result != null){
|
||||
for(ItemStack stack : result.requirements){
|
||||
state.inventory.addItem(stack.item, (int)(stack.amount * breakDropAmount));
|
||||
}
|
||||
}
|
||||
//todo add break results to core inventory
|
||||
|
||||
if(tile.block().drops != null){
|
||||
state.inventory.addItem(tile.block().drops.item, tile.block().drops.amount);
|
||||
}
|
||||
|
||||
if(sound) threads.run(() -> Effects.sound("break", x * tilesize, y * tilesize));
|
||||
if(sound) Effects.sound("break", x * tilesize, y * tilesize);
|
||||
|
||||
if(!tile.block().isMultiblock() && !tile.isLinked()){
|
||||
tile.setBlock(Blocks.air);
|
||||
@ -56,7 +48,8 @@ public class Placement {
|
||||
return block;
|
||||
}
|
||||
|
||||
public static void placeBlock(Team team, int x, int y, Recipe recipe, int rotation, boolean effects, boolean sound){
|
||||
/**Places a BuildBlock at this location. Call validPlace first.*/
|
||||
public static void placeBlock(Team team, int x, int y, Recipe recipe, int rotation){
|
||||
Tile tile = world.tile(x, y);
|
||||
Block result = recipe.result;
|
||||
|
||||
@ -86,23 +79,16 @@ public class Placement {
|
||||
toplace.setTeam(team);
|
||||
}
|
||||
}
|
||||
|
||||
if(effects) Effects.effect(Fx.none, worldx * tilesize, worldy * tilesize);
|
||||
}
|
||||
}
|
||||
}else if(effects){
|
||||
Effects.effect(Fx.none, x * tilesize, y * tilesize);
|
||||
}
|
||||
|
||||
if(effects && sound){
|
||||
threads.run(() -> Effects.sound("place", x * tilesize, y * tilesize));
|
||||
}
|
||||
}
|
||||
|
||||
/**Returns whether a tile can be placed at this location by this team.*/
|
||||
public static boolean validPlace(Team team, int x, int y, Block type, int rotation){
|
||||
Recipe recipe = Recipe.getByResult(type);
|
||||
|
||||
if(recipe == null || !state.inventory.hasItems(recipe.requirements)){
|
||||
if(recipe == null){
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -121,7 +107,7 @@ public class Placement {
|
||||
if (e == null) return; //not sure why this happens?
|
||||
Rectangle rect = e.hitbox.getRect(e.x, e.y);
|
||||
|
||||
if (Placement.rect.overlaps(rect) && !e.isFlying()) {
|
||||
if (Build.rect.overlaps(rect) && !e.isFlying()) {
|
||||
result[0] = true;
|
||||
}
|
||||
});
|
||||
@ -160,13 +146,12 @@ public class Placement {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**Returns whether the tile at this position is breakable by this team*/
|
||||
public static boolean validBreak(Team team, int x, int y) {
|
||||
Tile tile = world.tile(x, y);
|
||||
|
||||
if (tile == null || tile.block().unbreakable) return false;
|
||||
|
||||
return (!tile.isLinked() || !tile.getLinked().block().unbreakable) && tile.breakable()
|
||||
&& (tile.getTeam() == Team.none || tile.getTeam() == team);
|
||||
return tile != null && !tile.block().unbreakable
|
||||
&& (!tile.isLinked() || !tile.getLinked().block().unbreakable) && tile.breakable() && (tile.getTeam() == Team.none || tile.getTeam() == team);
|
||||
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@ import com.badlogic.gdx.utils.reflect.ClassReflection;
|
||||
import io.anuke.mindustry.content.blocks.Blocks;
|
||||
import io.anuke.mindustry.entities.TileEntity;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.resource.Recipe;
|
||||
import io.anuke.mindustry.world.blocks.types.Floor;
|
||||
import io.anuke.mindustry.world.blocks.types.modules.InventoryModule;
|
||||
import io.anuke.mindustry.world.blocks.types.modules.LiquidModule;
|
||||
@ -132,10 +133,14 @@ public class Tile implements Position{
|
||||
this.team = (byte)team.ordinal();
|
||||
}
|
||||
|
||||
/**Returns the breaktime of the block, <i>or</i> the breaktime of the linked block, if this tile is linked.*/
|
||||
/**Returns the break time of the block, <i>or</i> the breaktime of the linked block, if this tile is linked.*/
|
||||
public float getBreakTime(){
|
||||
Block block = block();
|
||||
return link == 0 ? block.breaktime : getLinked().block().breaktime;
|
||||
Block block = target().block();
|
||||
if(Recipe.getByResult(block) != null){
|
||||
return Recipe.getByResult(block).cost;
|
||||
}else{
|
||||
return 15f;
|
||||
}
|
||||
}
|
||||
|
||||
public void setBlock(Block type, int rotation){
|
||||
|
@ -8,7 +8,6 @@ public class Rock extends Block {
|
||||
super(name);
|
||||
shadow = name+"shadow";
|
||||
breakable = true;
|
||||
breaktime = 10;
|
||||
alwaysReplace = true;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user