Destructible grey blocks / Content cleanup / Wave fixes / Impact balance

This commit is contained in:
Anuken
2019-02-16 11:10:01 -05:00
parent fbcbca6f24
commit 4677de80c1
51 changed files with 1077 additions and 728 deletions

View File

@@ -20,7 +20,7 @@ import io.anuke.mindustry.world.blocks.production.*;
import io.anuke.mindustry.world.blocks.sandbox.*;
import io.anuke.mindustry.world.blocks.storage.CoreBlock;
import io.anuke.mindustry.world.blocks.storage.LaunchPad;
import io.anuke.mindustry.world.blocks.storage.SortedUnloader;
import io.anuke.mindustry.world.blocks.storage.Unloader;
import io.anuke.mindustry.world.blocks.storage.Vault;
import io.anuke.mindustry.world.blocks.units.MechPad;
import io.anuke.mindustry.world.blocks.units.RepairPoint;
@@ -88,6 +88,7 @@ public class Blocks implements ContentList{
public void draw(Tile tile){}
public void load(){}
public void init(){}
public boolean isHidden(){ return true; }
public TextureRegion[] variantRegions(){
if(variantRegions == null){
variantRegions = new TextureRegion[]{Core.atlas.find("clear")};
@@ -883,13 +884,14 @@ public class Blocks implements ContentList{
}};
impactReactor = new ImpactReactor("impact-reactor"){{
requirements(Category.power, ItemStack.with(Items.lead, 1000, Items.silicon, 600, Items.graphite, 600, Items.thorium, 200, Items.surgealloy, 400, Items.metaglass, 200));
requirements(Category.power, ItemStack.with(Items.lead, 1000, Items.silicon, 600, Items.graphite, 800, Items.thorium, 200, Items.surgealloy, 500, Items.metaglass, 500));
size = 4;
health = 900;
powerProduction = 70f;
powerProduction = 80f;
useTime = 40f;
consumes.power(23f);
consumes.item(Items.blastCompound);
consumes.liquid(Liquids.water, 0.3f);
consumes.liquid(Liquids.water, 0.4f);
}};
//endregion power
@@ -1005,7 +1007,7 @@ public class Blocks implements ContentList{
itemCapacity = 300;
}};
unloader = new SortedUnloader("unloader"){{
unloader = new Unloader("unloader"){{
requirements(Category.distribution, ItemStack.with(Items.titanium, 50, Items.silicon, 60));
speed = 7f;
}};

View File

@@ -34,7 +34,7 @@ public class Fx implements ContentList{
bigShockwave, nuclearShockwave, explosion, blockExplosion, blockExplosionSmoke, shootSmall, shootHeal, shootSmallSmoke, shootBig, shootBig2, shootBigSmoke,
shootBigSmoke2, shootSmallFlame, shootLiquid, shellEjectSmall, shellEjectMedium,
shellEjectBig, lancerLaserShoot, lancerLaserShootSmoke, lancerLaserCharge, lancerLaserChargeBegin, lightningCharge, lightningShoot,
launchFull, unitSpawn, spawnShockwave, magmasmoke;
launchFull, unitSpawn, spawnShockwave, magmasmoke, impactShockwave, impactcloud, impactsmoke;
@Override
public void load(){
@@ -567,6 +567,13 @@ public class Fx implements ContentList{
Draw.reset();
});
impactShockwave = new Effect(13f, 300f, e -> {
Draw.color(Pal.lighterOrange, Color.LIGHT_GRAY, e.fin());
Lines.stroke(e.fout() * 4f + 0.2f);
Lines.poly(e.x, e.y, 60, e.fin() * 200f);
Draw.reset();
});
spawnShockwave = new Effect(20f, 400f, e -> {
Draw.color(Color.WHITE, Color.LIGHT_GRAY, e.fin());
Lines.stroke(e.fout() * 3f + 0.5f);
@@ -860,6 +867,22 @@ public class Fx implements ContentList{
Draw.reset();
});
});
impactsmoke = new Effect(60, e -> {
Angles.randLenVectors(e.id, 7, e.fin() * 20f, (x, y) -> {
float size = e.fslope() * 4f;
Draw.color(Color.LIGHT_GRAY, Color.GRAY, e.fin());
Draw.rect("circle", e.x + x, e.y + y, size, size);
Draw.reset();
});
});
impactcloud = new Effect(140, 400f, e -> {
Angles.randLenVectors(e.id, 20, e.finpow() * 160f, (x, y) -> {
float size = e.fout() * 15f;
Draw.color(Pal.lighterOrange, Color.LIGHT_GRAY, e.fin());
Draw.rect("circle", e.x + x, e.y + y, size, size);
Draw.reset();
});
});
redgeneratespark = new Effect(18, e -> {
Angles.randLenVectors(e.id, 5, e.fin() * 8f, (x, y) -> {
float len = e.fout() * 4f;

View File

@@ -228,6 +228,20 @@ public class Zones implements ContentList{
spacing = 2;
unitScaling = 2;
unitAmount = 2;
}},
new SpawnGroup(UnitTypes.dagger){{
begin = 12;
spacing = 2;
unitScaling = 2;
unitAmount = 2;
}},
new SpawnGroup(UnitTypes.crawler){{
begin = 12;
spacing = 3;
unitScaling = 3;
unitAmount = 2;
}}
);
}};
@@ -346,6 +360,12 @@ public class Zones implements ContentList{
end = 10;
}},
new SpawnGroup(UnitTypes.dagger){{
begin = 1;
unitScaling = 1;
spacing = 2;
}},
new SpawnGroup(UnitTypes.dagger){{
begin = 2;
unitScaling = 1;
@@ -418,6 +438,12 @@ public class Zones implements ContentList{
end = 10;
}},
new SpawnGroup(UnitTypes.titan){{
begin = 1;
unitScaling = 3;
spacing = 2;
}},
new SpawnGroup(UnitTypes.dagger){{
begin = 2;
spacing = 2;
@@ -508,59 +534,72 @@ public class Zones implements ContentList{
waveSpacing = 60 * 60 * 2;
spawns = Array.with(
new SpawnGroup(UnitTypes.titan){{
unitScaling = 2;
spacing = 2;
end = 10;
}},
new SpawnGroup(UnitTypes.titan){{
unitScaling = 2;
spacing = 2;
end = 10;
}},
new SpawnGroup(UnitTypes.dagger){{
begin = 2;
unitScaling = 1;
spacing = 2;
}},
new SpawnGroup(UnitTypes.crawler){{
begin = 1;
unitScaling = 2;
spacing = 2;
unitAmount = 3;
}},
new SpawnGroup(UnitTypes.dagger){{
begin = 10;
spacing = 2;
unitScaling = 2;
unitAmount = 2;
}},
new SpawnGroup(UnitTypes.dagger){{
begin = 2;
unitScaling = 1;
spacing = 2;
}},
new SpawnGroup(UnitTypes.ghoul){{
begin = 5;
unitScaling = 0.5f;
unitAmount = 1;
spacing = 5;
}},
new SpawnGroup(UnitTypes.dagger){{
begin = 10;
spacing = 2;
unitScaling = 2;
unitAmount = 2;
}},
new SpawnGroup(UnitTypes.wraith){{
begin = 10;
unitScaling = 1f;
unitAmount = 1;
spacing = 5;
}},
new SpawnGroup(UnitTypes.ghoul){{
begin = 5;
unitScaling = 0.5f;
unitAmount = 1;
spacing = 5;
}},
new SpawnGroup(UnitTypes.dagger){{
begin = 2;
unitScaling = 1;
spacing = 2;
}},
new SpawnGroup(UnitTypes.fortress){{
begin = 13;
unitScaling = 2;
spacing = 3;
}},
new SpawnGroup(UnitTypes.wraith){{
begin = 23;
unitScaling = 1f;
unitAmount = 1;
spacing = 2;
}},
new SpawnGroup(UnitTypes.wraith){{
begin = 10;
unitScaling = 1f;
unitAmount = 1;
spacing = 5;
}},
new SpawnGroup(UnitTypes.crawler){{
begin = 20;
unitScaling = 1;
spacing = 10;
unitScaling = 0.5f;
unitAmount = 10;
}}
new SpawnGroup(UnitTypes.dagger){{
begin = 2;
unitScaling = 1;
spacing = 2;
}},
new SpawnGroup(UnitTypes.wraith){{
begin = 23;
unitScaling = 1f;
unitAmount = 1;
spacing = 2;
}},
new SpawnGroup(UnitTypes.crawler){{
begin = 20;
unitScaling = 1;
spacing = 10;
unitScaling = 0.5f;
unitAmount = 10;
}}
);
}};
}};

View File

@@ -80,7 +80,7 @@ public class ContentLoader{
for(Content c : contentMap[type.ordinal()]){
if(c instanceof MappableContent){
String name = ((MappableContent) c).getContentName();
String name = ((MappableContent) c).name;
if(contentNameMap[type.ordinal()].containsKey(name)){
throw new IllegalArgumentException("Two content objects cannot have the same name! (issue: '" + name + "')");
}

View File

@@ -68,7 +68,7 @@ public class Logic implements ApplicationListener{
state.gameOver = state.launched = false;
state.teams = new Teams();
state.rules = new Rules();
state.rules.spawns = Waves.getDefaultSpawns();
state.rules.spawns = DefaultWaves.getDefaultSpawns();
state.stats = new Stats();
Time.clear();

View File

@@ -510,7 +510,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
for(Block block : blocksOut){
TextureRegion region = block.icon(Icon.medium);
if(region == Core.atlas.find("jjfgj")) continue;
if(!Core.atlas.isFound(region)) continue;
ImageButton button = new ImageButton("white", "clear-toggle");
button.getStyle().imageUp = new TextureRegionDrawable(region);
@@ -527,7 +527,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
group.getButtons().get(2).setChecked(true);
table.table("underline", extra -> extra.labelWrap(() -> editor.getDrawBlock().formalName).width(200f).center()).growX();
table.table("underline", extra -> extra.labelWrap(() -> editor.getDrawBlock().localizedName).width(200f).center()).growX();
table.row();
table.add(pane).growY().fillX();
}

View File

@@ -6,7 +6,7 @@ import io.anuke.mindustry.content.StatusEffects;
import io.anuke.mindustry.content.UnitTypes;
import io.anuke.mindustry.type.ItemStack;
public class Waves{
public class DefaultWaves{
private static Array<SpawnGroup> spawns;
public static Array<SpawnGroup> getDefaultSpawns(){
@@ -165,23 +165,4 @@ public class Waves{
}
return spawns;
}
public static void testWaves(Array<SpawnGroup> spawns, int from, int to){
for(int i = from; i <= to; i++){
System.out.print(i + ": ");
int total = 0;
for(SpawnGroup spawn : spawns){
int a = spawn.getUnitsSpawned(i);
total += a;
if(a > 0){
System.out.print(a + "x" + spawn.type.name);
System.out.print(" ");
}
}
System.out.print(" (" + total + ")");
System.out.println();
}
}
}

View File

@@ -82,7 +82,7 @@ public class GlobalData{
/** Returns whether or not this piece of content is unlocked yet.*/
public boolean isUnlocked(UnlockableContent content){
return content.alwaysUnlocked() || unlocked.getOr(content.getContentType(), ObjectSet::new).contains(content.getContentName());
return content.alwaysUnlocked() || unlocked.getOr(content.getContentType(), ObjectSet::new).contains(content.name);
}
/**
@@ -94,7 +94,7 @@ public class GlobalData{
if(content.alwaysUnlocked()) return;
//fire unlock event so other classes can use it
if(unlocked.getOr(content.getContentType(), ObjectSet::new).add(content.getContentName())){
if(unlocked.getOr(content.getContentType(), ObjectSet::new).add(content.name)){
modified = true;
content.onUnlock();
Events.fire(new UnlockEvent(content));

View File

@@ -1,15 +1,14 @@
package io.anuke.mindustry.game;
public abstract class MappableContent extends Content {
/**
* Returns the unqiue name of this piece of content.
* The name only needs to be unique for all content of this type.
* Do not use IDs for names! Make sure this string stays constant with each update unless removed.
*/
public abstract String getContentName();
public final String name;
public MappableContent(String name){
this.name = name;
}
@Override
public String toString(){
return getContentName();
return name;
}
}

View File

@@ -9,13 +9,13 @@ public enum RulePreset{
waveTimer = true;
waves = true;
unitDrops = true;
spawns = Waves.getDefaultSpawns();
spawns = DefaultWaves.getDefaultSpawns();
}}),
sandbox(() -> new Rules(){{
infiniteResources = true;
waves = true;
waveTimer = false;
spawns = Waves.getDefaultSpawns();
spawns = DefaultWaves.getDefaultSpawns();
}}),
attack(() -> new Rules(){{
enemyCheat = true;

View File

@@ -1,11 +1,24 @@
package io.anuke.mindustry.game;
import io.anuke.arc.Core;
import io.anuke.arc.graphics.g2d.TextureRegion;
import io.anuke.arc.scene.ui.layout.Table;
import io.anuke.mindustry.Vars;
/**Base interface for an unlockable content type.*/
public abstract class UnlockableContent extends MappableContent{
/**Localized, formal name. Never null. Set to block name if not found in bundle.*/
public String localizedName;
/**Localized description. May be null.*/
public String description;
public UnlockableContent(String name){
super(name);
this.localizedName = Core.bundle.get(getContentType() + "." + name + ".name", name);
this.description = Core.bundle.getOrNull(getContentType() + "." + name + ".description");
}
/**Returns the localized name of this content.*/
public abstract String localizedName();

View File

@@ -217,7 +217,7 @@ public abstract class SaveFileVersion{
stream.writeByte(arr.first().getContentType().ordinal());
stream.writeShort(arr.size);
for(Content c : arr){
stream.writeUTF(((MappableContent) c).getContentName());
stream.writeUTF(((MappableContent) c).name);
}
}
}

View File

@@ -13,8 +13,6 @@ import io.anuke.mindustry.graphics.Pal;
import io.anuke.mindustry.ui.ContentDisplay;
public class Item extends UnlockableContent implements Comparable<Item>{
public final String name;
public final String description;
public final Color color;
private TextureRegion[] regions;
@@ -41,7 +39,7 @@ public class Item extends UnlockableContent implements Comparable<Item>{
public boolean alwaysUnlocked = false;
public Item(String name, Color color){
this.name = name;
super(name);
this.color = color;
this.description = Core.bundle.getOrNull("item." + this.name + ".description");
@@ -93,11 +91,6 @@ public class Item extends UnlockableContent implements Comparable<Item>{
return Integer.compare(id, item.id);
}
@Override
public String getContentName(){
return name;
}
@Override
public ContentType getContentType(){
return ContentType.item;

View File

@@ -10,8 +10,6 @@ import io.anuke.mindustry.ui.ContentDisplay;
public class Liquid extends UnlockableContent{
public final Color color;
public final String name;
public final String description;
/**0-1, 0 is completely inflammable, anything above that may catch fire when exposed to heat, 0.5+ is very flammable.*/
public float flammability;
@@ -33,7 +31,7 @@ public class Liquid extends UnlockableContent{
public TextureRegion iconRegion;
public Liquid(String name, Color color){
this.name = name;
super(name);
this.color = new Color(color);
this.description = Core.bundle.getOrNull("liquid." + name + ".description");
}
@@ -67,11 +65,6 @@ public class Liquid extends UnlockableContent{
return localizedName();
}
@Override
public String getContentName(){
return name;
}
@Override
public ContentType getContentType(){
return ContentType.liquid;

View File

@@ -10,9 +10,6 @@ import io.anuke.mindustry.graphics.Pal;
import io.anuke.mindustry.ui.ContentDisplay;
public class Mech extends UnlockableContent{
public final String name;
public final String description;
public boolean flying;
public float speed = 1.1f;
public float maxSpeed = 10f;
@@ -38,8 +35,8 @@ public class Mech extends UnlockableContent{
public TextureRegion baseRegion, legRegion, region, iconRegion;
public Mech(String name, boolean flying){
super(name);
this.flying = flying;
this.name = name;
this.description = Core.bundle.get("mech." + name + ".description");
}
@@ -77,11 +74,6 @@ public class Mech extends UnlockableContent{
return iconRegion;
}
@Override
public String getContentName(){
return name;
}
@Override
public ContentType getContentType(){
return ContentType.mech;

View File

@@ -16,9 +16,6 @@ import io.anuke.mindustry.ui.ContentDisplay;
public class UnitType extends UnlockableContent{
protected final Supplier<? extends BaseUnit> constructor;
public final String name;
public final String description;
public float health = 60;
public float hitsize = 7f;
public float hitsizeTile = 4f;
@@ -44,7 +41,7 @@ public class UnitType extends UnlockableContent{
public TextureRegion iconRegion, legRegion, baseRegion, region;
public <T extends BaseUnit> UnitType(String name, Class<T> type, Supplier<T> mainConstructor){
this.name = name;
super(name);
this.constructor = mainConstructor;
this.description = Core.bundle.getOrNull("unit." + name + ".description");
@@ -88,11 +85,6 @@ public class UnitType extends UnlockableContent{
return ContentType.unit;
}
@Override
public String getContentName(){
return name;
}
public BaseUnit create(Team team){
BaseUnit unit = constructor.get();
unit.init(this, team);

View File

@@ -13,7 +13,6 @@ import static io.anuke.mindustry.Vars.data;
import static io.anuke.mindustry.Vars.state;
public class Zone extends UnlockableContent{
public final String name;
public final MapGenerator generator;
public ItemStack[] deployCost = {};
public ItemStack[] startingItems = {};
@@ -28,7 +27,7 @@ public class Zone extends UnlockableContent{
public int launchPeriod = 10;
public Zone(String name, MapGenerator generator){
this.name = name;
super(name);
this.generator = generator;
}
@@ -63,11 +62,6 @@ public class Zone extends UnlockableContent{
@Override
public TextureRegion getContentIcon(){ return null; }
@Override
public String getContentName(){
return name;
}
@Override
public String localizedName(){
return Core.bundle.get("zone."+name+".name");

View File

@@ -25,7 +25,7 @@ public class ContentDisplay{
int size = 8 * 6;
title.addImage(block.icon(Icon.large)).size(size);
title.add("[accent]" + block.formalName).padLeft(5);
title.add("[accent]" + block.localizedName).padLeft(5);
});
table.row();
@@ -34,8 +34,8 @@ public class ContentDisplay{
table.row();
if(block.fullDescription != null){
table.add(block.fullDescription).padLeft(5).padRight(5).width(400f).wrap().fillX();
if(block.description != null){
table.add(block.description).padLeft(5).padRight(5).width(400f).wrap().fillX();
table.row();
table.addImage("white").height(3).color(Color.LIGHT_GRAY).pad(8).padLeft(0).padRight(0).fillX();

View File

@@ -182,7 +182,7 @@ public class DeployDialog extends FloatingDialog{
r.row();
for(Block block : zone.blockRequirements){
r.addImage(block.icon(Icon.small)).size(8 * 3).padRight(4);
r.add(block.formalName).color(Color.LIGHT_GRAY);
r.add(block.localizedName).color(Color.LIGHT_GRAY);
r.addImage(data.isUnlocked(block) ? "icon-check-2" : "icon-cancel-2")
.color(data.isUnlocked(block) ? Color.LIGHT_GRAY : Color.SCARLET).padLeft(3);
r.row();

View File

@@ -166,7 +166,7 @@ public class TechTreeDialog extends FloatingDialog{
void unlock(TechNode node){
data.unlockContent(node.block);
data.removeItems(node.requirements);
showToast(Core.bundle.format("researched", node.block.formalName));
showToast(Core.bundle.format("researched", node.block.localizedName));
checkNodes(root);
hoverNode = null;
rebuild();
@@ -201,7 +201,7 @@ public class TechTreeDialog extends FloatingDialog{
infoTable.table(desc -> {
desc.left().defaults().left();
desc.add(node.block.formalName);
desc.add(node.block.localizedName);
desc.row();
if(locked(node)){
desc.table(t -> {

View File

@@ -37,7 +37,7 @@ public class TraceDialog extends FloatingDialog{
table.row();
table.add(Core.bundle.format("trace.structureblocksbroken", info.structureBlocksBroken));
table.row();
table.add(Core.bundle.format("trace.lastblockbroken", info.lastBlockBroken.formalName));
table.add(Core.bundle.format("trace.lastblockbroken", info.lastBlockBroken.localizedName));
table.row();
table.add().pad(5);
@@ -45,7 +45,7 @@ public class TraceDialog extends FloatingDialog{
table.add(Core.bundle.format("trace.totalblocksplaced", info.totalBlocksPlaced));
table.row();
table.add(Core.bundle.format("trace.lastblockplaced", info.lastBlockPlaced.formalName));
table.add(Core.bundle.format("trace.lastblockplaced", info.lastBlockPlaced.localizedName));
table.row();
cont.add(table);

View File

@@ -21,6 +21,11 @@ public class ZoneInfoDialog extends FloatingDialog{
addCloseButton();
}
@Override
protected void drawBackground(float x, float y){
drawDefaultBackground(x, y);
}
public void show(Zone zone){
setup(zone);
show();
@@ -61,7 +66,7 @@ public class ZoneInfoDialog extends FloatingDialog{
r.row();
for(Block block : zone.blockRequirements){
r.addImage(block.icon(Icon.small)).size(8 * 3).padRight(4);
r.add(block.formalName).color(Color.LIGHT_GRAY);
r.add(block.localizedName).color(Color.LIGHT_GRAY);
r.addImage(data.isUnlocked(block) ? "icon-check-2" : "icon-cancel-2")
.color(data.isUnlocked(block) ? Color.LIGHT_GRAY : Color.SCARLET).padLeft(3);
r.row();
@@ -91,11 +96,26 @@ public class ZoneInfoDialog extends FloatingDialog{
cont.row();
cont.add(Core.bundle.format("bestwave", data.getWaveScore(zone)));
}
cont.row();
cont.table(t -> {
t.left();
for(ItemStack stack : zone.startingItems){
t.addImage(stack.item.icon(Item.Icon.medium)).size(8 * 3).padRight(4);
t.label(() -> stack.amount + "");
}
}).growX().left();
}
});
cont.row();
cont.addButton(!zone.canConfigure() ? Core.bundle.format("configure.locked", zone.configureWave) : "$configure", () -> {
}).disabled(b -> !zone.canConfigure()).size(300f, 70f).padTop(5).get();
cont.row();
Button button = cont.addButton(zone.locked() ? "$uncover" : "$launch", () -> {
if(!data.isUnlocked(zone)){
data.removeItems(zone.itemRequirements);

View File

@@ -194,7 +194,7 @@ public class PlacementFragment extends Fragment{
topTable.table(header -> {
header.left();
header.add(new Image(lastDisplay.icon(Icon.medium))).size(8 * 4);
header.labelWrap(() -> !unlocked(lastDisplay) ? Core.bundle.get("blocks.unknown") : lastDisplay.formalName)
header.labelWrap(() -> !unlocked(lastDisplay) ? Core.bundle.get("blocks.unknown") : lastDisplay.localizedName)
.left().width(190f).padLeft(5);
header.add().growX();
if(unlocked(lastDisplay)){

View File

@@ -43,12 +43,6 @@ import java.util.Arrays;
import static io.anuke.mindustry.Vars.*;
public class Block extends BlockStorage{
/** internal name */
public final String name;
/** display name */
public String formalName;
/** Detailed description of the block. Can be as long as necesary. */
public final String fullDescription;
/** whether this block has a tile entity that updates */
public boolean update;
/** whether this block has health and can be destroyed */
@@ -122,9 +116,8 @@ public class Block extends BlockStorage{
protected TextureRegion region;
public Block(String name){
this.name = name;
this.formalName = Core.bundle.get("block." + name + ".name", name);
this.fullDescription = Core.bundle.getOrNull("block." + name + ".description");
super(name);
this.description = Core.bundle.getOrNull("block." + name + ".description");
this.solid = false;
}
@@ -256,7 +249,7 @@ public class Block extends BlockStorage{
@Override
public String localizedName(){
return formalName;
return localizedName;
}
@Override
@@ -274,11 +267,6 @@ public class Block extends BlockStorage{
return ContentType.block;
}
@Override
public String getContentName() {
return name;
}
/** Called after all blocks are created. */
@Override
public void init(){
@@ -479,7 +467,7 @@ public class Block extends BlockStorage{
}
public String getDisplayName(Tile tile){
return formalName;
return localizedName;
}
public TextureRegion getDisplayIcon(Tile tile){

View File

@@ -41,6 +41,10 @@ public abstract class BlockStorage extends UnlockableContent{
public final Consumers consumes = new Consumers();
public final Producers produces = new Producers();
public BlockStorage(String name){
super(name);
}
public boolean shouldConsume(Tile tile){
return true;
}

View File

@@ -128,7 +128,7 @@ public class Build{
if(tile == null) return false;
if(type.isMultiblock()){
if(type.canReplace(tile.block()) && tile.block().size == type.size && type.canPlaceOn(tile) && tile.getTeam() == team){
if(type.canReplace(tile.block()) && tile.block().size == type.size && type.canPlaceOn(tile) && tile.interactable(team)){
return true;
}
@@ -154,7 +154,7 @@ public class Build{
}
return true;
}else{
return (tile.getTeam() == Team.none || tile.getTeam() == team)
return tile.interactable(team)
&& contactsGround(tile.x, tile.y, type)
&& (!tile.floor().isLiquid || type.floating)
&& tile.floor().placeableOn
@@ -190,6 +190,6 @@ public class Build{
Tile tile = world.tile(x, y);
if(tile != null) tile = tile.target();
return tile != null && tile.block().canBreak(tile) && tile.breakable() && (!tile.block().synthetic() || tile.getTeam() == team);
return tile != null && tile.block().canBreak(tile) && tile.breakable() && tile.interactable(team);
}
}

View File

@@ -18,6 +18,11 @@ public class BlockPart extends Block{
hasPower = hasItems = hasLiquids = true;
}
@Override
public boolean isHidden(){
return true;
}
@Override
public void draw(Tile tile){
//do nothing

View File

@@ -70,10 +70,15 @@ public class BuildBlock extends Block{
Core.app.post(() -> Events.fire(new BlockBuildEndEvent(tile, team, false)));
}
@Override
public boolean isHidden(){
return true;
}
@Override
public String getDisplayName(Tile tile){
BuildEntity entity = tile.entity();
return Core.bundle.format("block.constructing", entity.block == null ? entity.previous.formalName : entity.block.formalName);
return Core.bundle.format("block.constructing", entity.block == null ? entity.previous.localizedName : entity.block.localizedName);
}
@Override

View File

@@ -14,7 +14,7 @@ public class OreBlock extends Floor{
public OreBlock(Item ore, Floor base){
super("ore-" + ore.name + "-" + base.name);
this.formalName = ore.localizedName() + " " + base.formalName;
this.localizedName = ore.localizedName() + " " + base.localizedName;
this.itemDrop = ore;
this.base = base;
this.variants = 3;

View File

@@ -6,20 +6,32 @@ import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.TextureRegion;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.util.Strings;
import io.anuke.arc.util.Time;
import io.anuke.arc.util.Tmp;
import io.anuke.mindustry.content.Fx;
import io.anuke.mindustry.entities.Damage;
import io.anuke.mindustry.entities.Effects;
import io.anuke.mindustry.entities.type.TileEntity;
import io.anuke.mindustry.graphics.Pal;
import io.anuke.mindustry.ui.Bar;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.consumers.ConsumePower;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import static io.anuke.mindustry.Vars.tilesize;
public class ImpactReactor extends PowerGenerator{
protected int timerUse = timers++;
protected int plasmas = 4;
protected float warmupSpeed = 0.001f;
protected float useTime = 60f;
protected int explosionRadius = 30;
protected int explosionDamage = 180;
protected Color plasma1 = Color.valueOf("ffd06b"), plasma2 = Color.valueOf("ff361b");
protected Color ind1 = Color.valueOf("858585"), ind2 = Color.valueOf("fea080");
@@ -34,6 +46,17 @@ public class ImpactReactor extends PowerGenerator{
outputsPower = consumesPower = true;
}
@Override
public void setBars(){
super.setBars();
bars.add("poweroutput", entity -> new Bar(() ->
Core.bundle.format("blocks.poweroutput",
Strings.toFixed(Math.max(entity.tile.block().getPowerProduction(entity.tile) - consumes.get(ConsumePower.class).powerPerTick, 0)*60, 1)),
() -> Pal.powerBar,
() -> ((GeneratorEntity)entity).productionEfficiency));
}
@Override
public void update(Tile tile){
FusionReactorEntity entity = tile.entity();
@@ -118,7 +141,28 @@ public class ImpactReactor extends PowerGenerator{
if(entity.warmup < 0.4f) return;
//TODO catastrophic failure
Effects.shake(6f, 16f, tile.worldx(), tile.worldy());
Effects.effect(Fx.impactShockwave, tile.worldx(), tile.worldy());
for(int i = 0; i < 6; i++){
Time.run(Mathf.random(80), () -> Effects.effect(Fx.impactcloud, tile.worldx(), tile.worldy()));
}
Damage.damage(tile.worldx(), tile.worldy(), explosionRadius * tilesize, explosionDamage * 4);
for(int i = 0; i < 20; i++){
Time.run(Mathf.random(80), () -> {
Tmp.v1.rnd(Mathf.random(40f));
Effects.effect(Fx.explosion, Tmp.v1.x + tile.worldx(), Tmp.v1.y + tile.worldy());
});
}
for(int i = 0; i < 70; i++){
Time.run(Mathf.random(90), () -> {
Tmp.v1.rnd(Mathf.random(120f));
Effects.effect(Fx.impactsmoke, Tmp.v1.x + tile.worldx(), Tmp.v1.y + tile.worldy());
});
}
}
public static class FusionReactorEntity extends GeneratorEntity{

View File

@@ -20,13 +20,13 @@ import java.io.IOException;
import static io.anuke.mindustry.Vars.content;
public class SortedUnloader extends Block implements SelectionTrait{
public class Unloader extends Block implements SelectionTrait{
protected float speed = 1f;
protected final int timerUnload = timers++;
private static Item lastItem;
public SortedUnloader(String name){
public Unloader(String name){
super(name);
update = true;
solid = true;
@@ -59,7 +59,7 @@ public class SortedUnloader extends Block implements SelectionTrait{
if(tile.entity.timer.get(timerUnload, speed) && tile.entity.items.total() == 0){
for(Tile other : tile.entity.proximity()){
if(other.getTeam() == tile.getTeam() && other.block() instanceof StorageBlock && entity.items.total() == 0 &&
if(other.interactable(tile.getTeam()) && other.block() instanceof StorageBlock && entity.items.total() == 0 &&
((entity.sortItem == null && other.entity.items.total() > 0) || ((StorageBlock) other.block()).hasItem(other, entity.sortItem))){
offloadNear(tile, ((StorageBlock) other.block()).removeItem(other, entity.sortItem));
}

View File

@@ -12,7 +12,7 @@ import io.anuke.mindustry.world.meta.StatUnit;
/** Consumer class for blocks which consume power while being connected to a power graph. */
public class ConsumePower extends Consume{
/** The maximum amount of power which can be processed per tick. This might influence efficiency or load a buffer. */
protected final float powerPerTick;
public final float powerPerTick;
/** The maximum power capacity in power units. */
public final float powerCapacity;
/** True if the module can store power. */