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

Status screen rework #51

Open
wants to merge 7 commits into
base: develop
Choose a base branch
from
Open
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
61 changes: 61 additions & 0 deletions overrides/Core/ui/ingame/inventoryScreen.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{
"type": "inventoryScreen",
"skin": "inventoryDefault",
"contents": {
"type": "ColumnLayout",
"id": "outerColumns",
"columns": 3,
"column-widths": [
0.2,
0.6,
0.2
],
"contents": [
{
"type": "UISpace",
"size": [
0,
0
]
},
{
"type": "RelativeLayout",
"id": "inventoryLayout",
"contents": [
{
"type": "InventoryGrid",
"id": "inventory",
"maxHorizontalCells": 10,
"layoutInfo": {
"use-content-height": true,
"use-content-width": false,
"position-left": {
"offset": 32
},
"position-right": {
"offset": 32
},
"position-vertical-center": {}
}
}
]
},
{
"type": "RelativeLayout",
"id": "outerLayout",
"contents": [
{
"type": "PotionStatusWidget",
"id": "PotionUI",
"layoutInfo": {
"use-content-height": true,
"use-content-width": false,
"position-vertical-center": {},
"position-horizontal-center": {}
}
}
]
}
]
}
}
72 changes: 0 additions & 72 deletions src/main/java/org/terasology/potions/PotionStatusScreen.java

This file was deleted.

138 changes: 70 additions & 68 deletions src/main/java/org/terasology/potions/PotionStatusUISystem.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,115 +13,117 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.terasology.potions;

import org.terasology.entitySystem.entity.EntityManager;
import org.terasology.engine.Time;
import org.terasology.entitySystem.entity.EntityRef;
import org.terasology.entitySystem.event.EventPriority;
import org.terasology.entitySystem.event.ReceiveEvent;
import org.terasology.entitySystem.systems.BaseComponentSystem;
import org.terasology.entitySystem.systems.RegisterMode;
import org.terasology.entitySystem.systems.RegisterSystem;
import org.terasology.input.ButtonState;
import org.terasology.input.binds.general.PauseButton;
import org.terasology.input.binds.inventory.InventoryButton;
import org.terasology.logic.delay.DelayManager;
import org.terasology.logic.delay.PeriodicActionTriggeredEvent;
import org.terasology.logic.delay.DelayedActionTriggeredEvent;
import org.terasology.logic.players.LocalPlayer;
import org.terasology.potions.component.PotionEffect;
import org.terasology.potions.events.DrinkPotionEvent;
import org.terasology.registry.In;
import org.terasology.rendering.nui.NUIManager;

import java.util.ArrayList;
import org.terasology.rendering.nui.databinding.Binding;
import org.terasology.rendering.nui.databinding.ReadOnlyBinding;


