Skip to content

Commit

Permalink
feat(tutorial): move tutorial sections into headings
Browse files Browse the repository at this point in the history
  • Loading branch information
BenjaminAmos committed Mar 28, 2023
1 parent 1b74927 commit 2e5e04a
Show file tree
Hide file tree
Showing 7 changed files with 190 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.destinationsol.game.tutorial.steps.ButtonPressStep;
import org.destinationsol.game.tutorial.steps.BuyItemStep;
import org.destinationsol.game.tutorial.steps.BuyMercenaryStep;
import org.destinationsol.game.tutorial.steps.ChangeTutorialSectionStep;
import org.destinationsol.game.tutorial.steps.CheckGunReloadStep;
import org.destinationsol.game.tutorial.steps.CheckItemEquippedStep;
import org.destinationsol.game.tutorial.steps.CloseScreenStep;
Expand Down Expand Up @@ -78,6 +79,7 @@ public class TutorialManager implements UpdateAwareSystem {
private final BeanContext beanContext;
private List<TutorialStep> steps;
private int stepNo;
private String currentTutorialHeading;

@Inject
public TutorialManager(NUIManager nuiManager, SolApplication solApplication, Provider<SolGame> game, BeanContext beanContext) {
Expand Down Expand Up @@ -151,23 +153,23 @@ public void start() {
itemTypesExplanations.put(Shield.class, "Shields absorb energy-based projectiles until depleted.");

steps = new ArrayList<>(Arrays.asList(
new MessageStep("Section 1 - Movement"),
new ChangeTutorialSectionStep("Movement"),
new TurnLeftRightStep(isMobile ? "Turn left and right." : "Turn left and right (" + turnControlHint + ")."),
new ThrustForwardsStep(isMobile ? "Thrust forwards." : "Thrust forwards (" + thrustForwardControlHint + ")."),
new SlowVelocityStep(0.1f, "Turn around and thrust again to slow down.\n\nTry slowing to a stop."),
new FlyToRandomWaypointAroundHeroStep(1.0f, 2.5f, "Fly to the waypoint."),
new MessageStep("Section 2 - Weapons"),
new ChangeTutorialSectionStep("Weapons"),
new FireGunStep(isMobile ? "Fire your gun." : "Fire your gun (" + shootControlHint + ")."),
new CheckGunReloadStep(false, true, "Firing weapons drains your ammunition. Keep on firing."),
new CheckGunReloadStep(false, false,
"Your weapon reloads when depleted.\n" +
"You can't fire when reloading."),
new UseAbilityStep(isMobile ? "Use your ability." : "Use your ability (" + abilityControlHint + ")."),
new MessageStep("Abilities consume ability charges."),
new MessageStep("Section 3 - Money"),
new ChangeTutorialSectionStep("Money"),
new DestroySpawnedAsteroidAroundHeroStep(1.0f, 2.5f, "Fire at the asteroid."),
new MessageStep("Asteroids drop loot - money in this case."),
new MessageStep("Section 4 - Items"),
new MessageStep("Asteroids drop money. You can fly into it to collect it."),
new ChangeTutorialSectionStep("Items"),
new OpenScreenStep(
solGame.get().getScreens().mainGameScreen.getInventoryButton(),
solGame.get().getScreens().inventoryScreen,
Expand All @@ -191,27 +193,27 @@ public void start() {
solGame.get().getScreens().inventoryScreen.getCloseButton(),
solGame.get().getScreens().inventoryScreen,
isMobile ? "Close your inventory (tap outside of the inventory)." : "Close your inventory."),
new MessageStep("Section 5 - Weapon Mounts"),
new ChangeTutorialSectionStep("Weapon Mounts"),
new MessageStep("All ships may come with up to two weapon mounts."),
new MessageStep("Weapon mounts are either fixed or rotating."),
new MessageStep("You can only equip weapons on matching mounts."),
new MessageStep("Section 6 - Shops"),
new ChangeTutorialSectionStep("Shops"),
new FlyToNearestStationStep("Fly to the station."),
new OpenScreenStep(
solGame.get().getScreens().mainGameScreen.getTalkButton(),
solGame.get().getScreens().talkScreen,
isMobile ? "Talk to the station." : "Talk to the station (" + gameOptions.getKeyTalkName() + ")."),
new BuyItemStep(usesKeyboard ? "Select Buy (" + gameOptions.getKeyBuyMenuName() + ")." : "Select Buy.",
isMobile ? "Buy an item." : "Buy an item (" + gameOptions.getKeyBuyItemName() + ")."),
new MessageStep("Section 7 - Combat"),
new ChangeTutorialSectionStep("Combat"),
new MessageStep("Shoot at ships to destroy them.\n"),
new DestroySpawnedShipsStep(1, "core:minerSmall",
"core:fixedBlaster", "Destroy the targeted ship.",
"Enemy ships can be tough.\nOpen the pause menu and select Respawn."),
new MessageStep("Destroyed ships drop valuable loot."),
new MessageStep("Section 8 - Repair Kits"),
new ChangeTutorialSectionStep("Repair Kits"),
new WaitUntilFullyRepairedStep("Stay still and wait until the repair kits have repaired your hull fully."),
new MessageStep("Section 9 - Map"),
new ChangeTutorialSectionStep("Map"),
new OpenScreenStep(
solGame.get().getScreens().mainGameScreen.getMapButton(),
solGame.get().getScreens().mapScreen,
Expand All @@ -225,8 +227,9 @@ public void start() {
solGame.get().getScreens().mapScreen,
"Close the map."),
new FlyToHeroFirstWaypointStep("Fly to your waypoint."),
new MessageStep("Section 10 - Hiring Mercenaries"),
new FlyToPlanetSellingMercenariesStep("Fly to a planetary station providing mercenaries."),
new ChangeTutorialSectionStep("Planets"),
new FlyToPlanetSellingMercenariesStep("Head towards a planet.", "Look for the planetary station."),
new ChangeTutorialSectionStep("Mercenaries"),
new MessageStep("When flying around planets, you'll be affected by gravity."),
new OpenScreenStep(
solGame.get().getScreens().mainGameScreen.getTalkButton(),
Expand All @@ -236,7 +239,6 @@ public void start() {
usesKeyboard ? "Select Hire (" + gameOptions.getKeyHireShipMenuName() + ")." : "Select Hire.",
"Try hiring a mercenary."),
new MessageStep("Mercenaries will fight for you. They keep any money they collect as part of their payment."),
new MessageStep("Section 11 - Managing Mercenaries"),
new OpenScreenStep(
solGame.get().getScreens().mainGameScreen.getMercsButton(),
solGame.get().getScreens().inventoryScreen,
Expand All @@ -246,9 +248,11 @@ public void start() {
"Here you can give items to your mercenary.",
"Here you can take items back from your mercenary.",
"Here you can manage your mercenary's equipment."),
new ChangeTutorialSectionStep("Star Lanes"),
new FlyToNearestStarPortStep("Fly to the marked star lane."),
new MessageStep("For a small fee, star lanes allow you to travel quickly between planets."),
new TravelThroughStarPortStep("Fly into the centre to travel across the star lane."),
new ChangeTutorialSectionStep("Finish"),
new MessageStep("That's it! The tutorial is finished. You will be returned to the main menu.")
));

Expand Down Expand Up @@ -309,7 +313,12 @@ public void update(SolGame game, float timeStep) {
}

private void setUpTutorialBox(TutorialStep tutorialStep) {
if (tutorialStep.getTutorialHeading() != null) {
currentTutorialHeading = tutorialStep.getTutorialHeading();
}

tutorialScreen.setTutorialText(tutorialStep.getTutorialText(), tutorialStep.getTutorialBoxPosition());
tutorialScreen.setTutorialHeading(currentTutorialHeading, tutorialStep.getTutorialBoxPosition());
if (tutorialStep.getRequiredInput() != null) {
tutorialScreen.setInteractHintInput(tutorialStep.getTutorialBoxPosition(), tutorialStep.getRequiredInput());
tutorialScreen.setInteractEvent(tutorialStep.getTutorialBoxPosition(), tutorialStep.getInputHandler());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
* populate.
*/
public abstract class TutorialStep {
private String tutorialHeading;
private String tutorialText;
private HorizontalAlign tutorialBoxPosition = HorizontalAlign.CENTER;
private Input requiredInput;
Expand All @@ -46,8 +47,16 @@ public abstract class TutorialStep {
public abstract boolean checkComplete(float timeStep);

/**
* Returns the explanatory text to the shown to the player.
* @return the explanatory text to the shown to the player
* Returns the heading text shown to the player. This can be null, to preserve the existing heading.
* @return the heading text shown to the player This can be null to preserve the existing heading.
*/
public String getTutorialHeading() {
return tutorialHeading;
}

/**
* Returns the explanatory text to be the shown to the player.
* @return the explanatory text to be the shown to the player
*/
public String getTutorialText() {
return tutorialText;
Expand Down Expand Up @@ -77,6 +86,14 @@ public Consumer<Input> getInputHandler() {
return inputHandler;
}

/**
* Specifies the heading to display above the tutorial box. This can be null to preserve the existing heading.
* @param tutorialHeading the heading to display above the tutorial box, or null to preserve the existing heading.
*/
protected void setTutorialHeading(String tutorialHeading) {
this.tutorialHeading = tutorialHeading;
}

/**
* Specifies the explanatory text to display in the tutorial box.
* @param tutorialText the explanatory text to display
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright 2023 The Terasology Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.destinationsol.game.tutorial.steps;

import org.destinationsol.game.tutorial.TutorialStep;

import javax.inject.Inject;

/**
* This tutorial step simply changes the displayed heading above the tutorial box.
*/
public class ChangeTutorialSectionStep extends TutorialStep {
private final String sectionHeading;

@Inject
protected ChangeTutorialSectionStep() {
throw new RuntimeException("Attempted to instantiate TutorialStep via DI. This is not supported.");
}

public ChangeTutorialSectionStep(String sectionHeading) {
this.sectionHeading = sectionHeading;
}

@Override
public void start() {
setTutorialText(sectionHeading);
setTutorialHeading(sectionHeading);
}

@Override
public boolean checkComplete(float timeStep) {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,16 @@
* It guides the player towards the planet first with a waypoint, then towards the shop itself.
*/
public class FlyToPlanetSellingMercenariesStep extends FlyToPlanetStep {
private final String onPlanetMessage;

@Inject
protected FlyToPlanetSellingMercenariesStep() {
throw new RuntimeException("Attempted to instantiate TutorialStep via DI. This is not supported.");
}

public FlyToPlanetSellingMercenariesStep(String message) {
public FlyToPlanetSellingMercenariesStep(String message, String onPlanetMessage) {
super(null, message);
this.onPlanetMessage = onPlanetMessage;
}

@Override
Expand Down Expand Up @@ -107,12 +110,15 @@ private void setPlanetStationWaypoint() {
@Override
public boolean checkComplete(float timeStep) {
boolean nearPlanet = super.checkComplete(timeStep);
if (nearPlanet && planet.areObjectsCreated()) {
setPlanetStationWaypoint();
if (game.getMainGameScreen().getTalkButton().isEnabled()) {
game.getHero().getWaypoints().remove(waypoint);
game.getObjectManager().removeObjDelayed(waypoint);
return true;
if (nearPlanet) {
setTutorialText(onPlanetMessage);
if (planet.areObjectsCreated()) {
setPlanetStationWaypoint();
if (game.getMainGameScreen().getTalkButton().isEnabled()) {
game.getHero().getWaypoints().remove(waypoint);
game.getObjectManager().removeObjDelayed(waypoint);
return true;
}
}
}
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,14 @@ public class TutorialScreen extends NUIScreenLayer {
private static final class TutorialBox {
public final UIBox box;
public final UILabel text;
public final UILabel heading;
public final InteractHint interactHint;
public Consumer<Input> inputEventListener;

public TutorialBox(UIBox box, UILabel text, InteractHint interactHint) {
public TutorialBox(UIBox box, UILabel text, UILabel heading, InteractHint interactHint) {
this.box = box;
this.text = text;
this.heading = heading;
this.interactHint = interactHint;
}
}
Expand Down Expand Up @@ -86,6 +88,7 @@ public void initialise() {
TutorialBox tutorialBox = new TutorialBox(
find("tutorialBox" + horizontalAlign.toString(), UIBox.class),
find("tutorialText" + horizontalAlign.toString(), UILabel.class),
find("tutorialHeading" + horizontalAlign.toString(), UILabel.class),
find("interactHint" + horizontalAlign.toString(), InteractHint.class)
);
if (tutorialBox.interactHint != null) {
Expand Down Expand Up @@ -130,6 +133,41 @@ public void setTutorialText(String text, HorizontalAlign horizontalAlign) {
getTutorialBox(horizontalAlign).setVisible(!text.isEmpty());
}

/**
* Returns the heading displayed above the centre tutorial box.
* @return the heading displayed above the centre tutorial box.
*/
public String getTutorialHeading() {
return getTutorialHeading(HorizontalAlign.CENTER);
}

/**
* Returns the heading displayed above the specified tutorial box.
* @param horizontalAlign the tutorial box to select
* @return the heading displayed above the specified tutorial box.
*/
public String getTutorialHeading(HorizontalAlign horizontalAlign) {
return getTutorialHeadingLabel(horizontalAlign).getText();
}

/**
* Specifies the heading to be displayed above the specified tutorial box.
* @param heading the heading to be displayed
*/
public void setTutorialHeading(String heading) {
setTutorialHeading(heading, HorizontalAlign.CENTER);
}

/**
* Specifies the heading to be displayed above the specified tutorial box.
* @param heading the heading to be displayed
* @param horizontalAlign the tutorial box to select
*/
public void setTutorialHeading(String heading, HorizontalAlign horizontalAlign) {
getTutorialHeadingLabel(horizontalAlign).setText(heading);
getTutorialHeadingLabel(horizontalAlign).setVisible(!heading.isEmpty());
}

/**
* Returns the input hinted at by the centre tutorial box. This can be null.
* @return the input hinted at by the centre tutorial box
Expand Down Expand Up @@ -214,6 +252,10 @@ protected UILabel getTutorialTextLabel(HorizontalAlign horizontalAlign) {
return tutorialBoxes.get(horizontalAlign).text;
}

protected UILabel getTutorialHeadingLabel(HorizontalAlign horizontalAlign) {
return tutorialBoxes.get(horizontalAlign).heading;
}

protected UIBox getTutorialBox(HorizontalAlign horizontalAlign) {
return tutorialBoxes.get(horizontalAlign).box;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,17 @@
},
"tutorialBoxLEFT": {
"font": "engine:main#0.8",
"max-width": 160,
"min-width": 178,
"min-height": 192,
"elements": {
"UIBox": {
"background": "engine:box",
"text-align-horizontal": "middle"
}
}
},
"tutorialHeading": {
"font": "engine:main#0.4"
}
},
"elements": {
Expand Down
Loading

0 comments on commit 2e5e04a

Please sign in to comment.