From 582e7470cb2810c90cc2f65648f07c262ff33f7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilie=20J=C3=B8rgensen?= Date: Sun, 25 Feb 2018 02:36:58 +0100 Subject: [PATCH 1/8] Added item stacking and splitting --- .../scripts/radial/object/StackRadial.groovy | 145 ++++++++++++++++++ .../objects/tangible/TangibleObject.java | 30 ++++ 2 files changed, 175 insertions(+) create mode 100644 src/main/groovy/com/projectswg/holocore/scripts/radial/object/StackRadial.groovy diff --git a/src/main/groovy/com/projectswg/holocore/scripts/radial/object/StackRadial.groovy b/src/main/groovy/com/projectswg/holocore/scripts/radial/object/StackRadial.groovy new file mode 100644 index 000000000..5b42d33d4 --- /dev/null +++ b/src/main/groovy/com/projectswg/holocore/scripts/radial/object/StackRadial.groovy @@ -0,0 +1,145 @@ +/*********************************************************************************** + * Copyright (c) 2018 /// Project SWG /// www.projectswg.com * + * * + * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on * + * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * + * Our goal is to create an emulator which will provide a server for players to * + * continue playing a game similar to the one they used to play. We are basing * + * it on the final publish of the game prior to end-game events. * + * * + * This file is part of Holocore. * + * * + * --------------------------------------------------------------------------------* + * * + * Holocore is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Affero General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * Holocore is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Affero General Public License for more details. * + * * + * You should have received a copy of the GNU Affero General Public License * + * along with Holocore. If not, see . * + ***********************************************************************************/ + +package com.projectswg.holocore.scripts.radial.object + +import com.projectswg.common.data.radial.RadialItem +import com.projectswg.common.data.radial.RadialOption +import com.projectswg.common.debug.Log +import com.projectswg.holocore.intents.chat.SystemMessageIntent +import com.projectswg.holocore.intents.combat.loot.LootRequestIntent +import com.projectswg.holocore.intents.object.DestroyObjectIntent +import com.projectswg.holocore.intents.object.ObjectCreatedIntent +import com.projectswg.holocore.resources.objects.SWGObject +import com.projectswg.holocore.resources.objects.tangible.TangibleObject +import com.projectswg.holocore.resources.player.Player +import com.projectswg.holocore.resources.sui.SuiInputBox +import com.projectswg.holocore.scripts.radial.RadialHandlerInterface +import com.projectswg.holocore.services.objects.ObjectCreator + +class StackRadial extends SWGObjectRadial { + + def getOptions(List options, Player player, SWGObject target) { + // Verify that target is a tangible + if (!(target instanceof TangibleObject)) { + Log.w("StackRadial attached to non-TangibleObject") + return + } + + // Check if the target is not in a container then show no radial options + SWGObject container = target.getParent() + + if (container == null) { + return + } + + options.add(new RadialOption(RadialItem.SERVER_MENU49)) // Split + options.add(new RadialOption(RadialItem.SERVER_MENU50)) // Stack + } + + def split(Player player, SWGObject target) { + // Create input-window + def window = new SuiInputBox("@autostack:unstack", "@autostack:stacksize") + + // Handle button selection + window.addOkButtonCallback("split", {event, parameters -> + String input = SuiInputBox.getEnteredText(parameters) + TangibleObject originalStack = (TangibleObject) target + + try { + int newStackSize = Integer.parseInt(input) + int counter = originalStack.getCounter() + int oldStackSize = counter - newStackSize + + if (oldStackSize < 1) { + SystemMessageIntent.broadcastPersonal(player, "@autostack:zero_size") + return + } else if (oldStackSize >= counter) { + SystemMessageIntent.broadcastPersonal(player, "@autostack:too_big") + return + } + + // Check inventory volume + SWGObject container = target.getParent() + + if (container.getVolume() + 1 > container.getMaxContainerSize()) { + SystemMessageIntent.broadcastPersonal(player, "@autostack:full_container") + return + } + + // Create new identical object + String template = originalStack.getTemplate() + TangibleObject newStack = ObjectCreator.createObjectFromTemplate(template, TangibleObject.class) + ObjectCreatedIntent.broadcast(newStack) + + // Adjust stack sizes + originalStack.setCounter(oldStackSize) + newStack.setCounter(newStackSize) + + // Add new stack to container + container.addObject(newStack) + } catch (NumberFormatException e) { + SystemMessageIntent.broadcastPersonal(player, "@autostack:number_format_wrong") + } + }) + + // Display the window + window.display(player) + } + + def stack(SWGObject target) { + // Scan container for matching stackable item + String ourTemplate = target.getTemplate() + SWGObject container = target.getParent() + + for (SWGObject candidate : container.getContainedObjects()) { + String theirTemplate = candidate.getTemplate() + + if (candidate instanceof TangibleObject && ourTemplate.equals(theirTemplate)) { + // Increase stack count on matching stackable item + TangibleObject tangibleMatch = (TangibleObject) candidate + int theirCounter = tangibleMatch.getCounter() + TangibleObject tangibleTarget = (TangibleObject) target + int ourCounter = tangibleTarget.getCounter() + + DestroyObjectIntent.broadcast(tangibleTarget) + tangibleMatch.setCounter(theirCounter + ourCounter) + } + } + } + + def handleSelection(Player player, SWGObject target, RadialItem selection) { + switch (selection) { + case RadialItem.SERVER_MENU49: + split(player, target) + break + case RadialItem.SERVER_MENU50: + stack(target) + break + } + } +} diff --git a/src/main/java/com/projectswg/holocore/resources/objects/tangible/TangibleObject.java b/src/main/java/com/projectswg/holocore/resources/objects/tangible/TangibleObject.java index aa50ef934..0009fdfb2 100644 --- a/src/main/java/com/projectswg/holocore/resources/objects/tangible/TangibleObject.java +++ b/src/main/java/com/projectswg/holocore/resources/objects/tangible/TangibleObject.java @@ -42,6 +42,7 @@ import com.projectswg.holocore.intents.FactionIntent; import com.projectswg.holocore.intents.FactionIntent.FactionIntentType; import com.projectswg.holocore.resources.collections.SWGMap; import com.projectswg.holocore.resources.collections.SWGSet; +import com.projectswg.holocore.resources.containers.ContainerResult; import com.projectswg.holocore.resources.network.BaselineBuilder; import com.projectswg.holocore.resources.objects.SWGObject; import com.projectswg.holocore.resources.objects.creature.CreatureObject; @@ -83,6 +84,35 @@ public class TangibleObject extends SWGObject { inCombat = false; } + @Override + public ContainerResult moveToContainer(SWGObject requester, SWGObject container) { + // Check if object is stackable + if (counter > 0) { + // Check if requester has permission to container + + if (!getContainerPermissions().canMove(requester, container)) { + return ContainerResult.NO_PERMISSION; + } + + // Scan container for matching stackable item + String ourTemplate = getTemplate(); + + for (SWGObject candidate : container.getContainedObjects()) { + String theirTemplate = candidate.getTemplate(); + if (candidate instanceof TangibleObject && ourTemplate.equals(theirTemplate)) { + // Increase stack count on matching stackable item + TangibleObject tangibleMatch = (TangibleObject) candidate; + int theirCounter = tangibleMatch.getCounter(); + + tangibleMatch.setCounter(theirCounter + counter); + + return ContainerResult.SUCCESS; + } + } + } + return super.moveToContainer(requester, container); + } + public byte [] getAppearanceData() { return appearanceData; } From 02a6fcd33548191758a781a0d0f556d809d5364a Mon Sep 17 00:00:00 2001 From: Mads Boddum Date: Sun, 25 Feb 2018 03:49:10 +0100 Subject: [PATCH 2/8] Added attribute checks for autostacking --- .../resources/objects/tangible/TangibleObject.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/projectswg/holocore/resources/objects/tangible/TangibleObject.java b/src/main/java/com/projectswg/holocore/resources/objects/tangible/TangibleObject.java index 0009fdfb2..362b4e28a 100644 --- a/src/main/java/com/projectswg/holocore/resources/objects/tangible/TangibleObject.java +++ b/src/main/java/com/projectswg/holocore/resources/objects/tangible/TangibleObject.java @@ -28,6 +28,7 @@ package com.projectswg.holocore.resources.objects.tangible; import java.io.IOException; import java.io.ObjectInputStream; +import java.util.Map; import java.util.Set; import com.projectswg.common.data.encodables.tangible.PvpFaction; @@ -88,18 +89,21 @@ public class TangibleObject extends SWGObject { public ContainerResult moveToContainer(SWGObject requester, SWGObject container) { // Check if object is stackable if (counter > 0) { - // Check if requester has permission to container + // Check if requester has permission to container if (!getContainerPermissions().canMove(requester, container)) { return ContainerResult.NO_PERMISSION; } // Scan container for matching stackable item String ourTemplate = getTemplate(); + Map ourAttributes = getAttributes(); for (SWGObject candidate : container.getContainedObjects()) { String theirTemplate = candidate.getTemplate(); - if (candidate instanceof TangibleObject && ourTemplate.equals(theirTemplate)) { + Map theirAttributes = candidate.getAttributes(); + + if (candidate instanceof TangibleObject && ourTemplate.equals(theirTemplate) && ourAttributes.equals(theirAttributes)) { // Increase stack count on matching stackable item TangibleObject tangibleMatch = (TangibleObject) candidate; int theirCounter = tangibleMatch.getCounter(); From 5f4c60b85b83cbac9242aff837e2bd27cd2bf14d Mon Sep 17 00:00:00 2001 From: Mads Boddum Date: Mon, 5 Mar 2018 12:35:26 +0100 Subject: [PATCH 3/8] Fixed various item stacking/splitting issues --- .../radial/object/CreditObjectRadial.groovy | 2 +- .../radial/object/SWGObjectRadial.groovy | 131 +++++++++++++++- .../scripts/radial/object/StackRadial.groovy | 145 ------------------ .../radial/object/UsableObjectRadial.groovy | 1 + .../survey/ObjectSurveyToolRadial.groovy | 12 +- .../uniform/ObjectUniformBoxRadial.groovy | 2 +- .../TerminalCharacterBuilderRadial.groovy | 16 ++ .../holocore/resources/objects/SWGObject.java | 2 +- .../objects/tangible/TangibleObject.java | 14 +- 9 files changed, 167 insertions(+), 158 deletions(-) delete mode 100644 src/main/groovy/com/projectswg/holocore/scripts/radial/object/StackRadial.groovy diff --git a/src/main/groovy/com/projectswg/holocore/scripts/radial/object/CreditObjectRadial.groovy b/src/main/groovy/com/projectswg/holocore/scripts/radial/object/CreditObjectRadial.groovy index 7d6e1c40d..987d2eb1e 100644 --- a/src/main/groovy/com/projectswg/holocore/scripts/radial/object/CreditObjectRadial.groovy +++ b/src/main/groovy/com/projectswg/holocore/scripts/radial/object/CreditObjectRadial.groovy @@ -34,7 +34,7 @@ import com.projectswg.holocore.resources.objects.SWGObject import com.projectswg.holocore.resources.player.Player import com.projectswg.holocore.scripts.radial.RadialHandlerInterface -class CreditObjectRadial extends SWGObjectRadial implements RadialHandlerInterface { +class CreditObjectRadial extends SWGObjectRadial { def getOptions(List options, Player player, SWGObject target) { options.add(new RadialOption(RadialItem.TRANSFER_CREDITS_TO_BANK_ACCOUNT)) diff --git a/src/main/groovy/com/projectswg/holocore/scripts/radial/object/SWGObjectRadial.groovy b/src/main/groovy/com/projectswg/holocore/scripts/radial/object/SWGObjectRadial.groovy index d1eae1136..116908c83 100644 --- a/src/main/groovy/com/projectswg/holocore/scripts/radial/object/SWGObjectRadial.groovy +++ b/src/main/groovy/com/projectswg/holocore/scripts/radial/object/SWGObjectRadial.groovy @@ -29,18 +29,145 @@ package com.projectswg.holocore.scripts.radial.object import com.projectswg.common.data.radial.RadialItem import com.projectswg.common.data.radial.RadialOption +import com.projectswg.common.debug.Log +import com.projectswg.common.network.packets.swg.zone.UpdateContainmentMessage +import com.projectswg.holocore.intents.chat.SystemMessageIntent +import com.projectswg.holocore.intents.object.DestroyObjectIntent +import com.projectswg.holocore.intents.object.ObjectCreatedIntent import com.projectswg.holocore.resources.objects.SWGObject +import com.projectswg.holocore.resources.objects.creature.CreatureObject +import com.projectswg.holocore.resources.objects.tangible.TangibleObject import com.projectswg.holocore.resources.player.Player +import com.projectswg.holocore.resources.sui.SuiInputBox import com.projectswg.holocore.scripts.radial.RadialHandlerInterface +import com.projectswg.holocore.services.objects.ObjectCreator class SWGObjectRadial implements RadialHandlerInterface { def getOptions(List options, Player player, SWGObject target) { + stackOptions(options, target) + } + + def stackOptions(List options, SWGObject target) { + // Verify that target is a tangible + if (!(target instanceof TangibleObject)) { + return + } + if (target instanceof CreatureObject) { + return + } + + // Check if the target is not in a container then show no radial options + SWGObject container = target.getParent() + + if (container == null) { + return + } + + def tangibleTarget = (TangibleObject) target + + if (tangibleTarget.getCounter() < 1) { + return + } + + options.add(new RadialOption(RadialItem.SERVER_MENU49)) // Split + options.add(new RadialOption(RadialItem.SERVER_MENU50)) // Stack + } + + def split(Player player, SWGObject target) { + // Create input-window + def window = new SuiInputBox("@autostack:unstack", "@autostack:stacksize") + + // Handle button selection + window.addOkButtonCallback("split", {event, parameters -> + String input = SuiInputBox.getEnteredText(parameters) + TangibleObject originalStack = (TangibleObject) target + + try { + int newStackSize = Integer.parseInt(input) + int counter = originalStack.getCounter() + int oldStackSize = counter - newStackSize + + if (oldStackSize < 1) { + SystemMessageIntent.broadcastPersonal(player, "@autostack:zero_size") + return + } else if (oldStackSize >= counter) { + SystemMessageIntent.broadcastPersonal(player, "@autostack:too_big") + return + } + + // Check inventory volume + SWGObject container = target.getParent() + + if (container.getVolume() + 1 > container.getMaxContainerSize()) { + SystemMessageIntent.broadcastPersonal(player, "@autostack:full_container") + return + } + + // Create new object using same template + // TODO needs to copy other stuff as well, such as customization variables and object attributes + String template = originalStack.getTemplate() + TangibleObject newStack = ObjectCreator.createObjectFromTemplate(template, TangibleObject.class) + + // Adjust stack sizes + originalStack.setCounter(oldStackSize) + newStack.setCounter(newStackSize) + + // Add new stack to container + container.addObject(newStack) + + // Let objects aware of the container know that there's been created an object + container.getObjectsAware().forEach {observer -> newStack.createObject(observer) } + + // Let the executor of the split know that there's been created an object + newStack.createObject(player) + + ObjectCreatedIntent.broadcast(newStack) + } catch (NumberFormatException e) { + SystemMessageIntent.broadcastPersonal(player, "@autostack:number_format_wrong") + } + }) + + // Display the window + window.display(player) + } + + def stack(SWGObject target) { + // Scan container for matching stackable item + String ourTemplate = target.getTemplate() + SWGObject container = target.getParent() + + for (SWGObject candidate : container.getContainedObjects()) { + if (target.equals(candidate)) { + continue + } + + String theirTemplate = candidate.getTemplate() + + if (candidate instanceof TangibleObject && ourTemplate.equals(theirTemplate)) { + // Increase stack count on matching stackable item + TangibleObject tangibleMatch = (TangibleObject) candidate + int theirCounter = tangibleMatch.getCounter() + TangibleObject tangibleTarget = (TangibleObject) target + int ourCounter = tangibleTarget.getCounter() + + DestroyObjectIntent.broadcast(tangibleTarget) + tangibleMatch.setCounter(theirCounter + ourCounter) + + break + } + } } def handleSelection(Player player, SWGObject target, RadialItem selection) { - + switch (selection) { + case RadialItem.SERVER_MENU49: + split(player, target) + break + case RadialItem.SERVER_MENU50: + stack(target) + break + } } - } diff --git a/src/main/groovy/com/projectswg/holocore/scripts/radial/object/StackRadial.groovy b/src/main/groovy/com/projectswg/holocore/scripts/radial/object/StackRadial.groovy deleted file mode 100644 index 5b42d33d4..000000000 --- a/src/main/groovy/com/projectswg/holocore/scripts/radial/object/StackRadial.groovy +++ /dev/null @@ -1,145 +0,0 @@ -/*********************************************************************************** - * Copyright (c) 2018 /// Project SWG /// www.projectswg.com * - * * - * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on * - * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * - * Our goal is to create an emulator which will provide a server for players to * - * continue playing a game similar to the one they used to play. We are basing * - * it on the final publish of the game prior to end-game events. * - * * - * This file is part of Holocore. * - * * - * --------------------------------------------------------------------------------* - * * - * Holocore is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * Holocore is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with Holocore. If not, see . * - ***********************************************************************************/ - -package com.projectswg.holocore.scripts.radial.object - -import com.projectswg.common.data.radial.RadialItem -import com.projectswg.common.data.radial.RadialOption -import com.projectswg.common.debug.Log -import com.projectswg.holocore.intents.chat.SystemMessageIntent -import com.projectswg.holocore.intents.combat.loot.LootRequestIntent -import com.projectswg.holocore.intents.object.DestroyObjectIntent -import com.projectswg.holocore.intents.object.ObjectCreatedIntent -import com.projectswg.holocore.resources.objects.SWGObject -import com.projectswg.holocore.resources.objects.tangible.TangibleObject -import com.projectswg.holocore.resources.player.Player -import com.projectswg.holocore.resources.sui.SuiInputBox -import com.projectswg.holocore.scripts.radial.RadialHandlerInterface -import com.projectswg.holocore.services.objects.ObjectCreator - -class StackRadial extends SWGObjectRadial { - - def getOptions(List options, Player player, SWGObject target) { - // Verify that target is a tangible - if (!(target instanceof TangibleObject)) { - Log.w("StackRadial attached to non-TangibleObject") - return - } - - // Check if the target is not in a container then show no radial options - SWGObject container = target.getParent() - - if (container == null) { - return - } - - options.add(new RadialOption(RadialItem.SERVER_MENU49)) // Split - options.add(new RadialOption(RadialItem.SERVER_MENU50)) // Stack - } - - def split(Player player, SWGObject target) { - // Create input-window - def window = new SuiInputBox("@autostack:unstack", "@autostack:stacksize") - - // Handle button selection - window.addOkButtonCallback("split", {event, parameters -> - String input = SuiInputBox.getEnteredText(parameters) - TangibleObject originalStack = (TangibleObject) target - - try { - int newStackSize = Integer.parseInt(input) - int counter = originalStack.getCounter() - int oldStackSize = counter - newStackSize - - if (oldStackSize < 1) { - SystemMessageIntent.broadcastPersonal(player, "@autostack:zero_size") - return - } else if (oldStackSize >= counter) { - SystemMessageIntent.broadcastPersonal(player, "@autostack:too_big") - return - } - - // Check inventory volume - SWGObject container = target.getParent() - - if (container.getVolume() + 1 > container.getMaxContainerSize()) { - SystemMessageIntent.broadcastPersonal(player, "@autostack:full_container") - return - } - - // Create new identical object - String template = originalStack.getTemplate() - TangibleObject newStack = ObjectCreator.createObjectFromTemplate(template, TangibleObject.class) - ObjectCreatedIntent.broadcast(newStack) - - // Adjust stack sizes - originalStack.setCounter(oldStackSize) - newStack.setCounter(newStackSize) - - // Add new stack to container - container.addObject(newStack) - } catch (NumberFormatException e) { - SystemMessageIntent.broadcastPersonal(player, "@autostack:number_format_wrong") - } - }) - - // Display the window - window.display(player) - } - - def stack(SWGObject target) { - // Scan container for matching stackable item - String ourTemplate = target.getTemplate() - SWGObject container = target.getParent() - - for (SWGObject candidate : container.getContainedObjects()) { - String theirTemplate = candidate.getTemplate() - - if (candidate instanceof TangibleObject && ourTemplate.equals(theirTemplate)) { - // Increase stack count on matching stackable item - TangibleObject tangibleMatch = (TangibleObject) candidate - int theirCounter = tangibleMatch.getCounter() - TangibleObject tangibleTarget = (TangibleObject) target - int ourCounter = tangibleTarget.getCounter() - - DestroyObjectIntent.broadcast(tangibleTarget) - tangibleMatch.setCounter(theirCounter + ourCounter) - } - } - } - - def handleSelection(Player player, SWGObject target, RadialItem selection) { - switch (selection) { - case RadialItem.SERVER_MENU49: - split(player, target) - break - case RadialItem.SERVER_MENU50: - stack(target) - break - } - } -} diff --git a/src/main/groovy/com/projectswg/holocore/scripts/radial/object/UsableObjectRadial.groovy b/src/main/groovy/com/projectswg/holocore/scripts/radial/object/UsableObjectRadial.groovy index c076b2e9c..20a049565 100644 --- a/src/main/groovy/com/projectswg/holocore/scripts/radial/object/UsableObjectRadial.groovy +++ b/src/main/groovy/com/projectswg/holocore/scripts/radial/object/UsableObjectRadial.groovy @@ -35,6 +35,7 @@ import com.projectswg.holocore.resources.player.Player class UsableObjectRadial extends SWGObjectRadial { def getOptions(List options, Player player, SWGObject target) { + super.getOptions(options, player, target) options.add(new RadialOption(RadialItem.ITEM_USE)) options.add(new RadialOption(RadialItem.EXAMINE)) } diff --git a/src/main/groovy/com/projectswg/holocore/scripts/radial/object/survey/ObjectSurveyToolRadial.groovy b/src/main/groovy/com/projectswg/holocore/scripts/radial/object/survey/ObjectSurveyToolRadial.groovy index 4ae0ab253..04b9cfef4 100644 --- a/src/main/groovy/com/projectswg/holocore/scripts/radial/object/survey/ObjectSurveyToolRadial.groovy +++ b/src/main/groovy/com/projectswg/holocore/scripts/radial/object/survey/ObjectSurveyToolRadial.groovy @@ -33,15 +33,15 @@ import com.projectswg.holocore.intents.crafting.survey.StartSurveyToolIntent import com.projectswg.holocore.resources.objects.SWGObject import com.projectswg.holocore.resources.player.Player import com.projectswg.holocore.scripts.radial.RadialHandlerInterface +import com.projectswg.holocore.scripts.radial.object.UsableObjectRadial -class ObjectSurveyToolRadial implements RadialHandlerInterface { - - def getOptions(List options, Player player, SWGObject target) { - options.add(new RadialOption(RadialItem.ITEM_USE)) - options.add(new RadialOption(RadialItem.EXAMINE)) - } +class ObjectSurveyToolRadial extends UsableObjectRadial { def handleSelection(Player player, SWGObject target, RadialItem selection) { + if (selection != RadialItem.ITEM_USE) { + return + } + new StartSurveyToolIntent(player.getCreatureObject(), target).broadcast() } diff --git a/src/main/groovy/com/projectswg/holocore/scripts/radial/object/uniform/ObjectUniformBoxRadial.groovy b/src/main/groovy/com/projectswg/holocore/scripts/radial/object/uniform/ObjectUniformBoxRadial.groovy index 92485a318..7de0d7116 100644 --- a/src/main/groovy/com/projectswg/holocore/scripts/radial/object/uniform/ObjectUniformBoxRadial.groovy +++ b/src/main/groovy/com/projectswg/holocore/scripts/radial/object/uniform/ObjectUniformBoxRadial.groovy @@ -35,7 +35,7 @@ import com.projectswg.holocore.resources.player.Player import com.projectswg.holocore.scripts.radial.RadialHandlerInterface import com.projectswg.holocore.scripts.radial.object.SWGObjectRadial -class ObjectUniformBoxRadial extends SWGObjectRadial implements RadialHandlerInterface { +class ObjectUniformBoxRadial extends SWGObjectRadial { def handleSelection(Player player, SWGObject target, RadialItem selection) { DestroyObjectIntent.broadcast(target) diff --git a/src/main/groovy/com/projectswg/holocore/scripts/radial/terminal/TerminalCharacterBuilderRadial.groovy b/src/main/groovy/com/projectswg/holocore/scripts/radial/terminal/TerminalCharacterBuilderRadial.groovy index 0e5c4eaa5..cbc08d3e9 100644 --- a/src/main/groovy/com/projectswg/holocore/scripts/radial/terminal/TerminalCharacterBuilderRadial.groovy +++ b/src/main/groovy/com/projectswg/holocore/scripts/radial/terminal/TerminalCharacterBuilderRadial.groovy @@ -33,13 +33,16 @@ import com.projectswg.common.data.radial.RadialItem import com.projectswg.common.data.radial.RadialOption import com.projectswg.common.data.sui.SuiEvent import com.projectswg.holocore.intents.object.CreateStaticItemIntent +import com.projectswg.holocore.intents.object.ObjectCreatedIntent import com.projectswg.holocore.intents.object.ObjectTeleportIntent import com.projectswg.holocore.resources.containers.ContainerPermissionsType import com.projectswg.holocore.resources.objects.SWGObject +import com.projectswg.holocore.resources.objects.tangible.TangibleObject import com.projectswg.holocore.resources.player.Player import com.projectswg.holocore.resources.sui.SuiButtons import com.projectswg.holocore.resources.sui.SuiListBox import com.projectswg.holocore.scripts.radial.RadialHandlerInterface +import com.projectswg.holocore.services.objects.ObjectCreator import com.projectswg.holocore.services.objects.StaticItemService class TerminalCharacterBuilderRadial implements RadialHandlerInterface { @@ -59,6 +62,7 @@ class TerminalCharacterBuilderRadial implements RadialHandlerInterface { listBox.addListItem("Wearables") listBox.addListItem("Tools") listBox.addListItem("Travel") + listBox.addListItem("Stack test") listBox.addCallback(SuiEvent.OK_PRESSED, "handleCategorySelection", { event, parameters -> handleCategorySelection(player, parameters) }) listBox.display(player) @@ -76,6 +80,7 @@ class TerminalCharacterBuilderRadial implements RadialHandlerInterface { case 2: handleWearables(player); break case 3: handleTools(player); break case 4: handleTravel(player); break + case 5: handleStackTest(player); break } } @@ -1387,4 +1392,15 @@ class TerminalCharacterBuilderRadial implements RadialHandlerInterface { static def handleYavGeoCave(Player player) { new ObjectTeleportIntent(player.getCreatureObject(), new Location(-6485d, 83d, -446d, Terrain.YAVIN4)).broadcast() } + + static def handleStackTest(Player player) { + def stackObject = ObjectCreator.createObjectFromTemplate("object/tangible/dice/shared_eqp_chance_cube.iff", TangibleObject.class) + def creature = player.getCreatureObject() + def inventory = creature.getSlottedObject("inventory") + + stackObject.setCounter(6) + stackObject.moveToContainer(inventory) + + ObjectCreatedIntent.broadcast(stackObject) + } } diff --git a/src/main/java/com/projectswg/holocore/resources/objects/SWGObject.java b/src/main/java/com/projectswg/holocore/resources/objects/SWGObject.java index ae62cb6d4..9f9fc7e5d 100644 --- a/src/main/java/com/projectswg/holocore/resources/objects/SWGObject.java +++ b/src/main/java/com/projectswg/holocore/resources/objects/SWGObject.java @@ -550,7 +550,7 @@ public abstract class SWGObject extends BaselineObject implements Comparable getAttributes() { - return attributes; + return new HashMap<>(attributes); } public int getContainerType() { diff --git a/src/main/java/com/projectswg/holocore/resources/objects/tangible/TangibleObject.java b/src/main/java/com/projectswg/holocore/resources/objects/tangible/TangibleObject.java index 362b4e28a..c2dd5b19d 100644 --- a/src/main/java/com/projectswg/holocore/resources/objects/tangible/TangibleObject.java +++ b/src/main/java/com/projectswg/holocore/resources/objects/tangible/TangibleObject.java @@ -34,6 +34,7 @@ import java.util.Set; import com.projectswg.common.data.encodables.tangible.PvpFaction; import com.projectswg.common.data.encodables.tangible.PvpFlag; import com.projectswg.common.data.encodables.tangible.PvpStatus; +import com.projectswg.common.debug.Log; import com.projectswg.common.encoding.StringType; import com.projectswg.common.network.NetBuffer; import com.projectswg.common.network.NetBufferStream; @@ -41,6 +42,7 @@ import com.projectswg.common.network.packets.swg.zone.baselines.Baseline.Baselin import com.projectswg.holocore.intents.FactionIntent; import com.projectswg.holocore.intents.FactionIntent.FactionIntentType; +import com.projectswg.holocore.intents.object.DestroyObjectIntent; import com.projectswg.holocore.resources.collections.SWGMap; import com.projectswg.holocore.resources.collections.SWGSet; import com.projectswg.holocore.resources.containers.ContainerResult; @@ -85,11 +87,15 @@ public class TangibleObject extends SWGObject { inCombat = false; } + @Override + public ContainerResult moveToContainer(SWGObject container) { + return this.moveToContainer(null, container); + } + @Override public ContainerResult moveToContainer(SWGObject requester, SWGObject container) { // Check if object is stackable - if (counter > 0) { - + if (container != null && counter > 0) { // Check if requester has permission to container if (!getContainerPermissions().canMove(requester, container)) { return ContainerResult.NO_PERMISSION; @@ -104,6 +110,9 @@ public class TangibleObject extends SWGObject { Map theirAttributes = candidate.getAttributes(); if (candidate instanceof TangibleObject && ourTemplate.equals(theirTemplate) && ourAttributes.equals(theirAttributes)) { + Log.d("Match found! Merging objects."); + DestroyObjectIntent.broadcast(this); + // Increase stack count on matching stackable item TangibleObject tangibleMatch = (TangibleObject) candidate; int theirCounter = tangibleMatch.getCounter(); @@ -114,6 +123,7 @@ public class TangibleObject extends SWGObject { } } } + return super.moveToContainer(requester, container); } From b1a0e1f05dda5870995991f6f7025d6d78117ed0 Mon Sep 17 00:00:00 2001 From: Mads Boddum Date: Wed, 28 Mar 2018 15:47:31 +0200 Subject: [PATCH 4/8] Removed unnecessary SWGObject attribute Map manipulation --- .../scripts/radial/object/SWGObjectRadial.groovy | 12 ++---------- .../commands/callbacks/AttributesCmdCallback.java | 9 +-------- .../holocore/resources/objects/SWGObject.java | 2 +- 3 files changed, 4 insertions(+), 19 deletions(-) diff --git a/src/main/groovy/com/projectswg/holocore/scripts/radial/object/SWGObjectRadial.groovy b/src/main/groovy/com/projectswg/holocore/scripts/radial/object/SWGObjectRadial.groovy index 116908c83..cf549cb84 100644 --- a/src/main/groovy/com/projectswg/holocore/scripts/radial/object/SWGObjectRadial.groovy +++ b/src/main/groovy/com/projectswg/holocore/scripts/radial/object/SWGObjectRadial.groovy @@ -29,13 +29,10 @@ package com.projectswg.holocore.scripts.radial.object import com.projectswg.common.data.radial.RadialItem import com.projectswg.common.data.radial.RadialOption -import com.projectswg.common.debug.Log -import com.projectswg.common.network.packets.swg.zone.UpdateContainmentMessage import com.projectswg.holocore.intents.chat.SystemMessageIntent import com.projectswg.holocore.intents.object.DestroyObjectIntent import com.projectswg.holocore.intents.object.ObjectCreatedIntent import com.projectswg.holocore.resources.objects.SWGObject -import com.projectswg.holocore.resources.objects.creature.CreatureObject import com.projectswg.holocore.resources.objects.tangible.TangibleObject import com.projectswg.holocore.resources.player.Player import com.projectswg.holocore.resources.sui.SuiInputBox @@ -50,13 +47,8 @@ class SWGObjectRadial implements RadialHandlerInterface { def stackOptions(List options, SWGObject target) { // Verify that target is a tangible - if (!(target instanceof TangibleObject)) { + if (target == null || target.getClass() != TangibleObject.class) return - } - - if (target instanceof CreatureObject) { - return - } // Check if the target is not in a container then show no radial options SWGObject container = target.getParent() @@ -108,7 +100,7 @@ class SWGObjectRadial implements RadialHandlerInterface { // Create new object using same template // TODO needs to copy other stuff as well, such as customization variables and object attributes String template = originalStack.getTemplate() - TangibleObject newStack = ObjectCreator.createObjectFromTemplate(template, TangibleObject.class) + TangibleObject newStack = (TangibleObject) ObjectCreator.createObjectFromTemplate(template) // Adjust stack sizes originalStack.setCounter(oldStackSize) diff --git a/src/main/java/com/projectswg/holocore/resources/commands/callbacks/AttributesCmdCallback.java b/src/main/java/com/projectswg/holocore/resources/commands/callbacks/AttributesCmdCallback.java index 385af3fef..06af83d14 100644 --- a/src/main/java/com/projectswg/holocore/resources/commands/callbacks/AttributesCmdCallback.java +++ b/src/main/java/com/projectswg/holocore/resources/commands/callbacks/AttributesCmdCallback.java @@ -26,8 +26,6 @@ ***********************************************************************************/ package com.projectswg.holocore.resources.commands.callbacks; -import java.util.Map; - import com.projectswg.common.network.packets.swg.zone.spatial.AttributeListMessage; import com.projectswg.holocore.resources.commands.ICmdCallback; @@ -52,11 +50,6 @@ public class AttributesCmdCallback implements ICmdCallback { } private void handleSendItemAttributes(SWGObject object, Player player) { - Map attributes = object.getAttributes(); - if (attributes.size() == 0) - attributes.put("", ""); - - AttributeListMessage message = new AttributeListMessage(object.getObjectId(), attributes); - player.sendPacket(message); + player.sendPacket(new AttributeListMessage(object.getObjectId(), object.getAttributes())); } } diff --git a/src/main/java/com/projectswg/holocore/resources/objects/SWGObject.java b/src/main/java/com/projectswg/holocore/resources/objects/SWGObject.java index 9f9fc7e5d..9bf1d6ab5 100644 --- a/src/main/java/com/projectswg/holocore/resources/objects/SWGObject.java +++ b/src/main/java/com/projectswg/holocore/resources/objects/SWGObject.java @@ -550,7 +550,7 @@ public abstract class SWGObject extends BaselineObject implements Comparable getAttributes() { - return new HashMap<>(attributes); + return Collections.unmodifiableMap(attributes); } public int getContainerType() { From f70addfcbe3341e1566b0e4c2c735b47e1972427 Mon Sep 17 00:00:00 2001 From: Mads Boddum Date: Wed, 28 Mar 2018 16:47:20 +0200 Subject: [PATCH 5/8] Stack/split radial names are set --- .../scripts/radial/object/SWGObjectRadial.groovy | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/groovy/com/projectswg/holocore/scripts/radial/object/SWGObjectRadial.groovy b/src/main/groovy/com/projectswg/holocore/scripts/radial/object/SWGObjectRadial.groovy index a96865bac..180d3469f 100644 --- a/src/main/groovy/com/projectswg/holocore/scripts/radial/object/SWGObjectRadial.groovy +++ b/src/main/groovy/com/projectswg/holocore/scripts/radial/object/SWGObjectRadial.groovy @@ -63,8 +63,14 @@ class SWGObjectRadial implements RadialHandlerInterface { return } - options.add(new RadialOption(RadialItem.SERVER_MENU49)) // Split - options.add(new RadialOption(RadialItem.SERVER_MENU50)) // Stack + def splitOption = new RadialOption(RadialItem.SERVER_MENU49) + def stackOption = new RadialOption(RadialItem.SERVER_MENU50) + + splitOption.setOverriddenText("@autostack:unstack") + stackOption.setOverriddenText("@autostack:stack") + + options.add(splitOption) + options.add(stackOption) } def split(Player player, SWGObject target) { From fe08f7401f3fea37d80eae7ae984fd9a13498d7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilie=20Marott=20J=C3=B8rgensen?= Date: Wed, 28 Mar 2018 19:53:00 +0200 Subject: [PATCH 6/8] Removed old code in TangibleObject --- .../objects/tangible/TangibleObject.java | 41 ------------------- 1 file changed, 41 deletions(-) diff --git a/src/main/java/com/projectswg/holocore/resources/objects/tangible/TangibleObject.java b/src/main/java/com/projectswg/holocore/resources/objects/tangible/TangibleObject.java index bc55c468b..2bc8c4576 100644 --- a/src/main/java/com/projectswg/holocore/resources/objects/tangible/TangibleObject.java +++ b/src/main/java/com/projectswg/holocore/resources/objects/tangible/TangibleObject.java @@ -105,47 +105,6 @@ public class TangibleObject extends SWGObject { super.moveToContainer(newParent); // Not stackable, use default behavior } - /* - @Override - public void moveToContainer(SWGObject container) { - this.moveToContainer(null, container); - } - - @Override - public ContainerResult moveToContainer(SWGObject requester, SWGObject container) { - // Check if object is stackable - if (container != null && counter > 0) { - // Check if requester has permission to container - if (!getContainerPermissions().canMove(requester, container)) { - return ContainerResult.NO_PERMISSION; - } - - // Scan container for matching stackable item - String ourTemplate = getTemplate(); - Map ourAttributes = getAttributes(); - - for (SWGObject candidate : container.getContainedObjects()) { - String theirTemplate = candidate.getTemplate(); - Map theirAttributes = candidate.getAttributes(); - - if (candidate instanceof TangibleObject && ourTemplate.equals(theirTemplate) && ourAttributes.equals(theirAttributes)) { - Log.d("Match found! Merging objects."); - DestroyObjectIntent.broadcast(this); - - // Increase stack count on matching stackable item - TangibleObject tangibleMatch = (TangibleObject) candidate; - int theirCounter = tangibleMatch.getCounter(); - - tangibleMatch.setCounter(theirCounter + counter); - - return ContainerResult.SUCCESS; - } - } - } - - return super.moveToContainer(requester, container); - } - */ public int getMaxHitPoints() { return maxHitPoints; } From a57e3724900ce3287c9ea8c117e7550ae1f31336 Mon Sep 17 00:00:00 2001 From: Mads Boddum Date: Sat, 31 Mar 2018 16:24:51 +0200 Subject: [PATCH 7/8] Follow new awareness system in SWGObjectRadial --- .../holocore/scripts/radial/object/SWGObjectRadial.groovy | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/groovy/com/projectswg/holocore/scripts/radial/object/SWGObjectRadial.groovy b/src/main/groovy/com/projectswg/holocore/scripts/radial/object/SWGObjectRadial.groovy index 180d3469f..d65eb861e 100644 --- a/src/main/groovy/com/projectswg/holocore/scripts/radial/object/SWGObjectRadial.groovy +++ b/src/main/groovy/com/projectswg/holocore/scripts/radial/object/SWGObjectRadial.groovy @@ -113,9 +113,8 @@ class SWGObjectRadial implements RadialHandlerInterface { newStack.setCounter(newStackSize) // We don't use moveToContainer, because that would trigger auto-stacking. - container.addObject(newStack) + container.systemMove(newStack) - // TODO ContainmentUpdate somehow ContainerTransferIntent.broadcast(newStack, null, container) ObjectCreatedIntent.broadcast(newStack) From c08cb984228ef2939a4719572a1e6013a3401162 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilie=20Marott=20J=C3=B8rgensen?= Date: Sat, 31 Mar 2018 17:45:03 +0200 Subject: [PATCH 8/8] Fixed incorrect container transfer --- .../holocore/scripts/radial/object/SWGObjectRadial.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/groovy/com/projectswg/holocore/scripts/radial/object/SWGObjectRadial.groovy b/src/main/groovy/com/projectswg/holocore/scripts/radial/object/SWGObjectRadial.groovy index d65eb861e..0a2988328 100644 --- a/src/main/groovy/com/projectswg/holocore/scripts/radial/object/SWGObjectRadial.groovy +++ b/src/main/groovy/com/projectswg/holocore/scripts/radial/object/SWGObjectRadial.groovy @@ -113,7 +113,7 @@ class SWGObjectRadial implements RadialHandlerInterface { newStack.setCounter(newStackSize) // We don't use moveToContainer, because that would trigger auto-stacking. - container.systemMove(newStack) + newStack.systemMove(container) ContainerTransferIntent.broadcast(newStack, null, container)