@RegisterSystem(RegisterMode.CLIENT)
public class PotionStatusUISystem extends BaseComponentSystem {

private static final String PERIODIC_ACTION_ID = "PotionStatusScreenUI";
private static final String TARGET_SCREEN_NAME = "Core:InventoryScreen";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private static final String TARGET_SCREEN_NAME = "Core:InventoryScreen";
private static final String TARGET_SCREEN_NAME = "Inventory:InventoryScreen";

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

weirdly, it doesn't work for me locally if I use Inventory:InventoryScreen ... what is this referring to? 🤔

private static final String WIDGET_NAME = "PotionUI";
@In
private NUIManager nuiManager;
@In
private DelayManager delayManager;
@In
private EntityManager entityManager;

private PotionStatusScreen screen;

private ArrayList<Float> magnitudes = new ArrayList<>();
private ArrayList<Long> durations = new ArrayList<>();
private ArrayList<String> effects = new ArrayList<>();

private boolean isScreenVisible = false;
private LocalPlayer localPlayer;
@In
private Time time;
private PotionStatusWidget widget;

private int updateRate = 200;

private static final String PERIODIC_ACTION_ID = "PotionStatusScreenUI";
private static final String POTION_STATUS_SCREEN_NAME = "potions:potionStatusScreen";

@Override
public void initialise() {
}

@ReceiveEvent(priority = 110)
public void inventoryToggled(InventoryButton event, EntityRef entity) {
if (event.getState() == ButtonState.DOWN) {
nuiManager.toggleScreen(POTION_STATUS_SCREEN_NAME);
isScreenVisible = nuiManager.isOpen(POTION_STATUS_SCREEN_NAME);
updateScreen();
/**
* Locates the Potion Status widget on the inventory screen.
* <p>
* Called when the inventory button is pressed
* Priority Low to ensure it's called /after/ the screen is opened
*
* @see InventoryButton
*/
@ReceiveEvent(priority = EventPriority.PRIORITY_LOW)
public void onInventoryButton(InventoryButton event, EntityRef entity) {
if (nuiManager.isOpen(TARGET_SCREEN_NAME)) {
widget = nuiManager.getScreen(TARGET_SCREEN_NAME).find(WIDGET_NAME, PotionStatusWidget.class);
} else {
widget = null;
}
}

@ReceiveEvent(priority = 110)
public void inventoryToggledOff(PauseButton event, EntityRef entity) {
if (nuiManager.isOpen(POTION_STATUS_SCREEN_NAME)) {
nuiManager.closeScreen(POTION_STATUS_SCREEN_NAME);
isScreenVisible = nuiManager.isOpen(POTION_STATUS_SCREEN_NAME);
updateScreen();
}
}

@ReceiveEvent(priority = EventPriority.PRIORITY_HIGH)
/**
* Adds the effect to the screen and initiates the timer to remove it once it's done
* <p>
* Called when a potion is drunk
*
* @see DrinkPotionEvent
*/
@ReceiveEvent
public void onPotionDrink(DrinkPotionEvent event, EntityRef entity) {

for (PotionEffect effect : event.getPotionComponent().effects) {
int index = effects.indexOf(effect.effect);

if (index == -1) {
effects.add(effect.effect);
magnitudes.add(effect.magnitude);
durations.add(effect.duration);
delayManager.addPeriodicAction(entity, PERIODIC_ACTION_ID + effect.effect, updateRate, updateRate);
} else {
effects.set(index, effect.effect);
magnitudes.add(index, effect.magnitude);
durations.set(index, effect.duration);
}
if (widget != null) {
event.getPotionComponent().effects.forEach(this::addPotionEffect);
}
updateScreen();
}

@ReceiveEvent
public void onEffectUpdate(PeriodicActionTriggeredEvent event, EntityRef entity) {
String actionID = event.getActionId();
if (actionID.startsWith(PERIODIC_ACTION_ID)) {
int index = effects.indexOf(actionID.substring(PERIODIC_ACTION_ID.length()));
durations.set(index, durations.get(index) - updateRate);
if (durations.get(index) < 0) {
magnitudes.remove(index);
durations.remove(index);
effects.remove(index);
delayManager.cancelPeriodicAction(entity, actionID);
/**
* Adds a new effect to the widget.
* Also registers for the effect to be removed when the duration gets too low.
*
* @param effect The effect to add
*/
private void addPotionEffect(PotionEffect effect) {
long endTime = time.getGameTimeInMs() + effect.duration;
Binding<Long> binding = new ReadOnlyBinding<Long>() {
@Override
public Long get() {
return endTime - time.getGameTimeInMs();
}
updateScreen();
};
widget.addOrUpdateEffect(effect.effect, binding);

/* Register removal */
if (delayManager.hasDelayedAction(localPlayer.getCharacterEntity(), PERIODIC_ACTION_ID + effect.effect)) {
delayManager.cancelDelayedAction(localPlayer.getCharacterEntity(), PERIODIC_ACTION_ID + effect.effect);
}
delayManager.addDelayedAction(localPlayer.getCharacterEntity(), PERIODIC_ACTION_ID + effect.effect, effect.duration);
}

private void updateScreen() {
if (isScreenVisible) {
screen = (PotionStatusScreen) nuiManager.getScreen(POTION_STATUS_SCREEN_NAME);
screen.removeAll();
for (int i = 0; i < Math.min(15, effects.size()); i++) {
screen.addEffect(i, effects.get(i), magnitudes.get(i), durations.get(i));
/**
* Removes the effect from the widget once it's duration has ended.
* <p>
* Called when the timer is finished
*
* @see DelayedActionTriggeredEvent
*/
@ReceiveEvent
public void onDelayedActionTriggered(DelayedActionTriggeredEvent event, EntityRef entity) {
String eventId = event.getActionId();
if (eventId.startsWith(PERIODIC_ACTION_ID)) {
eventId = eventId.replace(PERIODIC_ACTION_ID, "");
if (widget != null) {
widget.removeEffect(eventId);
}
}
}
Expand Down
Loading