diff --git a/module.txt b/module.txt index 2ac2e69f5..62ab8bf06 100644 --- a/module.txt +++ b/module.txt @@ -15,6 +15,11 @@ "id": "ModuleTestingEnvironment", "minVersion": "0.2.0", "optional": true + }, + { + "id": "Notifications", + "minVersion": "0.1.0", + "maxVersion": "0.3.0" } ], "isLibrary": true, diff --git a/src/main/java/org/terasology/module/inventory/systems/InventoryClientSystem.java b/src/main/java/org/terasology/module/inventory/systems/InventoryClientSystem.java index 52c1deb57..77b0cd549 100644 --- a/src/main/java/org/terasology/module/inventory/systems/InventoryClientSystem.java +++ b/src/main/java/org/terasology/module/inventory/systems/InventoryClientSystem.java @@ -7,29 +7,17 @@ import org.terasology.engine.entitySystem.systems.BaseComponentSystem; import org.terasology.engine.entitySystem.systems.RegisterMode; import org.terasology.engine.entitySystem.systems.RegisterSystem; -import org.terasology.module.inventory.components.InventoryComponent; -import org.terasology.module.inventory.events.MoveItemAction; -import org.terasology.module.inventory.events.SwitchItemAction; -import org.terasology.module.inventory.events.AbstractMoveItemRequest; -import org.terasology.module.inventory.events.InventoryChangeAcknowledgedRequest; -import org.terasology.module.inventory.events.MoveItemAmountRequest; -import org.terasology.module.inventory.events.MoveItemRequest; -import org.terasology.module.inventory.events.MoveItemToSlotsRequest; import org.terasology.engine.logic.players.LocalPlayer; import org.terasology.engine.registry.In; import org.terasology.engine.registry.Share; +import org.terasology.module.inventory.components.InventoryComponent; +import org.terasology.module.inventory.events.*; -import java.util.Collection; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; @RegisterSystem(RegisterMode.REMOTE_CLIENT) @Share(value = InventoryManager.class) public class InventoryClientSystem extends BaseComponentSystem implements InventoryManager { - @In private LocalPlayer localPlayer; diff --git a/src/main/java/org/terasology/module/inventory/systems/InventoryUIClientSystem.java b/src/main/java/org/terasology/module/inventory/systems/InventoryUIClientSystem.java index e30b3be34..46552b518 100644 --- a/src/main/java/org/terasology/module/inventory/systems/InventoryUIClientSystem.java +++ b/src/main/java/org/terasology/module/inventory/systems/InventoryUIClientSystem.java @@ -4,6 +4,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.terasology.engine.core.SimpleUri; +import org.terasology.engine.input.InputSystem; +import org.terasology.engine.logic.players.event.LocalPlayerInitializedEvent; +import org.terasology.engine.unicode.EnclosedAlphanumerics; import org.terasology.gestalt.assets.ResourceUrn; import org.terasology.engine.entitySystem.entity.EntityRef; import org.terasology.engine.entitySystem.event.EventPriority; @@ -12,15 +16,21 @@ import org.terasology.engine.entitySystem.systems.RegisterMode; 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.module.inventory.input.InventoryButton; import org.terasology.engine.logic.characters.CharacterComponent; import org.terasology.engine.logic.characters.interactions.InteractionUtil; import org.terasology.engine.logic.players.LocalPlayer; import org.terasology.engine.network.ClientComponent; +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.ControlWidget; import org.terasology.engine.registry.In; import org.terasology.engine.rendering.nui.NUIManager; +import org.terasology.nui.FontColor; import java.util.ArrayList; import java.util.List; @@ -30,30 +40,43 @@ @RegisterSystem(RegisterMode.CLIENT) public class InventoryUIClientSystem extends BaseComponentSystem { + private static final String NOTIFICATION_ID = "Inventory:emptyPockets"; + private static final Logger logger = LoggerFactory.getLogger(InventoryUIClientSystem.class); + EntityRef movingItemItem = EntityRef.NULL; int movingItemCount = 0; - private static final Logger logger = LoggerFactory.getLogger(InventoryUIClientSystem.class); - @In private NUIManager nuiManager; @In private InventoryManager inventoryManager; + @In + private InputSystem inputSystem; + @In private LocalPlayer localPlayer; @Override public void initialise() { nuiManager.getHUD().addHUDElement("inventoryHud"); + nuiManager.getHUD().addHUDElement("Inventory:EmptyPocketsNagWidget"); nuiManager.addOverlay("Inventory:transferItemCursor", ControlWidget.class); } + @ReceiveEvent + public void onLocalPlayerInitialized(LocalPlayerInitializedEvent event, EntityRef entity) { + EntityRef targetEntity = localPlayer.getCharacterEntity(); + InventoryComponent inventoryComponent = targetEntity.getComponent(InventoryComponent.class); + showEmptyPocketsNotification(); + } + @ReceiveEvent(components = ClientComponent.class) public void onToggleInventory(InventoryButton event, EntityRef entity) { if (event.getState() == ButtonState.DOWN) { + localPlayer.getClientEntity().send(new ExpireNotificationEvent(NOTIFICATION_ID)); nuiManager.toggleScreen("Inventory:inventoryScreen"); event.consume(); } @@ -163,4 +186,44 @@ public void postAutoSave() { movingItemItem = EntityRef.NULL; } + + /** + * 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 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)); + } + + private void showEmptyPocketsNotification() { + Notification notification = + new Notification(NOTIFICATION_ID, + "Empty Pockets", + "Press " + getActivationKey(new SimpleUri("Inventory:inventory")) + " to open " + + "your inventory", + "CoreAssets:ChestFront"); + localPlayer.getClientEntity().send(new ShowNotificationEvent(notification)); + } }