From 9924796ad90d74f3ed08d70de4ad6440fc6fe4c4 Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 8 Aug 2019 20:50:15 -0400 Subject: [PATCH] A somewhat complete tutorial --- core/assets/bundles/bundle.properties | 19 +++- core/src/io/anuke/mindustry/core/Control.java | 2 + core/src/io/anuke/mindustry/core/UI.java | 2 +- .../io/anuke/mindustry/game/EventType.java | 12 +- .../src/io/anuke/mindustry/game/Tutorial.java | 107 +++++++++++++++--- .../io/anuke/mindustry/input/MobileInput.java | 7 +- .../mindustry/ui/dialogs/PausedDialog.java | 46 ++++---- .../mindustry/ui/fragments/HudFragment.java | 6 +- .../ui/fragments/LoadingFragment.java | 2 +- .../mindustry/ui/fragments/MenuFragment.java | 4 +- .../ui/fragments/PlacementFragment.java | 9 +- .../blocks/defense/turrets/ItemTurret.java | 2 +- .../world/blocks/storage/CoreBlock.java | 9 +- 13 files changed, 161 insertions(+), 66 deletions(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 357d531014..8e2a9c3daf 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -158,6 +158,7 @@ openlink = Open Link copylink = Copy Link back = Back quit.confirm = Are you sure you want to quit? +quit.confirm.tutorial = Are you sure you want to quit the tutorial? loading = [accent]Loading... saving = [accent]Saving... wave = [accent]Wave {0} @@ -861,15 +862,21 @@ unit.chaos-array.name = Chaos Array unit.eradicator.name = Eradicator unit.lich.name = Lich unit.reaper.name = Reaper -tutorial.intro = Begin by[accent] mining copper[]. Tap a copper ore vein near your core to do this.\n\n[accent]{0}/{1} copper -tutorial.drill = Mining manually is inefficient.\n[accent]Drills []can mine automatically.\n\nClick the drill tab in the bottom right, then select the[accent] mechanical drill[]. Place it on a copper vein by clicking. +tutorial.intro = You have entered the[scarlet] Mindustry Tutorial.[]\n\nBegin by[accent] mining copper[]. Tap a copper ore vein near your core to do this.\n\n[accent]{0}/{1} copper +tutorial.drill = Mining manually is inefficient.\n[accent]Drills []can mine automatically.\n\nClick the drill tab in the bottom right, then select the[accent] mechanical drill[]. Place it on a copper vein by clicking.\n[accent]Right-click[] to stop building. tutorial.drill.mobile = Mining manually is inefficient.\n[accent]Drills []can mine automatically.\n\nTap the drill tab in the bottom right, then select the[accent] mechanical drill[]. Place it on a copper vein by tapping, then press the[accent] checkmark[] below to confirm your selection.\nPress the[accent] X button[] to cancel placement. -tutorial.conveyor = [accent]Conveyors[] are used to transport items to the core.\nMake a line of conveyors from the drill to the core.[yellow] Hold down the mouse to place in a line.[]\nHold[accent] CTRL[] while selecting a line to place diagonally.\n\n[accent]{0}/{1} conveyors -tutorial.conveyor.mobile = [accent]Conveyors[] are used to transport items to the core.\nMake a line of conveyors from the drill to the core.[yellow] Place in a line by holding down your finger for a few seconds[] and dragging in a direction.\n\n[accent]{0}/{1} conveyors -tutorial.turret = Defensive structures must be built to repel the[lightgray] enemy[].\nBuild a duo turret near your base. +tutorial.blockinfo = Each block has different stats. Each drill can only mine certain ores.\nTo check a block's info and stats,[accent] tap the "?" button while selecting it in the build menu.[]\n\n[yellow]Access the Mechanical Drill's stats now.[] +tutorial.conveyor = [accent]Conveyors[] are used to transport items to the core.\nMake a line of conveyors from the drill to the core.\n[yellow]Hold down the mouse to place in a line.[]\nHold[accent] CTRL[] while selecting a line to place diagonally.\n\n[accent]{0}/{1} conveyors\n[accent]0/1 items delivered +tutorial.conveyor.mobile = [accent]Conveyors[] are used to transport items to the core.\nMake a line of conveyors from the drill to the core.[yellow] Place in a line by holding down your finger for a few seconds[] and dragging in a direction.\n\n[accent]{0}/{1} conveyors\n[accent]0/1 items delivered +tutorial.turret = Defensive structures must be built to repel the[lightgray] enemy[].\nBuild a[accent] duo turret[] near your base. tutorial.drillturret = Duo turrets require[accent] copper ammo []to shoot.\nPlace a drill near to the turret. Lead conveyors into the turret to supply it with copper.\n\n[accent]Ammo delivered: 0/1 +tutorial.pause = During battle, you are able to[accent] pause the game.[]\nYou may queue buildings while paused.\n\n[accent]Press space to pause and unpause. +tutorial.pause.mobile = During battle, you are able to[accent] pause the game.[]\nYou may queue buildings while paused.\n\n[accent]Press this button in the top left to pause and unpause. +tutorial.breaking = Blocks frequently need to be destroyed.\n[accent]Hold down right-click[] to destroy all blocks in a selection.[]\n\n[yellow]Destroy all the scrap blocks to the right of your core. +tutorial.breaking.mobile = Blocks frequently need to be destroyed.\n[accent]Select deconstruction mode[], then tap a block to begin breaking it.\nDestroy an area by holding down your finger for a few seconds[] and dragging in a direction.\nPress the checkmark button to confirm breaking.\n\n[yellow]Destroy all the scrap blocks to the right of your core. tutorial.waves = The[lightgray] enemy[] approaches.\n\nDefend the core for 2 waves.[accent] Click[] to shoot.\nBuild more turrets and drills. Mine more copper. 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. @@ -986,7 +993,7 @@ block.solar-panel.description = Provides a small amount of power from the sun. block.solar-panel-large.description = A significantly more efficient version of the standard solar panel. block.thorium-reactor.description = Generates significant amounts of power from thorium. Requires constant cooling. Will explode violently if insufficient amounts of coolant are supplied. Power output depends on fullness, with base power generated at full capacity. block.impact-reactor.description = An advanced generator, capable of creating massive amounts of power at peak efficiency. Requires a significant power input to kickstart the process. -block.mechanical-drill.description = A cheap drill. When placed on appropriate tiles, outputs items at a slow pace indefinitely. Only capable of mining copper, lead and coal. +block.mechanical-drill.description = A cheap drill. When placed on appropriate tiles, outputs items at a slow pace indefinitely. Only capable of mining basic resources. block.pneumatic-drill.description = An improved drill, capable of mining titanium. Mines at a faster pace than a mechanical drill. block.laser-drill.description = Allows drilling even faster through laser technology, but requires power. Capable of mining thorium. block.blast-drill.description = The ultimate drill. Requires large amounts of power. diff --git a/core/src/io/anuke/mindustry/core/Control.java b/core/src/io/anuke/mindustry/core/Control.java index 9a67f8cd39..d6d3dab468 100644 --- a/core/src/io/anuke/mindustry/core/Control.java +++ b/core/src/io/anuke/mindustry/core/Control.java @@ -275,6 +275,8 @@ public class Control implements ApplicationListener{ control.saves.zoneSave(); logic.play(); state.rules.waveTimer = false; + state.rules.waveSpacing = 60f * 30; + state.rules.buildCostMultiplier = 0.3f; state.rules.tutorial = true; }); } diff --git a/core/src/io/anuke/mindustry/core/UI.java b/core/src/io/anuke/mindustry/core/UI.java index 4d6fb7eb3a..298272522e 100644 --- a/core/src/io/anuke/mindustry/core/UI.java +++ b/core/src/io/anuke/mindustry/core/UI.java @@ -79,7 +79,7 @@ public class UI implements ApplicationListener{ Core.input.addProcessor(Core.scene); Dialog.setShowAction(() -> sequence(alpha(0f), fadeIn(0.1f))); - Dialog.setHideAction(() -> sequence(fadeOut(0.2f))); + Dialog.setHideAction(() -> sequence(fadeOut(0.1f))); Tooltips.getInstance().animations = false; diff --git a/core/src/io/anuke/mindustry/game/EventType.java b/core/src/io/anuke/mindustry/game/EventType.java index e3dd86a0e7..d697532afe 100644 --- a/core/src/io/anuke/mindustry/game/EventType.java +++ b/core/src/io/anuke/mindustry/game/EventType.java @@ -54,7 +54,17 @@ public class EventType{ } /** Called when a turret recieves ammo, but only when the tutorial is active! */ - public static class AmmoDeliverEvent{ + public static class TurretAmmoDeliverEvent{ + + } + + /** Called when a core recieves ammo, but only when the tutorial is active! */ + public static class CoreItemDeliverEvent{ + + } + + /** Called when the player opens info for a specific block.*/ + public static class BlockInfoEvent{ } diff --git a/core/src/io/anuke/mindustry/game/Tutorial.java b/core/src/io/anuke/mindustry/game/Tutorial.java index c6d48bea1b..82c5d44f2f 100644 --- a/core/src/io/anuke/mindustry/game/Tutorial.java +++ b/core/src/io/anuke/mindustry/game/Tutorial.java @@ -9,16 +9,18 @@ import io.anuke.arc.scene.*; import io.anuke.arc.scene.ui.*; import io.anuke.arc.scene.ui.layout.*; import io.anuke.arc.util.*; -import io.anuke.mindustry.*; import io.anuke.mindustry.content.*; import io.anuke.mindustry.game.EventType.*; import io.anuke.mindustry.graphics.*; import io.anuke.mindustry.type.*; import io.anuke.mindustry.world.*; +import static io.anuke.mindustry.Vars.*; + /** Handles tutorial state. */ public class Tutorial{ - private static final int mineCopper = 16; + private static final int mineCopper = 18; + private static final int blocksToBreak = 3, blockOffset = 5; private ObjectSet events = new ObjectSet<>(); private ObjectIntMap blocksPlaced = new ObjectIntMap<>(); @@ -32,7 +34,9 @@ public class Tutorial{ }); Events.on(LineConfirmEvent.class, event -> events.add("lineconfirm")); - Events.on(AmmoDeliverEvent.class, event -> events.add("ammo")); + Events.on(TurretAmmoDeliverEvent.class, event -> events.add("ammo")); + Events.on(CoreItemDeliverEvent.class, event -> events.add("coreitem")); + Events.on(BlockInfoEvent.class, event -> events.add("blockinfo")); } /** update tutorial state, transition if needed */ @@ -52,6 +56,7 @@ public class Tutorial{ /** Resets tutorial state. */ public void reset(){ stage = TutorialStage.values()[0]; + stage.begin(); blocksPlaced.clear(); events.clear(); } @@ -59,6 +64,7 @@ public class Tutorial{ /** Goes on to the next tutorial step. */ public void next(){ stage = TutorialStage.values()[Mathf.clamp(stage.ordinal() + 1, 0, TutorialStage.values().length)]; + stage.begin(); blocksPlaced.clear(); events.clear(); } @@ -74,9 +80,16 @@ public class Tutorial{ outline("block-mechanical-drill"); } }, + blockinfo(() -> event("blockinfo")){ + void draw(){ + outline("category-production"); + outline("block-mechanical-drill"); + outline("blockinfo"); + } + }, conveyor( - line -> Core.bundle.format(line, placed(Blocks.conveyor), 3), - () -> placed(Blocks.conveyor, 3) && event("lineconfirm")){ + line -> Core.bundle.format(line, Math.min(placed(Blocks.conveyor), 2), 2), + () -> placed(Blocks.conveyor, 2) && event("lineconfirm") && event("coreitem")){ void draw(){ outline("category-distribution"); outline("block-conveyor"); @@ -84,29 +97,57 @@ public class Tutorial{ }, turret(() -> placed(Blocks.duo, 1)){ void draw(){ - outline("category-turrets"); + outline("category-turret"); outline("block-duo"); } }, - drillturret(() -> event("ammo")){ + drillturret(() -> event("ammo")), + pause(() -> state.isPaused()){ void draw(){ - outline("category-production"); - outline("block-mechanical-drill"); + if(mobile){ + outline("pause"); + } } }, - waves(() -> Vars.state.wave > 2 && Vars.state.enemies() <= 0){ + breaking(TutorialStage::blocksBroken){ void begin(){ - Vars.state.rules.waveTimer = true; + placeBlocks(); + } + + void draw(){ + if(mobile){ + outline("breakmode"); + } + } + }, + waves(() -> state.wave > 2 && state.enemies() <= 0){ + void begin(){ + state.rules.waveTimer = true; + logic.runWave(); } void update(){ - if(Vars.state.wave > 2){ - Vars.state.rules.waveTimer = false; + if(state.wave > 2){ + state.rules.waveTimer = false; } } - }; + }, + launch(() -> false){ + void begin(){ + state.rules.waveTimer = false; + state.wave = 5; - protected final String line = Core.bundle.has("tutorial." + name() + ".mobile") && Vars.mobile ? "tutorial." + name() + ".mobile" : "tutorial." + name(); + //end tutorial, never show it again + Core.settings.put("tutorial", true); + Core.settings.save(); + } + + void draw(){ + outline("waves"); + } + },; + + protected final String line = Core.bundle.has("tutorial." + name() + ".mobile") && mobile ? "tutorial." + name() + ".mobile" : "tutorial." + name(); protected final Function text; protected final BooleanProvider done; @@ -142,8 +183,27 @@ public class Tutorial{ //utility + static void placeBlocks(){ + Tile core = state.teams.get(defaultTeam).cores.first(); + for(int i = 0; i < blocksToBreak; i++){ + world.removeBlock(world.ltile(core.x + blockOffset, core.y + i)); + world.tile(core.x + blockOffset, core.y + i).setBlock(Blocks.scrapWall); + } + } + + static boolean blocksBroken(){ + Tile core = state.teams.get(defaultTeam).cores.first(); + + for(int i = 0; i < blocksToBreak; i++){ + if(world.tile(core.x + blockOffset, core.y + i).block() == Blocks.scrapWall){ + return false; + } + } + return true; + } + static boolean event(String name){ - return Vars.control.tutorial.events.contains(name); + return control.tutorial.events.contains(name); } static boolean placed(Block block, int amount){ @@ -151,11 +211,11 @@ public class Tutorial{ } static int placed(Block block){ - return Vars.control.tutorial.blocksPlaced.get(block, 0); + return control.tutorial.blocksPlaced.get(block, 0); } static int item(Item item){ - return Vars.state.teams.get(Vars.defaultTeam).cores.isEmpty() ? 0 : Vars.state.teams.get(Vars.defaultTeam).cores.first().entity.items.get(item); + return state.teams.get(defaultTeam).cores.isEmpty() ? 0 : state.teams.get(defaultTeam).cores.first().entity.items.get(item); } static boolean toggled(String name){ @@ -173,6 +233,17 @@ public class Tutorial{ float sin = Mathf.sin(11f, UnitScl.dp.scl(4f)); Lines.stroke(UnitScl.dp.scl(7f), Pal.place); Lines.rect(Tmp.v1.x - sin, Tmp.v1.y - sin, element.getWidth() + sin*2, element.getHeight() + sin*2); + + float size = Math.max(element.getWidth(), element.getHeight()) + Mathf.absin(11f/2f, UnitScl.dp.scl(18f)); + float angle = Angles.angle(Core.graphics.getWidth()/2f, Core.graphics.getHeight()/2f, Tmp.v1.x + element.getWidth()/2f, Tmp.v1.y + element.getHeight()/2f); + Tmp.v2.trns(angle + 180f, size*1.4f); + float fs = UnitScl.dp.scl(40f); + float fs2 = UnitScl.dp.scl(50f); + + Draw.color(Pal.gray); + Drawf.tri(Tmp.v1.x + element.getWidth()/2f + Tmp.v2.x, Tmp.v1.y + element.getHeight()/2f + Tmp.v2.y, fs2, fs2, angle); + Draw.color(Pal.place); + Drawf.tri(Tmp.v1.x + element.getWidth()/2f + Tmp.v2.x, Tmp.v1.y + element.getHeight()/2f + Tmp.v2.y, fs, fs, angle); Draw.reset(); } } diff --git a/core/src/io/anuke/mindustry/input/MobileInput.java b/core/src/io/anuke/mindustry/input/MobileInput.java index 815e3bf61f..3d982065e9 100644 --- a/core/src/io/anuke/mindustry/input/MobileInput.java +++ b/core/src/io/anuke/mindustry/input/MobileInput.java @@ -254,7 +254,7 @@ public class MobileInput extends InputHandler implements GestureListener{ table.addImageButton("icon-break-small", "clear-toggle-partial", iconsizesmall, () -> { mode = mode == breaking ? block == null ? none : placing : breaking; lastBlock = block; - }).update(l -> l.setChecked(mode == breaking)); + }).update(l -> l.setChecked(mode == breaking)).name("breakmode"); //diagonal swap button table.addImageButton("icon-diagonal-small", "clear-toggle-partial", iconsizesmall, () -> { @@ -736,11 +736,6 @@ public class MobileInput extends InputHandler implements GestureListener{ return true; } - float clerp(float value, float min, float max){ - final float alpha = 0.07f; - return value < min ? Mathf.lerpDelta(value, min, alpha) : value > max ? Mathf.lerpDelta(value, max, alpha) : value; - } - //endregion private class PlaceRequest{ diff --git a/core/src/io/anuke/mindustry/ui/dialogs/PausedDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/PausedDialog.java index 0a8a004d85..6a7072a58e 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/PausedDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/PausedDialog.java @@ -48,25 +48,21 @@ public class PausedDialog extends FloatingDialog{ } cont.addButton("$settings", ui.settings::show); - if(!world.isZone() && !state.isEditor()){ + if(!state.rules.tutorial){ + if(!world.isZone() && !state.isEditor()){ + cont.row(); + cont.addButton("$savegame", save::show); + cont.addButton("$loadgame", load::show).disabled(b -> Net.active()); + } + cont.row(); - cont.addButton("$savegame", save::show); - cont.addButton("$loadgame", load::show).disabled(b -> Net.active()); + + cont.addButton("$hostserver", ui.host::show).disabled(b -> Net.active()).colspan(2).width(dw * 2 + 20f); } cont.row(); - cont.addButton("$hostserver", ui.host::show).disabled(b -> Net.active()).colspan(2).width(dw * 2 + 20f); - cont.row(); - - cont.addButton("$quit", () -> { - ui.showConfirm("$confirm", "$quit.confirm", () -> { - wasClient = Net.client(); - if(Net.client()) netClient.disconnectQuietly(); - runExitSave(); - hide(); - }); - }).colspan(2).width(dw + 10f); + cont.addButton("$quit", this::showQuitConfirm).colspan(2).width(dw + 10f); }else{ cont.defaults().size(120f).pad(5); @@ -87,17 +83,23 @@ public class PausedDialog extends FloatingDialog{ cont.addRowImageTextButton("$hostserver.mobile", "icon-host", isize, ui.host::show).disabled(b -> Net.active()); - cont.addRowImageTextButton("$quit", "icon-quit", isize, () -> { - ui.showConfirm("$confirm", "$quit.confirm", () -> { - wasClient = Net.client(); - if(Net.client()) netClient.disconnectQuietly(); - runExitSave(); - hide(); - }); - }); + cont.addRowImageTextButton("$quit", "icon-quit", isize, this::showQuitConfirm); } } + void showQuitConfirm(){ + ui.showConfirm("$confirm", state.rules.tutorial ? "$quit.confirm.tutorial" : "$quit.confirm", () -> { + if(state.rules.tutorial){ + Core.settings.put("tutorial", true); + Core.settings.save(); + } + wasClient = Net.client(); + if(Net.client()) netClient.disconnectQuietly(); + runExitSave(); + hide(); + }); + } + public void runExitSave(){ if(state.isEditor() && !wasClient){ ui.editor.resumeEditing(); diff --git a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java index 4448e93f6b..1f73eb788d 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java @@ -71,7 +71,7 @@ public class HudFragment extends Fragment{ }else{ state.set(state.is(State.paused) ? State.playing : State.paused); } - }).update(i -> { + }).name("pause").update(i -> { if(Net.active()){ i.getStyle().imageUp = Core.scene.skin.getDrawable("icon-players"); }else{ @@ -312,9 +312,10 @@ public class HudFragment extends Fragment{ .update(label -> label.getColor().set(Color.ORANGE).lerp(Color.SCARLET, Mathf.absin(Time.time(), 2f, 1f)))).touchable(Touchable.disabled); }); + //tutorial text parent.fill(t -> { t.top().visible(() -> state.rules.tutorial); - t.table("button-trans", f -> f.labelWrap(() -> control.tutorial.stage.text()).width(400f).pad(3f)); + t.table("button-trans", f -> f.labelWrap(() -> control.tutorial.stage.text()).width(500f).pad(3f)); }); //paused table @@ -549,6 +550,7 @@ public class HudFragment extends Fragment{ StringBuilder builder = new StringBuilder(); + table.setName("waves"); table.labelWrap(() -> { builder.setLength(0); builder.append(wavef.get(state.wave)); diff --git a/core/src/io/anuke/mindustry/ui/fragments/LoadingFragment.java b/core/src/io/anuke/mindustry/ui/fragments/LoadingFragment.java index 23ad95f0e2..9eb53bb913 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/LoadingFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/LoadingFragment.java @@ -55,6 +55,6 @@ public class LoadingFragment extends Fragment{ table.clearActions(); table.toFront(); table.touchable(Touchable.disabled); - table.actions(Actions.fadeOut(1f), Actions.visible(false)); + table.actions(Actions.fadeOut(0.5f), Actions.visible(false)); } } diff --git a/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java b/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java index 0ccd1c4811..71e599459a 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java @@ -45,9 +45,7 @@ public class MenuFragment extends Fragment{ parent = group; - parent.fill((x, y, w, h) -> { - renderer.render(); - }); + parent.fill((x, y, w, h) -> renderer.render()); parent.fill(c -> { container = c; diff --git a/core/src/io/anuke/mindustry/ui/fragments/PlacementFragment.java b/core/src/io/anuke/mindustry/ui/fragments/PlacementFragment.java index 98f17da60d..ae759f010f 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/PlacementFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/PlacementFragment.java @@ -13,8 +13,7 @@ import io.anuke.arc.scene.ui.*; import io.anuke.arc.scene.ui.layout.Table; import io.anuke.mindustry.content.Blocks; import io.anuke.mindustry.entities.type.TileEntity; -import io.anuke.mindustry.game.EventType.UnlockEvent; -import io.anuke.mindustry.game.EventType.WorldLoadEvent; +import io.anuke.mindustry.game.EventType.*; import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.input.Binding; import io.anuke.mindustry.input.InputHandler; @@ -200,8 +199,10 @@ public class PlacementFragment extends Fragment{ .left().width(190f).padLeft(5); header.add().growX(); if(unlocked(lastDisplay)){ - header.addButton("?", "clear-partial", () -> ui.content.show(lastDisplay)) - .size(8 * 5).padTop(-5).padRight(-5).right().grow(); + header.addButton("?", "clear-partial", () -> { + ui.content.show(lastDisplay); + Events.fire(new BlockInfoEvent()); + }).size(8 * 5).padTop(-5).padRight(-5).right().grow().name("blockinfo"); } if(lastDisplay.buildVisibility == Blocks.padVisible && !lastDisplay.buildVisibility.get()){ header.row(); diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/ItemTurret.java b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/ItemTurret.java index 5804c945a7..f0d3737d8d 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/ItemTurret.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/ItemTurret.java @@ -131,7 +131,7 @@ public class ItemTurret extends CooledTurret{ //fire events for the tutorial if(state.rules.tutorial){ - Events.fire(new AmmoDeliverEvent()); + Events.fire(new TurretAmmoDeliverEvent()); } } diff --git a/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java b/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java index efee63dbb8..5f42308d55 100644 --- a/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java @@ -2,6 +2,7 @@ package io.anuke.mindustry.world.blocks.storage; import io.anuke.annotations.Annotations.Loc; import io.anuke.annotations.Annotations.Remote; +import io.anuke.arc.*; import io.anuke.arc.collection.EnumSet; import io.anuke.arc.graphics.g2d.*; import io.anuke.arc.math.Mathf; @@ -11,6 +12,7 @@ import io.anuke.mindustry.content.Mechs; import io.anuke.mindustry.entities.Effects; import io.anuke.mindustry.entities.traits.SpawnerTrait; import io.anuke.mindustry.entities.type.*; +import io.anuke.mindustry.game.EventType.*; import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.graphics.Shaders; @@ -122,7 +124,12 @@ public class CoreBlock extends StorageBlock{ @Override public void handleItem(Item item, Tile tile, Tile source){ - if(Net.server() || !Net.active()) super.handleItem(item, tile, source); + if(Net.server() || !Net.active()){ + super.handleItem(item, tile, source); + if(state.rules.tutorial){ + Events.fire(new CoreItemDeliverEvent()); + } + } } @Override