diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index f7aa626580..8f76590433 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -2130,7 +2130,7 @@ hint.waveFire = [accent]Wave[] turrets with water as ammunition will automatical hint.generator = :combustion-generator: [accent]Combustion Generators[] burn coal and transmit power to adjacent blocks.\n\nPower transmission range can be extended with :power-node: [accent]Power Nodes[]. hint.guardian = [accent]Guardian[] units are armored. Weak ammo such as [accent]Copper[] and [accent]Lead[] is [scarlet]not effective[].\n\nUse higher tier turrets or :graphite: [accent]Graphite[] :duo:Duo/:salvo:Salvo ammunition to take Guardians down. hint.coreUpgrade = Cores can be upgraded by [accent]placing higher-tier cores over them[].\n\nPlace a :core-foundation: [accent]Foundation[] core over the :core-shard: [accent]Shard[] core. Make sure it is free from nearby obstructions. -hint.serpuloCoreZone = Additional cores may be constructed on :core-zone: [accent]Core Zone[] tiles. +hint.serpuloCoreZone = Additional :core-shard: [accent]Cores[] may be constructed on :core-zone: [accent]Core Zone[] tiles. hint.cannotUpgrade = A [red]:tree:[] icon over a payload unit indicates that its upgraded version is not researched yet.\n\nUnit upgrades must be researched in the [accent]:tree: tech tree[] before they can be produced in reconstructors. hint.presetLaunch = Gray [accent]landing zone sectors[], such as [accent]Frozen Forest[], can be launched to from anywhere. They do not require capture of nearby territory.\n\n[accent]Numbered sectors[], such as this one, are [accent]optional[]. hint.presetDifficulty = This sector has a [scarlet]high enemy threat level[].\nLaunching to such sectors is [accent]not recommended[] without proper technology and preparation. @@ -2159,6 +2159,9 @@ gz.zone2 = Anything built in the radius is destroyed when a wave starts. gz.zone3 = A wave will begin now.\nGet ready. gz.finish = Build more turrets, mine more resources,\nand defend against all the waves to [accent]capture the sector[]. +fungalpass.tutorial1 = Use [accent]units[] to defend buildings and attack the enemy.\nResearch and place a :ground-factory: [accent]ground factory[]. +fungalpass.tutorial2 = Select :dagger: [accent]Dagger[] units in the factory.\nProduce 3 units. + atolls.destroy1 = Destroy the 2 enemy [accent]foundation cores[] first.\n[accent]Gain access to thorium[]. atolls.destroy2 = The enemy base to the south is fragile to naval units. \nConstruct [accent]naval units[]   to proceed. atolls.destroy3 = The enemy base to the east is fragile to air units. \nConstruct [accent]air units[]   to proceed. @@ -2210,7 +2213,7 @@ aegis.tungsten = Tungsten can be mined using an [accent]impact drill[].\nThis st split.pickup = Some blocks can be picked up by the core unit.\nPick up this [accent]container[] and place it onto the [accent]payload loader[].\n(Default keys are [[ and ] to pick up and drop) split.pickup.mobile = Some blocks can be picked up by the core unit.\nPick up this [accent]container[] and place it onto the [accent]payload loader[].\n(To pick up or drop something, long-press it.) -split.acquire = You must acquire some tungsten to build units. +split.acquire = Acquire some tungsten to build units. split.build = Units must be transported to the other side of the wall.\nPlace two [accent]Payload Mass Drivers[], one on each side of the wall.\nSet up the link by pressing one of them, then selecting the other. split.container = Similar to the container, units can also be transported using a [accent]Payload Mass Driver[].\nPlace a unit fabricator adjacent to a mass driver to load them, then send them across the wall to attack the enemy base. diff --git a/core/assets/maps/fungalPass.msav b/core/assets/maps/fungalPass.msav index a8f41b5fb4..71e42dd144 100644 Binary files a/core/assets/maps/fungalPass.msav and b/core/assets/maps/fungalPass.msav differ diff --git a/core/src/mindustry/ui/fragments/HintsFragment.java b/core/src/mindustry/ui/fragments/HintsFragment.java index d5326090fa..630c58780a 100644 --- a/core/src/mindustry/ui/fragments/HintsFragment.java +++ b/core/src/mindustry/ui/fragments/HintsFragment.java @@ -167,48 +167,143 @@ public class HintsFragment{ public enum DefaultHint implements Hint{ desktopMove(visibleDesktop, () -> Core.input.axis(Binding.moveX) != 0 || Core.input.axis(Binding.moveY) != 0), + zoom(visibleDesktop, () -> Core.input.axis(KeyCode.scroll) != 0), - breaking(() -> isTutorial.get() && state.rules.defaultTeam.data().getCount(Blocks.conveyor) > 5, () -> ui.hints.events.contains("break")), - desktopShoot(visibleDesktop, () -> isSerpulo() && Vars.state.enemies > 0, () -> player.shooting), - depositItems(() -> !player.dead() && player.unit().hasItem(), () -> !player.dead() && !player.unit().hasItem()), - desktopPause(visibleDesktop, () -> isTutorial.get() && !Vars.net.active() && state.wave >= 2, () -> Core.input.keyTap(Binding.pause)), - unitControl(() -> isSerpulo() && state.rules.defaultTeam.data().units.size > 2 && !net.active() && !player.dead(), () -> !player.dead() && !player.unit().spawnedByCore), - unitSelectControl(() -> isSerpulo() && state.rules.defaultTeam.data().units.size > 3 && !net.active() && !player.dead(), - () -> control.input.commandMode && control.input.selectedUnits.size > 0 && control.input.selectedUnits.first().controller() instanceof CommandAI ai && ai.targetPos != null), - respawn(visibleMobile, () -> !player.dead() && !player.unit().spawnedByCore, () -> !player.dead() && player.unit().spawnedByCore), - launch(() -> (isTutorial.get() || Vars.state.rules.sector == SectorPresets.onset.sector) && state.rules.sector.isCaptured(), () -> ui.planet.isShown()), - schematicSelect(visibleDesktop, () -> ui.hints.placedBlocks.contains(Blocks.router) || ui.hints.placedBlocks.contains(Blocks.ductRouter), () -> Core.input.keyRelease(Binding.schematicSelect) || Core.input.keyTap(Binding.pick)), - conveyorPathfind(() -> control.input.block == Blocks.titaniumConveyor, () -> Core.input.keyRelease(Binding.diagonalPlacement) || (mobile && Core.settings.getBool("swapdiagonal"))), - boost(visibleDesktop, () -> !player.dead() && player.unit().type.canBoost, () -> Core.input.keyDown(Binding.boost)), - blockInfo(() -> control.input.block == Blocks.graphitePress, () -> ui.content.isShown()), - derelict(() -> ui.hints.events.contains("derelictmouse") && !isTutorial.get(), () -> ui.hints.events.contains("derelictbreak")), - payloadPickup(() -> isSerpulo() && !player.dead() && player.unit() instanceof Payloadc p && p.payloads().isEmpty(), () -> player.unit() instanceof Payloadc p && p.payloads().any()), - payloadDrop(() -> !player.dead() && player.unit() instanceof Payloadc p && p.payloads().any(), () -> player.unit() instanceof Payloadc p && p.payloads().isEmpty()), - waveFire(() -> Groups.fire.size() > 0 && Blocks.wave.unlockedNow(), () -> indexer.getFlagged(state.rules.defaultTeam, BlockFlag.extinguisher).size > 0), - generator(() -> control.input.block == Blocks.combustionGenerator, () -> ui.hints.placedBlocks.contains(Blocks.combustionGenerator)), - rebuildSelect(() -> state.rules.defaultTeam.data().plans.size >= 10, () -> control.input.isRebuildSelecting()), - guardian(() -> state.boss() != null && isSerpulo() && state.boss().armor >= 4, () -> state.boss() == null), - cannotUpgrade(() -> ui.hints.events.contains("cannotupgrade"), () -> false), + + breaking( + () -> isTutorial.get() && state.rules.defaultTeam.data().getCount(Blocks.conveyor) > 5, + () -> ui.hints.events.contains("break") + ), + + desktopShoot(visibleDesktop, + () -> isSerpulo() && Vars.state.enemies > 0, + () -> player.shooting + ), + + depositItems( + () -> !player.dead() && player.unit().hasItem(), + () -> !player.dead() && !player.unit().hasItem() + ), + + desktopPause(visibleDesktop, + () -> isTutorial.get() && !Vars.net.active() && state.wave >= 2, + () -> Core.input.keyTap(Binding.pause) + ), + + unitControl( + () -> isSerpulo() && state.rules.defaultTeam.data().units.size > 2 && !net.active() && !player.dead(), + () -> !player.dead() && !player.unit().spawnedByCore + ), + + unitSelectControl( + //if the player is on fungal pass or has *ever* played fungal pass, don't show this hint, it's redundant. + //in general, this should only be necessary if the player is doing a custom game or sequence-broke somehow + () -> isSerpulo() && state.rules.defaultTeam.data().units.size > 3 && !net.active() && !player.dead() && state.getSector() != SectorPresets.fungalPass.sector && SectorPresets.fungalPass.sector.save == null, + () -> control.input.commandMode && control.input.selectedUnits.size > 0 && control.input.selectedUnits.first().controller() instanceof CommandAI ai && ai.targetPos != null + ), + + respawn(visibleMobile, + () -> !player.dead() && !player.unit().spawnedByCore, + () -> !player.dead() && player.unit().spawnedByCore + ), + + launch( + () -> (isTutorial.get() || Vars.state.rules.sector == SectorPresets.onset.sector) && state.rules.sector.isCaptured(), + () -> ui.planet.isShown() + ), + + schematicSelect(visibleDesktop, + () -> ui.hints.placedBlocks.contains(Blocks.router) || ui.hints.placedBlocks.contains(Blocks.ductRouter), + () -> Core.input.keyRelease(Binding.schematicSelect) || Core.input.keyTap(Binding.pick) + ), + + conveyorPathfind( + () -> control.input.block == Blocks.titaniumConveyor, + () -> Core.input.keyRelease(Binding.diagonalPlacement) || (mobile && Core.settings.getBool("swapdiagonal")) + ), + + boost(visibleDesktop, + () -> !player.dead() && player.unit().type.canBoost, + () -> Core.input.keyDown(Binding.boost) + ), + + blockInfo( + () -> control.input.block == Blocks.graphitePress, + () -> ui.content.isShown() + ), + + derelict( + () -> ui.hints.events.contains("derelictmouse") && !isTutorial.get(), + () -> ui.hints.events.contains("derelictbreak") + ), + + payloadPickup( + () -> isSerpulo() && !player.dead() && player.unit() instanceof Payloadc p && p.payloads().isEmpty(), + () -> player.unit() instanceof Payloadc p && p.payloads().any() + ), + + payloadDrop( + () -> !player.dead() && player.unit() instanceof Payloadc p && p.payloads().any(), + () -> player.unit() instanceof Payloadc p && p.payloads().isEmpty() + ), + + waveFire( + () -> Groups.fire.size() > 0 && Blocks.wave.unlockedNow(), + () -> indexer.getFlagged(state.rules.defaultTeam, BlockFlag.extinguisher).size > 0 + ), + + generator( + () -> control.input.block == Blocks.combustionGenerator, + () -> ui.hints.placedBlocks.contains(Blocks.combustionGenerator) + ), + + rebuildSelect( + () -> state.rules.defaultTeam.data().plans.size >= 10, + () -> control.input.isRebuildSelecting() + ), + + guardian( + () -> state.boss() != null && isSerpulo() && state.boss().armor >= 4, + () -> state.boss() == null + ), + + cannotUpgrade( + () -> ui.hints.events.contains("cannotupgrade"), + () -> false + ), + factoryControl(() -> !(state.isCampaign() && state.rules.sector.preset == SectorPresets.onset) && - state.rules.defaultTeam.data().getBuildings(Blocks.tankFabricator).size + state.rules.defaultTeam.data().getBuildings(Blocks.groundFactory).size > 0, () -> ui.hints.events.contains("factorycontrol")), + state.rules.defaultTeam.data().getBuildings(Blocks.tankFabricator).size + state.rules.defaultTeam.data().getBuildings(Blocks.groundFactory).size > 0, + () -> ui.hints.events.contains("factorycontrol") + ), + coreUpgrade(() -> state.isCampaign() && state.rules.sector.planet == Planets.serpulo && Blocks.coreFoundation.unlocked() && state.rules.defaultTeam.core() != null && state.rules.defaultTeam.core().block == Blocks.coreShard && state.rules.defaultTeam.core().items.has(Blocks.coreFoundation.requirements), () -> ui.hints.placedBlocks.contains(Blocks.coreFoundation)), - serpuloCoreZone(() -> state.isCampaign() && state.getPlanet() == Planets.serpulo && Vars.indexer.isBlockPresent(Blocks.coreZone) && - (!state.rules.attackMode || state.stats.getDestroyed(Blocks.coreShard) + state.stats.getDestroyed(Blocks.coreFoundation) + state.stats.getDestroyed(Blocks.coreNucleus) > 0), + + serpuloCoreZone( + () -> state.isCampaign() && state.getPlanet() == Planets.serpulo && Vars.indexer.isBlockPresent(Blocks.coreZone) && + (!state.rules.attackMode || state.stats.getDestroyed(Blocks.coreShard) + state.stats.getDestroyed(Blocks.coreFoundation) + state.stats.getDestroyed(Blocks.coreNucleus) > 0), () -> state.rules.defaultTeam.cores().size > 1), - presetLaunch(() -> state.isCampaign() - && state.getSector().preset == null, - () -> state.isCampaign() && state.getSector().preset == SectorPresets.frozenForest), + presetLaunch( + () -> state.isCampaign() && state.getSector().preset == null, + () -> state.isCampaign() && state.getSector().preset == SectorPresets.frozenForest + ), + presetDifficulty(() -> state.isCampaign() && state.getSector().preset == null && state.getSector().threat >= 0.5f && !SectorPresets.tarFields.sector.isCaptured(), //appear only when the player hasn't progressed much in the game yet - () -> state.isCampaign() && state.getSector().preset != null), - coreIncinerate(() -> state.isCampaign() && state.rules.defaultTeam.core() != null && state.rules.defaultTeam.core().items.get(Items.copper) >= state.rules.defaultTeam.core().storageCapacity - 10, () -> false) + () -> state.isCampaign() && state.getSector().preset != null + ), + + coreIncinerate( + () -> state.isCampaign() && state.rules.defaultTeam.core() != null && state.rules.defaultTeam.core().items.get(Items.copper) >= state.rules.defaultTeam.core().storageCapacity - 10, + () -> false + ) ; @Nullable