From 50645f77cab685f019f60076753bd4755ca3fd14 Mon Sep 17 00:00:00 2001 From: Mayant Mukul Date: Mon, 29 Jul 2019 18:48:50 +0530 Subject: [PATCH 1/9] Extract a baseCitizen prefab --- assets/prefabs/characters/badCitizen.prefab | 67 +---------------- assets/prefabs/characters/baseCitizen.prefab | 71 +++++++++++++++++++ assets/prefabs/characters/goodCitizen.prefab | 67 +---------------- assets/prefabs/characters/gooeyCitizen.prefab | 67 +---------------- 4 files changed, 77 insertions(+), 195 deletions(-) create mode 100644 assets/prefabs/characters/baseCitizen.prefab diff --git a/assets/prefabs/characters/badCitizen.prefab b/assets/prefabs/characters/badCitizen.prefab index 8777a642..efee67c8 100644 --- a/assets/prefabs/characters/badCitizen.prefab +++ b/assets/prefabs/characters/badCitizen.prefab @@ -1,9 +1,8 @@ { - "alwaysRelevant": true, + "parent": "baseCitizen", "displayName": { "name": "badCitizen" }, - "persisted": true, "skeletalmesh": { "mesh": "MetalRenegades:gooey", "heightOffset": -2.0, @@ -43,67 +42,5 @@ }, "Behavior": { "tree": "MetalRenegades:citizen" - }, - "Stand": { - "animationPool": [ - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyLookRightLeft", - "gooeyLookRightLeft", - "gooeyLookRightUp" - ] - }, - "Walk": { - "animationPool": [ - "gooeyIdleBreathing" - ] - }, - "Location": {}, - "Character": {}, - "AliveCharacter": {}, - "CharacterMovement" : { - "groundFriction": 16, - "speedMultiplier": 0.3, - "distanceBetweenFootsteps": 0.2, - "distanceBetweenSwimStrokes": 2.5, - "height": 1.0, - "radius": 0.5, - "jumpSpeed": 12 - }, - "Network": {}, - "MinionMove": {}, - "Health": {}, - "BoxShape": { - "extents": [ - 1.0, - 1.0, - 1.0 - ] - }, - "Trigger": { - "detectGroups": [ - "engine:debris", - "engine:sensor" - ] - }, - "Citizen": {} + } } diff --git a/assets/prefabs/characters/baseCitizen.prefab b/assets/prefabs/characters/baseCitizen.prefab new file mode 100644 index 00000000..6a00046f --- /dev/null +++ b/assets/prefabs/characters/baseCitizen.prefab @@ -0,0 +1,71 @@ +{ + "alwaysRelevant": true, + "persisted": true, + "Stand": { + "animationPool": [ + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyLookRightLeft", + "gooeyLookRightLeft", + "gooeyLookRightUp" + ] + }, + "Walk": { + "animationPool": [ + "gooeyIdleBreathing" + ] + }, + "Location": {}, + "Character": {}, + "AliveCharacter": {}, + "CharacterMovement" : { + "groundFriction": 16, + "speedMultiplier": 0.3, + "distanceBetweenFootsteps": 0.2, + "distanceBetweenSwimStrokes": 2.5, + "height": 1.0, + "radius": 0.5, + "jumpSpeed": 12 + }, + "Network": {}, + "MinionMove": {}, + "Health": {}, + "BoxShape": { + "extents": [ + 1.0, + 1.0, + 1.0 + ] + }, + "Trigger": { + "detectGroups": [ + "engine:debris", + "engine:sensor" + ] + }, + "Citizen": {}, + "Inventory": {}, + "InteractionTarget": {}, + "InteractionScreen": { + "screen": "tradingScreen" + } +} diff --git a/assets/prefabs/characters/goodCitizen.prefab b/assets/prefabs/characters/goodCitizen.prefab index 6a5402ee..fc44b1de 100644 --- a/assets/prefabs/characters/goodCitizen.prefab +++ b/assets/prefabs/characters/goodCitizen.prefab @@ -1,9 +1,8 @@ { - "alwaysRelevant": true, + "parent": "baseCitizen", "displayName": { "name": "goodCitizen" }, - "persisted": true, "skeletalmesh": { "mesh": "MetalRenegades:gooey", "heightOffset": -2.0, @@ -43,67 +42,5 @@ }, "Behavior": { "tree": "MetalRenegades:citizen" - }, - "Stand": { - "animationPool": [ - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyLookRightLeft", - "gooeyLookRightLeft", - "gooeyLookRightUp" - ] - }, - "Walk": { - "animationPool": [ - "gooeyIdleBreathing" - ] - }, - "Location": {}, - "Character": {}, - "AliveCharacter": {}, - "CharacterMovement" : { - "groundFriction": 16, - "speedMultiplier": 0.3, - "distanceBetweenFootsteps": 0.2, - "distanceBetweenSwimStrokes": 2.5, - "height": 1.0, - "radius": 0.5, - "jumpSpeed": 12 - }, - "Network": {}, - "MinionMove": {}, - "Health": {}, - "BoxShape": { - "extents": [ - 1.0, - 1.0, - 1.0 - ] - }, - "Trigger": { - "detectGroups": [ - "engine:debris", - "engine:sensor" - ] - }, - "Citizen": {} + } } diff --git a/assets/prefabs/characters/gooeyCitizen.prefab b/assets/prefabs/characters/gooeyCitizen.prefab index 3a2f3f35..9b0ddea4 100644 --- a/assets/prefabs/characters/gooeyCitizen.prefab +++ b/assets/prefabs/characters/gooeyCitizen.prefab @@ -1,9 +1,8 @@ { - "alwaysRelevant": true, + "parent": "baseCitizen", "displayName": { "name": "gooeyCitizen" }, - "persisted": true, "skeletalmesh": { "mesh": "MetalRenegades:gooey", "heightOffset": -2.0, @@ -43,67 +42,5 @@ }, "Behavior": { "tree": "MetalRenegades:citizen" - }, - "Stand": { - "animationPool": [ - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyIdleBreathing", - "gooeyLookRightLeft", - "gooeyLookRightLeft", - "gooeyLookRightUp" - ] - }, - "Walk": { - "animationPool": [ - "gooeyIdleBreathing" - ] - }, - "Location": {}, - "Character": {}, - "AliveCharacter": {}, - "CharacterMovement" : { - "groundFriction": 16, - "speedMultiplier": 0.3, - "distanceBetweenFootsteps": 0.2, - "distanceBetweenSwimStrokes": 2.5, - "height": 1.0, - "radius": 0.5, - "jumpSpeed": 12 - }, - "Network": {}, - "MinionMove": {}, - "Health": {}, - "BoxShape": { - "extents": [ - 1.0, - 1.0, - 1.0 - ] - }, - "Trigger": { - "detectGroups": [ - "engine:debris", - "engine:sensor" - ] - }, - "Citizen": {} + } } From c14acd8fe2a24c7c84aca45bbca8b24347c4f930 Mon Sep 17 00:00:00 2001 From: Mayant Mukul Date: Fri, 2 Aug 2019 14:43:34 +0530 Subject: [PATCH 2/9] Add basic trading UI --- assets/prefabs/characters/baseCitizen.prefab | 6 +- assets/ui/tradingScreen.ui | 97 ++++++++++++++ .../ai/system/CitizenSpawnSystem.java | 38 ++++++ .../actions/ShowTradingScreenAction.java | 31 +++++ .../ShowTradingScreenActionTypeHandler.java | 45 +++++++ .../events/TradeScreenRequestEvent.java | 23 ++++ .../economy/systems/TraderSpawnSystem.java | 2 +- .../economy/ui/TradingScreen.java | 122 ++++++++++++++++++ .../economy/ui/TradingUISystem.java | 103 +++++++++++++++ 9 files changed, 461 insertions(+), 6 deletions(-) create mode 100644 assets/ui/tradingScreen.ui create mode 100644 src/main/java/org/terasology/metalrenegades/economy/actions/ShowTradingScreenAction.java create mode 100644 src/main/java/org/terasology/metalrenegades/economy/actions/ShowTradingScreenActionTypeHandler.java create mode 100644 src/main/java/org/terasology/metalrenegades/economy/events/TradeScreenRequestEvent.java create mode 100644 src/main/java/org/terasology/metalrenegades/economy/ui/TradingScreen.java create mode 100644 src/main/java/org/terasology/metalrenegades/economy/ui/TradingUISystem.java diff --git a/assets/prefabs/characters/baseCitizen.prefab b/assets/prefabs/characters/baseCitizen.prefab index 6a00046f..aabe1f4c 100644 --- a/assets/prefabs/characters/baseCitizen.prefab +++ b/assets/prefabs/characters/baseCitizen.prefab @@ -63,9 +63,5 @@ ] }, "Citizen": {}, - "Inventory": {}, - "InteractionTarget": {}, - "InteractionScreen": { - "screen": "tradingScreen" - } + "Inventory": {} } diff --git a/assets/ui/tradingScreen.ui b/assets/ui/tradingScreen.ui new file mode 100644 index 00000000..cf627f3e --- /dev/null +++ b/assets/ui/tradingScreen.ui @@ -0,0 +1,97 @@ +{ + "type": "tradingScreen", + "skin": "engineDefault", + "contents": { + "type": "relativeLayout", + "contents": [ + { + "type": "UIBox", + "layoutInfo": { + "width": 850, + "height": 850, + "position-horizontal-center": {}, + "position-vertical-center": {} + }, + "content": { + "type": "relativeLayout", + "contents": [ + { + "type": "UILabel", + "text": "Citizen", + "layoutInfo": { + "use-content-width": true, + "use-content-height": true, + "position-left": {}, + "position-top": { + "offset": 20 + } + } + }, + { + "type": "UIList", + "id": "citizenList", + "layoutInfo": { + "width": 400, + "use-content-height": true, + "position-left": {}, + "position-top": { + "offset": 50 + } + } + }, + { + "type": "UILabel", + "text": "Player", + "layoutInfo": { + "use-content-width": true, + "use-content-height": true, + "position-right": {}, + "position-top": { + "offset": 20 + } + } + }, + { + "type": "UIList", + "id": "playerList", + "layoutInfo": { + "width": 400, + "use-content-height": true, + "position-right": {}, + "position-top": { + "offset": 50 + } + } + }, + { + "type": "UILabel", + "id": "message", + "text": "label", + "layoutInfo": { + "use-content-width": true, + "use-content-height": true, + "position-horizontal-center": {}, + "position-bottom": { + "offset": 60 + } + } + }, + { + "type": "UIButton", + "id": "tradeButton", + "text": "Trade", + "layoutInfo": { + "width": 90, + "use-content-height": true, + "position-horizontal-center": {}, + "position-bottom": { + "offset": 20 + } + } + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/src/main/java/org/terasology/metalrenegades/ai/system/CitizenSpawnSystem.java b/src/main/java/org/terasology/metalrenegades/ai/system/CitizenSpawnSystem.java index f60f06b4..291034f7 100644 --- a/src/main/java/org/terasology/metalrenegades/ai/system/CitizenSpawnSystem.java +++ b/src/main/java/org/terasology/metalrenegades/ai/system/CitizenSpawnSystem.java @@ -15,6 +15,10 @@ */ package org.terasology.metalrenegades.ai.system; +import org.terasology.dialogs.action.CloseDialogAction; +import org.terasology.dialogs.components.DialogComponent; +import org.terasology.dialogs.components.DialogPage; +import org.terasology.dialogs.components.DialogResponse; import org.terasology.entitySystem.entity.EntityBuilder; import org.terasology.entitySystem.entity.EntityManager; import org.terasology.entitySystem.entity.EntityRef; @@ -28,8 +32,10 @@ import org.terasology.metalrenegades.ai.component.CitizenComponent; import org.terasology.metalrenegades.ai.component.HomeComponent; import org.terasology.metalrenegades.ai.component.PotentialHomeComponent; +import org.terasology.metalrenegades.economy.actions.ShowTradingScreenAction; import org.terasology.registry.In; +import java.util.ArrayList; import java.util.Collection; /** @@ -97,6 +103,7 @@ private EntityRef spawnCitizen(EntityRef homeEntity) { entityBuilder.addComponent(homeComponent); entityBuilder.saveComponent(citizenLocationComponent); + entityBuilder.addComponent(createTradeDialogComponent()); return entityBuilder.build(); } @@ -117,4 +124,35 @@ private Prefab chooseCitizenPrefab() { } return null; } + + private DialogComponent createTradeDialogComponent() { + DialogComponent component = new DialogComponent(); + component.pages = new ArrayList<>(); + + DialogPage page = new DialogPage(); + page.id = "main"; + page.title = "Wanna trade?"; + page.paragraphText = new ArrayList<>(); + page.responses = new ArrayList<>(); + + page.paragraphText.add("I've got wares"); + + DialogResponse tradeResponse = new DialogResponse(); + tradeResponse.text = "Show me what you got"; + tradeResponse.action = new ArrayList<>(); + tradeResponse.action.add(new ShowTradingScreenAction()); + + DialogResponse closeResponse = new DialogResponse(); + closeResponse.text = "Later"; + closeResponse.action = new ArrayList<>(); + closeResponse.action.add(new CloseDialogAction()); + + page.responses.add(tradeResponse); + page.responses.add(closeResponse); + + component.pages.add(page); + component.firstPage = page.id; + + return component; + } } diff --git a/src/main/java/org/terasology/metalrenegades/economy/actions/ShowTradingScreenAction.java b/src/main/java/org/terasology/metalrenegades/economy/actions/ShowTradingScreenAction.java new file mode 100644 index 00000000..b1322290 --- /dev/null +++ b/src/main/java/org/terasology/metalrenegades/economy/actions/ShowTradingScreenAction.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019 MovingBlocks + * + * 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.terasology.metalrenegades.economy.actions; + +import org.terasology.dialogs.action.PlayerAction; +import org.terasology.entitySystem.entity.EntityRef; +import org.terasology.metalrenegades.economy.events.TradeScreenRequestEvent; + +public class ShowTradingScreenAction implements PlayerAction { + + public ShowTradingScreenAction() { + } + + @Override + public void execute(EntityRef charEntity, EntityRef talkTo) { + talkTo.send(new TradeScreenRequestEvent()); + } +} diff --git a/src/main/java/org/terasology/metalrenegades/economy/actions/ShowTradingScreenActionTypeHandler.java b/src/main/java/org/terasology/metalrenegades/economy/actions/ShowTradingScreenActionTypeHandler.java new file mode 100644 index 00000000..e4daa4ad --- /dev/null +++ b/src/main/java/org/terasology/metalrenegades/economy/actions/ShowTradingScreenActionTypeHandler.java @@ -0,0 +1,45 @@ +/* + * Copyright 2019 MovingBlocks + * + * 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.terasology.metalrenegades.economy.actions; + +import com.google.common.collect.ImmutableMap; +import org.terasology.persistence.typeHandling.DeserializationContext; +import org.terasology.persistence.typeHandling.PersistedData; +import org.terasology.persistence.typeHandling.PersistedDataMap; +import org.terasology.persistence.typeHandling.RegisterTypeHandler; +import org.terasology.persistence.typeHandling.SerializationContext; +import org.terasology.persistence.typeHandling.SimpleTypeHandler; + +import java.util.Map; + +@RegisterTypeHandler +public class ShowTradingScreenActionTypeHandler extends SimpleTypeHandler { + + @Override + public PersistedData serialize(ShowTradingScreenAction action, SerializationContext context) { + Map data = ImmutableMap.of( + "type", context.create(action.getClass().getSimpleName())); + + return context.create(data); + } + + @Override + public ShowTradingScreenAction deserialize(PersistedData data, DeserializationContext context) { + return new ShowTradingScreenAction(); + } + +} diff --git a/src/main/java/org/terasology/metalrenegades/economy/events/TradeScreenRequestEvent.java b/src/main/java/org/terasology/metalrenegades/economy/events/TradeScreenRequestEvent.java new file mode 100644 index 00000000..04382783 --- /dev/null +++ b/src/main/java/org/terasology/metalrenegades/economy/events/TradeScreenRequestEvent.java @@ -0,0 +1,23 @@ +/* + * Copyright 2019 MovingBlocks + * + * 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.terasology.metalrenegades.economy.events; + +import org.terasology.entitySystem.event.Event; + +public class TradeScreenRequestEvent implements Event { + public TradeScreenRequestEvent() { + } +} diff --git a/src/main/java/org/terasology/metalrenegades/economy/systems/TraderSpawnSystem.java b/src/main/java/org/terasology/metalrenegades/economy/systems/TraderSpawnSystem.java index 10abf8dc..69621594 100644 --- a/src/main/java/org/terasology/metalrenegades/economy/systems/TraderSpawnSystem.java +++ b/src/main/java/org/terasology/metalrenegades/economy/systems/TraderSpawnSystem.java @@ -60,7 +60,7 @@ public void onMarketPlaceSpawn(BuildingEntitySpawnedEvent event, EntityRef entit if (genericBuildingComponent.name.equals("marketplace")) { DynParcel dynParcel = entityRef.getComponent(DynParcelRefComponent.class).dynParcel; - Optional traderGooeyOptional = Assets.getPrefab("MetalRenegades:neutralGooey"); + Optional traderGooeyOptional = Assets.getPrefab("MetalRenegades:goodCitizen"); if (traderGooeyOptional.isPresent()) { Rect2i rect2i = dynParcel.shape; Vector3f spawnPosition = new Vector3f(rect2i.minX() + rect2i.sizeX() / 2, dynParcel.getHeight() + 1, rect2i.minY() + rect2i.sizeY() / 2); diff --git a/src/main/java/org/terasology/metalrenegades/economy/ui/TradingScreen.java b/src/main/java/org/terasology/metalrenegades/economy/ui/TradingScreen.java new file mode 100644 index 00000000..32aa8df4 --- /dev/null +++ b/src/main/java/org/terasology/metalrenegades/economy/ui/TradingScreen.java @@ -0,0 +1,122 @@ +/* + * Copyright 2019 MovingBlocks + * + * 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.terasology.metalrenegades.economy.ui; + +import org.terasology.registry.In; +import org.terasology.rendering.nui.CoreScreenLayer; +import org.terasology.rendering.nui.NUIManager; +import org.terasology.rendering.nui.databinding.ReadOnlyBinding; +import org.terasology.rendering.nui.itemRendering.StringTextRenderer; +import org.terasology.rendering.nui.widgets.UIButton; +import org.terasology.rendering.nui.widgets.UILabel; +import org.terasology.rendering.nui.widgets.UIList; + +import java.util.ArrayList; +import java.util.List; + +/** + * UI for trading with citizens + */ +public class TradingScreen extends CoreScreenLayer { + + @In + private TradingUISystem tradingUISystem; + + private UIList player; + private UIList citizen; + private UIButton confirm; + private UILabel result; + + private List playerItems = new ArrayList<>(); + private List citizenItems = new ArrayList<>(); + + private MarketItem pSelected; + private MarketItem cSeleted; + + private String message; + + @Override + public void initialise() { + List items = new ArrayList<>(); + for (int i = 0; i < 6; i++) { + items.add(MarketItemBuilder.getDefault()); + } + + playerItems = items; + citizenItems = items; + + player = find("playerList", UIList.class); + player.setList(new ArrayList<>()); + player.setItemRenderer(new StringTextRenderer() { + @Override + public String getString(MarketItem value) { + return value.name; + } + }); + player.subscribeSelection(((widget, item) -> pSelected = item)); + player.bindList(new ReadOnlyBinding>() { + @Override + public List get() { + return playerItems; + } + }); + + citizen = find("citizenList", UIList.class); + citizen.setList(new ArrayList<>()); + citizen.setItemRenderer(new StringTextRenderer() { + @Override + public String getString(MarketItem value) { + return value.name; + } + }); + citizen.subscribeSelection(((widget, item) -> cSeleted = item)); + citizen.bindList(new ReadOnlyBinding>() { + @Override + public List get() { + return citizenItems; + } + }); + + result = find("message", UILabel.class); + result.bindText(new ReadOnlyBinding() { + @Override + public String get() { + return message; + } + }); + + confirm = find("tradeButton", UIButton.class); + confirm.subscribe(widget -> { + if (tradingUISystem.isAcceptable(player.getSelection(), citizen.getSelection())) { + if (tradingUISystem.trade(player.getSelection(), citizen.getSelection())) { + message = "Trade completed."; + } else { + message = "Trade failed. Try again"; + } + } else { + message = "Offer declined."; + } + }); + } + + public void setPlayerItems(List list) { + playerItems = list; + } + + public void setCitizenItems(List list) { + this.citizenItems = list; + } +} diff --git a/src/main/java/org/terasology/metalrenegades/economy/ui/TradingUISystem.java b/src/main/java/org/terasology/metalrenegades/economy/ui/TradingUISystem.java new file mode 100644 index 00000000..d535a88d --- /dev/null +++ b/src/main/java/org/terasology/metalrenegades/economy/ui/TradingUISystem.java @@ -0,0 +1,103 @@ +/* + * Copyright 2019 MovingBlocks + * + * 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.terasology.metalrenegades.economy.ui; + +import net.logstash.logback.encoder.org.apache.commons.lang.ArrayUtils; +import org.terasology.assets.ResourceUrn; +import org.terasology.entitySystem.entity.EntityRef; +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.logic.characters.interactions.InteractionUtil; +import org.terasology.logic.inventory.InventoryComponent; +import org.terasology.logic.inventory.InventoryManager; +import org.terasology.logic.players.LocalPlayer; +import org.terasology.metalrenegades.economy.events.MarketScreenRequestEvent; +import org.terasology.metalrenegades.economy.events.TradeScreenRequestEvent; +import org.terasology.metalrenegades.economy.events.TransactionType; +import org.terasology.protobuf.EntityData; +import org.terasology.registry.In; +import org.terasology.registry.Share; +import org.terasology.rendering.nui.NUIManager; +import org.terasology.segmentedpaths.controllers.SegmentMapping; + +import java.util.ArrayList; +import java.util.List; + +@Share(TradingUISystem.class) +@RegisterSystem(RegisterMode.CLIENT) +public class TradingUISystem extends BaseComponentSystem { + + @In + private NUIManager nuiManager; + + @In + private InventoryManager inventoryManager; + + @In + private LocalPlayer localPlayer; + + private TradingScreen tradingScreen; + + @Override + public void initialise() { + tradingScreen = (TradingScreen) nuiManager.createScreen("MetalRenegades:tradingScreen"); + } + + @ReceiveEvent + public void onToggleInventory(TradeScreenRequestEvent event, EntityRef entity) { + ResourceUrn activeInteractionScreenUri = InteractionUtil.getActiveInteractionScreenUri(entity); + if (activeInteractionScreenUri != null) { + InteractionUtil.cancelInteractionAsClient(entity); + } + + nuiManager.toggleScreen("MetalRenegades:tradingScreen"); + } + + @ReceiveEvent + public void onTradingScreenAction(TradeScreenRequestEvent event, EntityRef citizen) { + List citizenItems = new ArrayList<>(); + for (int i = 0; i < inventoryManager.getNumSlots(citizen); i++) { + EntityRef entity = inventoryManager.getItemInSlot(citizen, i); + if (entity.getParentPrefab() != null) { + MarketItem item = MarketItemBuilder.get(entity.getParentPrefab().getName(), 1); + citizenItems.add(item); + } + } + + List playerItems = new ArrayList<>(); + EntityRef player = localPlayer.getCharacterEntity(); + for (int i = 0; i < inventoryManager.getNumSlots(player); i++) { + EntityRef entity = inventoryManager.getItemInSlot(player, i); + if (entity.getParentPrefab() != null) { + MarketItem item = MarketItemBuilder.get(entity.getParentPrefab().getName(), 1); + playerItems.add(item); + } + } + + tradingScreen.setCitizenItems(citizenItems); + tradingScreen.setPlayerItems(playerItems); + } + + public boolean trade(MarketItem player, MarketItem citizen) { + return true; + } + + public boolean isAcceptable(MarketItem player, MarketItem citizen) { + return true; + } +} From 3e5ba62e5f3baa70856a77499d5b0547fe0adca5 Mon Sep 17 00:00:00 2001 From: Mayant Mukul Date: Fri, 2 Aug 2019 15:19:22 +0530 Subject: [PATCH 3/9] Give a railgun tool to all citizens --- assets/prefabs/characters/baseCitizen.prefab | 11 +++- .../ai/system/CitizenSpawnSystem.java | 16 +++++- .../economy/ui/TradingScreen.java | 1 + .../economy/ui/TradingUISystem.java | 50 +++++++++++++------ 4 files changed, 60 insertions(+), 18 deletions(-) diff --git a/assets/prefabs/characters/baseCitizen.prefab b/assets/prefabs/characters/baseCitizen.prefab index aabe1f4c..81558926 100644 --- a/assets/prefabs/characters/baseCitizen.prefab +++ b/assets/prefabs/characters/baseCitizen.prefab @@ -63,5 +63,14 @@ ] }, "Citizen": {}, - "Inventory": {} + "Inventory": { + "privateToOwner": false, + "itemSlots": [ + 0, + 0, + 0, + 0, + 0 + ] + } } diff --git a/src/main/java/org/terasology/metalrenegades/ai/system/CitizenSpawnSystem.java b/src/main/java/org/terasology/metalrenegades/ai/system/CitizenSpawnSystem.java index 291034f7..83bd6575 100644 --- a/src/main/java/org/terasology/metalrenegades/ai/system/CitizenSpawnSystem.java +++ b/src/main/java/org/terasology/metalrenegades/ai/system/CitizenSpawnSystem.java @@ -28,6 +28,8 @@ import org.terasology.entitySystem.systems.RegisterMode; import org.terasology.entitySystem.systems.RegisterSystem; import org.terasology.entitySystem.systems.UpdateSubscriberSystem; +import org.terasology.logic.inventory.InventoryManager; +import org.terasology.logic.inventory.events.GiveItemEvent; import org.terasology.logic.location.LocationComponent; import org.terasology.metalrenegades.ai.component.CitizenComponent; import org.terasology.metalrenegades.ai.component.HomeComponent; @@ -55,6 +57,9 @@ public class CitizenSpawnSystem extends BaseComponentSystem implements UpdateSub @In private PrefabManager prefabManager; + @In + private InventoryManager inventoryManager; + @Override public void update(float delta) { spawnTimer += delta; @@ -105,7 +110,10 @@ private EntityRef spawnCitizen(EntityRef homeEntity) { entityBuilder.saveComponent(citizenLocationComponent); entityBuilder.addComponent(createTradeDialogComponent()); - return entityBuilder.build(); + EntityRef entityRef = entityBuilder.build(); + setupStartInventory(entityRef); + + return entityRef; } /** @@ -125,6 +133,12 @@ private Prefab chooseCitizenPrefab() { return null; } + private void setupStartInventory(EntityRef citizen) { + Prefab railgun = prefabManager.getPrefab("Core:railgunTool"); + EntityRef item = entityManager.create(railgun); + item.send(new GiveItemEvent(citizen)); + } + private DialogComponent createTradeDialogComponent() { DialogComponent component = new DialogComponent(); component.pages = new ArrayList<>(); diff --git a/src/main/java/org/terasology/metalrenegades/economy/ui/TradingScreen.java b/src/main/java/org/terasology/metalrenegades/economy/ui/TradingScreen.java index 32aa8df4..34cc5652 100644 --- a/src/main/java/org/terasology/metalrenegades/economy/ui/TradingScreen.java +++ b/src/main/java/org/terasology/metalrenegades/economy/ui/TradingScreen.java @@ -103,6 +103,7 @@ public String get() { if (tradingUISystem.isAcceptable(player.getSelection(), citizen.getSelection())) { if (tradingUISystem.trade(player.getSelection(), citizen.getSelection())) { message = "Trade completed."; + tradingUISystem.refreshLists(); } else { message = "Trade failed. Try again"; } diff --git a/src/main/java/org/terasology/metalrenegades/economy/ui/TradingUISystem.java b/src/main/java/org/terasology/metalrenegades/economy/ui/TradingUISystem.java index d535a88d..739ef941 100644 --- a/src/main/java/org/terasology/metalrenegades/economy/ui/TradingUISystem.java +++ b/src/main/java/org/terasology/metalrenegades/economy/ui/TradingUISystem.java @@ -52,6 +52,7 @@ public class TradingUISystem extends BaseComponentSystem { private LocalPlayer localPlayer; private TradingScreen tradingScreen; + private EntityRef targetCitizen = EntityRef.NULL; @Override public void initialise() { @@ -70,34 +71,51 @@ public void onToggleInventory(TradeScreenRequestEvent event, EntityRef entity) { @ReceiveEvent public void onTradingScreenAction(TradeScreenRequestEvent event, EntityRef citizen) { - List citizenItems = new ArrayList<>(); - for (int i = 0; i < inventoryManager.getNumSlots(citizen); i++) { - EntityRef entity = inventoryManager.getItemInSlot(citizen, i); + targetCitizen = citizen; + refreshLists(); + } + + public boolean trade(MarketItem player, MarketItem citizen) { + return true; + } + + public boolean isAcceptable(MarketItem player, MarketItem citizen) { + return true; + } + + public void refreshLists() { + refreshCitizenList(); + refreshPlayerList(); + } + + private void refreshCitizenList() { + if (targetCitizen == EntityRef.NULL) { + return; + } + + List items = new ArrayList<>(); + for (int i = 0; i < inventoryManager.getNumSlots(targetCitizen); i++) { + EntityRef entity = inventoryManager.getItemInSlot(targetCitizen, i); if (entity.getParentPrefab() != null) { MarketItem item = MarketItemBuilder.get(entity.getParentPrefab().getName(), 1); - citizenItems.add(item); + items.add(item); } } - List playerItems = new ArrayList<>(); + tradingScreen.setCitizenItems(items); + } + + private void refreshPlayerList() { + List items = new ArrayList<>(); EntityRef player = localPlayer.getCharacterEntity(); for (int i = 0; i < inventoryManager.getNumSlots(player); i++) { EntityRef entity = inventoryManager.getItemInSlot(player, i); if (entity.getParentPrefab() != null) { MarketItem item = MarketItemBuilder.get(entity.getParentPrefab().getName(), 1); - playerItems.add(item); + items.add(item); } } - tradingScreen.setCitizenItems(citizenItems); - tradingScreen.setPlayerItems(playerItems); - } - - public boolean trade(MarketItem player, MarketItem citizen) { - return true; - } - - public boolean isAcceptable(MarketItem player, MarketItem citizen) { - return true; + tradingScreen.setPlayerItems(items); } } From 679474dfa1c8406f5501526bd3fdc0f39246e55c Mon Sep 17 00:00:00 2001 From: Mayant Mukul Date: Fri, 2 Aug 2019 19:27:47 +0530 Subject: [PATCH 4/9] Add inventory management and complete basic trading systems --- .../economy/ui/TradingScreen.java | 3 +- .../economy/ui/TradingUISystem.java | 83 +++++++++++++++++-- 2 files changed, 77 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/terasology/metalrenegades/economy/ui/TradingScreen.java b/src/main/java/org/terasology/metalrenegades/economy/ui/TradingScreen.java index 34cc5652..15891b8a 100644 --- a/src/main/java/org/terasology/metalrenegades/economy/ui/TradingScreen.java +++ b/src/main/java/org/terasology/metalrenegades/economy/ui/TradingScreen.java @@ -17,7 +17,6 @@ import org.terasology.registry.In; import org.terasology.rendering.nui.CoreScreenLayer; -import org.terasology.rendering.nui.NUIManager; import org.terasology.rendering.nui.databinding.ReadOnlyBinding; import org.terasology.rendering.nui.itemRendering.StringTextRenderer; import org.terasology.rendering.nui.widgets.UIButton; @@ -105,7 +104,7 @@ public String get() { message = "Trade completed."; tradingUISystem.refreshLists(); } else { - message = "Trade failed. Try again"; + message = "Trade failed."; } } else { message = "Offer declined."; diff --git a/src/main/java/org/terasology/metalrenegades/economy/ui/TradingUISystem.java b/src/main/java/org/terasology/metalrenegades/economy/ui/TradingUISystem.java index 739ef941..7a8933f2 100644 --- a/src/main/java/org/terasology/metalrenegades/economy/ui/TradingUISystem.java +++ b/src/main/java/org/terasology/metalrenegades/economy/ui/TradingUISystem.java @@ -15,28 +15,31 @@ */ package org.terasology.metalrenegades.economy.ui; -import net.logstash.logback.encoder.org.apache.commons.lang.ArrayUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.terasology.assets.ResourceUrn; +import org.terasology.assets.management.AssetManager; +import org.terasology.entitySystem.entity.EntityManager; import org.terasology.entitySystem.entity.EntityRef; import org.terasology.entitySystem.event.ReceiveEvent; +import org.terasology.entitySystem.prefab.Prefab; import org.terasology.entitySystem.systems.BaseComponentSystem; import org.terasology.entitySystem.systems.RegisterMode; import org.terasology.entitySystem.systems.RegisterSystem; import org.terasology.logic.characters.interactions.InteractionUtil; -import org.terasology.logic.inventory.InventoryComponent; import org.terasology.logic.inventory.InventoryManager; +import org.terasology.logic.inventory.ItemComponent; +import org.terasology.logic.inventory.events.GiveItemEvent; import org.terasology.logic.players.LocalPlayer; -import org.terasology.metalrenegades.economy.events.MarketScreenRequestEvent; import org.terasology.metalrenegades.economy.events.TradeScreenRequestEvent; -import org.terasology.metalrenegades.economy.events.TransactionType; -import org.terasology.protobuf.EntityData; import org.terasology.registry.In; import org.terasology.registry.Share; import org.terasology.rendering.nui.NUIManager; -import org.terasology.segmentedpaths.controllers.SegmentMapping; +import org.terasology.world.block.entity.BlockCommands; import java.util.ArrayList; import java.util.List; +import java.util.Set; @Share(TradingUISystem.class) @RegisterSystem(RegisterMode.CLIENT) @@ -51,9 +54,20 @@ public class TradingUISystem extends BaseComponentSystem { @In private LocalPlayer localPlayer; + @In + private AssetManager assetManager; + + @In + private EntityManager entityManager; + + @In + private BlockCommands blockCommands; + private TradingScreen tradingScreen; private EntityRef targetCitizen = EntityRef.NULL; + private Logger logger = LoggerFactory.getLogger(TradingUISystem.class); + @Override public void initialise() { tradingScreen = (TradingScreen) nuiManager.createScreen("MetalRenegades:tradingScreen"); @@ -75,7 +89,28 @@ public void onTradingScreenAction(TradeScreenRequestEvent event, EntityRef citiz refreshLists(); } - public boolean trade(MarketItem player, MarketItem citizen) { + public boolean trade(MarketItem pItem, MarketItem cItem) { + if (targetCitizen == EntityRef.NULL) { + return false; + } + + try { + // remove item from citizen's inventory + remove(cItem, targetCitizen); + + // add item to player's inventory + add(cItem, localPlayer.getCharacterEntity()); + + // remove item from player's inventory + remove(pItem, localPlayer.getCharacterEntity()); + + // add item to citizen's inventory + add(pItem, targetCitizen); + } catch (Exception e) { + logger.error("Trade failed. Exception: {}", e.getMessage()); + return false; + } + return true; } @@ -118,4 +153,38 @@ private void refreshPlayerList() { tradingScreen.setPlayerItems(items); } + + private void remove(MarketItem item, EntityRef entity) { + EntityRef itemEntity = EntityRef.NULL; + for (int i = 0; i < inventoryManager.getNumSlots(entity); i++) { + EntityRef current = inventoryManager.getItemInSlot(entity, i); + if (current != EntityRef.NULL + && item.name.equalsIgnoreCase(current.getParentPrefab().getName())) { + itemEntity = current; + break; + } + } + inventoryManager.removeItem(entity, EntityRef.NULL, itemEntity, true, 1); + } + + private void add(MarketItem item, EntityRef entity) throws Exception { + Set matches = assetManager.resolve(item.name, Prefab.class); + + if (matches.size() == 1) { + Prefab prefab = assetManager.getAsset(matches.iterator().next(), Prefab.class).orElse(null); + if (prefab != null && prefab.getComponent(ItemComponent.class) != null) { + EntityRef itemEntity = entityManager.create(prefab); + if (itemEntity != EntityRef.NULL) { + itemEntity.send(new GiveItemEvent(entity)); + return; + } + } + } + + String message = blockCommands.giveBlock(entity, item.name, 1, null); + if (message == null) { + String error = "Could not add block " + item.name + " to inventory " + entity; + throw new Exception(error); + } + } } From a1aac655c51c664e668aff30645cdd86ff186be9 Mon Sep 17 00:00:00 2001 From: Mayant Mukul Date: Sun, 4 Aug 2019 19:20:28 +0530 Subject: [PATCH 5/9] Add a close dialogue button to trading UI --- assets/ui/tradingScreen.ui | 19 +++++++++++++++++- .../economy/ui/TradingScreen.java | 20 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/assets/ui/tradingScreen.ui b/assets/ui/tradingScreen.ui index cf627f3e..300bab9c 100644 --- a/assets/ui/tradingScreen.ui +++ b/assets/ui/tradingScreen.ui @@ -83,7 +83,24 @@ "layoutInfo": { "width": 90, "use-content-height": true, - "position-horizontal-center": {}, + "position-horizontal-center": { + "offset": -50 + }, + "position-bottom": { + "offset": 20 + } + } + }, + { + "type": "UIButton", + "id": "cancelButton", + "text": "Cancel", + "layoutInfo": { + "width": 90, + "use-content-height": true, + "position-horizontal-center": { + "offset": 50 + }, "position-bottom": { "offset": 20 } diff --git a/src/main/java/org/terasology/metalrenegades/economy/ui/TradingScreen.java b/src/main/java/org/terasology/metalrenegades/economy/ui/TradingScreen.java index 15891b8a..1f36e34a 100644 --- a/src/main/java/org/terasology/metalrenegades/economy/ui/TradingScreen.java +++ b/src/main/java/org/terasology/metalrenegades/economy/ui/TradingScreen.java @@ -17,8 +17,11 @@ import org.terasology.registry.In; import org.terasology.rendering.nui.CoreScreenLayer; +import org.terasology.rendering.nui.NUIManager; +import org.terasology.rendering.nui.UIWidget; import org.terasology.rendering.nui.databinding.ReadOnlyBinding; import org.terasology.rendering.nui.itemRendering.StringTextRenderer; +import org.terasology.rendering.nui.widgets.ActivateEventListener; import org.terasology.rendering.nui.widgets.UIButton; import org.terasology.rendering.nui.widgets.UILabel; import org.terasology.rendering.nui.widgets.UIList; @@ -34,9 +37,13 @@ public class TradingScreen extends CoreScreenLayer { @In private TradingUISystem tradingUISystem; + @In + private NUIManager nuiManager; + private UIList player; private UIList citizen; private UIButton confirm; + private UIButton cancel; private UILabel result; private List playerItems = new ArrayList<>(); @@ -110,6 +117,11 @@ public String get() { message = "Offer declined."; } }); + + cancel = find("cancelButton", UIButton.class); + cancel.subscribe(widget -> { + nuiManager.closeScreen("MetalRenegades:tradingScreen"); + }); } public void setPlayerItems(List list) { @@ -119,4 +131,12 @@ public void setPlayerItems(List list) { public void setCitizenItems(List list) { this.citizenItems = list; } + + @Override + public void onClosed() { + super.onClosed(); + message = ""; + player.setSelection(null); + citizen.setSelection(null); + } } From a4cda02ce71ac4d58d8a34cd1b7b843419da418e Mon Sep 17 00:00:00 2001 From: Mayant Mukul Date: Sun, 4 Aug 2019 19:46:26 +0530 Subject: [PATCH 6/9] Add cost based trade approval --- assets/ui/tradingScreen.ui | 28 ++++++++++++++++++- .../economy/ui/TradingScreen.java | 27 ++++++++++++++---- .../economy/ui/TradingUISystem.java | 15 ++++++++-- 3 files changed, 62 insertions(+), 8 deletions(-) diff --git a/assets/ui/tradingScreen.ui b/assets/ui/tradingScreen.ui index 300bab9c..750e1c27 100644 --- a/assets/ui/tradingScreen.ui +++ b/assets/ui/tradingScreen.ui @@ -39,6 +39,19 @@ } } }, + { + "type": "UILabel", + "id": "citizenCost", + "text": "Cost", + "layoutInfo": { + "use-content-width": true, + "use-content-height": true, + "position-left": {}, + "position-bottom": { + "offset": 10 + } + } + }, { "type": "UILabel", "text": "Player", @@ -63,6 +76,19 @@ } } }, + { + "type": "UILabel", + "id": "playerCost", + "text": "Cost", + "layoutInfo": { + "use-content-width": true, + "use-content-height": true, + "position-right": {}, + "position-bottom": { + "offset": 10 + } + } + }, { "type": "UILabel", "id": "message", @@ -111,4 +137,4 @@ } ] } -} \ No newline at end of file +} diff --git a/src/main/java/org/terasology/metalrenegades/economy/ui/TradingScreen.java b/src/main/java/org/terasology/metalrenegades/economy/ui/TradingScreen.java index 1f36e34a..6e3630f5 100644 --- a/src/main/java/org/terasology/metalrenegades/economy/ui/TradingScreen.java +++ b/src/main/java/org/terasology/metalrenegades/economy/ui/TradingScreen.java @@ -18,10 +18,8 @@ import org.terasology.registry.In; import org.terasology.rendering.nui.CoreScreenLayer; import org.terasology.rendering.nui.NUIManager; -import org.terasology.rendering.nui.UIWidget; import org.terasology.rendering.nui.databinding.ReadOnlyBinding; import org.terasology.rendering.nui.itemRendering.StringTextRenderer; -import org.terasology.rendering.nui.widgets.ActivateEventListener; import org.terasology.rendering.nui.widgets.UIButton; import org.terasology.rendering.nui.widgets.UILabel; import org.terasology.rendering.nui.widgets.UIList; @@ -45,12 +43,14 @@ public class TradingScreen extends CoreScreenLayer { private UIButton confirm; private UIButton cancel; private UILabel result; + private UILabel pCost; + private UILabel cCost; private List playerItems = new ArrayList<>(); private List citizenItems = new ArrayList<>(); - private MarketItem pSelected; - private MarketItem cSeleted; + private MarketItem pSelected = MarketItemBuilder.getEmpty(); + private MarketItem cSelected = MarketItemBuilder.getEmpty(); private String message; @@ -88,7 +88,7 @@ public String getString(MarketItem value) { return value.name; } }); - citizen.subscribeSelection(((widget, item) -> cSeleted = item)); + citizen.subscribeSelection(((widget, item) -> cSelected = item)); citizen.bindList(new ReadOnlyBinding>() { @Override public List get() { @@ -122,6 +122,23 @@ public String get() { cancel.subscribe(widget -> { nuiManager.closeScreen("MetalRenegades:tradingScreen"); }); + + + pCost = find("playerCost", UILabel.class); + pCost.bindText(new ReadOnlyBinding() { + @Override + public String get() { + return "Cost: " + pSelected.cost; + } + }); + + cCost = find("citizenCost", UILabel.class); + cCost.bindText(new ReadOnlyBinding() { + @Override + public String get() { + return "Cost: " + cSelected.cost; + } + }); } public void setPlayerItems(List list) { diff --git a/src/main/java/org/terasology/metalrenegades/economy/ui/TradingUISystem.java b/src/main/java/org/terasology/metalrenegades/economy/ui/TradingUISystem.java index 7a8933f2..0b100235 100644 --- a/src/main/java/org/terasology/metalrenegades/economy/ui/TradingUISystem.java +++ b/src/main/java/org/terasology/metalrenegades/economy/ui/TradingUISystem.java @@ -31,6 +31,7 @@ import org.terasology.logic.inventory.ItemComponent; import org.terasology.logic.inventory.events.GiveItemEvent; import org.terasology.logic.players.LocalPlayer; +import org.terasology.math.TeraMath; import org.terasology.metalrenegades.economy.events.TradeScreenRequestEvent; import org.terasology.registry.In; import org.terasology.registry.Share; @@ -39,6 +40,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Random; import java.util.Set; @Share(TradingUISystem.class) @@ -63,6 +65,9 @@ public class TradingUISystem extends BaseComponentSystem { @In private BlockCommands blockCommands; + private final int PROBABILITY = 50; + private final int MARGIN_PERCENTAGE = 20; + private TradingScreen tradingScreen; private EntityRef targetCitizen = EntityRef.NULL; @@ -114,8 +119,9 @@ public boolean trade(MarketItem pItem, MarketItem cItem) { return true; } - public boolean isAcceptable(MarketItem player, MarketItem citizen) { - return true; + public boolean isAcceptable(MarketItem pItem, MarketItem cItem) { + Random rnd = new Random(); + return isAboutEqual(pItem.cost, cItem.cost) && (rnd.nextInt(100) < PROBABILITY); } public void refreshLists() { @@ -123,6 +129,11 @@ public void refreshLists() { refreshPlayerList(); } + private boolean isAboutEqual(int pCost, int cCost) { + int delta = TeraMath.fastAbs(pCost - cCost); + return ((float)(delta / cCost) * 100) < MARGIN_PERCENTAGE; + } + private void refreshCitizenList() { if (targetCitizen == EntityRef.NULL) { return; From d2a440a054323dc5fd6261de14e372cbfeb407cd Mon Sep 17 00:00:00 2001 From: Mayant Mukul Date: Sun, 4 Aug 2019 20:10:21 +0530 Subject: [PATCH 7/9] Add non-tradable market citizen --- .../{traderGooey.mat => marketGooey.mat} | 2 +- assets/prefabs/characters/badCitizen.prefab | 3 +- assets/prefabs/characters/goodCitizen.prefab | 3 +- assets/prefabs/characters/gooeyCitizen.prefab | 3 +- .../prefabs/characters/marketCitizen.prefab | 47 ++++++++++++++++++ assets/prefabs/characters/traderGooey.prefab | 46 ----------------- .../{traderGooey.png => marketGooey.png} | Bin .../ai/system/CitizenSpawnSystem.java | 11 +++- .../economy/MarketCitizenComponent.java | 21 ++++++++ .../economy/TraderComponent.java | 21 ++++++++ ...tem.java => MarketCitizenSpawnSystem.java} | 6 +-- .../economy/ui/MarketScreen.java | 15 ++++-- .../economy/ui/TradingScreen.java | 6 ++- 13 files changed, 124 insertions(+), 60 deletions(-) rename assets/materials/characters/{traderGooey.mat => marketGooey.mat} (73%) create mode 100644 assets/prefabs/characters/marketCitizen.prefab delete mode 100644 assets/prefabs/characters/traderGooey.prefab rename assets/textures/characters/{traderGooey.png => marketGooey.png} (100%) create mode 100644 src/main/java/org/terasology/metalrenegades/economy/MarketCitizenComponent.java create mode 100644 src/main/java/org/terasology/metalrenegades/economy/TraderComponent.java rename src/main/java/org/terasology/metalrenegades/economy/systems/{TraderSpawnSystem.java => MarketCitizenSpawnSystem.java} (96%) diff --git a/assets/materials/characters/traderGooey.mat b/assets/materials/characters/marketGooey.mat similarity index 73% rename from assets/materials/characters/traderGooey.mat rename to assets/materials/characters/marketGooey.mat index d8fc4838..41014de4 100644 --- a/assets/materials/characters/traderGooey.mat +++ b/assets/materials/characters/marketGooey.mat @@ -1,7 +1,7 @@ { "shader" : "engine:genericMeshMaterial", "params" : { - "diffuse" : "MetalRenegades:traderGooey", + "diffuse" : "MetalRenegades:marketGooey", "colorOffset" : [1.0, 1.0, 1.0], "textured" : true } diff --git a/assets/prefabs/characters/badCitizen.prefab b/assets/prefabs/characters/badCitizen.prefab index efee67c8..0df15ab4 100644 --- a/assets/prefabs/characters/badCitizen.prefab +++ b/assets/prefabs/characters/badCitizen.prefab @@ -42,5 +42,6 @@ }, "Behavior": { "tree": "MetalRenegades:citizen" - } + }, + "Trader": {} } diff --git a/assets/prefabs/characters/goodCitizen.prefab b/assets/prefabs/characters/goodCitizen.prefab index fc44b1de..4bf33810 100644 --- a/assets/prefabs/characters/goodCitizen.prefab +++ b/assets/prefabs/characters/goodCitizen.prefab @@ -42,5 +42,6 @@ }, "Behavior": { "tree": "MetalRenegades:citizen" - } + }, + "Trader": {} } diff --git a/assets/prefabs/characters/gooeyCitizen.prefab b/assets/prefabs/characters/gooeyCitizen.prefab index 9b0ddea4..0f757dc6 100644 --- a/assets/prefabs/characters/gooeyCitizen.prefab +++ b/assets/prefabs/characters/gooeyCitizen.prefab @@ -42,5 +42,6 @@ }, "Behavior": { "tree": "MetalRenegades:citizen" - } + }, + "Trader": {} } diff --git a/assets/prefabs/characters/marketCitizen.prefab b/assets/prefabs/characters/marketCitizen.prefab new file mode 100644 index 00000000..960b303c --- /dev/null +++ b/assets/prefabs/characters/marketCitizen.prefab @@ -0,0 +1,47 @@ +{ + "parent": "baseCitizen", + "displayName": { + "name": "shopkeeper" + }, + "skeletalmesh": { + "mesh": "MetalRenegades:gooey", + "heightOffset": -2.0, + "material": "MetalRenegades:marketGooey", + "animationPool": [ + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyIdleBreathing", + "gooeyLookRightLeft", + "gooeyLookRightLeft", + "gooeyLookRightUp" + ], + "loop": true, + "scale": [ + 0.25, + 0.25, + 0.25 + ] + }, + "Behavior" : { + "tree" : "Behaviors:stray" + }, + "MarketCitizen": {} +} diff --git a/assets/prefabs/characters/traderGooey.prefab b/assets/prefabs/characters/traderGooey.prefab deleted file mode 100644 index 3f7e72ec..00000000 --- a/assets/prefabs/characters/traderGooey.prefab +++ /dev/null @@ -1,46 +0,0 @@ -{ - "displayName": { - "name": "trader" - }, - "persisted": true, - "skeletalmesh" : { - "mesh" : "MetalRenegades:gooey", - "heightOffset" : -0.8, - "material" : "MetalRenegades:traderGooey", - "animation" : "gooeyIdleBreathing", - "loop" : true, - "scale": [ - 0.25, - 0.25, - 0.25 - ] - }, - "Behavior" : { - "tree" : "Behaviors:stray" - }, - "Stand" :{ - "animationPool": ["gooeyIdleBreathing"] - }, - "Walk" :{ - "animationPool": ["gooeyIdleBreathing"] - }, - "location": {}, - "Character": {}, - "AliveCharacter": {}, - "Network": {}, - "MinionMove": {}, - "BoxShape": { - "extents": [ - 1.0, - 1.0, - 1.0 - ] - }, - "Trigger": { - "detectGroups": [ - "engine:debris", - "engine:sensor" - ] - }, - "Resident": {} -} diff --git a/assets/textures/characters/traderGooey.png b/assets/textures/characters/marketGooey.png similarity index 100% rename from assets/textures/characters/traderGooey.png rename to assets/textures/characters/marketGooey.png diff --git a/src/main/java/org/terasology/metalrenegades/ai/system/CitizenSpawnSystem.java b/src/main/java/org/terasology/metalrenegades/ai/system/CitizenSpawnSystem.java index 83bd6575..98d7c9b3 100644 --- a/src/main/java/org/terasology/metalrenegades/ai/system/CitizenSpawnSystem.java +++ b/src/main/java/org/terasology/metalrenegades/ai/system/CitizenSpawnSystem.java @@ -34,11 +34,14 @@ import org.terasology.metalrenegades.ai.component.CitizenComponent; import org.terasology.metalrenegades.ai.component.HomeComponent; import org.terasology.metalrenegades.ai.component.PotentialHomeComponent; +import org.terasology.metalrenegades.economy.MarketCitizenComponent; +import org.terasology.metalrenegades.economy.TraderComponent; import org.terasology.metalrenegades.economy.actions.ShowTradingScreenAction; import org.terasology.registry.In; import java.util.ArrayList; import java.util.Collection; +import java.util.function.Predicate; /** * Spawns new citizens inside of available buildings with {@link PotentialHomeComponent}. @@ -108,10 +111,13 @@ private EntityRef spawnCitizen(EntityRef homeEntity) { entityBuilder.addComponent(homeComponent); entityBuilder.saveComponent(citizenLocationComponent); - entityBuilder.addComponent(createTradeDialogComponent()); EntityRef entityRef = entityBuilder.build(); - setupStartInventory(entityRef); + + if (entityRef.hasComponent(TraderComponent.class)) { + entityRef.addComponent(createTradeDialogComponent()); + setupStartInventory(entityRef); + } return entityRef; } @@ -123,6 +129,7 @@ private EntityRef spawnCitizen(EntityRef homeEntity) { */ private Prefab chooseCitizenPrefab() { Collection citizenList = prefabManager.listPrefabs(CitizenComponent.class); + citizenList.removeIf(prefab -> prefab.hasComponent(MarketCitizenComponent.class)); int i = (int) (Math.random() * citizenList.size()); for (Prefab prefab: citizenList) { diff --git a/src/main/java/org/terasology/metalrenegades/economy/MarketCitizenComponent.java b/src/main/java/org/terasology/metalrenegades/economy/MarketCitizenComponent.java new file mode 100644 index 00000000..2be8bbd7 --- /dev/null +++ b/src/main/java/org/terasology/metalrenegades/economy/MarketCitizenComponent.java @@ -0,0 +1,21 @@ +/* + * Copyright 2019 MovingBlocks + * + * 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.terasology.metalrenegades.economy; + +import org.terasology.entitySystem.Component; + +public class MarketCitizenComponent implements Component { +} diff --git a/src/main/java/org/terasology/metalrenegades/economy/TraderComponent.java b/src/main/java/org/terasology/metalrenegades/economy/TraderComponent.java new file mode 100644 index 00000000..7919007c --- /dev/null +++ b/src/main/java/org/terasology/metalrenegades/economy/TraderComponent.java @@ -0,0 +1,21 @@ +/* + * Copyright 2019 MovingBlocks + * + * 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.terasology.metalrenegades.economy; + +import org.terasology.entitySystem.Component; + +public class TraderComponent implements Component { +} diff --git a/src/main/java/org/terasology/metalrenegades/economy/systems/TraderSpawnSystem.java b/src/main/java/org/terasology/metalrenegades/economy/systems/MarketCitizenSpawnSystem.java similarity index 96% rename from src/main/java/org/terasology/metalrenegades/economy/systems/TraderSpawnSystem.java rename to src/main/java/org/terasology/metalrenegades/economy/systems/MarketCitizenSpawnSystem.java index 69621594..6bef298a 100644 --- a/src/main/java/org/terasology/metalrenegades/economy/systems/TraderSpawnSystem.java +++ b/src/main/java/org/terasology/metalrenegades/economy/systems/MarketCitizenSpawnSystem.java @@ -47,12 +47,12 @@ * Spawns a trader in all markets */ @RegisterSystem -public class TraderSpawnSystem extends BaseComponentSystem { +public class MarketCitizenSpawnSystem extends BaseComponentSystem { @In private EntityManager entityManager; - private Logger logger = LoggerFactory.getLogger(TraderSpawnSystem.class); + private Logger logger = LoggerFactory.getLogger(MarketCitizenSpawnSystem.class); @ReceiveEvent(components = GenericBuildingComponent.class) public void onMarketPlaceSpawn(BuildingEntitySpawnedEvent event, EntityRef entityRef) { @@ -60,7 +60,7 @@ public void onMarketPlaceSpawn(BuildingEntitySpawnedEvent event, EntityRef entit if (genericBuildingComponent.name.equals("marketplace")) { DynParcel dynParcel = entityRef.getComponent(DynParcelRefComponent.class).dynParcel; - Optional traderGooeyOptional = Assets.getPrefab("MetalRenegades:goodCitizen"); + Optional traderGooeyOptional = Assets.getPrefab("MetalRenegades:marketCitizen"); if (traderGooeyOptional.isPresent()) { Rect2i rect2i = dynParcel.shape; Vector3f spawnPosition = new Vector3f(rect2i.minX() + rect2i.sizeX() / 2, dynParcel.getHeight() + 1, rect2i.minY() + rect2i.sizeY() / 2); diff --git a/src/main/java/org/terasology/metalrenegades/economy/ui/MarketScreen.java b/src/main/java/org/terasology/metalrenegades/economy/ui/MarketScreen.java index fcbcee62..f19c7a1d 100644 --- a/src/main/java/org/terasology/metalrenegades/economy/ui/MarketScreen.java +++ b/src/main/java/org/terasology/metalrenegades/economy/ui/MarketScreen.java @@ -22,6 +22,7 @@ import org.terasology.metalrenegades.economy.systems.MarketManagementSystem; import org.terasology.registry.In; import org.terasology.rendering.nui.CoreScreenLayer; +import org.terasology.rendering.nui.NUIManager; import org.terasology.rendering.nui.databinding.ReadOnlyBinding; import org.terasology.rendering.nui.itemRendering.StringTextRenderer; import org.terasology.rendering.nui.widgets.UIButton; @@ -43,6 +44,9 @@ public class MarketScreen extends CoreScreenLayer { @In private MarketManagementSystem marketManagementSystem; + @In + private NUIManager nuiManager; + private UIList items; private UILabel name; @@ -142,9 +146,7 @@ public List get() { // Initialise back button back = find("back", UIButton.class); back.subscribe(widget -> { - // TODO: Close the window when back is pressed - selected = MarketItemBuilder.getEmpty(); - logger.info("Closing the UI..."); + nuiManager.closeScreen("MetalRenegades:marketScreen"); }); } @@ -153,6 +155,13 @@ public boolean isModal() { return true; } + @Override + public void onClosed() { + super.onClosed(); + selected = MarketItemBuilder.getEmpty(); + items.setSelection(null); + } + public void setItemList(List resources) { list = resources; } diff --git a/src/main/java/org/terasology/metalrenegades/economy/ui/TradingScreen.java b/src/main/java/org/terasology/metalrenegades/economy/ui/TradingScreen.java index 6e3630f5..0b6c2a10 100644 --- a/src/main/java/org/terasology/metalrenegades/economy/ui/TradingScreen.java +++ b/src/main/java/org/terasology/metalrenegades/economy/ui/TradingScreen.java @@ -128,7 +128,8 @@ public String get() { pCost.bindText(new ReadOnlyBinding() { @Override public String get() { - return "Cost: " + pSelected.cost; + int cost = (pSelected != null) ? (pSelected.cost) : 0; + return "Cost: " + cost; } }); @@ -136,7 +137,8 @@ public String get() { cCost.bindText(new ReadOnlyBinding() { @Override public String get() { - return "Cost: " + cSelected.cost; + int cost = (cSelected != null) ? (cSelected.cost) : 0; + return "Cost: " + cost; } }); } From b92888e695a639e4a4a1350cc4c8b6a575027c33 Mon Sep 17 00:00:00 2001 From: Mayant Mukul Date: Sun, 4 Aug 2019 20:29:15 +0530 Subject: [PATCH 8/9] Add javadocs and clean up code --- .../ai/system/CitizenSpawnSystem.java | 3 +- .../economy/MarketCitizenComponent.java | 3 + .../economy/TraderComponent.java | 3 + .../actions/ShowTradingScreenAction.java | 3 + .../events/TradeScreenRequestEvent.java | 3 + .../systems/MarketCitizenSpawnSystem.java | 2 +- .../economy/ui/TradingScreen.java | 67 ++++++++++--------- .../economy/ui/TradingUISystem.java | 41 ++++++++++++ 8 files changed, 92 insertions(+), 33 deletions(-) diff --git a/src/main/java/org/terasology/metalrenegades/ai/system/CitizenSpawnSystem.java b/src/main/java/org/terasology/metalrenegades/ai/system/CitizenSpawnSystem.java index 98d7c9b3..4ee09bb7 100644 --- a/src/main/java/org/terasology/metalrenegades/ai/system/CitizenSpawnSystem.java +++ b/src/main/java/org/terasology/metalrenegades/ai/system/CitizenSpawnSystem.java @@ -41,7 +41,6 @@ import java.util.ArrayList; import java.util.Collection; -import java.util.function.Predicate; /** * Spawns new citizens inside of available buildings with {@link PotentialHomeComponent}. @@ -132,7 +131,7 @@ private Prefab chooseCitizenPrefab() { citizenList.removeIf(prefab -> prefab.hasComponent(MarketCitizenComponent.class)); int i = (int) (Math.random() * citizenList.size()); - for (Prefab prefab: citizenList) { + for (Prefab prefab : citizenList) { if (i-- <= 0) { return prefab; } diff --git a/src/main/java/org/terasology/metalrenegades/economy/MarketCitizenComponent.java b/src/main/java/org/terasology/metalrenegades/economy/MarketCitizenComponent.java index 2be8bbd7..c9a24577 100644 --- a/src/main/java/org/terasology/metalrenegades/economy/MarketCitizenComponent.java +++ b/src/main/java/org/terasology/metalrenegades/economy/MarketCitizenComponent.java @@ -17,5 +17,8 @@ import org.terasology.entitySystem.Component; +/** + * Marks a citizen which will only spawn in markets + */ public class MarketCitizenComponent implements Component { } diff --git a/src/main/java/org/terasology/metalrenegades/economy/TraderComponent.java b/src/main/java/org/terasology/metalrenegades/economy/TraderComponent.java index 7919007c..54f2ac41 100644 --- a/src/main/java/org/terasology/metalrenegades/economy/TraderComponent.java +++ b/src/main/java/org/terasology/metalrenegades/economy/TraderComponent.java @@ -17,5 +17,8 @@ import org.terasology.entitySystem.Component; +/** + * Marks a citizen with which the player can trade + */ public class TraderComponent implements Component { } diff --git a/src/main/java/org/terasology/metalrenegades/economy/actions/ShowTradingScreenAction.java b/src/main/java/org/terasology/metalrenegades/economy/actions/ShowTradingScreenAction.java index b1322290..6a3aeb9c 100644 --- a/src/main/java/org/terasology/metalrenegades/economy/actions/ShowTradingScreenAction.java +++ b/src/main/java/org/terasology/metalrenegades/economy/actions/ShowTradingScreenAction.java @@ -19,6 +19,9 @@ import org.terasology.entitySystem.entity.EntityRef; import org.terasology.metalrenegades.economy.events.TradeScreenRequestEvent; +/** + * Calls an event which would bring up the trading UI + */ public class ShowTradingScreenAction implements PlayerAction { public ShowTradingScreenAction() { diff --git a/src/main/java/org/terasology/metalrenegades/economy/events/TradeScreenRequestEvent.java b/src/main/java/org/terasology/metalrenegades/economy/events/TradeScreenRequestEvent.java index 04382783..0efd5fab 100644 --- a/src/main/java/org/terasology/metalrenegades/economy/events/TradeScreenRequestEvent.java +++ b/src/main/java/org/terasology/metalrenegades/economy/events/TradeScreenRequestEvent.java @@ -17,6 +17,9 @@ import org.terasology.entitySystem.event.Event; +/** + * Event fired when the trading UI needs to be brought up + */ public class TradeScreenRequestEvent implements Event { public TradeScreenRequestEvent() { } diff --git a/src/main/java/org/terasology/metalrenegades/economy/systems/MarketCitizenSpawnSystem.java b/src/main/java/org/terasology/metalrenegades/economy/systems/MarketCitizenSpawnSystem.java index 6bef298a..995e2c2f 100644 --- a/src/main/java/org/terasology/metalrenegades/economy/systems/MarketCitizenSpawnSystem.java +++ b/src/main/java/org/terasology/metalrenegades/economy/systems/MarketCitizenSpawnSystem.java @@ -44,7 +44,7 @@ import java.util.Optional; /** - * Spawns a trader in all markets + * Spawns a market citizen in all markets */ @RegisterSystem public class MarketCitizenSpawnSystem extends BaseComponentSystem { diff --git a/src/main/java/org/terasology/metalrenegades/economy/ui/TradingScreen.java b/src/main/java/org/terasology/metalrenegades/economy/ui/TradingScreen.java index 0b6c2a10..3afca490 100644 --- a/src/main/java/org/terasology/metalrenegades/economy/ui/TradingScreen.java +++ b/src/main/java/org/terasology/metalrenegades/economy/ui/TradingScreen.java @@ -38,16 +38,16 @@ public class TradingScreen extends CoreScreenLayer { @In private NUIManager nuiManager; - private UIList player; - private UIList citizen; + private UIList pList; + private UIList cList; private UIButton confirm; private UIButton cancel; private UILabel result; private UILabel pCost; private UILabel cCost; - private List playerItems = new ArrayList<>(); - private List citizenItems = new ArrayList<>(); + private List pItems = new ArrayList<>(); + private List cItems = new ArrayList<>(); private MarketItem pSelected = MarketItemBuilder.getEmpty(); private MarketItem cSelected = MarketItemBuilder.getEmpty(); @@ -56,46 +56,42 @@ public class TradingScreen extends CoreScreenLayer { @Override public void initialise() { - List items = new ArrayList<>(); - for (int i = 0; i < 6; i++) { - items.add(MarketItemBuilder.getDefault()); - } - playerItems = items; - citizenItems = items; - - player = find("playerList", UIList.class); - player.setList(new ArrayList<>()); - player.setItemRenderer(new StringTextRenderer() { + // Initialize player inventory list + pList = find("playerList", UIList.class); + pList.setList(new ArrayList<>()); + pList.setItemRenderer(new StringTextRenderer() { @Override public String getString(MarketItem value) { return value.name; } }); - player.subscribeSelection(((widget, item) -> pSelected = item)); - player.bindList(new ReadOnlyBinding>() { + pList.subscribeSelection(((widget, item) -> pSelected = item)); + pList.bindList(new ReadOnlyBinding>() { @Override public List get() { - return playerItems; + return pItems; } }); - citizen = find("citizenList", UIList.class); - citizen.setList(new ArrayList<>()); - citizen.setItemRenderer(new StringTextRenderer() { + // Initialize citizen inventory list + cList = find("citizenList", UIList.class); + cList.setList(new ArrayList<>()); + cList.setItemRenderer(new StringTextRenderer() { @Override public String getString(MarketItem value) { return value.name; } }); - citizen.subscribeSelection(((widget, item) -> cSelected = item)); - citizen.bindList(new ReadOnlyBinding>() { + cList.subscribeSelection(((widget, item) -> cSelected = item)); + cList.bindList(new ReadOnlyBinding>() { @Override public List get() { - return citizenItems; + return cItems; } }); + // Initialize result message label result = find("message", UILabel.class); result.bindText(new ReadOnlyBinding() { @Override @@ -104,10 +100,11 @@ public String get() { } }); + // Initialize confirm trade button confirm = find("tradeButton", UIButton.class); confirm.subscribe(widget -> { - if (tradingUISystem.isAcceptable(player.getSelection(), citizen.getSelection())) { - if (tradingUISystem.trade(player.getSelection(), citizen.getSelection())) { + if (tradingUISystem.isAcceptable(pList.getSelection(), cList.getSelection())) { + if (tradingUISystem.trade(pList.getSelection(), cList.getSelection())) { message = "Trade completed."; tradingUISystem.refreshLists(); } else { @@ -118,12 +115,13 @@ public String get() { } }); + // Initialize close dialogue button cancel = find("cancelButton", UIButton.class); cancel.subscribe(widget -> { nuiManager.closeScreen("MetalRenegades:tradingScreen"); }); - + // Initialize player item cost label pCost = find("playerCost", UILabel.class); pCost.bindText(new ReadOnlyBinding() { @Override @@ -133,6 +131,7 @@ public String get() { } }); + // Initialize citizen item cost label cCost = find("citizenCost", UILabel.class); cCost.bindText(new ReadOnlyBinding() { @Override @@ -143,19 +142,27 @@ public String get() { }); } + /** + * Set the player's inventory items + * @param list: Content for the player's UIList + */ public void setPlayerItems(List list) { - playerItems = list; + pItems = list; } + /** + * Set the citizen's inventory items + * @param list: Content for the citizen's UIList + */ public void setCitizenItems(List list) { - this.citizenItems = list; + this.cItems = list; } @Override public void onClosed() { super.onClosed(); message = ""; - player.setSelection(null); - citizen.setSelection(null); + pList.setSelection(null); + cList.setSelection(null); } } diff --git a/src/main/java/org/terasology/metalrenegades/economy/ui/TradingUISystem.java b/src/main/java/org/terasology/metalrenegades/economy/ui/TradingUISystem.java index 0b100235..f380ee60 100644 --- a/src/main/java/org/terasology/metalrenegades/economy/ui/TradingUISystem.java +++ b/src/main/java/org/terasology/metalrenegades/economy/ui/TradingUISystem.java @@ -43,6 +43,9 @@ import java.util.Random; import java.util.Set; +/** + * System which handles the data presented to the TradingScreen + */ @Share(TradingUISystem.class) @RegisterSystem(RegisterMode.CLIENT) public class TradingUISystem extends BaseComponentSystem { @@ -94,6 +97,12 @@ public void onTradingScreenAction(TradeScreenRequestEvent event, EntityRef citiz refreshLists(); } + /** + * Start the trading process for the specified items + * @param pItem: MarketItem for the player's item + * @param cItem: MarketItem for the citizen's item + * @return boolean indicating successful or failed trade attempt + */ public boolean trade(MarketItem pItem, MarketItem cItem) { if (targetCitizen == EntityRef.NULL) { return false; @@ -119,21 +128,39 @@ public boolean trade(MarketItem pItem, MarketItem cItem) { return true; } + /** + * Calculates if the trade will be acceptable to the citizen based on market costs + * @param pItem: MarketItem for the player's item + * @param cItem: MarketItem for the citizen's item + * @return boolean indicating if the trade is acceptable or not + */ public boolean isAcceptable(MarketItem pItem, MarketItem cItem) { Random rnd = new Random(); return isAboutEqual(pItem.cost, cItem.cost) && (rnd.nextInt(100) < PROBABILITY); } + /** + * Calls appropriate functions to update player and citizen's inventories in the UI + */ public void refreshLists() { refreshCitizenList(); refreshPlayerList(); } + /** + * Determines if two costs are about equal, depending on MARGIN_PERCENTAGE + * @param pCost: Integer cost of the player's item + * @param cCost: Integer cost of the citizen's item + * @return boolean indicating if the two costs are about equal + */ private boolean isAboutEqual(int pCost, int cCost) { int delta = TeraMath.fastAbs(pCost - cCost); return ((float)(delta / cCost) * 100) < MARGIN_PERCENTAGE; } + /** + * Update the content in the citizen's inventory UIList + */ private void refreshCitizenList() { if (targetCitizen == EntityRef.NULL) { return; @@ -151,6 +178,9 @@ private void refreshCitizenList() { tradingScreen.setCitizenItems(items); } + /** + * Update the content in the player's inventory UIList + */ private void refreshPlayerList() { List items = new ArrayList<>(); EntityRef player = localPlayer.getCharacterEntity(); @@ -165,6 +195,11 @@ private void refreshPlayerList() { tradingScreen.setPlayerItems(items); } + /** + * Remove an item from the specified entity's inventory + * @param item: MarketItem to be removed + * @param entity: Entity to be removed from + */ private void remove(MarketItem item, EntityRef entity) { EntityRef itemEntity = EntityRef.NULL; for (int i = 0; i < inventoryManager.getNumSlots(entity); i++) { @@ -178,6 +213,12 @@ private void remove(MarketItem item, EntityRef entity) { inventoryManager.removeItem(entity, EntityRef.NULL, itemEntity, true, 1); } + /** + * Add an item to the specified entity's inventory + * @param item: MarketItem to be added + * @param entity: Entity to be added to + * @throws Exception if addition of block to inventory fails + */ private void add(MarketItem item, EntityRef entity) throws Exception { Set matches = assetManager.resolve(item.name, Prefab.class); From 2e962955c1c4e676f9e82a8d75ff41a3e5ab3a7b Mon Sep 17 00:00:00 2001 From: Mayant Mukul Date: Fri, 9 Aug 2019 16:31:56 +0530 Subject: [PATCH 9/9] Add javadocs to important fields --- .../metalrenegades/economy/ui/TradingScreen.java | 12 ++++++++++++ .../metalrenegades/economy/ui/TradingUISystem.java | 14 ++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/terasology/metalrenegades/economy/ui/TradingScreen.java b/src/main/java/org/terasology/metalrenegades/economy/ui/TradingScreen.java index 3afca490..dca71c7a 100644 --- a/src/main/java/org/terasology/metalrenegades/economy/ui/TradingScreen.java +++ b/src/main/java/org/terasology/metalrenegades/economy/ui/TradingScreen.java @@ -38,6 +38,9 @@ public class TradingScreen extends CoreScreenLayer { @In private NUIManager nuiManager; + /** + * UI Elements + */ private UIList pList; private UIList cList; private UIButton confirm; @@ -46,12 +49,21 @@ public class TradingScreen extends CoreScreenLayer { private UILabel pCost; private UILabel cCost; + /** + * Information for UILists + */ private List pItems = new ArrayList<>(); private List cItems = new ArrayList<>(); + /** + * Selected items + */ private MarketItem pSelected = MarketItemBuilder.getEmpty(); private MarketItem cSelected = MarketItemBuilder.getEmpty(); + /** + * Trade result message + */ private String message; @Override diff --git a/src/main/java/org/terasology/metalrenegades/economy/ui/TradingUISystem.java b/src/main/java/org/terasology/metalrenegades/economy/ui/TradingUISystem.java index f380ee60..8bd110ec 100644 --- a/src/main/java/org/terasology/metalrenegades/economy/ui/TradingUISystem.java +++ b/src/main/java/org/terasology/metalrenegades/economy/ui/TradingUISystem.java @@ -68,12 +68,22 @@ public class TradingUISystem extends BaseComponentSystem { @In private BlockCommands blockCommands; - private final int PROBABILITY = 50; + /** + * Maximum percentage difference between two values for them to be considered about equal + */ private final int MARGIN_PERCENTAGE = 20; - private TradingScreen tradingScreen; + /** + * Probability that a trade will be accepted, provided the costs are about equal + */ + private final int PROBABILITY = 50; + + /** + * Citizen entity that the player is trading with + */ private EntityRef targetCitizen = EntityRef.NULL; + private TradingScreen tradingScreen; private Logger logger = LoggerFactory.getLogger(TradingUISystem.class); @Override