Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add in-game shop in pregame phase #253

Merged
merged 3 commits into from
Dec 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,53 @@
// SPDX-License-Identifier: Apache-2.0
package org.terasology.module.lightandshadow.systems;

import org.terasology.economy.components.AllowShopScreenComponent;
import org.terasology.economy.ui.MarketUiClientSystem;
import org.terasology.engine.core.SimpleUri;
import org.terasology.engine.entitySystem.entity.EntityManager;
import org.terasology.engine.entitySystem.entity.EntityRef;
import org.terasology.engine.entitySystem.entity.lifecycleEvents.OnAddedComponent;
import org.terasology.engine.entitySystem.event.EventPriority;
import org.terasology.engine.entitySystem.event.ReceiveEvent;
import org.terasology.engine.entitySystem.systems.BaseComponentSystem;
import org.terasology.engine.entitySystem.systems.RegisterMode;
import org.terasology.engine.entitySystem.systems.RegisterSystem;
import org.terasology.engine.input.InputSystem;
import org.terasology.engine.logic.players.LocalPlayer;
import org.terasology.engine.logic.players.event.LocalPlayerInitializedEvent;
import org.terasology.engine.network.ClientComponent;
import org.terasology.engine.registry.In;
import org.terasology.engine.rendering.nui.NUIManager;
import org.terasology.engine.unicode.EnclosedAlphanumerics;
import org.terasology.gestalt.assets.ResourceUrn;
import org.terasology.input.ButtonState;
import org.terasology.input.Input;
import org.terasology.module.inventory.input.InventoryButton;
import org.terasology.module.lightandshadow.events.GameStartMessageEvent;
import org.terasology.module.lightandshadow.events.TimerEvent;
import org.terasology.notifications.events.ExpireNotificationEvent;
import org.terasology.notifications.events.ShowNotificationEvent;
import org.terasology.notifications.model.Notification;
import org.terasology.notify.ui.DialogNotificationOverlay;
import org.terasology.nui.Color;
import org.terasology.nui.FontColor;

import java.util.Timer;
import java.util.TimerTask;

@RegisterSystem(RegisterMode.CLIENT)
public class ClientPregameSystem extends BaseComponentSystem {
private static final String NOTIFICATION_ID = "LightAndShadow:firstTimeShop";

public static final ResourceUrn ASSET_URI = new ResourceUrn("LightAndShadow:Timer");

private static final String PREGAME_MESSAGE = "The game start's as soon as there is \n at least one player in each team.";

private static Timer timer;

@In
InputSystem inputSystem;

@In
private EntityManager entityManager;
@In
Expand All @@ -52,6 +73,7 @@ public void shutdown() {
public void onPregameStart(GameStartMessageEvent event, EntityRef entity) {
if (localPlayer.getClientEntity().equals(entity)) {
window.addNotification(PREGAME_MESSAGE);
entity.upsertComponent(AllowShopScreenComponent.class, c -> c.orElse(new AllowShopScreenComponent()));
}
}

Expand Down Expand Up @@ -81,5 +103,57 @@ public void run() {
}
}

/**
* Handles the button event if in-game shop is enabled.
* Needs to have a higher priority than {@link MarketUiClientSystem#onToggleInventory(InventoryButton, EntityRef)}
* to receive the {@link InventoryButton} event before it is consumed.
*
* @param event the help button event.
* @param entity the entity to display the help screen to.
*/
@ReceiveEvent(components = {ClientComponent.class, AllowShopScreenComponent.class}, priority = EventPriority.PRIORITY_CRITICAL)
public void onInGameShopButton(InventoryButton event, EntityRef entity) {
if (event.getState() == ButtonState.DOWN) {
entity.send(new ExpireNotificationEvent(NOTIFICATION_ID));
}
}

/**
* Get a formatted representation of the primary {@link Input} associated with the given button binding.
*
* If the display name of the primary bound key is a single character this representation will be the encircled
* character. Otherwise the full display name is used. The bound key will be printed in yellow.
*
* If no key binding was found the text "n/a" in red color is returned.
*
* @param button the URI of a bindable button
* @return a formatted text to be used as representation for the player
*/
//TODO: put this in a common place? Duplicated in Dialogs, EventualSkills, and InGameHelp
private String getActivationKey(SimpleUri button) {
return inputSystem.getInputsForBindButton(button).stream()
.findFirst()
.map(Input::getDisplayName)
.map(key -> {
if (key.length() == 1) {
// print the key in yellow within a circle
int off = key.charAt(0) - 'A';
char code = (char) (EnclosedAlphanumerics.CIRCLED_LATIN_CAPITAL_LETTER_A + off);
return String.valueOf(code);
} else {
return key;
}
})
.map(key -> FontColor.getColored(key, Color.yellow))
.orElse(FontColor.getColored("n/a", Color.red));
}

@ReceiveEvent(components = AllowShopScreenComponent.class)
public void onShopComponentAdded(OnAddedComponent event, EntityRef entity) {
Notification notification = new Notification(NOTIFICATION_ID,
"Shut Up and Take My Money!",
"Press " + getActivationKey(new SimpleUri("Inventory:inventory")) + " to buy items",
"Economy:GoldCoin");
localPlayer.getClientEntity().send(new ShowNotificationEvent(notification));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
*/
@RegisterSystem(RegisterMode.CLIENT)
public class ClientStatisticsSystem extends BaseComponentSystem {
private static final String NOTIFICATION_ID = "LightAndShadow:firstTime";
private static final String NOTIFICATION_ID = "LightAndShadow:firstTimeStatistics";

@In
InputSystem inputSystem;
Expand Down Expand Up @@ -88,6 +88,18 @@ public void onTab(TapButton event, EntityRef entity) {
}
}

/**
* Get a formatted representation of the primary {@link Input} associated with the given button binding.
*
* If the display name of the primary bound key is a single character this representation will be the encircled
* character. Otherwise the full display name is used. The bound key will be printed in yellow.
*
* If no key binding was found the text "n/a" in red color is returned.
*
* @param button the URI of a bindable button
* @return a formatted text to be used as representation for the player
*/
//TODO: put this in a common place? Duplicated in Dialogs, EventualSkills, and InGameHelp
private String getActivationKey(SimpleUri button) {
return inputSystem.getInputsForBindButton(button).stream()
.findFirst()
Expand Down