mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-07-04 15:27:19 +07:00
Replaced 'loadout' class with schematics / Small sound tweaks
This commit is contained in:
@ -1,10 +1,12 @@
|
||||
package io.anuke.mindustry.content;
|
||||
|
||||
import io.anuke.mindustry.ctype.ContentList;
|
||||
import io.anuke.mindustry.type.Loadout;
|
||||
import io.anuke.mindustry.ctype.*;
|
||||
import io.anuke.mindustry.game.*;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public class Loadouts implements ContentList{
|
||||
public static Loadout
|
||||
public static Schematic
|
||||
basicShard,
|
||||
advancedShard,
|
||||
basicFoundation,
|
||||
@ -12,43 +14,13 @@ public class Loadouts implements ContentList{
|
||||
|
||||
@Override
|
||||
public void load(){
|
||||
basicShard = new Loadout(
|
||||
" ### ",
|
||||
" #1# ",
|
||||
" ### ",
|
||||
" ^ ^ ",
|
||||
" ## ## ",
|
||||
" C# C# "
|
||||
);
|
||||
|
||||
advancedShard = new Loadout(
|
||||
" ### ",
|
||||
" #1# ",
|
||||
"#######",
|
||||
"C#^ ^C#",
|
||||
" ## ## ",
|
||||
" C# C# "
|
||||
);
|
||||
|
||||
basicFoundation = new Loadout(
|
||||
" #### ",
|
||||
" #### ",
|
||||
" #2## ",
|
||||
" #### ",
|
||||
" ^^^^ ",
|
||||
" ###### ",
|
||||
" C#C#C# "
|
||||
);
|
||||
|
||||
basicNucleus = new Loadout(
|
||||
" ##### ",
|
||||
" ##### ",
|
||||
" ##3## ",
|
||||
" ##### ",
|
||||
" >#####< ",
|
||||
" ^ ^ ^ ^ ",
|
||||
"#### ####",
|
||||
"C#C# C#C#"
|
||||
);
|
||||
try{
|
||||
basicShard = Schematics.readBase64("bXNjaAB4nD2K2wqAIBiD5ymibnoRn6YnEP1BwUMoBL19FuJ2sbFvUFgYZDaJsLeQrkinN9UJHImsNzlYE7WrIUastuSbnlKx2VJJt+8IQGGKdfO/8J5yrGJSMegLg+YUIA==");
|
||||
advancedShard = Schematics.readBase64("bXNjaAB4nD2LjQqAIAyET7OMIOhFfJqeYMxBgSkYCL199gu33fFtB4tOwUTaBCP5QpHFzwtl32DahBeKK1NwPq8hoOcUixwpY+CUxe3XIwBbB/pa6tadVCUP02hgHvp5vZq/0b7pBHPYFOQ=");
|
||||
basicFoundation = Schematics.readBase64("bXNjaAB4nD1OSQ6DMBBzFhVu8BG+0X8MQyoiJTNSukj8nlCi2Adbtg/GA4OBF8oB00rvyE/9ykafqOIw58A7SWRKy1ZiShhZ5RcOLZhYS1hefQ1gRIeptH9jq/qW2lvc1d2tgWsOfVX/tOwE86AYBA==");
|
||||
basicNucleus = Schematics.readBase64("bXNjaAB4nD2MUQqAIBBEJy0s6qOLdJXuYNtCgikYBd2+LNmdj308hkGHtkId7M4YFns4mk/yfB4a48602eDI+mlNznu0FMPFd0wYKCaewl8F0EOueqM+yKSLVfJrNKWnSw/FZGzEGXFG9sy/px4gEBW1");
|
||||
}catch(IOException e){
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import io.anuke.arc.util.ArcAnnotate.*;
|
||||
import io.anuke.mindustry.*;
|
||||
import io.anuke.mindustry.type.*;
|
||||
import io.anuke.mindustry.world.*;
|
||||
import io.anuke.mindustry.world.blocks.storage.*;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
@ -39,6 +40,16 @@ public class Schematic implements Publishable, Comparable<Schematic>{
|
||||
return stacks;
|
||||
}
|
||||
|
||||
public boolean hasCore(){
|
||||
return tiles.contains(s -> s.block instanceof CoreBlock);
|
||||
}
|
||||
|
||||
public @NonNull CoreBlock findCore(){
|
||||
CoreBlock block = (CoreBlock)tiles.find(s -> s.block instanceof CoreBlock).block;
|
||||
if(block == null) throw new IllegalArgumentException("Schematic is missing a core!");
|
||||
return block;
|
||||
}
|
||||
|
||||
public String name(){
|
||||
return tags.get("name", "unknown");
|
||||
}
|
||||
|
@ -20,6 +20,8 @@ import io.anuke.mindustry.input.Placement.*;
|
||||
import io.anuke.mindustry.type.*;
|
||||
import io.anuke.mindustry.world.*;
|
||||
import io.anuke.mindustry.world.blocks.*;
|
||||
import io.anuke.mindustry.world.blocks.production.*;
|
||||
import io.anuke.mindustry.world.blocks.storage.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.zip.*;
|
||||
@ -28,6 +30,8 @@ import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
/** Handles schematics.*/
|
||||
public class Schematics implements Loadable{
|
||||
public static final String base64Header = "bXNjaAB";
|
||||
|
||||
private static final byte[] header = {'m', 's', 'c', 'h'};
|
||||
private static final byte version = 0;
|
||||
|
||||
@ -231,6 +235,27 @@ public class Schematics implements Loadable{
|
||||
.removeAll(s -> !s.block.isVisible() || !s.block.unlockedCur());
|
||||
}
|
||||
|
||||
public void placeLoadout(Schematic schem, int x, int y){
|
||||
Stile coreTile = schem.tiles.find(s -> s.block instanceof CoreBlock);
|
||||
int ox = x - coreTile.x, oy = y - coreTile.y;
|
||||
schem.tiles.each(st -> {
|
||||
Tile tile = world.tile(st.x + ox, st.y + oy);
|
||||
if(tile == null) return;
|
||||
|
||||
world.setBlock(tile, st.block, defaultTeam);
|
||||
tile.rotation(st.rotation);
|
||||
if(st.block.posConfig){
|
||||
tile.configureAny(Pos.get(tile.x - st.x + Pos.x(st.config), tile.y - st.y + Pos.y(st.config)));
|
||||
}else{
|
||||
tile.configureAny(st.config);
|
||||
}
|
||||
|
||||
if(st.block instanceof Drill){
|
||||
tile.getLinkedTiles(t -> t.setOverlay(Blocks.oreCopper));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** Adds a schematic to the list, also copying it into the files.*/
|
||||
public void add(Schematic schematic){
|
||||
all.add(schematic);
|
||||
@ -328,13 +353,13 @@ public class Schematics implements Loadable{
|
||||
}
|
||||
}
|
||||
|
||||
//region IO methods
|
||||
|
||||
/** Loads a schematic from base64. May throw an exception. */
|
||||
public Schematic readBase64(String schematic) throws IOException{
|
||||
public static Schematic readBase64(String schematic) throws IOException{
|
||||
return read(new ByteArrayInputStream(Base64Coder.decode(schematic)));
|
||||
}
|
||||
|
||||
//region IO methods
|
||||
|
||||
public static Schematic read(FileHandle file) throws IOException{
|
||||
Schematic s = read(new DataInputStream(file.read(1024)));
|
||||
if(!s.tags.containsKey("name")){
|
||||
|
@ -33,7 +33,7 @@ public class Stats{
|
||||
score += (float)((wavesLasted - zone.conditionWave) / zone.launchPeriod + 1) * 1.2f;
|
||||
}
|
||||
|
||||
int capacity = zone.loadout.core().itemCapacity;
|
||||
int capacity = zone.loadout.findCore().itemCapacity;
|
||||
|
||||
//weigh used fractions
|
||||
float frac = 0f;
|
||||
|
@ -122,7 +122,7 @@ public class DesktopInput extends InputHandler{
|
||||
drawSelected(sreq.x, sreq.y, sreq.block, getRequest(sreq.x, sreq.y, sreq.block.size, sreq) != null ? Pal.remove : Pal.accent);
|
||||
}
|
||||
|
||||
if(Core.input.keyDown(Binding.schematic_select)){
|
||||
if(Core.input.keyDown(Binding.schematic_select) && !ui.chatfrag.chatOpen()){
|
||||
drawSelection(schemX, schemY, cursorX, cursorY, Vars.maxSchematicSize);
|
||||
}
|
||||
|
||||
@ -305,7 +305,7 @@ public class DesktopInput extends InputHandler{
|
||||
selectRequests.clear();
|
||||
}
|
||||
|
||||
if(Core.input.keyRelease(Binding.schematic_select)){
|
||||
if(Core.input.keyRelease(Binding.schematic_select) && !ui.chatfrag.chatOpen()){
|
||||
lastSchematic = schematics.create(schemX, schemY, rawCursorX, rawCursorY);
|
||||
useSchematic(lastSchematic);
|
||||
if(selectRequests.isEmpty()){
|
||||
|
@ -1,11 +1,11 @@
|
||||
package io.anuke.mindustry.maps.generators;
|
||||
|
||||
import io.anuke.mindustry.type.Loadout;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.world.*;
|
||||
|
||||
public abstract class Generator{
|
||||
public int width, height;
|
||||
protected Loadout loadout;
|
||||
protected Schematic loadout;
|
||||
|
||||
public Generator(int width, int height){
|
||||
this.width = width;
|
||||
@ -15,7 +15,7 @@ public abstract class Generator{
|
||||
public Generator(){
|
||||
}
|
||||
|
||||
public void init(Loadout loadout){
|
||||
public void init(Schematic loadout){
|
||||
this.loadout = loadout;
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@ import io.anuke.arc.math.*;
|
||||
import io.anuke.arc.math.geom.*;
|
||||
import io.anuke.arc.util.*;
|
||||
import io.anuke.mindustry.content.*;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.io.*;
|
||||
import io.anuke.mindustry.maps.*;
|
||||
import io.anuke.mindustry.type.*;
|
||||
@ -52,7 +53,7 @@ public class MapGenerator extends Generator{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Loadout loadout){
|
||||
public void init(Schematic loadout){
|
||||
this.loadout = loadout;
|
||||
map = maps.loadInternalMap(mapName);
|
||||
width = map.width;
|
||||
@ -149,7 +150,7 @@ public class MapGenerator extends Generator{
|
||||
throw new IllegalArgumentException("All zone maps must have a core.");
|
||||
}
|
||||
|
||||
loadout.setup(core.x, core.y);
|
||||
schematics.placeLoadout(loadout, core.x, core.y);
|
||||
|
||||
world.prepareTiles(tiles);
|
||||
world.setMap(map);
|
||||
|
@ -5,6 +5,8 @@ import io.anuke.mindustry.content.Blocks;
|
||||
import io.anuke.mindustry.maps.generators.BasicGenerator;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
|
||||
import static io.anuke.mindustry.Vars.schematics;
|
||||
|
||||
public class DesertWastesGenerator extends BasicGenerator{
|
||||
|
||||
public DesertWastesGenerator(int width, int height){
|
||||
@ -42,6 +44,6 @@ public class DesertWastesGenerator extends BasicGenerator{
|
||||
//scatter(tiles, Blocks.sandRocks, Blocks.creeptree, 1f);
|
||||
|
||||
tiles[endX][endY].setOverlay(Blocks.spawn);
|
||||
loadout.setup(spawnX, spawnY);
|
||||
schematics.placeLoadout(loadout, spawnX, spawnY);
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,8 @@ import io.anuke.mindustry.content.Blocks;
|
||||
import io.anuke.mindustry.maps.generators.BasicGenerator;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
|
||||
import static io.anuke.mindustry.Vars.schematics;
|
||||
|
||||
public class OvergrowthGenerator extends BasicGenerator{
|
||||
|
||||
public OvergrowthGenerator(int width, int height){
|
||||
@ -38,6 +40,6 @@ public class OvergrowthGenerator extends BasicGenerator{
|
||||
//scatter(tiles, Blocks.sporePine, Blocks.whiteTreeDead, 1f);
|
||||
|
||||
tiles[endX][endY].setOverlay(Blocks.spawn);
|
||||
loadout.setup(spawnX, spawnY);
|
||||
schematics.placeLoadout(loadout, spawnX, spawnY);
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,19 @@ public class ContentParser{
|
||||
private ObjectMap<Class<?>, FieldParser> classParsers = new ObjectMap<Class<?>, FieldParser>(){{
|
||||
put(Effect.class, (type, data) -> field(Fx.class, data));
|
||||
put(StatusEffect.class, (type, data) -> field(StatusEffects.class, data));
|
||||
put(Loadout.class, (type, data) -> field(Loadouts.class, data));
|
||||
put(Schematic.class, (type, data) -> {
|
||||
Object result = fieldOpt(Loadouts.class, data);
|
||||
if(result != null){
|
||||
return result;
|
||||
}else{
|
||||
String str = data.asString();
|
||||
if(str.startsWith(Schematics.base64Header)){
|
||||
return Schematics.readBase64(str);
|
||||
}else{
|
||||
return Schematics.read(Vars.tree.get("schematics/" + str + "." + Vars.schematicExtension));
|
||||
}
|
||||
}
|
||||
});
|
||||
put(Color.class, (type, data) -> Color.valueOf(data.asString()));
|
||||
put(BulletType.class, (type, data) -> {
|
||||
if(data.isString()){
|
||||
|
@ -1,113 +0,0 @@
|
||||
package io.anuke.mindustry.type;
|
||||
|
||||
import io.anuke.arc.collection.*;
|
||||
import io.anuke.mindustry.content.*;
|
||||
import io.anuke.mindustry.ctype.Content;
|
||||
import io.anuke.mindustry.world.*;
|
||||
import io.anuke.mindustry.world.blocks.storage.*;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
//TODO this class is a disappointment
|
||||
public class Loadout extends Content{
|
||||
private final Array<Tile> outArray = new Array<>();
|
||||
private final IntMap<BlockEntry> entries = new IntMap<BlockEntry>(){{
|
||||
put('>', new BlockEntry(Blocks.conveyor, 0));
|
||||
put('^', new BlockEntry(Blocks.conveyor, 1));
|
||||
put('<', new BlockEntry(Blocks.conveyor, 2));
|
||||
put('v', new BlockEntry(Blocks.conveyor, 3));
|
||||
|
||||
put('1', new BlockEntry(Blocks.coreShard));
|
||||
put('2', new BlockEntry(Blocks.coreFoundation));
|
||||
put('3', new BlockEntry(Blocks.coreNucleus));
|
||||
|
||||
put('C', new BlockEntry(Blocks.mechanicalDrill, Blocks.oreCopper));
|
||||
}};
|
||||
|
||||
private final IntMap<BlockEntry> blocks = new IntMap<>();
|
||||
private Block core;
|
||||
|
||||
public Loadout(String... layout){
|
||||
int coreX = -1, coreY = -1;
|
||||
|
||||
outer:
|
||||
for(int y = 0; y < layout.length; y++){
|
||||
for(int x = 0; x < layout[0].length(); x++){
|
||||
char c = layout[y].charAt(x);
|
||||
if(entries.get(c) != null && entries.get(c).block instanceof CoreBlock){
|
||||
core = entries.get(c).block;
|
||||
coreX = x;
|
||||
coreY = y;
|
||||
break outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(coreX == -1) throw new IllegalArgumentException("Schematic does not have a core.");
|
||||
|
||||
for(int y = 0; y < layout.length; y++){
|
||||
for(int x = 0; x < layout[0].length(); x++){
|
||||
char c = layout[y].charAt(x);
|
||||
if(entries.containsKey(c)){
|
||||
BlockEntry entry = entries.get(c);
|
||||
blocks.put(Pos.get(x - coreX, -(y - coreY)), entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Loadout(){
|
||||
|
||||
}
|
||||
|
||||
public Block core(){
|
||||
return core;
|
||||
}
|
||||
|
||||
public void setup(int x, int y){
|
||||
for(IntMap.Entry<BlockEntry> entry : blocks.entries()){
|
||||
int rx = Pos.x(entry.key);
|
||||
int ry = Pos.y(entry.key);
|
||||
Tile tile = world.tile(x + rx, y + ry);
|
||||
if(tile == null) continue;
|
||||
|
||||
world.setBlock(tile, entry.value.block, defaultTeam);
|
||||
tile.rotation((byte)entry.value.rotation);
|
||||
if(entry.value.ore != null){
|
||||
for(Tile t : tile.getLinkedTiles(outArray)){
|
||||
t.setOverlay(entry.value.ore);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContentType getContentType(){
|
||||
return ContentType.loadout;
|
||||
}
|
||||
|
||||
static class BlockEntry{
|
||||
final Block block;
|
||||
final Block ore;
|
||||
final int rotation;
|
||||
|
||||
BlockEntry(Block block, Block ore){
|
||||
this.block = block;
|
||||
this.ore = ore;
|
||||
this.rotation = 0;
|
||||
}
|
||||
|
||||
BlockEntry(Block block, int rotation){
|
||||
this.block = block;
|
||||
this.ore = null;
|
||||
this.rotation = rotation;
|
||||
}
|
||||
|
||||
BlockEntry(Block block){
|
||||
this.block = block;
|
||||
this.ore = null;
|
||||
this.rotation = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -26,7 +26,7 @@ public class Zone extends UnlockableContent{
|
||||
public boolean alwaysUnlocked;
|
||||
public int conditionWave = Integer.MAX_VALUE;
|
||||
public int launchPeriod = 10;
|
||||
public Loadout loadout = Loadouts.basicShard;
|
||||
public Schematic loadout = Loadouts.basicShard;
|
||||
public TextureRegion preview;
|
||||
|
||||
protected Array<ItemStack> baseLaunchCost = new Array<>();
|
||||
|
@ -153,7 +153,7 @@ public class SchematicsDialog extends FloatingDialog{
|
||||
t.addImageTextButton("$schematic.copy.import", Icon.copySmall, style, () -> {
|
||||
dialog.hide();
|
||||
try{
|
||||
Schematic s = schematics.readBase64(Core.app.getClipboardText());
|
||||
Schematic s = Schematics.readBase64(Core.app.getClipboardText());
|
||||
schematics.add(s);
|
||||
setup();
|
||||
ui.showInfoFade("$schematic.saved");
|
||||
|
@ -143,7 +143,7 @@ public class ZoneInfoDialog extends FloatingDialog{
|
||||
cont.row();
|
||||
|
||||
cont.addButton(zone.canConfigure() ? "$configure" : Core.bundle.format("configure.locked", zone.configureObjective.display()),
|
||||
() -> loadout.show(zone.loadout.core().itemCapacity, zone.getStartingItems(), zone::resetStartingItems, zone::updateLaunchCost, rebuildItems)
|
||||
() -> loadout.show(zone.loadout.findCore().itemCapacity, zone.getStartingItems(), zone::resetStartingItems, zone::updateLaunchCost, rebuildItems)
|
||||
).fillX().pad(3).disabled(b -> !zone.canConfigure());
|
||||
|
||||
cont.row();
|
||||
|
@ -16,7 +16,6 @@ import io.anuke.mindustry.world.blocks.BuildBlock.BuildEntity;
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class Build{
|
||||
private static final Rectangle rect = new Rectangle();
|
||||
|
||||
/** Returns block type that was broken, or null if unsuccesful. */
|
||||
@Remote(called = Loc.server)
|
||||
|
@ -7,6 +7,7 @@ import io.anuke.arc.Graphics.Cursor.*;
|
||||
import io.anuke.arc.graphics.g2d.*;
|
||||
import io.anuke.arc.math.*;
|
||||
import io.anuke.arc.util.ArcAnnotate.*;
|
||||
import io.anuke.arc.util.*;
|
||||
import io.anuke.mindustry.content.*;
|
||||
import io.anuke.mindustry.entities.*;
|
||||
import io.anuke.mindustry.entities.effect.*;
|
||||
@ -29,6 +30,10 @@ public class BuildBlock extends Block{
|
||||
public static final int maxSize = 9;
|
||||
private static final BuildBlock[] buildBlocks = new BuildBlock[maxSize];
|
||||
|
||||
private static long lastTime = 0;
|
||||
private static int pitchSeq = 0;
|
||||
private static long lastPlayed;
|
||||
|
||||
public BuildBlock(int size){
|
||||
super("build" + size);
|
||||
this.size = size;
|
||||
@ -53,7 +58,7 @@ public class BuildBlock extends Block{
|
||||
Effects.effect(Fx.breakBlock, tile.drawx(), tile.drawy(), block.size);
|
||||
world.removeBlock(tile);
|
||||
Events.fire(new BlockBuildEndEvent(tile, playerGroup.getByID(builderID), team, true));
|
||||
Sounds.breaks.at(tile, Mathf.random(0.7f, 1.4f));
|
||||
if(shouldPlay()) Sounds.breaks.at(tile, calcPitch(false));
|
||||
}
|
||||
|
||||
@Remote(called = Loc.server)
|
||||
@ -73,12 +78,36 @@ public class BuildBlock extends Block{
|
||||
Effects.effect(Fx.placeBlock, tile.drawx(), tile.drawy(), block.size);
|
||||
}
|
||||
|
||||
static boolean shouldPlay(){
|
||||
if(Time.timeSinceMillis(lastPlayed) >= 32){
|
||||
lastPlayed = Time.millis();
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static float calcPitch(boolean up){
|
||||
if(Time.timeSinceMillis(lastTime) < 16 * 30){
|
||||
lastTime = Time.millis();
|
||||
pitchSeq ++;
|
||||
if(pitchSeq > 30){
|
||||
pitchSeq = 0;
|
||||
}
|
||||
return 1f + Mathf.clamp(pitchSeq / 30f) * (up ? 1.9f : -0.4f);
|
||||
}else{
|
||||
pitchSeq = 0;
|
||||
lastTime = Time.millis();
|
||||
return Mathf.random(0.7f, 1.3f);
|
||||
}
|
||||
}
|
||||
|
||||
public static void constructed(Tile tile, Block block, int builderID, byte rotation, Team team, boolean skipConfig){
|
||||
Call.onConstructFinish(tile, block, builderID, rotation, team, skipConfig);
|
||||
tile.block().placed(tile);
|
||||
|
||||
Events.fire(new BlockBuildEndEvent(tile, playerGroup.getByID(builderID), team, false));
|
||||
Sounds.place.at(tile, Mathf.random(0.7f, 1.4f));
|
||||
if(shouldPlay()) Sounds.place.at(tile, calcPitch(true));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Reference in New Issue
Block a user