message blocks
BIN
core/assets-raw/sprites/blocks/extra/message.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
@ -148,6 +148,7 @@ save.rename = Rename
|
||||
save.rename.text = New name:
|
||||
selectslot = Select a save.
|
||||
slot = [accent]Slot {0}
|
||||
editmessage = Edit Message
|
||||
save.corrupted = [accent]Save file corrupted or invalid!\nIf you have just updated your game, this is probably a change in the save format and [scarlet]not[] a bug.
|
||||
empty = <empty>
|
||||
on = On
|
||||
@ -772,6 +773,7 @@ block.junction.name = Junction
|
||||
block.router.name = Router
|
||||
block.distributor.name = Distributor
|
||||
block.sorter.name = Sorter
|
||||
block.message.name = Message
|
||||
block.overflow-gate.name = Overflow Gate
|
||||
block.silicon-smelter.name = Silicon Smelter
|
||||
block.phase-weaver.name = Phase Weaver
|
||||
@ -908,7 +910,6 @@ tutorial.waves = The[lightgray] enemy[] approaches.\n\nDefend the core for 2 wav
|
||||
tutorial.waves.mobile = The[lightgray] enemy[] approaches.\n\nDefend the core for 2 waves. Your ship will automatically fire at enemies.\nBuild more turrets and drills. Mine more copper.
|
||||
tutorial.launch = Once you reach a specific wave, you are able to[accent] launch the core[], leaving your defenses behind and[accent] obtaining all the resources in your core.[]\nThese resources can then be used to research new technology.\n\n[accent]Press the launch button.
|
||||
|
||||
|
||||
item.copper.description = The most basic structural material. Used extensively in all types of blocks.
|
||||
item.lead.description = A basic starter material. Used extensively in electronics and liquid transportation blocks.
|
||||
item.metaglass.description = A super-tough glass compound. Extensively used for liquid distribution and storage.
|
||||
@ -948,6 +949,7 @@ unit.eruptor.description = A heavy mech designed to take down structures. Fires
|
||||
unit.wraith.description = A fast, hit-and-run interceptor unit. Targets power generators.
|
||||
unit.ghoul.description = A heavy carpet bomber. Rips through enemy structures, targeting critical infrastructure.
|
||||
unit.revenant.description = A heavy, hovering missile array.
|
||||
block.message.description = Stores a message. Used for communication between allies.
|
||||
block.graphite-press.description = Compresses chunks of coal into pure sheets of graphite.
|
||||
block.multi-press.description = An upgraded version of the graphite press. Employs water and power to process coal quickly and efficiently.
|
||||
block.silicon-smelter.description = Reduces sand with pure coal. Produces silicon.
|
||||
|
Before Width: | Height: | Size: 718 B After Width: | Height: | Size: 722 B |
Before Width: | Height: | Size: 672 KiB After Width: | Height: | Size: 672 KiB |
Before Width: | Height: | Size: 258 KiB After Width: | Height: | Size: 258 KiB |
Before Width: | Height: | Size: 574 KiB After Width: | Height: | Size: 566 KiB |
@ -17,6 +17,7 @@ import io.anuke.mindustry.world.blocks.*;
|
||||
import io.anuke.mindustry.world.blocks.defense.*;
|
||||
import io.anuke.mindustry.world.blocks.defense.turrets.*;
|
||||
import io.anuke.mindustry.world.blocks.distribution.*;
|
||||
import io.anuke.mindustry.world.blocks.logic.*;
|
||||
import io.anuke.mindustry.world.blocks.power.*;
|
||||
import io.anuke.mindustry.world.blocks.production.*;
|
||||
import io.anuke.mindustry.world.blocks.sandbox.*;
|
||||
@ -47,7 +48,7 @@ public class Blocks implements ContentList{
|
||||
melter, separator, sporePress, pulverizer, incinerator, coalCentrifuge,
|
||||
|
||||
//sandbox
|
||||
powerVoid, powerSource, itemSource, liquidSource, itemVoid,
|
||||
powerVoid, powerSource, itemSource, liquidSource, itemVoid, message,
|
||||
|
||||
//defense
|
||||
scrapWall, scrapWallLarge, scrapWallHuge, scrapWallGigantic, thruster, //ok, these names are getting ridiculous, but at least I don't have humongous walls yet
|
||||
@ -731,6 +732,9 @@ public class Blocks implements ContentList{
|
||||
requirements(Category.liquid, () -> state.rules.infiniteResources, ItemStack.with());
|
||||
alwaysUnlocked = true;
|
||||
}};
|
||||
message = new MessageBlock("message"){{
|
||||
requirements(Category.effect, ItemStack.with(Items.graphite, 5));
|
||||
}};
|
||||
|
||||
//endregion
|
||||
//region defense
|
||||
|
@ -9,6 +9,7 @@ import io.anuke.arc.graphics.g2d.*;
|
||||
import io.anuke.arc.math.Angles;
|
||||
import io.anuke.arc.math.Mathf;
|
||||
import io.anuke.arc.math.geom.*;
|
||||
import io.anuke.arc.scene.ui.*;
|
||||
import io.anuke.arc.scene.ui.layout.*;
|
||||
import io.anuke.arc.util.*;
|
||||
import io.anuke.arc.util.pooling.Pools;
|
||||
@ -607,7 +608,7 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
|
||||
|
||||
float xa = Core.input.axis(Binding.move_x);
|
||||
float ya = Core.input.axis(Binding.move_y);
|
||||
if(!Core.input.keyDown(Binding.gridMode)){
|
||||
if(!Core.input.keyDown(Binding.gridMode) && !(Core.scene.getKeyboardFocus() instanceof TextField)){
|
||||
movement.y += ya * speed;
|
||||
movement.x += xa * speed;
|
||||
}
|
||||
|
@ -1,17 +1,14 @@
|
||||
package io.anuke.mindustry.ui.fragments;
|
||||
|
||||
import io.anuke.arc.Core;
|
||||
import io.anuke.arc.math.Interpolation;
|
||||
import io.anuke.arc.math.geom.Vector2;
|
||||
import io.anuke.arc.scene.Element;
|
||||
import io.anuke.arc.scene.Group;
|
||||
import io.anuke.arc.scene.actions.Actions;
|
||||
import io.anuke.arc.scene.ui.layout.Table;
|
||||
import io.anuke.arc.util.Align;
|
||||
import io.anuke.mindustry.content.Blocks;
|
||||
import io.anuke.mindustry.core.GameState.State;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.arc.*;
|
||||
import io.anuke.arc.math.*;
|
||||
import io.anuke.arc.scene.*;
|
||||
import io.anuke.arc.scene.actions.*;
|
||||
import io.anuke.arc.scene.ui.layout.*;
|
||||
import io.anuke.arc.util.*;
|
||||
import io.anuke.mindustry.content.*;
|
||||
import io.anuke.mindustry.core.GameState.*;
|
||||
import io.anuke.mindustry.world.*;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
@ -66,10 +63,10 @@ public class BlockConfigFragment extends Fragment{
|
||||
}
|
||||
|
||||
table.setOrigin(Align.center);
|
||||
Vector2 pos = Core.input.mouseScreen(tile.drawx(), tile.drawy() - tile.block().size * tilesize / 2f - 1);
|
||||
table.setPosition(pos.x, pos.y, Align.top);
|
||||
if(configTile == null || configTile.block() == Blocks.air || configTile.block() != configBlock){
|
||||
hideConfig();
|
||||
}else{
|
||||
configTile.block().updateTableAlign(tile, table);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -439,11 +439,17 @@ public class Block extends BlockStorage{
|
||||
|
||||
/**
|
||||
* Called when this block is tapped to build a UI on the table.
|
||||
* {@link #configurable} able} must return true for this to be called.
|
||||
* {@link #configurable} must return true for this to be called.
|
||||
*/
|
||||
public void buildTable(Tile tile, Table table){
|
||||
}
|
||||
|
||||
/** Update table alignment after configuring.*/
|
||||
public void updateTableAlign(Tile tile, Table table){
|
||||
Vector2 pos = Core.input.mouseScreen(tile.drawx(), tile.drawy() - tile.block().size * tilesize / 2f - 1);
|
||||
table.setPosition(pos.x, pos.y, Align.top);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when another tile is tapped while this block is selected.
|
||||
* Returns whether or not this block should be deselected.
|
||||
|
131
core/src/io/anuke/mindustry/world/blocks/logic/MessageBlock.java
Normal file
@ -0,0 +1,131 @@
|
||||
package io.anuke.mindustry.world.blocks.logic;
|
||||
|
||||
import io.anuke.annotations.Annotations.*;
|
||||
import io.anuke.arc.*;
|
||||
import io.anuke.arc.Input.*;
|
||||
import io.anuke.arc.graphics.*;
|
||||
import io.anuke.arc.graphics.g2d.*;
|
||||
import io.anuke.arc.math.geom.*;
|
||||
import io.anuke.arc.scene.ui.*;
|
||||
import io.anuke.arc.scene.ui.layout.*;
|
||||
import io.anuke.arc.util.*;
|
||||
import io.anuke.arc.util.pooling.*;
|
||||
import io.anuke.mindustry.entities.type.*;
|
||||
import io.anuke.mindustry.gen.*;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.mindustry.net.*;
|
||||
import io.anuke.mindustry.ui.dialogs.*;
|
||||
import io.anuke.mindustry.world.*;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class MessageBlock extends Block{
|
||||
protected static int maxTextLength = 150;
|
||||
|
||||
public MessageBlock(String name){
|
||||
super(name);
|
||||
configurable = true;
|
||||
solid = true;
|
||||
destructible = true;
|
||||
}
|
||||
|
||||
@Remote(targets = Loc.both, called = Loc.both, forward = true)
|
||||
public static void setMessageBlockText(Player player, Tile tile, String text){
|
||||
if(Net.server() && text.length() > maxTextLength){
|
||||
throw new ValidateException(player, "Player has gone above text limit.");
|
||||
}
|
||||
|
||||
//can be broken while a player is typing
|
||||
if(!(tile.block() instanceof MessageBlock)){
|
||||
return;
|
||||
}
|
||||
|
||||
MessageBlockEntity entity = tile.entity();
|
||||
if(entity != null){
|
||||
entity.message = text.replace("\r", "\n");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawSelect(Tile tile){
|
||||
MessageBlockEntity entity = tile.entity();
|
||||
BitmapFont font = Core.scene.skin.getFont("outline");
|
||||
GlyphLayout l = Pools.obtain(GlyphLayout.class, GlyphLayout::new);
|
||||
boolean ints = font.usesIntegerPositions();
|
||||
font.getData().setScale(1 / 4f / UnitScl.dp.scl(1f));
|
||||
font.setUseIntegerPositions(false);
|
||||
|
||||
String text = entity.message == null || entity.message.isEmpty() ? "[lightgray]" + Core.bundle.get("empty") : entity.message;
|
||||
|
||||
l.setText(font, text, Color.WHITE, 90f, Align.left, false);
|
||||
float offset = 1f;
|
||||
|
||||
Draw.color(0f, 0f, 0f, 0.2f);
|
||||
Fill.rect(tile.drawx(), tile.drawy() - tilesize/2f - l.height/2f - offset, l.width + offset*2f, l.height + offset*2f);
|
||||
Draw.color();
|
||||
font.draw(text, tile.drawx() - l.width/2f, tile.drawy() - tilesize/2f - offset, 90f, Align.left, false);
|
||||
font.setUseIntegerPositions(ints);
|
||||
|
||||
font.getData().setScale(1f);
|
||||
|
||||
Pools.free(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildTable(Tile tile, Table table){
|
||||
MessageBlockEntity entity = tile.entity();
|
||||
|
||||
table.addImageButton("icon-pencil-small", iconsizesmall, () -> {
|
||||
if(mobile){
|
||||
Core.input.getTextInput(new TextInput(){{
|
||||
text = entity.message;
|
||||
multiline = true;
|
||||
maxLength = maxTextLength;
|
||||
accepted = out -> {
|
||||
Call.setMessageBlockText(player, tile, out);
|
||||
};
|
||||
}});
|
||||
}else{
|
||||
FloatingDialog dialog = new FloatingDialog("$editmessage");
|
||||
dialog.setFillParent(false);
|
||||
TextArea a = dialog.cont.add(new TextArea(entity.message.replace("\n", "\r"))).size(340f, 160f).get();
|
||||
a.setMaxLength(maxTextLength);
|
||||
dialog.buttons.addButton("$ok", () -> {
|
||||
Call.setMessageBlockText(player, tile, a.getText());
|
||||
dialog.hide();
|
||||
}).size(130f, 60f);
|
||||
dialog.show();
|
||||
}
|
||||
control.input.frag.config.hideConfig();
|
||||
}).size(40f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTableAlign(Tile tile, Table table){
|
||||
Vector2 pos = Core.input.mouseScreen(tile.drawx(), tile.drawy() + tile.block().size * tilesize / 2f + 1);
|
||||
table.setPosition(pos.x, pos.y, Align.bottom);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileEntity newEntity(){
|
||||
return new MessageBlockEntity();
|
||||
}
|
||||
|
||||
public class MessageBlockEntity extends TileEntity{
|
||||
public String message = "";
|
||||
|
||||
@Override
|
||||
public void write(DataOutput stream) throws IOException{
|
||||
super.write(stream);
|
||||
stream.writeUTF(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(DataInput stream, byte revision) throws IOException{
|
||||
super.read(stream, revision);
|
||||
message = stream.readUTF();
|
||||
}
|
||||
}
|
||||
}
|