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

feature: update shop with economy, add notification #71

Merged
merged 1 commit 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
5 changes: 5 additions & 0 deletions module.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@
{
"id": "Inventory",
"minVersion": "1.1.0"
},
{
"id": "Notifications",
"minVersion": "0.1.0",
"maxVersion": "0.3.0"
}
],
"serverSideOnly": false,
Expand Down
78 changes: 78 additions & 0 deletions src/main/java/org/terasology/gooeyDefence/economy/ShopManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,38 @@
// SPDX-License-Identifier: Apache-2.0
package org.terasology.gooeyDefence.economy;

import org.terasology.economy.components.AllowShopScreenComponent;
import org.terasology.economy.components.CurrencyStorageComponent;
import org.terasology.economy.events.WalletUpdatedEvent;
import org.terasology.economy.ui.MarketUiClientSystem;
import org.terasology.engine.core.SimpleUri;
import org.terasology.engine.entitySystem.entity.lifecycleEvents.OnAddedComponent;
import org.terasology.engine.entitySystem.event.EventPriority;
import org.terasology.engine.input.InputSystem;
import org.terasology.engine.logic.players.event.OnPlayerSpawnedEvent;
import org.terasology.engine.network.ClientComponent;
import org.terasology.engine.network.events.ConnectedEvent;
import org.terasology.engine.unicode.EnclosedAlphanumerics;
import org.terasology.gestalt.assets.management.AssetManager;
import org.terasology.engine.entitySystem.entity.EntityManager;
import org.terasology.engine.entitySystem.entity.EntityRef;
import org.terasology.engine.entitySystem.event.ReceiveEvent;
import org.terasology.engine.entitySystem.prefab.Prefab;
import org.terasology.engine.entitySystem.systems.BaseComponentSystem;
import org.terasology.engine.entitySystem.systems.RegisterSystem;
import org.terasology.input.ButtonState;
import org.terasology.input.Input;
import org.terasology.module.inventory.components.InventoryComponent;
import org.terasology.engine.logic.players.LocalPlayer;
import org.terasology.engine.registry.In;
import org.terasology.gooeyDefence.DefenceUris;
import org.terasology.gooeyDefence.events.OnFieldReset;
import org.terasology.module.inventory.input.InventoryButton;
import org.terasology.notifications.events.ExpireNotificationEvent;
import org.terasology.notifications.events.ShowNotificationEvent;
import org.terasology.notifications.model.Notification;
import org.terasology.nui.Color;
import org.terasology.nui.FontColor;

import java.util.Optional;

Expand All @@ -26,6 +42,10 @@
*/
@RegisterSystem
public class ShopManager extends BaseComponentSystem {
private static final String NOTIFICATION_ID = "GooeyDefence:firstTime";

@In
private InputSystem inputSystem;
@In
private AssetManager assetManager;
@In
Expand All @@ -35,11 +55,15 @@ public class ShopManager extends BaseComponentSystem {

@ReceiveEvent(priority = EventPriority.PRIORITY_LOW)
public void onPlayerJoin(OnPlayerSpawnedEvent onPlayerSpawnedEvent, EntityRef player, CurrencyStorageComponent currencyStorageComponent) {
// Fill player's wallet
CurrencyStorageComponent component = assetManager.getAsset(DefenceUris.PLAYER, Prefab.class)
.map(prefab -> prefab.getComponent(CurrencyStorageComponent.class))
.orElse(new CurrencyStorageComponent());
player.addOrSaveComponent(component);
player.send(new WalletUpdatedEvent(component.amount));

// Ensure that the client has the {@link AllowShopScreenComponent} such that they can use the in-game shop from the Economy module.
localPlayer.getClientEntity().upsertComponent(AllowShopScreenComponent.class, c -> c.orElse(new AllowShopScreenComponent()));
}

@ReceiveEvent
Expand Down Expand Up @@ -75,4 +99,58 @@ private void cleanUpMoney() {
}
}
}

/**
* 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 tower parts",
"Economy:GoldCoin");
localPlayer.getClientEntity().send(new ShowNotificationEvent(notification));
}
}